Commit 498ef5c7 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

loop: suppress uevents while reconfiguring the device

Currently, udev change event is generated for a loop device before the
device is ready for IO. Due to serialization on lo->lo_mutex in
lo_open() this does not matter because anybody is able to open the
device and do IO only after the configuration is finished. However this
synchronization in lo_open() is going away so make sure userspace
reacting to the change event will see the new device state by generating
the event only when the device is setup.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20220330052917.2566582-13-hch@lst.deSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent d2c7f56f
...@@ -569,6 +569,10 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, ...@@ -569,6 +569,10 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
if (!file) if (!file)
return -EBADF; return -EBADF;
/* suppress uevents while reconfiguring the device */
dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 1);
is_loop = is_loop_device(file); is_loop = is_loop_device(file);
error = loop_global_lock_killable(lo, is_loop); error = loop_global_lock_killable(lo, is_loop);
if (error) if (error)
...@@ -623,13 +627,18 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, ...@@ -623,13 +627,18 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
fput(old_file); fput(old_file);
if (partscan) if (partscan)
loop_reread_partitions(lo); loop_reread_partitions(lo);
return 0;
error = 0;
done:
/* enable and uncork uevent now that we are done */
dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0);
return error;
out_err: out_err:
loop_global_unlock(lo, is_loop); loop_global_unlock(lo, is_loop);
out_putf: out_putf:
fput(file); fput(file);
return error; goto done;
} }
/* loop sysfs attributes */ /* loop sysfs attributes */
...@@ -994,6 +1003,9 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, ...@@ -994,6 +1003,9 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
/* This is safe, since we have a reference from open(). */ /* This is safe, since we have a reference from open(). */
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
/* suppress uevents while reconfiguring the device */
dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 1);
/* /*
* If we don't hold exclusive handle for the device, upgrade to it * If we don't hold exclusive handle for the device, upgrade to it
* here to avoid changing device under exclusive owner. * here to avoid changing device under exclusive owner.
...@@ -1096,7 +1108,12 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, ...@@ -1096,7 +1108,12 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
loop_reread_partitions(lo); loop_reread_partitions(lo);
if (!(mode & FMODE_EXCL)) if (!(mode & FMODE_EXCL))
bd_abort_claiming(bdev, loop_configure); bd_abort_claiming(bdev, loop_configure);
return 0;
error = 0;
done:
/* enable and uncork uevent now that we are done */
dev_set_uevent_suppress(disk_to_dev(lo->lo_disk), 0);
return error;
out_unlock: out_unlock:
loop_global_unlock(lo, is_loop); loop_global_unlock(lo, is_loop);
...@@ -1107,7 +1124,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, ...@@ -1107,7 +1124,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
fput(file); fput(file);
/* This is safe: open() is still holding a reference. */ /* This is safe: open() is still holding a reference. */
module_put(THIS_MODULE); module_put(THIS_MODULE);
return error; goto done;
} }
static void __loop_clr_fd(struct loop_device *lo, bool release) static void __loop_clr_fd(struct loop_device *lo, bool release)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment