On Wed, Aug 11, 2021 at 01:25:14PM +0200, Jan Kara wrote:
Well, non-default bdi_writeback structures do hold bdi reference - see
wb_exit() which drops the reference. I think the problem rather was that a
block device's inode->i_wb was pointing to the default bdi_writeback
structure and that got freed after bdi_put() before block device inode was
shutdown through bdput()... So what I think we need is that if the inode
references the default writeback structure, it actually holds a reference
to the bdi.
Qian, can you test the patch below instead of the one I sent yesterday?
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index cd06dca232c3..edfb7ce2cc93 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -283,8 +283,7 @@ static int wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi,
memset(wb, 0, sizeof(*wb));
- if (wb != &bdi->wb)
- bdi_get(bdi);
+ bdi_get(bdi);
wb->bdi = bdi;
wb->last_old_flush = jiffies;
INIT_LIST_HEAD(&wb->b_dirty);
@@ -362,8 +361,7 @@ static void wb_exit(struct bdi_writeback *wb)
percpu_counter_destroy(&wb->stat[i]);
fprop_local_destroy_percpu(&wb->completions);
- if (wb != &wb->bdi->wb)
- bdi_put(wb->bdi);
+ bdi_put(wb->bdi);
}
#ifdef CONFIG_CGROUP_WRITEBACK