[PATCH v2 10/16] fuse: add support for multiple writeback contexts in fuse

Kundan Kumar
2025-10-14T12:11:13Z

Made a helper to fetch writeback context to which an inode is affined.
Use it to perform writeback related operations.

Signed-off-by: Kundan Kumar <kundan.kumar@samsung.com>
Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
---
fs/fuse/file.c | 7 +++----
include/linux/backing-dev.h | 17 +++++++++++++++++
2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 8c823a661139..9c7f0e4b741f 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1823,7 +1823,6 @@ static void fuse_writepage_finish(struct fuse_writepage_args *wpa)
struct fuse_args_pages *ap = &wpa->ia.ap;
struct inode *inode = wpa->inode;
struct fuse_inode *fi = get_fuse_inode(inode);
- struct backing_dev_info *bdi = inode_to_bdi(inode);
int i;

for (i = 0; i < ap->num_folios; i++) {
@@ -1833,8 +1832,8 @@ static void fuse_writepage_finish(struct fuse_writepage_args *wpa)
* contention and noticeably improves performance.
*/
iomap_finish_folio_write(inode, ap->folios[i], 1);
- dec_wb_stat(&bdi->wb_ctx[0]->wb, WB_WRITEBACK);
- wb_writeout_inc(&bdi->wb_ctx[0]->wb);
+ bdi_wb_stat_mod(inode, -1);
+ bdi_wb_writeout_inc(inode);
}

wake_up(&fi->page_waitq);
@@ -2017,7 +2016,7 @@ static void fuse_writepage_args_page_fill(struct fuse_writepage_args *wpa, struc
ap->descs[folio_index].offset = offset;
ap->descs[folio_index].length = len;

- inc_wb_stat(&inode_to_bdi(inode)->wb_ctx[0]->wb, WB_WRITEBACK);
+ bdi_wb_stat_mod(inode, 1);
}

static struct fuse_writepage_args *fuse_writepage_args_setup(struct folio *folio,
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index bb35f8fa4973..fb042e593c16 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -46,6 +46,9 @@ extern struct list_head bdi_list;

extern struct workqueue_struct *bdi_wq;

+static inline struct bdi_writeback_ctx *
+fetch_bdi_writeback_ctx(struct inode *inode);
+
static inline bool wb_has_dirty_io(struct bdi_writeback *wb)
{
return test_bit(WB_has_dirty_io, &wb->state);
@@ -103,6 +106,20 @@ static inline s64 wb_stat_sum(struct bdi_writeback *wb, enum wb_stat_item item)

extern void wb_writeout_inc(struct bdi_writeback *wb);

+static inline void bdi_wb_stat_mod(struct inode *inode, s64 amount)
+{
+ struct bdi_writeback_ctx *bdi_wb_ctx = fetch_bdi_writeback_ctx(inode);
+
+ wb_stat_mod(&bdi_wb_ctx->wb, WB_WRITEBACK, amount);
+}
+
+static inline void bdi_wb_writeout_inc(struct inode *inode)
+{
+ struct bdi_writeback_ctx *bdi_wb_ctx = fetch_bdi_writeback_ctx(inode);
+
+ wb_writeout_inc(&bdi_wb_ctx->wb);
+}
+
/*
* maximal error of a stat counter.
*/
--
2.25.1