@@ -2914,8 +2914,6 @@ static void btrfs_cmp_data_free(struct cmp_pages *cmp)
29142914 put_page (pg );
29152915 }
29162916 }
2917- kfree (cmp -> src_pages );
2918- kfree (cmp -> dst_pages );
29192917}
29202918
29212919static 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,
29242922{
29252923 int ret ;
29262924 int num_pages = PAGE_ALIGN (len ) >> PAGE_SHIFT ;
2927- struct page * * src_pgarr , * * dst_pgarr ;
29282925
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- }
29422926 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- }
29552927
2956- ret = gather_extent_pages (src , src_pgarr , cmp -> num_pages , loff );
2928+ ret = gather_extent_pages (src , cmp -> src_pages , num_pages , loff );
29572929 if (ret )
29582930 goto out ;
29592931
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 );
29612933
29622934out :
29632935 if (ret )
@@ -3028,11 +3000,11 @@ static int extent_same_check_offsets(struct inode *inode, u64 off, u64 *plen,
30283000}
30293001
30303002static 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 )
30323005{
30333006 int ret ;
30343007 u64 len = olen ;
3035- struct cmp_pages cmp ;
30363008 bool same_inode = (src == dst );
30373009 u64 same_lock_start = 0 ;
30383010 u64 same_lock_len = 0 ;
@@ -3072,7 +3044,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
30723044 }
30733045
30743046again :
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 );
30763048 if (ret )
30773049 return ret ;
30783050
@@ -3095,7 +3067,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
30953067 * Ranges in the io trees already unlocked. Now unlock all
30963068 * pages before waiting for all IO to complete.
30973069 */
3098- btrfs_cmp_data_free (& cmp );
3070+ btrfs_cmp_data_free (cmp );
30993071 if (same_inode ) {
31003072 btrfs_wait_ordered_range (src , same_lock_start ,
31013073 same_lock_len );
@@ -3108,12 +3080,12 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
31083080 ASSERT (ret == 0 );
31093081 if (WARN_ON (ret )) {
31103082 /* ranges in the io trees already unlocked */
3111- btrfs_cmp_data_free (& cmp );
3083+ btrfs_cmp_data_free (cmp );
31123084 return ret ;
31133085 }
31143086
31153087 /* 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 );
31173089 if (ret == 0 )
31183090 ret = btrfs_clone (src , dst , loff , olen , len , dst_loff , 1 );
31193091
@@ -3123,7 +3095,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
31233095 else
31243096 btrfs_double_extent_unlock (src , loff , dst , dst_loff , len );
31253097
3126- btrfs_cmp_data_free (& cmp );
3098+ btrfs_cmp_data_free (cmp );
31273099
31283100 return ret ;
31293101}
@@ -3134,6 +3106,8 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
31343106 struct inode * dst , u64 dst_loff )
31353107{
31363108 int ret ;
3109+ struct cmp_pages cmp ;
3110+ int num_pages = PAGE_ALIGN (BTRFS_MAX_DEDUPE_LEN ) >> PAGE_SHIFT ;
31373111 bool same_inode = (src == dst );
31383112 u64 i , tail_len , chunk_count ;
31393113
@@ -3154,10 +3128,33 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
31543128
31553129 tail_len = olen % BTRFS_MAX_DEDUPE_LEN ;
31563130 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+ }
31573154
31583155 for (i = 0 ; i < chunk_count ; i ++ ) {
31593156 ret = btrfs_extent_same_range (src , loff , BTRFS_MAX_DEDUPE_LEN ,
3160- dst , dst_loff );
3157+ dst , dst_loff , & cmp );
31613158 if (ret )
31623159 goto out_unlock ;
31633160
@@ -3166,14 +3163,18 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
31663163 }
31673164
31683165 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 );
31703168
31713169out_unlock :
31723170 if (same_inode )
31733171 inode_unlock (src );
31743172 else
31753173 btrfs_double_inode_unlock (src , dst );
31763174
3175+ kfree (cmp .src_pages );
3176+ kfree (cmp .dst_pages );
3177+
31773178 return ret ;
31783179}
31793180
0 commit comments