mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 07:04:10 +08:00
btrfs: zoned: introduce dedicated data write path for zoned filesystems
If more than one IO is issued for one file extent, these IO can be written to separate regions on a device. Since we cannot map one file extent to such a separate area on a zoned filesystem, we need to follow the "one IO == one ordered extent" rule. The normal buffered, uncompressed and not pre-allocated write path (used by cow_file_range()) sometimes does not follow this rule. It can write a part of an ordered extent when specified a region to write e.g., when its called from fdatasync(). Introduce a dedicated (uncompressed buffered) data write path for zoned filesystems, that will COW the region and write it at once. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
544d24f9de
commit
42c0110009
@ -1394,6 +1394,29 @@ static int cow_file_range_async(struct btrfs_inode *inode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static noinline int run_delalloc_zoned(struct btrfs_inode *inode,
|
||||
struct page *locked_page, u64 start,
|
||||
u64 end, int *page_started,
|
||||
unsigned long *nr_written)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cow_file_range(inode, locked_page, start, end, page_started,
|
||||
nr_written, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (*page_started)
|
||||
return 0;
|
||||
|
||||
__set_page_dirty_nobuffers(locked_page);
|
||||
account_page_redirty(locked_page);
|
||||
extent_write_locked_range(&inode->vfs_inode, start, end, WB_SYNC_ALL);
|
||||
*page_started = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static noinline int csum_exist_in_range(struct btrfs_fs_info *fs_info,
|
||||
u64 bytenr, u64 num_bytes)
|
||||
{
|
||||
@ -1871,17 +1894,24 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct page *locked_page
|
||||
{
|
||||
int ret;
|
||||
int force_cow = need_force_cow(inode, start, end);
|
||||
const bool zoned = btrfs_is_zoned(inode->root->fs_info);
|
||||
|
||||
if (inode->flags & BTRFS_INODE_NODATACOW && !force_cow) {
|
||||
ASSERT(!zoned);
|
||||
ret = run_delalloc_nocow(inode, locked_page, start, end,
|
||||
page_started, 1, nr_written);
|
||||
} else if (inode->flags & BTRFS_INODE_PREALLOC && !force_cow) {
|
||||
ASSERT(!zoned);
|
||||
ret = run_delalloc_nocow(inode, locked_page, start, end,
|
||||
page_started, 0, nr_written);
|
||||
} else if (!inode_can_compress(inode) ||
|
||||
!inode_need_compress(inode, start, end)) {
|
||||
ret = cow_file_range(inode, locked_page, start, end,
|
||||
page_started, nr_written, 1);
|
||||
if (zoned)
|
||||
ret = run_delalloc_zoned(inode, locked_page, start, end,
|
||||
page_started, nr_written);
|
||||
else
|
||||
ret = cow_file_range(inode, locked_page, start, end,
|
||||
page_started, nr_written, 1);
|
||||
} else {
|
||||
set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, &inode->runtime_flags);
|
||||
ret = cow_file_range_async(inode, wbc, locked_page, start, end,
|
||||
|
Loading…
Reference in New Issue
Block a user