]> www.infradead.org Git - users/hch/block.git/commitdiff
loop: implement ->free_disk
authorChristoph Hellwig <hch@lst.de>
Tue, 15 Mar 2022 13:50:25 +0000 (14:50 +0100)
committerChristoph Hellwig <hch@lst.de>
Tue, 29 Mar 2022 15:44:34 +0000 (17:44 +0200)
Ensure that the lo_device which is stored in the gendisk private
data is valid until the gendisk is freed.  Currently the loop driver
uses a lot of effort to make sure a device is not freed when it is
still in use, but to to fix a potential deadlock this will be relaxed
a bit soon.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
drivers/block/loop.c

index a5dd259958ee2c0c2974ca16f797444dfde665dd..b3170e8cdbe95a1fc55abf173355afd951793462 100644 (file)
@@ -1765,6 +1765,14 @@ out_unlock:
        mutex_unlock(&lo->lo_mutex);
 }
 
+static void lo_free_disk(struct gendisk *disk)
+{
+       struct loop_device *lo = disk->private_data;
+
+       mutex_destroy(&lo->lo_mutex);
+       kfree(lo);
+}
+
 static const struct block_device_operations lo_fops = {
        .owner =        THIS_MODULE,
        .open =         lo_open,
@@ -1773,6 +1781,7 @@ static const struct block_device_operations lo_fops = {
 #ifdef CONFIG_COMPAT
        .compat_ioctl = lo_compat_ioctl,
 #endif
+       .free_disk =    lo_free_disk,
 };
 
 /*
@@ -2064,15 +2073,14 @@ static void loop_remove(struct loop_device *lo)
 {
        /* Make this loop device unreachable from pathname. */
        del_gendisk(lo->lo_disk);
-       blk_cleanup_disk(lo->lo_disk);
+       blk_cleanup_queue(lo->lo_disk->queue);
        blk_mq_free_tag_set(&lo->tag_set);
 
        mutex_lock(&loop_ctl_mutex);
        idr_remove(&loop_index_idr, lo->lo_number);
        mutex_unlock(&loop_ctl_mutex);
-       /* There is no route which can find this loop device. */
-       mutex_destroy(&lo->lo_mutex);
-       kfree(lo);
+
+       put_disk(lo->lo_disk);
 }
 
 static void loop_probe(dev_t dev)