Commit 185ed423 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

memstick/mspro_block: simplify refcounting



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: default avatarChristoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20220215094514.3828912-5-hch@lst.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 6dab421b
Loading
Loading
Loading
Loading
+7 −42
Original line number Diff line number Diff line
@@ -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);
		}
	}

	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,
	.owner		= THIS_MODULE,
	.getgeo		= mspro_block_bd_getgeo,
	.owner   = THIS_MODULE
	.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);
}