]> www.infradead.org Git - users/hch/block.git/commit
loop: make autoclear operation synchronous again loop-fix.2
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>
Wed, 26 Jan 2022 15:50:04 +0000 (16:50 +0100)
commitde9a6eaedbc570c16f7c5f1db4bf762b23a2355c
treec1f6f253a031de7aaeec32c52bbbf74bc65ae55e
parentac502fc0928d92c6e9d1f5a46a29cd9d6c8c7f1d
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>
Tested-by: syzbot <syzbot+643e4ce4b6ad1347d372@syzkaller.appspotmail.com>
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>
drivers/block/loop.c
drivers/block/loop.h