@@ -305,20 +305,21 @@ int exofs_check_io(struct exofs_io_state *ios, u64 *resid)
305
305
struct _striping_info {
306
306
u64 obj_offset ;
307
307
u64 group_length ;
308
+ u64 M ; /* for truncate */
308
309
unsigned dev ;
309
310
unsigned unit_off ;
310
311
};
311
312
312
- static void _calc_stripe_info (struct exofs_io_state * ios , u64 file_offset ,
313
+ static void _calc_stripe_info (struct exofs_layout * layout , u64 file_offset ,
313
314
struct _striping_info * si )
314
315
{
315
- u32 stripe_unit = ios -> layout -> stripe_unit ;
316
- u32 group_width = ios -> layout -> group_width ;
317
- u64 group_depth = ios -> layout -> group_depth ;
316
+ u32 stripe_unit = layout -> stripe_unit ;
317
+ u32 group_width = layout -> group_width ;
318
+ u64 group_depth = layout -> group_depth ;
318
319
319
320
u32 U = stripe_unit * group_width ;
320
321
u64 T = U * group_depth ;
321
- u64 S = T * ios -> layout -> group_count ;
322
+ u64 S = T * layout -> group_count ;
322
323
u64 M = div64_u64 (file_offset , S );
323
324
324
325
/*
@@ -333,14 +334,15 @@ static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset,
333
334
334
335
/* "H - (N * U)" is just "H % U" so it's bound to u32 */
335
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
339
div_u64_rem (file_offset , stripe_unit , & si -> unit_off );
339
340
340
341
si -> obj_offset = si -> unit_off + (N * stripe_unit ) +
341
342
(M * group_depth * stripe_unit );
342
343
343
344
si -> group_length = T - H ;
345
+ si -> M = M ;
344
346
}
345
347
346
348
static 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
456
if (ios -> kern_buff ) {
455
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
460
per_dev -> offset = si .obj_offset ;
459
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
472
while (length ) {
471
- _calc_stripe_info (ios , offset , & si );
473
+ _calc_stripe_info (ios -> layout , offset , & si );
472
474
473
475
if (length < si .group_length )
474
476
si .group_length = length ;
@@ -745,6 +747,31 @@ static int _truncate_mirrors(struct exofs_io_state *ios, unsigned cur_comp,
745
747
return 0 ;
746
748
}
747
749
750
+ struct _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
+
760
+ void _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
+
748
775
int exofs_oi_truncate (struct exofs_i_info * oi , u64 size )
749
776
{
750
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
780
struct osd_attr attr ;
754
781
__be64 newsize ;
755
782
} * size_attrs ;
756
- struct _striping_info si ;
783
+ struct _trunc_info ti ;
757
784
int i , ret ;
758
785
759
786
ret = exofs_get_io_state (& sbi -> layout , & ios );
760
787
if (unlikely (ret ))
761
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
793
GFP_KERNEL );
765
794
if (unlikely (!size_attrs )) {
766
795
ret = - ENOMEM ;
@@ -769,26 +798,30 @@ int exofs_oi_truncate(struct exofs_i_info *oi, u64 size)
769
798
770
799
ios -> obj .id = exofs_oi_objno (oi );
771
800
ios -> cred = oi -> i_cred ;
772
-
773
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
804
struct exofs_trunc_attr * size_attr = & size_attrs [i ];
778
805
u64 obj_size ;
779
806
780
- if (i < si .dev )
781
- obj_size = si .obj_offset +
782
- ios -> layout -> stripe_unit - si .unit_off ;
783
- else if (i == si .dev )
784
- obj_size = si .obj_offset ;
785
- else /* i > si.dev */
786
- obj_size = si .obj_offset - si .unit_off ;
807
+ if (i < ti .first_group_dev )
808
+ obj_size = ti .prev_group_obj_off ;
809
+ else if (i >= ti .nex_group_dev )
810
+ obj_size = ti .next_group_obj_off ;
811
+ else if (i < ti .si .dev ) /* dev within this group */
812
+ obj_size = ti .si .obj_offset +
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
819
size_attr -> newsize = cpu_to_be64 (obj_size );
789
820
size_attr -> attr = g_attr_logical_length ;
790
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
825
ret = _truncate_mirrors (ios , i * ios -> layout -> mirrors_p1 ,
793
826
& size_attr -> attr );
794
827
if (unlikely (ret ))
0 commit comments