Commit 52334f4a authored by Guoqing Jiang's avatar Guoqing Jiang Committed by Jens Axboe
Browse files

rnbd-clt: don't free rsp in msg_open_conf for map scenario



For map scenario, rsp is freed in two places:

1. msg_open_conf frees rsp if rtrs_clt_request returns 0.

2. Otherwise, rsp is freed by the call sites of rtrs_clt_request.

Now, We'd like to control full lifecycle of rsp in rnbd_clt_map_device,
with that, it is feasible to pass rsp to rnbd_client_setup_device in
next commit.

For 1, it is possible to free rsp from the caller of send_usr_msg
because of the synchronization of iu->comp.wait. And we put iu later
in rnbd_clt_map_device to ensure order of release rsp and iu.

Acked-by: default avatarJack Wang <jinpu.wang@ionos.com>
Signed-off-by: default avatarGuoqing Jiang <guoqing.jiang@linux.dev>
Link: https://lore.kernel.org/r/20220706133152.12058-3-guoqing.jiang@linux.dev


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 9ddae3ba
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -507,6 +507,11 @@ static void msg_open_conf(struct work_struct *work)
	struct rnbd_msg_open_rsp *rsp = iu->buf;
	struct rnbd_clt_dev *dev = iu->dev;
	int errno = iu->errno;
	bool from_map = false;

	/* INIT state is only triggered from rnbd_clt_map_device */
	if (dev->dev_state == DEV_STATE_INIT)
		from_map = true;

	if (errno) {
		rnbd_clt_err(dev,
@@ -523,6 +528,8 @@ static void msg_open_conf(struct work_struct *work)
			send_msg_close(dev, device_id, RTRS_PERMIT_NOWAIT);
		}
	}
	/* We free rsp in rnbd_clt_map_device for map scenario */
	if (!from_map)
		kfree(rsp);
	wake_up_iu_comp(iu, errno);
	rnbd_put_iu(dev->sess, iu);
@@ -1617,16 +1624,14 @@ struct rnbd_clt_dev *rnbd_clt_map_device(const char *sessname,
	if (ret) {
		rnbd_clt_put_dev(dev);
		rnbd_put_iu(sess, iu);
		kfree(rsp);
	} else {
		ret = errno;
	}
	rnbd_put_iu(sess, iu);
	if (ret) {
		rnbd_clt_err(dev,
			      "map_device: failed, can't open remote device, err: %d\n",
			      ret);
		goto del_dev;
		goto put_iu;
	}
	mutex_lock(&dev->lock);
	pr_debug("Opened remote device: session=%s, path='%s'\n",
@@ -1650,12 +1655,17 @@ struct rnbd_clt_dev *rnbd_clt_map_device(const char *sessname,
		       dev->max_hw_sectors, dev->wc, dev->fua);

	mutex_unlock(&dev->lock);
	kfree(rsp);
	rnbd_put_iu(sess, iu);
	rnbd_clt_put_sess(sess);

	return dev;

send_close:
	send_msg_close(dev, dev->device_id, RTRS_PERMIT_WAIT);
put_iu:
	kfree(rsp);
	rnbd_put_iu(sess, iu);
del_dev:
	delete_dev(dev);
put_dev: