@@ -1974,8 +1974,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
1974
1974
int ret ;
1975
1975
bool check_prev = true;
1976
1976
u64 ino = btrfs_ino (inode );
1977
- struct btrfs_block_group * bg ;
1978
- bool nocow = false;
1979
1977
struct can_nocow_file_extent_args nocow_args = { 0 };
1980
1978
1981
1979
path = btrfs_alloc_path ();
@@ -1993,6 +1991,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
1993
1991
nocow_args .writeback_path = true;
1994
1992
1995
1993
while (1 ) {
1994
+ struct btrfs_block_group * nocow_bg = NULL ;
1996
1995
struct btrfs_ordered_extent * ordered ;
1997
1996
struct btrfs_key found_key ;
1998
1997
struct btrfs_file_extent_item * fi ;
@@ -2003,8 +2002,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
2003
2002
int extent_type ;
2004
2003
bool is_prealloc ;
2005
2004
2006
- nocow = false;
2007
-
2008
2005
ret = btrfs_lookup_file_extent (NULL , root , path , ino ,
2009
2006
cur_offset , 0 );
2010
2007
if (ret < 0 )
@@ -2063,7 +2060,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
2063
2060
if (found_key .offset > cur_offset ) {
2064
2061
extent_end = found_key .offset ;
2065
2062
extent_type = 0 ;
2066
- goto out_check ;
2063
+ goto must_cow ;
2067
2064
}
2068
2065
2069
2066
/*
@@ -2096,18 +2093,19 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
2096
2093
if (ret < 0 )
2097
2094
goto error ;
2098
2095
if (ret == 0 )
2099
- goto out_check ;
2096
+ goto must_cow ;
2100
2097
2101
2098
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
+ */
2111
2109
if (cow_start == (u64 )- 1 )
2112
2110
cow_start = cur_offset ;
2113
2111
cur_offset = extent_end ;
@@ -2128,8 +2126,10 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
2128
2126
ret = fallback_to_cow (inode , locked_page ,
2129
2127
cow_start , found_key .offset - 1 );
2130
2128
cow_start = (u64 )- 1 ;
2131
- if (ret )
2129
+ if (ret ) {
2130
+ btrfs_dec_nocow_writers (nocow_bg );
2132
2131
goto error ;
2132
+ }
2133
2133
}
2134
2134
2135
2135
nocow_end = cur_offset + nocow_args .num_bytes - 1 ;
@@ -2146,6 +2146,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
2146
2146
ram_bytes , BTRFS_COMPRESS_NONE ,
2147
2147
BTRFS_ORDERED_PREALLOC );
2148
2148
if (IS_ERR (em )) {
2149
+ btrfs_dec_nocow_writers (nocow_bg );
2149
2150
ret = PTR_ERR (em );
2150
2151
goto error ;
2151
2152
}
@@ -2159,6 +2160,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
2159
2160
? (1 << BTRFS_ORDERED_PREALLOC )
2160
2161
: (1 << BTRFS_ORDERED_NOCOW ),
2161
2162
BTRFS_COMPRESS_NONE );
2163
+ btrfs_dec_nocow_writers (nocow_bg );
2162
2164
if (IS_ERR (ordered )) {
2163
2165
if (is_prealloc ) {
2164
2166
btrfs_drop_extent_map_range (inode , cur_offset ,
@@ -2168,11 +2170,6 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
2168
2170
goto error ;
2169
2171
}
2170
2172
2171
- if (nocow ) {
2172
- btrfs_dec_nocow_writers (bg );
2173
- nocow = false;
2174
- }
2175
-
2176
2173
if (btrfs_is_data_reloc_root (root ))
2177
2174
/*
2178
2175
* Error handled later, as we must prevent
@@ -2213,18 +2210,18 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode,
2213
2210
goto error ;
2214
2211
}
2215
2212
2216
- error :
2217
- if (nocow )
2218
- btrfs_dec_nocow_writers (bg );
2213
+ btrfs_free_path (path );
2214
+ return 0 ;
2219
2215
2216
+ error :
2220
2217
/*
2221
2218
* If an error happened while a COW region is outstanding, cur_offset
2222
2219
* needs to be reset to cow_start to ensure the COW region is unlocked
2223
2220
* as well.
2224
2221
*/
2225
2222
if (cow_start != (u64 )- 1 )
2226
2223
cur_offset = cow_start ;
2227
- if (ret && cur_offset < end )
2224
+ if (cur_offset < end )
2228
2225
extent_clear_unlock_delalloc (inode , cur_offset , end ,
2229
2226
locked_page , EXTENT_LOCKED |
2230
2227
EXTENT_DELALLOC | EXTENT_DEFRAG |
0 commit comments