mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
rnbd-srv: publish the sess_dev at the end of OPEN
rnbd_sess_dev_alloc() stores the empty sess_dev in the XArray as its
first step. An IO message with the new ID from another connection can
find it before bdev_file is set, or hold a reference while a failing
OPEN frees it after a mere RCU grace period. Both are reachable from any
host that can open a device.
Reserve the ID with a NULL entry and store the sess_dev once nothing can
fail anymore. The error path still erases the ID, and no longer needs
synchronize_rcu().
Fixes: 2de6c8de19 ("block/rnbd: server: main functionality")
Cc: "Md. Haris Iqbal" <haris.iqbal@ionos.com>
Cc: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Chris Mason <mason@kernel.org>
Link: https://patch.msgid.link/20261028164415.1262013-41-axboe@kernel.dk
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
4912dab88b
commit
08ebf69c78
|
|
@ -431,7 +431,7 @@ static struct rnbd_srv_sess_dev
|
|||
if (!sess_dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
error = xa_alloc(&srv_sess->index_idr, &sess_dev->device_id, sess_dev,
|
||||
error = xa_alloc(&srv_sess->index_idr, &sess_dev->device_id, NULL,
|
||||
xa_limit_32b, GFP_NOWAIT);
|
||||
if (error < 0) {
|
||||
pr_warn("Allocating idr failed, err: %d\n", error);
|
||||
|
|
@ -802,6 +802,13 @@ static int process_msg_open(struct rnbd_srv_session *srv_sess,
|
|||
list_add(&srv_sess_dev->dev_list, &srv_dev->sess_dev_list);
|
||||
mutex_unlock(&srv_dev->lock);
|
||||
|
||||
/*
|
||||
* Nothing fails from here on, so let I/O messages find the sess_dev.
|
||||
* The ID is reserved, so this store allocates nothing.
|
||||
*/
|
||||
xa_store(&srv_sess->index_idr, srv_sess_dev->device_id, srv_sess_dev,
|
||||
GFP_KERNEL);
|
||||
|
||||
rnbd_srv_info(srv_sess_dev, "Opened device '%s'\n", srv_dev->name);
|
||||
|
||||
kfree(full_path);
|
||||
|
|
@ -813,7 +820,6 @@ static int process_msg_open(struct rnbd_srv_session *srv_sess,
|
|||
|
||||
free_srv_sess_dev:
|
||||
xa_erase(&srv_sess->index_idr, srv_sess_dev->device_id);
|
||||
synchronize_rcu();
|
||||
kfree(srv_sess_dev);
|
||||
srv_dev_put:
|
||||
if (open_msg->access_mode != RNBD_ACCESS_RO) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user