ore: fix BUG_ON, too few sgs when reading
authorBoaz Harrosh <bharrosh@panasas.com>
Wed, 28 Dec 2011 17:14:23 +0000 (19:14 +0200)
committerBoaz Harrosh <bharrosh@panasas.com>
Fri, 6 Jan 2012 14:49:07 +0000 (16:49 +0200)
When reading RAID5 files, in rare cases, we calculated too
few sg segments. There should be two extra for the beginning
and end partial units.

Also "too few sg segments" should not be a BUG_ON there is
all the mechanics in place to handle it, as a short read.
So just return -ENOMEM and the rest of the code will gracefully
split the IO.

[Bug in 3.2.0 Kernel]
CC: Stable Tree <stable@kernel.org>
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
fs/exofs/ore.c
fs/exofs/ore_raid.c

index 894f3e192e6b50190636c34a4dc216af143c56de..49cf230554a21d33785d16367d9397ab34a44d91 100644 (file)
@@ -266,7 +266,7 @@ int  ore_get_rw_state(struct ore_layout *layout, struct ore_components *oc,
 
                        /* first/last seg is split */
                        num_raid_units += layout->group_width;
-                       sgs_per_dev = div_u64(num_raid_units, data_devs);
+                       sgs_per_dev = div_u64(num_raid_units, data_devs) + 2;
                } else {
                        /* For Writes add parity pages array. */
                        max_par_pages = num_raid_units * pages_in_unit *
index 29c47e5c4a86888a5dfae3e98a76f83849ce9c6f..414a2dfd9500dc74e719e87ff989800684708297 100644 (file)
@@ -551,7 +551,11 @@ int _ore_add_parity_unit(struct ore_io_state *ios,
                            unsigned cur_len)
 {
        if (ios->reading) {
-               BUG_ON(per_dev->cur_sg >= ios->sgs_per_dev);
+               if (per_dev->cur_sg >= ios->sgs_per_dev) {
+                       ORE_DBGMSG("cur_sg(%d) >= sgs_per_dev(%d)\n" ,
+                               per_dev->cur_sg, ios->sgs_per_dev);
+                       return -ENOMEM;
+               }
                _ore_add_sg_seg(per_dev, cur_len, true);
        } else {
                struct __stripe_pages_2d *sp2d = ios->sp2d;