Skip to content

Commit

Permalink
btrfs: improve error handling in run_delalloc_nocow
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nikolay Borisov authored and David Sterba committed Sep 9, 2019
1 parent e8e2100 commit 762bf09
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,8 @@ static noinline int run_delalloc_nocow(struct inode *inode,
bool check_prev = true;
const bool freespace_inode = btrfs_is_free_space_inode(BTRFS_I(inode));
u64 ino = btrfs_ino(BTRFS_I(inode));
bool nocow = false;
u64 disk_bytenr = 0;

path = btrfs_alloc_path();
if (!path) {
Expand All @@ -1333,12 +1335,12 @@ static noinline int run_delalloc_nocow(struct inode *inode,
struct extent_buffer *leaf;
u64 extent_end;
u64 extent_offset;
u64 disk_bytenr = 0;
u64 num_bytes = 0;
u64 disk_num_bytes;
u64 ram_bytes;
int extent_type;
bool nocow = false;

nocow = false;

ret = btrfs_lookup_file_extent(NULL, root, path, ino,
cur_offset, 0);
Expand Down Expand Up @@ -1572,16 +1574,25 @@ static noinline int run_delalloc_nocow(struct inode *inode,
disk_bytenr, num_bytes,
num_bytes,
BTRFS_ORDERED_PREALLOC);
if (ret) {
btrfs_drop_extent_cache(BTRFS_I(inode),
cur_offset,
cur_offset + num_bytes - 1,
0);
goto error;
}
} else {
ret = btrfs_add_ordered_extent(inode, cur_offset,
disk_bytenr, num_bytes,
num_bytes,
BTRFS_ORDERED_NOCOW);
if (ret)
goto error;
}

if (nocow)
btrfs_dec_nocow_writers(fs_info, disk_bytenr);
BUG_ON(ret); /* -ENOMEM */
nocow = false;

if (root->root_key.objectid ==
BTRFS_DATA_RELOC_TREE_OBJECTID)
Expand Down Expand Up @@ -1626,6 +1637,9 @@ static noinline int run_delalloc_nocow(struct inode *inode,
}

error:
if (nocow)
btrfs_dec_nocow_writers(fs_info, disk_bytenr);

if (ret && cur_offset < end)
extent_clear_unlock_delalloc(inode, cur_offset, end,
locked_page, EXTENT_LOCKED |
Expand Down

0 comments on commit 762bf09

Please sign in to comment.