loop: raise media_change event
authorMatteo Croce <mcroce@microsoft.com>
Mon, 12 Jul 2021 23:05:30 +0000 (01:05 +0200)
committerJens Axboe <axboe@kernel.dk>
Mon, 2 Aug 2021 19:37:29 +0000 (13:37 -0600)
Make the loop device raise a DISK_MEDIA_CHANGE event on attach or detach.

# udevadm monitor -up |grep -e DISK_MEDIA_CHANGE -e DEVNAME &

# losetup -f zero
[    7.454235] loop0: detected capacity change from 0 to 16384
DISK_MEDIA_CHANGE=1
DEVNAME=/dev/loop0
DEVNAME=/dev/loop0
DEVNAME=/dev/loop0

# losetup -f zero
[   10.205245] loop1: detected capacity change from 0 to 16384
DISK_MEDIA_CHANGE=1
DEVNAME=/dev/loop1
DEVNAME=/dev/loop1
DEVNAME=/dev/loop1

# losetup -f zero2
[   13.532368] loop2: detected capacity change from 0 to 40960
DISK_MEDIA_CHANGE=1
DEVNAME=/dev/loop2
DEVNAME=/dev/loop2

# losetup -D
DEVNAME=/dev/loop1
DISK_MEDIA_CHANGE=1
DEVNAME=/dev/loop1
DEVNAME=/dev/loop2
DISK_MEDIA_CHANGE=1
DEVNAME=/dev/loop2
DEVNAME=/dev/loop0
DISK_MEDIA_CHANGE=1
DEVNAME=/dev/loop0

Signed-off-by: Matteo Croce <mcroce@microsoft.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Tested-by: Luca Boccassi <bluca@debian.org>
Link: https://lore.kernel.org/r/20210712230530.29323-7-mcroce@linux.microsoft.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/loop.c

index a03ef50..f8486d9 100644 (file)
@@ -774,6 +774,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
                goto out_err;
 
        /* and ... switch */
+       disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);
        blk_mq_freeze_queue(lo->lo_queue);
        mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
        lo->lo_backing_file = file;
@@ -1257,6 +1258,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
                goto out_unlock;
        }
 
+       disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);
        set_disk_ro(lo->lo_disk, (lo->lo_flags & LO_FLAGS_READ_ONLY) != 0);
 
        INIT_WORK(&lo->rootcg_work, loop_rootcg_workfn);
@@ -1410,6 +1412,7 @@ static int __loop_clr_fd(struct loop_device *lo, bool release)
 
        partscan = lo->lo_flags & LO_FLAGS_PARTSCAN && bdev;
        lo_number = lo->lo_number;
+       disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);
 out_unlock:
        mutex_unlock(&lo->lo_mutex);
        if (partscan) {
@@ -2386,6 +2389,8 @@ static int loop_add(int i)
        disk->fops              = &lo_fops;
        disk->private_data      = lo;
        disk->queue             = lo->lo_queue;
+       disk->events            = DISK_EVENT_MEDIA_CHANGE;
+       disk->event_flags       = DISK_EVENT_FLAG_UEVENT;
        sprintf(disk->disk_name, "loop%d", i);
        add_disk(disk);
        mutex_unlock(&loop_ctl_mutex);