diff options
author | Boaz Harrosh <bharrosh@panasas.com> | 2010-08-02 20:06:46 +0300 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2010-08-04 13:17:58 +0300 |
commit | 5002dd18c5940ce63b917d84f2b852c3b96009bb (patch) | |
tree | dcba726c5e705c787c00f7fac67201a82e06191a | |
parent | 6e31609b1dcd595d7e4676ce62323532b29e8999 (diff) | |
download | op-kernel-dev-5002dd18c5940ce63b917d84f2b852c3b96009bb.zip op-kernel-dev-5002dd18c5940ce63b917d84f2b852c3b96009bb.tar.gz |
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>
-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 5bb4737..5a19605 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) struct _striping_info { u64 obj_offset; u64 group_length; - u64 total_group_length; - u64 Major; unsigned dev; unsigned unit_off; }; @@ -343,8 +341,6 @@ static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset, (M * group_depth * stripe_unit); si->group_length = T - H; - si->total_group_length = T; - si->Major = M; } static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg, @@ -450,17 +446,15 @@ out: static int _prepare_for_striping(struct exofs_io_state *ios) { u64 length = ios->length; + u64 offset = ios->offset; struct _striping_info si; - unsigned devs_in_group = ios->layout->group_width * - ios->layout->mirrors_p1; int ret = 0; - _calc_stripe_info(ios, ios->offset, &si); - if (!ios->pages) { if (ios->kern_buff) { struct exofs_per_dev_state *per_dev = &ios->per_dev[0]; + _calc_stripe_info(ios, ios->offset, &si); per_dev->offset = si.obj_offset; per_dev->dev = si.dev; @@ -474,6 +468,8 @@ static int _prepare_for_striping(struct exofs_io_state *ios) } while (length) { + _calc_stripe_info(ios, offset, &si); + if (length < si.group_length) si.group_length = length; @@ -481,16 +477,8 @@ static int _prepare_for_striping(struct exofs_io_state *ios) if (unlikely(ret)) goto out; + offset += si.group_length; length -= si.group_length; - - si.group_length = si.total_group_length; - si.unit_off = 0; - ++si.Major; - si.obj_offset = si.Major * ios->layout->stripe_unit * - ios->layout->group_depth; - - si.dev = (si.dev - (si.dev % devs_in_group)) + devs_in_group; - si.dev %= ios->layout->s_numdevs; } out: |