Re: [PATCH v2 04/16] writeback: affine inode to a writeback ctx within a bdi

Jan Kara
2025-10-21T11:58:37Z

On Tue 14-10-25 17:38:33, Kundan Kumar wrote:
> Affine inode to a writeback context. This helps in minimizing the
> filesytem fragmentation due to inode being processed by different
> threads.
>
> To support parallel writeback, wire up a new superblock operation
> get_inode_wb_ctx(). Filesystems can override this callback and select
> desired writeback context for a inode. FS can use the wb context based
> on its geometry and also use 64 bit inode numbers.
>
> If a filesystem doesn't implement this callback, it defaults to
> DEFALT_WB_CTX = 0, maintaining its original behavior.
>
> An example implementation for XFS is provided, where XFS selects the
> writeback context based on its Allocation Group number.
>
> Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
> Signed-off-by: Kundan Kumar <kundan.kumar@samsung.com>

As Christoph asked in other patch. Please introduce generic writeback
changes in one patch and then provide xfs implementation of
xfs_get_inode_wb_ctx() in another patch. Thanks.

Honza

> ---
> fs/fs-writeback.c | 3 ++-
> fs/xfs/xfs_super.c | 13 +++++++++++++
> include/linux/backing-dev.h | 5 ++++-
> include/linux/fs.h | 1 +
> 4 files changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index 0715a7617391..56c048e22f72 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -265,7 +265,8 @@ void __inode_attach_wb(struct inode *inode, struct folio *folio)
> {
> struct backing_dev_info *bdi = inode_to_bdi(inode);
> struct bdi_writeback *wb = NULL;
> - struct bdi_writeback_ctx *bdi_writeback_ctx = bdi->wb_ctx[0];
> + struct bdi_writeback_ctx *bdi_writeback_ctx =
> + fetch_bdi_writeback_ctx(inode);
>
> if (inode_cgwb_enabled(inode)) {
> struct cgroup_subsys_state *memcg_css;
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index bb0a82635a77..b3ec9141d902 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -53,6 +53,7 @@
> #include <linux/magic.h>
> #include <linux/fs_context.h>
> #include <linux/fs_parser.h>
> +#include <linux/backing-dev.h>
>
> static const struct super_operations xfs_super_operations;
>
> @@ -1294,6 +1295,17 @@ xfs_fs_show_stats(
> return 0;
> }
>
> +static struct bdi_writeback_ctx *
> +xfs_get_inode_wb_ctx(
> + struct inode *inode)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + struct backing_dev_info *bdi = inode_to_bdi(inode);
> + xfs_agino_t agno = XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino);
> +
> + return bdi->wb_ctx[agno % bdi->nr_wb_ctx];
> +}
> +
> static const struct super_operations xfs_super_operations = {
> .alloc_inode = xfs_fs_alloc_inode,
> .destroy_inode = xfs_fs_destroy_inode,
> @@ -1310,6 +1322,7 @@ static const struct super_operations xfs_super_operations = {
> .free_cached_objects = xfs_fs_free_cached_objects,
> .shutdown = xfs_fs_shutdown,
> .show_stats = xfs_fs_show_stats,
> + .get_inode_wb_ctx = xfs_get_inode_wb_ctx,
> };
>
> static int
> diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
> index 951ab5497500..59bbb69d300c 100644
> --- a/include/linux/backing-dev.h
> +++ b/include/linux/backing-dev.h
> @@ -148,6 +148,7 @@ static inline bool mapping_can_writeback(struct address_space *mapping)
> return inode_to_bdi(mapping->host)->capabilities & BDI_CAP_WRITEBACK;
> }
>
> +#define DEFAULT_WB_CTX 0
> #define for_each_bdi_wb_ctx(bdi, wbctx) \
> for (int __i = 0; __i < (bdi)->nr_wb_ctx \
> && ((wbctx) = (bdi)->wb_ctx[__i]) != NULL; __i++)
> @@ -157,7 +158,9 @@ fetch_bdi_writeback_ctx(struct inode *inode)
> {
> struct backing_dev_info *bdi = inode_to_bdi(inode);
>
> - return bdi->wb_ctx[0];
> + if (inode->i_sb->s_op->get_inode_wb_ctx)
> + return inode->i_sb->s_op->get_inode_wb_ctx(inode);
> + return bdi->wb_ctx[DEFAULT_WB_CTX];
> }
>
> #ifdef CONFIG_CGROUP_WRITEBACK
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 754fec84f350..5199b0d49fa5 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2379,6 +2379,7 @@ struct super_operations {
> */
> int (*remove_bdev)(struct super_block *sb, struct block_device *bdev);
> void (*shutdown)(struct super_block *sb);
> + struct bdi_writeback_ctx *(*get_inode_wb_ctx)(struct inode *inode);
> };
>
> /*
> --
> 2.25.1
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR