diff options
| author | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-09-30 00:49:59 -0400 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-10-02 16:17:31 -0400 |
| commit | 9977bb18c92e694819266fc0e7c5a3cd0cd7b626 (patch) | |
| tree | fbcda9f670923c683971da2613645e1693d0210d /drivers/target | |
| parent | e004cb25927ad7a67c109ac13e1d2e5e378430dd (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>
Diffstat (limited to 'drivers/target')
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_nego.c | 4 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_parameters.c | 50 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_parameters.h | 2 |
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 | ||
| 1068 | static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value) | 1068 | static 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 *); | |||
| 36 | extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *); | 36 | extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *); |
| 37 | extern int iscsi_extract_key_value(char *, char **, char **); | 37 | extern int iscsi_extract_key_value(char *, char **, char **); |
| 38 | extern int iscsi_update_param_value(struct iscsi_param *, char *); | 38 | extern int iscsi_update_param_value(struct iscsi_param *, char *); |
| 39 | extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_param_list *); | 39 | extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *); |
| 40 | extern int iscsi_encode_text_output(u8, u8, char *, u32 *, | 40 | extern int iscsi_encode_text_output(u8, u8, char *, u32 *, |
| 41 | struct iscsi_param_list *); | 41 | struct iscsi_param_list *); |
| 42 | extern int iscsi_check_negotiated_keys(struct iscsi_param_list *); | 42 | extern int iscsi_check_negotiated_keys(struct iscsi_param_list *); |
