]> git.baikalelectronics.ru Git - kernel.git/commit
loop: Fix mount(2) failure due to race with LOOP_SET_FD
authorJan Kara <jack@suse.cz>
Tue, 30 Jul 2019 11:10:14 +0000 (13:10 +0200)
committerJens Axboe <axboe@kernel.dk>
Tue, 30 Jul 2019 19:16:57 +0000 (13:16 -0600)
commit9496a43a388c94a26ae01467fd1c90f90d2bfa70
treeb384005acf4d525150d0a8eb0d7a62b33a44e798
parent3528497f7b6773f27cb1aa2ff7acb410aad7abfd
loop: Fix mount(2) failure due to race with LOOP_SET_FD

Commit d1b363ec96d2 ("loop: Don't change loop device under exclusive
opener") made LOOP_SET_FD ioctl acquire exclusive block device reference
while it updates loop device binding. However this can make perfectly
valid mount(2) fail with EBUSY due to racing LOOP_SET_FD holding
temporarily the exclusive bdev reference in cases like this:

for i in {a..z}{a..z}; do
        dd if=/dev/zero of=$i.image bs=1k count=0 seek=1024
        mkfs.ext2 $i.image
        mkdir mnt$i
done

echo "Run"
for i in {a..z}{a..z}; do
        mount -o loop -t ext2 $i.image mnt$i &
done

Fix the problem by not getting full exclusive bdev reference in
LOOP_SET_FD but instead just mark the bdev as being claimed while we
update the binding information. This just blocks new exclusive openers
instead of failing them with EBUSY thus fixing the problem.

Fixes: d1b363ec96d2 ("loop: Don't change loop device under exclusive opener")
Cc: stable@vger.kernel.org
Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/loop.c
fs/block_dev.c
include/linux/fs.h