diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-03-14 07:05:59 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-03-23 12:36:24 -0400 |
commit | 613640e4e1b5358ce880d16f10ecc2550b32b250 (patch) | |
tree | e3bf4cdc79a21df08fc44a4d5f79c4d56d3b8c78 /drivers/target | |
parent | 5e8de4f3199446f5eeb371312da20534ebfe9979 (diff) |
[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: Fubo Chen <fubo.chen@gmail.com>
Signed-off-by: Nicholas A. Bellinger <nab@linux-iscsi.org>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_configfs.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_file.c | 13 | ||||
-rw-r--r-- | drivers/target/target_core_iblock.c | 15 | ||||
-rw-r--r-- | drivers/target/target_core_pscsi.c | 18 | ||||
-rw-r--r-- | drivers/target/target_core_rd.c | 8 |
5 files changed, 34 insertions, 24 deletions
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index c9254d7ad18a..9721ef28335c 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -1827,7 +1827,9 @@ static ssize_t target_core_store_dev_enable( | |||
1827 | return -EINVAL; | 1827 | return -EINVAL; |
1828 | 1828 | ||
1829 | dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr); | 1829 | dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr); |
1830 | if (!(dev) || IS_ERR(dev)) | 1830 | if (IS_ERR(dev)) |
1831 | return PTR_ERR(dev); | ||
1832 | else if (!dev) | ||
1831 | return -EINVAL; | 1833 | return -EINVAL; |
1832 | 1834 | ||
1833 | se_dev->se_dev_ptr = dev; | 1835 | se_dev->se_dev_ptr = dev; |
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 7850c6ae06e4..03fa40f72ef7 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -134,7 +134,7 @@ static struct se_device *fd_create_virtdevice( | |||
134 | mm_segment_t old_fs; | 134 | mm_segment_t old_fs; |
135 | struct file *file; | 135 | struct file *file; |
136 | struct inode *inode = NULL; | 136 | struct inode *inode = NULL; |
137 | int dev_flags = 0, flags; | 137 | int dev_flags = 0, flags, ret = -EINVAL; |
138 | 138 | ||
139 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); | 139 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); |
140 | 140 | ||
@@ -146,6 +146,7 @@ static struct se_device *fd_create_virtdevice( | |||
146 | if (IS_ERR(dev_p)) { | 146 | if (IS_ERR(dev_p)) { |
147 | printk(KERN_ERR "getname(%s) failed: %lu\n", | 147 | printk(KERN_ERR "getname(%s) failed: %lu\n", |
148 | fd_dev->fd_dev_name, IS_ERR(dev_p)); | 148 | fd_dev->fd_dev_name, IS_ERR(dev_p)); |
149 | ret = PTR_ERR(dev_p); | ||
149 | goto fail; | 150 | goto fail; |
150 | } | 151 | } |
151 | #if 0 | 152 | #if 0 |
@@ -165,8 +166,12 @@ static struct se_device *fd_create_virtdevice( | |||
165 | flags |= O_SYNC; | 166 | flags |= O_SYNC; |
166 | 167 | ||
167 | file = filp_open(dev_p, flags, 0600); | 168 | file = filp_open(dev_p, flags, 0600); |
168 | 169 | if (IS_ERR(file)) { | |
169 | if (IS_ERR(file) || !file || !file->f_dentry) { | 170 | printk(KERN_ERR "filp_open(%s) failed\n", dev_p); |
171 | ret = PTR_ERR(file); | ||
172 | goto fail; | ||
173 | } | ||
174 | if (!file || !file->f_dentry) { | ||
170 | printk(KERN_ERR "filp_open(%s) failed\n", dev_p); | 175 | printk(KERN_ERR "filp_open(%s) failed\n", dev_p); |
171 | goto fail; | 176 | goto fail; |
172 | } | 177 | } |
@@ -241,7 +246,7 @@ fail: | |||
241 | fd_dev->fd_file = NULL; | 246 | fd_dev->fd_file = NULL; |
242 | } | 247 | } |
243 | putname(dev_p); | 248 | putname(dev_p); |
244 | return NULL; | 249 | return ERR_PTR(ret); |
245 | } | 250 | } |
246 | 251 | ||
247 | /* fd_free_device(): (Part of se_subsystem_api_t template) | 252 | /* fd_free_device(): (Part of se_subsystem_api_t template) |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 96d98cc8f85b..0f4a50935a86 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -129,10 +129,11 @@ static struct se_device *iblock_create_virtdevice( | |||
129 | struct request_queue *q; | 129 | struct request_queue *q; |
130 | struct queue_limits *limits; | 130 | struct queue_limits *limits; |
131 | u32 dev_flags = 0; | 131 | u32 dev_flags = 0; |
132 | int ret = -EINVAL; | ||
132 | 133 | ||
133 | if (!(ib_dev)) { | 134 | if (!(ib_dev)) { |
134 | printk(KERN_ERR "Unable to locate struct iblock_dev parameter\n"); | 135 | printk(KERN_ERR "Unable to locate struct iblock_dev parameter\n"); |
135 | return 0; | 136 | return ERR_PTR(ret); |
136 | } | 137 | } |
137 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); | 138 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); |
138 | /* | 139 | /* |
@@ -141,7 +142,7 @@ static struct se_device *iblock_create_virtdevice( | |||
141 | ib_dev->ibd_bio_set = bioset_create(32, 64); | 142 | ib_dev->ibd_bio_set = bioset_create(32, 64); |
142 | if (!(ib_dev->ibd_bio_set)) { | 143 | if (!(ib_dev->ibd_bio_set)) { |
143 | printk(KERN_ERR "IBLOCK: Unable to create bioset()\n"); | 144 | printk(KERN_ERR "IBLOCK: Unable to create bioset()\n"); |
144 | return 0; | 145 | return ERR_PTR(-ENOMEM); |
145 | } | 146 | } |
146 | printk(KERN_INFO "IBLOCK: Created bio_set()\n"); | 147 | printk(KERN_INFO "IBLOCK: Created bio_set()\n"); |
147 | /* | 148 | /* |
@@ -153,8 +154,10 @@ static struct se_device *iblock_create_virtdevice( | |||
153 | 154 | ||
154 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, | 155 | bd = blkdev_get_by_path(ib_dev->ibd_udev_path, |
155 | FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); | 156 | FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); |
156 | if (IS_ERR(bd)) | 157 | if (IS_ERR(bd)) { |
158 | ret = PTR_ERR(bd); | ||
157 | goto failed; | 159 | goto failed; |
160 | } | ||
158 | /* | 161 | /* |
159 | * Setup the local scope queue_limits from struct request_queue->limits | 162 | * Setup the local scope queue_limits from struct request_queue->limits |
160 | * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. | 163 | * 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 | * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM | 187 | * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM |
185 | * in ATA and we need to set TPE=1 | 188 | * in ATA and we need to set TPE=1 |
186 | */ | 189 | */ |
187 | if (blk_queue_discard(bdev_get_queue(bd))) { | 190 | if (blk_queue_discard(q)) { |
188 | struct request_queue *q = bdev_get_queue(bd); | ||
189 | |||
190 | DEV_ATTRIB(dev)->max_unmap_lba_count = | 191 | DEV_ATTRIB(dev)->max_unmap_lba_count = |
191 | q->limits.max_discard_sectors; | 192 | q->limits.max_discard_sectors; |
192 | /* | 193 | /* |
@@ -212,7 +213,7 @@ failed: | |||
212 | ib_dev->ibd_bd = NULL; | 213 | ib_dev->ibd_bd = NULL; |
213 | ib_dev->ibd_major = 0; | 214 | ib_dev->ibd_major = 0; |
214 | ib_dev->ibd_minor = 0; | 215 | ib_dev->ibd_minor = 0; |
215 | return NULL; | 216 | return ERR_PTR(ret); |
216 | } | 217 | } |
217 | 218 | ||
218 | static void iblock_free_device(void *p) | 219 | static void iblock_free_device(void *p) |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 3031ef8261ef..51fd309388fc 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -555,7 +555,7 @@ static struct se_device *pscsi_create_virtdevice( | |||
555 | if (!(pdv)) { | 555 | if (!(pdv)) { |
556 | printk(KERN_ERR "Unable to locate struct pscsi_dev_virt" | 556 | printk(KERN_ERR "Unable to locate struct pscsi_dev_virt" |
557 | " parameter\n"); | 557 | " parameter\n"); |
558 | return NULL; | 558 | return ERR_PTR(-EINVAL); |
559 | } | 559 | } |
560 | /* | 560 | /* |
561 | * If not running in PHV_LLD_SCSI_HOST_NO mode, locate the | 561 | * If not running in PHV_LLD_SCSI_HOST_NO mode, locate the |
@@ -565,7 +565,7 @@ static struct se_device *pscsi_create_virtdevice( | |||
565 | if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) { | 565 | if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) { |
566 | printk(KERN_ERR "pSCSI: Unable to locate struct" | 566 | printk(KERN_ERR "pSCSI: Unable to locate struct" |
567 | " Scsi_Host for PHV_LLD_SCSI_HOST_NO\n"); | 567 | " Scsi_Host for PHV_LLD_SCSI_HOST_NO\n"); |
568 | return NULL; | 568 | return ERR_PTR(-ENODEV); |
569 | } | 569 | } |
570 | /* | 570 | /* |
571 | * For the newer PHV_VIRUTAL_HOST_ID struct scsi_device | 571 | * For the newer PHV_VIRUTAL_HOST_ID struct scsi_device |
@@ -574,7 +574,7 @@ static struct se_device *pscsi_create_virtdevice( | |||
574 | if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) { | 574 | if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) { |
575 | printk(KERN_ERR "pSCSI: udev_path attribute has not" | 575 | printk(KERN_ERR "pSCSI: udev_path attribute has not" |
576 | " been set before ENABLE=1\n"); | 576 | " been set before ENABLE=1\n"); |
577 | return NULL; | 577 | return ERR_PTR(-EINVAL); |
578 | } | 578 | } |
579 | /* | 579 | /* |
580 | * If no scsi_host_id= was passed for PHV_VIRUTAL_HOST_ID, | 580 | * If no scsi_host_id= was passed for PHV_VIRUTAL_HOST_ID, |
@@ -587,12 +587,12 @@ static struct se_device *pscsi_create_virtdevice( | |||
587 | printk(KERN_ERR "pSCSI: Unable to set hba_mode" | 587 | printk(KERN_ERR "pSCSI: Unable to set hba_mode" |
588 | " with active devices\n"); | 588 | " with active devices\n"); |
589 | spin_unlock(&hba->device_lock); | 589 | spin_unlock(&hba->device_lock); |
590 | return NULL; | 590 | return ERR_PTR(-EEXIST); |
591 | } | 591 | } |
592 | spin_unlock(&hba->device_lock); | 592 | spin_unlock(&hba->device_lock); |
593 | 593 | ||
594 | if (pscsi_pmode_enable_hba(hba, 1) != 1) | 594 | if (pscsi_pmode_enable_hba(hba, 1) != 1) |
595 | return NULL; | 595 | return ERR_PTR(-ENODEV); |
596 | 596 | ||
597 | legacy_mode_enable = 1; | 597 | legacy_mode_enable = 1; |
598 | hba->hba_flags |= HBA_FLAGS_PSCSI_MODE; | 598 | hba->hba_flags |= HBA_FLAGS_PSCSI_MODE; |
@@ -602,14 +602,14 @@ static struct se_device *pscsi_create_virtdevice( | |||
602 | if (!(sh)) { | 602 | if (!(sh)) { |
603 | printk(KERN_ERR "pSCSI: Unable to locate" | 603 | printk(KERN_ERR "pSCSI: Unable to locate" |
604 | " pdv_host_id: %d\n", pdv->pdv_host_id); | 604 | " pdv_host_id: %d\n", pdv->pdv_host_id); |
605 | return NULL; | 605 | return ERR_PTR(-ENODEV); |
606 | } | 606 | } |
607 | } | 607 | } |
608 | } else { | 608 | } else { |
609 | if (phv->phv_mode == PHV_VIRUTAL_HOST_ID) { | 609 | if (phv->phv_mode == PHV_VIRUTAL_HOST_ID) { |
610 | printk(KERN_ERR "pSCSI: PHV_VIRUTAL_HOST_ID set while" | 610 | printk(KERN_ERR "pSCSI: PHV_VIRUTAL_HOST_ID set while" |
611 | " struct Scsi_Host exists\n"); | 611 | " struct Scsi_Host exists\n"); |
612 | return NULL; | 612 | return ERR_PTR(-EEXIST); |
613 | } | 613 | } |
614 | } | 614 | } |
615 | 615 | ||
@@ -644,7 +644,7 @@ static struct se_device *pscsi_create_virtdevice( | |||
644 | hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; | 644 | hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; |
645 | } | 645 | } |
646 | pdv->pdv_sd = NULL; | 646 | pdv->pdv_sd = NULL; |
647 | return NULL; | 647 | return ERR_PTR(-ENODEV); |
648 | } | 648 | } |
649 | return dev; | 649 | return dev; |
650 | } | 650 | } |
@@ -660,7 +660,7 @@ static struct se_device *pscsi_create_virtdevice( | |||
660 | hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; | 660 | hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; |
661 | } | 661 | } |
662 | 662 | ||
663 | return NULL; | 663 | return ERR_PTR(-ENODEV); |
664 | } | 664 | } |
665 | 665 | ||
666 | /* pscsi_free_device(): (Part of se_subsystem_api_t template) | 666 | /* pscsi_free_device(): (Part of se_subsystem_api_t template) |
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 8dc6d74c1d40..f36094f0596a 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -253,13 +253,15 @@ static struct se_device *rd_create_virtdevice( | |||
253 | struct se_dev_limits dev_limits; | 253 | struct se_dev_limits dev_limits; |
254 | struct rd_dev *rd_dev = p; | 254 | struct rd_dev *rd_dev = p; |
255 | struct rd_host *rd_host = hba->hba_ptr; | 255 | struct rd_host *rd_host = hba->hba_ptr; |
256 | int dev_flags = 0; | 256 | int dev_flags = 0, ret = -EINVAL; |
257 | char prod[16], rev[4]; | 257 | char prod[16], rev[4]; |
258 | 258 | ||
259 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); | 259 | memset(&dev_limits, 0, sizeof(struct se_dev_limits)); |
260 | 260 | ||
261 | if (rd_build_device_space(rd_dev) < 0) | 261 | if (rd_build_device_space(rd_dev) < 0) { |
262 | ret = -ENOMEM; | ||
262 | goto fail; | 263 | goto fail; |
264 | } | ||
263 | 265 | ||
264 | snprintf(prod, 16, "RAMDISK-%s", (rd_dev->rd_direct) ? "DR" : "MCP"); | 266 | snprintf(prod, 16, "RAMDISK-%s", (rd_dev->rd_direct) ? "DR" : "MCP"); |
265 | snprintf(rev, 4, "%s", (rd_dev->rd_direct) ? RD_DR_VERSION : | 267 | snprintf(rev, 4, "%s", (rd_dev->rd_direct) ? RD_DR_VERSION : |
@@ -292,7 +294,7 @@ static struct se_device *rd_create_virtdevice( | |||
292 | 294 | ||
293 | fail: | 295 | fail: |
294 | rd_release_device_space(rd_dev); | 296 | rd_release_device_space(rd_dev); |
295 | return NULL; | 297 | return ERR_PTR(ret); |
296 | } | 298 | } |
297 | 299 | ||
298 | static struct se_device *rd_DIRECT_create_virtdevice( | 300 | static struct se_device *rd_DIRECT_create_virtdevice( |