Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -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;
+9 −4
Original line number Original line Diff line number Diff line
@@ -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(
	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(
		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(
		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)
+8 −7
Original line number Original line Diff line number Diff line
@@ -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(
	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(


	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(
	 * 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(
	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)
+9 −9
Original line number Original line Diff line number Diff line
@@ -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(
		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(
		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(
				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(
			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(
				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(
		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)
+5 −3
Original line number Original line Diff line number Diff line
@@ -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(


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(