aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2012-09-30 00:49:59 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-10-02 16:17:31 -0400
commit9977bb18c92e694819266fc0e7c5a3cd0cd7b626 (patch)
treefbcda9f670923c683971da2613645e1693d0210d
parente004cb25927ad7a67c109ac13e1d2e5e378430dd (diff)
iscsi-target: Enable MaxXmitDataSegmentLength operation in login path
This patch activates MaxXmitDataSegmentLength usage that performs the following sequence of events: - Once the incoming initiator's MAXRECVDATASEGMENTLENGTH key is detected within iscsi_check_acceptor_state(), save the requested MRDSL into conn->conn_ops->MaxRecvDataSegmentLength - Next change the outgoing target's MaxRecvDataSegmenthLength key=value based upon the local TPG's MaxXmitDataSegmentLength attribute value. - Change iscsi_set_connection_parameters() to skip the assignment of conn->conn_ops->MaxRecvDataSegmentLength, now setup within iscsi_check_acceptor_state() Also update iscsi_decode_text_input() -> iscsi_check_acceptor_state() code-path to accept struct iscsi_conn *. Cc: Mike Christie <michaelc@cs.wisc.edu> Cc: Andy Grover <agrover@redhat.com> Cc: Hannes Reinecke <hare@suse.de> Cc: Roland Dreier <roland@purestorage.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/iscsi/iscsi_target_nego.c4
-rw-r--r--drivers/target/iscsi/iscsi_target_parameters.c50
-rw-r--r--drivers/target/iscsi/iscsi_target_parameters.h2
3 files changed, 44 insertions, 12 deletions
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index a9a73ac88fd0..d08373fa8caf 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -550,7 +550,7 @@ static int iscsi_target_handle_csg_zero(
550 SENDER_INITIATOR|SENDER_RECEIVER, 550 SENDER_INITIATOR|SENDER_RECEIVER,
551 login->req_buf, 551 login->req_buf,
552 payload_length, 552 payload_length,
553 conn->param_list); 553 conn);
554 if (ret < 0) 554 if (ret < 0)
555 return -1; 555 return -1;
556 556
@@ -627,7 +627,7 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log
627 SENDER_INITIATOR|SENDER_RECEIVER, 627 SENDER_INITIATOR|SENDER_RECEIVER,
628 login->req_buf, 628 login->req_buf,
629 payload_length, 629 payload_length,
630 conn->param_list); 630 conn);
631 if (ret < 0) 631 if (ret < 0)
632 return -1; 632 return -1;
633 633
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c
index 40864ee70302..3678ff2139de 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -1065,7 +1065,8 @@ out:
1065 return proposer_values; 1065 return proposer_values;
1066} 1066}
1067 1067
1068static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value) 1068static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
1069 struct iscsi_conn *conn)
1069{ 1070{
1070 u8 acceptor_boolean_value = 0, proposer_boolean_value = 0; 1071 u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
1071 char *negoitated_value = NULL; 1072 char *negoitated_value = NULL;
@@ -1140,8 +1141,35 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
1140 return -1; 1141 return -1;
1141 } 1142 }
1142 1143
1143 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) 1144 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
1144 SET_PSTATE_REPLY_OPTIONAL(param); 1145 struct iscsi_param *param_mxdsl;
1146 unsigned long long tmp;
1147 int rc;
1148
1149 rc = strict_strtoull(param->value, 0, &tmp);
1150 if (rc < 0)
1151 return -1;
1152
1153 conn->conn_ops->MaxRecvDataSegmentLength = tmp;
1154 pr_debug("Saving op->MaxRecvDataSegmentLength from"
1155 " original initiator received value: %u\n",
1156 conn->conn_ops->MaxRecvDataSegmentLength);
1157
1158 param_mxdsl = iscsi_find_param_from_key(
1159 MAXXMITDATASEGMENTLENGTH,
1160 conn->param_list);
1161 if (!param_mxdsl)
1162 return -1;
1163
1164 rc = iscsi_update_param_value(param,
1165 param_mxdsl->value);
1166 if (rc < 0)
1167 return -1;
1168
1169 pr_debug("Updated %s to target MXDSL value: %s\n",
1170 param->name, param->value);
1171 }
1172
1145 } else if (IS_TYPE_NUMBER_RANGE(param)) { 1173 } else if (IS_TYPE_NUMBER_RANGE(param)) {
1146 negoitated_value = iscsi_get_value_from_number_range( 1174 negoitated_value = iscsi_get_value_from_number_range(
1147 param, value); 1175 param, value);
@@ -1535,8 +1563,9 @@ int iscsi_decode_text_input(
1535 u8 sender, 1563 u8 sender,
1536 char *textbuf, 1564 char *textbuf,
1537 u32 length, 1565 u32 length,
1538 struct iscsi_param_list *param_list) 1566 struct iscsi_conn *conn)
1539{ 1567{
1568 struct iscsi_param_list *param_list = conn->param_list;
1540 char *tmpbuf, *start = NULL, *end = NULL; 1569 char *tmpbuf, *start = NULL, *end = NULL;
1541 1570
1542 tmpbuf = kzalloc(length + 1, GFP_KERNEL); 1571 tmpbuf = kzalloc(length + 1, GFP_KERNEL);
@@ -1594,7 +1623,7 @@ int iscsi_decode_text_input(
1594 } 1623 }
1595 SET_PSTATE_RESPONSE_GOT(param); 1624 SET_PSTATE_RESPONSE_GOT(param);
1596 } else { 1625 } else {
1597 if (iscsi_check_acceptor_state(param, value) < 0) { 1626 if (iscsi_check_acceptor_state(param, value, conn) < 0) {
1598 kfree(tmpbuf); 1627 kfree(tmpbuf);
1599 return -1; 1628 return -1;
1600 } 1629 }
@@ -1755,10 +1784,13 @@ void iscsi_set_connection_parameters(
1755 pr_debug("DataDigest: %s\n", 1784 pr_debug("DataDigest: %s\n",
1756 param->value); 1785 param->value);
1757 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { 1786 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
1758 ops->MaxRecvDataSegmentLength = 1787 /*
1759 simple_strtoul(param->value, &tmpptr, 0); 1788 * At this point iscsi_check_acceptor_state() will have
1760 pr_debug("MaxRecvDataSegmentLength: %s\n", 1789 * set ops->MaxRecvDataSegmentLength from the original
1761 param->value); 1790 * initiator provided value.
1791 */
1792 pr_debug("MaxRecvDataSegmentLength: %u\n",
1793 ops->MaxRecvDataSegmentLength);
1762 } else if (!strcmp(param->name, OFMARKER)) { 1794 } else if (!strcmp(param->name, OFMARKER)) {
1763 ops->OFMarker = !strcmp(param->value, YES); 1795 ops->OFMarker = !strcmp(param->value, YES);
1764 pr_debug("OFMarker: %s\n", 1796 pr_debug("OFMarker: %s\n",
diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h
index 77a28b589d56..1e1b7504a76b 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.h
+++ b/drivers/target/iscsi/iscsi_target_parameters.h
@@ -36,7 +36,7 @@ extern void iscsi_release_param_list(struct iscsi_param_list *);
36extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *); 36extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *);
37extern int iscsi_extract_key_value(char *, char **, char **); 37extern int iscsi_extract_key_value(char *, char **, char **);
38extern int iscsi_update_param_value(struct iscsi_param *, char *); 38extern int iscsi_update_param_value(struct iscsi_param *, char *);
39extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_param_list *); 39extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *);
40extern int iscsi_encode_text_output(u8, u8, char *, u32 *, 40extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
41 struct iscsi_param_list *); 41 struct iscsi_param_list *);
42extern int iscsi_check_negotiated_keys(struct iscsi_param_list *); 42extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);