From mboxrd@z Thu Jan 1 00:00:00 1970 From: keith.busch@intel.com (Keith Busch) Date: Fri, 22 Aug 2014 14:32:41 -0600 (MDT) Subject: [PATCH] fs/block_dev.c: Use hd_part to find block inodes In-Reply-To: References: <1408724896-3671-1-git-send-email-keith.busch@intel.com> <20140822174848.GA11819@infradead.org> Message-ID: On Fri, 22 Aug 2014, Keith Busch wrote: > On Fri, 22 Aug 2014, Christoph Hellwig wrote: >> On Fri, Aug 22, 2014@10:28:16AM -0600, Keith Busch wrote: >>> When using the GENHD_FL_EXT_DEVT disk flags, a newly added device may >>> be assigned the same major/minor as one that was previously removed but >>> opened, and the pesky userspace refuses to close it! >> >> Which means life time rules for those dev_t allocations are broken. >> Please fix it to not release the dev_t until the device isn't referenced >> at all. > > Okay, thanks. So a proper fix would not let extended devt minors get > reused while still referenced, so we can't release it unconditionally > from del_gendisk(). I think the following does that, but I had to add > a reference counter to gendisk. Sorry for the rapid churn; I hadn't followed the function pointers through to discover the correct place to release the devt. This one's much simpler: --- diff --git a/block/genhd.c b/block/genhd.c index 791f419..321f1fd 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -665,7 +665,6 @@ void del_gendisk(struct gendisk *disk) sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); pm_runtime_set_memalloc_noio(disk_to_dev(disk), false); device_del(disk_to_dev(disk)); - blk_free_devt(disk_to_dev(disk)->devt); } EXPORT_SYMBOL(del_gendisk); @@ -1098,6 +1097,7 @@ static void disk_release(struct device *dev) { struct gendisk *disk = dev_to_disk(dev); + blk_free_devt(dev->devt); disk_release_events(disk); kfree(disk->random); disk_replace_part_tbl(disk, NULL); --