@@ -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;
}
@@ -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 */
@@ -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;
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(-)