aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2017-10-24 01:18:16 -0400
committerDavid Sterba <dsterba@suse.com>2017-11-15 08:44:31 -0500
commitf82b735936ffd58b6711cf1f1054616517d8ffcd (patch)
treeb4ad8e86330ccee60b085882d187bd4899010efa
parentd28e649a5c58b779b303c252c66ee84a0f2c3b32 (diff)
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>
-rw-r--r--fs/btrfs/compression.c7
-rw-r--r--fs/btrfs/compression.h3
-rw-r--r--fs/btrfs/extent_io.c2
-rw-r--r--fs/btrfs/extent_io.h3
-rw-r--r--fs/btrfs/inode.c15
5 files changed, 20 insertions, 10 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index b35ce16b3df3..4a78e5726337 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -295,7 +295,8 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
295 unsigned long len, u64 disk_start, 295 unsigned long len, u64 disk_start,
296 unsigned long compressed_len, 296 unsigned long compressed_len,
297 struct page **compressed_pages, 297 struct page **compressed_pages,
298 unsigned long nr_pages) 298 unsigned long nr_pages,
299 unsigned int write_flags)
299{ 300{
300 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); 301 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
301 struct bio *bio = NULL; 302 struct bio *bio = NULL;
@@ -327,7 +328,7 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
327 bdev = fs_info->fs_devices->latest_bdev; 328 bdev = fs_info->fs_devices->latest_bdev;
328 329
329 bio = btrfs_bio_alloc(bdev, first_byte); 330 bio = btrfs_bio_alloc(bdev, first_byte);
330 bio_set_op_attrs(bio, REQ_OP_WRITE, 0); 331 bio->bi_opf = REQ_OP_WRITE | write_flags;
331 bio->bi_private = cb; 332 bio->bi_private = cb;
332 bio->bi_end_io = end_compressed_bio_write; 333 bio->bi_end_io = end_compressed_bio_write;
333 refcount_set(&cb->pending_bios, 1); 334 refcount_set(&cb->pending_bios, 1);
@@ -374,7 +375,7 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
374 bio_put(bio); 375 bio_put(bio);
375 376
376 bio = btrfs_bio_alloc(bdev, first_byte); 377 bio = btrfs_bio_alloc(bdev, first_byte);
377 bio_set_op_attrs(bio, REQ_OP_WRITE, 0); 378 bio->bi_opf = REQ_OP_WRITE | write_flags;
378 bio->bi_private = cb; 379 bio->bi_private = cb;
379 bio->bi_end_io = end_compressed_bio_write; 380 bio->bi_end_io = end_compressed_bio_write;
380 bio_add_page(bio, page, PAGE_SIZE, 0); 381 bio_add_page(bio, page, PAGE_SIZE, 0);
diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h
index da20755ebf21..93c5b82ae97e 100644
--- a/fs/btrfs/compression.h
+++ b/fs/btrfs/compression.h
@@ -91,7 +91,8 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start,
91 unsigned long len, u64 disk_start, 91 unsigned long len, u64 disk_start,
92 unsigned long compressed_len, 92 unsigned long compressed_len,
93 struct page **compressed_pages, 93 struct page **compressed_pages,
94 unsigned long nr_pages); 94 unsigned long nr_pages,
95 unsigned int write_flags);
95blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, 96blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
96 int mirror_num, unsigned long bio_flags); 97 int mirror_num, unsigned long bio_flags);
97 98
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index dd941885b9c3..1dfd14678db8 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3252,7 +3252,7 @@ static noinline_for_stack int writepage_delalloc(struct inode *inode,
3252 delalloc_start, 3252 delalloc_start,
3253 delalloc_end, 3253 delalloc_end,
3254 &page_started, 3254 &page_started,
3255 nr_written); 3255 nr_written, wbc);
3256 /* File system has been set read-only */ 3256 /* File system has been set read-only */
3257 if (ret) { 3257 if (ret) {
3258 SetPageError(page); 3258 SetPageError(page);
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 861dacb371c7..d8b27af7101e 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -115,7 +115,8 @@ struct extent_io_ops {
115 */ 115 */
116 int (*fill_delalloc)(void *private_data, struct page *locked_page, 116 int (*fill_delalloc)(void *private_data, struct page *locked_page,
117 u64 start, u64 end, int *page_started, 117 u64 start, u64 end, int *page_started,
118 unsigned long *nr_written); 118 unsigned long *nr_written,
119 struct writeback_control *wbc);
119 120
120 int (*writepage_start_hook)(struct page *page, u64 start, u64 end); 121 int (*writepage_start_hook)(struct page *page, u64 start, u64 end);
121 void (*writepage_end_io_hook)(struct page *page, u64 start, u64 end, 122 void (*writepage_end_io_hook)(struct page *page, u64 start, u64 end,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b93fe05a39c7..8525a44a607e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -378,6 +378,7 @@ struct async_cow {
378 struct page *locked_page; 378 struct page *locked_page;
379 u64 start; 379 u64 start;
380 u64 end; 380 u64 end;
381 unsigned int write_flags;
381 struct list_head extents; 382 struct list_head extents;
382 struct btrfs_work work; 383 struct btrfs_work work;
383}; 384};
@@ -857,7 +858,8 @@ retry:
857 async_extent->ram_size, 858 async_extent->ram_size,
858 ins.objectid, 859 ins.objectid,
859 ins.offset, async_extent->pages, 860 ins.offset, async_extent->pages,
860 async_extent->nr_pages)) { 861 async_extent->nr_pages,
862 async_cow->write_flags)) {
861 struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; 863 struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
862 struct page *p = async_extent->pages[0]; 864 struct page *p = async_extent->pages[0];
863 const u64 start = async_extent->start; 865 const u64 start = async_extent->start;
@@ -1191,7 +1193,8 @@ static noinline void async_cow_free(struct btrfs_work *work)
1191 1193
1192static int cow_file_range_async(struct inode *inode, struct page *locked_page, 1194static int cow_file_range_async(struct inode *inode, struct page *locked_page,
1193 u64 start, u64 end, int *page_started, 1195 u64 start, u64 end, int *page_started,
1194 unsigned long *nr_written) 1196 unsigned long *nr_written,
1197 unsigned int write_flags)
1195{ 1198{
1196 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); 1199 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
1197 struct async_cow *async_cow; 1200 struct async_cow *async_cow;
@@ -1208,6 +1211,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
1208 async_cow->root = root; 1211 async_cow->root = root;
1209 async_cow->locked_page = locked_page; 1212 async_cow->locked_page = locked_page;
1210 async_cow->start = start; 1213 async_cow->start = start;
1214 async_cow->write_flags = write_flags;
1211 1215
1212 if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS && 1216 if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS &&
1213 !btrfs_test_opt(fs_info, FORCE_COMPRESS)) 1217 !btrfs_test_opt(fs_info, FORCE_COMPRESS))
@@ -1577,11 +1581,13 @@ static inline int need_force_cow(struct inode *inode, u64 start, u64 end)
1577 */ 1581 */
1578static int run_delalloc_range(void *private_data, struct page *locked_page, 1582static int run_delalloc_range(void *private_data, struct page *locked_page,
1579 u64 start, u64 end, int *page_started, 1583 u64 start, u64 end, int *page_started,
1580 unsigned long *nr_written) 1584 unsigned long *nr_written,
1585 struct writeback_control *wbc)
1581{ 1586{
1582 struct inode *inode = private_data; 1587 struct inode *inode = private_data;
1583 int ret; 1588 int ret;
1584 int force_cow = need_force_cow(inode, start, end); 1589 int force_cow = need_force_cow(inode, start, end);
1590 unsigned int write_flags = wbc_to_write_flags(wbc);
1585 1591
1586 if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW && !force_cow) { 1592 if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW && !force_cow) {
1587 ret = run_delalloc_nocow(inode, locked_page, start, end, 1593 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,
1596 set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, 1602 set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
1597 &BTRFS_I(inode)->runtime_flags); 1603 &BTRFS_I(inode)->runtime_flags);
1598 ret = cow_file_range_async(inode, locked_page, start, end, 1604 ret = cow_file_range_async(inode, locked_page, start, end,
1599 page_started, nr_written); 1605 page_started, nr_written,
1606 write_flags);
1600 } 1607 }
1601 if (ret) 1608 if (ret)
1602 btrfs_cleanup_ordered_extents(inode, start, end - start + 1); 1609 btrfs_cleanup_ordered_extents(inode, start, end - start + 1);