Copied from kernel raid6 lib, with some naming modification.
Signed-off-by: Qu Wenruo <quwenruo@xxxxxxxxxxxxxx>
---
raid56.c | 36 ++++++++++++++++++++++++++++++++++++
raid56.h | 3 +++
2 files changed, 39 insertions(+)
diff --git a/raid56.c b/raid56.c
index 599533e..3e471d6 100644
--- a/raid56.c
+++ b/raid56.c
@@ -233,3 +233,39 @@ int raid6_recov_data2(int nr_devs, size_t stripe_len, int dest1, int dest2,
free(zero_mem2);
return ret;
}
+
+int raid6_recov_datap(int nr_devs, size_t stripe_len, int dest1, void **data)
+{
+ u8 *p, *q, *dq;
+ const u8 *qmul; /* Q multiplier table */
+ char *zero_mem;
+
+ p = (u8 *)data[nr_devs - 2];
+ q = (u8 *)data[nr_devs - 1];
+
+ zero_mem = calloc(1, stripe_len);
+ if (!zero_mem)
+ return -ENOMEM;
+
+ /* Compute syndrome with zero for the missing data page
+ Use the dead data page as temporary storage for delta q */
+ dq = (u8 *)data[dest1];
+ data[dest1] = (void *)zero_mem;
+ data[nr_devs - 1] = dq;
+
+ raid6_gen_syndrome(nr_devs, stripe_len, data);
+
+ /* Restore pointer table */
+ data[dest1] = dq;
+ data[nr_devs - 1] = q;
+
+ /* Now, pick the proper data tables */
+ qmul = raid6_gfmul[raid6_gfinv[raid6_gfexp[dest1]]];
+
+ /* Now do it... */
+ while ( stripe_len-- ) {
+ *p++ ^= *dq = qmul[*q ^ *dq];
+ q++; dq++;
+ }
+ return 0;
+}
diff --git a/raid56.h b/raid56.h
index 46fd3a9..e30cc28 100644
--- a/raid56.h
+++ b/raid56.h
@@ -19,6 +19,9 @@
void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs);
int raid5_gen_result(int nr_devs, size_t stripe_len, int dest, void **data);
+/* Recover data and P */
+int raid6_recov_datap(int nr_devs, size_t stripe_len, int dest1, void **data);
+
/* Recover 2 data */
int raid6_recov_data2(int nr_devs, size_t stripe_len, int dest1, int dest2,
void **data);
--
2.10.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html