diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-09-29 21:49:59 -0700 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-10-02 13:17:31 -0700 |
commit | 9977bb18c92e694819266fc0e7c5a3cd0cd7b626 (patch) | |
tree | fbcda9f670923c683971da2613645e1693d0210d /drivers/target | |
parent | e004cb25927ad7a67c109ac13e1d2e5e378430dd (diff) | |
download | op-kernel-dev-9977bb18c92e694819266fc0e7c5a3cd0cd7b626.zip op-kernel-dev-9977bb18c92e694819266fc0e7c5a3cd0cd7b626.tar.gz |
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 a9a73ac..d08373f 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( SENDER_INITIATOR|SENDER_RECEIVER, login->req_buf, payload_length, - conn->param_list); + conn); if (ret < 0) return -1; @@ -627,7 +627,7 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log SENDER_INITIATOR|SENDER_RECEIVER, login->req_buf, payload_length, - conn->param_list); + conn); if (ret < 0) return -1; diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index 40864ee..3678ff2 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c @@ -1065,7 +1065,8 @@ out: return proposer_values; } -static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value) +static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value, + struct iscsi_conn *conn) { u8 acceptor_boolean_value = 0, proposer_boolean_value = 0; char *negoitated_value = NULL; @@ -1140,8 +1141,35 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value) return -1; } - if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) - SET_PSTATE_REPLY_OPTIONAL(param); + if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { + struct iscsi_param *param_mxdsl; + unsigned long long tmp; + int rc; + + rc = strict_strtoull(param->value, 0, &tmp); + if (rc < 0) + return -1; + + conn->conn_ops->MaxRecvDataSegmentLength = tmp; + pr_debug("Saving op->MaxRecvDataSegmentLength from" + " original initiator received value: %u\n", + conn->conn_ops->MaxRecvDataSegmentLength); + + param_mxdsl = iscsi_find_param_from_key( + MAXXMITDATASEGMENTLENGTH, + conn->param_list); + if (!param_mxdsl) + return -1; + + rc = iscsi_update_param_value(param, + param_mxdsl->value); + if (rc < 0) + return -1; + + pr_debug("Updated %s to target MXDSL value: %s\n", + param->name, param->value); + } + } else if (IS_TYPE_NUMBER_RANGE(param)) { negoitated_value = iscsi_get_value_from_number_range( param, value); @@ -1535,8 +1563,9 @@ int iscsi_decode_text_input( u8 sender, char *textbuf, u32 length, - struct iscsi_param_list *param_list) + struct iscsi_conn *conn) { + struct iscsi_param_list *param_list = conn->param_list; char *tmpbuf, *start = NULL, *end = NULL; tmpbuf = kzalloc(length + 1, GFP_KERNEL); @@ -1594,7 +1623,7 @@ int iscsi_decode_text_input( } SET_PSTATE_RESPONSE_GOT(param); } else { - if (iscsi_check_acceptor_state(param, value) < 0) { + if (iscsi_check_acceptor_state(param, value, conn) < 0) { kfree(tmpbuf); return -1; } @@ -1755,10 +1784,13 @@ void iscsi_set_connection_parameters( pr_debug("DataDigest: %s\n", param->value); } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { - ops->MaxRecvDataSegmentLength = - simple_strtoul(param->value, &tmpptr, 0); - pr_debug("MaxRecvDataSegmentLength: %s\n", - param->value); + /* + * At this point iscsi_check_acceptor_state() will have + * set ops->MaxRecvDataSegmentLength from the original + * initiator provided value. + */ + pr_debug("MaxRecvDataSegmentLength: %u\n", + ops->MaxRecvDataSegmentLength); } else if (!strcmp(param->name, OFMARKER)) { ops->OFMarker = !strcmp(param->value, YES); pr_debug("OFMarker: %s\n", diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h index 77a28b5..1e1b750 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 *); extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *); extern int iscsi_extract_key_value(char *, char **, char **); extern int iscsi_update_param_value(struct iscsi_param *, char *); -extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_param_list *); +extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *); extern int iscsi_encode_text_output(u8, u8, char *, u32 *, struct iscsi_param_list *); extern int iscsi_check_negotiated_keys(struct iscsi_param_list *); |