[sheepdog] [PATCH v2 04/21] lib/fec: rework ec_decode
Liu Yuan
namei.unix at gmail.com
Wed Oct 16 07:50:30 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