Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ore: fix BUG_ON, too few sgs when reading

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>

+6 -2
+1 -1
fs/exofs/ore.c
··· 266 266 267 267 /* first/last seg is split */ 268 268 num_raid_units += layout->group_width; 269 - sgs_per_dev = div_u64(num_raid_units, data_devs); 269 + sgs_per_dev = div_u64(num_raid_units, data_devs) + 2; 270 270 } else { 271 271 /* For Writes add parity pages array. */ 272 272 max_par_pages = num_raid_units * pages_in_unit *
+5 -1
fs/exofs/ore_raid.c
··· 551 551 unsigned cur_len) 552 552 { 553 553 if (ios->reading) { 554 - BUG_ON(per_dev->cur_sg >= ios->sgs_per_dev); 554 + if (per_dev->cur_sg >= ios->sgs_per_dev) { 555 + ORE_DBGMSG("cur_sg(%d) >= sgs_per_dev(%d)\n" , 556 + per_dev->cur_sg, ios->sgs_per_dev); 557 + return -ENOMEM; 558 + } 555 559 _ore_add_sg_seg(per_dev, cur_len, true); 556 560 } else { 557 561 struct __stripe_pages_2d *sp2d = ios->sp2d;