Commit d456c25d authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: push lock_extent down in cow_file_range()

Now that we've got the extent lock pushed into cow_file_range() we can
push it further down into the allocation loop.  This allows us to only
hold the extent lock during the dropping of the extent map range and
inserting the ordered extent.

This makes the error case a little trickier as we'll now have to lock
the range before clearing any of the other extent bits for the range,
but this is the error path so is less performance critical.
Reviewed-by: default avatarGoldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent cd241a8f
...@@ -1371,8 +1371,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode, ...@@ -1371,8 +1371,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
} }
} }
lock_extent(&inode->io_tree, start, end, NULL);
alloc_hint = get_extent_allocation_hint(inode, start, num_bytes); alloc_hint = get_extent_allocation_hint(inode, start, num_bytes);
/* /*
...@@ -1429,6 +1427,9 @@ static noinline int cow_file_range(struct btrfs_inode *inode, ...@@ -1429,6 +1427,9 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
extent_reserved = true; extent_reserved = true;
ram_size = ins.offset; ram_size = ins.offset;
lock_extent(&inode->io_tree, start, start + ram_size - 1, NULL);
em = create_io_em(inode, start, ins.offset, /* len */ em = create_io_em(inode, start, ins.offset, /* len */
start, /* orig_start */ start, /* orig_start */
ins.objectid, /* block_start */ ins.objectid, /* block_start */
...@@ -1438,6 +1439,8 @@ static noinline int cow_file_range(struct btrfs_inode *inode, ...@@ -1438,6 +1439,8 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
BTRFS_COMPRESS_NONE, /* compress_type */ BTRFS_COMPRESS_NONE, /* compress_type */
BTRFS_ORDERED_REGULAR /* type */); BTRFS_ORDERED_REGULAR /* type */);
if (IS_ERR(em)) { if (IS_ERR(em)) {
unlock_extent(&inode->io_tree, start,
start + ram_size - 1, NULL);
ret = PTR_ERR(em); ret = PTR_ERR(em);
goto out_reserve; goto out_reserve;
} }
...@@ -1448,6 +1451,8 @@ static noinline int cow_file_range(struct btrfs_inode *inode, ...@@ -1448,6 +1451,8 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
0, 1 << BTRFS_ORDERED_REGULAR, 0, 1 << BTRFS_ORDERED_REGULAR,
BTRFS_COMPRESS_NONE); BTRFS_COMPRESS_NONE);
if (IS_ERR(ordered)) { if (IS_ERR(ordered)) {
unlock_extent(&inode->io_tree, start,
start + ram_size - 1, NULL);
ret = PTR_ERR(ordered); ret = PTR_ERR(ordered);
goto out_drop_extent_cache; goto out_drop_extent_cache;
} }
...@@ -1549,6 +1554,13 @@ static noinline int cow_file_range(struct btrfs_inode *inode, ...@@ -1549,6 +1554,13 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
locked_page, 0, page_ops); locked_page, 0, page_ops);
} }
/*
* At this point we're unlocked, we want to make sure we're only
* clearing these flags under the extent lock, so lock the rest of the
* range and clear everything up.
*/
lock_extent(&inode->io_tree, start, end, NULL);
/* /*
* For the range (2). If we reserved an extent for our delalloc range * For the range (2). If we reserved an extent for our delalloc range
* (or a subrange) and failed to create the respective ordered extent, * (or a subrange) and failed to create the respective ordered extent,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment