mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 08:19:28 +00:00
Btrfs: add write_flags for compression bio
Compression code path has only flaged bios with REQ_OP_WRITE no matter where the bios come from, but it could be a sync write if fsync starts this writeback or a normal writeback write if wb kthread starts a periodic writeback. It breaks the rule that sync writes and writeback writes need to be differentiated from each other, because from the POV of block layer, all bios need to be recognized by these flags in order to do some management, e.g. throttlling. This passes writeback_control to compression write path so that it can send bios with proper flags to block layer. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
d28e649a5c
commit
f82b735936
5 changed files with 20 additions and 10 deletions
|
@ -295,7 +295,8 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
|
|||
unsigned long len, u64 disk_start,
|
||||
unsigned long compressed_len,
|
||||
struct page **compressed_pages,
|
||||
unsigned long nr_pages)
|
||||
unsigned long nr_pages,
|
||||
unsigned int write_flags)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
struct bio *bio = NULL;
|
||||
|
@ -327,7 +328,7 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
|
|||
bdev = fs_info->fs_devices->latest_bdev;
|
||||
|
||||
bio = btrfs_bio_alloc(bdev, first_byte);
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||
bio->bi_opf = REQ_OP_WRITE | write_flags;
|
||||
bio->bi_private = cb;
|
||||
bio->bi_end_io = end_compressed_bio_write;
|
||||
refcount_set(&cb->pending_bios, 1);
|
||||
|
@ -374,7 +375,7 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
|
|||
bio_put(bio);
|
||||
|
||||
bio = btrfs_bio_alloc(bdev, first_byte);
|
||||
bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
|
||||
bio->bi_opf = REQ_OP_WRITE | write_flags;
|
||||
bio->bi_private = cb;
|
||||
bio->bi_end_io = end_compressed_bio_write;
|
||||
bio_add_page(bio, page, PAGE_SIZE, 0);
|
||||
|
|
|
@ -91,7 +91,8 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
|
|||
unsigned long len, u64 disk_start,
|
||||
unsigned long compressed_len,
|
||||
struct page **compressed_pages,
|
||||
unsigned long nr_pages);
|
||||
unsigned long nr_pages,
|
||||
unsigned int write_flags);
|
||||
blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
|
||||
int mirror_num, unsigned long bio_flags);
|
||||
|
||||
|
|
|
@ -3252,7 +3252,7 @@ static noinline_for_stack int writepage_delalloc(struct inode *inode,
|
|||
delalloc_start,
|
||||
delalloc_end,
|
||||
&page_started,
|
||||
nr_written);
|
||||
nr_written, wbc);
|
||||
/* File system has been set read-only */
|
||||
if (ret) {
|
||||
SetPageError(page);
|
||||
|
|
|
@ -115,7 +115,8 @@ struct extent_io_ops {
|
|||
*/
|
||||
int (*fill_delalloc)(void *private_data, struct page *locked_page,
|
||||
u64 start, u64 end, int *page_started,
|
||||
unsigned long *nr_written);
|
||||
unsigned long *nr_written,
|
||||
struct writeback_control *wbc);
|
||||
|
||||
int (*writepage_start_hook)(struct page *page, u64 start, u64 end);
|
||||
void (*writepage_end_io_hook)(struct page *page, u64 start, u64 end,
|
||||
|
|
|
@ -378,6 +378,7 @@ struct async_cow {
|
|||
struct page *locked_page;
|
||||
u64 start;
|
||||
u64 end;
|
||||
unsigned int write_flags;
|
||||
struct list_head extents;
|
||||
struct btrfs_work work;
|
||||
};
|
||||
|
@ -857,7 +858,8 @@ static noinline void submit_compressed_extents(struct inode *inode,
|
|||
async_extent->ram_size,
|
||||
ins.objectid,
|
||||
ins.offset, async_extent->pages,
|
||||
async_extent->nr_pages)) {
|
||||
async_extent->nr_pages,
|
||||
async_cow->write_flags)) {
|
||||
struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
|
||||
struct page *p = async_extent->pages[0];
|
||||
const u64 start = async_extent->start;
|
||||
|
@ -1191,7 +1193,8 @@ static noinline void async_cow_free(struct btrfs_work *work)
|
|||
|
||||
static int cow_file_range_async(struct inode *inode, struct page *locked_page,
|
||||
u64 start, u64 end, int *page_started,
|
||||
unsigned long *nr_written)
|
||||
unsigned long *nr_written,
|
||||
unsigned int write_flags)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
struct async_cow *async_cow;
|
||||
|
@ -1208,6 +1211,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
|
|||
async_cow->root = root;
|
||||
async_cow->locked_page = locked_page;
|
||||
async_cow->start = start;
|
||||
async_cow->write_flags = write_flags;
|
||||
|
||||
if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS &&
|
||||
!btrfs_test_opt(fs_info, FORCE_COMPRESS))
|
||||
|
@ -1577,11 +1581,13 @@ static inline int need_force_cow(struct inode *inode, u64 start, u64 end)
|
|||
*/
|
||||
static int run_delalloc_range(void *private_data, struct page *locked_page,
|
||||
u64 start, u64 end, int *page_started,
|
||||
unsigned long *nr_written)
|
||||
unsigned long *nr_written,
|
||||
struct writeback_control *wbc)
|
||||
{
|
||||
struct inode *inode = private_data;
|
||||
int ret;
|
||||
int force_cow = need_force_cow(inode, start, end);
|
||||
unsigned int write_flags = wbc_to_write_flags(wbc);
|
||||
|
||||
if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW && !force_cow) {
|
||||
ret = run_delalloc_nocow(inode, locked_page, start, end,
|
||||
|
@ -1596,7 +1602,8 @@ static int run_delalloc_range(void *private_data, struct page *locked_page,
|
|||
set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
|
||||
&BTRFS_I(inode)->runtime_flags);
|
||||
ret = cow_file_range_async(inode, locked_page, start, end,
|
||||
page_started, nr_written);
|
||||
page_started, nr_written,
|
||||
write_flags);
|
||||
}
|
||||
if (ret)
|
||||
btrfs_cleanup_ordered_extents(inode, start, end - start + 1);
|
||||
|
|
Loading…
Reference in a new issue