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>
This commit is contained in:
parent
e004cb2592
commit
9977bb18c9
|
@ -550,7 +550,7 @@ static int iscsi_target_handle_csg_zero(
|
||||||
SENDER_INITIATOR|SENDER_RECEIVER,
|
SENDER_INITIATOR|SENDER_RECEIVER,
|
||||||
login->req_buf,
|
login->req_buf,
|
||||||
payload_length,
|
payload_length,
|
||||||
conn->param_list);
|
conn);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -627,7 +627,7 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log
|
||||||
SENDER_INITIATOR|SENDER_RECEIVER,
|
SENDER_INITIATOR|SENDER_RECEIVER,
|
||||||
login->req_buf,
|
login->req_buf,
|
||||||
payload_length,
|
payload_length,
|
||||||
conn->param_list);
|
conn);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
@ -1065,7 +1065,8 @@ out:
|
||||||
return proposer_values;
|
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;
|
u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
|
||||||
char *negoitated_value = NULL;
|
char *negoitated_value = NULL;
|
||||||
|
@ -1140,8 +1141,35 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
|
if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
|
||||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
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)) {
|
} else if (IS_TYPE_NUMBER_RANGE(param)) {
|
||||||
negoitated_value = iscsi_get_value_from_number_range(
|
negoitated_value = iscsi_get_value_from_number_range(
|
||||||
param, value);
|
param, value);
|
||||||
|
@ -1535,8 +1563,9 @@ int iscsi_decode_text_input(
|
||||||
u8 sender,
|
u8 sender,
|
||||||
char *textbuf,
|
char *textbuf,
|
||||||
u32 length,
|
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;
|
char *tmpbuf, *start = NULL, *end = NULL;
|
||||||
|
|
||||||
tmpbuf = kzalloc(length + 1, GFP_KERNEL);
|
tmpbuf = kzalloc(length + 1, GFP_KERNEL);
|
||||||
|
@ -1594,7 +1623,7 @@ int iscsi_decode_text_input(
|
||||||
}
|
}
|
||||||
SET_PSTATE_RESPONSE_GOT(param);
|
SET_PSTATE_RESPONSE_GOT(param);
|
||||||
} else {
|
} else {
|
||||||
if (iscsi_check_acceptor_state(param, value) < 0) {
|
if (iscsi_check_acceptor_state(param, value, conn) < 0) {
|
||||||
kfree(tmpbuf);
|
kfree(tmpbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1755,10 +1784,13 @@ void iscsi_set_connection_parameters(
|
||||||
pr_debug("DataDigest: %s\n",
|
pr_debug("DataDigest: %s\n",
|
||||||
param->value);
|
param->value);
|
||||||
} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
|
} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
|
||||||
ops->MaxRecvDataSegmentLength =
|
/*
|
||||||
simple_strtoul(param->value, &tmpptr, 0);
|
* At this point iscsi_check_acceptor_state() will have
|
||||||
pr_debug("MaxRecvDataSegmentLength: %s\n",
|
* set ops->MaxRecvDataSegmentLength from the original
|
||||||
param->value);
|
* initiator provided value.
|
||||||
|
*/
|
||||||
|
pr_debug("MaxRecvDataSegmentLength: %u\n",
|
||||||
|
ops->MaxRecvDataSegmentLength);
|
||||||
} else if (!strcmp(param->name, OFMARKER)) {
|
} else if (!strcmp(param->name, OFMARKER)) {
|
||||||
ops->OFMarker = !strcmp(param->value, YES);
|
ops->OFMarker = !strcmp(param->value, YES);
|
||||||
pr_debug("OFMarker: %s\n",
|
pr_debug("OFMarker: %s\n",
|
||||||
|
|
|
@ -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 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_extract_key_value(char *, char **, char **);
|
||||||
extern int iscsi_update_param_value(struct iscsi_param *, 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 *,
|
extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
|
||||||
struct iscsi_param_list *);
|
struct iscsi_param_list *);
|
||||||
extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
|
extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
|
||||||
|
|
Loading…
Reference in New Issue