[sheepdog] [PATCH v2 4/5] lib/fec: rework ec_decode

Liu Yuan namei.unix at gmail.com
Sat Oct 12 14:13:34 CEST 2013


fec_decode has some assumptins about the passed on buffer arrays and indexes.
The reworked ec_decode will handle all the cases internally and we can rebuild
whatever strip, be it data strip or parity strip, we want from this helper
function.

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 include/fec.h |   17 ++++++------
 lib/fec.c     |   85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 9 deletions(-)

diff --git a/include/fec.h b/include/fec.h
index c0ca2f5..ff79edb 100644
--- a/include/fec.h
+++ b/include/fec.h
@@ -118,7 +118,7 @@ void fec_decode(const struct fec *code,
 #define SD_EC_D_SIZE (SD_EC_STRIP_SIZE * SD_EC_D)
 #define SD_EC_OBJECT_SIZE (SD_DATA_OBJ_SIZE / SD_EC_D)
 #define SD_EC_STRIPE (SD_EC_STRIP_SIZE * SD_EC_DP)
-#define STRIP_PER_OBJECT (SD_DATA_OBJ_SIZE / SD_EC_STRIP_SIZE)
+#define SD_EC_NR_STRIPE_PER_OBJECT (SD_EC_OBJECT_SIZE / SD_EC_STRIP_SIZE)
 
 /*
  * Stripe: data strips + parity strips, spread on all replica
@@ -158,18 +158,17 @@ static inline void ec_encode(struct fec *ctx, const uint8_t *ds[SD_EC_D],
 }
 
 /*
- * This function takes input strips and return the lost strips
+ * This function takes input strips and return the lost strip
  *
  * @input: strips (either ds or ps) that are used to generate lost strips
+ * @inidx: indexes of each input strip in the whole stripe, must be in numeric
+ *         order such as { 0, 2, 4, 5 }
  * @output: the lost ds or ps to return
- * @idx: indexes of each input strip in the whole stripe
+ * @idx: index of output which is lost
  */
-static inline void ec_decode(struct fec *ctx, const uint8_t *input[SD_EC_D],
-			     uint8_t *output[],
-			     const int idx[])
-{
-	fec_decode(ctx, input, output, idx, SD_EC_STRIP_SIZE);
-}
+void ec_decode(struct fec *ctx, const uint8_t *input[SD_EC_D],
+	       const int inidx[SD_EC_D],
+	       uint8_t output[], int idx);
 
 /* Destroy the erasure code context */
 static inline void ec_destroy(struct fec *ctx)
diff --git a/lib/fec.c b/lib/fec.c
index bf5a993..6deafe4 100644
--- a/lib/fec.c
+++ b/lib/fec.c
@@ -576,3 +576,88 @@ void fec_decode(const struct fec *code,
 		}
 	}
 }
+
+/*
+ * fec_decode need primary(data) strips in the numeric place, e,g, we have
+ * indexes passed as { 0, 2, 4, 5 } and 4, 5 are parity strip, we need to pass
+ * { 0, 4, 2, 5 } (we choose this form) or { 0, 5, 2, 4} to it.
+ *
+ * Return out and outidx as fec_decode requested.
+ */
+static inline void decode_prepare(const uint8_t *dp[], const uint8_t *out[],
+				  int outidx[])
+{
+	int i, p = 0;
+
+	for (i = SD_EC_D; i < SD_EC_DP; i++) {
+		if (dp[i]) {
+			p = i;
+			break;
+		}
+	}
+
+	for (i = 0; i < SD_EC_D; i++) {
+		if (dp[i]) {
+			out[i] = dp[i];
+			outidx[i] = i;
+		} else {
+			out[i] = dp[p];
+			outidx[i] = p;
+			p++;
+		}
+	}
+}
+
+static inline bool data_is_missing(const uint8_t *dp[])
+{
+	for (int i = 0; i < SD_EC_D; i++)
+		if (!dp[i])
+			return true;
+	return false;
+}
+
+/*
+ * This function takes input strips and return the lost strip
+ *
+ * @input: strips (either ds or ps) that are used to generate lost strips
+ * @inidx: indexes of each input strip in the whole stripe, must be in numeric
+ *         order such as { 0, 2, 4, 5 }
+ * @output: the lost ds or ps to return
+ * @idx: index of output which is lost
+ */
+void ec_decode(struct fec *ctx, const uint8_t *input[SD_EC_D],
+	       const int inidx[SD_EC_D],
+	       uint8_t output[], int idx)
+{
+	const uint8_t *dp[SD_EC_DP] = { NULL };
+	const uint8_t *oin[SD_EC_D] = { NULL };
+	int oidx[SD_EC_D] = { 0 }, i;
+	uint8_t m0[SD_EC_STRIP_SIZE], m1[SD_EC_STRIP_SIZE],
+		p0[SD_EC_STRIP_SIZE], p1[SD_EC_STRIP_SIZE];
+	uint8_t *missing[SD_EC_P] = { m0, m1 };
+	uint8_t *p[SD_EC_P] = { p0, p1 };
+
+	for (i = 0; i < SD_EC_D; i++)
+		dp[inidx[i]] = input[i];
+
+	decode_prepare(dp, oin, oidx);
+
+	/* Fill the data strip if missing */
+	if (data_is_missing(dp)) {
+		int m = 0;
+		fec_decode(ctx, oin, missing, oidx, SD_EC_STRIP_SIZE);
+		for (i = 0; i < SD_EC_D; i++)
+			if (!dp[i])
+				dp[i] = missing[m++];
+	}
+
+	if (idx < SD_EC_D)
+		goto out;
+
+	/* Fill the parity strip */
+	ec_encode(ctx, dp, p);
+	for (i = 0; i < SD_EC_P; i++)
+		dp[SD_EC_D + i] = p[i];
+out:
+	memcpy(output, dp[idx], SD_EC_STRIP_SIZE);
+}
-- 
1.7.9.5




More information about the sheepdog mailing list