Commit b367e78b authored by Boaz Harrosh's avatar Boaz Harrosh

exofs: Prepare for groups

* Rename _offset_dev_unit_off() to _calc_stripe_info()
  and recieve a struct for the output params

* In _prepare_for_striping we only need to call
  _calc_stripe_info() once. The other componets
  are easy to calculate from that. This code
  was inspired by what's done in truncate.

* Some code shifts that make sense now but will make
  more sense when group support is added.
Signed-off-by: default avatarBoaz Harrosh <bharrosh@panasas.com>
parent 96391e2b
...@@ -259,28 +259,46 @@ int exofs_check_io(struct exofs_io_state *ios, u64 *resid) ...@@ -259,28 +259,46 @@ int exofs_check_io(struct exofs_io_state *ios, u64 *resid)
return acumulated_lin_err; return acumulated_lin_err;
} }
/* REMOVEME: After review /*
Some quoteing from the standard * L - logical offset into the file
*
L = logical offset into the file * U - The number of bytes in a full stripe
W = number of data components in a stripe *
S = W * stripe_unit (S is Stripe length) * U = stripe_unit * group_width
N = L / S (N is the stripe Number) *
C = (L-(N*S)) / stripe_unit (C is the component) * N - The stripe number
O = (N*stripe_unit)+(L%stripe_unit) (O is the object's offset) *
*/ * N = L / U
*
static void _offset_dev_unit_off(struct exofs_io_state *ios, u64 file_offset, * C - The component index coresponding to L
u64 *obj_offset, unsigned *dev, unsigned *unit_off) *
* C = (L - (N*U)) / stripe_unit
*
* O - The component offset coresponding to L
*
* (N*stripe_unit)+(L%stripe_unit)
*/
struct _striping_info {
u64 obj_offset;
unsigned dev;
unsigned unit_off;
};
static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset,
struct _striping_info *si)
{ {
unsigned stripe_unit = ios->layout->stripe_unit; u32 stripe_unit = ios->layout->stripe_unit;
unsigned stripe_length = stripe_unit * ios->layout->group_width; u32 group_width = ios->layout->group_width;
u64 stripe_no = file_offset; u32 U = stripe_unit * group_width;
unsigned stripe_mod = do_div(stripe_no, stripe_length);
u32 LmodU;
u64 N = div_u64_rem(file_offset, U, &LmodU);
*unit_off = stripe_mod % stripe_unit; si->unit_off = LmodU % stripe_unit;
*obj_offset = stripe_no * stripe_unit + *unit_off; si->obj_offset = N * stripe_unit + si->unit_off;
*dev = stripe_mod / stripe_unit * ios->layout->mirrors_p1; si->dev = LmodU / stripe_unit;
si->dev *= ios->layout->mirrors_p1;
} }
static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg, static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg,
...@@ -327,65 +345,88 @@ static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg, ...@@ -327,65 +345,88 @@ static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg,
return 0; return 0;
} }
static int _prepare_for_striping(struct exofs_io_state *ios) static int _prepare_pages(struct exofs_io_state *ios,
struct _striping_info *si)
{ {
u64 length = ios->length; u64 length = ios->length;
u64 offset = ios->offset;
unsigned stripe_unit = ios->layout->stripe_unit; unsigned stripe_unit = ios->layout->stripe_unit;
unsigned mirrors_p1 = ios->layout->mirrors_p1;
unsigned dev = si->dev;
unsigned comp = 0; unsigned comp = 0;
unsigned stripes = 0; unsigned stripes = 0;
unsigned cur_pg = 0; unsigned cur_pg = 0;
int ret = 0; int ret = 0;
if (!ios->pages) {
if (ios->kern_buff) {
struct exofs_per_dev_state *per_dev = &ios->per_dev[0];
unsigned unit_off;
_offset_dev_unit_off(ios, offset, &per_dev->offset,
&per_dev->dev, &unit_off);
/* no cross device without page array */
BUG_ON((ios->layout->group_width > 1) &&
(unit_off + length > stripe_unit));
}
ios->numdevs = ios->layout->mirrors_p1;
return 0;
}
while (length) { while (length) {
struct exofs_per_dev_state *per_dev = &ios->per_dev[comp]; struct exofs_per_dev_state *per_dev = &ios->per_dev[comp];
unsigned cur_len, page_off; unsigned cur_len, page_off = 0;
if (!per_dev->length) { if (!per_dev->length) {
unsigned unit_off; per_dev->dev = dev;
if (dev < si->dev) {
per_dev->offset = si->obj_offset + stripe_unit -
si->unit_off;
cur_len = stripe_unit;
} else if (dev == si->dev) {
per_dev->offset = si->obj_offset;
cur_len = stripe_unit - si->unit_off;
page_off = si->unit_off & ~PAGE_MASK;
BUG_ON(page_off && (page_off != ios->pgbase));
} else { /* dev > si->dev */
per_dev->offset = si->obj_offset - si->unit_off;
cur_len = stripe_unit;
}
_offset_dev_unit_off(ios, offset, &per_dev->offset,
&per_dev->dev, &unit_off);
stripes++; stripes++;
cur_len = min_t(u64, stripe_unit - unit_off, length);
offset += cur_len; dev += mirrors_p1;
page_off = unit_off & ~PAGE_MASK; dev %= ios->layout->s_numdevs;
BUG_ON(page_off != ios->pgbase);
} else { } else {
cur_len = min_t(u64, stripe_unit, length); cur_len = stripe_unit;
page_off = 0;
} }
if (cur_len >= length)
cur_len = length;
ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev, ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev,
cur_len); cur_len);
if (unlikely(ret)) if (unlikely(ret))
goto out; goto out;
comp += ios->layout->mirrors_p1; comp += mirrors_p1;
comp %= ios->layout->s_numdevs; comp %= ios->layout->s_numdevs;
length -= cur_len; length -= cur_len;
} }
out: out:
ios->numdevs = stripes * ios->layout->mirrors_p1; ios->numdevs = stripes * mirrors_p1;
return ret; return ret;
} }
static int _prepare_for_striping(struct exofs_io_state *ios)
{
struct _striping_info si;
_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];
per_dev->offset = si.obj_offset;
per_dev->dev = si.dev;
/* no cross device without page array */
BUG_ON((ios->layout->group_width > 1) &&
(si.unit_off + ios->length >
ios->layout->stripe_unit));
}
ios->numdevs = ios->layout->mirrors_p1;
return 0;
}
return _prepare_pages(ios, &si);
}
int exofs_sbi_create(struct exofs_io_state *ios) int exofs_sbi_create(struct exofs_io_state *ios)
{ {
int i, ret; int i, ret;
...@@ -648,9 +689,7 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size) ...@@ -648,9 +689,7 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
struct osd_attr attr; struct osd_attr attr;
__be64 newsize; __be64 newsize;
} *size_attrs; } *size_attrs;
u64 this_obj_size; struct _striping_info si;
unsigned dev;
unsigned unit_off;
int i, ret; int i, ret;
ret = exofs_get_io_state(&sbi->layout, &ios); ret = exofs_get_io_state(&sbi->layout, &ios);
...@@ -668,19 +707,19 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size) ...@@ -668,19 +707,19 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
ios->cred = oi->i_cred; ios->cred = oi->i_cred;
ios->numdevs = ios->layout->s_numdevs; ios->numdevs = ios->layout->s_numdevs;
_offset_dev_unit_off(ios, size, &this_obj_size, &dev, &unit_off); _calc_stripe_info(ios, size, &si);
for (i = 0; i < ios->layout->group_width; ++i) { for (i = 0; i < ios->layout->group_width; ++i) {
struct exofs_trunc_attr *size_attr = &size_attrs[i]; struct exofs_trunc_attr *size_attr = &size_attrs[i];
u64 obj_size; u64 obj_size;
if (i < dev) if (i < si.dev)
obj_size = this_obj_size + obj_size = si.obj_offset +
ios->layout->stripe_unit - unit_off; ios->layout->stripe_unit - si.unit_off;
else if (i == dev) else if (i == si.dev)
obj_size = this_obj_size; obj_size = si.obj_offset;
else /* i > dev */ else /* i > si.dev */
obj_size = this_obj_size - unit_off; obj_size = si.obj_offset - si.unit_off;
size_attr->newsize = cpu_to_be64(obj_size); size_attr->newsize = cpu_to_be64(obj_size);
size_attr->attr = g_attr_logical_length; size_attr->attr = g_attr_logical_length;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment