aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs/ios.c
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2010-08-02 13:06:46 -0400
committerBoaz Harrosh <bharrosh@panasas.com>2010-08-04 06:17:58 -0400
commit5002dd18c5940ce63b917d84f2b852c3b96009bb (patch)
treedcba726c5e705c787c00f7fac67201a82e06191a /fs/exofs/ios.c
parent6e31609b1dcd595d7e4676ce62323532b29e8999 (diff)
exofs: Fix groups code when num_devices is not divisible by group_width
There is a bug when num_devices is not divisible by group_width * mirrors. We would not return to the proper device and offset when looping on to the next group. The fix makes code simpler actually. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs/exofs/ios.c')
-rw-r--r--fs/exofs/ios.c22
1 files changed, 5 insertions, 17 deletions
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
index 5bb47373c7e0..5a1960500c8a 100644
--- a/fs/exofs/ios.c
+++ b/fs/exofs/ios.c
@@ -305,8 +305,6 @@ int exofs_check_io(struct exofs_io_state *ios, u64 *resid)
305struct _striping_info { 305struct _striping_info {
306 u64 obj_offset; 306 u64 obj_offset;
307 u64 group_length; 307 u64 group_length;
308 u64 total_group_length;
309 u64 Major;
310 unsigned dev; 308 unsigned dev;
311 unsigned unit_off; 309 unsigned unit_off;
312}; 310};
@@ -343,8 +341,6 @@ static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset,
343 (M * group_depth * stripe_unit); 341 (M * group_depth * stripe_unit);
344 342
345 si->group_length = T - H; 343 si->group_length = T - H;
346 si->total_group_length = T;
347 si->Major = M;
348} 344}
349 345
350static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg, 346static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg,
@@ -450,17 +446,15 @@ out:
450static int _prepare_for_striping(struct exofs_io_state *ios) 446static int _prepare_for_striping(struct exofs_io_state *ios)
451{ 447{
452 u64 length = ios->length; 448 u64 length = ios->length;
449 u64 offset = ios->offset;
453 struct _striping_info si; 450 struct _striping_info si;
454 unsigned devs_in_group = ios->layout->group_width *
455 ios->layout->mirrors_p1;
456 int ret = 0; 451 int ret = 0;
457 452
458 _calc_stripe_info(ios, ios->offset, &si);
459
460 if (!ios->pages) { 453 if (!ios->pages) {
461 if (ios->kern_buff) { 454 if (ios->kern_buff) {
462 struct exofs_per_dev_state *per_dev = &ios->per_dev[0]; 455 struct exofs_per_dev_state *per_dev = &ios->per_dev[0];
463 456
457 _calc_stripe_info(ios, ios->offset, &si);
464 per_dev->offset = si.obj_offset; 458 per_dev->offset = si.obj_offset;
465 per_dev->dev = si.dev; 459 per_dev->dev = si.dev;
466 460
@@ -474,6 +468,8 @@ static int _prepare_for_striping(struct exofs_io_state *ios)
474 } 468 }
475 469
476 while (length) { 470 while (length) {
471 _calc_stripe_info(ios, offset, &si);
472
477 if (length < si.group_length) 473 if (length < si.group_length)
478 si.group_length = length; 474 si.group_length = length;
479 475
@@ -481,16 +477,8 @@ static int _prepare_for_striping(struct exofs_io_state *ios)
481 if (unlikely(ret)) 477 if (unlikely(ret))
482 goto out; 478 goto out;
483 479
480 offset += si.group_length;
484 length -= si.group_length; 481 length -= si.group_length;
485
486 si.group_length = si.total_group_length;
487 si.unit_off = 0;
488 ++si.Major;
489 si.obj_offset = si.Major * ios->layout->stripe_unit *
490 ios->layout->group_depth;
491
492 si.dev = (si.dev - (si.dev % devs_in_group)) + devs_in_group;
493 si.dev %= ios->layout->s_numdevs;
494 } 482 }
495 483
496out: 484out: