Skip to content

Commit

Permalink
memstick/ms_block: simplify refcounting
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Jens Axboe committed Feb 17, 2022
1 parent 7679205 commit e2efa07
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 50 deletions.
64 changes: 15 additions & 49 deletions drivers/memstick/core/ms_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
{
Expand All @@ -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)
{
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down
1 change: 0 additions & 1 deletion drivers/memstick/core/ms_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit e2efa07

Please sign in to comment.