On Mon, Apr 15, 2024 at 05:26:19PM +0800, Ming Lei wrote: > Hello, > > On Tue, Jan 23, 2024 at 02:26:21PM +0100, Christian Brauner wrote: > > Signed-off-by: Christian Brauner <brauner@xxxxxxxxxx> > > --- > > drivers/md/dm.c | 23 +++++++++++++---------- > > drivers/md/md.c | 12 ++++++------ > > drivers/md/md.h | 2 +- > > include/linux/device-mapper.h | 2 +- > > 4 files changed, 21 insertions(+), 18 deletions(-) > > > > diff --git a/drivers/md/dm.c b/drivers/md/dm.c > > index 8dcabf84d866..87de5b5682ad 100644 > > --- a/drivers/md/dm.c > > +++ b/drivers/md/dm.c > > ... > > > @@ -775,7 +778,7 @@ static void close_table_device(struct table_device *td, struct mapped_device *md > > { > > if (md->disk->slave_dir) > > bd_unlink_disk_holder(td->dm_dev.bdev, md->disk); > > - bdev_release(td->dm_dev.bdev_handle); > > + fput(td->dm_dev.bdev_file); > > The above change caused regression on 'dmsetup remove_all'. > > blkdev_release() is delayed because of fput(), so dm_lock_for_deletion > returns -EBUSY, then this dm disk is skipped in remove_all(). > > Force to mark DMF_DEFERRED_REMOVE might solve it, but need our device > mapper guys to check if it is safe. > > Or other better solution? Yeah, I think there is. You can just switch all fput() instances in device mapper to bdev_fput() which is mainline now. This will yield the device and make it able to be reclaimed. Should be as simple as the patch below. Could you test this and send a patch based on this (I'm on a prolonged vacation so I don't have time right now.): diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 56aa2a8b9d71..0f681a1e70af 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -765,7 +765,7 @@ static struct table_device *open_table_device(struct mapped_device *md, return td; out_blkdev_put: - fput(bdev_file); + bdev_fput(bdev_file); out_free_td: kfree(td); return ERR_PTR(r); @@ -778,7 +778,7 @@ static void close_table_device(struct table_device *td, struct mapped_device *md { if (md->disk->slave_dir) bd_unlink_disk_holder(td->dm_dev.bdev, md->disk); - fput(td->dm_dev.bdev_file); + bdev_fput(td->dm_dev.bdev_file); put_dax(td->dm_dev.dax_dev); list_del(&td->list); kfree(td);