Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 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>

authored by

Christoph Hellwig and committed by
Jens Axboe
185ed423 6dab421b

+7 -42
+7 -42
drivers/memstick/core/mspro_block.c
··· 133 133 134 134 struct mspro_block_data { 135 135 struct memstick_dev *card; 136 - unsigned int usage_count; 137 136 unsigned int caps; 138 137 struct gendisk *disk; 139 138 struct request_queue *queue; ··· 177 178 178 179 /*** Block device ***/ 179 180 180 - static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode) 181 - { 182 - struct gendisk *disk = bdev->bd_disk; 183 - struct mspro_block_data *msb = disk->private_data; 184 - int rc = -ENXIO; 185 - 186 - mutex_lock(&mspro_block_disk_lock); 187 - 188 - if (msb && msb->card) 189 - msb->usage_count++; 190 - 191 - mutex_unlock(&mspro_block_disk_lock); 192 - 193 - return rc; 194 - } 195 - 196 - 197 - static void mspro_block_disk_release(struct gendisk *disk) 181 + static void mspro_block_bd_free_disk(struct gendisk *disk) 198 182 { 199 183 struct mspro_block_data *msb = disk->private_data; 200 184 int disk_id = MINOR(disk_devt(disk)) >> MSPRO_BLOCK_PART_SHIFT; 201 185 202 186 mutex_lock(&mspro_block_disk_lock); 203 - 204 - if (msb) { 205 - if (msb->usage_count) 206 - msb->usage_count--; 207 - 208 - if (!msb->usage_count) { 209 - kfree(msb); 210 - disk->private_data = NULL; 211 - idr_remove(&mspro_block_disk_idr, disk_id); 212 - put_disk(disk); 213 - } 214 - } 215 - 187 + idr_remove(&mspro_block_disk_idr, disk_id); 216 188 mutex_unlock(&mspro_block_disk_lock); 217 - } 218 189 219 - static void mspro_block_bd_release(struct gendisk *disk, fmode_t mode) 220 - { 221 - mspro_block_disk_release(disk); 190 + kfree(msb); 222 191 } 223 192 224 193 static int mspro_block_bd_getgeo(struct block_device *bdev, ··· 202 235 } 203 236 204 237 static const struct block_device_operations ms_block_bdops = { 205 - .open = mspro_block_bd_open, 206 - .release = mspro_block_bd_release, 207 - .getgeo = mspro_block_bd_getgeo, 208 - .owner = THIS_MODULE 238 + .owner = THIS_MODULE, 239 + .getgeo = mspro_block_bd_getgeo, 240 + .free_disk = mspro_block_bd_free_disk, 209 241 }; 210 242 211 243 /*** Information ***/ ··· 1187 1221 msb->disk->first_minor = disk_id << MSPRO_BLOCK_PART_SHIFT; 1188 1222 msb->disk->minors = 1 << MSPRO_BLOCK_PART_SHIFT; 1189 1223 msb->disk->fops = &ms_block_bdops; 1190 - msb->usage_count = 1; 1191 1224 msb->disk->private_data = msb; 1192 1225 1193 1226 sprintf(msb->disk->disk_name, "mspblk%d", disk_id); ··· 1304 1339 mspro_block_data_clear(msb); 1305 1340 mutex_unlock(&mspro_block_disk_lock); 1306 1341 1307 - mspro_block_disk_release(msb->disk); 1342 + put_disk(msb->disk); 1308 1343 memstick_set_drvdata(card, NULL); 1309 1344 } 1310 1345