static void fill_item_path(struct config_item * item, char * buffer, int length) { struct config_item * p; --length; for (p = item; p && !configfs_is_root(p); p = p->ci_parent) { int cur = strlen(config_item_name(p)); /* back up enough to print this bus id with '/' */ length -= cur; strncpy(buffer + length,config_item_name(p),cur); *(buffer + --length) = '/'; } }
void tcm_loop_drop_naa_tpg( struct se_portal_group *se_tpg) { struct se_wwn *wwn = se_tpg->se_tpg_wwn; struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, tl_se_tpg); struct tcm_loop_hba *tl_hba; unsigned short tpgt; tl_hba = tl_tpg->tl_hba; tpgt = tl_tpg->tl_tpgt; /* * Release the I_T Nexus for the Virtual SAS link if present */ tcm_loop_drop_nexus(tl_tpg); /* * Deregister the tl_tpg as a emulated SAS TCM Target Endpoint */ core_tpg_deregister(se_tpg); tl_tpg->tl_hba = NULL; tl_tpg->tl_tpgt = 0; pr_debug("TCM_Loop_ConfigFS: Deallocated Emulated %s" " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba), config_item_name(&wwn->wwn_group.cg_item), tpgt); }
static struct config_group *target_fabric_make_mappedlun( struct config_group *group, const char *name) { struct se_node_acl *se_nacl = container_of(group, struct se_node_acl, acl_group); struct se_portal_group *se_tpg = se_nacl->se_tpg; struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; struct se_lun_acl *lacl; struct config_item *acl_ci; char *buf; unsigned long mapped_lun; int ret = 0; acl_ci = &group->cg_item; if (!(acl_ci)) { printk(KERN_ERR "Unable to locatel acl_ci\n"); return NULL; } buf = kzalloc(strlen(name) + 1, GFP_KERNEL); if (!(buf)) { printk(KERN_ERR "Unable to allocate memory for name buf\n"); return ERR_PTR(-ENOMEM); } snprintf(buf, strlen(name) + 1, "%s", name); /* * Make sure user is creating iscsi/$IQN/$TPGT/acls/$INITIATOR/lun_$ID. */ if (strstr(buf, "lun_") != buf) { printk(KERN_ERR "Unable to locate \"lun_\" from buf: %s" " name: %s\n", buf, name); ret = -EINVAL; goto out; } /* * Determine the Mapped LUN value. This is what the SCSI Initiator * Port will actually see. */ if (strict_strtoul(buf + 4, 0, &mapped_lun) || mapped_lun > UINT_MAX) { ret = -EINVAL; goto out; } lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun, config_item_name(acl_ci), &ret); if (!(lacl)) goto out; config_group_init_type_name(&lacl->se_lun_group, name, &TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_cit); kfree(buf); return &lacl->se_lun_group; out: kfree(buf); return ERR_PTR(ret); }
static int target_fabric_mappedlun_link( struct config_item *lun_acl_ci, struct config_item *lun_ci) { struct se_dev_entry *deve; struct se_lun *lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group); struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci), 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 ret = 0, lun_access; if (lun->lun_link_magic != SE_LUN_LINK_MAGIC) { pr_err("Bad lun->lun_link_magic, not a valid lun_ci pointer:" " %p to struct lun: %p\n", lun_ci, lun); return -EFAULT; } /* * Ensure that the source port exists */ if (!lun->lun_sep || !lun->lun_sep->sep_tpg) { pr_err("Source se_lun->lun_sep or lun->lun_sep->sep" "_tpg does not exist\n"); return -EINVAL; } se_tpg = lun->lun_sep->sep_tpg; nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item; tpg_ci = &nacl_ci->ci_group->cg_item; wwn_ci = &tpg_ci->ci_group->cg_item; tpg_ci_s = &lun_ci->ci_parent->ci_group->cg_item; wwn_ci_s = &tpg_ci_s->ci_group->cg_item; if (strcmp(config_item_name(wwn_ci), config_item_name(wwn_ci_s))) { pr_err("Illegal Initiator ACL SymLink outside of %s\n", config_item_name(wwn_ci)); return -EINVAL; } if (strcmp(config_item_name(tpg_ci), config_item_name(tpg_ci_s))) { pr_err("Illegal Initiator ACL Symlink outside of %s" " TPGT: %s\n", config_item_name(wwn_ci), config_item_name(tpg_ci)); return -EINVAL; } spin_lock_irq(&lacl->se_lun_nacl->device_list_lock); deve = lacl->se_lun_nacl->device_list[lacl->mapped_lun]; if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) lun_access = deve->lun_flags; else lun_access = (se_tpg->se_tpg_tfo->tpg_check_prod_mode_write_protect( se_tpg)) ? TRANSPORT_LUNFLAGS_READ_ONLY : TRANSPORT_LUNFLAGS_READ_WRITE; spin_unlock_irq(&lacl->se_lun_nacl->device_list_lock); ret = core_dev_add_initiator_node_lun_acl(se_tpg, lacl, lun->unpacked_lun, lun_access); return (ret < 0) ? -EINVAL : 0; }
static int item_path_length(struct config_item * item) { struct config_item * p = item; int length = 1; do { length += strlen(config_item_name(p)) + 1; p = p->ci_parent; } while (p && !configfs_is_root(p)); return length; }
static int item_path_length(struct config_item *item) { struct config_item *p = item; int length = 1; do { length += strlen(config_item_name(p)) + 1; p = p->ci_parent; } while (in_krg_scheduler_subsys(p)); return length; }
static int target_fabric_port_link( struct config_item *lun_ci, struct config_item *se_dev_ci) { struct config_item *tpg_ci; struct se_device *dev; struct se_lun *lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group); struct se_lun *lun_p; struct se_portal_group *se_tpg; struct se_subsystem_dev *se_dev = container_of( to_config_group(se_dev_ci), struct se_subsystem_dev, se_dev_group); struct target_fabric_configfs *tf; int ret; tpg_ci = &lun_ci->ci_parent->ci_group->cg_item; se_tpg = container_of(to_config_group(tpg_ci), struct se_portal_group, tpg_group); tf = se_tpg->se_tpg_wwn->wwn_tf; if (lun->lun_se_dev != NULL) { printk(KERN_ERR "Port Symlink already exists\n"); return -EEXIST; } dev = se_dev->se_dev_ptr; if (!(dev)) { printk(KERN_ERR "Unable to locate struct se_device pointer from" " %s\n", config_item_name(se_dev_ci)); ret = -ENODEV; goto out; } lun_p = core_dev_add_lun(se_tpg, dev->se_hba, dev, lun->unpacked_lun); if ((IS_ERR(lun_p)) || !(lun_p)) { printk(KERN_ERR "core_dev_add_lun() failed\n"); ret = -EINVAL; goto out; } if (tf->tf_ops.fabric_post_link) { /* * Call the optional fabric_post_link() to allow a * fabric module to setup any additional state once * core_dev_add_lun() has been called.. */ tf->tf_ops.fabric_post_link(se_tpg, lun); } return 0; out: return ret; }
static int target_fabric_port_link( struct config_item *lun_ci, struct config_item *se_dev_ci) { struct config_item *tpg_ci; struct se_device *dev; struct se_lun *lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group); struct se_lun *lun_p; struct se_portal_group *se_tpg; struct se_subsystem_dev *se_dev = container_of( to_config_group(se_dev_ci), struct se_subsystem_dev, se_dev_group); struct target_fabric_configfs *tf; int ret; tpg_ci = &lun_ci->ci_parent->ci_group->cg_item; se_tpg = container_of(to_config_group(tpg_ci), struct se_portal_group, tpg_group); tf = se_tpg->se_tpg_wwn->wwn_tf; if (lun->lun_se_dev != NULL) { pr_err("Port Symlink already exists\n"); return -EEXIST; } dev = se_dev->se_dev_ptr; if (!dev) { pr_err("Unable to locate struct se_device pointer from" " %s\n", config_item_name(se_dev_ci)); ret = -ENODEV; goto out; } if (dev->dev_link_magic != SE_DEV_LINK_MAGIC) { pr_err("Bad dev->dev_link_magic, not a valid se_dev_ci pointer:" " %p to struct se_device: %p\n", se_dev_ci, dev); return -EFAULT; } lun_p = core_dev_add_lun(se_tpg, dev->se_hba, dev, lun->unpacked_lun); if (IS_ERR(lun_p)) { pr_err("core_dev_add_lun() failed\n"); ret = PTR_ERR(lun_p); goto out; } if (tf->tf_ops.fabric_post_link) { tf->tf_ops.fabric_post_link(se_tpg, lun); } return 0; out: return ret; }
void tcm_loop_drop_scsi_hba( struct se_wwn *wwn) { struct tcm_loop_hba *tl_hba = container_of(wwn, struct tcm_loop_hba, tl_hba_wwn); int host_no = tl_hba->sh->host_no; /* * Call device_unregister() on the original tl_hba->dev. * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will * release *tl_hba; */ device_unregister(&tl_hba->dev); pr_debug("TCM_Loop_ConfigFS: Deallocated emulated Target" " SAS Address: %s at Linux/SCSI Host ID: %d\n", config_item_name(&wwn->wwn_group.cg_item), host_no); }
struct se_portal_group *tcm_loop_make_naa_tpg( struct se_wwn *wwn, struct config_group *group, const char *name) { struct tcm_loop_hba *tl_hba = container_of(wwn, struct tcm_loop_hba, tl_hba_wwn); struct tcm_loop_tpg *tl_tpg; char *tpgt_str, *end_ptr; int ret; unsigned short int tpgt; tpgt_str = strstr(name, "tpgt_"); if (!tpgt_str) { pr_err("Unable to locate \"tpgt_#\" directory" " group\n"); return ERR_PTR(-EINVAL); } tpgt_str += 5; /* Skip ahead of "tpgt_" */ tpgt = (unsigned short int) simple_strtoul(tpgt_str, &end_ptr, 0); if (tpgt >= TL_TPGS_PER_HBA) { pr_err("Passed tpgt: %hu exceeds TL_TPGS_PER_HBA:" " %u\n", tpgt, TL_TPGS_PER_HBA); return ERR_PTR(-EINVAL); } tl_tpg = &tl_hba->tl_hba_tpgs[tpgt]; tl_tpg->tl_hba = tl_hba; tl_tpg->tl_tpgt = tpgt; /* * Register the tl_tpg as a emulated SAS TCM Target Endpoint */ ret = core_tpg_register(&tcm_loop_fabric_configfs->tf_ops, wwn, &tl_tpg->tl_se_tpg, tl_tpg, TRANSPORT_TPG_TYPE_NORMAL); if (ret < 0) return ERR_PTR(-ENOMEM); pr_debug("TCM_Loop_ConfigFS: Allocated Emulated %s" " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba), config_item_name(&wwn->wwn_group.cg_item), tpgt); return &tl_tpg->tl_se_tpg; }
static struct se_portal_group *tcm_loop_make_naa_tpg( struct se_wwn *wwn, struct config_group *group, const char *name) { struct tcm_loop_hba *tl_hba = container_of(wwn, struct tcm_loop_hba, tl_hba_wwn); struct tcm_loop_tpg *tl_tpg; int ret; unsigned long tpgt; if (strstr(name, "tpgt_") != name) { pr_err("Unable to locate \"tpgt_#\" directory" " group\n"); return ERR_PTR(-EINVAL); } if (kstrtoul(name+5, 10, &tpgt)) return ERR_PTR(-EINVAL); if (tpgt >= TL_TPGS_PER_HBA) { pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA:" " %u\n", tpgt, TL_TPGS_PER_HBA); return ERR_PTR(-EINVAL); } tl_tpg = &tl_hba->tl_hba_tpgs[tpgt]; tl_tpg->tl_hba = tl_hba; tl_tpg->tl_tpgt = tpgt; /* * Register the tl_tpg as a emulated TCM Target Endpoint */ ret = core_tpg_register(wwn, &tl_tpg->tl_se_tpg, tl_hba->tl_proto_id); if (ret < 0) return ERR_PTR(-ENOMEM); pr_debug("TCM_Loop_ConfigFS: Allocated Emulated %s" " Target Port %s,t,0x%04lx\n", tcm_loop_dump_proto_id(tl_hba), config_item_name(&wwn->wwn_group.cg_item), tpgt); return &tl_tpg->tl_se_tpg; }
static int target_fabric_mappedlun_link( struct config_item *lun_acl_ci, struct config_item *lun_ci) { struct se_dev_entry *deve; struct se_lun *lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group); struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci), 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 ret = 0, lun_access; if (lun->lun_link_magic != SE_LUN_LINK_MAGIC) { pr_err("Bad lun->lun_link_magic, not a valid lun_ci pointer:" " %p to struct lun: %p\n", lun_ci, lun); return -EFAULT; } /* * Ensure that the source port exists */ if (!lun->lun_sep || !lun->lun_sep->sep_tpg) { pr_err("Source se_lun->lun_sep or lun->lun_sep->sep" "_tpg does not exist\n"); return -EINVAL; } se_tpg = lun->lun_sep->sep_tpg; nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item; tpg_ci = &nacl_ci->ci_group->cg_item; wwn_ci = &tpg_ci->ci_group->cg_item; tpg_ci_s = &lun_ci->ci_parent->ci_group->cg_item; wwn_ci_s = &tpg_ci_s->ci_group->cg_item; /* * Make sure the SymLink is going to the same $FABRIC/$WWN/tpgt_$TPGT */ if (strcmp(config_item_name(wwn_ci), config_item_name(wwn_ci_s))) { pr_err("Illegal Initiator ACL SymLink outside of %s\n", config_item_name(wwn_ci)); return -EINVAL; } if (strcmp(config_item_name(tpg_ci), config_item_name(tpg_ci_s))) { pr_err("Illegal Initiator ACL Symlink outside of %s" " TPGT: %s\n", config_item_name(wwn_ci), config_item_name(tpg_ci)); return -EINVAL; } /* * 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/demo_mode_write_protect=1 */ spin_lock_irq(&lacl->se_lun_nacl->device_list_lock); deve = lacl->se_lun_nacl->device_list[lacl->mapped_lun]; if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) lun_access = deve->lun_flags; else lun_access = (se_tpg->se_tpg_tfo->tpg_check_prod_mode_write_protect( se_tpg)) ? TRANSPORT_LUNFLAGS_READ_ONLY : TRANSPORT_LUNFLAGS_READ_WRITE; spin_unlock_irq(&lacl->se_lun_nacl->device_list_lock); /* * Determine the actual mapped LUN value user wants.. * * This value is what the SCSI Initiator actually sees the * iscsi/$IQN/$TPGT/lun/lun_* as on their SCSI Initiator Ports. */ ret = core_dev_add_initiator_node_lun_acl(se_tpg, lacl, lun->unpacked_lun, lun_access); return (ret < 0) ? -EINVAL : 0; }
static void netconsole_target_put(struct netconsole_target *nt) { if (config_item_name(&nt->item)) config_item_put(&nt->item); }
static struct config_group *target_fabric_make_mappedlun( struct config_group *group, const char *name) { struct se_node_acl *se_nacl = container_of(group, struct se_node_acl, acl_group); struct se_portal_group *se_tpg = se_nacl->se_tpg; struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; struct se_lun_acl *lacl; struct config_item *acl_ci; struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL; char *buf; unsigned long mapped_lun; int ret = 0; acl_ci = &group->cg_item; if (!(acl_ci)) { printk(KERN_ERR "Unable to locatel acl_ci\n"); return NULL; } buf = kzalloc(strlen(name) + 1, GFP_KERNEL); if (!(buf)) { printk(KERN_ERR "Unable to allocate memory for name buf\n"); return ERR_PTR(-ENOMEM); } snprintf(buf, strlen(name) + 1, "%s", name); /* * Make sure user is creating iscsi/$IQN/$TPGT/acls/$INITIATOR/lun_$ID. */ if (strstr(buf, "lun_") != buf) { printk(KERN_ERR "Unable to locate \"lun_\" from buf: %s" " name: %s\n", buf, name); ret = -EINVAL; goto out; } /* * Determine the Mapped LUN value. This is what the SCSI Initiator * Port will actually see. */ if (strict_strtoul(buf + 4, 0, &mapped_lun) || mapped_lun > UINT_MAX) { ret = -EINVAL; goto out; } if (mapped_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { pr_err("Mapped LUN: %lu exceeds TRANSPORT_MAX_LUNS_PER_TPG" "-1: %u for Target Portal Group: %u\n", mapped_lun, TRANSPORT_MAX_LUNS_PER_TPG-1, se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg)); ret = -EINVAL; goto out; } lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun, config_item_name(acl_ci), &ret); if (!(lacl)) { ret = -EINVAL; goto out; } lacl_cg = &lacl->se_lun_group; lacl_cg->default_groups = kzalloc(sizeof(struct config_group) * 2, GFP_KERNEL); if (!lacl_cg->default_groups) { printk(KERN_ERR "Unable to allocate lacl_cg->default_groups\n"); ret = -ENOMEM; goto out; } config_group_init_type_name(&lacl->se_lun_group, name, &TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_cit); config_group_init_type_name(&lacl->ml_stat_grps.stat_group, "statistics", &TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_stat_cit); lacl_cg->default_groups[0] = &lacl->ml_stat_grps.stat_group; lacl_cg->default_groups[1] = NULL; ml_stat_grp = &ML_STAT_GRPS(lacl)->stat_group; ml_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 3, GFP_KERNEL); if (!ml_stat_grp->default_groups) { printk(KERN_ERR "Unable to allocate ml_stat_grp->default_groups\n"); ret = -ENOMEM; goto out; } target_stat_setup_mappedlun_default_groups(lacl); kfree(buf); return &lacl->se_lun_group; out: if (lacl_cg) kfree(lacl_cg->default_groups); kfree(buf); return ERR_PTR(ret); }
/* * Targets that were created by parsing the boot/module option string * do not exist in the configfs hierarchy (and have NULL names) and will * never go away, so make these a no-op for them. */ static void brcm_netconsole_target_get(struct brcm_netconsole_target *nt) { if (config_item_name(&nt->item)) config_item_get(&nt->item); }