memstick/mspro_block: simplify refcounting
authorChristoph Hellwig <hch@lst.de>
Tue, 15 Feb 2022 09:45:13 +0000 (10:45 +0100)
committerJens Axboe <axboe@kernel.dk>
Thu, 17 Feb 2022 02:44:24 +0000 (19:44 -0700)
Implement the ->free_disk method to free the msb_data structure only once
the last gendisk reference goes away instead of keeping a local
refcount.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20220215094514.3828912-5-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/memstick/core/mspro_block.c

index 7ea312f0840e01bc231fc782ad629eee68959788..725ba74ded308ab26e80fa2d6d4798690af853db 100644 (file)
@@ -133,7 +133,6 @@ struct mspro_devinfo {
 
 struct mspro_block_data {
        struct memstick_dev   *card;
-       unsigned int          usage_count;
        unsigned int          caps;
        struct gendisk        *disk;
        struct request_queue  *queue;
@@ -178,48 +177,16 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error);
 
 /*** Block device ***/
 
-static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode)
-{
-       struct gendisk *disk = bdev->bd_disk;
-       struct mspro_block_data *msb = disk->private_data;
-       int rc = -ENXIO;
-
-       mutex_lock(&mspro_block_disk_lock);
-
-       if (msb && msb->card)
-               msb->usage_count++;
-
-       mutex_unlock(&mspro_block_disk_lock);
-
-       return rc;
-}
-
-
-static void mspro_block_disk_release(struct gendisk *disk)
+static void mspro_block_bd_free_disk(struct gendisk *disk)
 {
        struct mspro_block_data *msb = disk->private_data;
        int disk_id = MINOR(disk_devt(disk)) >> MSPRO_BLOCK_PART_SHIFT;
 
        mutex_lock(&mspro_block_disk_lock);
-
-       if (msb) {
-               if (msb->usage_count)
-                       msb->usage_count--;
-
-               if (!msb->usage_count) {
-                       kfree(msb);
-                       disk->private_data = NULL;
-                       idr_remove(&mspro_block_disk_idr, disk_id);
-                       put_disk(disk);
-               }
-       }
-
+       idr_remove(&mspro_block_disk_idr, disk_id);
        mutex_unlock(&mspro_block_disk_lock);
-}
 
-static void mspro_block_bd_release(struct gendisk *disk, fmode_t mode)
-{
-       mspro_block_disk_release(disk);
+       kfree(msb);
 }
 
 static int mspro_block_bd_getgeo(struct block_device *bdev,
@@ -235,10 +202,9 @@ static int mspro_block_bd_getgeo(struct block_device *bdev,
 }
 
 static const struct block_device_operations ms_block_bdops = {
-       .open    = mspro_block_bd_open,
-       .release = mspro_block_bd_release,
-       .getgeo  = mspro_block_bd_getgeo,
-       .owner   = THIS_MODULE
+       .owner          = THIS_MODULE,
+       .getgeo         = mspro_block_bd_getgeo,
+       .free_disk      = mspro_block_bd_free_disk,
 };
 
 /*** Information ***/
@@ -1221,7 +1187,6 @@ static int mspro_block_init_disk(struct memstick_dev *card)
        msb->disk->first_minor = disk_id << MSPRO_BLOCK_PART_SHIFT;
        msb->disk->minors = 1 << MSPRO_BLOCK_PART_SHIFT;
        msb->disk->fops = &ms_block_bdops;
-       msb->usage_count = 1;
        msb->disk->private_data = msb;
 
        sprintf(msb->disk->disk_name, "mspblk%d", disk_id);
@@ -1339,7 +1304,7 @@ static void mspro_block_remove(struct memstick_dev *card)
        mspro_block_data_clear(msb);
        mutex_unlock(&mspro_block_disk_lock);
 
-       mspro_block_disk_release(msb->disk);
+       put_disk(msb->disk);
        memstick_set_drvdata(card, NULL);
 }