aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/exofs/ios.c159
1 files changed, 99 insertions, 60 deletions
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
index 263052c77f41..d28febdf54ab 100644
--- a/fs/exofs/ios.c
+++ b/fs/exofs/ios.c
@@ -259,28 +259,46 @@ int exofs_check_io(struct exofs_io_state *ios, u64 *resid)
259 return acumulated_lin_err; 259 return acumulated_lin_err;
260} 260}
261 261
262/* REMOVEME: After review 262/*
263 Some quoteing from the standard 263 * L - logical offset into the file
264 264 *
265 L = logical offset into the file 265 * U - The number of bytes in a full stripe
266 W = number of data components in a stripe 266 *
267 S = W * stripe_unit (S is Stripe length) 267 * U = stripe_unit * group_width
268 N = L / S (N is the stripe Number) 268 *
269 C = (L-(N*S)) / stripe_unit (C is the component) 269 * N - The stripe number
270 O = (N*stripe_unit)+(L%stripe_unit) (O is the object's offset) 270 *
271*/ 271 * N = L / U
272 272 *
273static void _offset_dev_unit_off(struct exofs_io_state *ios, u64 file_offset, 273 * C - The component index coresponding to L
274 u64 *obj_offset, unsigned *dev, unsigned *unit_off) 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 */
281
282struct _striping_info {
283 u64 obj_offset;
284 unsigned dev;
285 unsigned unit_off;
286};
287
288static 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; 291 u32 stripe_unit = ios->layout->stripe_unit;
277 unsigned stripe_length = stripe_unit * ios->layout->group_width; 292 u32 group_width = ios->layout->group_width;
278 u64 stripe_no = file_offset; 293 u32 U = stripe_unit * group_width;
279 unsigned stripe_mod = do_div(stripe_no, stripe_length); 294
295 u32 LmodU;
296 u64 N = div_u64_rem(file_offset, U, &LmodU);
280 297
281 *unit_off = stripe_mod % stripe_unit; 298 si->unit_off = LmodU % stripe_unit;
282 *obj_offset = stripe_no * stripe_unit + *unit_off; 299 si->obj_offset = N * stripe_unit + si->unit_off;
283 *dev = stripe_mod / stripe_unit * ios->layout->mirrors_p1; 300 si->dev = LmodU / stripe_unit;
301 si->dev *= ios->layout->mirrors_p1;
284} 302}
285 303
286static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg, 304static 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 return 0; 345 return 0;
328} 346}
329 347
330static int _prepare_for_striping(struct exofs_io_state *ios) 348static int _prepare_pages(struct exofs_io_state *ios,
349 struct _striping_info *si)
331{ 350{
332 u64 length = ios->length; 351 u64 length = ios->length;
333 u64 offset = ios->offset;
334 unsigned stripe_unit = ios->layout->stripe_unit; 352 unsigned stripe_unit = ios->layout->stripe_unit;
353 unsigned mirrors_p1 = ios->layout->mirrors_p1;
354 unsigned dev = si->dev;
335 unsigned comp = 0; 355 unsigned comp = 0;
336 unsigned stripes = 0; 356 unsigned stripes = 0;
337 unsigned cur_pg = 0; 357 unsigned cur_pg = 0;
338 int ret = 0; 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 while (length) { 360 while (length) {
356 struct exofs_per_dev_state *per_dev = &ios->per_dev[comp]; 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 if (!per_dev->length) { 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 stripes++; 380 stripes++;
365 cur_len = min_t(u64, stripe_unit - unit_off, length); 381
366 offset += cur_len; 382 dev += mirrors_p1;
367 page_off = unit_off & ~PAGE_MASK; 383 dev %= ios->layout->s_numdevs;
368 BUG_ON(page_off != ios->pgbase);
369 } else { 384 } else {
370 cur_len = min_t(u64, stripe_unit, length); 385 cur_len = stripe_unit;
371 page_off = 0;
372 } 386 }
387 if (cur_len >= length)
388 cur_len = length;
373 389
374 ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev, 390 ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev,
375 cur_len); 391 cur_len);
376 if (unlikely(ret)) 392 if (unlikely(ret))
377 goto out; 393 goto out;
378 394
379 comp += ios->layout->mirrors_p1; 395 comp += mirrors_p1;
380 comp %= ios->layout->s_numdevs; 396 comp %= ios->layout->s_numdevs;
381 397
382 length -= cur_len; 398 length -= cur_len;
383 } 399 }
384out: 400out:
385 ios->numdevs = stripes * ios->layout->mirrors_p1; 401 ios->numdevs = stripes * mirrors_p1;
386 return ret; 402 return ret;
387} 403}
388 404
405static 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
389int exofs_sbi_create(struct exofs_io_state *ios) 430int exofs_sbi_create(struct exofs_io_state *ios)
390{ 431{
391 int i, ret; 432 int i, ret;
@@ -648,9 +689,7 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
648 struct osd_attr attr; 689 struct osd_attr attr;
649 __be64 newsize; 690 __be64 newsize;
650 } *size_attrs; 691 } *size_attrs;
651 u64 this_obj_size; 692 struct _striping_info si;
652 unsigned dev;
653 unsigned unit_off;
654 int i, ret; 693 int i, ret;
655 694
656 ret = exofs_get_io_state(&sbi->layout, &ios); 695 ret = exofs_get_io_state(&sbi->layout, &ios);
@@ -668,19 +707,19 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
668 ios->cred = oi->i_cred; 707 ios->cred = oi->i_cred;
669 708
670 ios->numdevs = ios->layout->s_numdevs; 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 for (i = 0; i < ios->layout->group_width; ++i) { 712 for (i = 0; i < ios->layout->group_width; ++i) {
674 struct exofs_trunc_attr *size_attr = &size_attrs[i]; 713 struct exofs_trunc_attr *size_attr = &size_attrs[i];
675 u64 obj_size; 714 u64 obj_size;
676 715
677 if (i < dev) 716 if (i < si.dev)
678 obj_size = this_obj_size + 717 obj_size = si.obj_offset +
679 ios->layout->stripe_unit - unit_off; 718 ios->layout->stripe_unit - si.unit_off;
680 else if (i == dev) 719 else if (i == si.dev)
681 obj_size = this_obj_size; 720 obj_size = si.obj_offset;
682 else /* i > dev */ 721 else /* i > si.dev */
683 obj_size = this_obj_size - unit_off; 722 obj_size = si.obj_offset - si.unit_off;
684 723
685 size_attr->newsize = cpu_to_be64(obj_size); 724 size_attr->newsize = cpu_to_be64(obj_size);
686 size_attr->attr = g_attr_logical_length; 725 size_attr->attr = g_attr_logical_length;