Commit 613640e4 authored by Nicholas Bellinger's avatar Nicholas Bellinger Committed by James Bottomley

[SCSI] target: Convert backend ->create_virtdevice() call to return ERR_PTR

This patch converts the target_core_store_dev_enable() -> struct
se_subsystem_api->create_virtdevice() call to return proper ERR_PTR values
back up to configfs logic during backend dependent struct se_device ENABLE
exception conditions.

Along with the change to target_core_configfs.c, this includes converting IBLOCK,
FILEIO, pSCSI, and RAMDISK_* backend subsystem plugins to obtain upper level
PTR_ERR return codes (where available), and return via ERR_PTR during a
*_create_virtdev() failure.
Reported-by: default avatarFubo Chen <fubo.chen@gmail.com>
Signed-off-by: default avatarNicholas A. Bellinger <nab@linux-iscsi.org>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 5e8de4f3
...@@ -1827,7 +1827,9 @@ static ssize_t target_core_store_dev_enable( ...@@ -1827,7 +1827,9 @@ static ssize_t target_core_store_dev_enable(
return -EINVAL; return -EINVAL;
dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr); 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; return -EINVAL;
se_dev->se_dev_ptr = dev; se_dev->se_dev_ptr = dev;
......
...@@ -134,7 +134,7 @@ static struct se_device *fd_create_virtdevice( ...@@ -134,7 +134,7 @@ static struct se_device *fd_create_virtdevice(
mm_segment_t old_fs; mm_segment_t old_fs;
struct file *file; struct file *file;
struct inode *inode = NULL; 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)); memset(&dev_limits, 0, sizeof(struct se_dev_limits));
...@@ -146,6 +146,7 @@ static struct se_device *fd_create_virtdevice( ...@@ -146,6 +146,7 @@ static struct se_device *fd_create_virtdevice(
if (IS_ERR(dev_p)) { if (IS_ERR(dev_p)) {
printk(KERN_ERR "getname(%s) failed: %lu\n", printk(KERN_ERR "getname(%s) failed: %lu\n",
fd_dev->fd_dev_name, IS_ERR(dev_p)); fd_dev->fd_dev_name, IS_ERR(dev_p));
ret = PTR_ERR(dev_p);
goto fail; goto fail;
} }
#if 0 #if 0
...@@ -165,8 +166,12 @@ static struct se_device *fd_create_virtdevice( ...@@ -165,8 +166,12 @@ static struct se_device *fd_create_virtdevice(
flags |= O_SYNC; flags |= O_SYNC;
file = filp_open(dev_p, flags, 0600); file = filp_open(dev_p, flags, 0600);
if (IS_ERR(file)) {
if (IS_ERR(file) || !file || !file->f_dentry) { 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); printk(KERN_ERR "filp_open(%s) failed\n", dev_p);
goto fail; goto fail;
} }
...@@ -241,7 +246,7 @@ static struct se_device *fd_create_virtdevice( ...@@ -241,7 +246,7 @@ static struct se_device *fd_create_virtdevice(
fd_dev->fd_file = NULL; fd_dev->fd_file = NULL;
} }
putname(dev_p); putname(dev_p);
return NULL; return ERR_PTR(ret);
} }
/* fd_free_device(): (Part of se_subsystem_api_t template) /* fd_free_device(): (Part of se_subsystem_api_t template)
......
...@@ -129,10 +129,11 @@ static struct se_device *iblock_create_virtdevice( ...@@ -129,10 +129,11 @@ static struct se_device *iblock_create_virtdevice(
struct request_queue *q; struct request_queue *q;
struct queue_limits *limits; struct queue_limits *limits;
u32 dev_flags = 0; u32 dev_flags = 0;
int ret = -EINVAL;
if (!(ib_dev)) { if (!(ib_dev)) {
printk(KERN_ERR "Unable to locate struct iblock_dev parameter\n"); 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)); memset(&dev_limits, 0, sizeof(struct se_dev_limits));
/* /*
...@@ -141,7 +142,7 @@ static struct se_device *iblock_create_virtdevice( ...@@ -141,7 +142,7 @@ static struct se_device *iblock_create_virtdevice(
ib_dev->ibd_bio_set = bioset_create(32, 64); ib_dev->ibd_bio_set = bioset_create(32, 64);
if (!(ib_dev->ibd_bio_set)) { if (!(ib_dev->ibd_bio_set)) {
printk(KERN_ERR "IBLOCK: Unable to create bioset()\n"); printk(KERN_ERR "IBLOCK: Unable to create bioset()\n");
return 0; return ERR_PTR(-ENOMEM);
} }
printk(KERN_INFO "IBLOCK: Created bio_set()\n"); printk(KERN_INFO "IBLOCK: Created bio_set()\n");
/* /*
...@@ -153,8 +154,10 @@ static struct se_device *iblock_create_virtdevice( ...@@ -153,8 +154,10 @@ 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 (IS_ERR(bd)) if (IS_ERR(bd)) {
ret = PTR_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
* to pass into transport_add_device_to_core_hba() as struct se_dev_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( ...@@ -184,9 +187,7 @@ static struct se_device *iblock_create_virtdevice(
* the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
* in ATA and we need to set TPE=1 * in ATA and we need to set TPE=1
*/ */
if (blk_queue_discard(bdev_get_queue(bd))) { if (blk_queue_discard(q)) {
struct request_queue *q = bdev_get_queue(bd);
DEV_ATTRIB(dev)->max_unmap_lba_count = DEV_ATTRIB(dev)->max_unmap_lba_count =
q->limits.max_discard_sectors; q->limits.max_discard_sectors;
/* /*
...@@ -212,7 +213,7 @@ static struct se_device *iblock_create_virtdevice( ...@@ -212,7 +213,7 @@ static struct se_device *iblock_create_virtdevice(
ib_dev->ibd_bd = NULL; ib_dev->ibd_bd = NULL;
ib_dev->ibd_major = 0; ib_dev->ibd_major = 0;
ib_dev->ibd_minor = 0; ib_dev->ibd_minor = 0;
return NULL; return ERR_PTR(ret);
} }
static void iblock_free_device(void *p) static void iblock_free_device(void *p)
......
...@@ -555,7 +555,7 @@ static struct se_device *pscsi_create_virtdevice( ...@@ -555,7 +555,7 @@ static struct se_device *pscsi_create_virtdevice(
if (!(pdv)) { if (!(pdv)) {
printk(KERN_ERR "Unable to locate struct pscsi_dev_virt" printk(KERN_ERR "Unable to locate struct pscsi_dev_virt"
" parameter\n"); " parameter\n");
return NULL; return ERR_PTR(-EINVAL);
} }
/* /*
* If not running in PHV_LLD_SCSI_HOST_NO mode, locate the * If not running in PHV_LLD_SCSI_HOST_NO mode, locate the
...@@ -565,7 +565,7 @@ static struct se_device *pscsi_create_virtdevice( ...@@ -565,7 +565,7 @@ static struct se_device *pscsi_create_virtdevice(
if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) { if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) {
printk(KERN_ERR "pSCSI: Unable to locate struct" printk(KERN_ERR "pSCSI: Unable to locate struct"
" Scsi_Host for PHV_LLD_SCSI_HOST_NO\n"); " 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 * For the newer PHV_VIRUTAL_HOST_ID struct scsi_device
...@@ -574,7 +574,7 @@ static struct se_device *pscsi_create_virtdevice( ...@@ -574,7 +574,7 @@ static struct se_device *pscsi_create_virtdevice(
if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) { if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) {
printk(KERN_ERR "pSCSI: udev_path attribute has not" printk(KERN_ERR "pSCSI: udev_path attribute has not"
" been set before ENABLE=1\n"); " been set before ENABLE=1\n");
return NULL; return ERR_PTR(-EINVAL);
} }
/* /*
* If no scsi_host_id= was passed for PHV_VIRUTAL_HOST_ID, * If no scsi_host_id= was passed for PHV_VIRUTAL_HOST_ID,
...@@ -587,12 +587,12 @@ static struct se_device *pscsi_create_virtdevice( ...@@ -587,12 +587,12 @@ static struct se_device *pscsi_create_virtdevice(
printk(KERN_ERR "pSCSI: Unable to set hba_mode" printk(KERN_ERR "pSCSI: Unable to set hba_mode"
" with active devices\n"); " with active devices\n");
spin_unlock(&hba->device_lock); spin_unlock(&hba->device_lock);
return NULL; return ERR_PTR(-EEXIST);
} }
spin_unlock(&hba->device_lock); spin_unlock(&hba->device_lock);
if (pscsi_pmode_enable_hba(hba, 1) != 1) if (pscsi_pmode_enable_hba(hba, 1) != 1)
return NULL; return ERR_PTR(-ENODEV);
legacy_mode_enable = 1; legacy_mode_enable = 1;
hba->hba_flags |= HBA_FLAGS_PSCSI_MODE; hba->hba_flags |= HBA_FLAGS_PSCSI_MODE;
...@@ -602,14 +602,14 @@ static struct se_device *pscsi_create_virtdevice( ...@@ -602,14 +602,14 @@ static struct se_device *pscsi_create_virtdevice(
if (!(sh)) { if (!(sh)) {
printk(KERN_ERR "pSCSI: Unable to locate" printk(KERN_ERR "pSCSI: Unable to locate"
" pdv_host_id: %d\n", pdv->pdv_host_id); " pdv_host_id: %d\n", pdv->pdv_host_id);
return NULL; return ERR_PTR(-ENODEV);
} }
} }
} else { } else {
if (phv->phv_mode == PHV_VIRUTAL_HOST_ID) { if (phv->phv_mode == PHV_VIRUTAL_HOST_ID) {
printk(KERN_ERR "pSCSI: PHV_VIRUTAL_HOST_ID set while" printk(KERN_ERR "pSCSI: PHV_VIRUTAL_HOST_ID set while"
" struct Scsi_Host exists\n"); " struct Scsi_Host exists\n");
return NULL; return ERR_PTR(-EEXIST);
} }
} }
...@@ -644,7 +644,7 @@ static struct se_device *pscsi_create_virtdevice( ...@@ -644,7 +644,7 @@ static struct se_device *pscsi_create_virtdevice(
hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
} }
pdv->pdv_sd = NULL; pdv->pdv_sd = NULL;
return NULL; return ERR_PTR(-ENODEV);
} }
return dev; return dev;
} }
...@@ -660,7 +660,7 @@ static struct se_device *pscsi_create_virtdevice( ...@@ -660,7 +660,7 @@ static struct se_device *pscsi_create_virtdevice(
hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
} }
return NULL; return ERR_PTR(-ENODEV);
} }
/* pscsi_free_device(): (Part of se_subsystem_api_t template) /* pscsi_free_device(): (Part of se_subsystem_api_t template)
......
...@@ -253,13 +253,15 @@ static struct se_device *rd_create_virtdevice( ...@@ -253,13 +253,15 @@ static struct se_device *rd_create_virtdevice(
struct se_dev_limits dev_limits; struct se_dev_limits dev_limits;
struct rd_dev *rd_dev = p; struct rd_dev *rd_dev = p;
struct rd_host *rd_host = hba->hba_ptr; struct rd_host *rd_host = hba->hba_ptr;
int dev_flags = 0; int dev_flags = 0, ret = -EINVAL;
char prod[16], rev[4]; char prod[16], rev[4];
memset(&dev_limits, 0, sizeof(struct se_dev_limits)); memset(&dev_limits, 0, sizeof(struct se_dev_limits));
if (rd_build_device_space(rd_dev) < 0) if (rd_build_device_space(rd_dev) < 0) {
ret = -ENOMEM;
goto fail; goto fail;
}
snprintf(prod, 16, "RAMDISK-%s", (rd_dev->rd_direct) ? "DR" : "MCP"); snprintf(prod, 16, "RAMDISK-%s", (rd_dev->rd_direct) ? "DR" : "MCP");
snprintf(rev, 4, "%s", (rd_dev->rd_direct) ? RD_DR_VERSION : snprintf(rev, 4, "%s", (rd_dev->rd_direct) ? RD_DR_VERSION :
...@@ -292,7 +294,7 @@ static struct se_device *rd_create_virtdevice( ...@@ -292,7 +294,7 @@ static struct se_device *rd_create_virtdevice(
fail: fail:
rd_release_device_space(rd_dev); rd_release_device_space(rd_dev);
return NULL; return ERR_PTR(ret);
} }
static struct se_device *rd_DIRECT_create_virtdevice( static struct se_device *rd_DIRECT_create_virtdevice(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment