From 7861728d42338e1efac9d400c39319c1b5efd05c Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 9 Jan 2016 05:29:24 -0800 Subject: target: Add target_alloc_session() helper function Based on HCH's original patch, this adds a full version to support percpu-ida tag pre-allocation and callback function pointer into fabric driver code to complete session setup. Reported-by: Christoph Hellwig Cc: Sagi Grimberg Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Andy Grover Signed-off-by: Nicholas Bellinger --- include/target/target_core_fabric.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 56653408f53b..685a51aa98cc 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -108,6 +108,12 @@ void target_unregister_template(const struct target_core_fabric_ops *fo); int target_depend_item(struct config_item *item); void target_undepend_item(struct config_item *item); +struct se_session *target_alloc_session(struct se_portal_group *, + unsigned int, unsigned int, enum target_prot_op prot_op, + const char *, void *, + int (*callback)(struct se_portal_group *, + struct se_session *, void *)); + struct se_session *transport_init_session(enum target_prot_op); int transport_alloc_session_tags(struct se_session *, unsigned int, unsigned int); -- cgit v1.2.3 From 03a68b44faff1b3eef5424952044747c9c555f0e Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 25 Feb 2016 15:14:32 -0800 Subject: target: Remove enum transport_lunflags_table se_dev_entry.lun_flags and se_lun.lun_access are only used for keeping track of read-write vs. read-only state. Since this is an either/or thing we can represent it as bool, and remove the unneeded enum transport_lunflags_table, which is left over from when there were more flags. Change code that uses this enum to just use true/false, and make it clear through variable and param names that true means read-only, false means read-write. Signed-off-by: Andy Grover Reviewed-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_device.c | 41 ++++++++++------------------ drivers/target/target_core_fabric_configfs.c | 32 ++++++++++------------ drivers/target/target_core_internal.h | 8 +++--- drivers/target/target_core_spc.c | 3 +- drivers/target/target_core_tpg.c | 21 +++++++------- include/target/target_core_base.h | 11 ++------ 6 files changed, 45 insertions(+), 71 deletions(-) (limited to 'include') diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index da457e25717a..a4046ca6e60d 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -86,7 +86,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) se_cmd->lun_ref_active = true; if ((se_cmd->data_direction == DMA_TO_DEVICE) && - (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { + deve->lun_access_ro) { pr_err("TARGET_CORE[%s]: Detected WRITE_PROTECTED LUN" " Access for 0x%08llx\n", se_cmd->se_tfo->get_fabric_name(), @@ -199,7 +199,7 @@ bool target_lun_is_rdonly(struct se_cmd *cmd) rcu_read_lock(); deve = target_nacl_find_deve(se_sess->se_node_acl, cmd->orig_fe_lun); - ret = (deve && deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY); + ret = deve && deve->lun_access_ro; rcu_read_unlock(); return ret; @@ -258,22 +258,15 @@ void core_free_device_list_for_node( void core_update_device_list_access( u64 mapped_lun, - u32 lun_access, + bool lun_access_ro, struct se_node_acl *nacl) { struct se_dev_entry *deve; mutex_lock(&nacl->lun_entry_mutex); deve = target_nacl_find_deve(nacl, mapped_lun); - if (deve) { - if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; - } else { - deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE; - deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; - } - } + if (deve) + deve->lun_access_ro = lun_access_ro; mutex_unlock(&nacl->lun_entry_mutex); } @@ -319,7 +312,7 @@ int core_enable_device_list_for_node( struct se_lun *lun, struct se_lun_acl *lun_acl, u64 mapped_lun, - u32 lun_access, + bool lun_access_ro, struct se_node_acl *nacl, struct se_portal_group *tpg) { @@ -340,11 +333,7 @@ int core_enable_device_list_for_node( kref_init(&new->pr_kref); init_completion(&new->pr_comp); - if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) - new->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE; - else - new->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY; - + new->lun_access_ro = lun_access_ro; new->creation_time = get_jiffies_64(); new->attach_count++; @@ -433,7 +422,7 @@ void core_disable_device_list_for_node( hlist_del_rcu(&orig->link); clear_bit(DEF_PR_REG_ACTIVE, &orig->deve_flags); - orig->lun_flags = 0; + orig->lun_access_ro = false; orig->creation_time = 0; orig->attach_count--; /* @@ -558,8 +547,7 @@ int core_dev_add_lun( { int rc; - rc = core_tpg_add_lun(tpg, lun, - TRANSPORT_LUNFLAGS_READ_WRITE, dev); + rc = core_tpg_add_lun(tpg, lun, false, dev); if (rc < 0) return rc; @@ -635,7 +623,7 @@ int core_dev_add_initiator_node_lun_acl( struct se_portal_group *tpg, struct se_lun_acl *lacl, struct se_lun *lun, - u32 lun_access) + bool lun_access_ro) { struct se_node_acl *nacl = lacl->se_lun_nacl; /* @@ -647,20 +635,19 @@ int core_dev_add_initiator_node_lun_acl( if (!nacl) return -EINVAL; - if ((lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) && - (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE)) - lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; + if (lun->lun_access_ro) + lun_access_ro = true; lacl->se_lun = lun; if (core_enable_device_list_for_node(lun, lacl, lacl->mapped_lun, - lun_access, nacl, tpg) < 0) + lun_access_ro, nacl, tpg) < 0) return -EINVAL; pr_debug("%s_TPG[%hu]_LUN[%llu->%llu] - Added %s ACL for " " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun, - (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO", + lun_access_ro ? "RO" : "RW", nacl->initiatorname); /* * Check to see if there are any existing persistent reservation APTPL diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index f916d18ccb48..8cc68be71230 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -78,7 +78,7 @@ static int target_fabric_mappedlun_link( struct se_lun_acl, se_lun_group); struct se_portal_group *se_tpg; struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s; - int lun_access; + bool lun_access_ro; if (lun->lun_link_magic != SE_LUN_LINK_MAGIC) { pr_err("Bad lun->lun_link_magic, not a valid lun_ci pointer:" @@ -115,19 +115,18 @@ static int target_fabric_mappedlun_link( } /* * If this struct se_node_acl was dynamically generated with - * tpg_1/attrib/generate_node_acls=1, use the existing deve->lun_flags, - * which be will write protected (READ-ONLY) when + * tpg_1/attrib/generate_node_acls=1, use the existing + * deve->lun_access_ro value, which will be true when * tpg_1/attrib/demo_mode_write_protect=1 */ rcu_read_lock(); deve = target_nacl_find_deve(lacl->se_lun_nacl, lacl->mapped_lun); if (deve) - lun_access = deve->lun_flags; + lun_access_ro = deve->lun_access_ro; else - lun_access = + lun_access_ro = (se_tpg->se_tpg_tfo->tpg_check_prod_mode_write_protect( - se_tpg)) ? TRANSPORT_LUNFLAGS_READ_ONLY : - TRANSPORT_LUNFLAGS_READ_WRITE; + se_tpg)) ? true : false; rcu_read_unlock(); /* * Determine the actual mapped LUN value user wants.. @@ -135,7 +134,7 @@ static int target_fabric_mappedlun_link( * This value is what the SCSI Initiator actually sees the * $FABRIC/$WWPN/$TPGT/lun/lun_* as on their SCSI Initiator Ports. */ - return core_dev_add_initiator_node_lun_acl(se_tpg, lacl, lun, lun_access); + return core_dev_add_initiator_node_lun_acl(se_tpg, lacl, lun, lun_access_ro); } static int target_fabric_mappedlun_unlink( @@ -167,8 +166,7 @@ static ssize_t target_fabric_mappedlun_write_protect_show( rcu_read_lock(); deve = target_nacl_find_deve(se_nacl, lacl->mapped_lun); if (deve) { - len = sprintf(page, "%d\n", - (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) ? 1 : 0); + len = sprintf(page, "%d\n", deve->lun_access_ro); } rcu_read_unlock(); @@ -181,25 +179,23 @@ static ssize_t target_fabric_mappedlun_write_protect_store( struct se_lun_acl *lacl = item_to_lun_acl(item); struct se_node_acl *se_nacl = lacl->se_lun_nacl; struct se_portal_group *se_tpg = se_nacl->se_tpg; - unsigned long op; + unsigned long wp; int ret; - ret = kstrtoul(page, 0, &op); + ret = kstrtoul(page, 0, &wp); if (ret) return ret; - if ((op != 1) && (op != 0)) + if ((wp != 1) && (wp != 0)) return -EINVAL; - core_update_device_list_access(lacl->mapped_lun, (op) ? - TRANSPORT_LUNFLAGS_READ_ONLY : - TRANSPORT_LUNFLAGS_READ_WRITE, - lacl->se_lun_nacl); + /* wp=1 means lun_access_ro=true */ + core_update_device_list_access(lacl->mapped_lun, wp, lacl->se_lun_nacl); pr_debug("%s_ConfigFS: Changed Initiator ACL: %s" " Mapped LUN: %llu Write Protect bit to %s\n", se_tpg->se_tpg_tfo->get_fabric_name(), - se_nacl->initiatorname, lacl->mapped_lun, (op) ? "ON" : "OFF"); + se_nacl->initiatorname, lacl->mapped_lun, (wp) ? "ON" : "OFF"); return count; diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index db4412fe6b8a..040cf5202e54 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -60,10 +60,10 @@ struct se_dev_entry *core_get_se_deve_from_rtpi(struct se_node_acl *, u16); void target_pr_kref_release(struct kref *); void core_free_device_list_for_node(struct se_node_acl *, struct se_portal_group *); -void core_update_device_list_access(u64, u32, struct se_node_acl *); +void core_update_device_list_access(u64, bool, struct se_node_acl *); struct se_dev_entry *target_nacl_find_deve(struct se_node_acl *, u64); int core_enable_device_list_for_node(struct se_lun *, struct se_lun_acl *, - u64, u32, struct se_node_acl *, struct se_portal_group *); + u64, bool, struct se_node_acl *, struct se_portal_group *); void core_disable_device_list_for_node(struct se_lun *, struct se_dev_entry *, struct se_node_acl *, struct se_portal_group *); void core_clear_lun_from_tpg(struct se_lun *, struct se_portal_group *); @@ -73,7 +73,7 @@ void core_dev_del_lun(struct se_portal_group *, struct se_lun *); struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *, struct se_node_acl *, u64, int *); int core_dev_add_initiator_node_lun_acl(struct se_portal_group *, - struct se_lun_acl *, struct se_lun *lun, u32); + struct se_lun_acl *, struct se_lun *lun, bool); int core_dev_del_initiator_node_lun_acl(struct se_lun *, struct se_lun_acl *); void core_dev_free_initiator_node_lun_acl(struct se_portal_group *, @@ -119,7 +119,7 @@ void core_tpg_add_node_to_devs(struct se_node_acl *, struct se_portal_group *, void core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *); struct se_lun *core_tpg_alloc_lun(struct se_portal_group *, u64); int core_tpg_add_lun(struct se_portal_group *, struct se_lun *, - u32, struct se_device *); + bool, struct se_device *); void core_tpg_remove_lun(struct se_portal_group *, struct se_lun *); struct se_node_acl *core_tpg_add_initiator_node_acl(struct se_portal_group *tpg, const char *initiatorname); diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 0aa47babd16c..2a91ed3ef380 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -997,7 +997,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) int length = 0; int ret; int i; - bool read_only = target_lun_is_rdonly(cmd);; memset(buf, 0, SE_MODE_PAGE_BUF); @@ -1008,7 +1007,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) length = ten ? 3 : 2; /* DEVICE-SPECIFIC PARAMETER */ - if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || read_only) + if (cmd->se_lun->lun_access_ro || target_lun_is_rdonly(cmd)) spc_modesense_write_protect(&buf[length], type); /* diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 3608b1b5ecf7..ddf046080dc3 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -121,7 +121,7 @@ void core_tpg_add_node_to_devs( struct se_portal_group *tpg, struct se_lun *lun_orig) { - u32 lun_access = 0; + bool lun_access_ro = true; struct se_lun *lun; struct se_device *dev; @@ -137,27 +137,26 @@ void core_tpg_add_node_to_devs( * demo_mode_write_protect is ON, or READ_ONLY; */ if (!tpg->se_tpg_tfo->tpg_check_demo_mode_write_protect(tpg)) { - lun_access = TRANSPORT_LUNFLAGS_READ_WRITE; + lun_access_ro = false; } else { /* * Allow only optical drives to issue R/W in default RO * demo mode. */ if (dev->transport->get_device_type(dev) == TYPE_DISK) - lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; + lun_access_ro = true; else - lun_access = TRANSPORT_LUNFLAGS_READ_WRITE; + lun_access_ro = false; } pr_debug("TARGET_CORE[%s]->TPG[%u]_LUN[%llu] - Adding %s" " access for LUN in Demo Mode\n", tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, - (lun_access == TRANSPORT_LUNFLAGS_READ_WRITE) ? - "READ-WRITE" : "READ-ONLY"); + lun_access_ro ? "READ-ONLY" : "READ-WRITE"); core_enable_device_list_for_node(lun, NULL, lun->unpacked_lun, - lun_access, acl, tpg); + lun_access_ro, acl, tpg); /* * Check to see if there are any existing persistent reservation * APTPL pre-registrations that need to be enabled for this dynamic @@ -522,7 +521,7 @@ int core_tpg_register( return PTR_ERR(se_tpg->tpg_virt_lun0); ret = core_tpg_add_lun(se_tpg, se_tpg->tpg_virt_lun0, - TRANSPORT_LUNFLAGS_READ_ONLY, g_lun0_dev); + true, g_lun0_dev); if (ret < 0) { kfree(se_tpg->tpg_virt_lun0); return ret; @@ -616,7 +615,7 @@ struct se_lun *core_tpg_alloc_lun( int core_tpg_add_lun( struct se_portal_group *tpg, struct se_lun *lun, - u32 lun_access, + bool lun_access_ro, struct se_device *dev) { int ret; @@ -644,9 +643,9 @@ int core_tpg_add_lun( spin_unlock(&dev->se_port_lock); if (dev->dev_flags & DF_READ_ONLY) - lun->lun_access = TRANSPORT_LUNFLAGS_READ_ONLY; + lun->lun_access_ro = true; else - lun->lun_access = lun_access; + lun->lun_access_ro = lun_access_ro; if (!(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) hlist_add_head_rcu(&lun->link, &tpg->tpg_lun_hlist); mutex_unlock(&tpg->tpg_lun_mutex); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index e8c8c08bf575..fca03b993bec 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -144,12 +144,6 @@ enum se_cmd_flags_table { SCF_USE_CPUID = 0x00800000, }; -/* struct se_dev_entry->lun_flags and struct se_lun->lun_access */ -enum transport_lunflags_table { - TRANSPORT_LUNFLAGS_READ_ONLY = 0x01, - TRANSPORT_LUNFLAGS_READ_WRITE = 0x02, -}; - /* * Used by transport_send_check_condition_and_sense() * to signal which ASC/ASCQ sense payload should be built. @@ -634,11 +628,10 @@ struct se_lun_acl { }; struct se_dev_entry { - /* See transport_lunflags_table */ u64 mapped_lun; u64 pr_res_key; u64 creation_time; - u32 lun_flags; + bool lun_access_ro; u32 attach_count; atomic_long_t total_cmds; atomic_long_t read_bytes; @@ -712,7 +705,7 @@ struct se_lun { u64 unpacked_lun; #define SE_LUN_LINK_MAGIC 0xffff7771 u32 lun_link_magic; - u32 lun_access; + bool lun_access_ro; u32 lun_index; /* RELATIVE TARGET PORT IDENTIFER */ -- cgit v1.2.3 From 32c76de3466ed2a875e36c140ac4e3800fdfab6e Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Mon, 29 Feb 2016 16:02:15 -0800 Subject: target/user: Report capability of handling out-of-order completions to userspace TCMU_MAILBOX_FLAG_CAP_OOOC was introduced, and userspace can check the flag for out-of-order completion capability support. Also update the document on how to use the feature. Signed-off-by: Sheng Yang Reviewed-by: Andy Grover Signed-off-by: Nicholas Bellinger --- Documentation/target/tcmu-design.txt | 11 ++++++++++- drivers/target/target_core_user.c | 1 + include/uapi/linux/target_core_user.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/Documentation/target/tcmu-design.txt b/Documentation/target/tcmu-design.txt index bef81e42788f..4cebc1ebf99a 100644 --- a/Documentation/target/tcmu-design.txt +++ b/Documentation/target/tcmu-design.txt @@ -117,7 +117,9 @@ userspace (respectively) to put commands on the ring, and indicate when the commands are completed. version - 1 (userspace should abort if otherwise) -flags - none yet defined. +flags: +- TCMU_MAILBOX_FLAG_CAP_OOOC: indicates out-of-order completion is + supported. See "The Command Ring" for details. cmdr_off - The offset of the start of the command ring from the start of the memory region, to account for the mailbox size. cmdr_size - The size of the command ring. This does *not* need to be a @@ -162,6 +164,13 @@ rsp.sense_buffer if necessary. Userspace then increments mailbox.cmd_tail by entry.hdr.length (mod cmdr_size) and signals the kernel via the UIO method, a 4-byte write to the file descriptor. +If TCMU_MAILBOX_FLAG_CAP_OOOC is set for mailbox->flags, kernel is +capable of handling out-of-order completions. In this case, userspace can +handle command in different order other than original. Since kernel would +still process the commands in the same order it appeared in the command +ring, userspace need to update the cmd->id when completing the +command(a.k.a steal the original command's entry). + When the opcode is PAD, userspace only updates cmd_tail as above -- it's a no-op. (The kernel inserts PAD entries to ensure each CMD entry is contiguous within the command ring.) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index fc4789c6067c..62bf4fe5704a 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -930,6 +930,7 @@ static int tcmu_configure_device(struct se_device *dev) mb = udev->mb_addr; mb->version = TCMU_MAILBOX_VERSION; + mb->flags = TCMU_MAILBOX_FLAG_CAP_OOOC; mb->cmdr_off = CMDR_OFF; mb->cmdr_size = udev->cmdr_size; diff --git a/include/uapi/linux/target_core_user.h b/include/uapi/linux/target_core_user.h index 95c6521d8a95..c506cddb8165 100644 --- a/include/uapi/linux/target_core_user.h +++ b/include/uapi/linux/target_core_user.h @@ -41,6 +41,7 @@ #define TCMU_MAILBOX_VERSION 2 #define ALIGN_SIZE 64 /* Should be enough for most CPUs */ +#define TCMU_MAILBOX_FLAG_CAP_OOOC (1 << 0) /* Out-of-order completions */ struct tcmu_mailbox { __u16 version; -- cgit v1.2.3