Skip to content

Commit 0586d0a

Browse files
josefbacikkdave
authored andcommitted
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>
1 parent 0332967 commit 0586d0a

File tree

1 file changed

+51
-53
lines changed

1 file changed

+51
-53
lines changed

fs/btrfs/inode.c

Lines changed: 51 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -662,11 +662,11 @@ static bool can_cow_file_range_inline(struct btrfs_inode *inode,
662662
* does the checks required to make sure the data is small enough
663663
* to fit as an inline extent.
664664
*/
665-
static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
666-
u64 size, size_t compressed_size,
667-
int compress_type,
668-
struct folio *compressed_folio,
669-
bool update_i_size)
665+
static noinline int __cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
666+
u64 size, size_t compressed_size,
667+
int compress_type,
668+
struct folio *compressed_folio,
669+
bool update_i_size)
670670
{
671671
struct btrfs_drop_extents_args drop_args = { 0 };
672672
struct btrfs_root *root = inode->root;
@@ -737,6 +737,33 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
737737
return ret;
738738
}
739739

740+
static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 offset,
741+
u64 end,
742+
size_t compressed_size,
743+
int compress_type,
744+
struct folio *compressed_folio,
745+
bool update_i_size, bool locked)
746+
{
747+
unsigned long clear_flags = EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
748+
EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING;
749+
u64 size = min_t(u64, i_size_read(&inode->vfs_inode), end + 1);
750+
int ret;
751+
752+
ret = __cow_file_range_inline(inode, offset, size, compressed_size,
753+
compress_type, compressed_folio,
754+
update_i_size);
755+
if (ret > 0)
756+
return ret;
757+
758+
if (locked)
759+
clear_flags |= EXTENT_LOCKED;
760+
761+
extent_clear_unlock_delalloc(inode, offset, end, NULL, clear_flags,
762+
PAGE_UNLOCK | PAGE_START_WRITEBACK |
763+
PAGE_END_WRITEBACK);
764+
return ret;
765+
}
766+
740767
struct async_extent {
741768
u64 start;
742769
u64 ram_size;
@@ -1005,36 +1032,15 @@ static void compress_file_range(struct btrfs_work *work)
10051032
* extent for the subpage case.
10061033
*/
10071034
if (total_in < actual_end)
1008-
ret = cow_file_range_inline(inode, start, actual_end, 0,
1009-
BTRFS_COMPRESS_NONE, NULL, false);
1035+
ret = cow_file_range_inline(inode, start, end, 0,
1036+
BTRFS_COMPRESS_NONE, NULL, false,
1037+
false);
10101038
else
1011-
ret = cow_file_range_inline(inode, start, actual_end,
1012-
total_compressed, compress_type,
1013-
folios[0], false);
1039+
ret = cow_file_range_inline(inode, start, end, total_compressed,
1040+
compress_type, folios[0], false, false);
10141041
if (ret <= 0) {
1015-
unsigned long clear_flags = EXTENT_DELALLOC |
1016-
EXTENT_DELALLOC_NEW | EXTENT_DEFRAG |
1017-
EXTENT_DO_ACCOUNTING;
1018-
10191042
if (ret < 0)
10201043
mapping_set_error(mapping, -EIO);
1021-
1022-
/*
1023-
* inline extent creation worked or returned error,
1024-
* we don't need to create any more async work items.
1025-
* Unlock and free up our temp pages.
1026-
*
1027-
* We use DO_ACCOUNTING here because we need the
1028-
* delalloc_release_metadata to be done _after_ we drop
1029-
* our outstanding extent for clearing delalloc for this
1030-
* range.
1031-
*/
1032-
extent_clear_unlock_delalloc(inode, start, end,
1033-
NULL,
1034-
clear_flags,
1035-
PAGE_UNLOCK |
1036-
PAGE_START_WRITEBACK |
1037-
PAGE_END_WRITEBACK);
10381044
goto free_pages;
10391045
}
10401046

@@ -1344,29 +1350,21 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
13441350
inode_should_defrag(inode, start, end, num_bytes, SZ_64K);
13451351

13461352
if (!no_inline) {
1347-
u64 actual_end = min_t(u64, i_size_read(&inode->vfs_inode),
1348-
end + 1);
1349-
13501353
/* lets try to make an inline extent */
1351-
ret = cow_file_range_inline(inode, start, actual_end, 0,
1352-
BTRFS_COMPRESS_NONE, NULL, false);
1353-
if (ret == 0) {
1354+
ret = cow_file_range_inline(inode, start, end, 0,
1355+
BTRFS_COMPRESS_NONE, NULL, false,
1356+
true);
1357+
if (ret <= 0) {
13541358
/*
1355-
* We use DO_ACCOUNTING here because we need the
1356-
* delalloc_release_metadata to be run _after_ we drop
1357-
* our outstanding extent for clearing delalloc for this
1358-
* range.
1359+
* We succeeded, return 1 so the caller knows we're done
1360+
* with this page and already handled the IO.
1361+
*
1362+
* If there was an error then cow_file_range_inline() has
1363+
* already done the cleanup.
13591364
*/
1360-
extent_clear_unlock_delalloc(inode, start, end,
1361-
NULL,
1362-
EXTENT_LOCKED | EXTENT_DELALLOC |
1363-
EXTENT_DELALLOC_NEW | EXTENT_DEFRAG |
1364-
EXTENT_DO_ACCOUNTING, PAGE_UNLOCK |
1365-
PAGE_START_WRITEBACK | PAGE_END_WRITEBACK);
1366-
ret = 1;
1365+
if (ret == 0)
1366+
ret = 1;
13671367
goto done;
1368-
} else if (ret < 0) {
1369-
goto out_unlock;
13701368
}
13711369
}
13721370

@@ -10273,9 +10271,9 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
1027310271
/* Try an inline extent first. */
1027410272
if (encoded->unencoded_len == encoded->len &&
1027510273
encoded->unencoded_offset == 0) {
10276-
ret = cow_file_range_inline(inode, start, encoded->len,
10277-
orig_count, compression, folios[0],
10278-
true);
10274+
ret = __cow_file_range_inline(inode, start, encoded->len,
10275+
orig_count, compression, folios[0],
10276+
true);
1027910277
if (ret <= 0) {
1028010278
if (ret == 0)
1028110279
ret = orig_count;

0 commit comments

Comments
 (0)