You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (55 commits) [SCSI] tcm_loop: Add multi-fabric Linux/SCSI LLD fabric module [SCSI] qla4xxx: Use polling mode for disable interrupt mailbox completion [SCSI] Revert "[SCSI] Retrieve the Caching mode page" [SCSI] bnx2fc: IO completion not processed due to missed wakeup [SCSI] qla4xxx: Update driver version to 5.02.00-k6 [SCSI] qla4xxx: masking required bits of add_fw_options during initialization [SCSI] qla4xxx: added new function qla4xxx_relogin_all_devices [SCSI] qla4xxx: add support for ql4xsess_recovery_tmo cmd line param [SCSI] qla4xxx: Add support for ql4xmaxqdepth command line parameter [SCSI] qla4xxx: cleanup function qla4xxx_process_ddb_changed [SCSI] qla4xxx: Prevent other port reinitialization during remove_adapter [SCSI] qla4xxx: remove unused ddb flag DF_NO_RELOGIN [SCSI] qla4xxx: cleanup DDB relogin logic during initialization [SCSI] qla4xxx: Do not retry ISP82XX initialization if H/W state is failed [SCSI] qla4xxx: Do not send mbox command if FW is in failed state [SCSI] qla4xxx: cleanup qla4xxx_initialize_ddb_list() [SCSI] ses: add subenclosure support [SCSI] bnx2fc: Bump version to 1.0.1 [SCSI] bnx2fc: Remove unnecessary module state checks [SCSI] bnx2fc: Fix MTU issue by using static MTU ...
This commit is contained in:
@@ -29,4 +29,6 @@ config TCM_PSCSI
|
||||
Say Y here to enable the TCM/pSCSI subsystem plugin for non-buffered
|
||||
passthrough access to Linux/SCSI device
|
||||
|
||||
source "drivers/target/loopback/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
EXTRA_CFLAGS += -I$(srctree)/drivers/target/ -I$(srctree)/drivers/scsi/
|
||||
|
||||
target_core_mod-y := target_core_configfs.o \
|
||||
target_core_device.o \
|
||||
@@ -13,7 +12,8 @@ target_core_mod-y := target_core_configfs.o \
|
||||
target_core_transport.o \
|
||||
target_core_cdb.o \
|
||||
target_core_ua.o \
|
||||
target_core_rd.o
|
||||
target_core_rd.o \
|
||||
target_core_stat.o
|
||||
|
||||
obj-$(CONFIG_TARGET_CORE) += target_core_mod.o
|
||||
|
||||
@@ -21,3 +21,6 @@ obj-$(CONFIG_TARGET_CORE) += target_core_mod.o
|
||||
obj-$(CONFIG_TCM_IBLOCK) += target_core_iblock.o
|
||||
obj-$(CONFIG_TCM_FILEIO) += target_core_file.o
|
||||
obj-$(CONFIG_TCM_PSCSI) += target_core_pscsi.o
|
||||
|
||||
# Fabric modules
|
||||
obj-$(CONFIG_LOOPBACK_TARGET) += loopback/
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
config LOOPBACK_TARGET
|
||||
tristate "TCM Virtual SAS target and Linux/SCSI LDD fabric loopback module"
|
||||
help
|
||||
Say Y here to enable the TCM Virtual SAS target and Linux/SCSI LLD
|
||||
fabric loopback module.
|
||||
|
||||
config LOOPBACK_TARGET_CDB_DEBUG
|
||||
bool "TCM loopback fabric module CDB debug code"
|
||||
depends on LOOPBACK_TARGET
|
||||
help
|
||||
Say Y here to enable the TCM loopback fabric module CDB debug code
|
||||
@@ -0,0 +1 @@
|
||||
obj-$(CONFIG_LOOPBACK_TARGET) += tcm_loop.o
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,77 @@
|
||||
#define TCM_LOOP_VERSION "v2.1-rc1"
|
||||
#define TL_WWN_ADDR_LEN 256
|
||||
#define TL_TPGS_PER_HBA 32
|
||||
/*
|
||||
* Defaults for struct scsi_host_template tcm_loop_driver_template
|
||||
*
|
||||
* We use large can_queue and cmd_per_lun here and let TCM enforce
|
||||
* the underlying se_device_t->queue_depth.
|
||||
*/
|
||||
#define TL_SCSI_CAN_QUEUE 1024
|
||||
#define TL_SCSI_CMD_PER_LUN 1024
|
||||
#define TL_SCSI_MAX_SECTORS 1024
|
||||
#define TL_SCSI_SG_TABLESIZE 256
|
||||
/*
|
||||
* Used in tcm_loop_driver_probe() for struct Scsi_Host->max_cmd_len
|
||||
*/
|
||||
#define TL_SCSI_MAX_CMD_LEN 32
|
||||
|
||||
#ifdef CONFIG_LOOPBACK_TARGET_CDB_DEBUG
|
||||
# define TL_CDB_DEBUG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
# define TL_CDB_DEBUG(x...)
|
||||
#endif
|
||||
|
||||
struct tcm_loop_cmd {
|
||||
/* State of Linux/SCSI CDB+Data descriptor */
|
||||
u32 sc_cmd_state;
|
||||
/* Pointer to the CDB+Data descriptor from Linux/SCSI subsystem */
|
||||
struct scsi_cmnd *sc;
|
||||
struct list_head *tl_cmd_list;
|
||||
/* The TCM I/O descriptor that is accessed via container_of() */
|
||||
struct se_cmd tl_se_cmd;
|
||||
/* Sense buffer that will be mapped into outgoing status */
|
||||
unsigned char tl_sense_buf[TRANSPORT_SENSE_BUFFER];
|
||||
};
|
||||
|
||||
struct tcm_loop_tmr {
|
||||
atomic_t tmr_complete;
|
||||
wait_queue_head_t tl_tmr_wait;
|
||||
};
|
||||
|
||||
struct tcm_loop_nexus {
|
||||
int it_nexus_active;
|
||||
/*
|
||||
* Pointer to Linux/SCSI HBA from linux/include/scsi_host.h
|
||||
*/
|
||||
struct scsi_host *sh;
|
||||
/*
|
||||
* Pointer to TCM session for I_T Nexus
|
||||
*/
|
||||
struct se_session *se_sess;
|
||||
};
|
||||
|
||||
struct tcm_loop_nacl {
|
||||
struct se_node_acl se_node_acl;
|
||||
};
|
||||
|
||||
struct tcm_loop_tpg {
|
||||
unsigned short tl_tpgt;
|
||||
atomic_t tl_tpg_port_count;
|
||||
struct se_portal_group tl_se_tpg;
|
||||
struct tcm_loop_hba *tl_hba;
|
||||
};
|
||||
|
||||
struct tcm_loop_hba {
|
||||
u8 tl_proto_id;
|
||||
unsigned char tl_wwn_address[TL_WWN_ADDR_LEN];
|
||||
struct se_hba_s *se_hba;
|
||||
struct se_lun *tl_hba_lun;
|
||||
struct se_port *tl_hba_lun_sep;
|
||||
struct se_device_s *se_dev_hba_ptr;
|
||||
struct tcm_loop_nexus *tl_nexus;
|
||||
struct device dev;
|
||||
struct Scsi_Host *sh;
|
||||
struct tcm_loop_tpg tl_hba_tpgs[TL_TPGS_PER_HBA];
|
||||
struct se_wwn tl_hba_wwn;
|
||||
};
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* This file contains ConfigFS logic for the Generic Target Engine project.
|
||||
*
|
||||
* Copyright (c) 2008-2010 Rising Tide Systems
|
||||
* Copyright (c) 2008-2010 Linux-iSCSI.org
|
||||
* Copyright (c) 2008-2011 Rising Tide Systems
|
||||
* Copyright (c) 2008-2011 Linux-iSCSI.org
|
||||
*
|
||||
* Nicholas A. Bellinger <nab@kernel.org>
|
||||
*
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "target_core_hba.h"
|
||||
#include "target_core_pr.h"
|
||||
#include "target_core_rd.h"
|
||||
#include "target_core_stat.h"
|
||||
|
||||
static struct list_head g_tf_list;
|
||||
static struct mutex g_tf_lock;
|
||||
@@ -1451,8 +1452,8 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
||||
size_t count)
|
||||
{
|
||||
struct se_device *dev;
|
||||
unsigned char *i_fabric, *t_fabric, *i_port = NULL, *t_port = NULL;
|
||||
unsigned char *isid = NULL;
|
||||
unsigned char *i_fabric = NULL, *i_port = NULL, *isid = NULL;
|
||||
unsigned char *t_fabric = NULL, *t_port = NULL;
|
||||
char *orig, *ptr, *arg_p, *opts;
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
unsigned long long tmp_ll;
|
||||
@@ -1488,9 +1489,17 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
||||
switch (token) {
|
||||
case Opt_initiator_fabric:
|
||||
i_fabric = match_strdup(&args[0]);
|
||||
if (!i_fabric) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case Opt_initiator_node:
|
||||
i_port = match_strdup(&args[0]);
|
||||
if (!i_port) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) {
|
||||
printk(KERN_ERR "APTPL metadata initiator_node="
|
||||
" exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
|
||||
@@ -1501,6 +1510,10 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
||||
break;
|
||||
case Opt_initiator_sid:
|
||||
isid = match_strdup(&args[0]);
|
||||
if (!isid) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (strlen(isid) > PR_REG_ISID_LEN) {
|
||||
printk(KERN_ERR "APTPL metadata initiator_isid"
|
||||
"= exceeds PR_REG_ISID_LEN: %d\n",
|
||||
@@ -1511,6 +1524,10 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
||||
break;
|
||||
case Opt_sa_res_key:
|
||||
arg_p = match_strdup(&args[0]);
|
||||
if (!arg_p) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
ret = strict_strtoull(arg_p, 0, &tmp_ll);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "strict_strtoull() failed for"
|
||||
@@ -1547,9 +1564,17 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
||||
*/
|
||||
case Opt_target_fabric:
|
||||
t_fabric = match_strdup(&args[0]);
|
||||
if (!t_fabric) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case Opt_target_node:
|
||||
t_port = match_strdup(&args[0]);
|
||||
if (!t_port) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) {
|
||||
printk(KERN_ERR "APTPL metadata target_node="
|
||||
" exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
|
||||
@@ -1592,6 +1617,11 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
|
||||
i_port, isid, mapped_lun, t_port, tpgt, target_lun,
|
||||
res_holder, all_tg_pt, type);
|
||||
out:
|
||||
kfree(i_fabric);
|
||||
kfree(i_port);
|
||||
kfree(isid);
|
||||
kfree(t_fabric);
|
||||
kfree(t_port);
|
||||
kfree(orig);
|
||||
return (ret == 0) ? count : ret;
|
||||
}
|
||||
@@ -1798,7 +1828,9 @@ static ssize_t target_core_store_dev_enable(
|
||||
return -EINVAL;
|
||||
|
||||
dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr);
|
||||
if (!(dev) || IS_ERR(dev))
|
||||
if (IS_ERR(dev))
|
||||
return PTR_ERR(dev);
|
||||
else if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
se_dev->se_dev_ptr = dev;
|
||||
@@ -2678,6 +2710,34 @@ static struct config_item_type target_core_alua_cit = {
|
||||
|
||||
/* End functions for struct config_item_type target_core_alua_cit */
|
||||
|
||||
/* Start functions for struct config_item_type target_core_stat_cit */
|
||||
|
||||
static struct config_group *target_core_stat_mkdir(
|
||||
struct config_group *group,
|
||||
const char *name)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
static void target_core_stat_rmdir(
|
||||
struct config_group *group,
|
||||
struct config_item *item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct configfs_group_operations target_core_stat_group_ops = {
|
||||
.make_group = &target_core_stat_mkdir,
|
||||
.drop_item = &target_core_stat_rmdir,
|
||||
};
|
||||
|
||||
static struct config_item_type target_core_stat_cit = {
|
||||
.ct_group_ops = &target_core_stat_group_ops,
|
||||
.ct_owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
/* End functions for struct config_item_type target_core_stat_cit */
|
||||
|
||||
/* Start functions for struct config_item_type target_core_hba_cit */
|
||||
|
||||
static struct config_group *target_core_make_subdev(
|
||||
@@ -2690,10 +2750,12 @@ static struct config_group *target_core_make_subdev(
|
||||
struct config_item *hba_ci = &group->cg_item;
|
||||
struct se_hba *hba = item_to_hba(hba_ci);
|
||||
struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL;
|
||||
struct config_group *dev_stat_grp = NULL;
|
||||
int errno = -ENOMEM, ret;
|
||||
|
||||
if (mutex_lock_interruptible(&hba->hba_access_mutex))
|
||||
return NULL;
|
||||
|
||||
ret = mutex_lock_interruptible(&hba->hba_access_mutex);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
/*
|
||||
* Locate the struct se_subsystem_api from parent's struct se_hba.
|
||||
*/
|
||||
@@ -2723,7 +2785,7 @@ static struct config_group *target_core_make_subdev(
|
||||
se_dev->se_dev_hba = hba;
|
||||
dev_cg = &se_dev->se_dev_group;
|
||||
|
||||
dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 6,
|
||||
dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 7,
|
||||
GFP_KERNEL);
|
||||
if (!(dev_cg->default_groups))
|
||||
goto out;
|
||||
@@ -2755,13 +2817,17 @@ static struct config_group *target_core_make_subdev(
|
||||
&target_core_dev_wwn_cit);
|
||||
config_group_init_type_name(&se_dev->t10_alua.alua_tg_pt_gps_group,
|
||||
"alua", &target_core_alua_tg_pt_gps_cit);
|
||||
config_group_init_type_name(&se_dev->dev_stat_grps.stat_group,
|
||||
"statistics", &target_core_stat_cit);
|
||||
|
||||
dev_cg->default_groups[0] = &se_dev->se_dev_attrib.da_group;
|
||||
dev_cg->default_groups[1] = &se_dev->se_dev_pr_group;
|
||||
dev_cg->default_groups[2] = &se_dev->t10_wwn.t10_wwn_group;
|
||||
dev_cg->default_groups[3] = &se_dev->t10_alua.alua_tg_pt_gps_group;
|
||||
dev_cg->default_groups[4] = NULL;
|
||||
dev_cg->default_groups[4] = &se_dev->dev_stat_grps.stat_group;
|
||||
dev_cg->default_groups[5] = NULL;
|
||||
/*
|
||||
* Add core/$HBA/$DEV/alua/tg_pt_gps/default_tg_pt_gp
|
||||
* Add core/$HBA/$DEV/alua/default_tg_pt_gp
|
||||
*/
|
||||
tg_pt_gp = core_alua_allocate_tg_pt_gp(se_dev, "default_tg_pt_gp", 1);
|
||||
if (!(tg_pt_gp))
|
||||
@@ -2781,6 +2847,17 @@ static struct config_group *target_core_make_subdev(
|
||||
tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group;
|
||||
tg_pt_gp_cg->default_groups[1] = NULL;
|
||||
T10_ALUA(se_dev)->default_tg_pt_gp = tg_pt_gp;
|
||||
/*
|
||||
* Add core/$HBA/$DEV/statistics/ default groups
|
||||
*/
|
||||
dev_stat_grp = &DEV_STAT_GRP(se_dev)->stat_group;
|
||||
dev_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 4,
|
||||
GFP_KERNEL);
|
||||
if (!dev_stat_grp->default_groups) {
|
||||
printk(KERN_ERR "Unable to allocate dev_stat_grp->default_groups\n");
|
||||
goto out;
|
||||
}
|
||||
target_stat_setup_dev_default_groups(se_dev);
|
||||
|
||||
printk(KERN_INFO "Target_Core_ConfigFS: Allocated struct se_subsystem_dev:"
|
||||
" %p se_dev_su_ptr: %p\n", se_dev, se_dev->se_dev_su_ptr);
|
||||
@@ -2792,6 +2869,8 @@ out:
|
||||
core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp);
|
||||
T10_ALUA(se_dev)->default_tg_pt_gp = NULL;
|
||||
}
|
||||
if (dev_stat_grp)
|
||||
kfree(dev_stat_grp->default_groups);
|
||||
if (tg_pt_gp_cg)
|
||||
kfree(tg_pt_gp_cg->default_groups);
|
||||
if (dev_cg)
|
||||
@@ -2801,7 +2880,7 @@ out:
|
||||
kfree(se_dev);
|
||||
unlock:
|
||||
mutex_unlock(&hba->hba_access_mutex);
|
||||
return NULL;
|
||||
return ERR_PTR(errno);
|
||||
}
|
||||
|
||||
static void target_core_drop_subdev(
|
||||
@@ -2813,7 +2892,7 @@ static void target_core_drop_subdev(
|
||||
struct se_hba *hba;
|
||||
struct se_subsystem_api *t;
|
||||
struct config_item *df_item;
|
||||
struct config_group *dev_cg, *tg_pt_gp_cg;
|
||||
struct config_group *dev_cg, *tg_pt_gp_cg, *dev_stat_grp;
|
||||
int i;
|
||||
|
||||
hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item);
|
||||
@@ -2825,6 +2904,14 @@ static void target_core_drop_subdev(
|
||||
list_del(&se_dev->g_se_dev_list);
|
||||
spin_unlock(&se_global->g_device_lock);
|
||||
|
||||
dev_stat_grp = &DEV_STAT_GRP(se_dev)->stat_group;
|
||||
for (i = 0; dev_stat_grp->default_groups[i]; i++) {
|
||||
df_item = &dev_stat_grp->default_groups[i]->cg_item;
|
||||
dev_stat_grp->default_groups[i] = NULL;
|
||||
config_item_put(df_item);
|
||||
}
|
||||
kfree(dev_stat_grp->default_groups);
|
||||
|
||||
tg_pt_gp_cg = &T10_ALUA(se_dev)->alua_tg_pt_gps_group;
|
||||
for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) {
|
||||
df_item = &tg_pt_gp_cg->default_groups[i]->cg_item;
|
||||
@@ -3044,7 +3131,7 @@ static struct config_item_type target_core_cit = {
|
||||
|
||||
/* Stop functions for struct config_item_type target_core_hba_cit */
|
||||
|
||||
static int target_core_init_configfs(void)
|
||||
static int __init target_core_init_configfs(void)
|
||||
{
|
||||
struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL;
|
||||
struct config_group *lu_gp_cg = NULL;
|
||||
@@ -3176,7 +3263,7 @@ out_global:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void target_core_exit_configfs(void)
|
||||
static void __exit target_core_exit_configfs(void)
|
||||
{
|
||||
struct configfs_subsystem *subsys;
|
||||
struct config_group *hba_cg, *alua_cg, *lu_gp_cg;
|
||||
|
||||
@@ -589,6 +589,7 @@ static void core_export_port(
|
||||
* Called with struct se_device->se_port_lock spinlock held.
|
||||
*/
|
||||
static void core_release_port(struct se_device *dev, struct se_port *port)
|
||||
__releases(&dev->se_port_lock) __acquires(&dev->se_port_lock)
|
||||
{
|
||||
/*
|
||||
* Wait for any port reference for PR ALL_TG_PT=1 operation
|
||||
@@ -779,49 +780,14 @@ void se_release_vpd_for_dev(struct se_device *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called with struct se_hba->device_lock held.
|
||||
*/
|
||||
void se_clear_dev_ports(struct se_device *dev)
|
||||
{
|
||||
struct se_hba *hba = dev->se_hba;
|
||||
struct se_lun *lun;
|
||||
struct se_portal_group *tpg;
|
||||
struct se_port *sep, *sep_tmp;
|
||||
|
||||
spin_lock(&dev->se_port_lock);
|
||||
list_for_each_entry_safe(sep, sep_tmp, &dev->dev_sep_list, sep_list) {
|
||||
spin_unlock(&dev->se_port_lock);
|
||||
spin_unlock(&hba->device_lock);
|
||||
|
||||
lun = sep->sep_lun;
|
||||
tpg = sep->sep_tpg;
|
||||
spin_lock(&lun->lun_sep_lock);
|
||||
if (lun->lun_se_dev == NULL) {
|
||||
spin_unlock(&lun->lun_sep_lock);
|
||||
continue;
|
||||
}
|
||||
spin_unlock(&lun->lun_sep_lock);
|
||||
|
||||
core_dev_del_lun(tpg, lun->unpacked_lun);
|
||||
|
||||
spin_lock(&hba->device_lock);
|
||||
spin_lock(&dev->se_port_lock);
|
||||
}
|
||||
spin_unlock(&dev->se_port_lock);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* se_free_virtual_device():
|
||||
*
|
||||
* Used for IBLOCK, RAMDISK, and FILEIO Transport Drivers.
|
||||
*/
|
||||
int se_free_virtual_device(struct se_device *dev, struct se_hba *hba)
|
||||
{
|
||||
spin_lock(&hba->device_lock);
|
||||
se_clear_dev_ports(dev);
|
||||
spin_unlock(&hba->device_lock);
|
||||
if (!list_empty(&dev->dev_sep_list))
|
||||
dump_stack();
|
||||
|
||||
core_alua_free_lu_gp_mem(dev);
|
||||
se_release_device_for_hba(dev);
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
* This file contains generic fabric module configfs infrastructure for
|
||||
* TCM v4.x code
|
||||
*
|
||||
* Copyright (c) 2010 Rising Tide Systems
|
||||
* Copyright (c) 2010 Linux-iSCSI.org
|
||||
* Copyright (c) 2010,2011 Rising Tide Systems
|
||||
* Copyright (c) 2010,2011 Linux-iSCSI.org
|
||||
*
|
||||
* Copyright (c) 2010 Nicholas A. Bellinger <nab@linux-iscsi.org>
|
||||
* Copyright (c) Nicholas A. Bellinger <nab@linux-iscsi.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "target_core_alua.h"
|
||||
#include "target_core_hba.h"
|
||||
#include "target_core_pr.h"
|
||||
#include "target_core_stat.h"
|
||||
|
||||
#define TF_CIT_SETUP(_name, _item_ops, _group_ops, _attrs) \
|
||||
static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
|
||||
@@ -241,6 +242,32 @@ TF_CIT_SETUP(tpg_mappedlun, &target_fabric_mappedlun_item_ops, NULL,
|
||||
|
||||
/* End of tfc_tpg_mappedlun_cit */
|
||||
|
||||
/* Start of tfc_tpg_mappedlun_port_cit */
|
||||
|
||||
static struct config_group *target_core_mappedlun_stat_mkdir(
|
||||
struct config_group *group,
|
||||
const char *name)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
static void target_core_mappedlun_stat_rmdir(
|
||||
struct config_group *group,
|
||||
struct config_item *item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct configfs_group_operations target_fabric_mappedlun_stat_group_ops = {
|
||||
.make_group = target_core_mappedlun_stat_mkdir,
|
||||
.drop_item = target_core_mappedlun_stat_rmdir,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops,
|
||||
NULL);
|
||||
|
||||
/* End of tfc_tpg_mappedlun_port_cit */
|
||||
|
||||
/* Start of tfc_tpg_nacl_attrib_cit */
|
||||
|
||||
CONFIGFS_EATTR_OPS(target_fabric_nacl_attrib, se_node_acl, acl_attrib_group);
|
||||
@@ -294,6 +321,7 @@ static struct config_group *target_fabric_make_mappedlun(
|
||||
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;
|
||||
@@ -330,15 +358,42 @@ static struct config_group *target_fabric_make_mappedlun(
|
||||
|
||||
lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun,
|
||||
config_item_name(acl_ci), &ret);
|
||||
if (!(lacl))
|
||||
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);
|
||||
}
|
||||
@@ -347,6 +402,28 @@ static void target_fabric_drop_mappedlun(
|
||||
struct config_group *group,
|
||||
struct config_item *item)
|
||||
{
|
||||
struct se_lun_acl *lacl = container_of(to_config_group(item),
|
||||
struct se_lun_acl, se_lun_group);
|
||||
struct config_item *df_item;
|
||||
struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL;
|
||||
int i;
|
||||
|
||||
ml_stat_grp = &ML_STAT_GRPS(lacl)->stat_group;
|
||||
for (i = 0; ml_stat_grp->default_groups[i]; i++) {
|
||||
df_item = &ml_stat_grp->default_groups[i]->cg_item;
|
||||
ml_stat_grp->default_groups[i] = NULL;
|
||||
config_item_put(df_item);
|
||||
}
|
||||
kfree(ml_stat_grp->default_groups);
|
||||
|
||||
lacl_cg = &lacl->se_lun_group;
|
||||
for (i = 0; lacl_cg->default_groups[i]; i++) {
|
||||
df_item = &lacl_cg->default_groups[i]->cg_item;
|
||||
lacl_cg->default_groups[i] = NULL;
|
||||
config_item_put(df_item);
|
||||
}
|
||||
kfree(lacl_cg->default_groups);
|
||||
|
||||
config_item_put(item);
|
||||
}
|
||||
|
||||
@@ -376,6 +453,15 @@ TF_CIT_SETUP(tpg_nacl_base, &target_fabric_nacl_base_item_ops,
|
||||
|
||||
/* End of tfc_tpg_nacl_base_cit */
|
||||
|
||||
/* Start of tfc_node_fabric_stats_cit */
|
||||
/*
|
||||
* This is used as a placeholder for struct se_node_acl->acl_fabric_stat_group
|
||||
* to allow fabrics access to ->acl_fabric_stat_group->default_groups[]
|
||||
*/
|
||||
TF_CIT_SETUP(tpg_nacl_stat, NULL, NULL, NULL);
|
||||
|
||||
/* End of tfc_wwn_fabric_stats_cit */
|
||||
|
||||
/* Start of tfc_tpg_nacl_cit */
|
||||
|
||||
static struct config_group *target_fabric_make_nodeacl(
|
||||
@@ -402,7 +488,8 @@ static struct config_group *target_fabric_make_nodeacl(
|
||||
nacl_cg->default_groups[0] = &se_nacl->acl_attrib_group;
|
||||
nacl_cg->default_groups[1] = &se_nacl->acl_auth_group;
|
||||
nacl_cg->default_groups[2] = &se_nacl->acl_param_group;
|
||||
nacl_cg->default_groups[3] = NULL;
|
||||
nacl_cg->default_groups[3] = &se_nacl->acl_fabric_stat_group;
|
||||
nacl_cg->default_groups[4] = NULL;
|
||||
|
||||
config_group_init_type_name(&se_nacl->acl_group, name,
|
||||
&TF_CIT_TMPL(tf)->tfc_tpg_nacl_base_cit);
|
||||
@@ -412,6 +499,9 @@ static struct config_group *target_fabric_make_nodeacl(
|
||||
&TF_CIT_TMPL(tf)->tfc_tpg_nacl_auth_cit);
|
||||
config_group_init_type_name(&se_nacl->acl_param_group, "param",
|
||||
&TF_CIT_TMPL(tf)->tfc_tpg_nacl_param_cit);
|
||||
config_group_init_type_name(&se_nacl->acl_fabric_stat_group,
|
||||
"fabric_statistics",
|
||||
&TF_CIT_TMPL(tf)->tfc_tpg_nacl_stat_cit);
|
||||
|
||||
return &se_nacl->acl_group;
|
||||
}
|
||||
@@ -758,6 +848,31 @@ TF_CIT_SETUP(tpg_port, &target_fabric_port_item_ops, NULL, target_fabric_port_at
|
||||
|
||||
/* End of tfc_tpg_port_cit */
|
||||
|
||||
/* Start of tfc_tpg_port_stat_cit */
|
||||
|
||||
static struct config_group *target_core_port_stat_mkdir(
|
||||
struct config_group *group,
|
||||
const char *name)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
static void target_core_port_stat_rmdir(
|
||||
struct config_group *group,
|
||||
struct config_item *item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct configfs_group_operations target_fabric_port_stat_group_ops = {
|
||||
.make_group = target_core_port_stat_mkdir,
|
||||
.drop_item = target_core_port_stat_rmdir,
|
||||
};
|
||||
|
||||
TF_CIT_SETUP(tpg_port_stat, NULL, &target_fabric_port_stat_group_ops, NULL);
|
||||
|
||||
/* End of tfc_tpg_port_stat_cit */
|
||||
|
||||
/* Start of tfc_tpg_lun_cit */
|
||||
|
||||
static struct config_group *target_fabric_make_lun(
|
||||
@@ -768,7 +883,9 @@ static struct config_group *target_fabric_make_lun(
|
||||
struct se_portal_group *se_tpg = container_of(group,
|
||||
struct se_portal_group, tpg_lun_group);
|
||||
struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
|
||||
struct config_group *lun_cg = NULL, *port_stat_grp = NULL;
|
||||
unsigned long unpacked_lun;
|
||||
int errno;
|
||||
|
||||
if (strstr(name, "lun_") != name) {
|
||||
printk(KERN_ERR "Unable to locate \'_\" in"
|
||||
@@ -782,16 +899,64 @@ static struct config_group *target_fabric_make_lun(
|
||||
if (!(lun))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
lun_cg = &lun->lun_group;
|
||||
lun_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
|
||||
GFP_KERNEL);
|
||||
if (!lun_cg->default_groups) {
|
||||
printk(KERN_ERR "Unable to allocate lun_cg->default_groups\n");
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
config_group_init_type_name(&lun->lun_group, name,
|
||||
&TF_CIT_TMPL(tf)->tfc_tpg_port_cit);
|
||||
config_group_init_type_name(&lun->port_stat_grps.stat_group,
|
||||
"statistics", &TF_CIT_TMPL(tf)->tfc_tpg_port_stat_cit);
|
||||
lun_cg->default_groups[0] = &lun->port_stat_grps.stat_group;
|
||||
lun_cg->default_groups[1] = NULL;
|
||||
|
||||
port_stat_grp = &PORT_STAT_GRP(lun)->stat_group;
|
||||
port_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 3,
|
||||
GFP_KERNEL);
|
||||
if (!port_stat_grp->default_groups) {
|
||||
printk(KERN_ERR "Unable to allocate port_stat_grp->default_groups\n");
|
||||
errno = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
target_stat_setup_port_default_groups(lun);
|
||||
|
||||
return &lun->lun_group;
|
||||
out:
|
||||
if (lun_cg)
|
||||
kfree(lun_cg->default_groups);
|
||||
return ERR_PTR(errno);
|
||||
}
|
||||
|
||||
static void target_fabric_drop_lun(
|
||||
struct config_group *group,
|
||||
struct config_item *item)
|
||||
{
|
||||
struct se_lun *lun = container_of(to_config_group(item),
|
||||
struct se_lun, lun_group);
|
||||
struct config_item *df_item;
|
||||
struct config_group *lun_cg, *port_stat_grp;
|
||||
int i;
|
||||
|
||||
port_stat_grp = &PORT_STAT_GRP(lun)->stat_group;
|
||||
for (i = 0; port_stat_grp->default_groups[i]; i++) {
|
||||
df_item = &port_stat_grp->default_groups[i]->cg_item;
|
||||
port_stat_grp->default_groups[i] = NULL;
|
||||
config_item_put(df_item);
|
||||
}
|
||||
kfree(port_stat_grp->default_groups);
|
||||
|
||||
lun_cg = &lun->lun_group;
|
||||
for (i = 0; lun_cg->default_groups[i]; i++) {
|
||||
df_item = &lun_cg->default_groups[i]->cg_item;
|
||||
lun_cg->default_groups[i] = NULL;
|
||||
config_item_put(df_item);
|
||||
}
|
||||
kfree(lun_cg->default_groups);
|
||||
|
||||
config_item_put(item);
|
||||
}
|
||||
|
||||
@@ -946,6 +1111,15 @@ TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops,
|
||||
|
||||
/* End of tfc_tpg_cit */
|
||||
|
||||
/* Start of tfc_wwn_fabric_stats_cit */
|
||||
/*
|
||||
* This is used as a placeholder for struct se_wwn->fabric_stat_group
|
||||
* to allow fabrics access to ->fabric_stat_group->default_groups[]
|
||||
*/
|
||||
TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL);
|
||||
|
||||
/* End of tfc_wwn_fabric_stats_cit */
|
||||
|
||||
/* Start of tfc_wwn_cit */
|
||||
|
||||
static struct config_group *target_fabric_make_wwn(
|
||||
@@ -966,8 +1140,17 @@ static struct config_group *target_fabric_make_wwn(
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
wwn->wwn_tf = tf;
|
||||
/*
|
||||
* Setup default groups from pre-allocated wwn->wwn_default_groups
|
||||
*/
|
||||
wwn->wwn_group.default_groups = wwn->wwn_default_groups;
|
||||
wwn->wwn_group.default_groups[0] = &wwn->fabric_stat_group;
|
||||
wwn->wwn_group.default_groups[1] = NULL;
|
||||
|
||||
config_group_init_type_name(&wwn->wwn_group, name,
|
||||
&TF_CIT_TMPL(tf)->tfc_tpg_cit);
|
||||
config_group_init_type_name(&wwn->fabric_stat_group, "fabric_statistics",
|
||||
&TF_CIT_TMPL(tf)->tfc_wwn_fabric_stats_cit);
|
||||
|
||||
return &wwn->wwn_group;
|
||||
}
|
||||
@@ -976,6 +1159,18 @@ static void target_fabric_drop_wwn(
|
||||
struct config_group *group,
|
||||
struct config_item *item)
|
||||
{
|
||||
struct se_wwn *wwn = container_of(to_config_group(item),
|
||||
struct se_wwn, wwn_group);
|
||||
struct config_item *df_item;
|
||||
struct config_group *cg = &wwn->wwn_group;
|
||||
int i;
|
||||
|
||||
for (i = 0; cg->default_groups[i]; i++) {
|
||||
df_item = &cg->default_groups[i]->cg_item;
|
||||
cg->default_groups[i] = NULL;
|
||||
config_item_put(df_item);
|
||||
}
|
||||
|
||||
config_item_put(item);
|
||||
}
|
||||
|
||||
@@ -1015,9 +1210,11 @@ int target_fabric_setup_cits(struct target_fabric_configfs *tf)
|
||||
{
|
||||
target_fabric_setup_discovery_cit(tf);
|
||||
target_fabric_setup_wwn_cit(tf);
|
||||
target_fabric_setup_wwn_fabric_stats_cit(tf);
|
||||
target_fabric_setup_tpg_cit(tf);
|
||||
target_fabric_setup_tpg_base_cit(tf);
|
||||
target_fabric_setup_tpg_port_cit(tf);
|
||||
target_fabric_setup_tpg_port_stat_cit(tf);
|
||||
target_fabric_setup_tpg_lun_cit(tf);
|
||||
target_fabric_setup_tpg_np_cit(tf);
|
||||
target_fabric_setup_tpg_np_base_cit(tf);
|
||||
@@ -1028,7 +1225,9 @@ int target_fabric_setup_cits(struct target_fabric_configfs *tf)
|
||||
target_fabric_setup_tpg_nacl_attrib_cit(tf);
|
||||
target_fabric_setup_tpg_nacl_auth_cit(tf);
|
||||
target_fabric_setup_tpg_nacl_param_cit(tf);
|
||||
target_fabric_setup_tpg_nacl_stat_cit(tf);
|
||||
target_fabric_setup_tpg_mappedlun_cit(tf);
|
||||
target_fabric_setup_tpg_mappedlun_stat_cit(tf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_device.h>
|
||||
#include <target/target_core_transport.h>
|
||||
#include <target/target_core_fabric_lib.h>
|
||||
#include <target/target_core_fabric_ops.h>
|
||||
#include <target/target_core_configfs.h>
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ static struct se_device *fd_create_virtdevice(
|
||||
mm_segment_t old_fs;
|
||||
struct file *file;
|
||||
struct inode *inode = NULL;
|
||||
int dev_flags = 0, flags;
|
||||
int dev_flags = 0, flags, ret = -EINVAL;
|
||||
|
||||
memset(&dev_limits, 0, sizeof(struct se_dev_limits));
|
||||
|
||||
@@ -146,6 +146,7 @@ static struct se_device *fd_create_virtdevice(
|
||||
if (IS_ERR(dev_p)) {
|
||||
printk(KERN_ERR "getname(%s) failed: %lu\n",
|
||||
fd_dev->fd_dev_name, IS_ERR(dev_p));
|
||||
ret = PTR_ERR(dev_p);
|
||||
goto fail;
|
||||
}
|
||||
#if 0
|
||||
@@ -165,8 +166,12 @@ static struct se_device *fd_create_virtdevice(
|
||||
flags |= O_SYNC;
|
||||
|
||||
file = filp_open(dev_p, flags, 0600);
|
||||
|
||||
if (IS_ERR(file) || !file || !file->f_dentry) {
|
||||
if (IS_ERR(file)) {
|
||||
printk(KERN_ERR "filp_open(%s) failed\n", dev_p);
|
||||
ret = PTR_ERR(file);
|
||||
goto fail;
|
||||
}
|
||||
if (!file || !file->f_dentry) {
|
||||
printk(KERN_ERR "filp_open(%s) failed\n", dev_p);
|
||||
goto fail;
|
||||
}
|
||||
@@ -241,7 +246,7 @@ fail:
|
||||
fd_dev->fd_file = NULL;
|
||||
}
|
||||
putname(dev_p);
|
||||
return NULL;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/* fd_free_device(): (Part of se_subsystem_api_t template)
|
||||
@@ -509,7 +514,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_id=%d"},
|
||||
{Opt_fd_buffered_io, "fd_buffered_io=%d"},
|
||||
{Opt_err, NULL}
|
||||
};
|
||||
|
||||
@@ -536,15 +541,26 @@ static ssize_t fd_set_configfs_dev_params(
|
||||
token = match_token(ptr, tokens, args);
|
||||
switch (token) {
|
||||
case Opt_fd_dev_name:
|
||||
arg_p = match_strdup(&args[0]);
|
||||
if (!arg_p) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
snprintf(fd_dev->fd_dev_name, FD_MAX_DEV_NAME,
|
||||
"%s", match_strdup(&args[0]));
|
||||
"%s", arg_p);
|
||||
kfree(arg_p);
|
||||
printk(KERN_INFO "FILEIO: Referencing Path: %s\n",
|
||||
fd_dev->fd_dev_name);
|
||||
fd_dev->fbd_flags |= FBDF_HAS_PATH;
|
||||
break;
|
||||
case Opt_fd_dev_size:
|
||||
arg_p = match_strdup(&args[0]);
|
||||
if (!arg_p) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
ret = strict_strtoull(arg_p, 0, &fd_dev->fd_dev_size);
|
||||
kfree(arg_p);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "strict_strtoull() failed for"
|
||||
" fd_dev_size=\n");
|
||||
|
||||
@@ -151,19 +151,8 @@ out_free_hba:
|
||||
int
|
||||
core_delete_hba(struct se_hba *hba)
|
||||
{
|
||||
struct se_device *dev, *dev_tmp;
|
||||
|
||||
spin_lock(&hba->device_lock);
|
||||
list_for_each_entry_safe(dev, dev_tmp, &hba->hba_dev_list, dev_list) {
|
||||
|
||||
se_clear_dev_ports(dev);
|
||||
spin_unlock(&hba->device_lock);
|
||||
|
||||
se_release_device_for_hba(dev);
|
||||
|
||||
spin_lock(&hba->device_lock);
|
||||
}
|
||||
spin_unlock(&hba->device_lock);
|
||||
if (!list_empty(&hba->hba_dev_list))
|
||||
dump_stack();
|
||||
|
||||
hba->transport->detach_hba(hba);
|
||||
|
||||
|
||||
@@ -129,10 +129,11 @@ static struct se_device *iblock_create_virtdevice(
|
||||
struct request_queue *q;
|
||||
struct queue_limits *limits;
|
||||
u32 dev_flags = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!(ib_dev)) {
|
||||
printk(KERN_ERR "Unable to locate struct iblock_dev parameter\n");
|
||||
return 0;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
memset(&dev_limits, 0, sizeof(struct se_dev_limits));
|
||||
/*
|
||||
@@ -141,7 +142,7 @@ static struct se_device *iblock_create_virtdevice(
|
||||
ib_dev->ibd_bio_set = bioset_create(32, 64);
|
||||
if (!(ib_dev->ibd_bio_set)) {
|
||||
printk(KERN_ERR "IBLOCK: Unable to create bioset()\n");
|
||||
return 0;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
printk(KERN_INFO "IBLOCK: Created bio_set()\n");
|
||||
/*
|
||||
@@ -153,8 +154,10 @@ static struct se_device *iblock_create_virtdevice(
|
||||
|
||||
bd = blkdev_get_by_path(ib_dev->ibd_udev_path,
|
||||
FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev);
|
||||
if (IS_ERR(bd))
|
||||
if (IS_ERR(bd)) {
|
||||
ret = PTR_ERR(bd);
|
||||
goto failed;
|
||||
}
|
||||
/*
|
||||
* Setup the local scope queue_limits from struct request_queue->limits
|
||||
* to pass into transport_add_device_to_core_hba() as struct se_dev_limits.
|
||||
@@ -184,9 +187,7 @@ static struct se_device *iblock_create_virtdevice(
|
||||
* the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
|
||||
* in ATA and we need to set TPE=1
|
||||
*/
|
||||
if (blk_queue_discard(bdev_get_queue(bd))) {
|
||||
struct request_queue *q = bdev_get_queue(bd);
|
||||
|
||||
if (blk_queue_discard(q)) {
|
||||
DEV_ATTRIB(dev)->max_unmap_lba_count =
|
||||
q->limits.max_discard_sectors;
|
||||
/*
|
||||
@@ -212,7 +213,7 @@ failed:
|
||||
ib_dev->ibd_bd = NULL;
|
||||
ib_dev->ibd_major = 0;
|
||||
ib_dev->ibd_minor = 0;
|
||||
return NULL;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static void iblock_free_device(void *p)
|
||||
@@ -467,7 +468,7 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
|
||||
const char *page, ssize_t count)
|
||||
{
|
||||
struct iblock_dev *ib_dev = se_dev->se_dev_su_ptr;
|
||||
char *orig, *ptr, *opts;
|
||||
char *orig, *ptr, *arg_p, *opts;
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
int ret = 0, arg, token;
|
||||
|
||||
@@ -490,9 +491,14 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN,
|
||||
"%s", match_strdup(&args[0]));
|
||||
arg_p = match_strdup(&args[0]);
|
||||
if (!arg_p) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN,
|
||||
"%s", arg_p);
|
||||
kfree(arg_p);
|
||||
printk(KERN_INFO "IBLOCK: Referencing UDEV path: %s\n",
|
||||
ib_dev->ibd_udev_path);
|
||||
ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH;
|
||||
|
||||
@@ -441,6 +441,7 @@ static struct se_device *pscsi_create_type_disk(
|
||||
struct pscsi_dev_virt *pdv,
|
||||
struct se_subsystem_dev *se_dev,
|
||||
struct se_hba *hba)
|
||||
__releases(sh->host_lock)
|
||||
{
|
||||
struct se_device *dev;
|
||||
struct pscsi_hba_virt *phv = (struct pscsi_hba_virt *)pdv->pdv_se_hba->hba_ptr;
|
||||
@@ -488,6 +489,7 @@ static struct se_device *pscsi_create_type_rom(
|
||||
struct pscsi_dev_virt *pdv,
|
||||
struct se_subsystem_dev *se_dev,
|
||||
struct se_hba *hba)
|
||||
__releases(sh->host_lock)
|
||||
{
|
||||
struct se_device *dev;
|
||||
struct pscsi_hba_virt *phv = (struct pscsi_hba_virt *)pdv->pdv_se_hba->hba_ptr;
|
||||
@@ -522,6 +524,7 @@ static struct se_device *pscsi_create_type_other(
|
||||
struct pscsi_dev_virt *pdv,
|
||||
struct se_subsystem_dev *se_dev,
|
||||
struct se_hba *hba)
|
||||
__releases(sh->host_lock)
|
||||
{
|
||||
struct se_device *dev;
|
||||
struct pscsi_hba_virt *phv = (struct pscsi_hba_virt *)pdv->pdv_se_hba->hba_ptr;
|
||||
@@ -555,7 +558,7 @@ static struct se_device *pscsi_create_virtdevice(
|
||||
if (!(pdv)) {
|
||||
printk(KERN_ERR "Unable to locate struct pscsi_dev_virt"
|
||||
" parameter\n");
|
||||
return NULL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
/*
|
||||
* If not running in PHV_LLD_SCSI_HOST_NO mode, locate the
|
||||
@@ -565,7 +568,7 @@ static struct se_device *pscsi_create_virtdevice(
|
||||
if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) {
|
||||
printk(KERN_ERR "pSCSI: Unable to locate struct"
|
||||
" Scsi_Host for PHV_LLD_SCSI_HOST_NO\n");
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
/*
|
||||
* For the newer PHV_VIRUTAL_HOST_ID struct scsi_device
|
||||
@@ -574,7 +577,7 @@ static struct se_device *pscsi_create_virtdevice(
|
||||
if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) {
|
||||
printk(KERN_ERR "pSCSI: udev_path attribute has not"
|
||||
" been set before ENABLE=1\n");
|
||||
return NULL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
/*
|
||||
* If no scsi_host_id= was passed for PHV_VIRUTAL_HOST_ID,
|
||||
@@ -587,12 +590,12 @@ static struct se_device *pscsi_create_virtdevice(
|
||||
printk(KERN_ERR "pSCSI: Unable to set hba_mode"
|
||||
" with active devices\n");
|
||||
spin_unlock(&hba->device_lock);
|
||||
return NULL;
|
||||
return ERR_PTR(-EEXIST);
|
||||
}
|
||||
spin_unlock(&hba->device_lock);
|
||||
|
||||
if (pscsi_pmode_enable_hba(hba, 1) != 1)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
legacy_mode_enable = 1;
|
||||
hba->hba_flags |= HBA_FLAGS_PSCSI_MODE;
|
||||
@@ -602,14 +605,14 @@ static struct se_device *pscsi_create_virtdevice(
|
||||
if (!(sh)) {
|
||||
printk(KERN_ERR "pSCSI: Unable to locate"
|
||||
" pdv_host_id: %d\n", pdv->pdv_host_id);
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (phv->phv_mode == PHV_VIRUTAL_HOST_ID) {
|
||||
printk(KERN_ERR "pSCSI: PHV_VIRUTAL_HOST_ID set while"
|
||||
" struct Scsi_Host exists\n");
|
||||
return NULL;
|
||||
return ERR_PTR(-EEXIST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,7 +647,7 @@ static struct se_device *pscsi_create_virtdevice(
|
||||
hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
|
||||
}
|
||||
pdv->pdv_sd = NULL;
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
@@ -660,7 +663,7 @@ static struct se_device *pscsi_create_virtdevice(
|
||||
hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
/* pscsi_free_device(): (Part of se_subsystem_api_t template)
|
||||
@@ -816,6 +819,7 @@ pscsi_alloc_task(struct se_cmd *cmd)
|
||||
if (!(pt->pscsi_cdb)) {
|
||||
printk(KERN_ERR "pSCSI: Unable to allocate extended"
|
||||
" pt->pscsi_cdb\n");
|
||||
kfree(pt);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
|
||||
@@ -150,7 +150,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
|
||||
if (rd_dev->rd_page_count <= 0) {
|
||||
printk(KERN_ERR "Illegal page count: %u for Ramdisk device\n",
|
||||
rd_dev->rd_page_count);
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
total_sg_needed = rd_dev->rd_page_count;
|
||||
|
||||
@@ -160,7 +160,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
|
||||
if (!(sg_table)) {
|
||||
printk(KERN_ERR "Unable to allocate memory for Ramdisk"
|
||||
" scatterlist tables\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rd_dev->sg_table_array = sg_table;
|
||||
@@ -175,7 +175,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
|
||||
if (!(sg)) {
|
||||
printk(KERN_ERR "Unable to allocate scatterlist array"
|
||||
" for struct rd_dev\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sg_init_table((struct scatterlist *)&sg[0], sg_per_table);
|
||||
@@ -191,7 +191,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
|
||||
if (!(pg)) {
|
||||
printk(KERN_ERR "Unable to allocate scatterlist"
|
||||
" pages for struct rd_dev_sg_table\n");
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
sg_assign_page(&sg[j], pg);
|
||||
sg[j].length = PAGE_SIZE;
|
||||
@@ -253,12 +253,13 @@ static struct se_device *rd_create_virtdevice(
|
||||
struct se_dev_limits dev_limits;
|
||||
struct rd_dev *rd_dev = p;
|
||||
struct rd_host *rd_host = hba->hba_ptr;
|
||||
int dev_flags = 0;
|
||||
int dev_flags = 0, ret;
|
||||
char prod[16], rev[4];
|
||||
|
||||
memset(&dev_limits, 0, sizeof(struct se_dev_limits));
|
||||
|
||||
if (rd_build_device_space(rd_dev) < 0)
|
||||
ret = rd_build_device_space(rd_dev);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
snprintf(prod, 16, "RAMDISK-%s", (rd_dev->rd_direct) ? "DR" : "MCP");
|
||||
@@ -292,7 +293,7 @@ static struct se_device *rd_create_virtdevice(
|
||||
|
||||
fail:
|
||||
rd_release_device_space(rd_dev);
|
||||
return NULL;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static struct se_device *rd_DIRECT_create_virtdevice(
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#define RD_BLOCKSIZE 512
|
||||
#define RD_MAX_SECTORS 1024
|
||||
|
||||
extern struct kmem_cache *se_mem_cache;
|
||||
|
||||
/* Used in target_core_init_configfs() for virtual LUN 0 access */
|
||||
int __init rd_module_init(void);
|
||||
void rd_module_exit(void);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
#ifndef TARGET_CORE_STAT_H
|
||||
#define TARGET_CORE_STAT_H
|
||||
|
||||
extern void target_stat_setup_dev_default_groups(struct se_subsystem_dev *);
|
||||
extern void target_stat_setup_port_default_groups(struct se_lun *);
|
||||
extern void target_stat_setup_mappedlun_default_groups(struct se_lun_acl *);
|
||||
|
||||
#endif /*** TARGET_CORE_STAT_H ***/
|
||||
@@ -227,8 +227,6 @@ static void transport_remove_cmd_from_queue(struct se_cmd *cmd,
|
||||
static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq);
|
||||
static void transport_stop_all_task_timers(struct se_cmd *cmd);
|
||||
|
||||
int transport_emulate_control_cdb(struct se_task *task);
|
||||
|
||||
int init_se_global(void)
|
||||
{
|
||||
struct se_global *global;
|
||||
@@ -1622,7 +1620,7 @@ struct se_device *transport_add_device_to_core_hba(
|
||||
const char *inquiry_prod,
|
||||
const char *inquiry_rev)
|
||||
{
|
||||
int ret = 0, force_pt;
|
||||
int force_pt;
|
||||
struct se_device *dev;
|
||||
|
||||
dev = kzalloc(sizeof(struct se_device), GFP_KERNEL);
|
||||
@@ -1739,9 +1737,8 @@ struct se_device *transport_add_device_to_core_hba(
|
||||
}
|
||||
scsi_dump_inquiry(dev);
|
||||
|
||||
return dev;
|
||||
out:
|
||||
if (!ret)
|
||||
return dev;
|
||||
kthread_stop(dev->process_thread);
|
||||
|
||||
spin_lock(&hba->device_lock);
|
||||
@@ -4359,11 +4356,9 @@ transport_generic_get_mem(struct se_cmd *cmd, u32 length, u32 dma_size)
|
||||
printk(KERN_ERR "Unable to allocate struct se_mem\n");
|
||||
goto out;
|
||||
}
|
||||
INIT_LIST_HEAD(&se_mem->se_list);
|
||||
se_mem->se_len = (length > dma_size) ? dma_size : length;
|
||||
|
||||
/* #warning FIXME Allocate contigous pages for struct se_mem elements */
|
||||
se_mem->se_page = (struct page *) alloc_pages(GFP_KERNEL, 0);
|
||||
se_mem->se_page = alloc_pages(GFP_KERNEL, 0);
|
||||
if (!(se_mem->se_page)) {
|
||||
printk(KERN_ERR "alloc_pages() failed\n");
|
||||
goto out;
|
||||
@@ -4374,6 +4369,8 @@ transport_generic_get_mem(struct se_cmd *cmd, u32 length, u32 dma_size)
|
||||
printk(KERN_ERR "kmap_atomic() failed\n");
|
||||
goto out;
|
||||
}
|
||||
INIT_LIST_HEAD(&se_mem->se_list);
|
||||
se_mem->se_len = (length > dma_size) ? dma_size : length;
|
||||
memset(buf, 0, se_mem->se_len);
|
||||
kunmap_atomic(buf, KM_IRQ0);
|
||||
|
||||
@@ -4392,10 +4389,13 @@ transport_generic_get_mem(struct se_cmd *cmd, u32 length, u32 dma_size)
|
||||
|
||||
return 0;
|
||||
out:
|
||||
if (se_mem)
|
||||
__free_pages(se_mem->se_page, 0);
|
||||
kmem_cache_free(se_mem_cache, se_mem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern u32 transport_calc_sg_num(
|
||||
u32 transport_calc_sg_num(
|
||||
struct se_task *task,
|
||||
struct se_mem *in_se_mem,
|
||||
u32 task_offset)
|
||||
@@ -5834,31 +5834,26 @@ int transport_generic_do_tmr(struct se_cmd *cmd)
|
||||
int ret;
|
||||
|
||||
switch (tmr->function) {
|
||||
case ABORT_TASK:
|
||||
case TMR_ABORT_TASK:
|
||||
ref_cmd = tmr->ref_cmd;
|
||||
tmr->response = TMR_FUNCTION_REJECTED;
|
||||
break;
|
||||
case ABORT_TASK_SET:
|
||||
case CLEAR_ACA:
|
||||
case CLEAR_TASK_SET:
|
||||
case TMR_ABORT_TASK_SET:
|
||||
case TMR_CLEAR_ACA:
|
||||
case TMR_CLEAR_TASK_SET:
|
||||
tmr->response = TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
|
||||
break;
|
||||
case LUN_RESET:
|
||||
case TMR_LUN_RESET:
|
||||
ret = core_tmr_lun_reset(dev, tmr, NULL, NULL);
|
||||
tmr->response = (!ret) ? TMR_FUNCTION_COMPLETE :
|
||||
TMR_FUNCTION_REJECTED;
|
||||
break;
|
||||
#if 0
|
||||
case TARGET_WARM_RESET:
|
||||
transport_generic_host_reset(dev->se_hba);
|
||||
case TMR_TARGET_WARM_RESET:
|
||||
tmr->response = TMR_FUNCTION_REJECTED;
|
||||
break;
|
||||
case TARGET_COLD_RESET:
|
||||
transport_generic_host_reset(dev->se_hba);
|
||||
transport_generic_cold_reset(dev->se_hba);
|
||||
case TMR_TARGET_COLD_RESET:
|
||||
tmr->response = TMR_FUNCTION_REJECTED;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printk(KERN_ERR "Uknown TMR function: 0x%02x.\n",
|
||||
tmr->function);
|
||||
|
||||
Reference in New Issue
Block a user