Commit b367e78bd1c7af4c018ce98b1f6d3e001aba895a
1 parent
96391e2bae
Exists in
master
and in
7 other branches
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
fs/exofs/ios.c
... | ... | @@ -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; |