Patch "block: fix bdi vs gendisk lifetime mismatch" has been added to the 4.7-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
block: fix bdi vs gendisk lifetime mismatch
to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
block-fix-bdi-vs-gendisk-lifetime-mismatch.patch
and it can be found in the queue-4.7 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
df08c32ce3be5be138c1dbfcba203314a3a7cd6fMon Sep 17 00:00:00 2001
From: Dan Williams <[email protected]>
Date: Sun, 31 Jul 2016 11:15:13 -0700
Subject: block: fix bdi vs gendisk lifetime mismatch
From: Dan Williams <[email protected]>
commit df08c32ce3be5be138c1dbfcba203314a3a7cd6f upstream.
The name for a bdi of a gendisk is derived from the gendisk's devt. However, since the gendisk is destroyed before the bdi it leaves a window where a new gendisk could dynamically reuse the same devt while a bdi with the same name is still live. Arrange for the bdi to hold a reference against its "owner" disk device while it is registered. Otherwise we can hit sysfs duplicate name collisions like the following:
WARNING: CPU: 10 PID: 2078 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x64/0x80 sysfs: cannot create duplicate filename '/devices/virtual/bdi/259:1' Hardware name: HP ProLiant DL580 Gen8, BIOS P79 05/06/2015 0000000000000286 0000000002c04ad5 ffff88006f24f970 ffffffff8134caec ffff88006f24f9c0 0000000000000000 ffff88006f24f9b0 ffffffff8108c351 0000001f0000000c ffff88105d236000 ffff88105d1031e0 ffff8800357427f8 Call Trace: [<ffffffff8134caec>] dump_stack+0x63/0x87 [<ffffffff8108c351>] __warn+0xd1/0xf0 [<ffffffff8108c3cf>] warn_slowpath_fmt+0x5f/0x80 [<ffffffff812a0d34>] sysfs_warn_dup+0x64/0x80 [<ffffffff812a0e1e>] sysfs_create_dir_ns+0x7e/0x90 [<ffffffff8134faaa>] kobject_add_internal+0xaa/0x320 [<ffffffff81358d4e>] ? vsnprintf+0x34e/0x4d0 [<ffffffff8134ff55>] kobject_add+0x75/0xd0 [<ffffffff816e66b2>] ? mutex_lock+0x12/0x2f [<ffffffff8148b0a5>] device_add+0x125/0x610 [<ffffffff8148b788>] device_create_groups_vargs+0xd8/0x100 [<ffffffff8148b7cc>] device_create_vargs+0x1c/0x20 [<ffffffff811b775c>] bdi_register+0x8c/0x180 [<ffffffff811b7877>] bdi_register_dev+0x27/0x30 [<ffffffff813317f5>] add_disk+0x175/0x4a0
Fixed up missing 0 return in bdi_register_owner().
--- block/genhd.c | 2 +- include/linux/backing-dev-defs.h | 1 + include/linux/backing-dev.h | 1 + mm/backing-dev.c | 19 +++++++++++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-)
block/genhd.c +1 -1
@@ -613,7 +613,7 @@ void add_disk(struct gendisk *disk)/* Register BDI before referencing it from bdev */ bdi = &disk->queue->backing_dev_info; -bdi_register_dev (bdi,disk_devt (disk)); +bdi_register_owner (bdi,disk_to_dev (disk));blk_register_region (disk_devt (disk), disk->minors,NULL , exact_match, exact_lock, disk);
include/linux/backing-dev-defs.h +1 -0
@@ -163,6 +163,7 @@ struct backing_dev_info {wait_queue_head_t wb_waitq;struct device *dev; +struct device *owner;struct timer_list laptop_mode_wb_timer;
include/linux/backing-dev.h +1 -0
@@ -24,6 +24,7 @@ __printf(3, 4)int bdi_register (struct backing_dev_info *bdi,struct device *parent,const char *fmt, ...);int bdi_register_dev (struct backing_dev_info *bdi,dev_t dev); +int bdi_register_owner (struct backing_dev_info *bdi,struct device *owner);void bdi_unregister (struct backing_dev_info *bdi);int __must_check bdi_setup_and_register (struct backing_dev_info *,char *);
mm/backing-dev.c +19 -0
@@ -825,6 +825,20 @@ int bdi_register_dev(struct backing_dev_ }EXPORT_SYMBOL (bdi_register_dev); +int bdi_register_owner (struct backing_dev_info *bdi,struct device *owner) +{ +int rc; + + rc =bdi_register (bdi,NULL ,"%u:%u" ,MAJOR (owner->devt), +MINOR (owner->devt)); +if (rc) +return rc; + bdi->owner = owner; +get_device (owner); +return 0 ; +} +EXPORT_SYMBOL (bdi_register_owner); +/* * Remove bdi from bdi_list, and ensure that it is no longer visible */
@@ -849,6 +863,11 @@ void bdi_unregister(struct backing_dev_idevice_unregister (bdi->dev); bdi->dev =NULL ; } + +if (bdi->owner) { +put_device (bdi->owner); + bdi->owner =NULL ; + } }void bdi_exit (struct backing_dev_info *bdi)
Patches currently in stable-queue which might be from [email protected] are
queue-4.7/block-fix-bdi-vs-gendisk-lifetime-mismatch.patch