aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/target/target_core_file.c117
-rw-r--r--drivers/target/target_core_file.h4
-rw-r--r--drivers/target/target_core_iblock.c142
-rw-r--r--drivers/target/target_core_iblock.h1
-rw-r--r--drivers/target/target_core_pscsi.c172
-rw-r--r--drivers/target/target_core_pscsi.h1
-rw-r--r--drivers/target/target_core_rd.c40
-rw-r--r--drivers/target/target_core_tmr.c8
-rw-r--r--drivers/target/target_core_transport.c127
-rw-r--r--include/target/target_core_backend.h11
-rw-r--r--include/target/target_core_base.h11
11 files changed, 211 insertions, 423 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index a984964ab70..bbcedcfc068 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -244,53 +244,33 @@ static void fd_free_device(void *p)
kfree(fd_dev);
}
-static inline struct fd_request *FILE_REQ(struct se_task *task)
+static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl,
+ u32 sgl_nents)
{
- return container_of(task, struct fd_request, fd_task);
-}
-
-
-static struct se_task *
-fd_alloc_task(unsigned char *cdb)
-{
- struct fd_request *fd_req;
-
- fd_req = kzalloc(sizeof(struct fd_request), GFP_KERNEL);
- if (!fd_req) {
- pr_err("Unable to allocate struct fd_request\n");
- return NULL;
- }
-
- return &fd_req->fd_task;
-}
-
-static int fd_do_readv(struct se_task *task)
-{
- struct fd_request *req = FILE_REQ(task);
- struct se_device *se_dev = req->fd_task.task_se_cmd->se_dev;
+ struct se_device *se_dev = cmd->se_dev;
struct fd_dev *dev = se_dev->dev_ptr;
struct file *fd = dev->fd_file;
- struct scatterlist *sg = task->task_sg;
+ struct scatterlist *sg;
struct iovec *iov;
mm_segment_t old_fs;
- loff_t pos = (task->task_se_cmd->t_task_lba *
+ loff_t pos = (cmd->t_task_lba *
se_dev->se_sub_dev->se_dev_attrib.block_size);
int ret = 0, i;
- iov = kzalloc(sizeof(struct iovec) * task->task_sg_nents, GFP_KERNEL);
+ iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL);
if (!iov) {
pr_err("Unable to allocate fd_do_readv iov[]\n");
return -ENOMEM;
}
- for_each_sg(task->task_sg, sg, task->task_sg_nents, i) {
+ for_each_sg(sgl, sg, sgl_nents, i) {
iov[i].iov_len = sg->length;
iov[i].iov_base = sg_virt(sg);
}
old_fs = get_fs();
set_fs(get_ds());
- ret = vfs_readv(fd, &iov[0], task->task_sg_nents, &pos);
+ ret = vfs_readv(fd, &iov[0], sgl_nents, &pos);
set_fs(old_fs);
kfree(iov);
@@ -300,10 +280,10 @@ static int fd_do_readv(struct se_task *task)
* block_device.
*/
if (S_ISBLK(fd->f_dentry->d_inode->i_mode)) {
- if (ret < 0 || ret != task->task_se_cmd->data_length) {
+ if (ret < 0 || ret != cmd->data_length) {
pr_err("vfs_readv() returned %d,"
" expecting %d for S_ISBLK\n", ret,
- (int)task->task_se_cmd->data_length);
+ (int)cmd->data_length);
return (ret < 0 ? ret : -EINVAL);
}
} else {
@@ -317,38 +297,38 @@ static int fd_do_readv(struct se_task *task)
return 1;
}
-static int fd_do_writev(struct se_task *task)
+static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl,
+ u32 sgl_nents)
{
- struct fd_request *req = FILE_REQ(task);
- struct se_device *se_dev = req->fd_task.task_se_cmd->se_dev;
+ struct se_device *se_dev = cmd->se_dev;
struct fd_dev *dev = se_dev->dev_ptr;
struct file *fd = dev->fd_file;
- struct scatterlist *sg = task->task_sg;
+ struct scatterlist *sg;
struct iovec *iov;
mm_segment_t old_fs;
- loff_t pos = (task->task_se_cmd->t_task_lba *
+ loff_t pos = (cmd->t_task_lba *
se_dev->se_sub_dev->se_dev_attrib.block_size);
int ret, i = 0;
- iov = kzalloc(sizeof(struct iovec) * task->task_sg_nents, GFP_KERNEL);
+ iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL);
if (!iov) {
pr_err("Unable to allocate fd_do_writev iov[]\n");
return -ENOMEM;
}
- for_each_sg(task->task_sg, sg, task->task_sg_nents, i) {
+ for_each_sg(sgl, sg, sgl_nents, i) {
iov[i].iov_len = sg->length;
iov[i].iov_base = sg_virt(sg);
}
old_fs = get_fs();
set_fs(get_ds());
- ret = vfs_writev(fd, &iov[0], task->task_sg_nents, &pos);
+ ret = vfs_writev(fd, &iov[0], sgl_nents, &pos);
set_fs(old_fs);
kfree(iov);
- if (ret < 0 || ret != task->task_se_cmd->data_length) {
+ if (ret < 0 || ret != cmd->data_length) {
pr_err("vfs_writev() returned %d\n", ret);
return (ret < 0 ? ret : -EINVAL);
}
@@ -369,7 +349,7 @@ static void fd_emulate_sync_cache(struct se_cmd *cmd)
* for this SYNCHRONIZE_CACHE op
*/
if (immed)
- transport_complete_sync_cache(cmd, 1);
+ target_complete_cmd(cmd, SAM_STAT_GOOD);
/*
* Determine if we will be flushing the entire device.
@@ -389,35 +369,37 @@ static void fd_emulate_sync_cache(struct se_cmd *cmd)
if (ret != 0)
pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret);
- if (!immed)
- transport_complete_sync_cache(cmd, ret == 0);
+ if (immed)
+ return;
+
+ if (ret) {
+ cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+ target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
+ } else {
+ target_complete_cmd(cmd, SAM_STAT_GOOD);
+ }
}
-/*
- * WRITE Force Unit Access (FUA) emulation on a per struct se_task
- * LBA range basis..
- */
-static void fd_emulate_write_fua(struct se_cmd *cmd, struct se_task *task)
+static void fd_emulate_write_fua(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct fd_dev *fd_dev = dev->dev_ptr;
- loff_t start = task->task_se_cmd->t_task_lba *
+ loff_t start = cmd->t_task_lba *
dev->se_sub_dev->se_dev_attrib.block_size;
- loff_t end = start + task->task_se_cmd->data_length;
+ loff_t end = start + cmd->data_length;
int ret;
pr_debug("FILEIO: FUA WRITE LBA: %llu, bytes: %u\n",
- task->task_se_cmd->t_task_lba,
- task->task_se_cmd->data_length);
+ cmd->t_task_lba, cmd->data_length);
ret = vfs_fsync_range(fd_dev->fd_file, start, end, 1);
if (ret != 0)
pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret);
}
-static int fd_do_task(struct se_task *task)
+static int fd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
+ u32 sgl_nents, enum dma_data_direction data_direction)
{
- struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
int ret = 0;
@@ -425,10 +407,10 @@ static int fd_do_task(struct se_task *task)
* Call vectorized fileio functions to map struct scatterlist
* physical memory addresses to struct iovec virtual memory.
*/
- if (task->task_data_direction == DMA_FROM_DEVICE) {
- ret = fd_do_readv(task);
+ if (data_direction == DMA_FROM_DEVICE) {
+ ret = fd_do_readv(cmd, sgl, sgl_nents);
} else {
- ret = fd_do_writev(task);
+ ret = fd_do_writev(cmd, sgl, sgl_nents);
if (ret > 0 &&
dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 &&
@@ -439,7 +421,7 @@ static int fd_do_task(struct se_task *task)
* and return some sense data to let the initiator
* know the FUA WRITE cache sync failed..?
*/
- fd_emulate_write_fua(cmd, task);
+ fd_emulate_write_fua(cmd);
}
}
@@ -448,24 +430,11 @@ static int fd_do_task(struct se_task *task)
cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return ret;
}
- if (ret) {
- task->task_scsi_status = GOOD;
- transport_complete_task(task, 1);
- }
+ if (ret)
+ target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0;
}
-/* fd_free_task(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static void fd_free_task(struct se_task *task)
-{
- struct fd_request *req = FILE_REQ(task);
-
- kfree(req);
-}
-
enum {
Opt_fd_dev_name, Opt_fd_dev_size, Opt_fd_buffered_io, Opt_err
};
@@ -618,10 +587,8 @@ static struct se_subsystem_api fileio_template = {
.allocate_virtdevice = fd_allocate_virtdevice,
.create_virtdevice = fd_create_virtdevice,
.free_device = fd_free_device,
- .alloc_task = fd_alloc_task,
- .do_task = fd_do_task,
+ .execute_cmd = fd_execute_cmd,
.do_sync_cache = fd_emulate_sync_cache,
- .free_task = fd_free_task,
.check_configfs_dev_params = fd_check_configfs_dev_params,
.set_configfs_dev_params = fd_set_configfs_dev_params,
.show_configfs_dev_params = fd_show_configfs_dev_params,
diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h
index 59e6e73106c..fbd59ef7d8b 100644
--- a/drivers/target/target_core_file.h
+++ b/drivers/target/target_core_file.h
@@ -12,10 +12,6 @@
#define RRF_EMULATE_CDB 0x01
#define RRF_GOT_LBA 0x02
-struct fd_request {
- struct se_task fd_task;
-};
-
#define FBDF_HAS_PATH 0x01
#define FBDF_HAS_SIZE 0x02
#define FDBD_USE_BUFFERED_IO 0x04
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 82ec0d3fa9d..fd47950727b 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -189,26 +189,6 @@ static void iblock_free_device(void *p)
kfree(ib_dev);
}
-static inline struct iblock_req *IBLOCK_REQ(struct se_task *task)
-{
- return container_of(task, struct iblock_req, ib_task);
-}
-
-static struct se_task *
-iblock_alloc_task(unsigned char *cdb)
-{
- struct iblock_req *ib_req;
-
- ib_req = kzalloc(sizeof(struct iblock_req), GFP_KERNEL);
- if (!ib_req) {
- pr_err("Unable to allocate memory for struct iblock_req\n");
- return NULL;
- }
-
- atomic_set(&ib_req->pending, 1);
- return &ib_req->ib_task;
-}
-
static unsigned long long iblock_emulate_read_cap_with_block_size(
struct se_device *dev,
struct block_device *bd,
@@ -295,8 +275,16 @@ static void iblock_end_io_flush(struct bio *bio, int err)
if (err)
pr_err("IBLOCK: cache flush failed: %d\n", err);
- if (cmd)
- transport_complete_sync_cache(cmd, err == 0);
+ if (cmd) {
+ if (err) {
+ cmd->scsi_sense_reason =
+ TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+ target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
+ } else {
+ target_complete_cmd(cmd, SAM_STAT_GOOD);
+ }
+ }
+
bio_put(bio);
}
@@ -315,7 +303,7 @@ static void iblock_emulate_sync_cache(struct se_cmd *cmd)
* for this SYNCHRONIZE_CACHE op.
*/
if (immed)
- transport_complete_sync_cache(cmd, 1);
+ target_complete_cmd(cmd, SAM_STAT_GOOD);
bio = bio_alloc(GFP_KERNEL, 0);
bio->bi_end_io = iblock_end_io_flush;
@@ -334,11 +322,6 @@ static int iblock_do_discard(struct se_device *dev, sector_t lba, u32 range)
return blkdev_issue_discard(bd, lba, range, GFP_KERNEL, barrier);
}
-static void iblock_free_task(struct se_task *task)
-{
- kfree(IBLOCK_REQ(task));
-}
-
enum {
Opt_udev_path, Opt_force, Opt_err
};
@@ -447,19 +430,35 @@ static ssize_t iblock_show_configfs_dev_params(
return bl;
}
+static void iblock_complete_cmd(struct se_cmd *cmd)
+{
+ struct iblock_req *ibr = cmd->priv;
+ u8 status;
+
+ if (!atomic_dec_and_test(&ibr->pending))
+ return;
+
+ if (atomic_read(&ibr->ib_bio_err_cnt))
+ status = SAM_STAT_CHECK_CONDITION;
+ else
+ status = SAM_STAT_GOOD;
+
+ target_complete_cmd(cmd, status);
+ kfree(ibr);
+}
+
static void iblock_bio_destructor(struct bio *bio)
{
- struct se_task *task = bio->bi_private;
- struct iblock_dev *ib_dev = task->task_se_cmd->se_dev->dev_ptr;
+ struct se_cmd *cmd = bio->bi_private;
+ struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr;
bio_free(bio, ib_dev->ibd_bio_set);
}
static struct bio *
-iblock_get_bio(struct se_task *task, sector_t lba, u32 sg_num)
+iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num)
{
- struct iblock_dev *ib_dev = task->task_se_cmd->se_dev->dev_ptr;
- struct iblock_req *ib_req = IBLOCK_REQ(task);
+ struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr;
struct bio *bio;
/*
@@ -475,20 +474,11 @@ iblock_get_bio(struct se_task *task, sector_t lba, u32 sg_num)
return NULL;
}
- pr_debug("Allocated bio: %p task_sg_nents: %u using ibd_bio_set:"
- " %p\n", bio, task->task_sg_nents, ib_dev->ibd_bio_set);
- pr_debug("Allocated bio: %p task_size: %u\n", bio,
- task->task_se_cmd->data_length);
-
bio->bi_bdev = ib_dev->ibd_bd;
- bio->bi_private = task;
+ bio->bi_private = cmd;
bio->bi_destructor = iblock_bio_destructor;
bio->bi_end_io = &iblock_bio_done;
bio->bi_sector = lba;
- atomic_inc(&ib_req->pending);
-
- pr_debug("Set bio->bi_sector: %llu\n", (unsigned long long)bio->bi_sector);
- pr_debug("Set ib_req->pending: %d\n", atomic_read(&ib_req->pending));
return bio;
}
@@ -503,20 +493,21 @@ static void iblock_submit_bios(struct bio_list *list, int rw)
blk_finish_plug(&plug);
}
-static int iblock_do_task(struct se_task *task)
+static int iblock_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
+ u32 sgl_nents, enum dma_data_direction data_direction)
{
- struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
- struct iblock_req *ibr = IBLOCK_REQ(task);
+ struct iblock_req *ibr;
struct bio *bio;
struct bio_list list;
struct scatterlist *sg;
- u32 i, sg_num = task->task_sg_nents;
+ u32 sg_num = sgl_nents;
sector_t block_lba;
unsigned bio_cnt;
int rw;
+ int i;
- if (task->task_data_direction == DMA_TO_DEVICE) {
+ if (data_direction == DMA_TO_DEVICE) {
/*
* Force data to disk if we pretend to not have a volatile
* write cache, or the initiator set the Force Unit Access bit.
@@ -532,8 +523,8 @@ static int iblock_do_task(struct se_task *task)
}
/*
- * Do starting conversion up from non 512-byte blocksize with
- * struct se_task SCSI blocksize into Linux/Block 512 units for BIO.
+ * Convert the blocksize advertised to the initiator to the 512 byte
+ * units unconditionally used by the Linux block layer.
*/
if (dev->se_sub_dev->se_dev_attrib.block_size == 4096)
block_lba = (cmd->t_task_lba << 3);
@@ -550,17 +541,22 @@ static int iblock_do_task(struct se_task *task)
return -ENOSYS;
}
- bio = iblock_get_bio(task, block_lba, sg_num);
- if (!bio) {
- cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
- return -ENOMEM;
- }
+ ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL);
+ if (!ibr)
+ goto fail;
+ cmd->priv = ibr;
+
+ bio = iblock_get_bio(cmd, block_lba, sgl_nents);
+ if (!bio)
+ goto fail_free_ibr;
bio_list_init(&list);
bio_list_add(&list, bio);
+
+ atomic_set(&ibr->pending, 2);
bio_cnt = 1;
- for_each_sg(task->task_sg, sg, task->task_sg_nents, i) {
+ for_each_sg(sgl, sg, sgl_nents, i) {
/*
* XXX: if the length the device accepts is shorter than the
* length of the S/G list entry this will cause and
@@ -573,9 +569,11 @@ static int iblock_do_task(struct se_task *task)
bio_cnt = 0;
}
- bio = iblock_get_bio(task, block_lba, sg_num);
+ bio = iblock_get_bio(cmd, block_lba, sg_num);
if (!bio)
- goto fail;
+ goto fail_put_bios;
+
+ atomic_inc(&ibr->pending);
bio_list_add(&list, bio);
bio_cnt++;
}
@@ -586,17 +584,16 @@ static int iblock_do_task(struct se_task *task)
}
iblock_submit_bios(&list, rw);
-
- if (atomic_dec_and_test(&ibr->pending)) {
- transport_complete_task(task,
- !atomic_read(&ibr->ib_bio_err_cnt));
- }
+ iblock_complete_cmd(cmd);
return 0;
-fail:
+fail_put_bios:
while ((bio = bio_list_pop(&list)))
bio_put(bio);
+fail_free_ibr:
+ kfree(ibr);
cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+fail:
return -ENOMEM;
}
@@ -621,8 +618,8 @@ static sector_t iblock_get_blocks(struct se_device *dev)
static void iblock_bio_done(struct bio *bio, int err)
{
- struct se_task *task = bio->bi_private;
- struct iblock_req *ibr = IBLOCK_REQ(task);
+ struct se_cmd *cmd = bio->bi_private;
+ struct iblock_req *ibr = cmd->priv;
/*
* Set -EIO if !BIO_UPTODATE and the passed is still err=0
@@ -642,14 +639,7 @@ static void iblock_bio_done(struct bio *bio, int err)
bio_put(bio);
- if (!atomic_dec_and_test(&ibr->pending))
- return;
-
- pr_debug("done[%p] bio: %p task_lba: %llu bio_lba: %llu err=%d\n",
- task, bio, task->task_se_cmd->t_task_lba,
- (unsigned long long)bio->bi_sector, err);
-
- transport_complete_task(task, !atomic_read(&ibr->ib_bio_err_cnt));
+ iblock_complete_cmd(cmd);
}
static struct se_subsystem_api iblock_template = {
@@ -663,11 +653,9 @@ static struct se_subsystem_api iblock_template = {
.allocate_virtdevice = iblock_allocate_virtdevice,
.create_virtdevice = iblock_create_virtdevice,
.free_device = iblock_free_device,
- .alloc_task = iblock_alloc_task,
- .do_task = iblock_do_task,
+ .execute_cmd = iblock_execute_cmd,
.do_discard = iblock_do_discard,
.do_sync_cache = iblock_emulate_sync_cache,
- .free_task = iblock_free_task,
.check_configfs_dev_params = iblock_check_configfs_dev_params,
.set_configfs_dev_params = iblock_set_configfs_dev_params,
.show_configfs_dev_params = iblock_show_configfs_dev_params,
diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h
index e929370b6fd..66cf7b9e205 100644
--- a/drivers/target/target_core_iblock.h
+++ b/drivers/target/target_core_iblock.h
@@ -7,7 +7,6 @@
#define IBLOCK_LBA_SHIFT 9
struct iblock_req {
- struct se_task ib_task;
atomic_t pending;
atomic_t ib_bio_err_cnt;
} ____cacheline_aligned;
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 46eb017287a..4ce2cf642fc 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -663,22 +663,12 @@ static void pscsi_free_device(void *p)
kfree(pdv);
}
-static inline struct pscsi_plugin_task *PSCSI_TASK(struct se_task *task)
+static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)
{
- return container_of(task, struct pscsi_plugin_task, pscsi_task);
-}
-
-
-/* pscsi_transport_complete():
- *
- *
- */
-static int pscsi_transport_complete(struct se_task *task)
-{
- struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr;
+ struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
struct scsi_device *sd = pdv->pdv_sd;
int result;
- struct pscsi_plugin_task *pt = PSCSI_TASK(task);
+ struct pscsi_plugin_task *pt = cmd->priv;
unsigned char *cdb = &pt->pscsi_cdb[0];
result = pt->pscsi_result;
@@ -688,12 +678,11 @@ static int pscsi_transport_complete(struct se_task *task)
*/
if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) &&
(status_byte(result) << 1) == SAM_STAT_GOOD) {
- if (!task->task_se_cmd->se_deve)
+ if (!cmd->se_deve)
goto after_mode_sense;
- if (task->task_se_cmd->se_deve->lun_flags &
- TRANSPORT_LUNFLAGS_READ_ONLY) {
- unsigned char *buf = transport_kmap_data_sg(task->task_se_cmd);
+ if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) {
+ unsigned char *buf = transport_kmap_data_sg(cmd);
if (cdb[0] == MODE_SENSE_10) {
if (!(buf[3] & 0x80))
@@ -703,7 +692,7 @@ static int pscsi_transport_complete(struct se_task *task)
buf[2] |= 0x80;
}
- transport_kunmap_data_sg(task->task_se_cmd);
+ transport_kunmap_data_sg(cmd);
}
}
after_mode_sense:
@@ -722,7 +711,6 @@ after_mode_sense:
if (((cdb[0] == MODE_SELECT) || (cdb[0] == MODE_SELECT_10)) &&
(status_byte(result) << 1) == SAM_STAT_GOOD) {
unsigned char *buf;
- struct scatterlist *sg = task->task_sg;
u16 bdl;
u32 blocksize;
@@ -757,35 +745,6 @@ after_mode_select:
return 0;
}
-static struct se_task *
-pscsi_alloc_task(unsigned char *cdb)
-{
- struct pscsi_plugin_task *pt;
-
- /*
- * Dynamically alloc cdb space, since it may be larger than
- * TCM_MAX_COMMAND_SIZE
- */
- pt = kzalloc(sizeof(*pt) + scsi_command_size(cdb), GFP_KERNEL);
- if (!pt) {
- pr_err("Unable to allocate struct pscsi_plugin_task\n");
- return NULL;
- }
-
- return &pt->pscsi_task;
-}
-
-static void pscsi_free_task(struct se_task *task)
-{
- struct pscsi_plugin_task *pt = PSCSI_TASK(task);
-
- /*
- * We do not release the bio(s) here associated with this task, as
- * this is handled by bio_put() and pscsi_bi_endio().
- */
- kfree(pt);
-}
-
enum {
Opt_scsi_host_id, Opt_scsi_channel_id, Opt_scsi_target_id,
Opt_scsi_lun_id, Opt_err
@@ -958,26 +917,25 @@ static inline struct bio *pscsi_get_bio(int sg_num)
return bio;
}
-static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg,
+static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl,
+ u32 sgl_nents, enum dma_data_direction data_direction,
struct bio **hbio)
{
- struct se_cmd *cmd = task->task_se_cmd;
- struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr;
- u32 task_sg_num = task->task_sg_nents;
+ struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
struct bio *bio = NULL, *tbio = NULL;
struct page *page;
struct scatterlist *sg;
u32 data_len = cmd->data_length, i, len, bytes, off;
- int nr_pages = (cmd->data_length + task_sg[0].offset +
+ int nr_pages = (cmd->data_length + sgl[0].offset +
PAGE_SIZE - 1) >> PAGE_SHIFT;
int nr_vecs = 0, rc;
- int rw = (task->task_data_direction == DMA_TO_DEVICE);
+ int rw = (data_direction == DMA_TO_DEVICE);
*hbio = NULL;
pr_debug("PSCSI: nr_pages: %d\n", nr_pages);
- for_each_sg(task_sg, sg, task_sg_num, i) {
+ for_each_sg(sgl, sg, sgl_nents, i) {
page = sg_page(sg);
off = sg->offset;
len = sg->length;
@@ -1009,7 +967,7 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg,
* Set *hbio pointer to handle the case:
* nr_pages > BIO_MAX_PAGES, where additional
* bios need to be added to complete a given
- * struct se_task
+ * command.
*/
if (!*hbio)
*hbio = tbio = bio;
@@ -1049,7 +1007,7 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg,
}
}
- return task->task_sg_nents;
+ return sgl_nents;
fail:
while (*hbio) {
bio = *hbio;
@@ -1061,53 +1019,61 @@ fail:
return -ENOMEM;
}
-static int pscsi_do_task(struct se_task *task)
+static int pscsi_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
+ u32 sgl_nents, enum dma_data_direction data_direction)
{
- struct se_cmd *cmd = task->task_se_cmd;
- struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr;
- struct pscsi_plugin_task *pt = PSCSI_TASK(task);
+ struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
+ struct pscsi_plugin_task *pt;
struct request *req;
struct bio *hbio;
int ret;
+ /*
+ * Dynamically alloc cdb space, since it may be larger than
+ * TCM_MAX_COMMAND_SIZE
+ */
+ pt = kzalloc(sizeof(*pt) + scsi_command_size(cmd->t_task_cdb), GFP_KERNEL);
+ if (!pt) {
+ cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+ return -ENOMEM;
+ }
+ cmd->priv = pt;
+
memcpy(pt->pscsi_cdb, cmd->t_task_cdb,
scsi_command_size(cmd->t_task_cdb));
- if (task->task_se_cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) {
+ if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) {
req = blk_get_request(pdv->pdv_sd->request_queue,
- (task->task_data_direction == DMA_TO_DEVICE),
+ (data_direction == DMA_TO_DEVICE),
GFP_KERNEL);
if (!req || IS_ERR(req)) {
pr_err("PSCSI: blk_get_request() failed: %ld\n",
req ? IS_ERR(req) : -ENOMEM);
cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
- return -ENODEV;
+ goto fail;
}
} else {
BUG_ON(!cmd->data_length);
- /*
- * Setup the main struct request for the task->task_sg[] payload
- */
- ret = pscsi_map_sg(task, task->task_sg, &hbio);
+ ret = pscsi_map_sg(cmd, sgl, sgl_nents, data_direction, &hbio);
if (ret < 0) {
cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
- return ret;
+ goto fail;
}
req = blk_make_request(pdv->pdv_sd->request_queue, hbio,
GFP_KERNEL);
if (IS_ERR(req)) {
pr_err("pSCSI: blk_make_request() failed\n");
- goto fail;
+ goto fail_free_bio;
}
}
req->cmd_type = REQ_TYPE_BLOCK_PC;
req->end_io = pscsi_req_done;
- req->end_io_data = task;
+ req->end_io_data = cmd;
req->cmd_len = scsi_command_size(pt->pscsi_cdb);
req->cmd = &pt->pscsi_cdb[0];
req->sense = &pt->pscsi_sense[0];
@@ -1119,12 +1085,12 @@ static int pscsi_do_task(struct se_task *task)
req->retries = PS_RETRY;
blk_execute_rq_nowait(pdv->pdv_sd->request_queue, NULL, req,
- (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG),
+ (cmd->sam_task_attr == MSG_HEAD_TAG),
pscsi_req_done);
return 0;
-fail:
+fail_free_bio:
while (hbio) {
struct bio *bio = hbio;
hbio = hbio->bi_next;
@@ -1132,16 +1098,14 @@ fail:
bio_endio(bio, 0); /* XXX: should be error */
}
cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+fail:
+ kfree(pt);
return -ENOMEM;
}
-/* pscsi_get_sense_buffer():
- *
- *
- */
-static unsigned char *pscsi_get_sense_buffer(struct se_task *task)
+static unsigned char *pscsi_get_sense_buffer(struct se_cmd *cmd)
{
- struct pscsi_plugin_task *pt = PSCSI_TASK(task);
+ struct pscsi_plugin_task *pt = cmd->priv;
return pt->pscsi_sense;
}
@@ -1181,48 +1145,36 @@ static sector_t pscsi_get_blocks(struct se_device *dev)
return 0;
}
-/* pscsi_handle_SAM_STATUS_failures():
- *
- *
- */
-static inline void pscsi_process_SAM_status(
- struct se_task *task,
- struct pscsi_plugin_task *pt)
+static void pscsi_req_done(struct request *req, int uptodate)
{
- task->task_scsi_status = status_byte(pt->pscsi_result);
- if (task->task_scsi_status) {
- task->task_scsi_status <<= 1;
- pr_debug("PSCSI Status Byte exception at task: %p CDB:"
- " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0],
+ struct se_cmd *cmd = req->end_io_data;
+ struct pscsi_plugin_task *pt = cmd->priv;
+
+ pt->pscsi_result = req->errors;
+ pt->pscsi_resid = req->resid_len;
+
+ cmd->scsi_status = status_byte(pt->pscsi_result) << 1;
+ if (cmd->scsi_status) {
+ pr_debug("PSCSI Status Byte exception at cmd: %p CDB:"
+ " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0],
pt->pscsi_result);
}
switch (host_byte(pt->pscsi_result)) {
case DID_OK:
- transport_complete_task(task, (!task->task_scsi_status));
+ target_complete_cmd(cmd, cmd->scsi_status);
break;
default:
- pr_debug("PSCSI Host Byte exception at task: %p CDB:"
- " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0],
+ pr_debug("PSCSI Host Byte exception at cmd: %p CDB:"
+ " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0],
pt->pscsi_result);
- task->task_scsi_status = SAM_STAT_CHECK_CONDITION;
- task->task_se_cmd->scsi_sense_reason =
- TCM_UNSUPPORTED_SCSI_OPCODE;
- transport_complete_task(task, 0);
+ cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+ target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
break;
}
-}
-static void pscsi_req_done(struct request *req, int uptodate)
-{
- struct se_task *task = req->end_io_data;
- struct pscsi_plugin_task *pt = PSCSI_TASK(task);
-
- pt->pscsi_result = req->errors;
- pt->pscsi_resid = req->resid_len;
-
- pscsi_process_SAM_status(task, pt);
__blk_put_request(req->q, req);
+ kfree(pt);
}
static struct se_subsystem_api pscsi_template = {
@@ -1236,9 +1188,7 @@ static struct se_subsystem_api pscsi_template = {
.create_virtdevice = pscsi_create_virtdevice,
.free_device = pscsi_free_device,
.transport_complete = pscsi_transport_complete,
- .alloc_task = pscsi_alloc_task,
- .do_task = pscsi_do_task,
- .free_task = pscsi_free_task,
+ .execute_cmd = pscsi_execute_cmd,
.check_configfs_dev_params = pscsi_check_configfs_dev_params,
.set_configfs_dev_params = pscsi_set_configfs_dev_params,
.show_configfs_dev_params = pscsi_show_configfs_dev_params,
diff --git a/drivers/target/target_core_pscsi.h b/drivers/target/target_core_pscsi.h
index 43f1c419e8e..bc1e5e11eca 100644
--- a/drivers/target/target_core_pscsi.h
+++ b/drivers/target/target_core_pscsi.h
@@ -22,7 +22,6 @@
#include <linux/kobject.h>
struct pscsi_plugin_task {
- struct se_task pscsi_task;
unsigned char pscsi_sense[SCSI_SENSE_BUFFERSIZE];
int pscsi_direction;
int pscsi_result;
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index c6ce46891be..d0ceb873c0e 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -266,12 +266,6 @@ static void rd_free_device(void *p)
kfree(rd_dev);
}
-static struct se_task *
-rd_alloc_task(unsigned char *cdb)
-{
- return kzalloc(sizeof(struct se_task), GFP_KERNEL);
-}
-
static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page)
{
u32 i;
@@ -290,9 +284,10 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page)
return NULL;
}
-static int rd_do_task(struct se_task *task)
+static int rd_execute_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
+ u32 sgl_nents, enum dma_data_direction data_direction)
{
- struct se_device *se_dev = task->task_se_cmd->se_dev;
+ struct se_device *se_dev = cmd->se_dev;
struct rd_dev *dev = se_dev->dev_ptr;
struct rd_dev_sg_table *table;
struct scatterlist *rd_sg;
@@ -303,11 +298,10 @@ static int rd_do_task(struct se_task *task)
u32 src_len;
u64 tmp;
- tmp = task->task_se_cmd->t_task_lba *
- se_dev->se_sub_dev->se_dev_attrib.block_size;
+ tmp = cmd->t_task_lba * se_dev->se_sub_dev->se_dev_attrib.block_size;
rd_offset = do_div(tmp, PAGE_SIZE);
rd_page = tmp;
- rd_size = task->task_se_cmd->data_length;
+ rd_size = cmd->data_length;
table = rd_get_sg_table(dev, rd_page);
if (!table)
@@ -317,14 +311,12 @@ static int rd_do_task(struct se_task *task)
pr_debug("RD[%u]: %s LBA: %llu, Size: %u Page: %u, Offset: %u\n",
dev->rd_dev_id,
- task->task_data_direction == DMA_FROM_DEVICE ?
- "Read" : "Write",
- task->task_se_cmd->t_task_lba,
- rd_size, rd_page, rd_offset);
+ data_direction == DMA_FROM_DEVICE ? "Read" : "Write",
+ cmd->t_task_lba, rd_size, rd_page, rd_offset);
src_len = PAGE_SIZE - rd_offset;
- sg_miter_start(&m, task->task_sg, task->task_sg_nents,
- task->task_data_direction == DMA_FROM_DEVICE ?
+ sg_miter_start(&m, sgl, sgl_nents,
+ data_direction == DMA_FROM_DEVICE ?
SG_MITER_TO_SG : SG_MITER_FROM_SG);
while (rd_size) {
u32 len;
@@ -336,7 +328,7 @@ static int rd_do_task(struct se_task *task)
rd_addr = sg_virt(rd_sg) + rd_offset;
- if (task->task_data_direction == DMA_FROM_DEVICE)
+ if (data_direction == DMA_FROM_DEVICE)
memcpy(m.addr, rd_addr, len);
else
memcpy(rd_addr, m.addr, len);
@@ -371,16 +363,10 @@ static int rd_do_task(struct se_task *task)
}
sg_miter_stop(&m);
- task->task_scsi_status = GOOD;
- transport_complete_task(task, 1);
+ target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0;
}
-static void rd_free_task(struct se_task *task)
-{
- kfree(task);
-}
-
enum {
Opt_rd_pages, Opt_err
};
@@ -482,9 +468,7 @@ static struct se_subsystem_api rd_mcp_template = {
.allocate_virtdevice = rd_allocate_virtdevice,
.create_virtdevice = rd_create_virtdevice,
.free_device = rd_free_device,
- .alloc_task = rd_alloc_task,
- .do_task = rd_do_task,
- .free_task = rd_free_task,
+ .execute_cmd = rd_execute_cmd,
.check_configfs_dev_params = rd_check_configfs_dev_params,
.set_configfs_dev_params = rd_set_configfs_dev_params,
.show_configfs_dev_params = rd_show_configfs_dev_params,
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index e0ffbdc4a48..6e2378a88bd 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -374,13 +374,11 @@ static void core_tmr_drain_cmd_list(
struct se_queue_obj *qobj = &dev->dev_queue_obj;
struct se_cmd *cmd, *tcmd;
unsigned long flags;
+
/*
- * Release all commands remaining in the struct se_device cmd queue.
+ * Release all commands remaining in the per-device command queue.
*
- * This follows the same logic as above for the struct se_device
- * struct se_task state list, where commands are returned with
- * TASK_ABORTED status, if there is an outstanding $FABRIC_MOD
- * reference, otherwise the struct se_cmd is released.
+ * This follows the same logic as above for the state list.
*/
spin_lock_irqsave(&qobj->cmd_queue_lock, flags);
list_for_each_entry_safe(cmd, tcmd, &qobj->qobj_list, se_queue_node) {
diff --git a/drivers/target/target