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