mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
block/rnbd-srv: drop the sess_dev kobject unlocked
rnbd_srv_create_dev_session_sysfs() drops the kobject reference when it fails. The release function is rnbd_destroy_sess_dev(), which takes srv_dev->lock, and the caller holds that lock: the worker deadlocks on itself. A client opening one device as "ram0" and "./ram0" gets there through -EEXIST from kobject_add(). Have process_msg_open() drop the reference after releasing the lock, and leave the rest of the cleanup to the release function. 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-18-axboe@kernel.dk Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
d9667ade40
commit
81941915d5
|
|
@ -193,6 +193,10 @@ static const struct kobj_type rnbd_srv_sess_dev_ktype = {
|
|||
.release = rnbd_srv_sess_dev_release,
|
||||
};
|
||||
|
||||
/*
|
||||
* On failure the caller has to drop the reference of the kobject. The release
|
||||
* function takes the lock of the device, which the caller holds here.
|
||||
*/
|
||||
int rnbd_srv_create_dev_session_sysfs(struct rnbd_srv_sess_dev *sess_dev)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -200,17 +204,13 @@ int rnbd_srv_create_dev_session_sysfs(struct rnbd_srv_sess_dev *sess_dev)
|
|||
ret = kobject_init_and_add(&sess_dev->kobj, &rnbd_srv_sess_dev_ktype,
|
||||
sess_dev->dev->dev_sessions_kobj, "%s",
|
||||
sess_dev->sess->sessname);
|
||||
if (ret) {
|
||||
kobject_put(&sess_dev->kobj);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&sess_dev->kobj,
|
||||
&rnbd_srv_default_dev_session_attr_group);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
kobject_del(&sess_dev->kobj);
|
||||
kobject_put(&sess_dev->kobj);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -590,6 +590,7 @@ rnbd_srv_create_set_sess_dev(struct rnbd_srv_session *srv_sess,
|
|||
return sdev;
|
||||
|
||||
kref_init(&sdev->kref);
|
||||
INIT_LIST_HEAD(&sdev->dev_list);
|
||||
|
||||
strscpy(sdev->pathname, open_msg->dev_name, sizeof(sdev->pathname));
|
||||
|
||||
|
|
@ -789,7 +790,12 @@ static int process_msg_open(struct rnbd_srv_session *srv_sess,
|
|||
rnbd_srv_err(srv_sess_dev,
|
||||
"Opening device failed, failed to create dev client sysfs files, err: %d\n",
|
||||
ret);
|
||||
goto free_srv_sess_dev;
|
||||
/*
|
||||
* rnbd_destroy_sess_dev() undoes everything down to the open
|
||||
* of the block device.
|
||||
*/
|
||||
kobject_put(&srv_sess_dev->kobj);
|
||||
goto free_path;
|
||||
}
|
||||
|
||||
list_add(&srv_sess_dev->dev_list, &srv_dev->sess_dev_list);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user