提交 a2640111 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] qla2xxx: Return DID_NO_CONNECT when FC device is lost.
  [SCSI] mptfusion: Bump version 03.04.18
  [SCSI] mptfusion: Fix Incorrect return value in mptscsih_dev_reset
  [SCSI] mptfusion: mptctl_release is required in mptctl.c
  [SCSI] target: fix use after free detected by SLUB poison
  [SCSI] target: Remove procfs based target_core_mib.c code
  [SCSI] target: Fix SCF_SCSI_CONTROL_SG_IO_CDB breakage
  [SCSI] target: Fix top-level configfs_subsystem default_group shutdown breakage
  [SCSI] target: fixed missing lock drop in error path
  [SCSI] target: Fix demo-mode MappedLUN shutdown UA/PR breakage
  [SCSI] target/iblock: Fix failed bd claim NULL pointer dereference
  [SCSI] target: iblock/pscsi claim checking for NULL instead of IS_ERR
  [SCSI] scsi_debug: Fix 32-bit overflow in do_device_access causing memory corruption
  [SCSI] qla2xxx: Change from irq to irqsave with host_lock
  [SCSI] qla2xxx: Fix race that could hang kthread_stop()
...@@ -76,8 +76,8 @@ ...@@ -76,8 +76,8 @@
#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "3.04.17" #define MPT_LINUX_VERSION_COMMON "3.04.18"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.17" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.18"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
......
...@@ -596,6 +596,13 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -596,6 +596,13 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
return 1; return 1;
} }
static int
mptctl_release(struct inode *inode, struct file *filep)
{
fasync_helper(-1, filep, 0, &async_queue);
return 0;
}
static int static int
mptctl_fasync(int fd, struct file *filep, int mode) mptctl_fasync(int fd, struct file *filep, int mode)
{ {
...@@ -2815,6 +2822,7 @@ static const struct file_operations mptctl_fops = { ...@@ -2815,6 +2822,7 @@ static const struct file_operations mptctl_fops = {
.llseek = no_llseek, .llseek = no_llseek,
.fasync = mptctl_fasync, .fasync = mptctl_fasync,
.unlocked_ioctl = mptctl_ioctl, .unlocked_ioctl = mptctl_ioctl,
.release = mptctl_release,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = compat_mpctl_ioctl, .compat_ioctl = compat_mpctl_ioctl,
#endif #endif
......
...@@ -1873,8 +1873,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -1873,8 +1873,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
} }
out: out:
printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n", printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p) (sn=%ld)\n",
ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), SCpnt); ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
SCpnt, SCpnt->serial_number);
return retval; return retval;
} }
...@@ -1911,7 +1912,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) ...@@ -1911,7 +1912,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
vdevice = SCpnt->device->hostdata; vdevice = SCpnt->device->hostdata;
if (!vdevice || !vdevice->vtarget) { if (!vdevice || !vdevice->vtarget) {
retval = SUCCESS; retval = 0;
goto out; goto out;
} }
......
...@@ -1561,6 +1561,7 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) ...@@ -1561,6 +1561,7 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
{ {
struct Scsi_Host *host = rport_to_shost(rport); struct Scsi_Host *host = rport_to_shost(rport);
fc_port_t *fcport = *(fc_port_t **)rport->dd_data; fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
unsigned long flags;
if (!fcport) if (!fcport)
return; return;
...@@ -1573,10 +1574,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) ...@@ -1573,10 +1574,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
* Transport has effectively 'deleted' the rport, clear * Transport has effectively 'deleted' the rport, clear
* all local references. * all local references.
*/ */
spin_lock_irq(host->host_lock); spin_lock_irqsave(host->host_lock, flags);
fcport->rport = fcport->drport = NULL; fcport->rport = fcport->drport = NULL;
*((fc_port_t **)rport->dd_data) = NULL; *((fc_port_t **)rport->dd_data) = NULL;
spin_unlock_irq(host->host_lock); spin_unlock_irqrestore(host->host_lock, flags);
if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
return; return;
......
...@@ -2505,11 +2505,12 @@ qla2x00_rport_del(void *data) ...@@ -2505,11 +2505,12 @@ qla2x00_rport_del(void *data)
{ {
fc_port_t *fcport = data; fc_port_t *fcport = data;
struct fc_rport *rport; struct fc_rport *rport;
unsigned long flags;
spin_lock_irq(fcport->vha->host->host_lock); spin_lock_irqsave(fcport->vha->host->host_lock, flags);
rport = fcport->drport ? fcport->drport: fcport->rport; rport = fcport->drport ? fcport->drport: fcport->rport;
fcport->drport = NULL; fcport->drport = NULL;
spin_unlock_irq(fcport->vha->host->host_lock); spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
if (rport) if (rport)
fc_remote_port_delete(rport); fc_remote_port_delete(rport);
} }
...@@ -2879,6 +2880,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) ...@@ -2879,6 +2880,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
struct fc_rport_identifiers rport_ids; struct fc_rport_identifiers rport_ids;
struct fc_rport *rport; struct fc_rport *rport;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
unsigned long flags;
qla2x00_rport_del(fcport); qla2x00_rport_del(fcport);
...@@ -2893,9 +2895,9 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) ...@@ -2893,9 +2895,9 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
"Unable to allocate fc remote port!\n"); "Unable to allocate fc remote port!\n");
return; return;
} }
spin_lock_irq(fcport->vha->host->host_lock); spin_lock_irqsave(fcport->vha->host->host_lock, flags);
*((fc_port_t **)rport->dd_data) = fcport; *((fc_port_t **)rport->dd_data) = fcport;
spin_unlock_irq(fcport->vha->host->host_lock); spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
rport->supported_classes = fcport->supported_classes; rport->supported_classes = fcport->supported_classes;
......
...@@ -562,7 +562,6 @@ qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *) ...@@ -562,7 +562,6 @@ qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)
} }
if (atomic_read(&fcport->state) != FCS_ONLINE) { if (atomic_read(&fcport->state) != FCS_ONLINE) {
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
atomic_read(&fcport->state) == FCS_DEVICE_LOST ||
atomic_read(&base_vha->loop_state) == LOOP_DEAD) { atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
cmd->result = DID_NO_CONNECT << 16; cmd->result = DID_NO_CONNECT << 16;
goto qc24_fail_command; goto qc24_fail_command;
...@@ -2513,6 +2512,7 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -2513,6 +2512,7 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
{ {
struct fc_rport *rport; struct fc_rport *rport;
scsi_qla_host_t *base_vha; scsi_qla_host_t *base_vha;
unsigned long flags;
if (!fcport->rport) if (!fcport->rport)
return; return;
...@@ -2520,9 +2520,9 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -2520,9 +2520,9 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
rport = fcport->rport; rport = fcport->rport;
if (defer) { if (defer) {
base_vha = pci_get_drvdata(vha->hw->pdev); base_vha = pci_get_drvdata(vha->hw->pdev);
spin_lock_irq(vha->host->host_lock); spin_lock_irqsave(vha->host->host_lock, flags);
fcport->drport = rport; fcport->drport = rport;
spin_unlock_irq(vha->host->host_lock); spin_unlock_irqrestore(vha->host->host_lock, flags);
set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
qla2xxx_wake_dpc(base_vha); qla2xxx_wake_dpc(base_vha);
} else } else
...@@ -3282,10 +3282,10 @@ qla2x00_do_dpc(void *data) ...@@ -3282,10 +3282,10 @@ qla2x00_do_dpc(void *data)
set_user_nice(current, -20); set_user_nice(current, -20);
set_current_state(TASK_INTERRUPTIBLE);
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
DEBUG3(printk("qla2x00: DPC handler sleeping\n")); DEBUG3(printk("qla2x00: DPC handler sleeping\n"));
set_current_state(TASK_INTERRUPTIBLE);
schedule(); schedule();
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
...@@ -3454,7 +3454,9 @@ qla2x00_do_dpc(void *data) ...@@ -3454,7 +3454,9 @@ qla2x00_do_dpc(void *data)
qla2x00_do_dpc_all_vps(base_vha); qla2x00_do_dpc_all_vps(base_vha);
ha->dpc_active = 0; ha->dpc_active = 0;
set_current_state(TASK_INTERRUPTIBLE);
} /* End of while(1) */ } /* End of while(1) */
__set_current_state(TASK_RUNNING);
DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no)); DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no));
......
...@@ -1671,7 +1671,7 @@ static int do_device_access(struct scsi_cmnd *scmd, ...@@ -1671,7 +1671,7 @@ static int do_device_access(struct scsi_cmnd *scmd,
unsigned long long lba, unsigned int num, int write) unsigned long long lba, unsigned int num, int write)
{ {
int ret; int ret;
unsigned int block, rest = 0; unsigned long long block, rest = 0;
int (*func)(struct scsi_cmnd *, unsigned char *, int); int (*func)(struct scsi_cmnd *, unsigned char *, int);
func = write ? fetch_to_dev_buffer : fill_from_dev_buffer; func = write ? fetch_to_dev_buffer : fill_from_dev_buffer;
......
...@@ -13,8 +13,7 @@ target_core_mod-y := target_core_configfs.o \ ...@@ -13,8 +13,7 @@ target_core_mod-y := target_core_configfs.o \
target_core_transport.o \ target_core_transport.o \
target_core_cdb.o \ target_core_cdb.o \
target_core_ua.o \ target_core_ua.o \
target_core_rd.o \ target_core_rd.o
target_core_mib.o
obj-$(CONFIG_TARGET_CORE) += target_core_mod.o obj-$(CONFIG_TARGET_CORE) += target_core_mod.o
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/configfs.h> #include <linux/configfs.h>
#include <linux/proc_fs.h>
#include <target/target_core_base.h> #include <target/target_core_base.h>
#include <target/target_core_device.h> #include <target/target_core_device.h>
...@@ -1971,13 +1970,35 @@ static void target_core_dev_release(struct config_item *item) ...@@ -1971,13 +1970,35 @@ static void target_core_dev_release(struct config_item *item)
{ {
struct se_subsystem_dev *se_dev = container_of(to_config_group(item), struct se_subsystem_dev *se_dev = container_of(to_config_group(item),
struct se_subsystem_dev, se_dev_group); struct se_subsystem_dev, se_dev_group);
struct config_group *dev_cg; struct se_hba *hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item);
struct se_subsystem_api *t = hba->transport;
if (!(se_dev)) struct config_group *dev_cg = &se_dev->se_dev_group;
return;
dev_cg = &se_dev->se_dev_group;
kfree(dev_cg->default_groups); kfree(dev_cg->default_groups);
/*
* This pointer will set when the storage is enabled with:
*`echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable`
*/
if (se_dev->se_dev_ptr) {
printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_"
"virtual_device() for se_dev_ptr: %p\n",
se_dev->se_dev_ptr);
se_free_virtual_device(se_dev->se_dev_ptr, hba);
} else {
/*
* Release struct se_subsystem_dev->se_dev_su_ptr..
*/
printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_"
"device() for se_dev_su_ptr: %p\n",
se_dev->se_dev_su_ptr);
t->free_device(se_dev->se_dev_su_ptr);
}
printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem"
"_dev_t: %p\n", se_dev);
kfree(se_dev);
} }
static ssize_t target_core_dev_show(struct config_item *item, static ssize_t target_core_dev_show(struct config_item *item,
...@@ -2140,7 +2161,16 @@ static struct configfs_attribute *target_core_alua_lu_gp_attrs[] = { ...@@ -2140,7 +2161,16 @@ static struct configfs_attribute *target_core_alua_lu_gp_attrs[] = {
NULL, NULL,
}; };
static void target_core_alua_lu_gp_release(struct config_item *item)
{
struct t10_alua_lu_gp *lu_gp = container_of(to_config_group(item),
struct t10_alua_lu_gp, lu_gp_group);
core_alua_free_lu_gp(lu_gp);
}
static struct configfs_item_operations target_core_alua_lu_gp_ops = { static struct configfs_item_operations target_core_alua_lu_gp_ops = {
.release = target_core_alua_lu_gp_release,
.show_attribute = target_core_alua_lu_gp_attr_show, .show_attribute = target_core_alua_lu_gp_attr_show,
.store_attribute = target_core_alua_lu_gp_attr_store, .store_attribute = target_core_alua_lu_gp_attr_store,
}; };
...@@ -2191,9 +2221,11 @@ static void target_core_alua_drop_lu_gp( ...@@ -2191,9 +2221,11 @@ static void target_core_alua_drop_lu_gp(
printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Logical Unit" printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Logical Unit"
" Group: core/alua/lu_gps/%s, ID: %hu\n", " Group: core/alua/lu_gps/%s, ID: %hu\n",
config_item_name(item), lu_gp->lu_gp_id); config_item_name(item), lu_gp->lu_gp_id);
/*
* core_alua_free_lu_gp() is called from target_core_alua_lu_gp_ops->release()
* -> target_core_alua_lu_gp_release()
*/
config_item_put(item); config_item_put(item);
core_alua_free_lu_gp(lu_gp);
} }
static struct configfs_group_operations target_core_alua_lu_gps_group_ops = { static struct configfs_group_operations target_core_alua_lu_gps_group_ops = {
...@@ -2549,7 +2581,16 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = { ...@@ -2549,7 +2581,16 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
NULL, NULL,
}; };
static void target_core_alua_tg_pt_gp_release(struct config_item *item)
{
struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(to_config_group(item),
struct t10_alua_tg_pt_gp, tg_pt_gp_group);
core_alua_free_tg_pt_gp(tg_pt_gp);
}
static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = { static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = {
.release = target_core_alua_tg_pt_gp_release,
.show_attribute = target_core_alua_tg_pt_gp_attr_show, .show_attribute = target_core_alua_tg_pt_gp_attr_show,
.store_attribute = target_core_alua_tg_pt_gp_attr_store, .store_attribute = target_core_alua_tg_pt_gp_attr_store,
}; };
...@@ -2602,9 +2643,11 @@ static void target_core_alua_drop_tg_pt_gp( ...@@ -2602,9 +2643,11 @@ static void target_core_alua_drop_tg_pt_gp(
printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port" printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port"
" Group: alua/tg_pt_gps/%s, ID: %hu\n", " Group: alua/tg_pt_gps/%s, ID: %hu\n",
config_item_name(item), tg_pt_gp->tg_pt_gp_id); config_item_name(item), tg_pt_gp->tg_pt_gp_id);
/*
* core_alua_free_tg_pt_gp() is called from target_core_alua_tg_pt_gp_ops->release()
* -> target_core_alua_tg_pt_gp_release().
*/
config_item_put(item); config_item_put(item);
core_alua_free_tg_pt_gp(tg_pt_gp);
} }
static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = { static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = {
...@@ -2771,13 +2814,11 @@ static void target_core_drop_subdev( ...@@ -2771,13 +2814,11 @@ static void target_core_drop_subdev(
struct se_subsystem_api *t; struct se_subsystem_api *t;
struct config_item *df_item; struct config_item *df_item;
struct config_group *dev_cg, *tg_pt_gp_cg; struct config_group *dev_cg, *tg_pt_gp_cg;
int i, ret; int i;
hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item);
if (mutex_lock_interruptible(&hba->hba_access_mutex)) mutex_lock(&hba->hba_access_mutex);
goto out;
t = hba->transport; t = hba->transport;
spin_lock(&se_global->g_device_lock); spin_lock(&se_global->g_device_lock);
...@@ -2791,7 +2832,10 @@ static void target_core_drop_subdev( ...@@ -2791,7 +2832,10 @@ static void target_core_drop_subdev(
config_item_put(df_item); config_item_put(df_item);
} }
kfree(tg_pt_gp_cg->default_groups); kfree(tg_pt_gp_cg->default_groups);
core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp); /*
* core_alua_free_tg_pt_gp() is called from ->default_tg_pt_gp
* directly from target_core_alua_tg_pt_gp_release().
*/
T10_ALUA(se_dev)->default_tg_pt_gp = NULL; T10_ALUA(se_dev)->default_tg_pt_gp = NULL;
dev_cg = &se_dev->se_dev_group; dev_cg = &se_dev->se_dev_group;
...@@ -2800,38 +2844,12 @@ static void target_core_drop_subdev( ...@@ -2800,38 +2844,12 @@ static void target_core_drop_subdev(
dev_cg->default_groups[i] = NULL; dev_cg->default_groups[i] = NULL;
config_item_put(df_item); config_item_put(df_item);
} }
config_item_put(item);
/* /*
* This pointer will set when the storage is enabled with: * The releasing of se_dev and associated se_dev->se_dev_ptr is done
* `echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` * from target_core_dev_item_ops->release() ->target_core_dev_release().
*/ */
if (se_dev->se_dev_ptr) { config_item_put(item);
printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_"
"virtual_device() for se_dev_ptr: %p\n",
se_dev->se_dev_ptr);
ret = se_free_virtual_device(se_dev->se_dev_ptr, hba);
if (ret < 0)
goto hba_out;
} else {
/*
* Release struct se_subsystem_dev->se_dev_su_ptr..
*/
printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_"
"device() for se_dev_su_ptr: %p\n",
se_dev->se_dev_su_ptr);
t->free_device(se_dev->se_dev_su_ptr);
}
printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem"
"_dev_t: %p\n", se_dev);
hba_out:
mutex_unlock(&hba->hba_access_mutex); mutex_unlock(&hba->hba_access_mutex);
out:
kfree(se_dev);
} }
static struct configfs_group_operations target_core_hba_group_ops = { static struct configfs_group_operations target_core_hba_group_ops = {
...@@ -2914,6 +2932,13 @@ SE_HBA_ATTR(hba_mode, S_IRUGO | S_IWUSR); ...@@ -2914,6 +2932,13 @@ SE_HBA_ATTR(hba_mode, S_IRUGO | S_IWUSR);
CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group); CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group);
static void target_core_hba_release(struct config_item *item)
{
struct se_hba *hba = container_of(to_config_group(item),
struct se_hba, hba_group);
core_delete_hba(hba);
}
static struct configfs_attribute *target_core_hba_attrs[] = { static struct configfs_attribute *target_core_hba_attrs[] = {
&target_core_hba_hba_info.attr, &target_core_hba_hba_info.attr,
&target_core_hba_hba_mode.attr, &target_core_hba_hba_mode.attr,
...@@ -2921,6 +2946,7 @@ static struct configfs_attribute *target_core_hba_attrs[] = { ...@@ -2921,6 +2946,7 @@ static struct configfs_attribute *target_core_hba_attrs[] = {
}; };
static struct configfs_item_operations target_core_hba_item_ops = { static struct configfs_item_operations target_core_hba_item_ops = {
.release = target_core_hba_release,
.show_attribute = target_core_hba_attr_show, .show_attribute = target_core_hba_attr_show,
.store_attribute = target_core_hba_attr_store, .store_attribute = target_core_hba_attr_store,
}; };
...@@ -2997,10 +3023,11 @@ static void target_core_call_delhbafromtarget( ...@@ -2997,10 +3023,11 @@ static void target_core_call_delhbafromtarget(
struct config_group *group, struct config_group *group,
struct config_item *item) struct config_item *item)
{ {
struct se_hba *hba = item_to_hba(item); /*
* core_delete_hba() is called from target_core_hba_item_ops->release()
* -> target_core_hba_release()
*/
config_item_put(item); config_item_put(item);
core_delete_hba(hba);
} }
static struct configfs_group_operations target_core_group_ops = { static struct configfs_group_operations target_core_group_ops = {
...@@ -3022,7 +3049,6 @@ static int target_core_init_configfs(void) ...@@ -3022,7 +3049,6 @@ static int target_core_init_configfs(void)
struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL;
struct config_group *lu_gp_cg = NULL; struct config_group *lu_gp_cg = NULL;
struct configfs_subsystem *subsys; struct configfs_subsystem *subsys;
struct proc_dir_entry *scsi_target_proc = NULL;
struct t10_alua_lu_gp *lu_gp; struct t10_alua_lu_gp *lu_gp;
int ret; int ret;
...@@ -3128,21 +3154,10 @@ static int target_core_init_configfs(void) ...@@ -3128,21 +3154,10 @@ static int target_core_init_configfs(void)
if (core_dev_setup_virtual_lun0() < 0) if (core_dev_setup_virtual_lun0() < 0)
goto out; goto out;
scsi_target_proc = proc_mkdir("scsi_target", 0);
if (!(scsi_target_proc)) {
printk(KERN_ERR "proc_mkdir(scsi_target, 0) failed\n");
goto out;
}
ret = init_scsi_target_mib();
if (ret < 0)
goto out;
return 0; return 0;
out: out:
configfs_unregister_subsystem(subsys); configfs_unregister_subsystem(subsys);
if (scsi_target_proc)
remove_proc_entry("scsi_target", 0);
core_dev_release_virtual_lun0(); core_dev_release_virtual_lun0();
rd_module_exit(); rd_module_exit();
out_global: out_global:
...@@ -3178,8 +3193,7 @@ static void target_core_exit_configfs(void) ...@@ -3178,8 +3193,7 @@ static void target_core_exit_configfs(void)
config_item_put(item); config_item_put(item);
} }
kfree(lu_gp_cg->default_groups); kfree(lu_gp_cg->default_groups);
core_alua_free_lu_gp(se_global->default_lu_gp); lu_gp_cg->default_groups = NULL;
se_global->default_lu_gp = NULL;
alua_cg = &se_global->alua_group; alua_cg = &se_global->alua_group;
for (i = 0; alua_cg->default_groups[i]; i++) { for (i = 0; alua_cg->default_groups[i]; i++) {
...@@ -3188,6 +3202,7 @@ static void target_core_exit_configfs(void) ...@@ -3188,6 +3202,7 @@ static void target_core_exit_configfs(void)
config_item_put(item); config_item_put(item);
} }
kfree(alua_cg->default_groups); kfree(alua_cg->default_groups);
alua_cg->default_groups = NULL;
hba_cg = &se_global->target_core_hbagroup; hba_cg = &se_global->target_core_hbagroup;
for (i = 0; hba_cg->default_groups[i]; i++) { for (i = 0; hba_cg->default_groups[i]; i++) {
...@@ -3196,20 +3211,20 @@ static void target_core_exit_configfs(void) ...@@ -3196,20 +3211,20 @@ static void target_core_exit_configfs(void)
config_item_put(item); config_item_put(item);
} }
kfree(hba_cg->default_groups); kfree(hba_cg->default_groups);
hba_cg->default_groups = NULL;
for (i = 0; subsys->su_group.default_groups[i]; i++) { /*
item = &subsys->su_group.default_groups[i]->cg_item; * We expect subsys->su_group.default_groups to be released
subsys->su_group.default_groups[i] = NULL; * by configfs subsystem provider logic..
config_item_put(item); */
} configfs_unregister_subsystem(subsys);
kfree(subsys->su_group.default_groups); kfree(subsys->su_group.default_groups);
configfs_unregister_subsystem(subsys); core_alua_free_lu_gp(se_global->default_lu_gp);
se_global->default_lu_gp = NULL;
printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric" printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric"
" Infrastructure\n"); " Infrastructure\n");
remove_scsi_target_mib();
remove_proc_entry("scsi_target", 0);
core_dev_release_virtual_lun0(); core_dev_release_virtual_lun0();
rd_module_exit(); rd_module_exit();
release_se_global(); release_se_global();
......
...@@ -373,11 +373,11 @@ int core_update_device_list_for_node( ...@@ -373,11 +373,11 @@ int core_update_device_list_for_node(
/* /*
* deve->se_lun_acl will be NULL for demo-mode created LUNs * deve->se_lun_acl will be NULL for demo-mode created LUNs
* that have not been explictly concerted to MappedLUNs -> * that have not been explictly concerted to MappedLUNs ->
* struct se_lun_acl. * struct se_lun_acl, but we remove deve->alua_port_list from
* port->sep_alua_list. This also means that active UAs and
* NodeACL context specific PR metadata for demo-mode
* MappedLUN *deve will be released below..
*/ */
if (!(deve->se_lun_acl))
return 0;
spin_lock_bh(&port->sep_alua_lock); spin_lock_bh(&port->sep_alua_lock);
list_del(&deve->alua_port_list); list_del(&deve->alua_port_list);
spin_unlock_bh(&port->sep_alua_lock); spin_unlock_bh(&port->sep_alua_lock);
...@@ -395,12 +395,14 @@ int core_update_device_list_for_node( ...@@ -395,12 +395,14 @@ int core_update_device_list_for_node(
printk(KERN_ERR "struct se_dev_entry->se_lun_acl" printk(KERN_ERR "struct se_dev_entry->se_lun_acl"
" already set for demo mode -> explict" " already set for demo mode -> explict"
" LUN ACL transition\n"); " LUN ACL transition\n");
spin_unlock_irq(&nacl->device_list_lock);
return -1; return -1;
} }
if (deve->se_lun != lun) { if (deve->se_lun != lun) {
printk(KERN_ERR "struct se_dev_entry->se_lun does" printk(KERN_ERR "struct se_dev_entry->se_lun does"
" match passed struct se_lun for demo mode" " match passed struct se_lun for demo mode"
" -> explict LUN ACL transition\n"); " -> explict LUN ACL transition\n");
spin_unlock_irq(&nacl->device_list_lock);
return -1; return -1;
} }
deve->se_lun_acl = lun_acl; deve->se_lun_acl = lun_acl;
...@@ -865,9 +867,6 @@ static void se_dev_stop(struct se_device *dev) ...@@ -865,9 +867,6 @@ static void se_dev_stop(struct se_device *dev)
} }
} }
spin_unlock(&hba->device_lock); spin_unlock(&hba->device_lock);
while (atomic_read(&hba->dev_mib_access_count))
cpu_relax();
} }
int se_dev_check_online(struct se_device *dev) int se_dev_check_online(struct se_device *dev)
......
...@@ -214,12 +214,22 @@ TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR); ...@@ -214,12 +214,22 @@ TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR);
CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group); CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group);
static void target_fabric_mappedlun_release(struct config_item *item)
{
struct se_lun_acl *lacl = container_of(to_config_group(item),
struct se_lun_acl, se_lun_group);
struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg;
core_dev_free_initiator_node_lun_acl(se_tpg, lacl);
}
static struct configfs_attribute *target_fabric_mappedlun_attrs[] = { static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
&target_fabric_mappedlun_write_protect.attr, &target_fabric_mappedlun_write_protect.attr,
NULL, NULL,
}; };
static struct configfs_item_operations target_fabric_mappedlun_item_ops = { static struct configfs_item_operations target_fabric_mappedlun_item_ops = {
.release = target_fabric_mappedlun_release,
.show_attribute = target_fabric_mappedlun_attr_show, .show_attribute = target_fabric_mappedlun_attr_show,
.store_attribute = target_fabric_mappedlun_attr_store, .store_attribute = target_fabric_mappedlun_attr_store,
.allow_link = target_fabric_mappedlun_link, .allow_link = target_fabric_mappedlun_link,
...@@ -337,15 +347,21 @@ static void target_fabric_drop_mappedlun( ...@@ -337,15 +347,21 @@ static void target_fabric_drop_mappedlun(
struct config_group *group, struct config_group *group,
struct config_item *item) struct config_item *item)
{ {
struct se_lun_acl *lacl = container_of(to_config_group(item),
struct se_lun_acl, se_lun_group);
struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg;
config_item_put(item); config_item_put(item);
core_dev_free_initiator_node_lun_acl(se_tpg, lacl); }
static void target_fabric_nacl_base_release(struct config_item *item)
{
struct se_node_acl *se_nacl = container_of(to_config_group(item),
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;
tf->tf_ops.fabric_drop_nodeacl(se_nacl);
} }
static struct configfs_item_operations target_fabric_nacl_base_item_ops = { static struct configfs_item_operations target_fabric_nacl_base_item_ops = {
.release = target_fabric_nacl_base_release,
.show_attribute = target_fabric_nacl_base_attr_show, .show_attribute = target_fabric_nacl_base_attr_show,
.store_attribute = target_fabric_nacl_base_attr_store, .store_attribute = target_fabric_nacl_base_attr_store,
}; };
...@@ -404,9 +420,6 @@ static void target_fabric_drop_nodeacl( ...@@ -404,9 +420,6 @@ static void target_fabric_drop_nodeacl(
struct config_group *group, struct config_group *group,
struct config_item *item) struct config_item *item)
{ {
struct se_portal_group *se_tpg = container_of(group,
struct se_portal_group, tpg_acl_group);
struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
struct se_node_acl *se_nacl = container_of(to_config_group(item), struct se_node_acl *se_nacl = container_of(to_config_group(item),
struct se_node_acl, acl_group); struct se_node_acl, acl_group);
struct config_item *df_item; struct config_item *df_item;
...@@ -419,9 +432,10 @@ static void target_fabric_drop_nodeacl( ...@@ -419,9 +432,10 @@ static void target_fabric_drop_nodeacl(
nacl_cg->default_groups[i] = NULL; nacl_cg->default_groups[i] = NULL;
config_item_put(df_item); config_item_put(df_item);
} }
/*
* struct se_node_acl free is done in target_fabric_nacl_base_release()
*/
config_item_put(item); config_item_put(item);
tf->tf_ops.fabric_drop_nodeacl(se_nacl);
} }
static struct configfs_group_operations target_fabric_nacl_group_ops = { static struct configfs_group_operations target_fabric_nacl_group_ops = {
...@@ -437,7 +451,18 @@ TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL); ...@@ -437,7 +451,18 @@ TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL);
CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group); CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group);
static void target_fabric_np_base_release(struct config_item *item)
{
struct se_tpg_np *se_tpg_np = container_of(to_config_group(item),
struct se_tpg_np, tpg_np_group);
struct se_portal_group *se_tpg = se_tpg_np->tpg_np_parent;
struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
tf->tf_ops.fabric_drop_np(se_tpg_np);
}
static struct configfs_item_operations target_fabric_np_base_item_ops = { static struct configfs_item_operations target_fabric_np_base_item_ops = {
.release = target_fabric_np_base_release,
.show_attribute = target_fabric_np_base_attr_show, .show_attribute = target_fabric_np_base_attr_show,
.store_attribute = target_fabric_np_base_attr_store, .store_attribute = target_fabric_np_base_attr_store,
}; };
...@@ -466,6 +491,7 @@ static struct config_group *target_fabric_make_np( ...@@ -466,6 +491,7 @@ static struct config_group *target_fabric_make_np(
if (!(se_tpg_np) || IS_ERR(se_tpg_np)) if (!(se_tpg_np) || IS_ERR(se_tpg_np))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
se_tpg_np->tpg_np_parent = se_tpg;
config_group_init_type_name(&se_tpg_np->tpg_np_group, name, config_group_init_type_name(&se_tpg_np->tpg_np_group, name,
&TF_CIT_TMPL(tf)->tfc_tpg_np_base_cit); &TF_CIT_TMPL(tf)->tfc_tpg_np_base_cit);
...@@ -476,14 +502,10 @@ static void target_fabric_drop_np( ...@@ -476,14 +502,10 @@ static void target_fabric_drop_np(
struct config_group *group, struct config_group *group,
struct config_item *item) struct config_item *item)
{ {
struct se_portal_group *se_tpg = container_of(group, /*
struct se_portal_group, tpg_np_group); * struct se_tpg_np is released via target_fabric_np_base_release()
struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; */
struct se_tpg_np *se_tpg_np = container_of(to_config_group(item),
struct se_tpg_np, tpg_np_group);
config_item_put(item); config_item_put(item);
tf->tf_ops.fabric_drop_np(se_tpg_np);
} }
static struct configfs_group_operations target_fabric_np_group_ops = { static struct configfs_group_operations target_fabric_np_group_ops = {
...@@ -814,7 +836,18 @@ TF_CIT_SETUP(tpg_param, &target_fabric_tpg_param_item_ops, NULL, NULL); ...@@ -814,7 +836,18 @@ TF_CIT_SETUP(tpg_param, &target_fabric_tpg_param_item_ops, NULL, NULL);
*/ */
CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group); CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group);
static void target_fabric_tpg_release(struct config_item *item)
{
struct se_portal_group *se_tpg = container_of(to_config_group(item),
struct se_portal_group, tpg_group);
struct se_wwn *wwn = se_tpg->se_tpg_wwn;
struct target_fabric_configfs *tf = wwn->wwn_tf;
tf->tf_ops.fabric_drop_tpg(se_tpg);
}
static struct configfs_item_operations target_fabric_tpg_base_item_ops = { static struct configfs_item_operations target_fabric_tpg_base_item_ops = {
.release = target_fabric_tpg_release,
.show_attribute = target_fabric_tpg_attr_show, .show_attribute = target_fabric_tpg_attr_show,
.store_attribute = target_fabric_tpg_attr_store, .store_attribute = target_fabric_tpg_attr_store,
}; };
...@@ -872,8 +905,6 @@ static void target_fabric_drop_tpg( ...@@ -872,8 +905,6 @@ static void target_fabric_drop_tpg(
struct config_group *group, struct config_group *group,
struct config_item *item) struct config_item *item)
{ {
struct se_wwn *wwn = container_of(group, struct se_wwn, wwn_group);
struct target_fabric_configfs *tf = wwn->wwn_tf;
struct se_portal_group *se_tpg = container_of(to_config_group(item), struct se_portal_group *se_tpg = container_of(to_config_group(item),
struct se_portal_group, tpg_group); struct se_portal_group, tpg_group);
struct config_group *tpg_cg = &se_tpg->tpg_group; struct config_group *tpg_cg = &se_tpg->tpg_group;
...@@ -890,15 +921,28 @@ static void target_fabric_drop_tpg( ...@@ -890,15 +921,28 @@ static void target_fabric_drop_tpg(
} }
config_item_put(item); config_item_put(item);
tf->tf_ops.fabric_drop_tpg(se_tpg);
} }
static void target_fabric_release_wwn(struct config_item *item)
{
struct se_wwn *wwn = container_of(to_config_group(item),
struct se_wwn, wwn_group);
struct target_fabric_configfs *tf = wwn->wwn_tf;
tf->tf_ops.fabric_drop_wwn(wwn);
}
static struct configfs_item_operations target_fabric_tpg_item_ops = {
.release = target_fabric_release_wwn,
};
static struct configfs_group_operations target_fabric_tpg_group_ops = { static struct configfs_group_operations target_fabric_tpg_group_ops = {
.make_group = target_fabric_make_tpg, .make_group = target_fabric_make_tpg,
.drop_item = target_fabric_drop_tpg, .drop_item = target_fabric_drop_tpg,
}; };
TF_CIT_SETUP(tpg, NULL, &target_fabric_tpg_group_ops, NULL); TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops,
NULL);
/* End of tfc_tpg_cit */ /* End of tfc_tpg_cit */
...@@ -932,13 +976,7 @@ static void target_fabric_drop_wwn( ...@@ -932,13 +976,7 @@ static void target_fabric_drop_wwn(
struct config_group *group, struct config_group *group,
struct config_item *item) struct config_item *item)
{ {
struct target_fabric_configfs *tf = container_of(group,
struct target_fabric_configfs, tf_group);
struct se_wwn *wwn = container_of(to_config_group(item),
struct se_wwn, wwn_group);
config_item_put(item); config_item_put(item);
tf->tf_ops.fabric_drop_wwn(wwn);
} }
static struct configfs_group_operations target_fabric_wwn_group_ops = { static struct configfs_group_operations target_fabric_wwn_group_ops = {
......
...@@ -154,7 +154,7 @@ static struct se_device *iblock_create_virtdevice( ...@@ -154,7 +154,7 @@ static struct se_device *iblock_create_virtdevice(
bd = blkdev_get_by_path(ib_dev->ibd_udev_path, bd = blkdev_get_by_path(ib_dev->ibd_udev_path,
FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev);
if (!(bd)) if (IS_ERR(bd))
goto failed; goto failed;
/* /*
* Setup the local scope queue_limits from struct request_queue->limits * Setup the local scope queue_limits from struct request_queue->limits
...@@ -220,8 +220,10 @@ static void iblock_free_device(void *p) ...@@ -220,8 +220,10 @@ static void iblock_free_device(void *p)
{ {
struct iblock_dev *ib_dev = p; struct iblock_dev *ib_dev = p;
blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); if (ib_dev->ibd_bd != NULL)
bioset_free(ib_dev->ibd_bio_set); blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL);
if (ib_dev->ibd_bio_set != NULL)
bioset_free(ib_dev->ibd_bio_set);
kfree(ib_dev); kfree(ib_dev);
} }
......
此差异已折叠。
#ifndef TARGET_CORE_MIB_H
#define TARGET_CORE_MIB_H
typedef enum {
SCSI_INST_INDEX,
SCSI_DEVICE_INDEX,
SCSI_AUTH_INTR_INDEX,
SCSI_INDEX_TYPE_MAX
} scsi_index_t;
struct scsi_index_table {
spinlock_t lock;
u32 scsi_mib_index[SCSI_INDEX_TYPE_MAX];
} ____cacheline_aligned;
/* SCSI Port stats */
struct scsi_port_stats {
u64 cmd_pdus;
u64 tx_data_octets;
u64 rx_data_octets;
} ____cacheline_aligned;
extern int init_scsi_target_mib(void);
extern void remove_scsi_target_mib(void);
extern void init_scsi_index_table(void);
extern u32 scsi_get_new_index(scsi_index_t);
#endif /*** TARGET_CORE_MIB_H ***/
...@@ -462,8 +462,8 @@ static struct se_device *pscsi_create_type_disk( ...@@ -462,8 +462,8 @@ static struct se_device *pscsi_create_type_disk(
*/ */
bd = blkdev_get_by_path(se_dev->se_dev_udev_path, bd = blkdev_get_by_path(se_dev->se_dev_udev_path,
FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv); FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv);
if (!(bd)) { if (IS_ERR(bd)) {
printk("pSCSI: blkdev_get_by_path() failed\n"); printk(KERN_ERR "pSCSI: blkdev_get_by_path() failed\n");
scsi_device_put(sd); scsi_device_put(sd);
return NULL; return NULL;
} }
......
...@@ -275,7 +275,6 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( ...@@ -275,7 +275,6 @@ struct se_node_acl *core_tpg_check_initiator_node_acl(
spin_lock_init(&acl->device_list_lock); spin_lock_init(&acl->device_list_lock);
spin_lock_init(&acl->nacl_sess_lock); spin_lock_init(&acl->nacl_sess_lock);
atomic_set(&acl->acl_pr_ref_count, 0); atomic_set(&acl->acl_pr_ref_count, 0);
atomic_set(&acl->mib_ref_count, 0);
acl->queue_depth = TPG_TFO(tpg)->tpg_get_default_depth(tpg); acl->queue_depth = TPG_TFO(tpg)->tpg_get_default_depth(tpg);
snprintf(acl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname); snprintf(acl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname);
acl->se_tpg = tpg; acl->se_tpg = tpg;
...@@ -318,12 +317,6 @@ void core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *nacl) ...@@ -318,12 +317,6 @@ void core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *nacl)
cpu_relax(); cpu_relax();
} }
void core_tpg_wait_for_mib_ref(struct se_node_acl *nacl)
{
while (atomic_read(&nacl->mib_ref_count) != 0)
cpu_relax();
}
void core_tpg_clear_object_luns(struct se_portal_group *tpg) void core_tpg_clear_object_luns(struct se_portal_group *tpg)
{ {
int i, ret; int i, ret;
...@@ -480,7 +473,6 @@ int core_tpg_del_initiator_node_acl( ...@@ -480,7 +473,6 @@ int core_tpg_del_initiator_node_acl(
spin_unlock_bh(&tpg->session_lock); spin_unlock_bh(&tpg->session_lock);
core_tpg_wait_for_nacl_pr_ref(acl); core_tpg_wait_for_nacl_pr_ref(acl);
core_tpg_wait_for_mib_ref(acl);
core_clear_initiator_node_from_tpg(acl, tpg); core_clear_initiator_node_from_tpg(acl, tpg);
core_free_device_list_for_node(acl, tpg); core_free_device_list_for_node(acl, tpg);
...@@ -701,6 +693,8 @@ EXPORT_SYMBOL(core_tpg_register); ...@@ -701,6 +693,8 @@ EXPORT_SYMBOL(core_tpg_register);
int core_tpg_deregister(struct se_portal_group *se_tpg) int core_tpg_deregister(struct se_portal_group *se_tpg)
{ {
struct se_node_acl *nacl, *nacl_tmp;
printk(KERN_INFO "TARGET_CORE[%s]: Deallocating %s struct se_portal_group" printk(KERN_INFO "TARGET_CORE[%s]: Deallocating %s struct se_portal_group"
" for endpoint: %s Portal Tag %u\n", " for endpoint: %s Portal Tag %u\n",
(se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) ? (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) ?
...@@ -714,6 +708,25 @@ int core_tpg_deregister(struct se_portal_group *se_tpg) ...@@ -714,6 +708,25 @@ int core_tpg_deregister(struct se_portal_group *se_tpg)
while (atomic_read(&se_tpg->tpg_pr_ref_count) != 0) while (atomic_read(&se_tpg->tpg_pr_ref_count) != 0)
cpu_relax(); cpu_relax();
/*
* Release any remaining demo-mode generated se_node_acl that have
* not been released because of TFO->tpg_check_demo_mode_cache() == 1
* in transport_deregister_session().
*/
spin_lock_bh(&se_tpg->acl_node_lock);
list_for_each_entry_safe(nacl, nacl_tmp, &se_tpg->acl_node_list,
acl_list) {
list_del(&nacl->acl_list);
se_tpg->num_node_acls--;
spin_unlock_bh(&se_tpg->acl_node_lock);
core_tpg_wait_for_nacl_pr_ref(nacl);
core_free_device_list_for_node(nacl, se_tpg);
TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg, nacl);
spin_lock_bh(&se_tpg->acl_node_lock);
}
spin_unlock_bh(&se_tpg->acl_node_lock);
if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL)
core_tpg_release_virtual_lun0(se_tpg); core_tpg_release_virtual_lun0(se_tpg);
......
...@@ -379,6 +379,40 @@ void release_se_global(void) ...@@ -379,6 +379,40 @@ void release_se_global(void)
se_global = NULL; se_global = NULL;
} }
/* SCSI statistics table index */
static struct scsi_index_table scsi_index_table;
/*
* Initialize the index table for allocating unique row indexes to various mib
* tables.
*/
void init_scsi_index_table(void)
{
memset(&scsi_index_table, 0, sizeof(struct scsi_index_table));
spin_lock_init(&scsi_index_table.lock);
}
/*
* Allocate a new row index for the entry type specified
*/
u32 scsi_get_new_index(scsi_index_t type)
{
u32 new_index;
if ((type < 0) || (type >= SCSI_INDEX_TYPE_MAX)) {
printk(KERN_ERR "Invalid index type %d\n", type);
return -EINVAL;
}
spin_lock(&scsi_index_table.lock);
new_index = ++scsi_index_table.scsi_mib_index[type];
if (new_index == 0)
new_index = ++scsi_index_table.scsi_mib_index[type];
spin_unlock(&scsi_index_table.lock);
return new_index;
}
void transport_init_queue_obj(struct se_queue_obj *qobj) void transport_init_queue_obj(struct se_queue_obj *qobj)
{ {
atomic_set(&qobj->queue_cnt, 0); atomic_set(&qobj->queue_cnt, 0);
...@@ -437,7 +471,6 @@ struct se_session *transport_init_session(void) ...@@ -437,7 +471,6 @@ struct se_session *transport_init_session(void)
} }
INIT_LIST_HEAD(&se_sess->sess_list); INIT_LIST_HEAD(&se_sess->sess_list);
INIT_LIST_HEAD(&se_sess->sess_acl_list); INIT_LIST_HEAD(&se_sess->sess_acl_list);
atomic_set(&se_sess->mib_ref_count, 0);
return se_sess; return se_sess;
} }
...@@ -546,12 +579,6 @@ void transport_deregister_session(struct se_session *se_sess) ...@@ -546,12 +579,6 @@ void transport_deregister_session(struct se_session *se_sess)
transport_free_session(se_sess); transport_free_session(se_sess);
return; return;
} }
/*
* Wait for possible reference in drivers/target/target_core_mib.c:
* scsi_att_intr_port_seq_show()
*/
while (atomic_read(&se_sess->mib_ref_count) != 0)
cpu_relax();
spin_lock_bh(&se_tpg->session_lock); spin_lock_bh(&se_tpg->session_lock);
list_del(&se_sess->sess_list); list_del(&se_sess->sess_list);
...@@ -574,7 +601,6 @@ void transport_deregister_session(struct se_session *se_sess) ...@@ -574,7 +601,6 @@ void transport_deregister_session(struct se_session *se_sess)
spin_unlock_bh(&se_tpg->acl_node_lock); spin_unlock_bh(&se_tpg->acl_node_lock);
core_tpg_wait_for_nacl_pr_ref(se_nacl); core_tpg_wait_for_nacl_pr_ref(se_nacl);
core_tpg_wait_for_mib_ref(se_nacl);
core_free_device_list_for_node(se_nacl, se_tpg); core_free_device_list_for_node(se_nacl, se_tpg);
TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg, TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg,
se_nacl); se_nacl);
...@@ -4827,6 +4853,8 @@ static int transport_do_se_mem_map( ...@@ -4827,6 +4853,8 @@ static int transport_do_se_mem_map(
return ret; return ret;
} }
BUG_ON(list_empty(se_mem_list));
/* /*
* This is the normal path for all normal non BIDI and BIDI-COMMAND * This is the normal path for all normal non BIDI and BIDI-COMMAND
* WRITE payloads.. If we need to do BIDI READ passthrough for * WRITE payloads.. If we need to do BIDI READ passthrough for
...@@ -5008,7 +5036,9 @@ transport_map_control_cmd_to_task(struct se_cmd *cmd) ...@@ -5008,7 +5036,9 @@ transport_map_control_cmd_to_task(struct se_cmd *cmd)
struct se_mem *se_mem = NULL, *se_mem_lout = NULL; struct se_mem *se_mem = NULL, *se_mem_lout = NULL;
u32 se_mem_cnt = 0, task_offset = 0; u32 se_mem_cnt = 0, task_offset = 0;
BUG_ON(list_empty(cmd->t_task->t_mem_list)); if (!list_empty(T_TASK(cmd)->t_mem_list))
se_mem = list_entry(T_TASK(cmd)->t_mem_list->next,
struct se_mem, se_list);
ret = transport_do_se_mem_map(dev, task, ret = transport_do_se_mem_map(dev, task,
cmd->t_task->t_mem_list, NULL, se_mem, cmd->t_task->t_mem_list, NULL, se_mem,
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/tcp.h> #include <net/tcp.h>
#include "target_core_mib.h"
#define TARGET_CORE_MOD_VERSION "v4.0.0-rc6" #define TARGET_CORE_MOD_VERSION "v4.0.0-rc6"
#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT)) #define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT))
...@@ -195,6 +194,21 @@ typedef enum { ...@@ -195,6 +194,21 @@ typedef enum {
SAM_TASK_ATTR_EMULATED SAM_TASK_ATTR_EMULATED
} t10_task_attr_index_t; } t10_task_attr_index_t;
/*
* Used for target SCSI statistics
*/
typedef enum {
SCSI_INST_INDEX,
SCSI_DEVICE_INDEX,
SCSI_AUTH_INTR_INDEX,
SCSI_INDEX_TYPE_MAX
} scsi_index_t;
struct scsi_index_table {
spinlock_t lock;
u32 scsi_mib_index[SCSI_INDEX_TYPE_MAX];
} ____cacheline_aligned;
struct se_cmd; struct se_cmd;
struct t10_alua { struct t10_alua {
...@@ -578,8 +592,6 @@ struct se_node_acl { ...@@ -578,8 +592,6 @@ struct se_node_acl {
spinlock_t stats_lock; spinlock_t stats_lock;
/* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
atomic_t acl_pr_ref_count; atomic_t acl_pr_ref_count;
/* Used for MIB access */
atomic_t mib_ref_count;
struct se_dev_entry *device_list; struct se_dev_entry *device_list;
struct se_session *nacl_sess; struct se_session *nacl_sess;
struct se_portal_group *se_tpg; struct se_portal_group *se_tpg;
...@@ -595,8 +607,6 @@ struct se_node_acl { ...@@ -595,8 +607,6 @@ struct se_node_acl {
} ____cacheline_aligned; } ____cacheline_aligned;
struct se_session { struct se_session {
/* Used for MIB access */
atomic_t mib_ref_count;
u64 sess_bin_isid; u64 sess_bin_isid;
struct se_node_acl *se_node_acl; struct se_node_acl *se_node_acl;
struct se_portal_group *se_tpg; struct se_portal_group *se_tpg;
...@@ -806,7 +816,6 @@ struct se_hba { ...@@ -806,7 +816,6 @@ struct se_hba {
/* Virtual iSCSI devices attached. */ /* Virtual iSCSI devices attached. */
u32 dev_count; u32 dev_count;
u32 hba_index; u32 hba_index;
atomic_t dev_mib_access_count;
atomic_t load_balance_queue; atomic_t load_balance_queue;
atomic_t left_queue_depth; atomic_t left_queue_depth;
/* Maximum queue depth the HBA can handle. */ /* Maximum queue depth the HBA can handle. */
...@@ -845,6 +854,12 @@ struct se_lun { ...@@ -845,6 +854,12 @@ struct se_lun {
#define SE_LUN(c) ((struct se_lun *)(c)->se_lun) #define SE_LUN(c) ((struct se_lun *)(c)->se_lun)
struct scsi_port_stats {
u64 cmd_pdus;
u64 tx_data_octets;
u64 rx_data_octets;
} ____cacheline_aligned;
struct se_port { struct se_port {
/* RELATIVE TARGET PORT IDENTIFER */ /* RELATIVE TARGET PORT IDENTIFER */
u16 sep_rtpi; u16 sep_rtpi;
...@@ -867,6 +882,7 @@ struct se_port { ...@@ -867,6 +882,7 @@ struct se_port {
} ____cacheline_aligned; } ____cacheline_aligned;
struct se_tpg_np { struct se_tpg_np {
struct se_portal_group *tpg_np_parent;
struct config_group tpg_np_group; struct config_group tpg_np_group;
} ____cacheline_aligned; } ____cacheline_aligned;
......
...@@ -111,6 +111,8 @@ struct se_subsystem_api; ...@@ -111,6 +111,8 @@ struct se_subsystem_api;
extern int init_se_global(void); extern int init_se_global(void);
extern void release_se_global(void); extern void release_se_global(void);
extern void init_scsi_index_table(void);
extern u32 scsi_get_new_index(scsi_index_t);
extern void transport_init_queue_obj(struct se_queue_obj *); extern void transport_init_queue_obj(struct se_queue_obj *);
extern int transport_subsystem_check_init(void); extern int transport_subsystem_check_init(void);
extern int transport_subsystem_register(struct se_subsystem_api *); extern int transport_subsystem_register(struct se_subsystem_api *);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册