Blob Blame History Raw
From a0632d193b7ab3342ecde1f1244e35b2ad7405fa Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@suse.de>
Date: Tue, 1 Sep 2015 13:08:03 +0200
Subject: [PATCH] target/rbd: add pr_report_capabilities support
Patch-mainline: Not yet, SES2 clustered LIO/RBD
References: fate#318836

Add a tcm_rbd_pr_ops handler for PR REPORT CAPABILITIES requests.
The rbd backend response matches the LIO default, except:
- SIP_C=0 and ATP_C=0: no support for all_tg_pt/spec_i_pt
- PTPL_A=1: Persistence across Target Power Loss Active flag is always
	    set.

Signed-off-by: David Disseldorp <ddiss@suse.de>
---
 drivers/target/target_core_rbd.c |   40 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

--- a/drivers/target/target_core_rbd.c
+++ b/drivers/target/target_core_rbd.c
@@ -1617,6 +1617,45 @@ out:
 	return TCM_NO_SENSE;
 }
 
+static sense_reason_t
+tcm_rbd_execute_pr_report_capabilities(struct se_cmd *cmd, unsigned char *buf,
+				       u32 buf_len)
+{
+	u16 add_len = 8; /* Hardcoded to 8. */
+
+	BUG_ON(buf_len < 6);
+
+	buf[0] = ((add_len >> 8) & 0xff);
+	buf[1] = (add_len & 0xff);
+	buf[2] |= 0x10; /* CRH: Compatible Reservation Handling bit. */
+	/* SIP_C=0 and ATP_C=0: no support for all_tg_pt/spec_i_pt */
+	buf[2] |= 0x01; /* PTPL_C: Persistence across Target Power Loss bit */
+	/*
+	 * We are filling in the PERSISTENT RESERVATION TYPE MASK below, so
+	 * set the TMV: Task Mask Valid bit.
+	 */
+	buf[3] |= 0x80;
+	/*
+	 * Change ALLOW COMMANDS to 0x20 or 0x40 later from Table 166
+	 */
+	buf[3] |= 0x10; /* ALLOW COMMANDS field 001b */
+	/*
+	 * PTPL_A: Persistence across Target Power Loss Active bit
+	 */
+	buf[3] |= 0x01;
+	/*
+	 * Setup the PERSISTENT RESERVATION TYPE MASK from Table 167
+	 */
+	buf[4] |= 0x80; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */
+	buf[4] |= 0x40; /* PR_TYPE_EXCLUSIVE_ACCESS_REGONLY */
+	buf[4] |= 0x20; /* PR_TYPE_WRITE_EXCLUSIVE_REGONLY */
+	buf[4] |= 0x08; /* PR_TYPE_EXCLUSIVE_ACCESS */
+	buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */
+	buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */
+
+	return TCM_NO_SENSE;
+}
+
 /* handle PR registration for a currently unregistered I_T nexus */
 static sense_reason_t
 tcm_rbd_execute_pr_register_new(struct tcm_rbd_pr_info *pr_info, u64 old_key,
@@ -2403,6 +2442,7 @@ tcm_rbd_execute_pr_register_and_move(str
 static struct target_pr_ops tcm_rbd_pr_ops = {
 	.pr_read_keys		= tcm_rbd_execute_pr_read_keys,
 	.pr_read_reservation	= tcm_rbd_execute_pr_read_reservation,
+	.pr_report_capabilities	= tcm_rbd_execute_pr_report_capabilities,
 
 	.pr_register		= tcm_rbd_execute_pr_register,
 	.pr_reserve		= tcm_rbd_execute_pr_reserve,