]> www.infradead.org Git - users/hch/block.git/commit
loop: make autoclear operation synchronous again loop-fix.3
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Wed, 26 Jan 2022 07:45:00 +0000 (08:45 +0100)
committerChristoph Hellwig <hch@lst.de>
Fri, 28 Jan 2022 12:58:53 +0000 (13:58 +0100)
commit227fb6305e40f0559fc8f44a6edc8cbcc6d9048a
tree97f6fccc3b2891d4d66d7e33e84c52efd62b2f90
parent83ffc7b0ee1998cc0ad00a55bf82b3b2601f6f2d
loop: make autoclear operation synchronous again

The kernel test robot is reporting that xfstest can fail at

  umount ext2 on xfs
  umount xfs

sequence, for commit 322c4293ecc58110 ("loop: make autoclear operation
asynchronous") broke what commit ("loop: Make explicit loop device
destruction lazy") wanted to achieve.

Although we cannot guarantee that nobody is holding a reference when
"umount xfs" is called, we should try to close a race window opened
by asynchronous autoclear operation.

It turned out that there is no need to call flush_workqueue() from
__loop_clr_fd(), for blk_mq_freeze_queue() blocks until all pending
"struct work_struct" are processed by loop_process_work().

Revert commit 322c4293ecc58110 ("loop: make autoclear operation
asynchronous"), and simply defer calling destroy_workqueue() till
loop_remove() after ensuring that the worker rbtree and repaing
timer are kept alive while the loop device exists.

Since a loop device is likely reused after once created thanks to
ioctl(LOOP_CTL_GET_FREE), being unable to destroy corresponding WQ
when ioctl(LOOP_CLR_FD) is called should be an acceptable waste.

Reported-by: kernel test robot <oliver.sang@intel.com>
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
[hch: rebased, keep the work rbtree and timer around longer]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Tested-by: Darrick J. Wong <djwong@kernel.org>
Tested-by: syzbot <syzbot+643e4ce4b6ad1347d372@syzkaller.appspotmail.com>
drivers/block/loop.c
drivers/block/loop.h