diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2010-08-02 13:06:46 -0400 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2010-08-04 06:17:58 -0400 |
commit | 5002dd18c5940ce63b917d84f2b852c3b96009bb (patch) | |
tree | dcba726c5e705c787c00f7fac67201a82e06191a /fs/exofs | |
parent | 6e31609b1dcd595d7e4676ce62323532b29e8999 (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')
-rw-r--r-- | fs/exofs/ios.c | 22 |
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) | |||
305 | struct _striping_info { | 305 | struct _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 | ||
350 | static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg, | 346 | static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg, |
@@ -450,17 +446,15 @@ out: | |||
450 | static int _prepare_for_striping(struct exofs_io_state *ios) | 446 | static 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 | ||
496 | out: | 484 | out: |