Skip to content

Commit

Permalink
target: remove struct se_task
Browse files Browse the repository at this point in the history
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: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
  • Loading branch information
Christoph Hellwig authored and Nicholas Bellinger committed May 6, 2012
1 parent cf572a9 commit 5787cac
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 423 deletions.
117 changes: 42 additions & 75 deletions drivers/target/target_core_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 {
Expand All @@ -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);
}
Expand All @@ -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.
Expand All @@ -389,46 +369,48 @@ 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;

/*
* 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 &&
Expand All @@ -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);
}

}
Expand All @@ -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
};
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 0 additions & 4 deletions drivers/target/target_core_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 5787cac

Please sign in to comment.