btrfs: move extent bit and page cleanup into cow_file_range_inline
We duplicate the extent cleanup for cow_file_range_inline() in the cow and compressed case. The encoded case doesn't need to do cleanup the same way, so rename cow_file_range_inline to __cow_file_range_inline and then make cow_file_range_inline handle the extent cleanup appropriately, and update the callers. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
0332967b4d
commit
0586d0a89e
1 changed files with 51 additions and 53 deletions
104
fs/btrfs/inode.c
104
fs/btrfs/inode.c
|
@ -662,11 +662,11 @@ static bool can_cow_file_range_inline(struct btrfs_inode *inode,
|
||||||
* does the checks required to make sure the data is small enough
|
* does the checks required to make sure the data is small enough
|
||||||
* to fit as an inline extent.
|
* to fit as an inline extent.
|
||||||
*/
|
*/
|
||||||
static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
|
static noinline int __cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
|
||||||
u64 size, size_t compressed_size,
|
u64 size, size_t compressed_size,
|
||||||
int compress_type,
|
int compress_type,
|
||||||
struct folio *compressed_folio,
|
struct folio *compressed_folio,
|
||||||
bool update_i_size)
|
bool update_i_size)
|
||||||
{
|
{
|
||||||
struct btrfs_drop_extents_args drop_args = { 0 };
|
struct btrfs_drop_extents_args drop_args = { 0 };
|
||||||
struct btrfs_root *root = inode->root;
|
struct btrfs_root *root = inode->root;
|
||||||
|
@ -737,6 +737,33 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
|
||||||
|
u64 end,
|
||||||
|
size_t compressed_size,
|
||||||
|
int compress_type,
|
||||||
|
struct folio *compressed_folio,
|
||||||
|
bool update_i_size, bool locked)
|
||||||
|
{
|
||||||
|
unsigned long clear_flags = EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
|
||||||
|
EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING;
|
||||||
|
u64 size = min_t(u64, i_size_read(&inode->vfs_inode), end + 1);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = __cow_file_range_inline(inode, offset, size, compressed_size,
|
||||||
|
compress_type, compressed_folio,
|
||||||
|
update_i_size);
|
||||||
|
if (ret > 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (locked)
|
||||||
|
clear_flags |= EXTENT_LOCKED;
|
||||||
|
|
||||||
|
extent_clear_unlock_delalloc(inode, offset, end, NULL, clear_flags,
|
||||||
|
PAGE_UNLOCK | PAGE_START_WRITEBACK |
|
||||||
|
PAGE_END_WRITEBACK);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
struct async_extent {
|
struct async_extent {
|
||||||
u64 start;
|
u64 start;
|
||||||
u64 ram_size;
|
u64 ram_size;
|
||||||
|
@ -1005,36 +1032,15 @@ again:
|
||||||
* extent for the subpage case.
|
* extent for the subpage case.
|
||||||
*/
|
*/
|
||||||
if (total_in < actual_end)
|
if (total_in < actual_end)
|
||||||
ret = cow_file_range_inline(inode, start, actual_end, 0,
|
ret = cow_file_range_inline(inode, start, end, 0,
|
||||||
BTRFS_COMPRESS_NONE, NULL, false);
|
BTRFS_COMPRESS_NONE, NULL, false,
|
||||||
|
false);
|
||||||
else
|
else
|
||||||
ret = cow_file_range_inline(inode, start, actual_end,
|
ret = cow_file_range_inline(inode, start, end, total_compressed,
|
||||||
total_compressed, compress_type,
|
compress_type, folios[0], false, false);
|
||||||
folios[0], false);
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
unsigned long clear_flags = EXTENT_DELALLOC |
|
|
||||||
EXTENT_DELALLOC_NEW | EXTENT_DEFRAG |
|
|
||||||
EXTENT_DO_ACCOUNTING;
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
mapping_set_error(mapping, -EIO);
|
mapping_set_error(mapping, -EIO);
|
||||||
|
|
||||||
/*
|
|
||||||
* inline extent creation worked or returned error,
|
|
||||||
* we don't need to create any more async work items.
|
|
||||||
* Unlock and free up our temp pages.
|
|
||||||
*
|
|
||||||
* We use DO_ACCOUNTING here because we need the
|
|
||||||
* delalloc_release_metadata to be done _after_ we drop
|
|
||||||
* our outstanding extent for clearing delalloc for this
|
|
||||||
* range.
|
|
||||||
*/
|
|
||||||
extent_clear_unlock_delalloc(inode, start, end,
|
|
||||||
NULL,
|
|
||||||
clear_flags,
|
|
||||||
PAGE_UNLOCK |
|
|
||||||
PAGE_START_WRITEBACK |
|
|
||||||
PAGE_END_WRITEBACK);
|
|
||||||
goto free_pages;
|
goto free_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1344,29 +1350,21 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
|
||||||
inode_should_defrag(inode, start, end, num_bytes, SZ_64K);
|
inode_should_defrag(inode, start, end, num_bytes, SZ_64K);
|
||||||
|
|
||||||
if (!no_inline) {
|
if (!no_inline) {
|
||||||
u64 actual_end = min_t(u64, i_size_read(&inode->vfs_inode),
|
|
||||||
end + 1);
|
|
||||||
|
|
||||||
/* lets try to make an inline extent */
|
/* lets try to make an inline extent */
|
||||||
ret = cow_file_range_inline(inode, start, actual_end, 0,
|
ret = cow_file_range_inline(inode, start, end, 0,
|
||||||
BTRFS_COMPRESS_NONE, NULL, false);
|
BTRFS_COMPRESS_NONE, NULL, false,
|
||||||
if (ret == 0) {
|
true);
|
||||||
|
if (ret <= 0) {
|
||||||
/*
|
/*
|
||||||
* We use DO_ACCOUNTING here because we need the
|
* We succeeded, return 1 so the caller knows we're done
|
||||||
* delalloc_release_metadata to be run _after_ we drop
|
* with this page and already handled the IO.
|
||||||
* our outstanding extent for clearing delalloc for this
|
*
|
||||||
* range.
|
* If there was an error then cow_file_range_inline() has
|
||||||
|
* already done the cleanup.
|
||||||
*/
|
*/
|
||||||
extent_clear_unlock_delalloc(inode, start, end,
|
if (ret == 0)
|
||||||
NULL,
|
ret = 1;
|
||||||
EXTENT_LOCKED | EXTENT_DELALLOC |
|
|
||||||
EXTENT_DELALLOC_NEW | EXTENT_DEFRAG |
|
|
||||||
EXTENT_DO_ACCOUNTING, PAGE_UNLOCK |
|
|
||||||
PAGE_START_WRITEBACK | PAGE_END_WRITEBACK);
|
|
||||||
ret = 1;
|
|
||||||
goto done;
|
goto done;
|
||||||
} else if (ret < 0) {
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10273,9 +10271,9 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
|
||||||
/* Try an inline extent first. */
|
/* Try an inline extent first. */
|
||||||
if (encoded->unencoded_len == encoded->len &&
|
if (encoded->unencoded_len == encoded->len &&
|
||||||
encoded->unencoded_offset == 0) {
|
encoded->unencoded_offset == 0) {
|
||||||
ret = cow_file_range_inline(inode, start, encoded->len,
|
ret = __cow_file_range_inline(inode, start, encoded->len,
|
||||||
orig_count, compression, folios[0],
|
orig_count, compression, folios[0],
|
||||||
true);
|
true);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = orig_count;
|
ret = orig_count;
|
||||||
|
|
Loading…
Add table
Reference in a new issue