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

memstick/ms_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-3-hch@lst.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 76792055
Loading
Loading
Loading
Loading
+15 −49
Original line number Diff line number Diff line
@@ -1943,22 +1943,6 @@ static void msb_io_work(struct work_struct *work)
static DEFINE_IDR(msb_disk_idr); /*set of used disk numbers */
static DEFINE_MUTEX(msb_disk_lock); /* protects against races in open/release */

static int msb_bd_open(struct block_device *bdev, fmode_t mode)
{
	struct gendisk *disk = bdev->bd_disk;
	struct msb_data *msb = disk->private_data;

	dbg_verbose("block device open");

	mutex_lock(&msb_disk_lock);

	if (msb && msb->card)
		msb->usage_count++;

	mutex_unlock(&msb_disk_lock);
	return 0;
}

static void msb_data_clear(struct msb_data *msb)
{
	kfree(msb->boot_page);
@@ -1968,39 +1952,23 @@ static void msb_data_clear(struct msb_data *msb)
	msb->card = NULL;
}

static int msb_disk_release(struct gendisk *disk)
static int msb_bd_getgeo(struct block_device *bdev,
				 struct hd_geometry *geo)
{
	struct msb_data *msb = bdev->bd_disk->private_data;
	*geo = msb->geometry;
	return 0;
}

static void msb_bd_free_disk(struct gendisk *disk)
{
	struct msb_data *msb = disk->private_data;

	dbg_verbose("block device release");
	mutex_lock(&msb_disk_lock);

	if (msb) {
		if (msb->usage_count)
			msb->usage_count--;

		if (!msb->usage_count) {
			disk->private_data = NULL;
	idr_remove(&msb_disk_idr, msb->disk_id);
			put_disk(disk);
			kfree(msb);
		}
	}
	mutex_unlock(&msb_disk_lock);
	return 0;
}

static void msb_bd_release(struct gendisk *disk, fmode_t mode)
{
	msb_disk_release(disk);
}

static int msb_bd_getgeo(struct block_device *bdev,
				 struct hd_geometry *geo)
{
	struct msb_data *msb = bdev->bd_disk->private_data;
	*geo = msb->geometry;
	return 0;
	kfree(msb);
}

static blk_status_t msb_queue_rq(struct blk_mq_hw_ctx *hctx,
@@ -2096,10 +2064,9 @@ static void msb_start(struct memstick_dev *card)
}

static const struct block_device_operations msb_bdops = {
	.open    = msb_bd_open,
	.release = msb_bd_release,
	.owner		= THIS_MODULE,
	.getgeo		= msb_bd_getgeo,
	.owner   = THIS_MODULE
	.free_disk	= msb_bd_free_disk, 
};

static const struct blk_mq_ops msb_mq_ops = {
@@ -2147,7 +2114,6 @@ static int msb_init_disk(struct memstick_dev *card)
	set_capacity(msb->disk, capacity);
	dbg("Set total disk size to %lu sectors", capacity);

	msb->usage_count = 1;
	msb->io_queue = alloc_ordered_workqueue("ms_block", WQ_MEM_RECLAIM);
	INIT_WORK(&msb->io_work, msb_io_work);
	sg_init_table(msb->prealloc_sg, MS_BLOCK_MAX_SEGS+1);
@@ -2229,7 +2195,7 @@ static void msb_remove(struct memstick_dev *card)
	msb_data_clear(msb);
	mutex_unlock(&msb_disk_lock);

	msb_disk_release(msb->disk);
	put_disk(msb->disk);
	memstick_set_drvdata(card, NULL);
}

+0 −1
Original line number Diff line number Diff line
@@ -143,7 +143,6 @@ struct ms_boot_page {
} __packed;

struct msb_data {
	unsigned int			usage_count;
	struct memstick_dev		*card;
	struct gendisk			*disk;
	struct request_queue		*queue;