mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
block/rnbd-srv: don't free the device on a sysfs error
rnbd_srv_create_dev_sysfs() drops the only kobject reference on its error paths, and the release function frees the rnbd_srv_dev. process_msg_open() keeps using it and ends in destroy_device() with a list_del() and a second kfree(). This doesn't need memory pressure: a client opening a device while its last mapping goes away gets -EEXIST from kobject_add() against the old directory. Only undo kobject_add() on failure and leave the reference to destroy_device(). Initialise the kobject once, the next open retries. Fixes:8cee532f46("block/rnbd: server: sysfs interface functions") Fixes:d3a95ccaaf("block/rnbd: call kobject_put in the failure path") Cc: "Md. Haris Iqbal" <haris.iqbal@ionos.com> Cc: Jack Wang <jinpu.wang@ionos.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Link: https://patch.msgid.link/20261028164415.1262013-17-axboe@kernel.dk Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
bf7fff620c
commit
d9667ade40
|
|
@ -44,12 +44,17 @@ int rnbd_srv_create_dev_sysfs(struct rnbd_srv_dev *dev,
|
|||
struct kobject *bdev_kobj;
|
||||
int ret;
|
||||
|
||||
ret = kobject_init_and_add(&dev->dev_kobj, &dev_ktype,
|
||||
rnbd_devs_kobj, "%pg", bdev);
|
||||
if (ret) {
|
||||
kobject_put(&dev->dev_kobj);
|
||||
/*
|
||||
* The release function frees the device, which the caller goes on
|
||||
* using and which others may share: never drop the reference of the
|
||||
* kobject here. That is for destroy_device().
|
||||
*/
|
||||
if (!dev->dev_kobj.state_initialized)
|
||||
kobject_init(&dev->dev_kobj, &dev_ktype);
|
||||
|
||||
ret = kobject_add(&dev->dev_kobj, rnbd_devs_kobj, "%pg", bdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev->dev_sessions_kobj = kobject_create_and_add("sessions",
|
||||
&dev->dev_kobj);
|
||||
|
|
@ -69,7 +74,6 @@ int rnbd_srv_create_dev_sysfs(struct rnbd_srv_dev *dev,
|
|||
kobject_put(dev->dev_sessions_kobj);
|
||||
free_dev_kobj:
|
||||
kobject_del(&dev->dev_kobj);
|
||||
kobject_put(&dev->dev_kobj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,9 @@ static void destroy_device(struct kref *kref)
|
|||
* Destroy kobj only if it was really created.
|
||||
*/
|
||||
rnbd_srv_destroy_dev_sysfs(dev);
|
||||
else if (dev->dev_kobj.state_initialized)
|
||||
/* The files could not be created. Frees the name, too. */
|
||||
kobject_put(&dev->dev_kobj);
|
||||
else
|
||||
kfree(dev);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user