@@ -1974,8 +1974,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
19741974 int ret ;
19751975 bool check_prev = true;
19761976 u64 ino = btrfs_ino (inode );
1977- struct btrfs_block_group * bg ;
1978- bool nocow = false;
19791977 struct can_nocow_file_extent_args nocow_args = { 0 };
19801978
19811979 path = btrfs_alloc_path ();
@@ -1993,6 +1991,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
19931991 nocow_args .writeback_path = true;
19941992
19951993 while (1 ) {
1994+ struct btrfs_block_group * nocow_bg = NULL ;
19961995 struct btrfs_ordered_extent * ordered ;
19971996 struct btrfs_key found_key ;
19981997 struct btrfs_file_extent_item * fi ;
@@ -2003,8 +2002,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
20032002 int extent_type ;
20042003 bool is_prealloc ;
20052004
2006- nocow = false;
2007-
20082005 ret = btrfs_lookup_file_extent (NULL , root , path , ino ,
20092006 cur_offset , 0 );
20102007 if (ret < 0 )
@@ -2063,7 +2060,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
20632060 if (found_key .offset > cur_offset ) {
20642061 extent_end = found_key .offset ;
20652062 extent_type = 0 ;
2066- goto out_check ;
2063+ goto must_cow ;
20672064 }
20682065
20692066 /*
@@ -2096,18 +2093,19 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
20962093 if (ret < 0 )
20972094 goto error ;
20982095 if (ret == 0 )
2099- goto out_check ;
2096+ goto must_cow ;
21002097
21012098 ret = 0 ;
2102- bg = btrfs_inc_nocow_writers (fs_info , nocow_args .disk_bytenr );
2103- if (bg )
2104- nocow = true;
2105- out_check :
2106- /*
2107- * If nocow is false then record the beginning of the range
2108- * that needs to be COWed
2109- */
2110- if (!nocow ) {
2099+ nocow_bg = btrfs_inc_nocow_writers (fs_info , nocow_args .disk_bytenr );
2100+ if (!nocow_bg ) {
2101+ must_cow :
2102+ /*
2103+ * If we can't perform NOCOW writeback for the range,
2104+ * then record the beginning of the range that needs to
2105+ * be COWed. It will be written out before the next
2106+ * NOCOW range if we find one, or when exiting this
2107+ * loop.
2108+ */
21112109 if (cow_start == (u64 )- 1 )
21122110 cow_start = cur_offset ;
21132111 cur_offset = extent_end ;
@@ -2128,8 +2126,10 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
21282126 ret = fallback_to_cow (inode , locked_page ,
21292127 cow_start , found_key .offset - 1 );
21302128 cow_start = (u64 )- 1 ;
2131- if (ret )
2129+ if (ret ) {
2130+ btrfs_dec_nocow_writers (nocow_bg );
21322131 goto error ;
2132+ }
21332133 }
21342134
21352135 nocow_end = cur_offset + nocow_args .num_bytes - 1 ;
@@ -2146,6 +2146,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
21462146 ram_bytes , BTRFS_COMPRESS_NONE ,
21472147 BTRFS_ORDERED_PREALLOC );
21482148 if (IS_ERR (em )) {
2149+ btrfs_dec_nocow_writers (nocow_bg );
21492150 ret = PTR_ERR (em );
21502151 goto error ;
21512152 }
@@ -2159,6 +2160,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
21592160 ? (1 << BTRFS_ORDERED_PREALLOC )
21602161 : (1 << BTRFS_ORDERED_NOCOW ),
21612162 BTRFS_COMPRESS_NONE );
2163+ btrfs_dec_nocow_writers (nocow_bg );
21622164 if (IS_ERR (ordered )) {
21632165 if (is_prealloc ) {
21642166 btrfs_drop_extent_map_range (inode , cur_offset ,
@@ -2168,11 +2170,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
21682170 goto error ;
21692171 }
21702172
2171- if (nocow ) {
2172- btrfs_dec_nocow_writers (bg );
2173- nocow = false;
2174- }
2175-
21762173 if (btrfs_is_data_reloc_root (root ))
21772174 /*
21782175 * Error handled later, as we must prevent
@@ -2213,18 +2210,18 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
22132210 goto error ;
22142211 }
22152212
2216- error :
2217- if (nocow )
2218- btrfs_dec_nocow_writers (bg );
2213+ btrfs_free_path (path );
2214+ return 0 ;
22192215
2216+ error :
22202217 /*
22212218 * If an error happened while a COW region is outstanding, cur_offset
22222219 * needs to be reset to cow_start to ensure the COW region is unlocked
22232220 * as well.
22242221 */
22252222 if (cow_start != (u64 )- 1 )
22262223 cur_offset = cow_start ;
2227- if (ret && cur_offset < end )
2224+ if (cur_offset < end )
22282225 extent_clear_unlock_delalloc (inode , cur_offset , end ,
22292226 locked_page , EXTENT_LOCKED |
22302227 EXTENT_DELALLOC | EXTENT_DEFRAG |
0 commit comments