summaryrefslogtreecommitdiff
path: root/drivers/target/iscsi/iscsi_target_parameters.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-10 19:52:19 +0900
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-10 19:52:19 +0900
commita188e7e93a36627fb3f0013f41857ab54f076d04 (patch)
tree7686a0e870decdab3971db709fb0edf04241c07e /drivers/target/iscsi/iscsi_target_parameters.c
parente1b28147f684af67bfac989756c27c19859d3d4e (diff)
parentcf0eb28d3ba60098865bf7dbcbfdd6b1cc483e3b (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull scsi target updates from Nicholas Bellinger: "Things have been calm for the most part with no new fabric drivers in flight for v3.7 (we're up to eight now !), so this update is primarily focused on addressing a few long-standing items within target-core and iscsi-target fabric code. The highlights include: - target: Simplify fabric sense data length handling (roland) - qla2xxx: Fix endianness of task management response code (roland) - target: fix truncation of mode data, support zero allocation length (paolo) - target: Properly support zero-length commands in normal processing path (paolo) - iscsi-target: Correctly set 0xffffffff field within ISCSI_OP_REJECT PDU (ronnie + nab) - iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG demo-mode (ronnie + nab) - target/file: Re-enable optional fd_buffered_io=1 operation (nab + hch) - iscsi-target: Add MaxXmitDataSegmenthLength forr target -> initiator MDRSL declaration (nab) - target: Add target_submit_cmd_map_sgls for SGL fabric memory passthrough (nab + hch) - tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls (hch + nab) - tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls (nab + hch) The last series for adding a new target_submit_cmd_map_sgls() fabric caller (as requested by hch) that accepts pre-allocated SGL memory (using existing logic), along with converting tcm_loop + tcm_vhost has only been in -next for the last days, but has gotten enough review +testing and is clear enough a mechanical change that I think it's reasonable to merge for -rc1 code. Thanks again to everyone who contributed this round! Extra special thanks to Roland (PureStorage) for tracking down the qla2xxx target TMR response code endian issue, and to Paolo (Redhat) for resolving the long standing zero-length CDB issues within target-core between virtual and pSCSI backends." * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (44 commits) iscsi-target: Bump defaults for nopin_timeout + nopin_response_timeout values iscsit: proper endianess conversions iscsit: use the itt_t abstract type iscsit: add missing endianess conversion in iscsit_check_inaddr_any iscsit: remove incorrect unlock in iscsit_build_sendtargets_resp iscsit: mark various functions static target/iscsi: precedence bug in iscsit_set_dataout_sequence_values() target/usb-gadget: strlen() doesn't count the terminator target/usb-gadget: remove duplicate initialization tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls target: Add control CDB READ payload zero work-around tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls target: Add target_submit_cmd_map_sgls for SGL fabric memory passthrough iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG demo-mode iscsi-target: Change iscsi_target_seq_pdu_list.c to honor MaxXmitDataSegmentLength iscsi-target: Add MaxXmitDataSegmentLength connection recovery check iscsi-target: Convert incoming PDU payload checks to MaxXmitDataSegmentLength iscsi-target: Enable MaxXmitDataSegmentLength operation in login path iscsi-target: Add base MaxXmitDataSegmentLength code target/file: Re-enable optional fd_buffered_io=1 operation ...
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_parameters.c')
-rw-r--r--drivers/target/iscsi/iscsi_target_parameters.c71
1 files changed, 62 insertions, 9 deletions
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c
index 240f7aa76ed1..90b740048f26 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -334,6 +334,13 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
if (!param)
goto out;
+ param = iscsi_set_default_param(pl, MAXXMITDATASEGMENTLENGTH,
+ INITIAL_MAXXMITDATASEGMENTLENGTH,
+ PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
+ TYPERANGE_512_TO_16777215, USE_ALL);
+ if (!param)
+ goto out;
+
param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH,
INITIAL_MAXRECVDATASEGMENTLENGTH,
PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
@@ -467,6 +474,8 @@ int iscsi_set_keys_to_negotiate(
SET_PSTATE_NEGOTIATE(param);
} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
SET_PSTATE_NEGOTIATE(param);
+ } else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
+ continue;
} else if (!strcmp(param->name, MAXBURSTLENGTH)) {
SET_PSTATE_NEGOTIATE(param);
} else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
@@ -1056,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;
@@ -1131,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);
@@ -1526,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);
@@ -1585,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;
}
@@ -1720,6 +1758,18 @@ void iscsi_set_connection_parameters(
pr_debug("---------------------------------------------------"
"---------------\n");
list_for_each_entry(param, &param_list->param_list, p_list) {
+ /*
+ * Special case to set MAXXMITDATASEGMENTLENGTH from the
+ * target requested MaxRecvDataSegmentLength, even though
+ * this key is not sent over the wire.
+ */
+ if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
+ ops->MaxXmitDataSegmentLength =
+ simple_strtoul(param->value, &tmpptr, 0);
+ pr_debug("MaxXmitDataSegmentLength: %s\n",
+ param->value);
+ }
+
if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
continue;
if (!strcmp(param->name, AUTHMETHOD)) {
@@ -1734,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",