Commit b367e78bd1c7af4c018ce98b1f6d3e001aba895a

Authored by Boaz Harrosh
1 parent 96391e2bae

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>

Showing 1 changed file with 99 additions and 60 deletions Side-by-side Diff

... ... @@ -259,28 +259,46 @@
259 259 return acumulated_lin_err;
260 260 }
261 261  
262   -/* REMOVEME: After review
263   - Some quoteing from the standard
  262 +/*
  263 + * L - logical offset into the file
  264 + *
  265 + * U - The number of bytes in a full stripe
  266 + *
  267 + * U = stripe_unit * group_width
  268 + *
  269 + * N - The stripe number
  270 + *
  271 + * N = L / U
  272 + *
  273 + * C - The component index coresponding to L
  274 + *
  275 + * C = (L - (N*U)) / stripe_unit
  276 + *
  277 + * O - The component offset coresponding to L
  278 + *
  279 + * (N*stripe_unit)+(L%stripe_unit)
  280 + */
264 281  
265   - L = logical offset into the file
266   - W = number of data components in a stripe
267   - S = W * stripe_unit (S is Stripe length)
268   - N = L / S (N is the stripe Number)
269   - C = (L-(N*S)) / stripe_unit (C is the component)
270   - O = (N*stripe_unit)+(L%stripe_unit) (O is the object's offset)
271   -*/
  282 +struct _striping_info {
  283 + u64 obj_offset;
  284 + unsigned dev;
  285 + unsigned unit_off;
  286 +};
272 287  
273   -static void _offset_dev_unit_off(struct exofs_io_state *ios, u64 file_offset,
274   - u64 *obj_offset, unsigned *dev, unsigned *unit_off)
  288 +static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset,
  289 + struct _striping_info *si)
275 290 {
276   - unsigned stripe_unit = ios->layout->stripe_unit;
277   - unsigned stripe_length = stripe_unit * ios->layout->group_width;
278   - u64 stripe_no = file_offset;
279   - unsigned stripe_mod = do_div(stripe_no, stripe_length);
  291 + u32 stripe_unit = ios->layout->stripe_unit;
  292 + u32 group_width = ios->layout->group_width;
  293 + u32 U = stripe_unit * group_width;
280 294  
281   - *unit_off = stripe_mod % stripe_unit;
282   - *obj_offset = stripe_no * stripe_unit + *unit_off;
283   - *dev = stripe_mod / stripe_unit * ios->layout->mirrors_p1;
  295 + u32 LmodU;
  296 + u64 N = div_u64_rem(file_offset, U, &LmodU);
  297 +
  298 + si->unit_off = LmodU % stripe_unit;
  299 + si->obj_offset = N * stripe_unit + si->unit_off;
  300 + si->dev = LmodU / stripe_unit;
  301 + si->dev *= ios->layout->mirrors_p1;
284 302 }
285 303  
286 304 static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg,
287 305  
288 306  
289 307  
290 308  
291 309  
292 310  
293 311  
294 312  
295 313  
296 314  
297 315  
298 316  
... ... @@ -327,65 +345,88 @@
327 345 return 0;
328 346 }
329 347  
330   -static int _prepare_for_striping(struct exofs_io_state *ios)
  348 +static int _prepare_pages(struct exofs_io_state *ios,
  349 + struct _striping_info *si)
331 350 {
332 351 u64 length = ios->length;
333   - u64 offset = ios->offset;
334 352 unsigned stripe_unit = ios->layout->stripe_unit;
  353 + unsigned mirrors_p1 = ios->layout->mirrors_p1;
  354 + unsigned dev = si->dev;
335 355 unsigned comp = 0;
336 356 unsigned stripes = 0;
337 357 unsigned cur_pg = 0;
338 358 int ret = 0;
339 359  
340   - if (!ios->pages) {
341   - if (ios->kern_buff) {
342   - struct exofs_per_dev_state *per_dev = &ios->per_dev[0];
343   - unsigned unit_off;
344   -
345   - _offset_dev_unit_off(ios, offset, &per_dev->offset,
346   - &per_dev->dev, &unit_off);
347   - /* no cross device without page array */
348   - BUG_ON((ios->layout->group_width > 1) &&
349   - (unit_off + length > stripe_unit));
350   - }
351   - ios->numdevs = ios->layout->mirrors_p1;
352   - return 0;
353   - }
354   -
355 360 while (length) {
356 361 struct exofs_per_dev_state *per_dev = &ios->per_dev[comp];
357   - unsigned cur_len, page_off;
  362 + unsigned cur_len, page_off = 0;
358 363  
359 364 if (!per_dev->length) {
360   - unsigned unit_off;
  365 + per_dev->dev = dev;
  366 + if (dev < si->dev) {
  367 + per_dev->offset = si->obj_offset + stripe_unit -
  368 + si->unit_off;
  369 + cur_len = stripe_unit;
  370 + } else if (dev == si->dev) {
  371 + per_dev->offset = si->obj_offset;
  372 + cur_len = stripe_unit - si->unit_off;
  373 + page_off = si->unit_off & ~PAGE_MASK;
  374 + BUG_ON(page_off && (page_off != ios->pgbase));
  375 + } else { /* dev > si->dev */
  376 + per_dev->offset = si->obj_offset - si->unit_off;
  377 + cur_len = stripe_unit;
  378 + }
361 379  
362   - _offset_dev_unit_off(ios, offset, &per_dev->offset,
363   - &per_dev->dev, &unit_off);
364 380 stripes++;
365   - cur_len = min_t(u64, stripe_unit - unit_off, length);
366   - offset += cur_len;
367   - page_off = unit_off & ~PAGE_MASK;
368   - BUG_ON(page_off != ios->pgbase);
  381 +
  382 + dev += mirrors_p1;
  383 + dev %= ios->layout->s_numdevs;
369 384 } else {
370   - cur_len = min_t(u64, stripe_unit, length);
371   - page_off = 0;
  385 + cur_len = stripe_unit;
372 386 }
  387 + if (cur_len >= length)
  388 + cur_len = length;
373 389  
374 390 ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev,
375 391 cur_len);
376 392 if (unlikely(ret))
377 393 goto out;
378 394  
379   - comp += ios->layout->mirrors_p1;
  395 + comp += mirrors_p1;
380 396 comp %= ios->layout->s_numdevs;
381 397  
382 398 length -= cur_len;
383 399 }
384 400 out:
385   - ios->numdevs = stripes * ios->layout->mirrors_p1;
  401 + ios->numdevs = stripes * mirrors_p1;
386 402 return ret;
387 403 }
388 404  
  405 +static int _prepare_for_striping(struct exofs_io_state *ios)
  406 +{
  407 + struct _striping_info si;
  408 +
  409 + _calc_stripe_info(ios, ios->offset, &si);
  410 +
  411 + if (!ios->pages) {
  412 + if (ios->kern_buff) {
  413 + struct exofs_per_dev_state *per_dev = &ios->per_dev[0];
  414 +
  415 + per_dev->offset = si.obj_offset;
  416 + per_dev->dev = si.dev;
  417 +
  418 + /* no cross device without page array */
  419 + BUG_ON((ios->layout->group_width > 1) &&
  420 + (si.unit_off + ios->length >
  421 + ios->layout->stripe_unit));
  422 + }
  423 + ios->numdevs = ios->layout->mirrors_p1;
  424 + return 0;
  425 + }
  426 +
  427 + return _prepare_pages(ios, &si);
  428 +}
  429 +
389 430 int exofs_sbi_create(struct exofs_io_state *ios)
390 431 {
391 432 int i, ret;
... ... @@ -648,9 +689,7 @@
648 689 struct osd_attr attr;
649 690 __be64 newsize;
650 691 } *size_attrs;
651   - u64 this_obj_size;
652   - unsigned dev;
653   - unsigned unit_off;
  692 + struct _striping_info si;
654 693 int i, ret;
655 694  
656 695 ret = exofs_get_io_state(&sbi->layout, &ios);
657 696  
... ... @@ -668,19 +707,19 @@
668 707 ios->cred = oi->i_cred;
669 708  
670 709 ios->numdevs = ios->layout->s_numdevs;
671   - _offset_dev_unit_off(ios, size, &this_obj_size, &dev, &unit_off);
  710 + _calc_stripe_info(ios, size, &si);
672 711  
673 712 for (i = 0; i < ios->layout->group_width; ++i) {
674 713 struct exofs_trunc_attr *size_attr = &size_attrs[i];
675 714 u64 obj_size;
676 715  
677   - if (i < dev)
678   - obj_size = this_obj_size +
679   - ios->layout->stripe_unit - unit_off;
680   - else if (i == dev)
681   - obj_size = this_obj_size;
682   - else /* i > dev */
683   - obj_size = this_obj_size - unit_off;
  716 + if (i < si.dev)
  717 + obj_size = si.obj_offset +
  718 + ios->layout->stripe_unit - si.unit_off;
  719 + else if (i == si.dev)
  720 + obj_size = si.obj_offset;
  721 + else /* i > si.dev */
  722 + obj_size = si.obj_offset - si.unit_off;
684 723  
685 724 size_attr->newsize = cpu_to_be64(obj_size);
686 725 size_attr->attr = g_attr_logical_length;