Skip to content

Commit 18f62b8

Browse files
Christoph Hellwigkdave
authored andcommitted
btrfs: cleanup the COW fallback logic in run_delalloc_nocow
Use the block group pointer used to track the outstanding NOCOW writes as a boolean to remove the duplicate nocow variable, and keep it contained in the main loop to simplify the logic. Reviewed-by: Boris Burkov <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 953fa5c commit 18f62b8

File tree

1 file changed

+22
-25
lines changed

1 file changed

+22
-25
lines changed

fs/btrfs/inode.c

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)