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

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.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent d2c7f56f
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -569,6 +569,10 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,

	if (!file)
		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);
	error = loop_global_lock_killable(lo, is_loop);
	if (error)
@@ -623,13 +627,18 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
	fput(old_file);
	if (partscan)
		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:
	loop_global_unlock(lo, is_loop);
out_putf:
	fput(file);
	return error;
	goto done;
}

/* loop sysfs attributes */
@@ -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(). */
	__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
	 * here to avoid changing device under exclusive owner.
@@ -1096,7 +1108,12 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
		loop_reread_partitions(lo);
	if (!(mode & FMODE_EXCL))
		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:
	loop_global_unlock(lo, is_loop);
@@ -1107,7 +1124,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
	fput(file);
	/* This is safe: open() is still holding a reference. */
	module_put(THIS_MODULE);
	return error;
	goto done;
}

static void __loop_clr_fd(struct loop_device *lo, bool release)