aboutsummaryrefslogtreecommitdiff
path: root/drivers/block/rnbd/rnbd-srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/rnbd/rnbd-srv.c')
-rw-r--r--drivers/block/rnbd/rnbd-srv.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c
index e1bc8b4cd592..d1ee72ed8384 100644
--- a/drivers/block/rnbd/rnbd-srv.c
+++ b/drivers/block/rnbd/rnbd-srv.c
@@ -212,12 +212,20 @@ static void rnbd_put_srv_dev(struct rnbd_srv_dev *dev)
kref_put(&dev->kref, destroy_device_cb);
}
-void rnbd_destroy_sess_dev(struct rnbd_srv_sess_dev *sess_dev)
+void rnbd_destroy_sess_dev(struct rnbd_srv_sess_dev *sess_dev, bool keep_id)
{
DECLARE_COMPLETION_ONSTACK(dc);
- xa_erase(&sess_dev->sess->index_idr, sess_dev->device_id);
+ if (keep_id)
+ /* free the resources for the id but don't */
+ /* allow to re-use the id itself because it */
+ /* is still used by the client */
+ xa_cmpxchg(&sess_dev->sess->index_idr, sess_dev->device_id,
+ sess_dev, NULL, 0);
+ else
+ xa_erase(&sess_dev->sess->index_idr, sess_dev->device_id);
synchronize_rcu();
+
sess_dev->destroy_comp = &dc;
rnbd_put_sess_dev(sess_dev);
wait_for_completion(&dc); /* wait for inflights to drop to zero */
@@ -328,6 +336,13 @@ static int rnbd_srv_link_ev(struct rtrs_srv *rtrs,
}
}
+void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev)
+{
+ rnbd_srv_destroy_dev_session_sysfs(sess_dev);
+ sess_dev->keep_id = true;
+
+}
+
static int process_msg_close(struct rtrs_srv *rtrs,
struct rnbd_srv_session *srv_sess,
void *data, size_t datalen, const void *usr,