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: Boaz Harrosh <bharrosh@panasas.com>
This commit is contained in:
155
fs/exofs/ios.c
155
fs/exofs/ios.c
@@ -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
|
||||||
|
*
|
||||||
|
* U - The number of bytes in a full stripe
|
||||||
|
*
|
||||||
|
* U = stripe_unit * group_width
|
||||||
|
*
|
||||||
|
* N - The stripe number
|
||||||
|
*
|
||||||
|
* N = L / U
|
||||||
|
*
|
||||||
|
* C - The component index coresponding to L
|
||||||
|
*
|
||||||
|
* C = (L - (N*U)) / stripe_unit
|
||||||
|
*
|
||||||
|
* O - The component offset coresponding to L
|
||||||
|
*
|
||||||
|
* (N*stripe_unit)+(L%stripe_unit)
|
||||||
|
*/
|
||||||
|
|
||||||
L = logical offset into the file
|
struct _striping_info {
|
||||||
W = number of data components in a stripe
|
u64 obj_offset;
|
||||||
S = W * stripe_unit (S is Stripe length)
|
unsigned dev;
|
||||||
N = L / S (N is the stripe Number)
|
unsigned unit_off;
|
||||||
C = (L-(N*S)) / stripe_unit (C is the component)
|
};
|
||||||
O = (N*stripe_unit)+(L%stripe_unit) (O is the object's offset)
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void _offset_dev_unit_off(struct exofs_io_state *ios, u64 file_offset,
|
static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset,
|
||||||
u64 *obj_offset, unsigned *dev, unsigned *unit_off)
|
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);
|
|
||||||
|
|
||||||
*unit_off = stripe_mod % stripe_unit;
|
u32 LmodU;
|
||||||
*obj_offset = stripe_no * stripe_unit + *unit_off;
|
u64 N = div_u64_rem(file_offset, U, &LmodU);
|
||||||
*dev = stripe_mod / stripe_unit * ios->layout->mirrors_p1;
|
|
||||||
|
si->unit_off = LmodU % stripe_unit;
|
||||||
|
si->obj_offset = N * stripe_unit + si->unit_off;
|
||||||
|
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user