iscsi-target: Add IFC_SENDTARGETS_SINGLE support
authorNicholas Bellinger <nab@linux-iscsi.org>
Thu, 20 Jun 2013 05:45:42 +0000 (22:45 -0700)
committerNicholas Bellinger <nab@linux-iscsi.org>
Thu, 4 Jul 2013 02:43:24 +0000 (19:43 -0700)
This patch changes ISCSI_OP_TEXT handling of SendTargets=[iqn.,eui.]
payloads to return explicit discovery information.

It adds checks to iscsit_process_text_cmd() and adds the special single
$TARGETNAME discovery case in iscsit_build_sendtargets_response() code.

Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_core.h

index 30ca188..f2c3d4a 100644 (file)
@@ -2016,6 +2016,9 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
        }
        if (!strncmp("=All", text_ptr, 4)) {
                cmd->cmd_flags |= IFC_SENDTARGETS_ALL;
+       } else if (!strncmp("=iqn.", text_ptr, 5) ||
+                  !strncmp("=eui.", text_ptr, 5)) {
+               cmd->cmd_flags |= IFC_SENDTARGETS_SINGLE;
        } else {
                pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr);
                goto reject;
@@ -3398,6 +3401,7 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
        struct iscsi_tpg_np *tpg_np;
        int buffer_len, end_of_buf = 0, len = 0, payload_len = 0;
        unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */
+       unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL;
 
        buffer_len = max(conn->conn_ops->MaxRecvDataSegmentLength,
                         SENDTARGETS_BUF_LIMIT);
@@ -3408,9 +3412,30 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
                                " response.\n");
                return -ENOMEM;
        }
+       /*
+        * Locate pointer to iqn./eui. string for IFC_SENDTARGETS_SINGLE
+        * explicit case..
+        */
+       if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) {
+               text_ptr = strchr(text_in, '=');
+               if (!text_ptr) {
+                       pr_err("Unable to locate '=' string in text_in:"
+                              " %s\n", text_in);
+                       return -EINVAL;
+               }
+               /*
+                * Skip over '=' character..
+                */
+               text_ptr += 1;
+       }
 
        spin_lock(&tiqn_lock);
        list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) {
+               if ((cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) &&
+                    strcmp(tiqn->tiqn, text_ptr)) {
+                       continue;
+               }
+
                len = sprintf(buf, "TargetName=%s", tiqn->tiqn);
                len += 1;
 
@@ -3464,6 +3489,9 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
 eob:
                if (end_of_buf)
                        break;
+
+               if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE)
+                       break;
        }
        spin_unlock(&tiqn_lock);
 
index ad46e73..3436a2c 100644 (file)
@@ -134,6 +134,7 @@ enum cmd_flags_table {
        ICF_OOO_CMDSN                           = 0x00000080,
        ICF_REJECT_FAIL_CONN                    = 0x00000100,
        IFC_SENDTARGETS_ALL                     = 0x00000200,
+       IFC_SENDTARGETS_SINGLE                  = 0x00000400,
 };
 
 /* struct iscsi_cmd->i_state */