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

block: add a ->free_disk method

Add a method to notify the driver that the gendisk is about to be freed.
This allows drivers to tie the lifetime of their private data to that of
the gendisk and thus deal with device removal races without expensive
synchronization and boilerplate code.

A new flag is added so that ->free_disk is only called after a successful
call to add_disk, which significantly simplifies the error handling path
during probing.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20220215094514.3828912-2-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
76792055 34841e6f

+7
+5
block/genhd.c
··· 526 526 527 527 disk_update_readahead(disk); 528 528 disk_add_events(disk); 529 + set_bit(GD_ADDED, &disk->state); 529 530 return 0; 530 531 531 532 out_unregister_bdi: ··· 1120 1119 xa_destroy(&disk->part_tbl); 1121 1120 disk->queue->disk = NULL; 1122 1121 blk_put_queue(disk->queue); 1122 + 1123 + if (test_bit(GD_ADDED, &disk->state) && disk->fops->free_disk) 1124 + disk->fops->free_disk(disk); 1125 + 1123 1126 iput(disk->part0->bd_inode); /* frees the disk */ 1124 1127 } 1125 1128
+2
include/linux/blkdev.h
··· 146 146 #define GD_READ_ONLY 1 147 147 #define GD_DEAD 2 148 148 #define GD_NATIVE_CAPACITY 3 149 + #define GD_ADDED 4 149 150 150 151 struct mutex open_mutex; /* open/close mutex */ 151 152 unsigned open_partitions; /* number of open partitions */ ··· 1465 1464 void (*unlock_native_capacity) (struct gendisk *); 1466 1465 int (*getgeo)(struct block_device *, struct hd_geometry *); 1467 1466 int (*set_read_only)(struct block_device *bdev, bool ro); 1467 + void (*free_disk)(struct gendisk *disk); 1468 1468 /* this callback is with swap_lock and sometimes page table lock held */ 1469 1469 void (*swap_slot_free_notify) (struct block_device *, unsigned long); 1470 1470 int (*report_zones)(struct gendisk *, sector_t sector,