aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/exofs/ios.c73
1 files changed, 53 insertions, 20 deletions
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
index f74a2ec027a6..fbb47ba2cd71 100644
--- a/fs/exofs/ios.c
+++ b/fs/exofs/ios.c
@@ -305,20 +305,21 @@ int exofs_check_io(struct exofs_io_state *ios, u64 *resid)
305struct _striping_info { 305struct _striping_info {
306 u64 obj_offset; 306 u64 obj_offset;
307 u64 group_length; 307 u64 group_length;
308 u64 M; /* for truncate */
308 unsigned dev; 309 unsigned dev;
309 unsigned unit_off; 310 unsigned unit_off;
310}; 311};
311 312
312static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset, 313static void _calc_stripe_info(struct exofs_layout *layout, u64 file_offset,
313 struct _striping_info *si) 314 struct _striping_info *si)
314{ 315{
315 u32 stripe_unit = ios->layout->stripe_unit; 316 u32 stripe_unit = layout->stripe_unit;
316 u32 group_width = ios->layout->group_width; 317 u32 group_width = layout->group_width;
317 u64 group_depth = ios->layout->group_depth; 318 u64 group_depth = layout->group_depth;
318 319
319 u32 U = stripe_unit * group_width; 320 u32 U = stripe_unit * group_width;
320 u64 T = U * group_depth; 321 u64 T = U * group_depth;
321 u64 S = T * ios->layout->group_count; 322 u64 S = T * layout->group_count;
322 u64 M = div64_u64(file_offset, S); 323 u64 M = div64_u64(file_offset, S);
323 324
324 /* 325 /*
@@ -333,7 +334,7 @@ static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset,
333 334
334 /* "H - (N * U)" is just "H % U" so it's bound to u32 */ 335 /* "H - (N * U)" is just "H % U" so it's bound to u32 */
335 si->dev = (u32)(H - (N * U)) / stripe_unit + G * group_width; 336 si->dev = (u32)(H - (N * U)) / stripe_unit + G * group_width;
336 si->dev *= ios->layout->mirrors_p1; 337 si->dev *= layout->mirrors_p1;
337 338
338 div_u64_rem(file_offset, stripe_unit, &si->unit_off); 339 div_u64_rem(file_offset, stripe_unit, &si->unit_off);
339 340
@@ -341,6 +342,7 @@ static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset,
341 (M * group_depth * stripe_unit); 342 (M * group_depth * stripe_unit);
342 343
343 si->group_length = T - H; 344 si->group_length = T - H;
345 si->M = M;
344} 346}
345 347
346static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg, 348static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg,
@@ -454,7 +456,7 @@ static int _prepare_for_striping(struct exofs_io_state *ios)
454 if (ios->kern_buff) { 456 if (ios->kern_buff) {
455 struct exofs_per_dev_state *per_dev = &ios->per_dev[0]; 457 struct exofs_per_dev_state *per_dev = &ios->per_dev[0];
456 458
457 _calc_stripe_info(ios, ios->offset, &si); 459 _calc_stripe_info(ios->layout, ios->offset, &si);
458 per_dev->offset = si.obj_offset; 460 per_dev->offset = si.obj_offset;
459 per_dev->dev = si.dev; 461 per_dev->dev = si.dev;
460 462
@@ -468,7 +470,7 @@ static int _prepare_for_striping(struct exofs_io_state *ios)
468 } 470 }
469 471
470 while (length) { 472 while (length) {
471 _calc_stripe_info(ios, offset, &si); 473 _calc_stripe_info(ios->layout, offset, &si);
472 474
473 if (length < si.group_length) 475 if (length < si.group_length)
474 si.group_length = length; 476 si.group_length = length;
@@ -745,6 +747,31 @@ static int _truncate_mirrors(struct exofs_io_state *ios, unsigned cur_comp,
745 return 0; 747 return 0;
746} 748}
747 749
750struct _trunc_info {
751 struct _striping_info si;
752 u64 prev_group_obj_off;
753 u64 next_group_obj_off;
754
755 unsigned first_group_dev;
756 unsigned nex_group_dev;
757 unsigned max_devs;
758};
759
760void _calc_trunk_info(struct exofs_layout *layout, u64 file_offset,
761 struct _trunc_info *ti)
762{
763 unsigned stripe_unit = layout->stripe_unit;
764
765 _calc_stripe_info(layout, file_offset, &ti->si);
766
767 ti->prev_group_obj_off = ti->si.M * stripe_unit;
768 ti->next_group_obj_off = ti->si.M ? (ti->si.M - 1) * stripe_unit : 0;
769
770 ti->first_group_dev = ti->si.dev - (ti->si.dev % layout->group_width);
771 ti->nex_group_dev = ti->first_group_dev + layout->group_width;
772 ti->max_devs = layout->group_width * layout->group_count;
773}
774
748int exofs_oi_truncate(struct exofs_i_info *oi, u64 size) 775int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
749{ 776{
750 struct exofs_sb_info *sbi = oi->vfs_inode.i_sb->s_fs_info; 777 struct exofs_sb_info *sbi = oi->vfs_inode.i_sb->s_fs_info;
@@ -753,14 +780,16 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
753 struct osd_attr attr; 780 struct osd_attr attr;
754 __be64 newsize; 781 __be64 newsize;
755 } *size_attrs; 782 } *size_attrs;
756 struct _striping_info si; 783 struct _trunc_info ti;
757 int i, ret; 784 int i, ret;
758 785
759 ret = exofs_get_io_state(&sbi->layout, &ios); 786 ret = exofs_get_io_state(&sbi->layout, &ios);
760 if (unlikely(ret)) 787 if (unlikely(ret))
761 return ret; 788 return ret;
762 789
763 size_attrs = kcalloc(ios->layout->group_width, sizeof(*size_attrs), 790 _calc_trunk_info(ios->layout, size, &ti);
791
792 size_attrs = kcalloc(ti.max_devs, sizeof(*size_attrs),
764 GFP_KERNEL); 793 GFP_KERNEL);
765 if (unlikely(!size_attrs)) { 794 if (unlikely(!size_attrs)) {
766 ret = -ENOMEM; 795 ret = -ENOMEM;
@@ -769,26 +798,30 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
769 798
770 ios->obj.id = exofs_oi_objno(oi); 799 ios->obj.id = exofs_oi_objno(oi);
771 ios->cred = oi->i_cred; 800 ios->cred = oi->i_cred;
772
773 ios->numdevs = ios->layout->s_numdevs; 801 ios->numdevs = ios->layout->s_numdevs;
774 _calc_stripe_info(ios, size, &si);
775 802
776 for (i = 0; i < ios->layout->group_width; ++i) { 803 for (i = 0; i < ti.max_devs; ++i) {
777 struct exofs_trunc_attr *size_attr = &size_attrs[i]; 804 struct exofs_trunc_attr *size_attr = &size_attrs[i];
778 u64 obj_size; 805 u64 obj_size;
779 806
780 if (i < si.dev) 807 if (i < ti.first_group_dev)
781 obj_size = si.obj_offset + 808 obj_size = ti.prev_group_obj_off;
782 ios->layout->stripe_unit - si.unit_off; 809 else if (i >= ti.nex_group_dev)
783 else if (i == si.dev) 810 obj_size = ti.next_group_obj_off;
784 obj_size = si.obj_offset; 811 else if (i < ti.si.dev) /* dev within this group */
785 else /* i > si.dev */ 812 obj_size = ti.si.obj_offset +
786 obj_size = si.obj_offset - si.unit_off; 813 ios->layout->stripe_unit - ti.si.unit_off;
814 else if (i == ti.si.dev)
815 obj_size = ti.si.obj_offset;
816 else /* i > ti.dev */
817 obj_size = ti.si.obj_offset - ti.si.unit_off;
787 818
788 size_attr->newsize = cpu_to_be64(obj_size); 819 size_attr->newsize = cpu_to_be64(obj_size);
789 size_attr->attr = g_attr_logical_length; 820 size_attr->attr = g_attr_logical_length;
790 size_attr->attr.val_ptr = &size_attr->newsize; 821 size_attr->attr.val_ptr = &size_attr->newsize;
791 822
823 EXOFS_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n",
824 _LLU(ios->obj.id), _LLU(obj_size), i);
792 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1, 825 ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
793 &size_attr->attr); 826 &size_attr->attr);
794 if (unlikely(ret)) 827 if (unlikely(ret))