diff mbox series

[6/6] btrfs: bypass filemap_fdatawrite_range in btrfs_write_buffers

Message ID 20230515192256.29006-7-hch@lst.de (mailing list archive)
State New, archived
Headers show
Series [1/6] btrfs: use a linked list for tracking per-transaction/log dirty buffers | expand

Commit Message

Christoph Hellwig May 15, 2023, 7:22 p.m. UTC
btrfs_write_buffers already has a pointer to each extent_buffer it needs
to write.  Instead of going through filemap_fdatawrite_range to look up
each page in the buffer, just to cycle back to the buffer for writing
it, just call write_one_eb directly.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/btrfs/extent_buffer.c | 17 +++++++++++++----
 fs/btrfs/extent_buffer.h |  3 +++
 fs/btrfs/extent_io.c     |  6 +++---
 3 files changed, 19 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/fs/btrfs/extent_buffer.c b/fs/btrfs/extent_buffer.c
index 70a6a5f2e0e0a8..8d0802d2ab004e 100644
--- a/fs/btrfs/extent_buffer.c
+++ b/fs/btrfs/extent_buffer.c
@@ -8,6 +8,7 @@ 
 #include "extent_io.h"
 #include "fs.h"
 #include "transaction.h"
+#include "zoned.h"
 
 void btrfs_add_to_dirty_buffers_list(struct extent_buffer *eb,
 				     struct btrfs_transaction *trans,
@@ -44,20 +45,28 @@  static int extent_buffer_cmp(void *priv, const struct list_head *a,
 
 int btrfs_write_buffers(struct btrfs_fs_info *fs_info, struct list_head *list)
 {
-	struct address_space *mapping = fs_info->btree_inode->i_mapping;
 	struct dirty_buffer *db;
+	struct writeback_control wbc = {
+		.sync_mode	= WB_SYNC_ALL,
+		.nr_to_write	= LONG_MAX,
+	};
 	int werr = 0, err;
 
 	list_sort(NULL, list, extent_buffer_cmp);
 
+	btrfs_zoned_meta_io_lock(fs_info);
 	list_for_each_entry(db, list, wb_entry) {
-		err = filemap_fdatawrite_range(mapping, db->eb->start,
-					       db->eb->start + db->eb->len - 1);
-		if (err)
+		err = write_one_eb(db->eb, &wbc, NULL);
+		if (err < 0) {
 			werr = err;
+			break;
+		}
 		cond_resched();
 	}
+	btrfs_zoned_meta_io_unlock(fs_info);
 
+	if (!werr && BTRFS_FS_ERROR(fs_info))
+		return -EROFS;
 	return werr;
 }
 
diff --git a/fs/btrfs/extent_buffer.h b/fs/btrfs/extent_buffer.h
index 880b325d7b411a..c521685d7ca85c 100644
--- a/fs/btrfs/extent_buffer.h
+++ b/fs/btrfs/extent_buffer.h
@@ -7,6 +7,7 @@  struct btrfs_fs_info;
 struct btrfs_root;
 struct btrfs_transaction;
 struct list_head;
+struct writeback_control;
 
 struct dirty_buffer {
 	struct list_head wb_entry;
@@ -19,5 +20,7 @@  void btrfs_add_to_dirty_buffers_list(struct extent_buffer *eb,
 int btrfs_write_buffers(struct btrfs_fs_info *fs_info, struct list_head *list);
 int btrfs_wait_buffers(struct btrfs_fs_info *fs_info, struct list_head *list);
 void btrfs_release_buffers(struct list_head *list);
+int write_one_eb(struct extent_buffer *eb, struct writeback_control *wbc,
+		 struct extent_buffer **eb_context);
 
 #endif /* BTRFS_EXTENT_BUFFER_H */
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index c291fc728db047..28078dd4acd99a 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -15,6 +15,7 @@ 
 #include <linux/prefetch.h>
 #include <linux/fsverity.h>
 #include "misc.h"
+#include "extent_buffer.h"
 #include "extent_io.h"
 #include "extent-io-tree.h"
 #include "extent_map.h"
@@ -1759,9 +1760,8 @@  static void prepare_eb_write(struct extent_buffer *eb)
 	}
 }
 
-static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
-					   struct writeback_control *wbc,
-					   struct extent_buffer **eb_context)
+int write_one_eb(struct extent_buffer *eb, struct writeback_control *wbc,
+		 struct extent_buffer **eb_context)
 {
 	struct btrfs_fs_info *fs_info = eb->fs_info;
 	struct btrfs_block_group *zoned_bg = NULL;