From 16233799e383fc76f20d8142ef55da2308d36c65 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 13 Apr 2015 19:51:11 +0200 Subject: sbp_target: remove struct sbp_nacl Except for the embedded struct se_node_acl none of the fields were ever used. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 18b0f97..61da83b 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1714,24 +1714,14 @@ static u32 sbp_get_default_depth(struct se_portal_group *se_tpg) static struct se_node_acl *sbp_alloc_fabric_acl(struct se_portal_group *se_tpg) { - struct sbp_nacl *nacl; - - nacl = kzalloc(sizeof(struct sbp_nacl), GFP_KERNEL); - if (!nacl) { - pr_err("Unable to allocate struct sbp_nacl\n"); - return NULL; - } - - return &nacl->se_node_acl; + return kzalloc(sizeof(struct se_node_acl), GFP_KERNEL); } static void sbp_release_fabric_acl( struct se_portal_group *se_tpg, struct se_node_acl *se_nacl) { - struct sbp_nacl *nacl = - container_of(se_nacl, struct sbp_nacl, se_node_acl); - kfree(nacl); + kfree(se_nacl); } static u32 sbp_tpg_get_inst_index(struct se_portal_group *se_tpg) @@ -2106,7 +2096,6 @@ static struct se_node_acl *sbp_make_nodeacl( const char *name) { struct se_node_acl *se_nacl, *se_nacl_new; - struct sbp_nacl *nacl; u64 guid = 0; u32 nexus_depth = 1; @@ -2128,20 +2117,13 @@ static struct se_node_acl *sbp_make_nodeacl( return se_nacl; } - nacl = container_of(se_nacl, struct sbp_nacl, se_node_acl); - nacl->guid = guid; - sbp_format_wwn(nacl->iport_name, SBP_NAMELEN, guid); - return se_nacl; } static void sbp_drop_nodeacl(struct se_node_acl *se_acl) { - struct sbp_nacl *nacl = - container_of(se_acl, struct sbp_nacl, se_node_acl); - core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1); - kfree(nacl); + kfree(se_acl); } static int sbp_post_link_lun( -- cgit v1.1 From e1750d20e69477c0d7b26d6e0ba24c3c9ec47530 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 13 Apr 2015 19:51:13 +0200 Subject: target: make the tpg_get_default_depth method optional All fabric drivers except for iSCSI always return 1, so implement that as default behavior. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 61da83b..0d70d4f 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1707,11 +1707,6 @@ static u16 sbp_get_tag(struct se_portal_group *se_tpg) return tpg->tport_tpgt; } -static u32 sbp_get_default_depth(struct se_portal_group *se_tpg) -{ - return 1; -} - static struct se_node_acl *sbp_alloc_fabric_acl(struct se_portal_group *se_tpg) { return kzalloc(sizeof(struct se_node_acl), GFP_KERNEL); @@ -2490,7 +2485,6 @@ static const struct target_core_fabric_ops sbp_ops = { .get_fabric_proto_ident = sbp_get_fabric_proto_ident, .tpg_get_wwn = sbp_get_fabric_wwn, .tpg_get_tag = sbp_get_tag, - .tpg_get_default_depth = sbp_get_default_depth, .tpg_get_pr_transport_id = sbp_get_pr_transport_id, .tpg_get_pr_transport_id_len = sbp_get_pr_transport_id_len, .tpg_parse_pr_out_transport_id = sbp_parse_pr_out_transport_id, -- cgit v1.1 From c7d6a803926bae9bbf4510a18fc8dd8957cc0e01 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 13 Apr 2015 19:51:14 +0200 Subject: target: refactor init/drop_nodeacl methods By always allocating and adding, respectively removing and freeing the se_node_acl structure in core code we can remove tons of repeated code in the init_nodeacl and drop_nodeacl routines. Additionally this now respects the get_default_queue_depth method in this code path as well. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 0d70d4f..3a47fe4 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -2085,40 +2085,13 @@ static ssize_t sbp_format_wwn(char *buf, size_t len, u64 wwn) return snprintf(buf, len, "%016llx", wwn); } -static struct se_node_acl *sbp_make_nodeacl( - struct se_portal_group *se_tpg, - struct config_group *group, - const char *name) +static int sbp_init_nodeacl(struct se_node_acl *se_nacl, const char *name) { - struct se_node_acl *se_nacl, *se_nacl_new; u64 guid = 0; - u32 nexus_depth = 1; if (sbp_parse_wwn(name, &guid) < 0) - return ERR_PTR(-EINVAL); - - se_nacl_new = sbp_alloc_fabric_acl(se_tpg); - if (!se_nacl_new) - return ERR_PTR(-ENOMEM); - - /* - * se_nacl_new may be released by core_tpg_add_initiator_node_acl() - * when converting a NodeACL from demo mode -> explict - */ - se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new, - name, nexus_depth); - if (IS_ERR(se_nacl)) { - sbp_release_fabric_acl(se_tpg, se_nacl_new); - return se_nacl; - } - - return se_nacl; -} - -static void sbp_drop_nodeacl(struct se_node_acl *se_acl) -{ - core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1); - kfree(se_acl); + return -EINVAL; + return 0; } static int sbp_post_link_lun( @@ -2518,8 +2491,7 @@ static const struct target_core_fabric_ops sbp_ops = { .fabric_pre_unlink = sbp_pre_unlink_lun, .fabric_make_np = NULL, .fabric_drop_np = NULL, - .fabric_make_nodeacl = sbp_make_nodeacl, - .fabric_drop_nodeacl = sbp_drop_nodeacl, + .fabric_init_nodeacl = sbp_init_nodeacl, .tfc_wwn_attrs = sbp_wwn_attrs, .tfc_tpg_base_attrs = sbp_tpg_base_attrs, -- cgit v1.1 From 144bc4c2a42a0f42a32c106d53f5bf2724fbf098 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 13 Apr 2015 19:51:16 +0200 Subject: target: move node ACL allocation to core code Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 3a47fe4..5df2a61 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1707,18 +1707,6 @@ static u16 sbp_get_tag(struct se_portal_group *se_tpg) return tpg->tport_tpgt; } -static struct se_node_acl *sbp_alloc_fabric_acl(struct se_portal_group *se_tpg) -{ - return kzalloc(sizeof(struct se_node_acl), GFP_KERNEL); -} - -static void sbp_release_fabric_acl( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl) -{ - kfree(se_nacl); -} - static u32 sbp_tpg_get_inst_index(struct se_portal_group *se_tpg) { return 1; @@ -2465,8 +2453,6 @@ static const struct target_core_fabric_ops sbp_ops = { .tpg_check_demo_mode_cache = sbp_check_true, .tpg_check_demo_mode_write_protect = sbp_check_false, .tpg_check_prod_mode_write_protect = sbp_check_false, - .tpg_alloc_fabric_acl = sbp_alloc_fabric_acl, - .tpg_release_fabric_acl = sbp_release_fabric_acl, .tpg_get_inst_index = sbp_tpg_get_inst_index, .release_cmd = sbp_release_cmd, .shutdown_session = sbp_shutdown_session, -- cgit v1.1 From e4aae5af810eaa61c2cd7ba79d95ebfe0d88fe9b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 1 May 2015 17:47:56 +0200 Subject: target: change core_tpg_register prototype Remove the unneeded fabric_ptr argument, and change the type argument to pass in a SPC protocol identifier. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 5df2a61..40b9f51 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -2152,8 +2152,7 @@ static struct se_portal_group *sbp_make_tpg( goto out_free_tpg; } - ret = core_tpg_register(&sbp_ops, wwn, &tpg->se_tpg, tpg, - TRANSPORT_TPG_TYPE_NORMAL); + ret = core_tpg_register(&sbp_ops, wwn, &tpg->se_tpg, SCSI_PROTOCOL_SBP); if (ret < 0) goto out_unreg_mgt_agt; -- cgit v1.1 From 2aeeafae6bb9f04dbe17b521bcd8f0d03516c393 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 1 May 2015 17:47:57 +0200 Subject: target: remove the get_fabric_proto_ident method Now that we store the protocol identifier in the tpg structure we don't need this method. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 40b9f51..8acb37f 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1832,18 +1832,6 @@ static int sbp_check_stop_free(struct se_cmd *se_cmd) return 1; } -/* - * Handlers for Serial Bus Protocol 2/3 (SBP-2 / SBP-3) - */ -static u8 sbp_get_fabric_proto_ident(struct se_portal_group *se_tpg) -{ - /* - * Return a IEEE 1394 SCSI Protocol identifier for loopback operations - * This is defined in section 7.5.1 Table 362 in spc4r17 - */ - return SCSI_PROTOCOL_SBP; -} - static u32 sbp_get_pr_transport_id( struct se_portal_group *se_tpg, struct se_node_acl *se_nacl, @@ -2442,7 +2430,6 @@ static const struct target_core_fabric_ops sbp_ops = { .module = THIS_MODULE, .name = "sbp", .get_fabric_name = sbp_get_fabric_name, - .get_fabric_proto_ident = sbp_get_fabric_proto_ident, .tpg_get_wwn = sbp_get_fabric_wwn, .tpg_get_tag = sbp_get_tag, .tpg_get_pr_transport_id = sbp_get_pr_transport_id, -- cgit v1.1 From 2650d71e244fb3637b5f58a0080682a8bf9c7091 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 1 May 2015 17:47:58 +0200 Subject: target: move transport ID handling to the core Now that struct se_portal_group contains a protocol identifier field we can take all the code to format an parse protocol identifiers in CDBs into common code instead of leaving this to low-level drivers. Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 70 ----------------------------------------- 1 file changed, 70 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 8acb37f..89f172d 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1832,73 +1832,6 @@ static int sbp_check_stop_free(struct se_cmd *se_cmd) return 1; } -static u32 sbp_get_pr_transport_id( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct t10_pr_registration *pr_reg, - int *format_code, - unsigned char *buf) -{ - int ret; - - /* - * Set PROTOCOL IDENTIFIER to 3h for SBP - */ - buf[0] = SCSI_PROTOCOL_SBP; - /* - * From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI - * over IEEE 1394 - */ - ret = hex2bin(&buf[8], se_nacl->initiatorname, 8); - if (ret < 0) - pr_debug("sbp transport_id: invalid hex string\n"); - - /* - * The IEEE 1394 Transport ID is a hardcoded 24-byte length - */ - return 24; -} - -static u32 sbp_get_pr_transport_id_len( - struct se_portal_group *se_tpg, - struct se_node_acl *se_nacl, - struct t10_pr_registration *pr_reg, - int *format_code) -{ - *format_code = 0; - /* - * From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI - * over IEEE 1394 - * - * The SBP Transport ID is a hardcoded 24-byte length - */ - return 24; -} - -/* - * Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above - * Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations. - */ -static char *sbp_parse_pr_out_transport_id( - struct se_portal_group *se_tpg, - const char *buf, - u32 *out_tid_len, - char **port_nexus_ptr) -{ - /* - * Assume the FORMAT CODE 00b from spc4r17, 7.5.4.4 TransportID - * for initiator ports using SCSI over SBP Serial SCSI Protocol - * - * The TransportID for a IEEE 1394 Initiator Port is of fixed size of - * 24 bytes, and IEEE 1394 does not contain a I_T nexus identifier, - * so we return the **port_nexus_ptr set to NULL. - */ - *port_nexus_ptr = NULL; - *out_tid_len = 24; - - return (char *)&buf[8]; -} - static int sbp_count_se_tpg_luns(struct se_portal_group *tpg) { int i, count = 0; @@ -2432,9 +2365,6 @@ static const struct target_core_fabric_ops sbp_ops = { .get_fabric_name = sbp_get_fabric_name, .tpg_get_wwn = sbp_get_fabric_wwn, .tpg_get_tag = sbp_get_tag, - .tpg_get_pr_transport_id = sbp_get_pr_transport_id, - .tpg_get_pr_transport_id_len = sbp_get_pr_transport_id_len, - .tpg_parse_pr_out_transport_id = sbp_parse_pr_out_transport_id, .tpg_check_demo_mode = sbp_check_true, .tpg_check_demo_mode_cache = sbp_check_true, .tpg_check_demo_mode_write_protect = sbp_check_false, -- cgit v1.1 From 649ee05499d1257a3af0e10d961a1c52d9ef95b7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 14 Apr 2015 13:26:44 +0200 Subject: target: Move task tag into struct se_cmd + support 64-bit tags Simplify target core and target drivers by storing the task tag a.k.a. command identifier inside struct se_cmd. For several transports (e.g. SRP) tags are 64 bits wide. Hence add support for 64-bit tags. (Fix core_tmr_abort_task conversion spec warnings - nab) (Fix up usb-gadget to use 16-bit tags - HCH + bart) Signed-off-by: Bart Van Assche Cc: Christoph Hellwig Cc: Andy Grover Cc: Sagi Grimberg Cc: Cc: Felipe Balbi Cc: Michael S. Tsirkin Cc: Juergen Gross Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 89f172d..2916a40 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1234,6 +1234,8 @@ static void sbp_handle_command(struct sbp_target_request *req) pr_debug("sbp_handle_command ORB:0x%llx unpacked_lun:%d data_len:%d data_dir:%d\n", req->orb_pointer, unpacked_lun, data_length, data_dir); + /* only used for printk until we do TMRs */ + req->se_cmd.tag = req->orb_pointer; if (target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf, req->sense_buf, unpacked_lun, data_length, TCM_SIMPLE_TAG, data_dir, 0)) @@ -1768,15 +1770,6 @@ static void sbp_set_default_node_attrs(struct se_node_acl *nacl) return; } -static u32 sbp_get_task_tag(struct se_cmd *se_cmd) -{ - struct sbp_target_request *req = container_of(se_cmd, - struct sbp_target_request, se_cmd); - - /* only used for printk until we do TMRs */ - return (u32)req->orb_pointer; -} - static int sbp_get_cmd_state(struct se_cmd *se_cmd) { return 0; @@ -2377,7 +2370,6 @@ static const struct target_core_fabric_ops sbp_ops = { .write_pending = sbp_write_pending, .write_pending_status = sbp_write_pending_status, .set_default_node_attributes = sbp_set_default_node_attrs, - .get_task_tag = sbp_get_task_tag, .get_cmd_state = sbp_get_cmd_state, .queue_data_in = sbp_queue_data_in, .queue_status = sbp_queue_status, -- cgit v1.1 From 7ad34a93675e9c5a65711f83c518871317adc2ee Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 3 May 2015 08:50:56 +0200 Subject: target: target_core_configfs.h is not needed in fabric drivers Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 2916a40..5d7755e 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include -- cgit v1.1 From 6bb826121be244a5a3c8bd8b7d45c47df18810b7 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sun, 10 May 2015 19:31:10 -0700 Subject: target: Convert se_portal_group->tpg_lun_list[] to RCU hlist This patch converts the fixed size se_portal_group->tpg_lun_list[] to use modern RCU with hlist_head in order to support an arbitary number of se_lun ports per target endpoint. It includes dropping core_tpg_alloc_lun() from core_dev_add_lun(), and calling it directly from target_fabric_make_lun() to allocate a new se_lun. And add a new target_fabric_port_release() configfs item callback to invoke kfree_rcu() to release memory during se_lun->lun_group shutdown. Also now that se_node_acl->lun_entry_hlist is using RCU, convert existing tpg_lun_lock to struct mutex so core_tpg_add_node_to_devs() can perform RCU updater logic without releasing ->tpg_lun_mutex. Also, drop core_tpg_clear_object_luns() and it's single consumer in iscsi-target, which is duplicating TPG LUN shutdown logic and is current code results in a NOP. Finally, sbp-target and xen-scsiback fabric driver conversions are included, which are required due to the non-standard way they use ->tpg_lun_hlist. Reviewed-by: Hannes Reinecke Cc: Christoph Hellwig Cc: Sagi Grimberg Cc: Paul E. McKenney Cc: Chris Boot Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 97 ++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 55 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 5d7755e..47fb12f 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -108,13 +108,13 @@ static struct sbp_session *sbp_session_find_by_guid( } static struct sbp_login_descriptor *sbp_login_find_by_lun( - struct sbp_session *session, struct se_lun *lun) + struct sbp_session *session, u32 unpacked_lun) { struct sbp_login_descriptor *login, *found = NULL; spin_lock_bh(&session->lock); list_for_each_entry(login, &session->login_list, link) { - if (login->lun == lun) + if (login->login_lun == unpacked_lun) found = login; } spin_unlock_bh(&session->lock); @@ -124,7 +124,7 @@ static struct sbp_login_descriptor *sbp_login_find_by_lun( static int sbp_login_count_all_by_lun( struct sbp_tpg *tpg, - struct se_lun *lun, + u32 unpacked_lun, int exclusive) { struct se_session *se_sess; @@ -138,7 +138,7 @@ static int sbp_login_count_all_by_lun( spin_lock_bh(&sess->lock); list_for_each_entry(login, &sess->login_list, link) { - if (login->lun != lun) + if (login->login_lun != unpacked_lun) continue; if (!exclusive || login->exclusive) @@ -174,23 +174,23 @@ static struct sbp_login_descriptor *sbp_login_find_by_id( return found; } -static struct se_lun *sbp_get_lun_from_tpg(struct sbp_tpg *tpg, int lun) +static u32 sbp_get_lun_from_tpg(struct sbp_tpg *tpg, u32 login_lun, int *err) { struct se_portal_group *se_tpg = &tpg->se_tpg; struct se_lun *se_lun; - if (lun >= TRANSPORT_MAX_LUNS_PER_TPG) - return ERR_PTR(-EINVAL); - - spin_lock(&se_tpg->tpg_lun_lock); - se_lun = se_tpg->tpg_lun_list[lun]; - - if (se_lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) - se_lun = ERR_PTR(-ENODEV); - - spin_unlock(&se_tpg->tpg_lun_lock); + rcu_read_lock(); + hlist_for_each_entry_rcu(se_lun, &se_tpg->tpg_lun_hlist, link) { + if (se_lun->unpacked_lun == login_lun) { + rcu_read_unlock(); + *err = 0; + return login_lun; + } + } + rcu_read_unlock(); - return se_lun; + *err = -ENODEV; + return login_lun; } static struct sbp_session *sbp_session_create( @@ -294,17 +294,16 @@ static void sbp_management_request_login( { struct sbp_tport *tport = agent->tport; struct sbp_tpg *tpg = tport->tpg; - struct se_lun *se_lun; - int ret; - u64 guid; struct sbp_session *sess; struct sbp_login_descriptor *login; struct sbp_login_response_block *response; - int login_response_len; + u64 guid; + u32 unpacked_lun; + int login_response_len, ret; - se_lun = sbp_get_lun_from_tpg(tpg, - LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc))); - if (IS_ERR(se_lun)) { + unpacked_lun = sbp_get_lun_from_tpg(tpg, + LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc)), &ret); + if (ret) { pr_notice("login to unknown LUN: %d\n", LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc))); @@ -325,11 +324,11 @@ static void sbp_management_request_login( } pr_notice("mgt_agent LOGIN to LUN %d from %016llx\n", - se_lun->unpacked_lun, guid); + unpacked_lun, guid); sess = sbp_session_find_by_guid(tpg, guid); if (sess) { - login = sbp_login_find_by_lun(sess, se_lun); + login = sbp_login_find_by_lun(sess, unpacked_lun); if (login) { pr_notice("initiator already logged-in\n"); @@ -357,7 +356,7 @@ static void sbp_management_request_login( * reject with access_denied if any logins present */ if (LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc)) && - sbp_login_count_all_by_lun(tpg, se_lun, 0)) { + sbp_login_count_all_by_lun(tpg, unpacked_lun, 0)) { pr_warn("refusing exclusive login with other active logins\n"); req->status.status = cpu_to_be32( @@ -370,7 +369,7 @@ static void sbp_management_request_login( * check exclusive bit in any existing login descriptor * reject with access_denied if any exclusive logins present */ - if (sbp_login_count_all_by_lun(tpg, se_lun, 1)) { + if (sbp_login_count_all_by_lun(tpg, unpacked_lun, 1)) { pr_warn("refusing login while another exclusive login present\n"); req->status.status = cpu_to_be32( @@ -383,7 +382,7 @@ static void sbp_management_request_login( * check we haven't exceeded the number of allowed logins * reject with resources_unavailable if we have */ - if (sbp_login_count_all_by_lun(tpg, se_lun, 0) >= + if (sbp_login_count_all_by_lun(tpg, unpacked_lun, 0) >= tport->max_logins_per_lun) { pr_warn("max number of logins reached\n"); @@ -439,7 +438,7 @@ static void sbp_management_request_login( } login->sess = sess; - login->lun = se_lun; + login->login_lun = unpacked_lun; login->status_fifo_addr = sbp2_pointer_to_addr(&req->orb.status_fifo); login->exclusive = LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc)); login->login_id = atomic_inc_return(&login_id); @@ -601,7 +600,7 @@ static void sbp_management_request_logout( } pr_info("mgt_agent LOGOUT from LUN %d session %d\n", - login->lun->unpacked_lun, login->login_id); + login->login_lun, login->login_id); if (req->node_addr != login->sess->node_id) { pr_warn("logout from different node ID\n"); @@ -1227,7 +1226,7 @@ static void sbp_handle_command(struct sbp_target_request *req) goto err; } - unpacked_lun = req->login->lun->unpacked_lun; + unpacked_lun = req->login->login_lun; sbp_calc_data_length_direction(req, &data_length, &data_dir); pr_debug("sbp_handle_command ORB:0x%llx unpacked_lun:%d data_len:%d data_dir:%d\n", @@ -1826,25 +1825,21 @@ static int sbp_check_stop_free(struct se_cmd *se_cmd) static int sbp_count_se_tpg_luns(struct se_portal_group *tpg) { - int i, count = 0; - - spin_lock(&tpg->tpg_lun_lock); - for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { - struct se_lun *se_lun = tpg->tpg_lun_list[i]; - - if (se_lun->lun_status == TRANSPORT_LUN_STATUS_FREE) - continue; + struct se_lun *lun; + int count = 0; + rcu_read_lock(); + hlist_for_each_entry_rcu(lun, &tpg->tpg_lun_hlist, link) count++; - } - spin_unlock(&tpg->tpg_lun_lock); + rcu_read_unlock(); return count; } static int sbp_update_unit_directory(struct sbp_tport *tport) { - int num_luns, num_entries, idx = 0, mgt_agt_addr, ret, i; + struct se_lun *lun; + int num_luns, num_entries, idx = 0, mgt_agt_addr, ret; u32 *data; if (tport->unit_directory.data) { @@ -1906,28 +1901,20 @@ static int sbp_update_unit_directory(struct sbp_tport *tport) /* unit unique ID (leaf is just after LUNs) */ data[idx++] = 0x8d000000 | (num_luns + 1); - spin_lock(&tport->tpg->se_tpg.tpg_lun_lock); - for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { - struct se_lun *se_lun = tport->tpg->se_tpg.tpg_lun_list[i]; + rcu_read_lock(); + hlist_for_each_entry_rcu(lun, &tport->tpg->se_tpg.tpg_lun_hlist, link) { struct se_device *dev; int type; - if (se_lun->lun_status == TRANSPORT_LUN_STATUS_FREE) - continue; - - spin_unlock(&tport->tpg->se_tpg.tpg_lun_lock); - - dev = se_lun->lun_se_dev; + dev = lun->lun_se_dev; type = dev->transport->get_device_type(dev); /* logical_unit_number */ data[idx++] = 0x14000000 | ((type << 16) & 0x1f0000) | - (se_lun->unpacked_lun & 0xffff); - - spin_lock(&tport->tpg->se_tpg.tpg_lun_lock); + (lun->unpacked_lun & 0xffff); } - spin_unlock(&tport->tpg->se_tpg.tpg_lun_lock); + rcu_read_unlock(); /* unit unique ID leaf */ data[idx++] = 2 << 16; -- cgit v1.1 From 4cc987eaff9144182cde88d6d132420c28d3f81b Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Tue, 19 May 2015 00:03:07 -0700 Subject: target: Drop lun_sep_lock for se_lun->lun_se_dev RCU usage With se_port and t10_alua_tg_pt_gp_member being absored into se_lun, there is no need for an extra lock to protect se_lun->lun_se_dev assignment. This patch also converts backend drivers to use call_rcu() release to allow any se_device readers to complete. The call_rcu() instead of kfree_rcu() is required here because se_device is embedded into the backend driver specific structure. Also, convert se_lun->lun_stats to use atomic_long_t within the target_complete_ok_work() completion callback, and add FIXME for transport_lookup_tmr_lun() with se_lun->lun_ref. Finally, update sbp_update_unit_directory() special case usage with proper rcu_dereference_raw() and configfs symlink comment. Reported-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Cc: Paul E. McKenney Cc: Chris Boot Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 47fb12f..28e3adf 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1905,8 +1905,11 @@ static int sbp_update_unit_directory(struct sbp_tport *tport) hlist_for_each_entry_rcu(lun, &tport->tpg->se_tpg.tpg_lun_hlist, link) { struct se_device *dev; int type; - - dev = lun->lun_se_dev; + /* + * rcu_dereference_raw protected by se_lun->lun_group symlink + * reference to se_device->dev_group. + */ + dev = rcu_dereference_raw(lun->lun_se_dev); type = dev->transport->get_device_type(dev); /* logical_unit_number */ -- cgit v1.1 From bc0c94b1404b225b19b6b53a0e508f43e269ed1e Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 20 May 2015 21:48:03 -0700 Subject: target: Drop unnecessary core_tpg_register TFO parameter This patch drops unnecessary target_core_fabric_ops parameter usage for core_tpg_register() during fabric driver TFO->fabric_make_tpg() se_portal_group creation callback execution. Instead, use the existing se_wwn->wwn_tf->tf_ops pointer to ensure fabric driver is really using the same TFO provided at module_init time. Also go ahead and drop the forward TFO declarations tree-wide, and handling the special case for iscsi-target discovery TPG. Cc: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Nicholas Bellinger --- drivers/target/sbp/sbp_target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/target/sbp/sbp_target.c') diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 28e3adf..42f82d3 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -2055,7 +2055,7 @@ static struct se_portal_group *sbp_make_tpg( goto out_free_tpg; } - ret = core_tpg_register(&sbp_ops, wwn, &tpg->se_tpg, SCSI_PROTOCOL_SBP); + ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SBP); if (ret < 0) goto out_unreg_mgt_agt; -- cgit v1.1