Skip to content

Commit

Permalink
Btrfs: unlock everything properly in the error case for nocow
Browse files Browse the repository at this point in the history
I was getting hung on umount when a transaction was aborted because a range
of one of the free space inodes was still locked.  This is because the nocow
stuff doesn't unlock anything on error.  This fixed the problem and I
verified that is what was happening.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
  • Loading branch information
Josef Bacik authored and Chris Mason committed Jun 15, 2012
1 parent ee670f0 commit 17ca04a
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,8 +1136,18 @@ static noinline int run_delalloc_nocow(struct inode *inode,
u64 ino = btrfs_ino(inode);

path = btrfs_alloc_path();
if (!path)
if (!path) {
extent_clear_unlock_delalloc(inode,
&BTRFS_I(inode)->io_tree,
start, end, locked_page,
EXTENT_CLEAR_UNLOCK_PAGE |
EXTENT_CLEAR_UNLOCK |
EXTENT_CLEAR_DELALLOC |
EXTENT_CLEAR_DIRTY |
EXTENT_SET_WRITEBACK |
EXTENT_END_WRITEBACK);
return -ENOMEM;
}

nolock = btrfs_is_free_space_inode(root, inode);

Expand All @@ -1147,6 +1157,15 @@ static noinline int run_delalloc_nocow(struct inode *inode,
trans = btrfs_join_transaction(root);

if (IS_ERR(trans)) {
extent_clear_unlock_delalloc(inode,
&BTRFS_I(inode)->io_tree,
start, end, locked_page,
EXTENT_CLEAR_UNLOCK_PAGE |
EXTENT_CLEAR_UNLOCK |
EXTENT_CLEAR_DELALLOC |
EXTENT_CLEAR_DIRTY |
EXTENT_SET_WRITEBACK |
EXTENT_END_WRITEBACK);
btrfs_free_path(path);
return PTR_ERR(trans);
}
Expand Down Expand Up @@ -1327,8 +1346,11 @@ static noinline int run_delalloc_nocow(struct inode *inode,
}
btrfs_release_path(path);

if (cur_offset <= end && cow_start == (u64)-1)
if (cur_offset <= end && cow_start == (u64)-1) {
cow_start = cur_offset;
cur_offset = end;
}

if (cow_start != (u64)-1) {
ret = cow_file_range(inode, locked_page, cow_start, end,
page_started, nr_written, 1);
Expand All @@ -1347,6 +1369,17 @@ static noinline int run_delalloc_nocow(struct inode *inode,
if (!ret)
ret = err;

if (ret && cur_offset < end)
extent_clear_unlock_delalloc(inode,
&BTRFS_I(inode)->io_tree,
cur_offset, end, locked_page,
EXTENT_CLEAR_UNLOCK_PAGE |
EXTENT_CLEAR_UNLOCK |
EXTENT_CLEAR_DELALLOC |
EXTENT_CLEAR_DIRTY |
EXTENT_SET_WRITEBACK |
EXTENT_END_WRITEBACK);

btrfs_free_path(path);
return ret;
}
Expand Down

0 comments on commit 17ca04a

Please sign in to comment.