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: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20220215094514.3828912-3-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
76792055c4
commit
e2efa07966
@ -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,33 +1952,6 @@ static void msb_data_clear(struct msb_data *msb)
|
||||
msb->card = NULL;
|
||||
}
|
||||
|
||||
static int msb_disk_release(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)
|
||||
{
|
||||
@ -2003,6 +1960,17 @@ static int msb_bd_getgeo(struct block_device *bdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msb_bd_free_disk(struct gendisk *disk)
|
||||
{
|
||||
struct msb_data *msb = disk->private_data;
|
||||
|
||||
mutex_lock(&msb_disk_lock);
|
||||
idr_remove(&msb_disk_idr, msb->disk_id);
|
||||
mutex_unlock(&msb_disk_lock);
|
||||
|
||||
kfree(msb);
|
||||
}
|
||||
|
||||
static blk_status_t msb_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
const struct blk_mq_queue_data *bd)
|
||||
{
|
||||
@ -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,
|
||||
.getgeo = msb_bd_getgeo,
|
||||
.owner = THIS_MODULE
|
||||
.owner = THIS_MODULE,
|
||||
.getgeo = msb_bd_getgeo,
|
||||
.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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user