Re: [RFC v2 2/2] fs: btrfs: Extends btrfs/raid56 to support up to six parities

2014-01-07 Thread Andrea Mazzoleni
Hi Chris,

On 01/06, Chris Mason wrote:
> Neat.  The faila/failb were always my least favorite part of the btrfs
> code ;)  Did you test just raid5/6 or also the higher parity counts?
At this stage no real testing was made with btrfs.

The intention of this btrfs patch is mainly to get feedback on the new raid
inteface, and see if it matches the needs of btrfs, and if it results in
cleaner code than before.

And besides the removal of the faila/failb variables, something other that
likely you can appreciate is the removal of all the P/Q logic from btrfs,
that it's now replaced with a single raid_rec() call.

After the raid interface stabilizes, this patch can be used as starting
point for a real btrfs patch. But at now it's just to show
some example code of what kind of modification btrfs will need.

Ciao,
Andrea
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC v2 2/2] fs: btrfs: Extends btrfs/raid56 to support up to six parities

2014-01-06 Thread Chris Mason
On Mon, 2014-01-06 at 10:31 +0100, Andrea Mazzoleni wrote:
> This patch changes btrfs/raid56.c to use the new raid interface and
> extends its support to an arbitrary number of parities.
> 
> More in details, the two faila/failb failure indexes are now replaced
> with a fail[] vector that keeps track of up to six failures, and now
> the new raid_par() and raid_rec() functions are used to handle with
> parity instead of the old xor/raid6 ones.
> 

Neat.  The faila/failb were always my least favorite part of the btrfs
code ;)  Did you test just raid5/6 or also the higher parity counts?

-chris

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v2 2/2] fs: btrfs: Extends btrfs/raid56 to support up to six parities

2014-01-06 Thread Andrea Mazzoleni
This patch changes btrfs/raid56.c to use the new raid interface and
extends its support to an arbitrary number of parities.

More in details, the two faila/failb failure indexes are now replaced
with a fail[] vector that keeps track of up to six failures, and now
the new raid_par() and raid_rec() functions are used to handle with
parity instead of the old xor/raid6 ones.

Signed-off-by: Andrea Mazzoleni 
---
 fs/btrfs/Kconfig   |   1 +
 fs/btrfs/raid56.c  | 278 ++---
 fs/btrfs/raid56.h  |  12 ++-
 fs/btrfs/volumes.c |   4 +-
 4 files changed, 102 insertions(+), 193 deletions(-)

diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig
index aa976ec..173fabe 100644
--- a/fs/btrfs/Kconfig
+++ b/fs/btrfs/Kconfig
@@ -5,6 +5,7 @@ config BTRFS_FS
select ZLIB_DEFLATE
select LZO_COMPRESS
select LZO_DECOMPRESS
+   select RAID_CAUCHY
select RAID6_PQ
select XOR_BLOCKS
 
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index 24ac218..2ceff3a 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -27,10 +27,9 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include "ctree.h"
@@ -125,11 +124,11 @@ struct btrfs_raid_bio {
 */
int read_rebuild;
 
-   /* first bad stripe */
-   int faila;
+   /* bad stripes */
+   int fail[RAID_PARITY_MAX];
 
-   /* second bad stripe (for raid6 use) */
-   int failb;
+   /* number of bad stripes in fail[] */
+   int nr_fail;
 
/*
 * number of pages needed to represent the full
@@ -496,26 +495,6 @@ static void cache_rbio(struct btrfs_raid_bio *rbio)
 }
 
 /*
- * helper function to run the xor_blocks api.  It is only
- * able to do MAX_XOR_BLOCKS at a time, so we need to
- * loop through.
- */
-static void run_xor(void **pages, int src_cnt, ssize_t len)
-{
-   int src_off = 0;
-   int xor_src_cnt = 0;
-   void *dest = pages[src_cnt];
-
-   while(src_cnt > 0) {
-   xor_src_cnt = min(src_cnt, MAX_XOR_BLOCKS);
-   xor_blocks(xor_src_cnt, len, dest, pages + src_off);
-
-   src_cnt -= xor_src_cnt;
-   src_off += xor_src_cnt;
-   }
-}
-
-/*
  * returns true if the bio list inside this rbio
  * covers an entire stripe (no rmw required).
  * Must be called with the bio list lock held, or
@@ -587,25 +566,18 @@ static int rbio_can_merge(struct btrfs_raid_bio *last,
 }
 
 /*
- * helper to index into the pstripe
+ * helper to index into the parity stripe
+ * returns null if there is no stripe
  */
-static struct page *rbio_pstripe_page(struct btrfs_raid_bio *rbio, int index)
+static struct page *rbio_pstripe_page(struct btrfs_raid_bio *rbio,
+   int index, int parity)
 {
-   index += (rbio->nr_data * rbio->stripe_len) >> PAGE_CACHE_SHIFT;
-   return rbio->stripe_pages[index];
-}
-
-/*
- * helper to index into the qstripe, returns null
- * if there is no qstripe
- */
-static struct page *rbio_qstripe_page(struct btrfs_raid_bio *rbio, int index)
-{
-   if (rbio->nr_data + 1 == rbio->bbio->num_stripes)
+   if (rbio->nr_data + parity >= rbio->bbio->num_stripes)
return NULL;
 
-   index += ((rbio->nr_data + 1) * rbio->stripe_len) >>
-   PAGE_CACHE_SHIFT;
+   index += ((rbio->nr_data + parity) * rbio->stripe_len)
+   >> PAGE_CACHE_SHIFT;
+
return rbio->stripe_pages[index];
 }
 
@@ -946,8 +918,7 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_root 
*root,
rbio->fs_info = root->fs_info;
rbio->stripe_len = stripe_len;
rbio->nr_pages = num_pages;
-   rbio->faila = -1;
-   rbio->failb = -1;
+   rbio->nr_fail = 0;
atomic_set(&rbio->refs, 1);
 
/*
@@ -958,10 +929,10 @@ static struct btrfs_raid_bio *alloc_rbio(struct 
btrfs_root *root,
rbio->stripe_pages = p;
rbio->bio_pages = p + sizeof(struct page *) * num_pages;
 
-   if (raid_map[bbio->num_stripes - 1] == RAID6_Q_STRIPE)
-   nr_data = bbio->num_stripes - 2;
-   else
-   nr_data = bbio->num_stripes - 1;
+   /* get the number of data stripes removing all the parities */
+   nr_data = bbio->num_stripes;
+   while (nr_data > 0 && is_parity_stripe(raid_map[nr_data - 1]))
+   --nr_data;
 
rbio->nr_data = nr_data;
return rbio;
@@ -1072,8 +1043,7 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio,
  */
 static void validate_rbio_for_rmw(struct btrfs_raid_bio *rbio)
 {
-   if (rbio->faila >= 0 || rbio->failb >= 0) {
-   BUG_ON(rbio->faila == rbio->bbio->num_stripes - 1);
+   if (rbio->nr_fail > 0) {
__raid56_parity_recover(rbio);
} else {
finish_rmw(rbio);
@@ -1137,10 +1107,10 @@ static noinline void finish_rmw(struct btrfs_raid_bio 
*rbio)
void *pointers[bbio->num_stripes];
int stripe_l