From 9483a06e4f1ea4c715a3f3b917978ba97c174de6 Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@suse.de>
Date: Mon, 13 Jun 2016 11:01:07 +0200
Subject: [PATCH 2/2] target/rbd: remove caw_mutex usage
Patch-mainline: Not yet, SES clustered LIO/RBD
References: bsc#981143
The RBD backstore maps SCSI Compare And Write requests into cmpext+write
compound OSD operations, which are handled by the OSDs in an atomic
fashion. This means that SCSI Compare And Write request handling doesn't
need to be serialised with caw_sem.
Suggested-by: Mike Christie <mchristi@redhat.com>
Signed-off-by: David Disseldorp <ddiss@suse.de>
Reviewed-by: Jan Fajerski <jan.fajerski@suse.com>
---
drivers/target/target_core_rbd.c | 52 ++++++++++++++++++++++++---------------
drivers/target/target_core_rbd.h | 4 ---
2 files changed, 32 insertions(+), 24 deletions(-)
--- a/drivers/target/target_core_rbd.c
+++ b/drivers/target/target_core_rbd.c
@@ -392,11 +392,15 @@ static sense_reason_t tcm_rbd_execute_wr
false);
}
+struct tcm_rbd_caw_state {
+ struct se_cmd *cmd;
+ struct scatterlist *cmp_and_write_sg;
+};
+
static void tcm_rbd_cmp_and_write_callback(struct rbd_img_request *img_request)
{
- struct se_cmd *cmd = img_request->lio_cmd_data;
- struct se_device *dev = cmd->se_dev;
- struct tcm_rbd_dev *tcm_rbd_dev = TCM_RBD_DEV(dev);
+ struct tcm_rbd_caw_state *caw_state = img_request->lio_cmd_data;
+ struct se_cmd *cmd = caw_state->cmd;
sense_reason_t sense_reason = TCM_NO_SENSE;
if (img_request->result <= -MAX_ERRNO) {
@@ -406,9 +410,8 @@ static void tcm_rbd_cmp_and_write_callba
(unsigned long long)cmd->bad_sector);
sense_reason = TCM_MISCOMPARE_VERIFY;
}
- kfree(tcm_rbd_dev->cmp_and_write_sg);
- tcm_rbd_dev->cmp_and_write_sg = NULL;
- up(&dev->caw_sem);
+ kfree(caw_state->cmp_and_write_sg);
+ kfree(caw_state);
if (sense_reason != TCM_NO_SENSE) {
/* TODO pass miscompare offset */
@@ -426,6 +429,7 @@ static sense_reason_t tcm_rbd_execute_cm
struct se_device *dev = cmd->se_dev;
struct tcm_rbd_dev *tcm_rbd_dev = TCM_RBD_DEV(dev);
struct rbd_device *rbd_dev = tcm_rbd_dev->rbd_dev;
+ struct tcm_rbd_caw_state *caw_state = NULL;
struct rbd_img_request *img_request;
struct ceph_snap_context *snapc;
sense_reason_t sense = TCM_NO_SENSE;
@@ -437,6 +441,11 @@ static sense_reason_t tcm_rbd_execute_cm
ceph_get_snap_context(snapc);
up_read(&rbd_dev->header_rwsem);
+ /*
+ * No need to take dev->caw_sem here, as the IO is mapped to a compound
+ * compare+write OSD request, which is handled atomically by the OSD.
+ */
+
img_request = rbd_img_request_create(rbd_dev,
rbd_lba_shift(dev, cmd->t_task_lba),
len, OBJ_OP_CMP_AND_WRITE, snapc);
@@ -446,19 +455,21 @@ static sense_reason_t tcm_rbd_execute_cm
}
snapc = NULL; /* img_request consumes a ref */
- ret = down_interruptible(&dev->caw_sem);
- if (ret != 0) {
- sense = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
- goto free_req;
- }
+ caw_state = kmalloc(sizeof(*caw_state), GFP_KERNEL);
+ if (caw_state == NULL) {
+ sense = TCM_OUT_OF_RESOURCES;
+ goto free_req;
+ }
- tcm_rbd_dev->cmp_and_write_sg = sbc_create_compare_and_write_sg(cmd);
- if (!tcm_rbd_dev->cmp_and_write_sg)
- goto rel_caw_sem;
+ caw_state->cmp_and_write_sg = sbc_create_compare_and_write_sg(cmd);
+ if (!caw_state->cmp_and_write_sg) {
+ sense = TCM_OUT_OF_RESOURCES;
+ goto free_caw_state;
+ }
ret = rbd_img_cmp_and_write_request_fill(img_request, cmd->t_data_sg,
len,
- tcm_rbd_dev->cmp_and_write_sg,
+ caw_state->cmp_and_write_sg,
len);
if (ret == -EOPNOTSUPP) {
sense = TCM_INVALID_CDB_FIELD;
@@ -469,7 +480,8 @@ static sense_reason_t tcm_rbd_execute_cm
}
cmd->priv = img_request;
- img_request->lio_cmd_data = cmd;
+ caw_state->cmd = cmd;
+ img_request->lio_cmd_data = caw_state;
img_request->callback = tcm_rbd_cmp_and_write_callback;
ret = rbd_img_request_submit(img_request);
@@ -484,10 +496,10 @@ static sense_reason_t tcm_rbd_execute_cm
return 0;
free_write_sg:
- kfree(tcm_rbd_dev->cmp_and_write_sg);
- tcm_rbd_dev->cmp_and_write_sg = NULL;
-rel_caw_sem:
- up(&dev->caw_sem);
+ kfree(caw_state->cmp_and_write_sg);
+ caw_state->cmp_and_write_sg = NULL;
+free_caw_state:
+ kfree(caw_state);
free_req:
rbd_img_request_put(img_request);
free_snapc:
--- a/drivers/target/target_core_rbd.h
+++ b/drivers/target/target_core_rbd.h
@@ -5,14 +5,10 @@
#define TCM_RBD_HAS_UDEV_PATH 0x01
-struct scatterlist;
-
struct tcm_rbd_dev {
struct se_device dev;
struct rbd_device *rbd_dev;
- struct scatterlist *cmp_and_write_sg;
-
unsigned char bd_udev_path[SE_UDEV_PATH_LEN];
u32 bd_flags;
struct block_device *bd;