@@ -2914,8 +2914,6 @@ static void btrfs_cmp_data_free(struct cmp_pages *cmp)
2914
2914
put_page (pg );
2915
2915
}
2916
2916
}
2917
- kfree (cmp -> src_pages );
2918
- kfree (cmp -> dst_pages );
2919
2917
}
2920
2918
2921
2919
static int btrfs_cmp_data_prepare (struct inode * src , u64 loff ,
@@ -2924,40 +2922,14 @@ static int btrfs_cmp_data_prepare(struct inode *src, u64 loff,
2924
2922
{
2925
2923
int ret ;
2926
2924
int num_pages = PAGE_ALIGN (len ) >> PAGE_SHIFT ;
2927
- struct page * * src_pgarr , * * dst_pgarr ;
2928
2925
2929
- /*
2930
- * We must gather up all the pages before we initiate our
2931
- * extent locking. We use an array for the page pointers. Size
2932
- * of the array is bounded by len, which is in turn bounded by
2933
- * BTRFS_MAX_DEDUPE_LEN.
2934
- */
2935
- src_pgarr = kcalloc (num_pages , sizeof (struct page * ), GFP_KERNEL );
2936
- dst_pgarr = kcalloc (num_pages , sizeof (struct page * ), GFP_KERNEL );
2937
- if (!src_pgarr || !dst_pgarr ) {
2938
- kfree (src_pgarr );
2939
- kfree (dst_pgarr );
2940
- return - ENOMEM ;
2941
- }
2942
2926
cmp -> num_pages = num_pages ;
2943
- cmp -> src_pages = src_pgarr ;
2944
- cmp -> dst_pages = dst_pgarr ;
2945
-
2946
- /*
2947
- * If deduping ranges in the same inode, locking rules make it mandatory
2948
- * to always lock pages in ascending order to avoid deadlocks with
2949
- * concurrent tasks (such as starting writeback/delalloc).
2950
- */
2951
- if (src == dst && dst_loff < loff ) {
2952
- swap (src_pgarr , dst_pgarr );
2953
- swap (loff , dst_loff );
2954
- }
2955
2927
2956
- ret = gather_extent_pages (src , src_pgarr , cmp -> num_pages , loff );
2928
+ ret = gather_extent_pages (src , cmp -> src_pages , num_pages , loff );
2957
2929
if (ret )
2958
2930
goto out ;
2959
2931
2960
- ret = gather_extent_pages (dst , dst_pgarr , cmp -> num_pages , dst_loff );
2932
+ ret = gather_extent_pages (dst , cmp -> dst_pages , num_pages , dst_loff );
2961
2933
2962
2934
out :
2963
2935
if (ret )
@@ -3028,11 +3000,11 @@ static int extent_same_check_offsets(struct inode *inode, u64 off, u64 *plen,
3028
3000
}
3029
3001
3030
3002
static int btrfs_extent_same_range (struct inode * src , u64 loff , u64 olen ,
3031
- struct inode * dst , u64 dst_loff )
3003
+ struct inode * dst , u64 dst_loff ,
3004
+ struct cmp_pages * cmp )
3032
3005
{
3033
3006
int ret ;
3034
3007
u64 len = olen ;
3035
- struct cmp_pages cmp ;
3036
3008
bool same_inode = (src == dst );
3037
3009
u64 same_lock_start = 0 ;
3038
3010
u64 same_lock_len = 0 ;
@@ -3072,7 +3044,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
3072
3044
}
3073
3045
3074
3046
again :
3075
- ret = btrfs_cmp_data_prepare (src , loff , dst , dst_loff , olen , & cmp );
3047
+ ret = btrfs_cmp_data_prepare (src , loff , dst , dst_loff , olen , cmp );
3076
3048
if (ret )
3077
3049
return ret ;
3078
3050
@@ -3095,7 +3067,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
3095
3067
* Ranges in the io trees already unlocked. Now unlock all
3096
3068
* pages before waiting for all IO to complete.
3097
3069
*/
3098
- btrfs_cmp_data_free (& cmp );
3070
+ btrfs_cmp_data_free (cmp );
3099
3071
if (same_inode ) {
3100
3072
btrfs_wait_ordered_range (src , same_lock_start ,
3101
3073
same_lock_len );
@@ -3108,12 +3080,12 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
3108
3080
ASSERT (ret == 0 );
3109
3081
if (WARN_ON (ret )) {
3110
3082
/* ranges in the io trees already unlocked */
3111
- btrfs_cmp_data_free (& cmp );
3083
+ btrfs_cmp_data_free (cmp );
3112
3084
return ret ;
3113
3085
}
3114
3086
3115
3087
/* pass original length for comparison so we stay within i_size */
3116
- ret = btrfs_cmp_data (olen , & cmp );
3088
+ ret = btrfs_cmp_data (olen , cmp );
3117
3089
if (ret == 0 )
3118
3090
ret = btrfs_clone (src , dst , loff , olen , len , dst_loff , 1 );
3119
3091
@@ -3123,7 +3095,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
3123
3095
else
3124
3096
btrfs_double_extent_unlock (src , loff , dst , dst_loff , len );
3125
3097
3126
- btrfs_cmp_data_free (& cmp );
3098
+ btrfs_cmp_data_free (cmp );
3127
3099
3128
3100
return ret ;
3129
3101
}
@@ -3134,6 +3106,8 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
3134
3106
struct inode * dst , u64 dst_loff )
3135
3107
{
3136
3108
int ret ;
3109
+ struct cmp_pages cmp ;
3110
+ int num_pages = PAGE_ALIGN (BTRFS_MAX_DEDUPE_LEN ) >> PAGE_SHIFT ;
3137
3111
bool same_inode = (src == dst );
3138
3112
u64 i , tail_len , chunk_count ;
3139
3113
@@ -3154,10 +3128,33 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
3154
3128
3155
3129
tail_len = olen % BTRFS_MAX_DEDUPE_LEN ;
3156
3130
chunk_count = div_u64 (olen , BTRFS_MAX_DEDUPE_LEN );
3131
+ if (chunk_count == 0 )
3132
+ num_pages = PAGE_ALIGN (tail_len ) >> PAGE_SHIFT ;
3133
+
3134
+ /*
3135
+ * If deduping ranges in the same inode, locking rules make it
3136
+ * mandatory to always lock pages in ascending order to avoid deadlocks
3137
+ * with concurrent tasks (such as starting writeback/delalloc).
3138
+ */
3139
+ if (same_inode && dst_loff < loff )
3140
+ swap (loff , dst_loff );
3141
+
3142
+ /*
3143
+ * We must gather up all the pages before we initiate our extent
3144
+ * locking. We use an array for the page pointers. Size of the array is
3145
+ * bounded by len, which is in turn bounded by BTRFS_MAX_DEDUPE_LEN.
3146
+ */
3147
+ cmp .src_pages = kcalloc (num_pages , sizeof (struct page * ), GFP_KERNEL );
3148
+ cmp .dst_pages = kcalloc (num_pages , sizeof (struct page * ), GFP_KERNEL );
3149
+ if (!cmp .src_pages || !cmp .dst_pages ) {
3150
+ kfree (cmp .src_pages );
3151
+ kfree (cmp .dst_pages );
3152
+ return - ENOMEM ;
3153
+ }
3157
3154
3158
3155
for (i = 0 ; i < chunk_count ; i ++ ) {
3159
3156
ret = btrfs_extent_same_range (src , loff , BTRFS_MAX_DEDUPE_LEN ,
3160
- dst , dst_loff );
3157
+ dst , dst_loff , & cmp );
3161
3158
if (ret )
3162
3159
goto out_unlock ;
3163
3160
@@ -3166,14 +3163,18 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
3166
3163
}
3167
3164
3168
3165
if (tail_len > 0 )
3169
- ret = btrfs_extent_same_range (src , loff , tail_len , dst , dst_loff );
3166
+ ret = btrfs_extent_same_range (src , loff , tail_len , dst ,
3167
+ dst_loff , & cmp );
3170
3168
3171
3169
out_unlock :
3172
3170
if (same_inode )
3173
3171
inode_unlock (src );
3174
3172
else
3175
3173
btrfs_double_inode_unlock (src , dst );
3176
3174
3175
+ kfree (cmp .src_pages );
3176
+ kfree (cmp .dst_pages );
3177
+
3177
3178
return ret ;
3178
3179
}
3179
3180
0 commit comments