[PATCH 07/33] TCMU PR: add functions to handle SCSI2 Reservation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch added two functions: tcmu_pr_info_scsi2_rsv_encode()
and tcmu_pr_info_scsi2_rsv_decode() to encode and decode SCSI2
Reservations.

Signed-off-by: Zhu Lingshan <lszhu@xxxxxxxx>
---
 drivers/target/target_core_user.c | 65 +++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index ccb1607edd0a..50723ac0ed22 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -94,6 +94,9 @@
 #define TCMU_GLOBAL_MAX_BLOCKS_DEF (512 * 1024)
 
 #define TCMU_PR_INFO_XATTR_VERS		1
+#define TCMU_PR_INFO_XATTR_VAL_SCSI2_RSV_ABSENT		"No SPC-2 Reservation holder"
+
+#define TCMU_PR_IT_NEXUS_MAXLEN		484
 
 static u8 tcmu_kern_cmd_reply_supported;
 
@@ -200,6 +203,14 @@ struct tcmu_cmd {
 #define TCMU_CMD_BIT_EXPIRED 0
 	unsigned long flags;
 };
+
+/*
+ * I-T nexus for SCSI2 (RESERVE/RELEASE) reservation.
+ */
+struct tcmu_scsi2_rsv {
+	char it_nexus[TCMU_PR_IT_NEXUS_MAXLEN];
+	};
+
 /*
  * To avoid dead lock the mutex lock order should always be:
  *
@@ -1875,6 +1886,60 @@ tcmu_pr_info_vers_decode(char *str, u32 *vers)
 	return 0;
 }
 
+static int
+tcmu_pr_info_scsi2_rsv_decode(char *str, struct tcmu_scsi2_rsv **_scsi2_rsv)
+{
+	struct tcmu_scsi2_rsv *scsi2_rsv;
+
+	if (!_scsi2_rsv) {
+		WARN_ON(1);
+		return -EINVAL;
+	}
+	if (!strncmp(str, TCMU_PR_INFO_XATTR_VAL_SCSI2_RSV_ABSENT,
+		     sizeof(TCMU_PR_INFO_XATTR_VAL_SCSI2_RSV_ABSENT))) {
+		scsi2_rsv = NULL;
+	} else {
+		size_t n;
+
+		scsi2_rsv = kzalloc(sizeof(*scsi2_rsv), GFP_KERNEL);
+		if (!scsi2_rsv)
+			return -ENOMEM;
+
+		n = strlcpy(scsi2_rsv->it_nexus, str,
+			    TCMU_PR_IT_NEXUS_MAXLEN);
+		if (n >= TCMU_PR_IT_NEXUS_MAXLEN) {
+			kfree(scsi2_rsv);
+			return -EINVAL;
+		}
+	}
+
+	pr_debug("processed pr_info SCSI2 rsv: %s\n", str);
+
+	*_scsi2_rsv = scsi2_rsv;
+	return 0;
+}
+
+static int
+tcmu_pr_info_scsi2_rsv_encode(char *buf, size_t buf_remain,
+			      struct tcmu_scsi2_rsv *scsi2_rsv)
+{
+	int rc;
+
+	if (!scsi2_rsv) {
+		/* no reservation */
+		rc = snprintf(buf, buf_remain, "%s\n",
+			      TCMU_PR_INFO_XATTR_VAL_SCSI2_RSV_ABSENT);
+	} else {
+		rc = snprintf(buf, buf_remain, "%s\n", scsi2_rsv->it_nexus);
+	}
+	if ((rc < 0) || (rc >= buf_remain)) {
+		pr_err("failed to encode SCSI2 reservation\n");
+		return -EINVAL;
+	}
+
+	return rc;
+}
+
 static int tcmu_configure_device(struct se_device *dev)
 {
 	struct tcmu_dev *udev = TCMU_DEV(dev);
-- 
2.17.1




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux