Skip to content

Commit 762bf09

Browse files
lorddoskiaskdave
authored andcommitted
btrfs: improve error handling in run_delalloc_nocow
Correctly handle failure cases when adding an ordered extents in case of REGULAR or PREALLOC extents. Remove the BUG_ON. Signed-off-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent e8e2100 commit 762bf09

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

fs/btrfs/inode.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,8 @@ static noinline int run_delalloc_nocow(struct inode *inode,
13141314
bool check_prev = true;
13151315
const bool freespace_inode = btrfs_is_free_space_inode(BTRFS_I(inode));
13161316
u64 ino = btrfs_ino(BTRFS_I(inode));
1317+
bool nocow = false;
1318+
u64 disk_bytenr = 0;
13171319

13181320
path = btrfs_alloc_path();
13191321
if (!path) {
@@ -1333,12 +1335,12 @@ static noinline int run_delalloc_nocow(struct inode *inode,
13331335
struct extent_buffer *leaf;
13341336
u64 extent_end;
13351337
u64 extent_offset;
1336-
u64 disk_bytenr = 0;
13371338
u64 num_bytes = 0;
13381339
u64 disk_num_bytes;
13391340
u64 ram_bytes;
13401341
int extent_type;
1341-
bool nocow = false;
1342+
1343+
nocow = false;
13421344

13431345
ret = btrfs_lookup_file_extent(NULL, root, path, ino,
13441346
cur_offset, 0);
@@ -1572,16 +1574,25 @@ static noinline int run_delalloc_nocow(struct inode *inode,
15721574
disk_bytenr, num_bytes,
15731575
num_bytes,
15741576
BTRFS_ORDERED_PREALLOC);
1577+
if (ret) {
1578+
btrfs_drop_extent_cache(BTRFS_I(inode),
1579+
cur_offset,
1580+
cur_offset + num_bytes - 1,
1581+
0);
1582+
goto error;
1583+
}
15751584
} else {
15761585
ret = btrfs_add_ordered_extent(inode, cur_offset,
15771586
disk_bytenr, num_bytes,
15781587
num_bytes,
15791588
BTRFS_ORDERED_NOCOW);
1589+
if (ret)
1590+
goto error;
15801591
}
15811592

15821593
if (nocow)
15831594
btrfs_dec_nocow_writers(fs_info, disk_bytenr);
1584-
BUG_ON(ret); /* -ENOMEM */
1595+
nocow = false;
15851596

15861597
if (root->root_key.objectid ==
15871598
BTRFS_DATA_RELOC_TREE_OBJECTID)
@@ -1626,6 +1637,9 @@ static noinline int run_delalloc_nocow(struct inode *inode,
16261637
}
16271638

16281639
error:
1640+
if (nocow)
1641+
btrfs_dec_nocow_writers(fs_info, disk_bytenr);
1642+
16291643
if (ret && cur_offset < end)
16301644
extent_clear_unlock_delalloc(inode, cur_offset, end,
16311645
locked_page, EXTENT_LOCKED |

0 commit comments

Comments
 (0)