Implemented bdi_inc_writeback() to increase the writeback context
count and called this function at XFS mount time to set the desired
count.

Signed-off-by: Kundan Kumar <[email protected]>
Signed-off-by: Anuj Gupta <[email protected]>
---
 fs/xfs/xfs_super.c          |  2 ++
 include/linux/backing-dev.h |  1 +
 mm/backing-dev.c            | 58 +++++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index b3ec9141d902..aa97b59f53c6 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1783,6 +1783,8 @@ xfs_fs_fill_super(
        if (error)
                goto out_free_sb;
 
+       bdi_inc_writeback(sb->s_bdi, mp->m_sb.sb_agcount);
+
        /*
         * V4 support is undergoing deprecation.
         *
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 14f53183b8d1..89a465e1964f 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -40,6 +40,7 @@ void wb_start_background_writeback(struct bdi_writeback *wb);
 void wb_workfn(struct work_struct *work);
 
 void wb_wait_for_completion(struct wb_completion *done);
+int bdi_inc_writeback(struct backing_dev_info *bdi, int nwriteback);
 
 extern spinlock_t bdi_lock;
 extern struct list_head bdi_list;
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 5bfb9bf3ce52..e450b3a9b952 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -1219,6 +1219,64 @@ struct backing_dev_info *bdi_alloc(int node_id)
 }
 EXPORT_SYMBOL(bdi_alloc);
 
+int bdi_inc_writeback(struct backing_dev_info *bdi, int nwritebacks)
+{
+       struct bdi_writeback_ctx **wb_ctx;
+       int ret = 0;
+
+       if (nwritebacks <= bdi->nr_wb_ctx)
+               return ret;
+
+       wb_ctx = kcalloc(nwritebacks, sizeof(struct bdi_writeback_ctx *),
+                        GFP_KERNEL);
+       if (!wb_ctx)
+               return -ENOMEM;
+
+       for (int i = 0; i < bdi->nr_wb_ctx; i++)
+               wb_ctx[i] = bdi->wb_ctx[i];
+
+       for (int i = bdi->nr_wb_ctx; i < nwritebacks; i++) {
+               wb_ctx[i] = (struct bdi_writeback_ctx *)
+                       kzalloc(sizeof(struct bdi_writeback_ctx), GFP_KERNEL);
+               if (!wb_ctx[i]) {
+                       pr_err("Failed to allocate %d", i);
+                       while (--i >= bdi->nr_wb_ctx)
+                               kfree(wb_ctx[i]);
+                       kfree(wb_ctx);
+                       return -ENOMEM;
+               }
+               INIT_LIST_HEAD(&wb_ctx[i]->wb_list);
+               init_waitqueue_head(&wb_ctx[i]->wb_waitq);
+
+#ifdef CONFIG_CGROUP_WRITEBACK
+               INIT_RADIX_TREE(&wb_ctx[i]->cgwb_tree, GFP_ATOMIC);
+               init_rwsem(&wb_ctx[i]->wb_switch_rwsem);
+#endif
+               ret = wb_init(&wb_ctx[i]->wb, wb_ctx[i], bdi, GFP_KERNEL);
+               if (!ret) {
+#ifdef CONFIG_CGROUP_WRITEBACK
+                       wb_ctx[i]->wb.memcg_css = &root_mem_cgroup->css;
+                       wb_ctx[i]->wb.blkcg_css = blkcg_root_css;
+#endif
+               } else {
+                       while (--i >= bdi->nr_wb_ctx)
+                               kfree(wb_ctx[i]);
+                       kfree(wb_ctx);
+                       return ret;
+               }
+               cgwb_bdi_register(bdi, wb_ctx[i]);
+               set_bit(WB_registered, &wb_ctx[i]->wb.state);
+       }
+
+       spin_lock_bh(&bdi_lock);
+       kfree(bdi->wb_ctx);
+       bdi->wb_ctx = wb_ctx;
+       bdi->nr_wb_ctx = nwritebacks;
+       spin_unlock_bh(&bdi_lock);
+       return 0;
+}
+EXPORT_SYMBOL(bdi_inc_writeback);
+
 static struct rb_node **bdi_lookup_rb_node(u64 id, struct rb_node **parentp)
 {
        struct rb_node **p = &bdi_tree.rb_node;
-- 
2.25.1



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to