From 593e909166c884077b0f56274a97a8e90a0926af Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 30 Jul 2012 15:54:16 -0700 Subject: [PATCH 01/44] target: Remove request_module for target_core_stgt It is no longer a supported module. Signed-off-by: Andy Grover Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 269f54488397..223acc175c2b 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -211,10 +211,6 @@ void transport_subsystem_check_init(void) if (ret != 0) pr_err("Unable to load target_core_pscsi\n"); - ret = request_module("target_core_stgt"); - if (ret != 0) - pr_err("Unable to load target_core_stgt\n"); - sub_api_initialized = 1; return; } From 283669d282836c5b96faca9bcca184efb9618975 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 30 Jul 2012 15:54:17 -0700 Subject: [PATCH 02/44] target: Cleanup transport_subsystem_check_init Move static into function body from file scope. Remove extraneous return statement Signed-off-by: Andy Grover Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 223acc175c2b..fd0d0f03326b 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -55,8 +55,6 @@ #include "target_core_pr.h" #include "target_core_ua.h" -static int sub_api_initialized; - static struct workqueue_struct *target_completion_wq; static struct kmem_cache *se_sess_cache; struct kmem_cache *se_ua_cache; @@ -195,6 +193,7 @@ u32 scsi_get_new_index(scsi_index_t type) void transport_subsystem_check_init(void) { int ret; + static int sub_api_initialized; if (sub_api_initialized) return; @@ -212,7 +211,6 @@ void transport_subsystem_check_init(void) pr_err("Unable to load target_core_pscsi\n"); sub_api_initialized = 1; - return; } struct se_session *transport_init_session(void) From 343d475d6176fa081918fcbf3fcb0b0143e28661 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 30 Jul 2012 15:54:18 -0700 Subject: [PATCH 03/44] target/sbp: Remove strict param from sbp_parse_wwn It's always set, and controls whether uppercase A-F are allowed hex values. I don't see a reason not to accept these. Signed-off-by: Andy Grover Cc: Chris Boot Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 39ddba584b30..713b88203799 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -2068,7 +2068,7 @@ static int sbp_update_unit_directory(struct sbp_tport *tport) return ret; } -static ssize_t sbp_parse_wwn(const char *name, u64 *wwn, int strict) +static ssize_t sbp_parse_wwn(const char *name, u64 *wwn) { const char *cp; char c, nibble; @@ -2088,7 +2088,7 @@ static ssize_t sbp_parse_wwn(const char *name, u64 *wwn, int strict) err = 3; if (isdigit(c)) nibble = c - '0'; - else if (isxdigit(c) && (islower(c) || !strict)) + else if (isxdigit(c)) nibble = tolower(c) - 'a' + 10; else goto fail; @@ -2117,7 +2117,7 @@ static struct se_node_acl *sbp_make_nodeacl( u64 guid = 0; u32 nexus_depth = 1; - if (sbp_parse_wwn(name, &guid, 1) < 0) + if (sbp_parse_wwn(name, &guid) < 0) return ERR_PTR(-EINVAL); se_nacl_new = sbp_alloc_fabric_acl(se_tpg); @@ -2253,7 +2253,7 @@ static struct se_wwn *sbp_make_tport( struct sbp_tport *tport; u64 guid = 0; - if (sbp_parse_wwn(name, &guid, 1) < 0) + if (sbp_parse_wwn(name, &guid) < 0) return ERR_PTR(-EINVAL); tport = kzalloc(sizeof(*tport), GFP_KERNEL); From 2ed772b7b9df0f459308b3cbececc0136076d09e Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 15 Aug 2012 14:35:24 -0700 Subject: [PATCH 04/44] target: Remove unused target_core_fabric_ops.get_fabric_sense_len method There are no callers of se_tfo->get_fabric_sense_len(), so we should stop having every fabric driver implement it. Signed-off-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- Documentation/target/tcm_mod_builder.py | 8 -------- drivers/infiniband/ulp/srpt/ib_srpt.c | 6 ------ drivers/scsi/qla2xxx/tcm_qla2xxx.c | 7 ------- drivers/target/iscsi/iscsi_target_configfs.c | 9 --------- drivers/target/loopback/tcm_loop.c | 6 ------ drivers/target/sbp/sbp_target.c | 6 ------ drivers/target/target_core_configfs.c | 4 ---- drivers/target/tcm_fc/tfc_conf.c | 6 ------ drivers/usb/gadget/tcm_usb_gadget.c | 6 ------ drivers/vhost/tcm_vhost.c | 6 ------ include/target/target_core_fabric.h | 1 - 11 files changed, 65 deletions(-) diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py index a78879b01f09..13652381cb71 100755 --- a/Documentation/target/tcm_mod_builder.py +++ b/Documentation/target/tcm_mod_builder.py @@ -402,7 +402,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name): buf += " .queue_data_in = " + fabric_mod_name + "_queue_data_in,\n" buf += " .queue_status = " + fabric_mod_name + "_queue_status,\n" buf += " .queue_tm_rsp = " + fabric_mod_name + "_queue_tm_rsp,\n" - buf += " .get_fabric_sense_len = " + fabric_mod_name + "_get_fabric_sense_len,\n" buf += " .set_fabric_sense_len = " + fabric_mod_name + "_set_fabric_sense_len,\n" buf += " .is_state_remove = " + fabric_mod_name + "_is_state_remove,\n" buf += " /*\n" @@ -906,13 +905,6 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name): buf += "}\n\n" bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n" - if re.search('get_fabric_sense_len\)\(', fo): - buf += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void)\n" - buf += "{\n" - buf += " return 0;\n" - buf += "}\n\n" - bufi += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void);\n" - if re.search('set_fabric_sense_len\)\(', fo): buf += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)\n" buf += "{\n" diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 9e1449f8c6a2..9e949750be3a 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3569,11 +3569,6 @@ static u16 srpt_set_fabric_sense_len(struct se_cmd *cmd, u32 sense_length) return 0; } -static u16 srpt_get_fabric_sense_len(void) -{ - return 0; -} - /** * srpt_parse_i_port_id() - Parse an initiator port ID. * @name: ASCII representation of a 128-bit initiator port ID. @@ -3953,7 +3948,6 @@ static struct target_core_fabric_ops srpt_template = { .queue_data_in = srpt_queue_response, .queue_status = srpt_queue_status, .queue_tm_rsp = srpt_queue_response, - .get_fabric_sense_len = srpt_get_fabric_sense_len, .set_fabric_sense_len = srpt_set_fabric_sense_len, /* * Setup function pointers for generic logic in diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 4752f65a9272..556afd5da9ff 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -735,11 +735,6 @@ static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 tcm_qla2xxx_get_fabric_sense_len(void) -{ - return 0; -} - static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) { @@ -1691,7 +1686,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { .queue_data_in = tcm_qla2xxx_queue_data_in, .queue_status = tcm_qla2xxx_queue_status, .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, - .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len, .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, /* * Setup function pointers for generic logic in @@ -1740,7 +1734,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { .queue_data_in = tcm_qla2xxx_queue_data_in, .queue_status = tcm_qla2xxx_queue_status, .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, - .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len, .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, /* * Setup function pointers for generic logic in diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index a7b25e783b58..518fd4e86409 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1557,14 +1557,6 @@ static u16 lio_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) return 2; } -static u16 lio_get_fabric_sense_len(void) -{ - /* - * Return two byte offset into allocated sense_buffer. - */ - return 2; -} - static int lio_queue_tm_rsp(struct se_cmd *se_cmd) { struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); @@ -1749,7 +1741,6 @@ int iscsi_target_register_configfs(void) fabric->tf_ops.queue_status = &lio_queue_status; fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp; fabric->tf_ops.set_fabric_sense_len = &lio_set_fabric_sense_len; - fabric->tf_ops.get_fabric_sense_len = &lio_get_fabric_sense_len; /* * Setup function pointers for generic logic in target_core_fabric_configfs.c */ diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 5491c632a15e..4ab1d0b43a85 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -851,11 +851,6 @@ static u16 tcm_loop_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length return 0; } -static u16 tcm_loop_get_fabric_sense_len(void) -{ - return 0; -} - static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) { switch (tl_hba->tl_proto_id) { @@ -1374,7 +1369,6 @@ static int tcm_loop_register_configfs(void) fabric->tf_ops.queue_status = &tcm_loop_queue_status; fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp; fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len; - fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len; /* * Setup function pointers for generic logic in target_core_fabric_configfs.c diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 713b88203799..cb40a40326cd 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1852,11 +1852,6 @@ static u16 sbp_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) return 0; } -static u16 sbp_get_fabric_sense_len(void) -{ - return 0; -} - static int sbp_check_stop_free(struct se_cmd *se_cmd) { struct sbp_target_request *req = container_of(se_cmd, @@ -2534,7 +2529,6 @@ static struct target_core_fabric_ops sbp_ops = { .queue_data_in = sbp_queue_data_in, .queue_status = sbp_queue_status, .queue_tm_rsp = sbp_queue_tm_rsp, - .get_fabric_sense_len = sbp_get_fabric_sense_len, .set_fabric_sense_len = sbp_set_fabric_sense_len, .check_stop_free = sbp_check_stop_free, diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 801efa892046..946d8e952b67 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -461,10 +461,6 @@ static int target_fabric_tf_ops_check( pr_err("Missing tfo->set_fabric_sense_len()\n"); return -EINVAL; } - if (!tfo->get_fabric_sense_len) { - pr_err("Missing tfo->get_fabric_sense_len()\n"); - return -EINVAL; - } /* * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 9501844fae2d..4f97701350a8 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -495,11 +495,6 @@ static void ft_set_default_node_attr(struct se_node_acl *se_nacl) { } -static u16 ft_get_fabric_sense_len(void) -{ - return 0; -} - static u16 ft_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_len) { return 0; @@ -542,7 +537,6 @@ static struct target_core_fabric_ops ft_fabric_ops = { .queue_data_in = ft_queue_data_in, .queue_status = ft_queue_status, .queue_tm_rsp = ft_queue_tm_resp, - .get_fabric_sense_len = ft_get_fabric_sense_len, .set_fabric_sense_len = ft_set_fabric_sense_len, /* * Setup function pointers for generic logic in diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 5444866e13ef..b7ac43b08851 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1480,11 +1480,6 @@ static u16 usbg_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) return 0; } -static u16 usbg_get_fabric_sense_len(void) -{ - return 0; -} - static const char *usbg_check_wwn(const char *name) { const char *n; @@ -1910,7 +1905,6 @@ static struct target_core_fabric_ops usbg_ops = { .queue_data_in = usbg_send_read_response, .queue_status = usbg_send_status_response, .queue_tm_rsp = usbg_queue_tm_rsp, - .get_fabric_sense_len = usbg_get_fabric_sense_len, .set_fabric_sense_len = usbg_set_fabric_sense_len, .check_stop_free = usbg_check_stop_free, diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index ed8e2e6c8df2..94e6e04aecf2 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -336,11 +336,6 @@ static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd, return 0; } -static u16 tcm_vhost_get_fabric_sense_len(void) -{ - return 0; -} - static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd) { struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; @@ -1531,7 +1526,6 @@ static struct target_core_fabric_ops tcm_vhost_ops = { .queue_data_in = tcm_vhost_queue_data_in, .queue_status = tcm_vhost_queue_status, .queue_tm_rsp = tcm_vhost_queue_tm_rsp, - .get_fabric_sense_len = tcm_vhost_get_fabric_sense_len, .set_fabric_sense_len = tcm_vhost_set_fabric_sense_len, /* * Setup callers for generic logic in target_core_fabric_configfs.c diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 69fb3cfd02d7..a218d02f8295 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -63,7 +63,6 @@ struct target_core_fabric_ops { int (*queue_status)(struct se_cmd *); int (*queue_tm_rsp)(struct se_cmd *); u16 (*set_fabric_sense_len)(struct se_cmd *, u32); - u16 (*get_fabric_sense_len)(void); /* * fabric module calls for target_core_fabric_configfs.c */ From 9c58b7ddd70dd7bfaac4ca87131f36d10aaba441 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 15 Aug 2012 14:35:25 -0700 Subject: [PATCH 05/44] target: Simplify fabric sense data length handling Every fabric driver has to supply a se_tfo->set_fabric_sense_len() method, just so iSCSI can return an offset of 2. However, every fabric driver is already allocating a sense buffer and passing it into the target core, either via transport_init_se_cmd() or target_submit_cmd(). So instead of having iSCSI pass the start of its sense buffer into the core and then later tell the core to skip the first 2 bytes, it seems easier for iSCSI just to do the offset of 2 when it passes the sense buffer into the core. Then we can drop the se_tfo->set_fabric_sense_len() everywhere, and just add a couple of lines of code to iSCSI to set the sense data length to the beginning of the buffer right before it sends it over the network. (nab: Remove .set_fabric_sense_len usage from tcm_qla2xxx_npiv_ops + change transport_get_sense_buffer to follow v3.6-rc6 code w/o ->set_fabric_sense_len usage) Signed-off-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- Documentation/target/tcm_mod_builder.py | 8 - drivers/infiniband/ulp/srpt/ib_srpt.c | 6 - drivers/scsi/qla2xxx/tcm_qla2xxx.c | 8 - drivers/target/iscsi/iscsi_target.c | 13 +- drivers/target/iscsi/iscsi_target_configfs.c | 16 -- drivers/target/loopback/tcm_loop.c | 6 - drivers/target/sbp/sbp_target.c | 6 - drivers/target/target_core_configfs.c | 4 - drivers/target/target_core_transport.c | 155 +++++++++---------- drivers/target/tcm_fc/tfc_conf.c | 6 - drivers/usb/gadget/tcm_usb_gadget.c | 6 - drivers/vhost/tcm_vhost.c | 7 - include/target/target_core_fabric.h | 1 - 13 files changed, 79 insertions(+), 163 deletions(-) diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py index 13652381cb71..3fe0d812dcec 100755 --- a/Documentation/target/tcm_mod_builder.py +++ b/Documentation/target/tcm_mod_builder.py @@ -402,7 +402,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name): buf += " .queue_data_in = " + fabric_mod_name + "_queue_data_in,\n" buf += " .queue_status = " + fabric_mod_name + "_queue_status,\n" buf += " .queue_tm_rsp = " + fabric_mod_name + "_queue_tm_rsp,\n" - buf += " .set_fabric_sense_len = " + fabric_mod_name + "_set_fabric_sense_len,\n" buf += " .is_state_remove = " + fabric_mod_name + "_is_state_remove,\n" buf += " /*\n" buf += " * Setup function pointers for generic logic in target_core_fabric_configfs.c\n" @@ -905,13 +904,6 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name): buf += "}\n\n" bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n" - if re.search('set_fabric_sense_len\)\(', fo): - buf += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)\n" - buf += "{\n" - buf += " return 0;\n" - buf += "}\n\n" - bufi += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *, u32);\n" - if re.search('is_state_remove\)\(', fo): buf += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *se_cmd)\n" buf += "{\n" diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 9e949750be3a..cf23c46185b2 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3564,11 +3564,6 @@ static int srpt_get_tcm_cmd_state(struct se_cmd *se_cmd) return srpt_get_cmd_state(ioctx); } -static u16 srpt_set_fabric_sense_len(struct se_cmd *cmd, u32 sense_length) -{ - return 0; -} - /** * srpt_parse_i_port_id() - Parse an initiator port ID. * @name: ASCII representation of a 128-bit initiator port ID. @@ -3948,7 +3943,6 @@ static struct target_core_fabric_ops srpt_template = { .queue_data_in = srpt_queue_response, .queue_status = srpt_queue_status, .queue_tm_rsp = srpt_queue_response, - .set_fabric_sense_len = srpt_set_fabric_sense_len, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 556afd5da9ff..2358c16c4c8e 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -735,12 +735,6 @@ static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd, - u32 sense_length) -{ - return 0; -} - /* Local pointer to allocated TCM configfs fabric module */ struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; @@ -1686,7 +1680,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { .queue_data_in = tcm_qla2xxx_queue_data_in, .queue_status = tcm_qla2xxx_queue_status, .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, - .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c @@ -1734,7 +1727,6 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { .queue_data_in = tcm_qla2xxx_queue_data_in, .queue_status = tcm_qla2xxx_queue_status, .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, - .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 97c0f78c3c9c..9cfdeedaadb6 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -953,7 +953,7 @@ done: */ transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, conn->sess->se_sess, hdr->data_length, cmd->data_direction, - sam_task_attr, &cmd->sense_buffer[0]); + sam_task_attr, cmd->sense_buffer + 2); pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, @@ -1700,7 +1700,7 @@ static int iscsit_handle_task_mgt_cmd( transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, conn->sess->se_sess, 0, DMA_NONE, - MSG_SIMPLE_TAG, &cmd->sense_buffer[0]); + MSG_SIMPLE_TAG, cmd->sense_buffer + 2); switch (function) { case ISCSI_TM_FUNC_ABORT_TASK: @@ -3092,15 +3092,18 @@ static int iscsit_send_status( if (cmd->se_cmd.sense_buffer && ((cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) || (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) { + put_unaligned_be16(cmd->se_cmd.scsi_sense_length, cmd->sense_buffer); + cmd->se_cmd.scsi_sense_length += sizeof (__be16); + padding = -(cmd->se_cmd.scsi_sense_length) & 3; hton24(hdr->dlength, cmd->se_cmd.scsi_sense_length); - iov[iov_count].iov_base = cmd->se_cmd.sense_buffer; + iov[iov_count].iov_base = cmd->sense_buffer; iov[iov_count++].iov_len = (cmd->se_cmd.scsi_sense_length + padding); tx_size += cmd->se_cmd.scsi_sense_length; if (padding) { - memset(cmd->se_cmd.sense_buffer + + memset(cmd->sense_buffer + cmd->se_cmd.scsi_sense_length, 0, padding); tx_size += padding; pr_debug("Adding %u bytes of padding to" @@ -3109,7 +3112,7 @@ static int iscsit_send_status( if (conn->conn_ops->DataDigest) { iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, - cmd->se_cmd.sense_buffer, + cmd->sense_buffer, (cmd->se_cmd.scsi_sense_length + padding), 0, NULL, (u8 *)&cmd->data_crc); diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 518fd4e86409..f86833fcf33c 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1542,21 +1542,6 @@ static int lio_queue_status(struct se_cmd *se_cmd) return 0; } -static u16 lio_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) -{ - unsigned char *buffer = se_cmd->sense_buffer; - /* - * From RFC-3720 10.4.7. Data Segment - Sense and Response Data Segment - * 16-bit SenseLength. - */ - buffer[0] = ((sense_length >> 8) & 0xff); - buffer[1] = (sense_length & 0xff); - /* - * Return two byte offset into allocated sense_buffer. - */ - return 2; -} - static int lio_queue_tm_rsp(struct se_cmd *se_cmd) { struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); @@ -1740,7 +1725,6 @@ int iscsi_target_register_configfs(void) fabric->tf_ops.queue_data_in = &lio_queue_data_in; fabric->tf_ops.queue_status = &lio_queue_status; fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp; - fabric->tf_ops.set_fabric_sense_len = &lio_set_fabric_sense_len; /* * Setup function pointers for generic logic in target_core_fabric_configfs.c */ diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 4ab1d0b43a85..7a0da1ae0040 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -846,11 +846,6 @@ static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 tcm_loop_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) -{ - return 0; -} - static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) { switch (tl_hba->tl_proto_id) { @@ -1368,7 +1363,6 @@ static int tcm_loop_register_configfs(void) fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in; fabric->tf_ops.queue_status = &tcm_loop_queue_status; fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp; - fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len; /* * Setup function pointers for generic logic in target_core_fabric_configfs.c diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index cb40a40326cd..4d9797744637 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1847,11 +1847,6 @@ static int sbp_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 sbp_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) -{ - return 0; -} - static int sbp_check_stop_free(struct se_cmd *se_cmd) { struct sbp_target_request *req = container_of(se_cmd, @@ -2529,7 +2524,6 @@ static struct target_core_fabric_ops sbp_ops = { .queue_data_in = sbp_queue_data_in, .queue_status = sbp_queue_status, .queue_tm_rsp = sbp_queue_tm_rsp, - .set_fabric_sense_len = sbp_set_fabric_sense_len, .check_stop_free = sbp_check_stop_free, .fabric_make_wwn = sbp_make_tport, diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 946d8e952b67..81dbfed16b20 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -457,10 +457,6 @@ static int target_fabric_tf_ops_check( pr_err("Missing tfo->queue_tm_rsp()\n"); return -EINVAL; } - if (!tfo->set_fabric_sense_len) { - pr_err("Missing tfo->set_fabric_sense_len()\n"); - return -EINVAL; - } /* * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index fd0d0f03326b..d6d48447f1a4 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -567,9 +567,7 @@ static void target_complete_failure_work(struct work_struct *work) */ static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd) { - unsigned char *buffer = cmd->sense_buffer; struct se_device *dev = cmd->se_dev; - u32 offset = 0; WARN_ON(!cmd->se_lun); @@ -579,14 +577,11 @@ static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd) if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) return NULL; - offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); - - /* Automatically padded */ - cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; + cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n", dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); - return &buffer[offset]; + return cmd->sense_buffer; } void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) @@ -2804,7 +2799,6 @@ int transport_send_check_condition_and_sense( { unsigned char *buffer = cmd->sense_buffer; unsigned long flags; - int offset; u8 asc = 0, ascq = 0; spin_lock_irqsave(&cmd->t_state_lock, flags); @@ -2820,14 +2814,7 @@ int transport_send_check_condition_and_sense( if (!from_transport) cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE; - /* - * Data Segment and SenseLength of the fabric response PDU. - * - * TRANSPORT_SENSE_BUFFER is now set to SCSI_SENSE_BUFFERSIZE - * from include/scsi/scsi_cmnd.h - */ - offset = cmd->se_tfo->set_fabric_sense_len(cmd, - TRANSPORT_SENSE_BUFFER); + /* * Actual SENSE DATA, see SPC-3 7.23.2 SPC_SENSE_KEY_OFFSET uses * SENSE KEY values from include/scsi/scsi.h @@ -2835,151 +2822,151 @@ int transport_send_check_condition_and_sense( switch (reason) { case TCM_NON_EXISTENT_LUN: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* LOGICAL UNIT NOT SUPPORTED */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x25; + buffer[SPC_ASC_KEY_OFFSET] = 0x25; break; case TCM_UNSUPPORTED_SCSI_OPCODE: case TCM_SECTOR_COUNT_TOO_MANY: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID COMMAND OPERATION CODE */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x20; + buffer[SPC_ASC_KEY_OFFSET] = 0x20; break; case TCM_UNKNOWN_MODE_PAGE: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID FIELD IN CDB */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24; + buffer[SPC_ASC_KEY_OFFSET] = 0x24; break; case TCM_CHECK_CONDITION_ABORT_CMD: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* BUS DEVICE RESET FUNCTION OCCURRED */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x29; - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x03; + buffer[SPC_ASC_KEY_OFFSET] = 0x29; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x03; break; case TCM_INCORRECT_AMOUNT_OF_DATA: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* WRITE ERROR */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c; + buffer[SPC_ASC_KEY_OFFSET] = 0x0c; /* NOT ENOUGH UNSOLICITED DATA */ - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0d; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x0d; break; case TCM_INVALID_CDB_FIELD: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID FIELD IN CDB */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24; + buffer[SPC_ASC_KEY_OFFSET] = 0x24; break; case TCM_INVALID_PARAMETER_LIST: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* INVALID FIELD IN PARAMETER LIST */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x26; + buffer[SPC_ASC_KEY_OFFSET] = 0x26; break; case TCM_UNEXPECTED_UNSOLICITED_DATA: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* WRITE ERROR */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c; + buffer[SPC_ASC_KEY_OFFSET] = 0x0c; /* UNEXPECTED_UNSOLICITED_DATA */ - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0c; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x0c; break; case TCM_SERVICE_CRC_ERROR: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* PROTOCOL SERVICE CRC ERROR */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x47; + buffer[SPC_ASC_KEY_OFFSET] = 0x47; /* N/A */ - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x05; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x05; break; case TCM_SNACK_REJECTED: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ABORTED COMMAND */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; + buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; /* READ ERROR */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x11; + buffer[SPC_ASC_KEY_OFFSET] = 0x11; /* FAILED RETRANSMISSION REQUEST */ - buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x13; + buffer[SPC_ASCQ_KEY_OFFSET] = 0x13; break; case TCM_WRITE_PROTECTED: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* DATA PROTECT */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = DATA_PROTECT; + buffer[SPC_SENSE_KEY_OFFSET] = DATA_PROTECT; /* WRITE PROTECTED */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x27; + buffer[SPC_ASC_KEY_OFFSET] = 0x27; break; case TCM_ADDRESS_OUT_OF_RANGE: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* LOGICAL BLOCK ADDRESS OUT OF RANGE */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x21; + buffer[SPC_ASC_KEY_OFFSET] = 0x21; break; case TCM_CHECK_CONDITION_UNIT_ATTENTION: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* UNIT ATTENTION */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; + buffer[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; core_scsi3_ua_for_check_condition(cmd, &asc, &ascq); - buffer[offset+SPC_ASC_KEY_OFFSET] = asc; - buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq; + buffer[SPC_ASC_KEY_OFFSET] = asc; + buffer[SPC_ASCQ_KEY_OFFSET] = ascq; break; case TCM_CHECK_CONDITION_NOT_READY: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* Not Ready */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = NOT_READY; + buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY; transport_get_sense_codes(cmd, &asc, &ascq); - buffer[offset+SPC_ASC_KEY_OFFSET] = asc; - buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq; + buffer[SPC_ASC_KEY_OFFSET] = asc; + buffer[SPC_ASCQ_KEY_OFFSET] = ascq; break; case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: default: /* CURRENT ERROR */ - buffer[offset] = 0x70; - buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10; + buffer[0] = 0x70; + buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; /* ILLEGAL REQUEST */ - buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; + buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; /* LOGICAL UNIT COMMUNICATION FAILURE */ - buffer[offset+SPC_ASC_KEY_OFFSET] = 0x80; + buffer[SPC_ASC_KEY_OFFSET] = 0x80; break; } /* @@ -2990,7 +2977,7 @@ int transport_send_check_condition_and_sense( * Automatically padded, this value is encoded in the fabric's * data_length response PDU containing the SCSI defined sense data. */ - cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; + cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; after_reason: return cmd->se_tfo->queue_status(cmd); diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 4f97701350a8..b74feb0d5133 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -495,11 +495,6 @@ static void ft_set_default_node_attr(struct se_node_acl *se_nacl) { } -static u16 ft_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_len) -{ - return 0; -} - static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg) { struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr; @@ -537,7 +532,6 @@ static struct target_core_fabric_ops ft_fabric_ops = { .queue_data_in = ft_queue_data_in, .queue_status = ft_queue_status, .queue_tm_rsp = ft_queue_tm_resp, - .set_fabric_sense_len = ft_set_fabric_sense_len, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index b7ac43b08851..575c82437e4a 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1475,11 +1475,6 @@ static int usbg_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 usbg_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length) -{ - return 0; -} - static const char *usbg_check_wwn(const char *name) { const char *n; @@ -1905,7 +1900,6 @@ static struct target_core_fabric_ops usbg_ops = { .queue_data_in = usbg_send_read_response, .queue_status = usbg_send_status_response, .queue_tm_rsp = usbg_queue_tm_rsp, - .set_fabric_sense_len = usbg_set_fabric_sense_len, .check_stop_free = usbg_check_stop_free, .fabric_make_wwn = usbg_make_tport, diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index 94e6e04aecf2..89dc99baca80 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -330,12 +330,6 @@ static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) return 0; } -static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd, - u32 sense_length) -{ - return 0; -} - static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd) { struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; @@ -1526,7 +1520,6 @@ static struct target_core_fabric_ops tcm_vhost_ops = { .queue_data_in = tcm_vhost_queue_data_in, .queue_status = tcm_vhost_queue_status, .queue_tm_rsp = tcm_vhost_queue_tm_rsp, - .set_fabric_sense_len = tcm_vhost_set_fabric_sense_len, /* * Setup callers for generic logic in target_core_fabric_configfs.c */ diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index a218d02f8295..85a5d7a99543 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -62,7 +62,6 @@ struct target_core_fabric_ops { int (*queue_data_in)(struct se_cmd *); int (*queue_status)(struct se_cmd *); int (*queue_tm_rsp)(struct se_cmd *); - u16 (*set_fabric_sense_len)(struct se_cmd *, u32); /* * fabric module calls for target_core_fabric_configfs.c */ From 35d1efe80500a55f9aa01b305a6714ec78c33764 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 16 Aug 2012 22:43:13 +0900 Subject: [PATCH 06/44] target: Fix minor spelling typos in drivers/target Correct spelling typo in printk and comment within drivers/target. Signed-off-by: Masanari Iida Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_alua.c | 2 +- drivers/target/target_core_configfs.c | 2 +- drivers/target/target_core_device.c | 6 +++--- drivers/target/target_core_fabric_lib.c | 8 ++++---- drivers/target/target_core_pr.c | 4 ++-- drivers/target/target_core_pscsi.c | 2 +- drivers/target/target_core_tpg.c | 2 +- drivers/target/target_core_transport.c | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 41641ba54828..9a5f9a7aecd2 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -344,7 +344,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) */ rtpi = get_unaligned_be16(ptr + 2); /* - * Locate the matching relative target port identifer + * Locate the matching relative target port identifier * for the struct se_device storage object. */ spin_lock(&dev->se_port_lock); diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 81dbfed16b20..a1b41715464a 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -1200,7 +1200,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( " Target Node Endpoint: %s\n", tfo->get_fabric_name(), tfo->tpg_get_wwn(se_tpg)); len += sprintf(page+len, "SPC-3 Reservation: Relative Port" - " Identifer Tag: %hu %s Portal Group Tag: %hu" + " Identifier Tag: %hu %s Portal Group Tag: %hu" " %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi, tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg), tfo->get_fabric_name(), lun->unpacked_lun); diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 9fc9a6006ca0..2d0353355ebd 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -531,7 +531,7 @@ static struct se_port *core_alloc_port(struct se_device *dev) } again: /* - * Allocate the next RELATIVE TARGET PORT IDENTIFER for this struct se_device + * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device * Here is the table from spc4r17 section 7.7.3.8. * * Table 473 -- RELATIVE TARGET PORT IDENTIFIER field @@ -548,7 +548,7 @@ again: list_for_each_entry(port_tmp, &dev->dev_sep_list, sep_list) { /* - * Make sure RELATIVE TARGET PORT IDENTIFER is unique + * Make sure RELATIVE TARGET PORT IDENTIFIER is unique * for 16-bit wrap.. */ if (port->sep_rtpi == port_tmp->sep_rtpi) @@ -595,7 +595,7 @@ static void core_export_port( } dev->dev_port_count++; - port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFER */ + port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFIER */ } /* diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c index 283a36e464e6..e460d6233a0a 100644 --- a/drivers/target/target_core_fabric_lib.c +++ b/drivers/target/target_core_fabric_lib.c @@ -338,7 +338,7 @@ u32 iscsi_get_pr_transport_id_len( * 00b: iSCSI Initiator device TransportID format */ if (pr_reg->isid_present_at_reg) { - len += 5; /* For ",i,0x" ASCII seperator */ + len += 5; /* For ",i,0x" ASCII separator */ len += 7; /* For iSCSI Initiator Session ID + Null terminator */ *format_code = 1; } else @@ -415,20 +415,20 @@ char *iscsi_parse_pr_out_transport_id( *out_tid_len = (add_len + 4); } /* - * Check for ',i,0x' seperator between iSCSI Name and iSCSI Initiator + * Check for ',i,0x' separator between iSCSI Name and iSCSI Initiator * Session ID as defined in Table 390 - iSCSI initiator port TransportID * format. */ if (format_code == 0x40) { p = strstr(&buf[4], ",i,0x"); if (!p) { - pr_err("Unable to locate \",i,0x\" seperator" + pr_err("Unable to locate \",i,0x\" separator" " for Initiator port identifier: %s\n", &buf[4]); return NULL; } *p = '\0'; /* Terminate iSCSI Name */ - p += 5; /* Skip over ",i,0x" seperator */ + p += 5; /* Skip over ",i,0x" separator */ *port_nexus_ptr = p; /* diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 956c84c6b666..3f8aac36ec31 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1620,7 +1620,7 @@ static int core_scsi3_decode_spec_i_port( goto out; } /* - * Locate the desination initiator ACL to be registered + * Locate the destination initiator ACL to be registered * from the decoded fabric module specific TransportID * at *i_str. */ @@ -4257,7 +4257,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) buf[off++] = ((port->sep_rtpi >> 8) & 0xff); buf[off++] = (port->sep_rtpi & 0xff); } else - off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFER */ + off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFIER */ /* * Now, have the $FABRIC_MOD fill in the protocol identifier diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 9d7ce3daa262..617c086a8a02 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -264,7 +264,7 @@ pscsi_get_inquiry_vpd_device_ident(struct scsi_device *sdev, " length zero!\n"); break; } - pr_debug("T10 VPD Identifer Length: %d\n", ident_len); + pr_debug("T10 VPD Identifier Length: %d\n", ident_len); vpd = kzalloc(sizeof(struct t10_vpd), GFP_KERNEL); if (!vpd) { diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index b8628a5014b9..a531fe282b1e 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -303,7 +303,7 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( } /* * Here we only create demo-mode MappedLUNs from the active - * TPG LUNs if the fabric is not explictly asking for + * TPG LUNs if the fabric is not explicitly asking for * tpg_check_demo_mode_login_only() == 1. */ if ((tpg->se_tpg_tfo->tpg_check_demo_mode_login_only == NULL) || diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index d6d48447f1a4..3cc76ad14ce2 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -958,7 +958,7 @@ int transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83) { static const char hex_str[] = "0123456789abcdef"; - int j = 0, i = 4; /* offset to start of the identifer */ + int j = 0, i = 4; /* offset to start of the identifier */ /* * The VPD Code Set (encoding) @@ -2760,7 +2760,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) spin_lock_irqsave(&cmd->t_state_lock, flags); cmd->transport_state &= ~(CMD_T_ACTIVE | CMD_T_STOP); - pr_debug("wait_for_tasks: Stopped wait_for_compltion(" + pr_debug("wait_for_tasks: Stopped wait_for_completion(" "&cmd->t_transport_stop_comp) for ITT: 0x%08x\n", cmd->se_tfo->get_task_tag(cmd)); From 852b6ed110990891d21bf76b4f46a3c854866f67 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 22 Aug 2012 18:45:11 -0700 Subject: [PATCH 07/44] target/iblock: Use match_strlcpy for Opt_udev_path string assignment Following commit dbc6e0222 from Al Viro for fileio, go ahead and make Opt_udev_path within iblock_set_configfs_dev_params use match_strlcpy instead of the match_strdup -> snprintf -> kfree equivalent. Reported-by: Al Viro Cc: Al Viro Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_iblock.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 9ba495477fd2..0f6ece80bffe 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -454,14 +454,11 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba, ret = -EEXIST; goto out; } - arg_p = match_strdup(&args[0]); - if (!arg_p) { - ret = -ENOMEM; + if (match_strlcpy(ib_dev->ibd_udev_path, &args[0], + SE_UDEV_PATH_LEN) == 0) { + ret = -EINVAL; break; } - snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN, - "%s", arg_p); - kfree(arg_p); pr_debug("IBLOCK: Referencing UDEV path: %s\n", ib_dev->ibd_udev_path); ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH; From a60fbbc446a75e077d6e20e0bdb32adfefbec569 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 22 Aug 2012 18:53:12 -0700 Subject: [PATCH 08/44] target/rd: Allow WriteCacheEnabled=1 operation with rd_mcp backends This patch adds the missing rd_mcp_template->write_cache_emulated=1 bit to optionally allow WriteCacheEnabled=1 (WCE) to be enabled for the built-in TCM/rd_mcp backend driver. Tested on v3.6-rc[0,2] code with loopback+tcm_vhost fabric ports. Cc: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_rd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index d00bbe33ff8b..58bcc870366f 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -474,6 +474,7 @@ static int rd_parse_cdb(struct se_cmd *cmd) static struct se_subsystem_api rd_mcp_template = { .name = "rd_mcp", .transport_type = TRANSPORT_PLUGIN_VHBA_VDEV, + .write_cache_emulated = 1, .attach_hba = rd_attach_hba, .detach_hba = rd_detach_hba, .allocate_virtdevice = rd_allocate_virtdevice, From 484018c874804a0563cfa2aba8098b64af04f80a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 08:37:50 +0800 Subject: [PATCH 09/44] tcm_fc: remove unused including Remove including that don't need it. Signed-off-by: Wei Yongjun Signed-off-by: Nicholas Bellinger --- drivers/target/tcm_fc/tfc_cmd.c | 1 - drivers/target/tcm_fc/tfc_io.c | 1 - drivers/target/tcm_fc/tfc_sess.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 823e6922249d..b406f178ff39 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c index ad36ede1a1ea..d051102679a4 100644 --- a/drivers/target/tcm_fc/tfc_io.c +++ b/drivers/target/tcm_fc/tfc_io.c @@ -28,7 +28,6 @@ #include #include -#include #include #include #include diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index 3c9e5b57caab..9585010964ec 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include From 93d441a888c4aefd9f37b30911f8fefa27bdfda3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 26 Aug 2012 08:38:22 +0800 Subject: [PATCH 10/44] target: remove unused including Remove including that don't need it. Signed-off-by: Wei Yongjun Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_fabric_configfs.c | 1 - drivers/target/target_core_stat.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index ea479e54f5fd..bca737bb813d 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c index 3d44beb0cf1f..cb6b0036ae95 100644 --- a/drivers/target/target_core_stat.c +++ b/drivers/target/target_core_stat.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include From fd30e9310253235e88a4eaa38fa92439b56c220e Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sun, 26 Aug 2012 13:35:58 -0700 Subject: [PATCH 11/44] target: Drop se_subsystem_api->[write_cache,fua_write]_emulated flags This patch drops se_subsystem_api->[write_cache,fua_write]_emulated flags set by viritual FILEIO/IBLOCK/RD_MCP backend drivers in favor of explict TRANSPORT_PLUGIN_PHBA_PDEV checks to know when to fail if userspace is attempting to set virtual emulation bits for an pSCSI (passthrough) backend device. Reported-by: Christoph Hellwig Cc: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_device.c | 10 ++++++---- drivers/target/target_core_file.c | 2 -- drivers/target/target_core_iblock.c | 2 -- drivers/target/target_core_rd.c | 1 - include/target/target_core_backend.h | 3 --- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 2d0353355ebd..8d774da16320 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -988,8 +988,9 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) return -EINVAL; } - if (flag && dev->transport->fua_write_emulated == 0) { - pr_err("fua_write_emulated not supported\n"); + if (flag && + dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { + pr_err("emulate_fua_write not supported for pSCSI\n"); return -EINVAL; } dev->se_sub_dev->se_dev_attrib.emulate_fua_write = flag; @@ -1019,8 +1020,9 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) pr_err("Illegal value %d\n", flag); return -EINVAL; } - if (flag && dev->transport->write_cache_emulated == 0) { - pr_err("write_cache_emulated not supported\n"); + if (flag && + dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) { + pr_err("emulate_write_cache not supported for pSCSI\n"); return -EINVAL; } dev->se_sub_dev->se_dev_attrib.emulate_write_cache = flag; diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index cbb5aaf3e567..11119257e514 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -546,8 +546,6 @@ static struct se_subsystem_api fileio_template = { .name = "fileio", .owner = THIS_MODULE, .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, - .write_cache_emulated = 1, - .fua_write_emulated = 1, .attach_hba = fd_attach_hba, .detach_hba = fd_detach_hba, .allocate_virtdevice = fd_allocate_virtdevice, diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 0f6ece80bffe..5b745bb56a68 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -766,8 +766,6 @@ static struct se_subsystem_api iblock_template = { .name = "iblock", .owner = THIS_MODULE, .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, - .write_cache_emulated = 1, - .fua_write_emulated = 1, .attach_hba = iblock_attach_hba, .detach_hba = iblock_detach_hba, .allocate_virtdevice = iblock_allocate_virtdevice, diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 58bcc870366f..d00bbe33ff8b 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -474,7 +474,6 @@ static int rd_parse_cdb(struct se_cmd *cmd) static struct se_subsystem_api rd_mcp_template = { .name = "rd_mcp", .transport_type = TRANSPORT_PLUGIN_VHBA_VDEV, - .write_cache_emulated = 1, .attach_hba = rd_attach_hba, .detach_hba = rd_detach_hba, .allocate_virtdevice = rd_allocate_virtdevice, diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index 941c84bf1065..2acd54018b64 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -13,9 +13,6 @@ struct se_subsystem_api { u8 transport_type; - unsigned int fua_write_emulated : 1; - unsigned int write_cache_emulated : 1; - int (*attach_hba)(struct se_hba *, u32); void (*detach_hba)(struct se_hba *); int (*pmode_enable_hba)(struct se_hba *, unsigned long); From 06cda529d27d778f55690d5b09af8ae4448e796b Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 30 Aug 2012 16:28:30 -0700 Subject: [PATCH 12/44] target/iscsi: Don't log "iSCSI Login negotiation failed." twice There's no need for iscsi_target_init_negotiation() to print iSCSI Login negotiation failed. on failure, since its only caller (__iscsi_target_login_thread()) prints exactly the same message if it gets an error return back. Signed-off-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_nego.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 2dba448cac19..a9a73ac88fd0 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c @@ -1000,7 +1000,6 @@ struct iscsi_login *iscsi_target_init_negotiation( * Locates Target Portal from NP -> Target IQN */ if (iscsi_target_locate_portal(np, conn, login) < 0) { - pr_err("iSCSI Login negotiation failed.\n"); goto out; } From bf11eefcb1dc1326341ebdc44566ad08bee3f539 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 5 Sep 2012 14:42:48 +0800 Subject: [PATCH 13/44] target: use list_move_tail instead of list_del/list_add_tail Using list_move_tail() instead of list_del() + list_add_tail(). spatch with a semantic match is used to found this problem. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 4d9797744637..0ce44cd3488e 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -660,8 +660,7 @@ static void session_reconnect_expired(struct sbp_session *sess) spin_lock_bh(&sess->lock); list_for_each_entry_safe(login, temp, &sess->login_list, link) { login->sess = NULL; - list_del(&login->link); - list_add_tail(&login->link, &login_list); + list_move_tail(&login->link, &login_list); } spin_unlock_bh(&sess->lock); From ffe7b0e9326d9c68f5688bef691dd49f1e0d3651 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 7 Sep 2012 17:30:38 +0200 Subject: [PATCH 14/44] target: support zero allocation length in INQUIRY INQUIRY processing already uses an on-heap bounce buffer for loopback, but not for other fabrics. Switch this to a cheaper on-stack bounce buffer, similar to the one used by MODE SENSE and REQUEST SENSE, and use it unconditionally. With this in place, zero allocation length is handled simply by checking the return address of transport_kmap_data_sg. Testcase: sg_raw /dev/sdb 12 00 83 00 00 00 should fail with ILLEGAL REQUEST / INVALID FIELD IN CDB sense does not fail without the patch fails correctly with the series Signed-off-by: Paolo Bonzini Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_spc.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 388a922c8f6d..b3d8fd260374 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -600,30 +600,11 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; - unsigned char *buf, *map_buf; + unsigned char *rbuf; unsigned char *cdb = cmd->t_task_cdb; + unsigned char buf[SE_INQUIRY_BUF]; int p, ret; - map_buf = transport_kmap_data_sg(cmd); - /* - * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we - * know we actually allocated a full page. Otherwise, if the - * data buffer is too small, allocate a temporary buffer so we - * don't have to worry about overruns in all our INQUIRY - * emulation handling. - */ - if (cmd->data_length < SE_INQUIRY_BUF && - (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) { - buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL); - if (!buf) { - transport_kunmap_data_sg(cmd); - cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - return -ENOMEM; - } - } else { - buf = map_buf; - } - if (dev == tpg->tpg_virt_lun0.lun_se_dev) buf[0] = 0x3f; /* Not connected */ else @@ -655,11 +636,11 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) ret = -EINVAL; out: - if (buf != map_buf) { - memcpy(map_buf, buf, cmd->data_length); - kfree(buf); + rbuf = transport_kmap_data_sg(cmd); + if (rbuf) { + memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); + transport_kunmap_data_sg(cmd); } - transport_kunmap_data_sg(cmd); if (!ret) target_complete_cmd(cmd, GOOD); From 7a3f369ce31694017996524a1cdb08208a839077 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 7 Sep 2012 17:30:39 +0200 Subject: [PATCH 15/44] target: fix truncation of mode data, support zero allocation length The offset was not bumped back to the full size after writing the header of the MODE SENSE response, so the last 1 or 2 bytes were not copied. On top of this, support zero-length requests by checking for the return value of transport_kmap_data_sg. Testcase: sg_raw -r20 /dev/sdb 5a 00 0a 00 00 00 00 00 14 00 last byte should be 0x1e it is 0x00 without the patch it is correct with the patch Signed-off-by: Paolo Bonzini Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_spc.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index b3d8fd260374..9229bd9ad61b 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -784,7 +784,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd) unsigned char *rbuf; int type = dev->transport->get_device_type(dev); int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); - int offset = ten ? 8 : 4; + u32 offset = ten ? 8 : 4; int length = 0; unsigned char buf[SE_MODE_PAGE_BUF]; @@ -817,6 +817,7 @@ static int spc_emulate_modesense(struct se_cmd *cmd) offset -= 2; buf[0] = (offset >> 8) & 0xff; buf[1] = offset & 0xff; + offset += 2; if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || (cmd->se_deve && @@ -826,13 +827,10 @@ static int spc_emulate_modesense(struct se_cmd *cmd) if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) spc_modesense_dpofua(&buf[3], type); - - if ((offset + 2) > cmd->data_length) - offset = cmd->data_length; - } else { offset -= 1; buf[0] = offset & 0xff; + offset += 1; if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || (cmd->se_deve && @@ -842,14 +840,13 @@ static int spc_emulate_modesense(struct se_cmd *cmd) if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) spc_modesense_dpofua(&buf[2], type); - - if ((offset + 1) > cmd->data_length) - offset = cmd->data_length; } rbuf = transport_kmap_data_sg(cmd); - memcpy(rbuf, buf, offset); - transport_kunmap_data_sg(cmd); + if (rbuf) { + memcpy(rbuf, buf, min(offset, cmd->data_length)); + transport_kunmap_data_sg(cmd); + } target_complete_cmd(cmd, GOOD); return 0; From a50da144d048f9dbebed2b1441ed779d6bbbcd03 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 7 Sep 2012 17:30:40 +0200 Subject: [PATCH 16/44] target: support zero allocation length in SBC commands READ CAPACITY must be subject to the same treatment as INQUIRY, REQUEST SENSE, and MODE SENSE, but there are no pre-existing bugs to fix here. Just use an on-stack buffer, and copy to it after checking the return value of transport_kmap_data_sg. Signed-off-by: Paolo Bonzini Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_sbc.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index a9dd9469e3bd..868f8aa04f13 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -40,8 +40,9 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; - unsigned char *buf; unsigned long long blocks_long = dev->transport->get_blocks(dev); + unsigned char *rbuf; + unsigned char buf[8]; u32 blocks; if (blocks_long >= 0x00000000ffffffff) @@ -49,8 +50,6 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) else blocks = (u32)blocks_long; - buf = transport_kmap_data_sg(cmd); - buf[0] = (blocks >> 24) & 0xff; buf[1] = (blocks >> 16) & 0xff; buf[2] = (blocks >> 8) & 0xff; @@ -60,7 +59,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; - transport_kunmap_data_sg(cmd); + rbuf = transport_kmap_data_sg(cmd); + if (rbuf) { + memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); + transport_kunmap_data_sg(cmd); + } target_complete_cmd(cmd, GOOD); return 0; @@ -69,11 +72,11 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd) static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; - unsigned char *buf; + unsigned char *rbuf; + unsigned char buf[32]; unsigned long long blocks = dev->transport->get_blocks(dev); - buf = transport_kmap_data_sg(cmd); - + memset(buf, 0, sizeof(buf)); buf[0] = (blocks >> 56) & 0xff; buf[1] = (blocks >> 48) & 0xff; buf[2] = (blocks >> 40) & 0xff; @@ -93,7 +96,11 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd) if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) buf[14] = 0x80; - transport_kunmap_data_sg(cmd); + rbuf = transport_kmap_data_sg(cmd); + if (rbuf) { + memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); + transport_kunmap_data_sg(cmd); + } target_complete_cmd(cmd, GOOD); return 0; From e0de44573637ba43e43ae1af042e109bbf2b6dd0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 7 Sep 2012 17:30:41 +0200 Subject: [PATCH 17/44] target: do not submit a zero-bio I/O request scsi_setup_fs_cmnd does not like to receive requests with no bios attached to it. Special-case zero-length reads and writes, by not submitting any bio. Testcase: sg_raw /dev/sdb 28 00 00 00 00 00 00 00 00 00 should not fail panics with the rest of the series but not this patch behaves correctly without or with this series Signed-off-by: Paolo Bonzini Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_iblock.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 5b745bb56a68..29408d46a6d9 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -654,6 +654,12 @@ static int iblock_execute_rw(struct se_cmd *cmd) goto fail; cmd->priv = ibr; + if (!sgl_nents) { + atomic_set(&ibr->pending, 1); + iblock_complete_cmd(cmd); + return 0; + } + bio = iblock_get_bio(cmd, block_lba, sgl_nents); if (!bio) goto fail_free_ibr; From d81cb44726f050d7cf1be4afd9cb45d153b52066 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 17 Sep 2012 16:36:11 -0700 Subject: [PATCH 18/44] target: go through normal processing for all zero-length commands Yay, all users of transport_kmap_data_sg now check for a zero-length request and/or a too-small parameter list length. We can thus go through the normal emulation path even for such commands. This means that out-of-bounds reads and writes are now reported correctly even if they transfer 0 blocks. Other errors are also reported correctly. Testcase: sg_raw /dev/sdb 28 00 80 00 00 00 00 00 00 00 should fail with ILLEGAL REQUEST / LBA OUT OF RANGE sense does not fail without the patch (still wrong with the patch, but better: the ASC is INVALID FIELD IN CDB) Signed-off-by: Paolo Bonzini Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 3cc76ad14ce2..221f67f3427c 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2289,23 +2289,6 @@ int transport_generic_new_cmd(struct se_cmd *cmd) if (ret < 0) goto out_fail; } - /* - * If this command doesn't have any payload and we don't have to call - * into the fabric for data transfers, go ahead and complete it right - * away. - */ - if (!cmd->data_length && - cmd->t_task_cdb[0] != REQUEST_SENSE && - cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { - spin_lock_irq(&cmd->t_state_lock); - cmd->t_state = TRANSPORT_COMPLETE; - cmd->transport_state |= CMD_T_ACTIVE; - spin_unlock_irq(&cmd->t_state_lock); - - INIT_WORK(&cmd->work, target_complete_ok_work); - queue_work(target_completion_wq, &cmd->work); - return 0; - } atomic_inc(&cmd->t_fe_count); From 7875f179085608c659b676be74d33a2e515d8f43 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 7 Sep 2012 14:55:32 +0800 Subject: [PATCH 19/44] tcm_fc: move the dereference below the NULL test The dereference should be moved below the NULL test. spatch with a semantic match is used to found this. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Nicholas Bellinger --- drivers/target/tcm_fc/tfc_io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c index d051102679a4..b6fd4cf42840 100644 --- a/drivers/target/tcm_fc/tfc_io.c +++ b/drivers/target/tcm_fc/tfc_io.c @@ -327,11 +327,12 @@ drop: */ void ft_invl_hw_context(struct ft_cmd *cmd) { - struct fc_seq *seq = cmd->seq; + struct fc_seq *seq; struct fc_exch *ep = NULL; struct fc_lport *lport = NULL; BUG_ON(!cmd); + seq = cmd->seq; /* Cleanup the DDP context in HW if DDP was setup */ if (cmd->was_ddp_setup && seq) { From 609234e3b6d69315b5cd511b66435d733204e779 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 7 Sep 2012 14:56:28 +0800 Subject: [PATCH 20/44] target: move the dereference below the NULL test The dereference should be moved below the NULL test. spatch with a semantic match is used to found this. (http://coccinelle.lip6.fr/) Signed-off-by: Wei Yongjun Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_pr.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 3f8aac36ec31..8c323a98c4a0 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -197,10 +197,10 @@ int target_scsi2_reservation_release(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; - struct se_portal_group *tpg = sess->se_tpg; + struct se_portal_group *tpg; int ret = 0, rc; - if (!sess || !tpg) + if (!sess || !sess->se_tpg) goto out; rc = target_check_scsi2_reservation_conflict(cmd); if (rc == 1) @@ -228,6 +228,7 @@ int target_scsi2_reservation_release(struct se_cmd *cmd) dev->dev_res_bin_isid = 0; dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID; } + tpg = sess->se_tpg; pr_debug("SCSI-2 Released reservation for %s LUN: %u ->" " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(), cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, @@ -245,7 +246,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; struct se_session *sess = cmd->se_sess; - struct se_portal_group *tpg = sess->se_tpg; + struct se_portal_group *tpg; int ret = 0, rc; if ((cmd->t_task_cdb[1] & 0x01) && @@ -260,7 +261,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) * This is currently the case for target_core_mod passthrough struct se_cmd * ops */ - if (!sess || !tpg) + if (!sess || !sess->se_tpg) goto out; rc = target_check_scsi2_reservation_conflict(cmd); if (rc == 1) @@ -272,6 +273,7 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd) } ret = 0; + tpg = sess->se_tpg; spin_lock(&dev->dev_reservation_lock); if (dev->dev_reserved_node_acl && (dev->dev_reserved_node_acl != sess->se_node_acl)) { From 37bb7899ca366dc212b71b150e78566d04808cc0 Mon Sep 17 00:00:00 2001 From: Peter Senna Tschudin Date: Mon, 17 Sep 2012 20:05:33 +0200 Subject: [PATCH 21/44] target: fix return code in target_core_init_configfs error path This patch fixes error cases within target_core_init_configfs() to properly set ret = -ENOMEM before jumping to the out_global exception path. This was originally discovered with the following Coccinelle semantic match information: Convert a nonnegative error return code to a negative one, as returned elsewhere in the function. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // ( if@p1 (\(ret < 0\|ret != 0\)) { ... return ret; } | ret@p1 = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Peter Senna Tschudin Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_configfs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index a1b41715464a..015f5be27bf6 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -3124,6 +3124,7 @@ static int __init target_core_init_configfs(void) GFP_KERNEL); if (!target_cg->default_groups) { pr_err("Unable to allocate target_cg->default_groups\n"); + ret = -ENOMEM; goto out_global; } @@ -3139,6 +3140,7 @@ static int __init target_core_init_configfs(void) GFP_KERNEL); if (!hba_cg->default_groups) { pr_err("Unable to allocate hba_cg->default_groups\n"); + ret = -ENOMEM; goto out_global; } config_group_init_type_name(&alua_group, @@ -3154,6 +3156,7 @@ static int __init target_core_init_configfs(void) GFP_KERNEL); if (!alua_cg->default_groups) { pr_err("Unable to allocate alua_cg->default_groups\n"); + ret = -ENOMEM; goto out_global; } @@ -3165,14 +3168,17 @@ static int __init target_core_init_configfs(void) * Add core/alua/lu_gps/default_lu_gp */ lu_gp = core_alua_allocate_lu_gp("default_lu_gp", 1); - if (IS_ERR(lu_gp)) + if (IS_ERR(lu_gp)) { + ret = -ENOMEM; goto out_global; + } lu_gp_cg = &alua_lu_gps_group; lu_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, GFP_KERNEL); if (!lu_gp_cg->default_groups) { pr_err("Unable to allocate lu_gp_cg->default_groups\n"); + ret = -ENOMEM; goto out_global; } From e4b11b89f9039ca97b2ed1b6efeb6749fbdeb252 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 18 Sep 2012 15:10:56 -0700 Subject: [PATCH 22/44] qla2xxx: Fix endianness of task management response code The qla2xxx firmware actually expects the task management response code in a CTIO IOCB with SCSI status mode 1 to be in little-endian byte order, ie the response code should be the first byte in the sense_data[] array. The old code erroneously byte-swapped the response code, which puts it in the wrong place on the wire and leads to initiators thinking every task management request succeeds (since they see 0 in the byte where they look for the response code). Signed-off-by: Roland Dreier Cc: Chad Dupuis Cc: Arun Easi Acked-by: Saurav Kashyap Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/scsi/qla2xxx/qla_target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 5b30132960c7..41b74ba8d4e5 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1403,7 +1403,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, ctio->u.status1.scsi_status = __constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID); ctio->u.status1.response_len = __constant_cpu_to_le16(8); - ((uint32_t *)ctio->u.status1.sense_data)[0] = cpu_to_be32(resp_code); + ctio->u.status1.sense_data[0] = resp_code; qla2x00_start_iocbs(ha, ha->req); } From b659f4b4ff52b14dcef4848e3f434b3582842960 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 21 Sep 2012 13:57:31 +0800 Subject: [PATCH 23/44] sbp-target: fix return value check in sbp_register_configfs() In case of error, the function target_fabric_configfs_init() returns ERR_PTR() not NULL pointer. The NULL test in the return value check should be replaced with IS_ERR(). dpatch engine is used to auto generated this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 0ce44cd3488e..0d6d7c1f025e 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -2543,9 +2543,9 @@ static int sbp_register_configfs(void) int ret; fabric = target_fabric_configfs_init(THIS_MODULE, "sbp"); - if (!fabric) { + if (IS_ERR(fabric)) { pr_err("target_fabric_configfs_init() failed\n"); - return -ENOMEM; + return PTR_ERR(fabric); } fabric->tf_ops = sbp_ops; From f25590f39d543272f7ae7b00d533359c8d7ff331 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 22 Sep 2012 17:21:06 -0700 Subject: [PATCH 24/44] iscsi-target: Correctly set 0xffffffff field within ISCSI_OP_REJECT PDU This patch adds a missing iscsi_reject->ffffffff assignment within iscsit_send_reject() code to properly follow RFC-3720 Section 10.17 Bytes 16 -> 19 for the PDU format definition of ISCSI_OP_REJECT. We've not seen any initiators care about this bytes in practice, but as Ronnie reported this was causing trouble with wireshark packet decoding lets go ahead and fix this up now. Reported-by: Ronnie Sahlberg Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 9cfdeedaadb6..30842e195996 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3427,6 +3427,7 @@ static int iscsit_send_reject( hdr->opcode = ISCSI_OP_REJECT; hdr->flags |= ISCSI_FLAG_CMD_FINAL; hton24(hdr->dlength, ISCSI_HDR_LEN); + hdr->ffffffff = 0xffffffff; cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); From b32f4c7ed85c5cee2a21a55c9f59ebc9d57a2463 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 29 Sep 2012 17:15:37 -0700 Subject: [PATCH 25/44] target/file: Re-enable optional fd_buffered_io=1 operation This patch re-adds the ability to optionally run in buffered FILEIO mode (eg: w/o O_DSYNC) for device backends in order to once again use the Linux buffered cache as a write-back storage mechanism. This logic was originally dropped with mainline v3.5-rc commit: commit a4dff3043c231d57f982af635c9d2192ee40e5ae Author: Nicholas Bellinger Date: Wed May 30 16:25:41 2012 -0700 target/file: Use O_DSYNC by default for FILEIO backends This difference with this patch is that fd_create_virtdevice() now forces the explicit setting of emulate_write_cache=1 when buffered FILEIO operation has been enabled. (v2: Switch to FDBD_HAS_BUFFERED_IO_WCE + add more detailed comment as requested by hch) Reported-by: Ferry Cc: Christoph Hellwig Cc: Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_file.c | 41 ++++++++++++++++++++++++++++--- drivers/target/target_core_file.h | 1 + 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 11119257e514..0360383dfb94 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -125,6 +125,19 @@ static struct se_device *fd_create_virtdevice( * of pure timestamp updates. */ flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC; + /* + * Optionally allow fd_buffered_io=1 to be enabled for people + * who want use the fs buffer cache as an WriteCache mechanism. + * + * This means that in event of a hard failure, there is a risk + * of silent data-loss if the SCSI client has *not* performed a + * forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE + * to write-out the entire device cache. + */ + if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { + pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n"); + flags &= ~O_DSYNC; + } file = filp_open(fd_dev->fd_dev_name, flags, 0600); if (IS_ERR(file)) { @@ -188,6 +201,12 @@ static struct se_device *fd_create_virtdevice( if (!dev) goto fail; + if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { + pr_debug("FILEIO: Forcing setting of emulate_write_cache=1" + " with FDBD_HAS_BUFFERED_IO_WCE\n"); + dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1; + } + fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++; fd_dev->fd_queue_depth = dev->queue_depth; @@ -407,6 +426,7 @@ enum { static match_table_t tokens = { {Opt_fd_dev_name, "fd_dev_name=%s"}, {Opt_fd_dev_size, "fd_dev_size=%s"}, + {Opt_fd_buffered_io, "fd_buffered_io=%d"}, {Opt_err, NULL} }; @@ -418,7 +438,7 @@ static ssize_t fd_set_configfs_dev_params( struct fd_dev *fd_dev = se_dev->se_dev_su_ptr; char *orig, *ptr, *arg_p, *opts; substring_t args[MAX_OPT_ARGS]; - int ret = 0, token; + int ret = 0, arg, token; opts = kstrdup(page, GFP_KERNEL); if (!opts) @@ -459,6 +479,19 @@ static ssize_t fd_set_configfs_dev_params( " bytes\n", fd_dev->fd_dev_size); fd_dev->fbd_flags |= FBDF_HAS_SIZE; break; + case Opt_fd_buffered_io: + match_int(args, &arg); + if (arg != 1) { + pr_err("bogus fd_buffered_io=%d value\n", arg); + ret = -EINVAL; + goto out; + } + + pr_debug("FILEIO: Using buffered I/O" + " operations for struct fd_dev\n"); + + fd_dev->fbd_flags |= FDBD_HAS_BUFFERED_IO_WCE; + break; default: break; } @@ -490,8 +523,10 @@ static ssize_t fd_show_configfs_dev_params( ssize_t bl = 0; bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id); - bl += sprintf(b + bl, " File: %s Size: %llu Mode: O_DSYNC\n", - fd_dev->fd_dev_name, fd_dev->fd_dev_size); + bl += sprintf(b + bl, " File: %s Size: %llu Mode: %s\n", + fd_dev->fd_dev_name, fd_dev->fd_dev_size, + (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) ? + "Buffered-WCE" : "O_DSYNC"); return bl; } diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h index 70ce7fd7111d..876ae53ef5b8 100644 --- a/drivers/target/target_core_file.h +++ b/drivers/target/target_core_file.h @@ -14,6 +14,7 @@ #define FBDF_HAS_PATH 0x01 #define FBDF_HAS_SIZE 0x02 +#define FDBD_HAS_BUFFERED_IO_WCE 0x04 struct fd_dev { u32 fbd_flags; From e004cb25927ad7a67c109ac13e1d2e5e378430dd Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 29 Sep 2012 21:47:16 -0700 Subject: [PATCH 26/44] iscsi-target: Add base MaxXmitDataSegmentLength code This patch introduces a new per connection MaxXmitDataSegmentLength parameter value used to represent the outgoing MaxRecvDataSegmentLength that is actually sent over the wire during iSCSI login response back to the initiator side. It also adds a new MaxXmitDataSegmentLength configfs attribute to represent this value within the existing TPG parameter group under /sys/kernel/config/target/iscsi/$TARGETNAME/$TPGT/param/ Cc: Mike Christie Cc: Andy Grover Cc: Hannes Reinecke Cc: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_configfs.c | 4 ++++ drivers/target/iscsi/iscsi_target_core.h | 1 + .../target/iscsi/iscsi_target_parameters.c | 21 +++++++++++++++++++ .../target/iscsi/iscsi_target_parameters.h | 5 +++++ 4 files changed, 31 insertions(+) diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index f86833fcf33c..f491f969ab95 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1034,6 +1034,9 @@ TPG_PARAM_ATTR(ImmediateData, S_IRUGO | S_IWUSR); DEF_TPG_PARAM(MaxRecvDataSegmentLength); TPG_PARAM_ATTR(MaxRecvDataSegmentLength, S_IRUGO | S_IWUSR); +DEF_TPG_PARAM(MaxXmitDataSegmentLength); +TPG_PARAM_ATTR(MaxXmitDataSegmentLength, S_IRUGO | S_IWUSR); + DEF_TPG_PARAM(MaxBurstLength); TPG_PARAM_ATTR(MaxBurstLength, S_IRUGO | S_IWUSR); @@ -1079,6 +1082,7 @@ static struct configfs_attribute *lio_target_tpg_param_attrs[] = { &iscsi_tpg_param_InitialR2T.attr, &iscsi_tpg_param_ImmediateData.attr, &iscsi_tpg_param_MaxRecvDataSegmentLength.attr, + &iscsi_tpg_param_MaxXmitDataSegmentLength.attr, &iscsi_tpg_param_MaxBurstLength.attr, &iscsi_tpg_param_FirstBurstLength.attr, &iscsi_tpg_param_DefaultTime2Wait.attr, diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 8a908b28d8b2..b26611aa5ff3 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -239,6 +239,7 @@ struct iscsi_conn_ops { u8 HeaderDigest; /* [0,1] == [None,CRC32C] */ u8 DataDigest; /* [0,1] == [None,CRC32C] */ u32 MaxRecvDataSegmentLength; /* [512..2**24-1] */ + u32 MaxXmitDataSegmentLength; /* [512..2**24-1] */ u8 OFMarker; /* [0,1] == [No,Yes] */ u8 IFMarker; /* [0,1] == [No,Yes] */ u32 OFMarkInt; /* [1..65535] */ diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index 0c4760fabfc0..40864ee70302 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)) { @@ -1720,6 +1729,18 @@ void iscsi_set_connection_parameters( pr_debug("---------------------------------------------------" "---------------\n"); list_for_each_entry(param, ¶m_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)) { diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h index 6a37fd6f1285..77a28b589d56 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.h +++ b/drivers/target/iscsi/iscsi_target_parameters.h @@ -70,6 +70,7 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *, #define INITIALR2T "InitialR2T" #define IMMEDIATEDATA "ImmediateData" #define MAXRECVDATASEGMENTLENGTH "MaxRecvDataSegmentLength" +#define MAXXMITDATASEGMENTLENGTH "MaxXmitDataSegmentLength" #define MAXBURSTLENGTH "MaxBurstLength" #define FIRSTBURSTLENGTH "FirstBurstLength" #define DEFAULTTIME2WAIT "DefaultTime2Wait" @@ -113,6 +114,10 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *, #define INITIAL_INITIALR2T YES #define INITIAL_IMMEDIATEDATA YES #define INITIAL_MAXRECVDATASEGMENTLENGTH "8192" +/* + * Match outgoing MXDSL default to incoming Open-iSCSI default + */ +#define INITIAL_MAXXMITDATASEGMENTLENGTH "262144" #define INITIAL_MAXBURSTLENGTH "262144" #define INITIAL_FIRSTBURSTLENGTH "65536" #define INITIAL_DEFAULTTIME2WAIT "2" From 9977bb18c92e694819266fc0e7c5a3cd0cd7b626 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 29 Sep 2012 21:49:59 -0700 Subject: [PATCH 27/44] 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 Cc: Andy Grover Cc: Hannes Reinecke Cc: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_nego.c | 4 +- .../target/iscsi/iscsi_target_parameters.c | 50 +++++++++++++++---- .../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( 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 40864ee70302..3678ff2139de 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 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 *); 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 *); From 21f5aa7eb8572b5cfe36884c23d306c72fe3987c Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 29 Sep 2012 21:51:26 -0700 Subject: [PATCH 28/44] iscsi-target: Convert incoming PDU payload checks to MaxXmitDataSegmentLength Now that iscsi-target supports a local configurable MaxXmitDataSegmentLength, go ahead and make ISCSI_OP_SCSI_CMD, ISCSI_OP_SCSI_DATA_OUT, ISCSI_OP_NOOP_OUT and ISCSI_OP_TEXT PDU payload checks honor conn_ops->MaxXmitDataSegmentLength. Cc: Mike Christie Cc: Andy Grover Cc: Hannes Reinecke Cc: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 30842e195996..632a5aeb14d9 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -869,10 +869,10 @@ done: buf, conn); } - if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) { + if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { pr_err("DataSegmentLength: %u is greater than" - " MaxRecvDataSegmentLength: %u, protocol error.\n", - payload_length, conn->conn_ops->MaxRecvDataSegmentLength); + " MaxXmitDataSegmentLength: %u, protocol error.\n", + payload_length, conn->conn_ops->MaxXmitDataSegmentLength); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, buf, conn); } @@ -1216,10 +1216,10 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) } spin_unlock_bh(&conn->sess->session_stats_lock); - if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) { + if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { pr_err("DataSegmentLength: %u is greater than" - " MaxRecvDataSegmentLength: %u\n", payload_length, - conn->conn_ops->MaxRecvDataSegmentLength); + " MaxXmitDataSegmentLength: %u\n", payload_length, + conn->conn_ops->MaxXmitDataSegmentLength); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, buf, conn); } @@ -1437,11 +1437,11 @@ static int iscsit_handle_nop_out( buf, conn); } - if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) { + if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { pr_err("NOPOUT Ping Data DataSegmentLength: %u is" - " greater than MaxRecvDataSegmentLength: %u, protocol" + " greater than MaxXmitDataSegmentLength: %u, protocol" " error.\n", payload_length, - conn->conn_ops->MaxRecvDataSegmentLength); + conn->conn_ops->MaxXmitDataSegmentLength); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, buf, conn); } @@ -1874,10 +1874,10 @@ static int iscsit_handle_text_cmd( hdr->cmdsn = be32_to_cpu(hdr->cmdsn); hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) { + if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { pr_err("Unable to accept text parameter length: %u" - "greater than MaxRecvDataSegmentLength %u.\n", - payload_length, conn->conn_ops->MaxRecvDataSegmentLength); + "greater than MaxXmitDataSegmentLength %u.\n", + payload_length, conn->conn_ops->MaxXmitDataSegmentLength); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, buf, conn); } From 1c417f39c1f896206f0d5bfec65cd61a8f5e69b8 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 29 Sep 2012 22:14:51 -0700 Subject: [PATCH 29/44] iscsi-target: Add MaxXmitDataSegmentLength connection recovery check The iSCSI TMR TASK_REASSIGN completion logic in iscsi_tmr_task_reassign() does an explict check for MRDSL across task reassignment, so go ahead and add an explict MaxXmitDataSegmentLength check here as well to be safe. Cc: Mike Christie Cc: Andy Grover Cc: Hannes Reinecke Cc: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_core.h | 1 + drivers/target/iscsi/iscsi_target_erl2.c | 1 + drivers/target/iscsi/iscsi_target_tmr.c | 9 ++++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index b26611aa5ff3..e6a830545c89 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -579,6 +579,7 @@ struct iscsi_conn_recovery { u16 cid; u32 cmd_count; u32 maxrecvdatasegmentlength; + u32 maxxmitdatasegmentlength; int ready_for_reallegiance; struct list_head conn_recovery_cmd_list; spinlock_t conn_recovery_cmd_lock; diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index 65aac14fd831..667c19cc3b28 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c @@ -421,6 +421,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) cr->cid = conn->cid; cr->cmd_count = cmd_count; cr->maxrecvdatasegmentlength = conn->conn_ops->MaxRecvDataSegmentLength; + cr->maxxmitdatasegmentlength = conn->conn_ops->MaxXmitDataSegmentLength; cr->sess = conn->sess; iscsit_attach_inactive_connection_recovery_entry(conn->sess, cr); diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index f62fe123d902..05d2e6445ade 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c @@ -146,7 +146,7 @@ u8 iscsit_tmr_task_reassign( } /* * Temporary check to prevent connection recovery for - * connections with a differing MaxRecvDataSegmentLength. + * connections with a differing Max*DataSegmentLength. */ if (cr->maxrecvdatasegmentlength != conn->conn_ops->MaxRecvDataSegmentLength) { @@ -155,6 +155,13 @@ u8 iscsit_tmr_task_reassign( " TMR TASK_REASSIGN.\n"); return ISCSI_TMF_RSP_REJECTED; } + if (cr->maxxmitdatasegmentlength != + conn->conn_ops->MaxXmitDataSegmentLength) { + pr_err("Unable to perform connection recovery for" + " differing MaxXmitDataSegmentLength, rejecting" + " TMR TASK_REASSIGN.\n"); + return ISCSI_TMF_RSP_REJECTED; + } ref_lun = scsilun_to_int(&hdr->lun); if (ref_lun != ref_cmd->se_cmd.orig_fe_lun) { From b094a4bd840e6f268f70a79a099debaf235e44e5 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 29 Sep 2012 22:34:10 -0700 Subject: [PATCH 30/44] iscsi-target: Change iscsi_target_seq_pdu_list.c to honor MaxXmitDataSegmentLength This patch converts iscsi_target_seq_pdu_list.c code for DataSequenceInOrder=No + DataPDUInOrder=No operation to honor the MaxXmitDataSegmentLength value for iscsi_cmd->se_cmd.data_direction == DMA_TO_DEVICE cases. Cc: Mike Christie Cc: Andy Grover Cc: Hannes Reinecke Cc: Roland Dreier Signed-off-by: Nicholas Bellinger --- .../target/iscsi/iscsi_target_seq_pdu_list.c | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c index 85a306e067ba..edb592a368ef 100644 --- a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c +++ b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c @@ -219,8 +219,14 @@ static void iscsit_determine_counts_for_list( int check_immediate = 0; u32 burstlength = 0, offset = 0; u32 unsolicited_data_length = 0; + u32 mdsl; struct iscsi_conn *conn = cmd->conn; + if (cmd->se_cmd.data_direction == DMA_TO_DEVICE) + mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength; + else + mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength; + if ((bl->type == PDULIST_IMMEDIATE) || (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED)) check_immediate = 1; @@ -243,14 +249,13 @@ static void iscsit_determine_counts_for_list( continue; } if (unsolicited_data_length > 0) { - if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) - >= cmd->se_cmd.data_length) { + if ((offset + mdsl) >= cmd->se_cmd.data_length) { unsolicited_data_length -= (cmd->se_cmd.data_length - offset); offset += (cmd->se_cmd.data_length - offset); continue; } - if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) + if ((offset + mdsl) >= conn->sess->sess_ops->FirstBurstLength) { unsolicited_data_length -= (conn->sess->sess_ops->FirstBurstLength - @@ -262,17 +267,15 @@ static void iscsit_determine_counts_for_list( continue; } - offset += conn->conn_ops->MaxRecvDataSegmentLength; - unsolicited_data_length -= - conn->conn_ops->MaxRecvDataSegmentLength; + offset += mdsl; + unsolicited_data_length -= mdsl; continue; } - if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { + if ((offset + mdsl) >= cmd->se_cmd.data_length) { offset += (cmd->se_cmd.data_length - offset); continue; } - if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >= + if ((burstlength + mdsl) >= conn->sess->sess_ops->MaxBurstLength) { offset += (conn->sess->sess_ops->MaxBurstLength - burstlength); @@ -281,8 +284,8 @@ static void iscsit_determine_counts_for_list( continue; } - burstlength += conn->conn_ops->MaxRecvDataSegmentLength; - offset += conn->conn_ops->MaxRecvDataSegmentLength; + burstlength += mdsl; + offset += mdsl; } } @@ -296,12 +299,17 @@ static int iscsit_do_build_pdu_and_seq_lists( struct iscsi_build_list *bl) { int check_immediate = 0, datapduinorder, datasequenceinorder; - u32 burstlength = 0, offset = 0, i = 0; + u32 burstlength = 0, offset = 0, i = 0, mdsl; u32 pdu_count = 0, seq_no = 0, unsolicited_data_length = 0; struct iscsi_conn *conn = cmd->conn; struct iscsi_pdu *pdu = cmd->pdu_list; struct iscsi_seq *seq = cmd->seq_list; + if (cmd->se_cmd.data_direction == DMA_TO_DEVICE) + mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength; + else + mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength; + datapduinorder = conn->sess->sess_ops->DataPDUInOrder; datasequenceinorder = conn->sess->sess_ops->DataSequenceInOrder; @@ -348,9 +356,7 @@ static int iscsit_do_build_pdu_and_seq_lists( continue; } if (unsolicited_data_length > 0) { - if ((offset + - conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { + if ((offset + mdsl) >= cmd->se_cmd.data_length) { if (!datapduinorder) { pdu[i].type = PDUTYPE_UNSOLICITED; pdu[i].length = @@ -367,8 +373,7 @@ static int iscsit_do_build_pdu_and_seq_lists( offset += (cmd->se_cmd.data_length - offset); continue; } - if ((offset + - conn->conn_ops->MaxRecvDataSegmentLength) >= + if ((offset + mdsl) >= conn->sess->sess_ops->FirstBurstLength) { if (!datapduinorder) { pdu[i].type = PDUTYPE_UNSOLICITED; @@ -396,17 +401,14 @@ static int iscsit_do_build_pdu_and_seq_lists( if (!datapduinorder) { pdu[i].type = PDUTYPE_UNSOLICITED; - pdu[i++].length = - conn->conn_ops->MaxRecvDataSegmentLength; + pdu[i++].length = mdsl; } - burstlength += conn->conn_ops->MaxRecvDataSegmentLength; - offset += conn->conn_ops->MaxRecvDataSegmentLength; - unsolicited_data_length -= - conn->conn_ops->MaxRecvDataSegmentLength; + burstlength += mdsl; + offset += mdsl; + unsolicited_data_length -= mdsl; continue; } - if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >= - cmd->se_cmd.data_length) { + if ((offset + mdsl) >= cmd->se_cmd.data_length) { if (!datapduinorder) { pdu[i].type = PDUTYPE_NORMAL; pdu[i].length = (cmd->se_cmd.data_length - offset); @@ -420,7 +422,7 @@ static int iscsit_do_build_pdu_and_seq_lists( offset += (cmd->se_cmd.data_length - offset); continue; } - if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >= + if ((burstlength + mdsl) >= conn->sess->sess_ops->MaxBurstLength) { if (!datapduinorder) { pdu[i].type = PDUTYPE_NORMAL; @@ -445,11 +447,10 @@ static int iscsit_do_build_pdu_and_seq_lists( if (!datapduinorder) { pdu[i].type = PDUTYPE_NORMAL; - pdu[i++].length = - conn->conn_ops->MaxRecvDataSegmentLength; + pdu[i++].length = mdsl; } - burstlength += conn->conn_ops->MaxRecvDataSegmentLength; - offset += conn->conn_ops->MaxRecvDataSegmentLength; + burstlength += mdsl; + offset += mdsl; } if (!datasequenceinorder) { From 38b11bae6ba02da352340aff12ee25755977b222 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sun, 30 Sep 2012 12:20:02 -0700 Subject: [PATCH 31/44] iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG demo-mode We've had reports in the past about this specific case, so it's time to go ahead and explicitly set cache_dynamic_acls=1 for generate_node_acls=1 (TPG demo-mode) operation. During normal generate_node_acls=0 operation with explicit NodeACLs -> se_node_acl memory is persistent to the configfs group located at /sys/kernel/config/target/$TARGETNAME/$TPGT/acls/$INITIATORNAME, so in the generate_node_acls=1 case we want the reservation logic to reference existing per initiator IQN se_node_acl memory (not to generate a new se_node_acl), so go ahead and always set cache_dynamic_acls=1 when TPG demo-mode is enabled. Reported-by: Ronnie Sahlberg Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_tpg.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index a38a3f8ab0d9..de9ea32b6104 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -677,6 +677,12 @@ int iscsit_ta_generate_node_acls( pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n", tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled"); + if (flag == 1 && a->cache_dynamic_acls == 0) { + pr_debug("Explicitly setting cache_dynamic_acls=1 when " + "generate_node_acls=1\n"); + a->cache_dynamic_acls = 1; + } + return 0; } @@ -716,6 +722,12 @@ int iscsit_ta_cache_dynamic_acls( return -EINVAL; } + if (a->generate_node_acls == 1 && flag == 0) { + pr_debug("Skipping cache_dynamic_acls=0 when" + " generate_node_acls=1\n"); + return 0; + } + a->cache_dynamic_acls = flag; pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group" " ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ? From a026757ff56365b4aa3875c14f1bd5733e0e8bb2 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Mon, 1 Oct 2012 17:23:22 -0700 Subject: [PATCH 32/44] target: Add target_submit_cmd_map_sgls for SGL fabric memory passthrough This patch adds a new target_submit_cmd_map_sgls() to pass pre-allocated SGL memory using transport_generic_map_mem_to_cmd() logic into the generic target submit I/O codepath. It also adds a target_submit_cmd() wrapper around target_submit_cmd_map_sgls() for existing fabric code that already assumes internal target-core SGL memory allocation. (v2: Rename to target_submit_cmd_map_sgls + drop TARGET_SCF_MAP_MEM flag in favor of non zero sgl_count check) Reported-by: Christoph Hellwig Cc: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 63 ++++++++++++++++++++++++-- include/target/target_core_fabric.h | 3 ++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 221f67f3427c..d96d9aa3a496 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1455,8 +1455,9 @@ int transport_handle_cdb_direct( } EXPORT_SYMBOL(transport_handle_cdb_direct); -/** - * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd +/* + * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized + * se_cmd + use pre-allocated SGL memory. * * @se_cmd: command descriptor to submit * @se_sess: associated se_sess for endpoint @@ -1467,6 +1468,10 @@ EXPORT_SYMBOL(transport_handle_cdb_direct); * @task_addr: SAM task attribute * @data_dir: DMA data direction * @flags: flags for command submission from target_sc_flags_tables + * @sgl: struct scatterlist memory for unidirectional mapping + * @sgl_count: scatterlist count for unidirectional mapping + * @sgl_bidi: struct scatterlist memory for bidirectional READ mapping + * @sgl_bidi_count: scatterlist count for bidirectional READ mapping * * Returns non zero to signal active I/O shutdown failure. All other * setup exceptions will be returned as a SCSI CHECK_CONDITION response, @@ -1474,10 +1479,12 @@ EXPORT_SYMBOL(transport_handle_cdb_direct); * * This may only be called from process context, and also currently * assumes internal allocation of fabric payload buffer by target-core. - **/ -int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, + */ +int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, - u32 data_length, int task_attr, int data_dir, int flags) + u32 data_length, int task_attr, int data_dir, int flags, + struct scatterlist *sgl, u32 sgl_count, + struct scatterlist *sgl_bidi, u32 sgl_bidi_count) { struct se_portal_group *se_tpg; int rc; @@ -1524,7 +1531,21 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, transport_generic_request_failure(se_cmd); return 0; } + /* + * When a non zero sgl_count has been passed perform SGL passthrough + * mapping for pre-allocated fabric memory instead of having target + * core perform an internal SGL allocation.. + */ + if (sgl_count != 0) { + BUG_ON(!sgl); + rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count, + sgl_bidi, sgl_bidi_count); + if (rc != 0) { + transport_generic_request_failure(se_cmd); + return 0; + } + } /* * Check if we need to delay processing because of ALUA * Active/NonOptimized primary access state.. @@ -1534,6 +1555,38 @@ int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, transport_handle_cdb_direct(se_cmd); return 0; } +EXPORT_SYMBOL(target_submit_cmd_map_sgls); + +/* + * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd + * + * @se_cmd: command descriptor to submit + * @se_sess: associated se_sess for endpoint + * @cdb: pointer to SCSI CDB + * @sense: pointer to SCSI sense buffer + * @unpacked_lun: unpacked LUN to reference for struct se_lun + * @data_length: fabric expected data transfer length + * @task_addr: SAM task attribute + * @data_dir: DMA data direction + * @flags: flags for command submission from target_sc_flags_tables + * + * Returns non zero to signal active I/O shutdown failure. All other + * setup exceptions will be returned as a SCSI CHECK_CONDITION response, + * but still return zero here. + * + * This may only be called from process context, and also currently + * assumes internal allocation of fabric payload buffer by target-core. + * + * It also assumes interal target core SGL memory allocation. + */ +int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, + unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, + u32 data_length, int task_attr, int data_dir, int flags) +{ + return target_submit_cmd_map_sgls(se_cmd, se_sess, cdb, sense, + unpacked_lun, data_length, task_attr, data_dir, + flags, NULL, 0, NULL, 0); +} EXPORT_SYMBOL(target_submit_cmd); static void target_complete_tmr_failure(struct work_struct *work) diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 85a5d7a99543..81ddb4ae6c3f 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -100,6 +100,9 @@ void transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *, struct se_session *, u32, int, int, unsigned char *); int transport_lookup_cmd_lun(struct se_cmd *, u32); int target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *); +int target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *, + unsigned char *, unsigned char *, u32, u32, int, int, int, + struct scatterlist *, u32, struct scatterlist *, u32); int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, unsigned char *, u32, u32, int, int, int); int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, From 8f9f44f8957b262de717a48269a5ceca36c2b504 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Mon, 1 Oct 2012 23:29:49 -0700 Subject: [PATCH 33/44] tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls This patch converts tcm_loop to use target_submit_cmd_map_sgls() for I/O submission and mapping of pre-allocated SGL memory from incoming scsi_cmnd -> se_cmd descriptors. This includes removing the original open-coded fabric uses of target core callers to support transport_generic_map_mem_to_cmd() between target_setup_cmd_from_cdb() and transport_handle_cdb_direct() logic. (v2: Use renamed target_submit_cmd_map_sgls) Reported-by: Christoph Hellwig Reviewed-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/loopback/tcm_loop.c | 62 ++++-------------------------- 1 file changed, 8 insertions(+), 54 deletions(-) diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 7a0da1ae0040..2d444b1ccd33 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -166,7 +166,7 @@ static void tcm_loop_submission_work(struct work_struct *work) struct tcm_loop_tpg *tl_tpg; struct scatterlist *sgl_bidi = NULL; u32 sgl_bidi_count = 0; - int ret; + int rc; tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; @@ -187,12 +187,6 @@ static void tcm_loop_submission_work(struct work_struct *work) set_host_byte(sc, DID_ERROR); goto out_done; } - - transport_init_se_cmd(se_cmd, tl_tpg->tl_se_tpg.se_tpg_tfo, - tl_nexus->se_sess, - scsi_bufflen(sc), sc->sc_data_direction, - tcm_loop_sam_attr(sc), &tl_cmd->tl_sense_buf[0]); - if (scsi_bidi_cmnd(sc)) { struct scsi_data_buffer *sdb = scsi_in(sc); @@ -201,56 +195,16 @@ static void tcm_loop_submission_work(struct work_struct *work) se_cmd->se_cmd_flags |= SCF_BIDI; } - - if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) { - kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); + rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd, + &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun, + scsi_bufflen(sc), tcm_loop_sam_attr(sc), + sc->sc_data_direction, 0, + scsi_sglist(sc), scsi_sg_count(sc), + sgl_bidi, sgl_bidi_count); + if (rc < 0) { set_host_byte(sc, DID_NO_CONNECT); goto out_done; } - - /* - * Because some userspace code via scsi-generic do not memset their - * associated read buffers, go ahead and do that here for type - * non-data CDBs. Also note that this is currently guaranteed to be a - * single SGL for this case by target core in - * target_setup_cmd_from_cdb() -> transport_generic_cmd_sequencer(). - */ - if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && - se_cmd->data_direction == DMA_FROM_DEVICE) { - struct scatterlist *sg = scsi_sglist(sc); - unsigned char *buf = kmap(sg_page(sg)) + sg->offset; - - if (buf != NULL) { - memset(buf, 0, sg->length); - kunmap(sg_page(sg)); - } - } - - ret = target_setup_cmd_from_cdb(se_cmd, sc->cmnd); - if (ret == -ENOMEM) { - transport_send_check_condition_and_sense(se_cmd, - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } else if (ret < 0) { - if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) - tcm_loop_queue_status(se_cmd); - else - transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } - - ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), - scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); - if (ret) { - transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } - transport_handle_cdb_direct(se_cmd); return; out_done: From 944981c7e106af2aa004847e9177497856630980 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Tue, 2 Oct 2012 14:00:33 -0700 Subject: [PATCH 34/44] target: Add control CDB READ payload zero work-around This patch carries forward a work-around from tcm_loop to target core code to explicitly clear control CDB READ paylods in order to avoid bugs in scsi-generic user-space code for INQUIRY that do not explicitly zero CDB payload memory. (v2: Drop TARGET_SCF_MAP_CLEAR_MEM, and perform the explicit zero of READ memory for all target_submit_cmd_map_sgls users) Cc: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index d96d9aa3a496..c33baff86aa6 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1539,6 +1539,27 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess if (sgl_count != 0) { BUG_ON(!sgl); + /* + * A work-around for tcm_loop as some userspace code via + * scsi-generic do not memset their associated read buffers, + * so go ahead and do that here for type non-data CDBs. Also + * note that this is currently guaranteed to be a single SGL + * for this case by target core in target_setup_cmd_from_cdb() + * -> transport_generic_cmd_sequencer(). + */ + if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && + se_cmd->data_direction == DMA_FROM_DEVICE) { + unsigned char *buf = NULL; + + if (sgl) + buf = kmap(sg_page(sgl)) + sgl->offset; + + if (buf) { + memset(buf, 0, sgl->length); + kunmap(sg_page(sgl)); + } + } + rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count, sgl_bidi, sgl_bidi_count); if (rc != 0) { From 9f0abc1554cfedf2f2391f6ee54ae319441cd1b9 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Mon, 1 Oct 2012 18:40:55 -0700 Subject: [PATCH 35/44] tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls This patch converts tcm_vhost to use target_submit_cmd_map_sgls() for I/O submission and mapping of pre-allocated SGL memory from incoming virtio-scsi SGL memory -> se_cmd descriptors. This includes removing the original open-coded fabric uses of target core callers to support transport_generic_map_mem_to_cmd() between target_setup_cmd_from_cdb() and transport_handle_cdb_direct() logic. It also includes adding a handful of new tcm_vhost_cmnd member + assignments in vhost_scsi_allocate_cmd() used from cmwq process context I/O submission within tcm_vhost_submission_work() (v2: Use renamed target_submit_cmd_map_sgls) Reported-by: Christoph Hellwig Cc: Christoph Hellwig Acked-by: Michael S. Tsirkin Cc: Paolo Bonzini Cc: Stefan Hajnoczi Signed-off-by: Nicholas Bellinger --- drivers/vhost/tcm_vhost.c | 66 ++++++++------------------------------- drivers/vhost/tcm_vhost.h | 8 +++++ 2 files changed, 21 insertions(+), 53 deletions(-) diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index 89dc99baca80..aa31692064dd 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -415,10 +415,7 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( { struct tcm_vhost_cmd *tv_cmd; struct tcm_vhost_nexus *tv_nexus; - struct se_portal_group *se_tpg = &tv_tpg->se_tpg; struct se_session *se_sess; - struct se_cmd *se_cmd; - int sam_task_attr; tv_nexus = tv_tpg->tpg_nexus; if (!tv_nexus) { @@ -434,23 +431,11 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( } INIT_LIST_HEAD(&tv_cmd->tvc_completion_list); tv_cmd->tvc_tag = v_req->tag; + tv_cmd->tvc_task_attr = v_req->task_attr; + tv_cmd->tvc_exp_data_len = exp_data_len; + tv_cmd->tvc_data_direction = data_direction; + tv_cmd->tvc_nexus = tv_nexus; - se_cmd = &tv_cmd->tvc_se_cmd; - /* - * Locate the SAM Task Attr from virtio_scsi_cmd_req - */ - sam_task_attr = v_req->task_attr; - /* - * Initialize struct se_cmd descriptor from TCM infrastructure - */ - transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len, - data_direction, sam_task_attr, - &tv_cmd->tvc_sense_buf[0]); - -#if 0 /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */ - if (bidi) - se_cmd->se_cmd_flags |= SCF_BIDI; -#endif return tv_cmd; } @@ -549,37 +534,10 @@ static void tcm_vhost_submission_work(struct work_struct *work) { struct tcm_vhost_cmd *tv_cmd = container_of(work, struct tcm_vhost_cmd, work); + struct tcm_vhost_nexus *tv_nexus; struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL; int rc, sg_no_bidi = 0; - /* - * Locate the struct se_lun pointer based on v_req->lun, and - * attach it to struct se_cmd - */ - rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun); - if (rc < 0) { - pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun); - transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd, - tv_cmd->tvc_se_cmd.scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } - - rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb); - if (rc == -ENOMEM) { - transport_send_check_condition_and_sense(se_cmd, - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } else if (rc < 0) { - if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) - tcm_vhost_queue_status(se_cmd); - else - transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); - transport_generic_free_cmd(se_cmd, 0); - return; - } if (tv_cmd->tvc_sgl_count) { sg_ptr = tv_cmd->tvc_sgl; @@ -597,17 +555,19 @@ static void tcm_vhost_submission_work(struct work_struct *work) } else { sg_ptr = NULL; } + tv_nexus = tv_cmd->tvc_nexus; - rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr, - tv_cmd->tvc_sgl_count, sg_bidi_ptr, - sg_no_bidi); + rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess, + tv_cmd->tvc_cdb, &tv_cmd->tvc_sense_buf[0], + tv_cmd->tvc_lun, tv_cmd->tvc_exp_data_len, + tv_cmd->tvc_task_attr, tv_cmd->tvc_data_direction, + 0, sg_ptr, tv_cmd->tvc_sgl_count, + sg_bidi_ptr, sg_no_bidi); if (rc < 0) { transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); + TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); transport_generic_free_cmd(se_cmd, 0); - return; } - transport_handle_cdb_direct(se_cmd); } static void vhost_scsi_handle_vq(struct vhost_scsi *vs) diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h index d9e93557d669..7e87c63ecbcd 100644 --- a/drivers/vhost/tcm_vhost.h +++ b/drivers/vhost/tcm_vhost.h @@ -5,6 +5,12 @@ struct tcm_vhost_cmd { /* Descriptor from vhost_get_vq_desc() for virt_queue segment */ int tvc_vq_desc; + /* virtio-scsi initiator task attribute */ + int tvc_task_attr; + /* virtio-scsi initiator data direction */ + enum dma_data_direction tvc_data_direction; + /* Expected data transfer length from virtio-scsi header */ + u32 tvc_exp_data_len; /* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */ u64 tvc_tag; /* The number of scatterlists associated with this cmd */ @@ -17,6 +23,8 @@ struct tcm_vhost_cmd { struct virtio_scsi_cmd_resp __user *tvc_resp; /* Pointer to vhost_scsi for our device */ struct vhost_scsi *tvc_vhost; + /* Pointer to vhost nexus memory */ + struct tcm_vhost_nexus *tvc_nexus; /* The TCM I/O descriptor that is accessed via container_of() */ struct se_cmd tvc_se_cmd; /* work item used for cmwq dispatch to tcm_vhost_submission_work() */ From 8ecf595bc2bb468f567eaa4ea5ffbf5d2c871b94 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Oct 2012 11:27:39 +0300 Subject: [PATCH 36/44] target/usb-gadget: remove duplicate initialization We set bAlternateSetting to zero twice. I kept the second one (.bAlternateSetting = USB_G_ALT_INT_BBB) because that's more descriptive. Signed-off-by: Dan Carpenter Signed-off-by: Nicholas Bellinger --- drivers/usb/gadget/tcm_usb_gadget.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 575c82437e4a..0f75f23ef661 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1959,7 +1959,6 @@ static void usbg_deregister_configfs(void) static struct usb_interface_descriptor bot_intf_desc = { .bLength = sizeof(bot_intf_desc), .bDescriptorType = USB_DT_INTERFACE, - .bAlternateSetting = 0, .bNumEndpoints = 2, .bAlternateSetting = USB_G_ALT_INT_BBB, .bInterfaceClass = USB_CLASS_MASS_STORAGE, From 232ebe34e1a7827c9ddd4f31e95e21ba498ae52c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Oct 2012 11:27:14 +0300 Subject: [PATCH 37/44] target/usb-gadget: strlen() doesn't count the terminator We need to take the terminator into consideration here or the last character gets silently truncated away later. Signed-off-by: Dan Carpenter Signed-off-by: Nicholas Bellinger --- drivers/usb/gadget/tcm_usb_gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 0f75f23ef661..5662d6e927c0 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1815,7 +1815,7 @@ static ssize_t tcm_usbg_tpg_store_nexus( ret = tcm_usbg_drop_nexus(tpg); return (!ret) ? count : ret; } - if (strlen(page) > USBG_NAMELEN) { + if (strlen(page) >= USBG_NAMELEN) { pr_err("Emulated NAA Sas Address: %s, exceeds" " max: %d\n", page, USBG_NAMELEN); return -EINVAL; From d7ca663c775bd1aafb718bdd6c208b49a9d53f50 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Oct 2012 11:22:48 +0300 Subject: [PATCH 38/44] target/iscsi: precedence bug in iscsit_set_dataout_sequence_values() Clang warns about this bug: drivers/target/iscsi/iscsi_target_erl0.c:52:45: warning: operator '?:' has lower precedence than '+'; '+' will be evaluated first [-Wparentheses] Signed-off-by: Dan Carpenter Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_erl0.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 1a02016ecdab..2067efd2b7f7 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c @@ -48,9 +48,9 @@ void iscsit_set_dataout_sequence_values( if (cmd->unsolicited_data) { cmd->seq_start_offset = cmd->write_data_done; cmd->seq_end_offset = (cmd->write_data_done + - (cmd->se_cmd.data_length > - conn->sess->sess_ops->FirstBurstLength) ? - conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length); + ((cmd->se_cmd.data_length > + conn->sess->sess_ops->FirstBurstLength) ? + conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length)); return; } From fceb5bc7be7d9a98459fb1e44e1b1bedef094b2c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 Sep 2012 08:00:36 -0400 Subject: [PATCH 39/44] iscsit: mark various functions static This patch marks a number of functions static to appease sparse static checking. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target.c | 2 +- drivers/target/iscsi/iscsi_target.h | 5 +++++ drivers/target/iscsi/iscsi_target_configfs.c | 10 +++++----- drivers/target/iscsi/iscsi_target_erl0.c | 8 ++++---- drivers/target/iscsi/iscsi_target_erl2.c | 4 +--- drivers/target/iscsi/iscsi_target_login.c | 4 ---- drivers/target/iscsi/iscsi_target_nego.c | 2 +- drivers/target/iscsi/iscsi_target_tmr.c | 6 +++--- drivers/target/iscsi/iscsi_target_tq.c | 6 +++--- drivers/target/iscsi/iscsi_target_tq.h | 1 - 10 files changed, 23 insertions(+), 25 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 632a5aeb14d9..cca6d1384a1f 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -427,7 +427,7 @@ int iscsit_reset_np_thread( return 0; } -int iscsit_del_np_comm(struct iscsi_np *np) +static int iscsit_del_np_comm(struct iscsi_np *np) { if (np->np_socket) sock_release(np->np_socket); diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index 12abb4c9e34e..f1e4f3155bac 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h @@ -38,4 +38,9 @@ extern struct kmem_cache *lio_cmd_cache; extern struct kmem_cache *lio_qr_cache; extern struct kmem_cache *lio_r2t_cache; +extern struct idr sess_idr; +extern struct mutex auth_id_lock; +extern spinlock_t sess_idr_lock; + + #endif /*** ISCSI_TARGET_H ***/ diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index f491f969ab95..8c9955f51c5d 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -135,7 +135,7 @@ static struct configfs_attribute *lio_target_portal_attrs[] = { #define MAX_PORTAL_LEN 256 -struct se_tpg_np *lio_target_call_addnptotpg( +static struct se_tpg_np *lio_target_call_addnptotpg( struct se_portal_group *se_tpg, struct config_group *group, const char *name) @@ -1170,7 +1170,7 @@ static struct configfs_attribute *lio_target_tpg_attrs[] = { /* Start items for lio_target_tiqn_cit */ -struct se_portal_group *lio_target_tiqn_addtpg( +static struct se_portal_group *lio_target_tiqn_addtpg( struct se_wwn *wwn, struct config_group *group, const char *name) @@ -1220,7 +1220,7 @@ out: return NULL; } -void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg) +static void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg) { struct iscsi_portal_group *tpg; struct iscsi_tiqn *tiqn; @@ -1252,7 +1252,7 @@ static struct configfs_attribute *lio_target_wwn_attrs[] = { NULL, }; -struct se_wwn *lio_target_call_coreaddtiqn( +static struct se_wwn *lio_target_call_coreaddtiqn( struct target_fabric_configfs *tf, struct config_group *group, const char *name) @@ -1300,7 +1300,7 @@ struct se_wwn *lio_target_call_coreaddtiqn( return &tiqn->tiqn_wwn; } -void lio_target_call_coredeltiqn( +static void lio_target_call_coredeltiqn( struct se_wwn *wwn) { struct iscsi_tiqn *tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn); diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 2067efd2b7f7..0c37533ccbb5 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c @@ -685,7 +685,7 @@ recover: * Called from iscsit_handle_data_out() before DataOUT Payload is received * and CRC computed. */ -extern int iscsit_check_pre_dataout( +int iscsit_check_pre_dataout( struct iscsi_cmd *cmd, unsigned char *buf) { @@ -789,7 +789,7 @@ static void iscsit_handle_time2retain_timeout(unsigned long data) target_put_session(sess->se_sess); } -extern void iscsit_start_time2retain_handler(struct iscsi_session *sess) +void iscsit_start_time2retain_handler(struct iscsi_session *sess) { int tpg_active; /* @@ -822,7 +822,7 @@ extern void iscsit_start_time2retain_handler(struct iscsi_session *sess) /* * Called with spin_lock_bh(&struct se_portal_group->session_lock) held */ -extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess) +int iscsit_stop_time2retain_timer(struct iscsi_session *sess) { struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess); struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; @@ -926,7 +926,7 @@ static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn) } } -extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) +void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) { spin_lock_bh(&conn->state_lock); if (atomic_read(&conn->connection_exit)) { diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index 667c19cc3b28..660694544128 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c @@ -193,15 +193,13 @@ int iscsit_remove_active_connection_recovery_entry( return 0; } -int iscsit_remove_inactive_connection_recovery_entry( +static void iscsit_remove_inactive_connection_recovery_entry( struct iscsi_conn_recovery *cr, struct iscsi_session *sess) { spin_lock(&sess->cr_i_lock); list_del(&cr->cr_list); spin_unlock(&sess->cr_i_lock); - - return 0; } /* diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 6aba4395e8d8..1e5d05011915 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -39,10 +39,6 @@ #include "iscsi_target.h" #include "iscsi_target_parameters.h" -extern struct idr sess_idr; -extern struct mutex auth_id_lock; -extern spinlock_t sess_idr_lock; - static int iscsi_login_init_conn(struct iscsi_conn *conn) { INIT_LIST_HEAD(&conn->conn_list); diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index d08373fa8caf..42b1c50d296a 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c @@ -44,7 +44,7 @@ void convert_null_to_semi(char *buf, int len) buf[i] = ';'; } -int strlen_semi(char *buf) +static int strlen_semi(char *buf) { int i = 0; diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index 05d2e6445ade..f15462bfafd2 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c @@ -462,7 +462,7 @@ static int iscsit_task_reassign_complete( * Right now the only one that its really needed for is * connection recovery releated TASK_REASSIGN. */ -extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn) +int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn) { struct iscsi_tmr_req *tmr_req = cmd->tmr_req; struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req; @@ -477,7 +477,7 @@ extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *con /* * Nothing to do here, but leave it for good measure. :-) */ -int iscsit_task_reassign_prepare_read( +static int iscsit_task_reassign_prepare_read( struct iscsi_tmr_req *tmr_req, struct iscsi_conn *conn) { @@ -552,7 +552,7 @@ static void iscsit_task_reassign_prepare_unsolicited_dataout( } } -int iscsit_task_reassign_prepare_write( +static int iscsit_task_reassign_prepare_write( struct iscsi_tmr_req *tmr_req, struct iscsi_conn *conn) { diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c index 977e1cf90e83..9d881a000e42 100644 --- a/drivers/target/iscsi/iscsi_target_tq.c +++ b/drivers/target/iscsi/iscsi_target_tq.c @@ -40,7 +40,7 @@ static void iscsi_add_ts_to_active_list(struct iscsi_thread_set *ts) spin_unlock(&active_ts_lock); } -extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) +static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts) { spin_lock(&inactive_ts_lock); list_add_tail(&ts->ts_list, &inactive_ts_list); @@ -76,7 +76,7 @@ static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void) return ts; } -extern int iscsi_allocate_thread_sets(u32 thread_pair_count) +int iscsi_allocate_thread_sets(u32 thread_pair_count) { int allocated_thread_pair_count = 0, i, thread_id; struct iscsi_thread_set *ts = NULL; @@ -140,7 +140,7 @@ extern int iscsi_allocate_thread_sets(u32 thread_pair_count) return allocated_thread_pair_count; } -extern void iscsi_deallocate_thread_sets(void) +void iscsi_deallocate_thread_sets(void) { u32 released_count = 0; struct iscsi_thread_set *ts = NULL; diff --git a/drivers/target/iscsi/iscsi_target_tq.h b/drivers/target/iscsi/iscsi_target_tq.h index 26e6a95ec203..547d11831282 100644 --- a/drivers/target/iscsi/iscsi_target_tq.h +++ b/drivers/target/iscsi/iscsi_target_tq.h @@ -5,7 +5,6 @@ * Defines for thread sets. */ extern int iscsi_thread_set_force_reinstatement(struct iscsi_conn *); -extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *); extern int iscsi_allocate_thread_sets(u32); extern void iscsi_deallocate_thread_sets(void); extern void iscsi_activate_thread_set(struct iscsi_conn *, struct iscsi_thread_set *); From 904753da183566c71211d23c169a80184648c121 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 Sep 2012 08:00:37 -0400 Subject: [PATCH 40/44] iscsit: remove incorrect unlock in iscsit_build_sendtargets_resp Fix a potential multiple spin-unlock -> deadlock scenario during the overflow check within iscsit_build_sendtargets_resp() as found by sparse static checking. Signed-off-by: Christoph Hellwig Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index cca6d1384a1f..29f3b2414596 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3274,7 +3274,6 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) len += 1; if ((len + payload_len) > buffer_len) { - spin_unlock(&tiqn->tiqn_tpg_lock); end_of_buf = 1; goto eob; } From cea0b4ceec5d09330fd80c0185532a502db9c2b7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 Sep 2012 08:00:38 -0400 Subject: [PATCH 41/44] iscsit: add missing endianess conversion in iscsit_check_inaddr_any Sparse noticed that INADDR_ANY needs to be converted to big endian before it can be stored in struct sockaddr_in.s_addr. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 29f3b2414596..2e7bf7a51e7f 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3239,7 +3239,7 @@ static bool iscsit_check_inaddr_any(struct iscsi_np *np) struct sockaddr_in * sock_in = (struct sockaddr_in *)&np->np_sockaddr; - if (sock_in->sin_addr.s_addr == INADDR_ANY) + if (sock_in->sin_addr.s_addr == htonl(INADDR_ANY)) ret = true; } From 66c7db687631247b7a3493322b9aedeef3c6c7b5 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 Sep 2012 08:00:39 -0400 Subject: [PATCH 42/44] iscsit: use the itt_t abstract type Use the special itt_t type defined by the iscsi headers and the initiator to make sure it's an opaque value. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target.c | 36 ++++++++------------ drivers/target/iscsi/iscsi_target_configfs.c | 3 +- drivers/target/iscsi/iscsi_target_core.h | 8 ++--- drivers/target/iscsi/iscsi_target_erl1.c | 4 +-- drivers/target/iscsi/iscsi_target_erl1.h | 4 +-- drivers/target/iscsi/iscsi_target_login.c | 2 +- drivers/target/iscsi/iscsi_target_nego.c | 6 ++-- drivers/target/iscsi/iscsi_target_tmr.c | 4 +-- drivers/target/iscsi/iscsi_target_util.c | 10 +++--- drivers/target/iscsi/iscsi_target_util.h | 6 ++-- 10 files changed, 37 insertions(+), 46 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 2e7bf7a51e7f..1c843b51f261 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -785,7 +785,6 @@ static int iscsit_handle_scsi_cmd( hdr = (struct iscsi_scsi_req *) buf; payload_length = ntoh24(hdr->dlength); - hdr->itt = be32_to_cpu(hdr->itt); hdr->data_length = be32_to_cpu(hdr->data_length); hdr->cmdsn = be32_to_cpu(hdr->cmdsn); hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); @@ -1194,7 +1193,6 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) hdr = (struct iscsi_data *) buf; payload_length = ntoh24(hdr->dlength); - hdr->itt = be32_to_cpu(hdr->itt); hdr->ttt = be32_to_cpu(hdr->ttt); hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); hdr->datasn = be32_to_cpu(hdr->datasn); @@ -1425,12 +1423,11 @@ static int iscsit_handle_nop_out( hdr = (struct iscsi_nopout *) buf; payload_length = ntoh24(hdr->dlength); - hdr->itt = be32_to_cpu(hdr->itt); hdr->ttt = be32_to_cpu(hdr->ttt); hdr->cmdsn = be32_to_cpu(hdr->cmdsn); hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - if ((hdr->itt == 0xFFFFFFFF) && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { + if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { pr_err("NOPOUT ITT is reserved, but Immediate Bit is" " not set, protocol error.\n"); return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1, @@ -1448,7 +1445,7 @@ static int iscsit_handle_nop_out( pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%09x," " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n", - (hdr->itt == 0xFFFFFFFF) ? "Response" : "Request", + hdr->itt == RESERVED_ITT ? "Response" : "Request", hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn, payload_length); /* @@ -1556,7 +1553,7 @@ static int iscsit_handle_nop_out( pr_debug("Ping Data: \"%s\"\n", ping_data); } - if (hdr->itt != 0xFFFFFFFF) { + if (hdr->itt != RESERVED_ITT) { if (!cmd) { pr_err("Checking CmdSN for NOPOUT," " but cmd is NULL!\n"); @@ -1639,8 +1636,6 @@ static int iscsit_handle_task_mgt_cmd( u8 function; hdr = (struct iscsi_tm *) buf; - hdr->itt = be32_to_cpu(hdr->itt); - hdr->rtt = be32_to_cpu(hdr->rtt); hdr->cmdsn = be32_to_cpu(hdr->cmdsn); hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); hdr->refcmdsn = be32_to_cpu(hdr->refcmdsn); @@ -1655,9 +1650,9 @@ static int iscsit_handle_task_mgt_cmd( if ((function != ISCSI_TM_FUNC_ABORT_TASK) && ((function != ISCSI_TM_FUNC_TASK_REASSIGN) && - (hdr->rtt != ISCSI_RESERVED_TAG))) { + hdr->rtt != RESERVED_ITT)) { pr_err("RefTaskTag should be set to 0xFFFFFFFF.\n"); - hdr->rtt = ISCSI_RESERVED_TAG; + hdr->rtt = RESERVED_ITT; } if ((function == ISCSI_TM_FUNC_TASK_REASSIGN) && @@ -1869,7 +1864,6 @@ static int iscsit_handle_text_cmd( hdr = (struct iscsi_text *) buf; payload_length = ntoh24(hdr->dlength); - hdr->itt = be32_to_cpu(hdr->itt); hdr->ttt = be32_to_cpu(hdr->ttt); hdr->cmdsn = be32_to_cpu(hdr->cmdsn); hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); @@ -2131,7 +2125,6 @@ static int iscsit_handle_logout_cmd( hdr = (struct iscsi_logout *) buf; reason_code = (hdr->flags & 0x7f); - hdr->itt = be32_to_cpu(hdr->itt); hdr->cid = be16_to_cpu(hdr->cid); hdr->cmdsn = be32_to_cpu(hdr->cmdsn); hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); @@ -2219,7 +2212,6 @@ static int iscsit_handle_snack( hdr = (struct iscsi_snack *) buf; hdr->flags &= ~ISCSI_FLAG_CMD_FINAL; - hdr->itt = be32_to_cpu(hdr->itt); hdr->ttt = be32_to_cpu(hdr->ttt); hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); hdr->begrun = be32_to_cpu(hdr->begrun); @@ -2414,7 +2406,7 @@ static int iscsit_send_conn_drop_async_message( hdr = (struct iscsi_async *) cmd->pdu; hdr->opcode = ISCSI_OP_ASYNC_EVENT; hdr->flags = ISCSI_FLAG_CMD_FINAL; - cmd->init_task_tag = 0xFFFFFFFF; + cmd->init_task_tag = RESERVED_ITT; cmd->targ_xfer_tag = 0xFFFFFFFF; put_unaligned_be64(0xFFFFFFFFFFFFFFFFULL, &hdr->rsvd4[0]); cmd->stat_sn = conn->stat_sn++; @@ -2536,7 +2528,7 @@ static int iscsit_send_data_in( else put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun); - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; hdr->ttt = (hdr->flags & ISCSI_FLAG_DATA_ACK) ? cpu_to_be32(cmd->targ_xfer_tag) : 0xFFFFFFFF; @@ -2708,7 +2700,7 @@ static int iscsit_send_logout_response( hdr->opcode = ISCSI_OP_LOGOUT_RSP; hdr->flags |= ISCSI_FLAG_CMD_FINAL; hdr->response = cmd->logout_response; - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); @@ -2759,7 +2751,7 @@ static int iscsit_send_unsolicited_nopin( memset(hdr, 0, ISCSI_HDR_LEN); hdr->opcode = ISCSI_OP_NOOP_IN; hdr->flags |= ISCSI_FLAG_CMD_FINAL; - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); cmd->stat_sn = conn->stat_sn; hdr->statsn = cpu_to_be32(cmd->stat_sn); @@ -2816,7 +2808,7 @@ static int iscsit_send_nopin_response( hdr->flags |= ISCSI_FLAG_CMD_FINAL; hton24(hdr->dlength, cmd->buf_ptr_size); put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun); - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); @@ -2906,7 +2898,7 @@ static int iscsit_send_r2t( hdr->flags |= ISCSI_FLAG_CMD_FINAL; int_to_scsilun(cmd->se_cmd.orig_fe_lun, (struct scsi_lun *)&hdr->lun); - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; spin_lock_bh(&conn->sess->ttt_lock); r2t->targ_xfer_tag = conn->sess->targ_xfer_tag++; if (r2t->targ_xfer_tag == 0xFFFFFFFF) @@ -3074,7 +3066,7 @@ static int iscsit_send_status( } hdr->response = cmd->iscsi_response; hdr->cmd_status = cmd->se_cmd.scsi_status; - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; hdr->statsn = cpu_to_be32(cmd->stat_sn); iscsit_increment_maxcmdsn(cmd, conn->sess); @@ -3187,7 +3179,7 @@ static int iscsit_send_task_mgt_rsp( hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; hdr->flags = ISCSI_FLAG_CMD_FINAL; hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); @@ -3360,7 +3352,7 @@ static int iscsit_send_text_rsp( hdr->opcode = ISCSI_OP_TEXT_RSP; hdr->flags |= ISCSI_FLAG_CMD_FINAL; hton24(hdr->dlength, text_length); - hdr->itt = cpu_to_be32(cmd->init_task_tag); + hdr->itt = cmd->init_task_tag; hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 8c9955f51c5d..ff6fd4fb624d 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1475,7 +1475,8 @@ static u32 iscsi_get_task_tag(struct se_cmd *se_cmd) { struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); - return cmd->init_task_tag; + /* only used for printks or comparism with ->ref_task_tag */ + return (__force u32)cmd->init_task_tag; } static int iscsi_get_cmd_state(struct se_cmd *se_cmd) diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index e6a830545c89..226fe62d4e61 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -361,7 +361,7 @@ struct iscsi_cmd { /* Command flags */ enum cmd_flags_table cmd_flags; /* Initiator Task Tag assigned from Initiator */ - u32 init_task_tag; + itt_t init_task_tag; /* Target Transfer Tag assigned from Target */ u32 targ_xfer_tag; /* CmdSN assigned from Initiator */ @@ -506,7 +506,7 @@ struct iscsi_conn { u32 auth_id; u32 conn_flags; /* Used for iscsi_tx_login_rsp() */ - u32 login_itt; + itt_t login_itt; u32 exp_statsn; /* Per connection status sequence number */ u32 stat_sn; @@ -599,7 +599,7 @@ struct iscsi_session { /* state session is currently in */ u32 session_state; /* session wide counter: initiator assigned task tag */ - u32 init_task_tag; + itt_t init_task_tag; /* session wide counter: target assigned task tag */ u32 targ_xfer_tag; u32 cmdsn_window; @@ -665,7 +665,7 @@ struct iscsi_login { u8 version_max; char isid[6]; u32 cmd_sn; - u32 init_task_tag; + itt_t init_task_tag; u32 initial_exp_statsn; u32 rsp_length; u16 cid; diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index 3df8a2cef86f..21f29d91a8cb 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c @@ -466,7 +466,7 @@ static int iscsit_handle_recovery_datain( int iscsit_handle_recovery_datain_or_r2t( struct iscsi_conn *conn, unsigned char *buf, - u32 init_task_tag, + itt_t init_task_tag, u32 targ_xfer_tag, u32 begrun, u32 runlength) @@ -498,7 +498,7 @@ int iscsit_handle_recovery_datain_or_r2t( /* #warning FIXME: Status SNACK needs to be dependent on OPCODE!!! */ int iscsit_handle_status_snack( struct iscsi_conn *conn, - u32 init_task_tag, + itt_t init_task_tag, u32 targ_xfer_tag, u32 begrun, u32 runlength) diff --git a/drivers/target/iscsi/iscsi_target_erl1.h b/drivers/target/iscsi/iscsi_target_erl1.h index 85e67e29de6b..2a3ebf118a34 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.h +++ b/drivers/target/iscsi/iscsi_target_erl1.h @@ -7,8 +7,8 @@ extern int iscsit_create_recovery_datain_values_datasequenceinorder_yes( extern int iscsit_create_recovery_datain_values_datasequenceinorder_no( struct iscsi_cmd *, struct iscsi_datain_req *); extern int iscsit_handle_recovery_datain_or_r2t(struct iscsi_conn *, unsigned char *, - u32, u32, u32, u32); -extern int iscsit_handle_status_snack(struct iscsi_conn *, u32, u32, + itt_t, u32, u32, u32); +extern int iscsit_handle_status_snack(struct iscsi_conn *, itt_t, u32, u32, u32); extern int iscsit_handle_data_ack(struct iscsi_conn *, u32, u32, u32); extern int iscsit_dataout_datapduinorder_no_fbit(struct iscsi_cmd *, struct iscsi_pdu *); diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 1e5d05011915..4c83d7a39bf3 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -953,9 +953,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) pdu = (struct iscsi_login_req *) buffer; pdu->cid = be16_to_cpu(pdu->cid); pdu->tsih = be16_to_cpu(pdu->tsih); - pdu->itt = be32_to_cpu(pdu->itt); pdu->cmdsn = be32_to_cpu(pdu->cmdsn); pdu->exp_statsn = be32_to_cpu(pdu->exp_statsn); + /* * Used by iscsit_tx_login_rsp() for Login Resonses PDUs * when Status-Class != 0. diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 42b1c50d296a..33ed9b5209cd 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c @@ -339,14 +339,14 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log hton24(login_rsp->dlength, login->rsp_length); memcpy(login_rsp->isid, login->isid, 6); login_rsp->tsih = cpu_to_be16(login->tsih); - login_rsp->itt = cpu_to_be32(login->init_task_tag); + login_rsp->itt = login->init_task_tag; login_rsp->statsn = cpu_to_be32(conn->stat_sn++); login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); login_rsp->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x," " ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:" - " %u\n", login_rsp->flags, ntohl(login_rsp->itt), + " %u\n", login_rsp->flags, (__force u32)login_rsp->itt, ntohl(login_rsp->exp_cmdsn), ntohl(login_rsp->max_cmdsn), ntohl(login_rsp->statsn), login->rsp_length); @@ -361,7 +361,6 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log login->rsp_length = 0; login_rsp->tsih = be16_to_cpu(login_rsp->tsih); - login_rsp->itt = be32_to_cpu(login_rsp->itt); login_rsp->statsn = be32_to_cpu(login_rsp->statsn); mutex_lock(&sess->cmdsn_mutex); login_rsp->exp_cmdsn = be32_to_cpu(sess->exp_cmd_sn); @@ -382,7 +381,6 @@ static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_log login_req = (struct iscsi_login_req *) login->req; payload_length = ntoh24(login_req->dlength); login_req->tsih = be16_to_cpu(login_req->tsih); - login_req->itt = be32_to_cpu(login_req->itt); login_req->cid = be16_to_cpu(login_req->cid); login_req->cmdsn = be32_to_cpu(login_req->cmdsn); login_req->exp_statsn = be32_to_cpu(login_req->exp_statsn); diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index f15462bfafd2..925f829a3704 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c @@ -61,7 +61,7 @@ u8 iscsit_tmr_abort_task( return ISCSI_TMF_RSP_REJECTED; } - se_tmr->ref_task_tag = hdr->rtt; + se_tmr->ref_task_tag = (__force u32)hdr->rtt; tmr_req->ref_cmd = ref_cmd; tmr_req->ref_cmd_sn = hdr->refcmdsn; tmr_req->exp_data_sn = hdr->exp_datasn; @@ -171,7 +171,7 @@ u8 iscsit_tmr_task_reassign( return ISCSI_TMF_RSP_REJECTED; } - se_tmr->ref_task_tag = hdr->rtt; + se_tmr->ref_task_tag = (__force u32)hdr->rtt; tmr_req->ref_cmd = ref_cmd; tmr_req->ref_cmd_sn = hdr->refcmdsn; tmr_req->exp_data_sn = hdr->exp_datasn; diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index b42cdeb153df..22bec9e899c0 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -351,7 +351,7 @@ int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf) struct iscsi_cmd *iscsit_find_cmd_from_itt( struct iscsi_conn *conn, - u32 init_task_tag) + itt_t init_task_tag) { struct iscsi_cmd *cmd; @@ -371,7 +371,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt( struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump( struct iscsi_conn *conn, - u32 init_task_tag, + itt_t init_task_tag, u32 length) { struct iscsi_cmd *cmd; @@ -417,7 +417,7 @@ int iscsit_find_cmd_for_recovery( struct iscsi_session *sess, struct iscsi_cmd **cmd_ptr, struct iscsi_conn_recovery **cr_ptr, - u32 init_task_tag) + itt_t init_task_tag) { struct iscsi_cmd *cmd = NULL; struct iscsi_conn_recovery *cr; @@ -855,7 +855,7 @@ static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response) cmd->iscsi_opcode = ISCSI_OP_NOOP_IN; state = (want_response) ? ISTATE_SEND_NOPIN_WANT_RESPONSE : ISTATE_SEND_NOPIN_NO_RESPONSE; - cmd->init_task_tag = 0xFFFFFFFF; + cmd->init_task_tag = RESERVED_ITT; spin_lock_bh(&conn->sess->ttt_lock); cmd->targ_xfer_tag = (want_response) ? conn->sess->targ_xfer_tag++ : 0xFFFFFFFF; @@ -1222,7 +1222,7 @@ int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_deta hdr->opcode = ISCSI_OP_LOGIN_RSP; hdr->status_class = status_class; hdr->status_detail = status_detail; - hdr->itt = cpu_to_be32(conn->login_itt); + hdr->itt = conn->login_itt; iov.iov_base = &iscsi_hdr; iov.iov_len = ISCSI_HDR_LEN; diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index e1c729b8a1c5..09e2f9f563a7 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h @@ -14,12 +14,12 @@ extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *); extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32); int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, u32 cmdsn); extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *); -extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, u32); +extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t); extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *, - u32, u32); + itt_t, u32); extern struct iscsi_cmd *iscsit_find_cmd_from_ttt(struct iscsi_conn *, u32); extern int iscsit_find_cmd_for_recovery(struct iscsi_session *, struct iscsi_cmd **, - struct iscsi_conn_recovery **, u32); + struct iscsi_conn_recovery **, itt_t); extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *); extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); From 50e5c87de4c244662e47b28e499ace885d62248f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 Sep 2012 08:00:40 -0400 Subject: [PATCH 43/44] iscsit: proper endianess conversions Make sure all on the wire types are use as big endian and big endian only so that sparse can verify all the conversions are done right. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target.c | 121 ++++++++++------------ drivers/target/iscsi/iscsi_target_core.h | 1 - drivers/target/iscsi/iscsi_target_erl0.c | 80 +++++++------- drivers/target/iscsi/iscsi_target_erl2.c | 4 +- drivers/target/iscsi/iscsi_target_erl2.h | 2 +- drivers/target/iscsi/iscsi_target_login.c | 14 +-- drivers/target/iscsi/iscsi_target_nego.c | 18 ++-- drivers/target/iscsi/iscsi_target_tmr.c | 12 +-- drivers/target/iscsi/iscsi_target_util.c | 6 +- drivers/target/iscsi/iscsi_target_util.h | 2 +- 10 files changed, 122 insertions(+), 138 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 1c843b51f261..d6ce2182e672 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -785,9 +785,6 @@ static int iscsit_handle_scsi_cmd( hdr = (struct iscsi_scsi_req *) buf; payload_length = ntoh24(hdr->dlength); - hdr->data_length = be32_to_cpu(hdr->data_length); - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); /* FIXME; Add checks for AdditionalHeaderSegment */ @@ -851,7 +848,7 @@ done: buf, conn); } - if ((hdr->data_length == payload_length) && + if ((be32_to_cpu(hdr->data_length )== payload_length) && (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) { pr_err("Expected Data Transfer Length and Length of" " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" @@ -860,7 +857,7 @@ done: buf, conn); } - if (payload_length > hdr->data_length) { + if (payload_length > be32_to_cpu(hdr->data_length)) { pr_err("DataSegmentLength: %u is greater than" " EDTL: %u, protocol error.\n", payload_length, hdr->data_length); @@ -931,8 +928,8 @@ done: spin_unlock_bh(&conn->sess->ttt_lock); } else if (hdr->flags & ISCSI_FLAG_CMD_WRITE) cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); cmd->first_burst_len = payload_length; if (cmd->data_direction == DMA_FROM_DEVICE) { @@ -951,8 +948,9 @@ done: * Initialize struct se_cmd descriptor from target_core_mod infrastructure */ transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, - conn->sess->se_sess, hdr->data_length, cmd->data_direction, - sam_task_attr, cmd->sense_buffer + 2); + conn->sess->se_sess, be32_to_cpu(hdr->data_length), + cmd->data_direction, sam_task_attr, + cmd->sense_buffer + 2); pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, @@ -1027,7 +1025,7 @@ attach_cmd: 1, 0, buf, cmd); } - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); /* * If no Immediate Data is attached, it's OK to return now. @@ -1193,10 +1191,6 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) hdr = (struct iscsi_data *) buf; payload_length = ntoh24(hdr->dlength); - hdr->ttt = be32_to_cpu(hdr->ttt); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - hdr->datasn = be32_to_cpu(hdr->datasn); - hdr->offset = be32_to_cpu(hdr->offset); if (!payload_length) { pr_err("DataOUT payload is ZERO, protocol error.\n"); @@ -1248,7 +1242,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) se_cmd = &cmd->se_cmd; iscsit_mod_dataout_timer(cmd); - if ((hdr->offset + payload_length) > cmd->se_cmd.data_length) { + if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) { pr_err("DataOut Offset: %u, Length %u greater than" " iSCSI Command EDTL %u, protocol error.\n", hdr->offset, payload_length, cmd->se_cmd.data_length); @@ -1331,7 +1325,8 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) rx_size += payload_length; iov = &cmd->iov_data[0]; - iov_ret = iscsit_map_iovec(cmd, iov, hdr->offset, payload_length); + iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset), + payload_length); if (iov_ret < 0) return -1; @@ -1362,7 +1357,8 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) u32 data_crc; data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd, - hdr->offset, payload_length, padding, + be32_to_cpu(hdr->offset), + payload_length, padding, cmd->pad_bytes); if (checksum != data_crc) { @@ -1423,9 +1419,6 @@ static int iscsit_handle_nop_out( hdr = (struct iscsi_nopout *) buf; payload_length = ntoh24(hdr->dlength); - hdr->ttt = be32_to_cpu(hdr->ttt); - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { pr_err("NOPOUT ITT is reserved, but Immediate Bit is" @@ -1455,7 +1448,7 @@ static int iscsit_handle_nop_out( * Either way, make sure we allocate an struct iscsi_cmd, as both * can contain ping data. */ - if (hdr->ttt == 0xFFFFFFFF) { + if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); if (!cmd) return iscsit_add_reject( @@ -1468,12 +1461,12 @@ static int iscsit_handle_nop_out( 1 : 0); conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); cmd->data_direction = DMA_NONE; } - if (payload_length && (hdr->ttt == 0xFFFFFFFF)) { + if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { rx_size = payload_length; ping_data = kzalloc(payload_length + 1, GFP_KERNEL); if (!ping_data) { @@ -1566,7 +1559,7 @@ static int iscsit_handle_nop_out( list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); if (hdr->opcode & ISCSI_OP_IMMEDIATE) { iscsit_add_cmd_to_response_queue(cmd, conn, @@ -1587,11 +1580,11 @@ static int iscsit_handle_nop_out( return 0; } - if (hdr->ttt != 0xFFFFFFFF) { + if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) { /* * This was a response to a unsolicited NOPIN ping. */ - cmd = iscsit_find_cmd_from_ttt(conn, hdr->ttt); + cmd = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt)); if (!cmd) return -1; @@ -1636,10 +1629,6 @@ static int iscsit_handle_task_mgt_cmd( u8 function; hdr = (struct iscsi_tm *) buf; - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - hdr->refcmdsn = be32_to_cpu(hdr->refcmdsn); - hdr->exp_datasn = be32_to_cpu(hdr->exp_datasn); hdr->flags &= ~ISCSI_FLAG_CMD_FINAL; function = hdr->flags; @@ -1664,8 +1653,8 @@ static int iscsit_handle_task_mgt_cmd( buf, conn); } if ((function != ISCSI_TM_FUNC_ABORT_TASK) && - (hdr->refcmdsn != ISCSI_RESERVED_TAG)) - hdr->refcmdsn = ISCSI_RESERVED_TAG; + be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) + hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG); cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); if (!cmd) @@ -1742,8 +1731,8 @@ static int iscsit_handle_task_mgt_cmd( cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); cmd->init_task_tag = hdr->itt; cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); se_tmr = cmd->se_cmd.se_tmr_req; tmr_req = cmd->tmr_req; /* @@ -1827,7 +1816,7 @@ attach: ISCSI_REASON_PROTOCOL_ERROR, 1, 0, buf, cmd); } - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); if (out_of_order_cmdsn || !(hdr->opcode & ISCSI_OP_IMMEDIATE)) return 0; @@ -1864,9 +1853,6 @@ static int iscsit_handle_text_cmd( hdr = (struct iscsi_text *) buf; payload_length = ntoh24(hdr->dlength); - hdr->ttt = be32_to_cpu(hdr->ttt); - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { pr_err("Unable to accept text parameter length: %u" @@ -1983,15 +1969,15 @@ static int iscsit_handle_text_cmd( cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); cmd->data_direction = DMA_NONE; spin_lock_bh(&conn->cmd_lock); list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); spin_unlock_bh(&conn->cmd_lock); - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn); @@ -2125,9 +2111,6 @@ static int iscsit_handle_logout_cmd( hdr = (struct iscsi_logout *) buf; reason_code = (hdr->flags & 0x7f); - hdr->cid = be16_to_cpu(hdr->cid); - hdr->cmdsn = be32_to_cpu(hdr->cmdsn); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); if (tiqn) { spin_lock(&tiqn->logout_stats.lock); @@ -2159,9 +2142,9 @@ static int iscsit_handle_logout_cmd( cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; cmd->targ_xfer_tag = 0xFFFFFFFF; - cmd->cmd_sn = hdr->cmdsn; - cmd->exp_stat_sn = hdr->exp_statsn; - cmd->logout_cid = hdr->cid; + cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); + cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); + cmd->logout_cid = be16_to_cpu(hdr->cid); cmd->logout_reason = reason_code; cmd->data_direction = DMA_NONE; @@ -2171,7 +2154,7 @@ static int iscsit_handle_logout_cmd( */ if ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) || ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) && - (hdr->cid == conn->cid))) + be16_to_cpu(hdr->cid) == conn->cid)) logout_remove = 1; spin_lock_bh(&conn->cmd_lock); @@ -2179,7 +2162,7 @@ static int iscsit_handle_logout_cmd( spin_unlock_bh(&conn->cmd_lock); if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY) - iscsit_ack_from_expstatsn(conn, hdr->exp_statsn); + iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); /* * Immediate commands are executed, well, immediately. @@ -2212,10 +2195,6 @@ static int iscsit_handle_snack( hdr = (struct iscsi_snack *) buf; hdr->flags &= ~ISCSI_FLAG_CMD_FINAL; - hdr->ttt = be32_to_cpu(hdr->ttt); - hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn); - hdr->begrun = be32_to_cpu(hdr->begrun); - hdr->runlength = be32_to_cpu(hdr->runlength); pr_debug("Got ISCSI_INIT_SNACK, ITT: 0x%08x, ExpStatSN:" " 0x%08x, Type: 0x%02x, BegRun: 0x%08x, RunLength: 0x%08x," @@ -2235,13 +2214,18 @@ static int iscsit_handle_snack( switch (hdr->flags & ISCSI_FLAG_SNACK_TYPE_MASK) { case 0: return iscsit_handle_recovery_datain_or_r2t(conn, buf, - hdr->itt, hdr->ttt, hdr->begrun, hdr->runlength); + hdr->itt, + be32_to_cpu(hdr->ttt), + be32_to_cpu(hdr->begrun), + be32_to_cpu(hdr->runlength)); case ISCSI_FLAG_SNACK_TYPE_STATUS: - return iscsit_handle_status_snack(conn, hdr->itt, hdr->ttt, - hdr->begrun, hdr->runlength); + return iscsit_handle_status_snack(conn, hdr->itt, + be32_to_cpu(hdr->ttt), + be32_to_cpu(hdr->begrun), be32_to_cpu(hdr->runlength)); case ISCSI_FLAG_SNACK_TYPE_DATA_ACK: - return iscsit_handle_data_ack(conn, hdr->ttt, hdr->begrun, - hdr->runlength); + return iscsit_handle_data_ack(conn, be32_to_cpu(hdr->ttt), + be32_to_cpu(hdr->begrun), + be32_to_cpu(hdr->runlength)); case ISCSI_FLAG_SNACK_TYPE_RDATA: /* FIXME: Support R-Data SNACK */ pr_err("R-Data SNACK Not Supported.\n"); @@ -2529,11 +2513,16 @@ static int iscsit_send_data_in( put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun); hdr->itt = cmd->init_task_tag; - hdr->ttt = (hdr->flags & ISCSI_FLAG_DATA_ACK) ? - cpu_to_be32(cmd->targ_xfer_tag) : - 0xFFFFFFFF; - hdr->statsn = (set_statsn) ? cpu_to_be32(cmd->stat_sn) : - 0xFFFFFFFF; + + if (hdr->flags & ISCSI_FLAG_DATA_ACK) + hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); + else + hdr->ttt = cpu_to_be32(0xFFFFFFFF); + if (set_statsn) + hdr->statsn = cpu_to_be32(cmd->stat_sn); + else + hdr->statsn = cpu_to_be32(0xFFFFFFFF); + hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->datasn = cpu_to_be32(datain.data_sn); @@ -3088,7 +3077,7 @@ static int iscsit_send_status( cmd->se_cmd.scsi_sense_length += sizeof (__be16); padding = -(cmd->se_cmd.scsi_sense_length) & 3; - hton24(hdr->dlength, cmd->se_cmd.scsi_sense_length); + hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length); iov[iov_count].iov_base = cmd->sense_buffer; iov[iov_count++].iov_len = (cmd->se_cmd.scsi_sense_length + padding); @@ -3418,7 +3407,7 @@ static int iscsit_send_reject( hdr->opcode = ISCSI_OP_REJECT; hdr->flags |= ISCSI_FLAG_CMD_FINAL; hton24(hdr->dlength, ISCSI_HDR_LEN); - hdr->ffffffff = 0xffffffff; + hdr->ffffffff = cpu_to_be32(0xffffffff); cmd->stat_sn = conn->stat_sn++; hdr->statsn = cpu_to_be32(cmd->stat_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 226fe62d4e61..ff3f482968c8 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -479,7 +479,6 @@ struct iscsi_cmd { struct iscsi_tmr_req { bool task_reassign:1; - u32 ref_cmd_sn; u32 exp_data_sn; struct iscsi_cmd *ref_cmd; struct iscsi_conn_recovery *conn_recovery; diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 0c37533ccbb5..8aacf611b86d 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c @@ -95,14 +95,15 @@ static int iscsit_dataout_within_command_recovery_check( */ if (conn->sess->sess_ops->DataSequenceInOrder) { if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) && - (cmd->write_data_done != hdr->offset)) + cmd->write_data_done != be32_to_cpu(hdr->offset)) goto dump; cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY; } else { struct iscsi_seq *seq; - seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length); + seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset), + payload_length); if (!seq) return DATAOUT_CANNOT_RECOVER; /* @@ -111,15 +112,15 @@ static int iscsit_dataout_within_command_recovery_check( cmd->seq_ptr = seq; if (conn->sess->sess_ops->DataPDUInOrder) { - if ((seq->status == - DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) && - ((seq->offset != hdr->offset) || - (seq->data_sn != hdr->datasn))) + if (seq->status == + DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY && + (seq->offset != be32_to_cpu(hdr->offset) || + seq->data_sn != be32_to_cpu(hdr->datasn))) goto dump; } else { - if ((seq->status == - DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) && - (seq->data_sn != hdr->datasn)) + if (seq->status == + DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY && + seq->data_sn != be32_to_cpu(hdr->datasn)) goto dump; } @@ -148,12 +149,12 @@ static int iscsit_dataout_check_unsolicited_sequence( u32 payload_length = ntoh24(hdr->dlength); - if ((hdr->offset < cmd->seq_start_offset) || - ((hdr->offset + payload_length) > cmd->seq_end_offset)) { + if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) || + ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) { pr_err("Command ITT: 0x%08x with Offset: %u," " Length: %u outside of Unsolicited Sequence %u:%u while" " DataSequenceInOrder=Yes.\n", cmd->init_task_tag, - hdr->offset, payload_length, cmd->seq_start_offset, + be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset, cmd->seq_end_offset); return DATAOUT_CANNOT_RECOVER; } @@ -236,12 +237,12 @@ static int iscsit_dataout_check_sequence( * fullfilling an Recovery R2T, it's best to just dump the * payload here, instead of erroring out. */ - if ((hdr->offset < cmd->seq_start_offset) || - ((hdr->offset + payload_length) > cmd->seq_end_offset)) { + if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) || + ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) { pr_err("Command ITT: 0x%08x with Offset: %u," " Length: %u outside of Sequence %u:%u while" " DataSequenceInOrder=Yes.\n", cmd->init_task_tag, - hdr->offset, payload_length, cmd->seq_start_offset, + be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset, cmd->seq_end_offset); if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) @@ -251,7 +252,8 @@ static int iscsit_dataout_check_sequence( next_burst_len = (cmd->next_burst_len + payload_length); } else { - seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length); + seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset), + payload_length); if (!seq) return DATAOUT_CANNOT_RECOVER; /* @@ -366,16 +368,16 @@ static int iscsit_dataout_check_datasn( data_sn = seq->data_sn; } - if (hdr->datasn > data_sn) { + if (be32_to_cpu(hdr->datasn) > data_sn) { pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x" " higher than expected 0x%08x.\n", cmd->init_task_tag, - hdr->datasn, data_sn); + be32_to_cpu(hdr->datasn), data_sn); recovery = 1; goto recover; - } else if (hdr->datasn < data_sn) { + } else if (be32_to_cpu(hdr->datasn) < data_sn) { pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x" " lower than expected 0x%08x, discarding payload.\n", - cmd->init_task_tag, hdr->datasn, data_sn); + cmd->init_task_tag, be32_to_cpu(hdr->datasn), data_sn); dump = 1; goto dump; } @@ -415,26 +417,27 @@ static int iscsit_dataout_pre_datapduinorder_yes( * error has occured and fail the connection. */ if (conn->sess->sess_ops->DataSequenceInOrder) { - if (hdr->offset != cmd->write_data_done) { + if (be32_to_cpu(hdr->offset) != cmd->write_data_done) { pr_err("Command ITT: 0x%08x, received offset" " %u different than expected %u.\n", cmd->init_task_tag, - hdr->offset, cmd->write_data_done); + be32_to_cpu(hdr->offset), cmd->write_data_done); recovery = 1; goto recover; } } else { struct iscsi_seq *seq = cmd->seq_ptr; - if (hdr->offset > seq->offset) { + if (be32_to_cpu(hdr->offset) > seq->offset) { pr_err("Command ITT: 0x%08x, received offset" " %u greater than expected %u.\n", cmd->init_task_tag, - hdr->offset, seq->offset); + be32_to_cpu(hdr->offset), seq->offset); recovery = 1; goto recover; - } else if (hdr->offset < seq->offset) { + } else if (be32_to_cpu(hdr->offset) < seq->offset) { pr_err("Command ITT: 0x%08x, received offset" " %u less than expected %u, discarding payload.\n", - cmd->init_task_tag, hdr->offset, seq->offset); + cmd->init_task_tag, be32_to_cpu(hdr->offset), + seq->offset); dump = 1; goto dump; } @@ -453,7 +456,7 @@ dump: return DATAOUT_CANNOT_RECOVER; return (recovery) ? iscsit_recover_dataout_sequence(cmd, - hdr->offset, payload_length) : + be32_to_cpu(hdr->offset), payload_length) : (dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL; } @@ -465,7 +468,8 @@ static int iscsit_dataout_pre_datapduinorder_no( struct iscsi_data *hdr = (struct iscsi_data *) buf; u32 payload_length = ntoh24(hdr->dlength); - pdu = iscsit_get_pdu_holder(cmd, hdr->offset, payload_length); + pdu = iscsit_get_pdu_holder(cmd, be32_to_cpu(hdr->offset), + payload_length); if (!pdu) return DATAOUT_CANNOT_RECOVER; @@ -479,7 +483,7 @@ static int iscsit_dataout_pre_datapduinorder_no( case ISCSI_PDU_RECEIVED_OK: pr_err("Command ITT: 0x%08x received already gotten" " Offset: %u, Length: %u\n", cmd->init_task_tag, - hdr->offset, payload_length); + be32_to_cpu(hdr->offset), payload_length); return iscsit_dump_data_payload(cmd->conn, payload_length, 1); default: return DATAOUT_CANNOT_RECOVER; @@ -553,7 +557,7 @@ static int iscsit_dataout_post_crc_passed( if (cmd->unsolicited_data) { if ((cmd->first_burst_len + payload_length) == conn->sess->sess_ops->FirstBurstLength) { - if (iscsit_dataout_update_r2t(cmd, hdr->offset, + if (iscsit_dataout_update_r2t(cmd, be32_to_cpu(hdr->offset), payload_length) < 0) return DATAOUT_CANNOT_RECOVER; send_r2t = 1; @@ -561,7 +565,8 @@ static int iscsit_dataout_post_crc_passed( if (!conn->sess->sess_ops->DataPDUInOrder) { ret = iscsit_dataout_update_datapduinorder_no(cmd, - hdr->datasn, (hdr->flags & ISCSI_FLAG_CMD_FINAL)); + be32_to_cpu(hdr->datasn), + (hdr->flags & ISCSI_FLAG_CMD_FINAL)); if (ret == DATAOUT_CANNOT_RECOVER) return ret; } @@ -586,7 +591,8 @@ static int iscsit_dataout_post_crc_passed( if (conn->sess->sess_ops->DataSequenceInOrder) { if ((cmd->next_burst_len + payload_length) == conn->sess->sess_ops->MaxBurstLength) { - if (iscsit_dataout_update_r2t(cmd, hdr->offset, + if (iscsit_dataout_update_r2t(cmd, + be32_to_cpu(hdr->offset), payload_length) < 0) return DATAOUT_CANNOT_RECOVER; send_r2t = 1; @@ -594,7 +600,7 @@ static int iscsit_dataout_post_crc_passed( if (!conn->sess->sess_ops->DataPDUInOrder) { ret = iscsit_dataout_update_datapduinorder_no( - cmd, hdr->datasn, + cmd, be32_to_cpu(hdr->datasn), (hdr->flags & ISCSI_FLAG_CMD_FINAL)); if (ret == DATAOUT_CANNOT_RECOVER) return ret; @@ -610,7 +616,8 @@ static int iscsit_dataout_post_crc_passed( if ((seq->next_burst_len + payload_length) == seq->xfer_len) { - if (iscsit_dataout_update_r2t(cmd, hdr->offset, + if (iscsit_dataout_update_r2t(cmd, + be32_to_cpu(hdr->offset), payload_length) < 0) return DATAOUT_CANNOT_RECOVER; send_r2t = 1; @@ -618,7 +625,7 @@ static int iscsit_dataout_post_crc_passed( if (!conn->sess->sess_ops->DataPDUInOrder) { ret = iscsit_dataout_update_datapduinorder_no( - cmd, hdr->datasn, + cmd, be32_to_cpu(hdr->datasn), (hdr->flags & ISCSI_FLAG_CMD_FINAL)); if (ret == DATAOUT_CANNOT_RECOVER) return ret; @@ -678,7 +685,8 @@ static int iscsit_dataout_post_crc_failed( } recover: - return iscsit_recover_dataout_sequence(cmd, hdr->offset, payload_length); + return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset), + payload_length); } /* diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index 660694544128..17d8c20094fd 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c @@ -36,7 +36,7 @@ */ void iscsit_create_conn_recovery_datain_values( struct iscsi_cmd *cmd, - u32 exp_data_sn) + __be32 exp_data_sn) { u32 data_sn = 0; struct iscsi_conn *conn = cmd->conn; @@ -44,7 +44,7 @@ void iscsit_create_conn_recovery_datain_values( cmd->next_burst_len = 0; cmd->read_data_done = 0; - while (exp_data_sn > data_sn) { + while (be32_to_cpu(exp_data_sn) > data_sn) { if ((cmd->next_burst_len + conn->conn_ops->MaxRecvDataSegmentLength) < conn->sess->sess_ops->MaxBurstLength) { diff --git a/drivers/target/iscsi/iscsi_target_erl2.h b/drivers/target/iscsi/iscsi_target_erl2.h index 22f8d24780a6..63f2501f3fe0 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.h +++ b/drivers/target/iscsi/iscsi_target_erl2.h @@ -1,7 +1,7 @@ #ifndef ISCSI_TARGET_ERL2_H #define ISCSI_TARGET_ERL2_H -extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, u32); +extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, __be32); extern void iscsit_create_conn_recovery_dataout_values(struct iscsi_cmd *); extern struct iscsi_conn_recovery *iscsit_get_inactive_connection_recovery_entry( struct iscsi_session *, u16); diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 4c83d7a39bf3..cdc8a10939c3 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -192,10 +192,10 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn) static void iscsi_login_set_conn_values( struct iscsi_session *sess, struct iscsi_conn *conn, - u16 cid) + __be16 cid) { conn->sess = sess; - conn->cid = cid; + conn->cid = be16_to_cpu(cid); /* * Generate a random Status sequence number (statsn) for the new * iSCSI connection. @@ -230,7 +230,7 @@ static int iscsi_login_zero_tsih_s1( iscsi_login_set_conn_values(sess, conn, pdu->cid); sess->init_task_tag = pdu->itt; memcpy(&sess->isid, pdu->isid, 6); - sess->exp_cmd_sn = pdu->cmdsn; + sess->exp_cmd_sn = be32_to_cpu(pdu->cmdsn); INIT_LIST_HEAD(&sess->sess_conn_list); INIT_LIST_HEAD(&sess->sess_ooo_cmdsn_list); INIT_LIST_HEAD(&sess->cr_active_list); @@ -271,7 +271,7 @@ static int iscsi_login_zero_tsih_s1( * The FFP CmdSN window values will be allocated from the TPG's * Initiator Node's ACL once the login has been successfully completed. */ - sess->max_cmd_sn = pdu->cmdsn; + sess->max_cmd_sn = be32_to_cpu(pdu->cmdsn); sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL); if (!sess->sess_ops) { @@ -449,7 +449,7 @@ static int iscsi_login_non_zero_tsih_s2( (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED)) continue; if (!memcmp(sess_p->isid, pdu->isid, 6) && - (sess_p->tsih == pdu->tsih)) { + (sess_p->tsih == be16_to_cpu(pdu->tsih))) { iscsit_inc_session_usage_count(sess_p); iscsit_stop_time2retain_timer(sess_p); sess = sess_p; @@ -951,10 +951,6 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) } pdu = (struct iscsi_login_req *) buffer; - pdu->cid = be16_to_cpu(pdu->cid); - pdu->tsih = be16_to_cpu(pdu->tsih); - pdu->cmdsn = be32_to_cpu(pdu->cmdsn); - pdu->exp_statsn = be32_to_cpu(pdu->exp_statsn); /* * Used by iscsit_tx_login_rsp() for Login Resonses PDUs diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 33ed9b5209cd..e9053a04f24c 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c @@ -360,11 +360,9 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log return -1; login->rsp_length = 0; - login_rsp->tsih = be16_to_cpu(login_rsp->tsih); - login_rsp->statsn = be32_to_cpu(login_rsp->statsn); mutex_lock(&sess->cmdsn_mutex); - login_rsp->exp_cmdsn = be32_to_cpu(sess->exp_cmd_sn); - login_rsp->max_cmdsn = be32_to_cpu(sess->max_cmd_sn); + login_rsp->exp_cmdsn = cpu_to_be32(sess->exp_cmd_sn); + login_rsp->max_cmdsn = cpu_to_be32(sess->max_cmd_sn); mutex_unlock(&sess->cmdsn_mutex); return 0; @@ -380,10 +378,6 @@ static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_log login_req = (struct iscsi_login_req *) login->req; payload_length = ntoh24(login_req->dlength); - login_req->tsih = be16_to_cpu(login_req->tsih); - login_req->cid = be16_to_cpu(login_req->cid); - login_req->cmdsn = be32_to_cpu(login_req->cmdsn); - login_req->exp_statsn = be32_to_cpu(login_req->exp_statsn); pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x," " CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n", @@ -760,11 +754,11 @@ static int iscsi_target_locate_portal( login->version_min = login_req->min_version; login->version_max = login_req->max_version; memcpy(login->isid, login_req->isid, 6); - login->cmd_sn = login_req->cmdsn; + login->cmd_sn = be32_to_cpu(login_req->cmdsn); login->init_task_tag = login_req->itt; - login->initial_exp_statsn = login_req->exp_statsn; - login->cid = login_req->cid; - login->tsih = login_req->tsih; + login->initial_exp_statsn = be32_to_cpu(login_req->exp_statsn); + login->cid = be16_to_cpu(login_req->cid); + login->tsih = be16_to_cpu(login_req->tsih); if (iscsi_target_get_initial_payload(conn, login) < 0) return -1; diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index 925f829a3704..4a99820d063b 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c @@ -50,11 +50,11 @@ u8 iscsit_tmr_abort_task( if (!ref_cmd) { pr_err("Unable to locate RefTaskTag: 0x%08x on CID:" " %hu.\n", hdr->rtt, conn->cid); - return ((hdr->refcmdsn >= conn->sess->exp_cmd_sn) && - (hdr->refcmdsn <= conn->sess->max_cmd_sn)) ? + return (be32_to_cpu(hdr->refcmdsn) >= conn->sess->exp_cmd_sn && + be32_to_cpu(hdr->refcmdsn) <= conn->sess->max_cmd_sn) ? ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK; } - if (ref_cmd->cmd_sn != hdr->refcmdsn) { + if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) { pr_err("RefCmdSN 0x%08x does not equal" " task's CmdSN 0x%08x. Rejecting ABORT_TASK.\n", hdr->refcmdsn, ref_cmd->cmd_sn); @@ -63,8 +63,7 @@ u8 iscsit_tmr_abort_task( se_tmr->ref_task_tag = (__force u32)hdr->rtt; tmr_req->ref_cmd = ref_cmd; - tmr_req->ref_cmd_sn = hdr->refcmdsn; - tmr_req->exp_data_sn = hdr->exp_datasn; + tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn); return ISCSI_TMF_RSP_COMPLETE; } @@ -173,8 +172,7 @@ u8 iscsit_tmr_task_reassign( se_tmr->ref_task_tag = (__force u32)hdr->rtt; tmr_req->ref_cmd = ref_cmd; - tmr_req->ref_cmd_sn = hdr->refcmdsn; - tmr_req->exp_data_sn = hdr->exp_datasn; + tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn); tmr_req->conn_recovery = cr; tmr_req->task_reassign = 1; /* diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 22bec9e899c0..afd98ccd40ae 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -274,14 +274,14 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm int iscsit_sequence_cmd( struct iscsi_conn *conn, struct iscsi_cmd *cmd, - u32 cmdsn) + __be32 cmdsn) { int ret; int cmdsn_ret; mutex_lock(&conn->sess->cmdsn_mutex); - cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, cmdsn); + cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, be32_to_cpu(cmdsn)); switch (cmdsn_ret) { case CMDSN_NORMAL_OPERATION: ret = iscsit_execute_cmd(cmd, 0); @@ -289,7 +289,7 @@ int iscsit_sequence_cmd( iscsit_execute_ooo_cmdsns(conn->sess); break; case CMDSN_HIGHER_THAN_EXP: - ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, cmdsn); + ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, be32_to_cpu(cmdsn)); break; case CMDSN_LOWER_THAN_EXP: cmd->i_state = ISTATE_REMOVE; diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 09e2f9f563a7..44054bd35437 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h @@ -12,7 +12,7 @@ extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t); extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32); extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *); extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32); -int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, u32 cmdsn); +int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, __be32 cmdsn); extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *); extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t); extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *, From cf0eb28d3ba60098865bf7dbcbfdd6b1cc483e3b Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 3 Oct 2012 15:42:48 -0700 Subject: [PATCH 44/44] iscsi-target: Bump defaults for nopin_timeout + nopin_response_timeout values This patch increases the default for nopin_timeout to 15 seconds (wait between sending a new NopIN ping) and nopin_response_timeout to 30 seconds (wait for NopOUT response before failing the connection) in order to avoid false positives by iSCSI Initiators who are not always able (under load) to respond to NopIN echo PING requests within the current 5 second window. False positives have been observed recently using Open-iSCSI code on v3.3.x with heavy large-block READ workloads over small MTU 1 Gb/sec ports, and increasing these values to more reasonable defaults significantly reduces the possibility of false positive NopIN response timeout events under this specific workload. Historically these have been set low to initiate connection recovery as soon as possible if we don't hear a ping back, but for modern v3.x code on 1 -> 10 Gb/sec ports these new defaults make alot more sense. Cc: Christoph Hellwig Cc: Andy Grover Cc: Mike Christie Cc: Hannes Reinecke Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index ff3f482968c8..2ba9f9b9435c 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -25,10 +25,10 @@ #define NA_DATAOUT_TIMEOUT_RETRIES 5 #define NA_DATAOUT_TIMEOUT_RETRIES_MAX 15 #define NA_DATAOUT_TIMEOUT_RETRIES_MIN 1 -#define NA_NOPIN_TIMEOUT 5 +#define NA_NOPIN_TIMEOUT 15 #define NA_NOPIN_TIMEOUT_MAX 60 #define NA_NOPIN_TIMEOUT_MIN 3 -#define NA_NOPIN_RESPONSE_TIMEOUT 5 +#define NA_NOPIN_RESPONSE_TIMEOUT 30 #define NA_NOPIN_RESPONSE_TIMEOUT_MAX 60 #define NA_NOPIN_RESPONSE_TIMEOUT_MIN 3 #define NA_RANDOM_DATAIN_PDU_OFFSETS 0