Commit 5787cacd authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nicholas Bellinger

target: remove struct se_task

We can use struct se_cmd for everything it did.  Make sure to pass the S/G
list and data direction to the execution function to ease adding back BIDI
support later on.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent cf572a96
......@@ -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,
......
......@@ -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
......
......@@ -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,
......
......@@ -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;
......
This diff is collapsed.
......@@ -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;
......
......@@ -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,
......
......@@ -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) {
......
......@@ -72,7 +72,6 @@ static int __transport_execute_tasks(struct se_device *dev, struct se_cmd *);
static void transport_complete_task_attr(struct se_cmd *cmd);
static void transport_handle_queue_full(struct se_cmd *cmd,
struct se_device *dev);
static void transport_free_dev_tasks(struct se_cmd *cmd);
static int transport_generic_get_mem(struct se_cmd *cmd);
static void transport_put_cmd(struct se_cmd *cmd);
static void transport_remove_cmd_from_queue(struct se_cmd *cmd);
......@@ -662,28 +661,6 @@ static void transport_remove_cmd_from_queue(struct se_cmd *cmd)
spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
}
/*
* Completion function used by TCM subsystem plugins (such as FILEIO)
* for queueing up response from struct se_subsystem_api->do_task()
*/
void transport_complete_sync_cache(struct se_cmd *cmd, int good)
{
struct se_task *task = cmd->t_task;
if (good) {
cmd->scsi_status = SAM_STAT_GOOD;
task->task_scsi_status = GOOD;
} else {
task->task_scsi_status = SAM_STAT_CHECK_CONDITION;
task->task_se_cmd->scsi_sense_reason =
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
}
transport_complete_task(task, good);
}
EXPORT_SYMBOL(transport_complete_sync_cache);
static void target_complete_failure_work(struct work_struct *work)
{
struct se_cmd *cmd = container_of(work, struct se_cmd, work);
......@@ -691,35 +668,28 @@ static void target_complete_failure_work(struct work_struct *work)
transport_generic_request_failure(cmd);
}
/* transport_complete_task():
*
* Called from interrupt and non interrupt context depending
* on the transport plugin.
*/
void transport_complete_task(struct se_task *task, int success)
void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
int success = scsi_status == GOOD;
unsigned long flags;
cmd->scsi_status = scsi_status;
spin_lock_irqsave(&cmd->t_state_lock, flags);
cmd->transport_state &= ~CMD_T_BUSY;
/*
* See if any sense data exists, if so set the TASK_SENSE flag.
* Also check for any other post completion work that needs to be
* done by the plugins.
*/
if (dev && dev->transport->transport_complete) {
if (dev->transport->transport_complete(task) != 0) {
if (dev->transport->transport_complete(cmd,
cmd->t_data_sg) != 0) {
cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE;
success = 1;
}
}
/*
* See if we are waiting for outstanding struct se_task
* to complete for an exception condition
* See if we are waiting to complete for an exception condition.
*/
if (cmd->transport_state & CMD_T_REQUEST_STOP) {
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
......@@ -730,15 +700,11 @@ void transport_complete_task(struct se_task *task, int success)
if (!success)
cmd->transport_state |= CMD_T_FAILED;
/*
* Decrement the outstanding t_task_cdbs_left count. The last
* struct se_task from struct se_cmd will complete itself into the
* device queue depending upon int success.
*/
if (!atomic_dec_and_test(&cmd->t_task_cdbs_left)) {
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
return;
}
/*
* Check for case where an explict ABORT_TASK has been received
* and transport_wait_for_tasks() will be waiting for completion..
......@@ -761,15 +727,6 @@ void transport_complete_task(struct se_task *task, int success)
queue_work(target_completion_wq, &cmd->work);
}
EXPORT_SYMBOL(transport_complete_task);
void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
{
struct se_task *task = cmd->t_task;
task->task_scsi_status = scsi_status;
transport_complete_task(task, scsi_status == GOOD);
}
EXPORT_SYMBOL(target_complete_cmd);
static void target_add_to_state_list(struct se_cmd *cmd)
......@@ -2076,8 +2033,10 @@ static int __transport_execute_tasks(struct se_device *dev, struct se_cmd *new_c
if (cmd->execute_cmd)
error = cmd->execute_cmd(cmd);
else
error = dev->transport->do_task(cmd->t_task);
else {
error = dev->transport->execute_cmd(cmd, cmd->t_data_sg,
cmd->t_data_nents, cmd->data_direction);
}
if (error != 0) {
spin_lock_irqsave(&cmd->t_state_lock, flags);
......@@ -2312,7 +2271,6 @@ static int transport_get_sense_data(struct se_cmd *cmd)
{
unsigned char *buffer = cmd->sense_buffer, *sense_buffer = NULL;
struct se_device *dev = cmd->se_dev;
struct se_task *task = NULL;
unsigned long flags;
u32 offset = 0;
......@@ -2327,9 +2285,6 @@ static int transport_get_sense_data(struct se_cmd *cmd)
return 0;
}
if (!cmd->t_task)
goto out;
if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE))
goto out;
......@@ -2338,19 +2293,19 @@ static int transport_get_sense_data(struct se_cmd *cmd)
goto out;
}
sense_buffer = dev->transport->get_sense_buffer(task);
sense_buffer = dev->transport->get_sense_buffer(cmd);
if (!sense_buffer) {
pr_err("ITT[0x%08x]_TASK[%p]: Unable to locate"
pr_err("ITT 0x%08x cmd %p: Unable to locate"
" sense buffer for task with sense\n",
cmd->se_tfo->get_task_tag(cmd), task);
cmd->se_tfo->get_task_tag(cmd), cmd);
goto out;
}
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER);
memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER);
cmd->scsi_status = task->task_scsi_status;
/* Automatically padded */
cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset;
......@@ -3199,10 +3154,6 @@ static void target_complete_ok_work(struct work_struct *work)
if (transport_get_sense_data(cmd) < 0)
reason = TCM_NON_EXISTENT_LUN;
/*
* Only set when an struct se_task->task_scsi_status returned
* a non GOOD status.
*/
if (cmd->scsi_status) {
ret = transport_send_check_condition_and_sense(
cmd, reason, 1);
......@@ -3277,15 +3228,6 @@ static void target_complete_ok_work(struct work_struct *work)
transport_handle_queue_full(cmd, cmd->se_dev);
}
static void transport_free_dev_tasks(struct se_cmd *cmd)
{
struct se_task *task;
task = cmd->t_task;
if (task && !(cmd->transport_state & CMD_T_BUSY))
cmd->se_dev->transport->free_task(task);
}
static inline void transport_free_sgl(struct scatterlist *sgl, int nents)
{
struct scatterlist *sg;
......@@ -3346,7 +3288,6 @@ static void transport_release_cmd(struct se_cmd *cmd)
static void transport_put_cmd(struct se_cmd *cmd)
{
unsigned long flags;
int free_tasks = 0;
spin_lock_irqsave(&cmd->t_state_lock, flags);
if (atomic_read(&cmd->t_fe_count)) {
......@@ -3362,13 +3303,9 @@ static void transport_put_cmd(struct se_cmd *cmd)
if (cmd->transport_state & CMD_T_DEV_ACTIVE) {
cmd->transport_state &= ~CMD_T_DEV_ACTIVE;
target_remove_from_state_list(cmd);
free_tasks = 1;
}
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
if (free_tasks != 0)
transport_free_dev_tasks(cmd);
transport_free_pages(cmd);
transport_release_cmd(cmd);
return;
......@@ -3526,7 +3463,6 @@ transport_generic_get_mem(struct se_cmd *cmd)
int transport_generic_new_cmd(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct se_task *task;
int ret = 0;
/*
......@@ -3572,19 +3508,6 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
attr->max_sectors);
}
task = dev->transport->alloc_task(cmd->t_task_cdb);
if (!task) {
pr_err("Unable to allocate struct se_task\n");
goto out_fail;
}
task->task_se_cmd = cmd;
task->task_data_direction = cmd->data_direction;
task->task_sg = cmd->t_data_sg;
task->task_sg_nents = cmd->t_data_nents;
cmd->t_task = task;
atomic_inc(&cmd->t_fe_count);
atomic_inc(&cmd->t_se_count);
......@@ -3592,19 +3515,17 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
atomic_set(&cmd->t_task_cdbs_ex_left, 1);
/*
* For WRITEs, let the fabric know its buffer is ready..
* This WRITE struct se_cmd (and all of its associated struct se_task's)
* will be added to the struct se_device execution queue after its WRITE
* data has arrived. (ie: It gets handled by the transport processing
* thread a second time)
* For WRITEs, let the fabric know its buffer is ready.
*
* The command will be added to the execution queue after its write
* data has arrived.
*/
if (cmd->data_direction == DMA_TO_DEVICE) {
target_add_to_state_list(cmd);
return transport_generic_write_pending(cmd);
}
/*
* Everything else but a WRITE, add the struct se_cmd's struct se_task's
* to the execution queue.
* Everything else but a WRITE, add the command to the execution queue.
*/
transport_execute_tasks(cmd);
return 0;
......@@ -3691,8 +3612,6 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
if (cmd->se_lun)
transport_lun_remove_cmd(cmd);
transport_free_dev_tasks(cmd);
transport_put_cmd(cmd);
}
}
......@@ -3832,7 +3751,6 @@ EXPORT_SYMBOL(target_wait_for_sess_cmds);
*/
static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun)
{
struct se_task *task = cmd->t_task;
unsigned long flags;
int ret = 0;
......@@ -3944,7 +3862,6 @@ static void __transport_clear_lun_from_sessions(struct se_lun *lun)
target_remove_from_state_list(cmd);
spin_unlock_irqrestore(&cmd->t_state_lock, cmd_flags);
transport_free_dev_tasks(cmd);
/*
* The Storage engine stopped this struct se_cmd before it was
* send to the fabric frontend for delivery back to the
......
......@@ -23,12 +23,11 @@ struct se_subsystem_api {
struct se_device *(*create_virtdevice)(struct se_hba *,
struct se_subsystem_dev *, void *);
void (*free_device)(void *);
int (*transport_complete)(struct se_task *task);
struct se_task *(*alloc_task)(unsigned char *cdb);
int (*do_task)(struct se_task *);
int (*transport_complete)(struct se_cmd *cmd, struct scatterlist *);
int (*execute_cmd)(struct se_cmd *, struct scatterlist *, u32,
enum dma_data_direction);
int (*do_discard)(struct se_device *, sector_t, u32);
void (*do_sync_cache)(struct se_cmd *);
void (*free_task)(struct se_task *);
ssize_t (*check_configfs_dev_params)(struct se_hba *,
struct se_subsystem_dev *);
ssize_t (*set_configfs_dev_params)(struct se_hba *,
......@@ -38,7 +37,7 @@ struct se_subsystem_api {
u32 (*get_device_rev)(struct se_device *);
u32 (*get_device_type)(struct se_device *);
sector_t (*get_blocks)(struct se_device *);
unsigned char *(*get_sense_buffer)(struct se_task *);
unsigned char *(*get_sense_buffer)(struct se_cmd *);
};
int transport_subsystem_register(struct se_subsystem_api *);
......@@ -48,8 +47,6 @@ struct se_device *transport_add_device_to_core_hba(struct se_hba *,
struct se_subsystem_api *, struct se_subsystem_dev *, u32,
void *, struct se_dev_limits *, const char *, const char *);
void transport_complete_sync_cache(struct se_cmd *, int);
void transport_complete_task(struct se_task *, int);
void target_complete_cmd(struct se_cmd *, u8);
void transport_set_vpd_proto_id(struct t10_vpd *, unsigned char *);
......
......@@ -477,14 +477,6 @@ struct se_queue_obj {
wait_queue_head_t thread_wq;
};
struct se_task {
struct se_cmd *task_se_cmd;
struct scatterlist *task_sg;
u32 task_sg_nents;
u8 task_scsi_status;
enum dma_data_direction task_data_direction;
};
struct se_tmr_req {
/* Task Management function to be performed */
u8 function;
......@@ -592,7 +584,8 @@ struct se_cmd {
/* old task stop completion, consider merging with some of the above */
struct completion task_stop_comp;
struct se_task *t_task;
/* backend private data */
void *priv;
};
struct se_ua {
......
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