Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / drivers / target / target_core_file.c
index 2e7ea74..f286955 100644 (file)
  *
  ******************************************************************************/
 
-#include <linux/version.h>
 #include <linux/string.h>
 #include <linux/parser.h>
 #include <linux/timer.h>
 #include <linux/blkdev.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 
 #include <target/target_core_base.h>
-#include <target/target_core_device.h>
-#include <target/target_core_transport.h>
+#include <target/target_core_backend.h>
 
 #include "target_core_file.h"
 
-#if 1
-#define DEBUG_FD_CACHE(x...) printk(x)
-#else
-#define DEBUG_FD_CACHE(x...)
-#endif
-
-#if 1
-#define DEBUG_FD_FUA(x...) printk(x)
-#else
-#define DEBUG_FD_FUA(x...)
-#endif
-
 static struct se_subsystem_api fileio_template;
 
 /*     fd_attach_hba(): (Part of se_subsystem_api_t template)
@@ -65,8 +52,8 @@ static int fd_attach_hba(struct se_hba *hba, u32 host_id)
        struct fd_host *fd_host;
 
        fd_host = kzalloc(sizeof(struct fd_host), GFP_KERNEL);
-       if (!(fd_host)) {
-               printk(KERN_ERR "Unable to allocate memory for struct fd_host\n");
+       if (!fd_host) {
+               pr_err("Unable to allocate memory for struct fd_host\n");
                return -ENOMEM;
        }
 
@@ -74,10 +61,10 @@ static int fd_attach_hba(struct se_hba *hba, u32 host_id)
 
        hba->hba_ptr = fd_host;
 
-       printk(KERN_INFO "CORE_HBA[%d] - TCM FILEIO HBA Driver %s on Generic"
+       pr_debug("CORE_HBA[%d] - TCM FILEIO HBA Driver %s on Generic"
                " Target Core Stack %s\n", hba->hba_id, FD_VERSION,
                TARGET_CORE_MOD_VERSION);
-       printk(KERN_INFO "CORE_HBA[%d] - Attached FILEIO HBA: %u to Generic"
+       pr_debug("CORE_HBA[%d] - Attached FILEIO HBA: %u to Generic"
                " MaxSectors: %u\n",
                hba->hba_id, fd_host->fd_host_id, FD_MAX_SECTORS);
 
@@ -88,7 +75,7 @@ static void fd_detach_hba(struct se_hba *hba)
 {
        struct fd_host *fd_host = hba->hba_ptr;
 
-       printk(KERN_INFO "CORE_HBA[%d] - Detached FILEIO HBA: %u from Generic"
+       pr_debug("CORE_HBA[%d] - Detached FILEIO HBA: %u from Generic"
                " Target Core\n", hba->hba_id, fd_host->fd_host_id);
 
        kfree(fd_host);
@@ -98,17 +85,17 @@ static void fd_detach_hba(struct se_hba *hba)
 static void *fd_allocate_virtdevice(struct se_hba *hba, const char *name)
 {
        struct fd_dev *fd_dev;
-       struct fd_host *fd_host = (struct fd_host *) hba->hba_ptr;
+       struct fd_host *fd_host = hba->hba_ptr;
 
        fd_dev = kzalloc(sizeof(struct fd_dev), GFP_KERNEL);
-       if (!(fd_dev)) {
-               printk(KERN_ERR "Unable to allocate memory for struct fd_dev\n");
+       if (!fd_dev) {
+               pr_err("Unable to allocate memory for struct fd_dev\n");
                return NULL;
        }
 
        fd_dev->fd_host = fd_host;
 
-       printk(KERN_INFO "FILEIO: Allocated fd_dev for %p\n", name);
+       pr_debug("FILEIO: Allocated fd_dev for %p\n", name);
 
        return fd_dev;
 }
@@ -126,8 +113,8 @@ static struct se_device *fd_create_virtdevice(
        struct se_device *dev;
        struct se_dev_limits dev_limits;
        struct queue_limits *limits;
-       struct fd_dev *fd_dev = (struct fd_dev *) p;
-       struct fd_host *fd_host = (struct fd_host *) hba->hba_ptr;
+       struct fd_dev *fd_dev = p;
+       struct fd_host *fd_host = hba->hba_ptr;
        mm_segment_t old_fs;
        struct file *file;
        struct inode *inode = NULL;
@@ -141,7 +128,7 @@ static struct se_device *fd_create_virtdevice(
        set_fs(old_fs);
 
        if (IS_ERR(dev_p)) {
-               printk(KERN_ERR "getname(%s) failed: %lu\n",
+               pr_err("getname(%s) failed: %lu\n",
                        fd_dev->fd_dev_name, IS_ERR(dev_p));
                ret = PTR_ERR(dev_p);
                goto fail;
@@ -164,12 +151,12 @@ static struct se_device *fd_create_virtdevice(
 
        file = filp_open(dev_p, flags, 0600);
        if (IS_ERR(file)) {
-               printk(KERN_ERR "filp_open(%s) failed\n", dev_p);
+               pr_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);
+               pr_err("filp_open(%s) failed\n", dev_p);
                goto fail;
        }
        fd_dev->fd_file = file;
@@ -182,6 +169,7 @@ static struct se_device *fd_create_virtdevice(
        inode = file->f_mapping->host;
        if (S_ISBLK(inode->i_mode)) {
                struct request_queue *q;
+               unsigned long long dev_size;
                /*
                 * 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.
@@ -196,17 +184,16 @@ static struct se_device *fd_create_virtdevice(
                 * one (1) logical sector from underlying struct block_device
                 */
                fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev);
-               fd_dev->fd_dev_size = (i_size_read(file->f_mapping->host) -
+               dev_size = (i_size_read(file->f_mapping->host) -
                                       fd_dev->fd_block_size);
 
-               printk(KERN_INFO "FILEIO: Using size: %llu bytes from struct"
+               pr_debug("FILEIO: Using size: %llu bytes from struct"
                        " block_device blocks: %llu logical_block_size: %d\n",
-                       fd_dev->fd_dev_size,
-                       div_u64(fd_dev->fd_dev_size, fd_dev->fd_block_size),
+                       dev_size, div_u64(dev_size, fd_dev->fd_block_size),
                        fd_dev->fd_block_size);
        } else {
                if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) {
-                       printk(KERN_ERR "FILEIO: Missing fd_dev_size="
+                       pr_err("FILEIO: Missing fd_dev_size="
                                " parameter, and no backing struct"
                                " block_device\n");
                        goto fail;
@@ -225,13 +212,13 @@ static struct se_device *fd_create_virtdevice(
        dev = transport_add_device_to_core_hba(hba, &fileio_template,
                                se_dev, dev_flags, fd_dev,
                                &dev_limits, "FILEIO", FD_VERSION);
-       if (!(dev))
+       if (!dev)
                goto fail;
 
        fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
        fd_dev->fd_queue_depth = dev->queue_depth;
 
-       printk(KERN_INFO "CORE_FILE[%u] - Added TCM FILEIO Device ID: %u at %s,"
+       pr_debug("CORE_FILE[%u] - Added TCM FILEIO Device ID: %u at %s,"
                " %llu total bytes\n", fd_host->fd_host_id, fd_dev->fd_dev_id,
                        fd_dev->fd_dev_name, fd_dev->fd_dev_size);
 
@@ -252,7 +239,7 @@ fail:
  */
 static void fd_free_device(void *p)
 {
-       struct fd_dev *fd_dev = (struct fd_dev *) p;
+       struct fd_dev *fd_dev = p;
 
        if (fd_dev->fd_file) {
                filp_close(fd_dev->fd_file, NULL);
@@ -269,46 +256,46 @@ static inline struct fd_request *FILE_REQ(struct se_task *task)
 
 
 static struct se_task *
-fd_alloc_task(struct se_cmd *cmd)
+fd_alloc_task(unsigned char *cdb)
 {
        struct fd_request *fd_req;
 
        fd_req = kzalloc(sizeof(struct fd_request), GFP_KERNEL);
-       if (!(fd_req)) {
-               printk(KERN_ERR "Unable to allocate struct fd_request\n");
+       if (!fd_req) {
+               pr_err("Unable to allocate struct fd_request\n");
                return NULL;
        }
 
-       fd_req->fd_dev = cmd->se_dev->dev_ptr;
-
        return &fd_req->fd_task;
 }
 
 static int fd_do_readv(struct se_task *task)
 {
        struct fd_request *req = FILE_REQ(task);
-       struct file *fd = req->fd_dev->fd_file;
+       struct se_device *se_dev = req->fd_task.task_se_cmd->se_dev;
+       struct fd_dev *dev = se_dev->dev_ptr;
+       struct file *fd = dev->fd_file;
        struct scatterlist *sg = task->task_sg;
        struct iovec *iov;
        mm_segment_t old_fs;
        loff_t pos = (task->task_lba *
-                     task->se_dev->se_sub_dev->se_dev_attrib.block_size);
+                     se_dev->se_sub_dev->se_dev_attrib.block_size);
        int ret = 0, i;
 
-       iov = kzalloc(sizeof(struct iovec) * task->task_sg_num, GFP_KERNEL);
-       if (!(iov)) {
-               printk(KERN_ERR "Unable to allocate fd_do_readv iov[]\n");
+       iov = kzalloc(sizeof(struct iovec) * task->task_sg_nents, GFP_KERNEL);
+       if (!iov) {
+               pr_err("Unable to allocate fd_do_readv iov[]\n");
                return -ENOMEM;
        }
 
-       for (i = 0; i < task->task_sg_num; i++) {
-               iov[i].iov_len = sg[i].length;
-               iov[i].iov_base = sg_virt(&sg[i]);
+       for_each_sg(task->task_sg, sg, task->task_sg_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_num, &pos);
+       ret = vfs_readv(fd, &iov[0], task->task_sg_nents, &pos);
        set_fs(old_fs);
 
        kfree(iov);
@@ -319,14 +306,14 @@ static int fd_do_readv(struct se_task *task)
         */
        if (S_ISBLK(fd->f_dentry->d_inode->i_mode)) {
                if (ret < 0 || ret != task->task_size) {
-                       printk(KERN_ERR "vfs_readv() returned %d,"
+                       pr_err("vfs_readv() returned %d,"
                                " expecting %d for S_ISBLK\n", ret,
                                (int)task->task_size);
                        return (ret < 0 ? ret : -EINVAL);
                }
        } else {
                if (ret < 0) {
-                       printk(KERN_ERR "vfs_readv() returned %d for non"
+                       pr_err("vfs_readv() returned %d for non"
                                " S_ISBLK\n", ret);
                        return ret;
                }
@@ -338,34 +325,36 @@ static int fd_do_readv(struct se_task *task)
 static int fd_do_writev(struct se_task *task)
 {
        struct fd_request *req = FILE_REQ(task);
-       struct file *fd = req->fd_dev->fd_file;
+       struct se_device *se_dev = req->fd_task.task_se_cmd->se_dev;
+       struct fd_dev *dev = se_dev->dev_ptr;
+       struct file *fd = dev->fd_file;
        struct scatterlist *sg = task->task_sg;
        struct iovec *iov;
        mm_segment_t old_fs;
        loff_t pos = (task->task_lba *
-                     task->se_dev->se_sub_dev->se_dev_attrib.block_size);
+                     se_dev->se_sub_dev->se_dev_attrib.block_size);
        int ret, i = 0;
 
-       iov = kzalloc(sizeof(struct iovec) * task->task_sg_num, GFP_KERNEL);
-       if (!(iov)) {
-               printk(KERN_ERR "Unable to allocate fd_do_writev iov[]\n");
+       iov = kzalloc(sizeof(struct iovec) * task->task_sg_nents, GFP_KERNEL);
+       if (!iov) {
+               pr_err("Unable to allocate fd_do_writev iov[]\n");
                return -ENOMEM;
        }
 
-       for (i = 0; i < task->task_sg_num; i++) {
-               iov[i].iov_len = sg[i].length;
-               iov[i].iov_base = sg_virt(&sg[i]);
+       for_each_sg(task->task_sg, sg, task->task_sg_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_num, &pos);
+       ret = vfs_writev(fd, &iov[0], task->task_sg_nents, &pos);
        set_fs(old_fs);
 
        kfree(iov);
 
        if (ret < 0 || ret != task->task_size) {
-               printk(KERN_ERR "vfs_writev() returned %d\n", ret);
+               pr_err("vfs_writev() returned %d\n", ret);
                return (ret < 0 ? ret : -EINVAL);
        }
 
@@ -377,7 +366,7 @@ static void fd_emulate_sync_cache(struct se_task *task)
        struct se_cmd *cmd = task->task_se_cmd;
        struct se_device *dev = cmd->se_dev;
        struct fd_dev *fd_dev = dev->dev_ptr;
-       int immed = (cmd->t_task.t_task_cdb[1] & 0x2);
+       int immed = (cmd->t_task_cdb[1] & 0x2);
        loff_t start, end;
        int ret;
 
@@ -391,11 +380,11 @@ static void fd_emulate_sync_cache(struct se_task *task)
        /*
         * Determine if we will be flushing the entire device.
         */
-       if (cmd->t_task.t_task_lba == 0 && cmd->data_length == 0) {
+       if (cmd->t_task_lba == 0 && cmd->data_length == 0) {
                start = 0;
                end = LLONG_MAX;
        } else {
-               start = cmd->t_task.t_task_lba * dev->se_sub_dev->se_dev_attrib.block_size;
+               start = cmd->t_task_lba * dev->se_sub_dev->se_dev_attrib.block_size;
                if (cmd->data_length)
                        end = start + cmd->data_length;
                else
@@ -404,40 +393,13 @@ static void fd_emulate_sync_cache(struct se_task *task)
 
        ret = vfs_fsync_range(fd_dev->fd_file, start, end, 1);
        if (ret != 0)
-               printk(KERN_ERR "FILEIO: vfs_fsync_range() failed: %d\n", ret);
+               pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret);
 
        if (!immed)
                transport_complete_sync_cache(cmd, ret == 0);
 }
 
 /*
- * Tell TCM Core that we are capable of WriteCache emulation for
- * an underlying struct se_device.
- */
-static int fd_emulated_write_cache(struct se_device *dev)
-{
-       return 1;
-}
-
-static int fd_emulated_dpo(struct se_device *dev)
-{
-       return 0;
-}
-/*
- * Tell TCM Core that we will be emulating Forced Unit Access (FUA) for WRITEs
- * for TYPE_DISK.
- */
-static int fd_emulated_fua_write(struct se_device *dev)
-{
-       return 1;
-}
-
-static int fd_emulated_fua_read(struct se_device *dev)
-{
-       return 0;
-}
-
-/*
  * WRITE Force Unit Access (FUA) emulation on a per struct se_task
  * LBA range basis..
  */
@@ -449,12 +411,12 @@ static void fd_emulate_write_fua(struct se_cmd *cmd, struct se_task *task)
        loff_t end = start + task->task_size;
        int ret;
 
-       DEBUG_FD_CACHE("FILEIO: FUA WRITE LBA: %llu, bytes: %u\n",
+       pr_debug("FILEIO: FUA WRITE LBA: %llu, bytes: %u\n",
                        task->task_lba, task->task_size);
 
        ret = vfs_fsync_range(fd_dev->fd_file, start, end, 1);
        if (ret != 0)
-               printk(KERN_ERR "FILEIO: vfs_fsync_range() failed: %d\n", ret);
+               pr_err("FILEIO: vfs_fsync_range() failed: %d\n", ret);
 }
 
 static int fd_do_task(struct se_task *task)
@@ -475,7 +437,7 @@ static int fd_do_task(struct se_task *task)
                if (ret > 0 &&
                    dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 &&
                    dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 &&
-                   cmd->t_task.t_tasks_fua) {
+                   (cmd->se_cmd_flags & SCF_FUA)) {
                        /*
                         * We might need to be a bit smarter here
                         * and return some sense data to let the initiator
@@ -486,13 +448,15 @@ static int fd_do_task(struct se_task *task)
 
        }
 
-       if (ret < 0)
+       if (ret < 0) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                return ret;
+       }
        if (ret) {
                task->task_scsi_status = GOOD;
                transport_complete_task(task, 1);
        }
-       return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+       return 0;
 }
 
 /*     fd_free_task(): (Part of se_subsystem_api_t template)
@@ -533,7 +497,7 @@ static ssize_t fd_set_configfs_dev_params(
 
        orig = opts;
 
-       while ((ptr = strsep(&opts, ",")) != NULL) {
+       while ((ptr = strsep(&opts, ",\n")) != NULL) {
                if (!*ptr)
                        continue;
 
@@ -548,7 +512,7 @@ static ssize_t fd_set_configfs_dev_params(
                        snprintf(fd_dev->fd_dev_name, FD_MAX_DEV_NAME,
                                        "%s", arg_p);
                        kfree(arg_p);
-                       printk(KERN_INFO "FILEIO: Referencing Path: %s\n",
+                       pr_debug("FILEIO: Referencing Path: %s\n",
                                        fd_dev->fd_dev_name);
                        fd_dev->fbd_flags |= FBDF_HAS_PATH;
                        break;
@@ -561,23 +525,23 @@ static ssize_t fd_set_configfs_dev_params(
                        ret = strict_strtoull(arg_p, 0, &fd_dev->fd_dev_size);
                        kfree(arg_p);
                        if (ret < 0) {
-                               printk(KERN_ERR "strict_strtoull() failed for"
+                               pr_err("strict_strtoull() failed for"
                                                " fd_dev_size=\n");
                                goto out;
                        }
-                       printk(KERN_INFO "FILEIO: Referencing Size: %llu"
+                       pr_debug("FILEIO: Referencing Size: %llu"
                                        " bytes\n", fd_dev->fd_dev_size);
                        fd_dev->fbd_flags |= FBDF_HAS_SIZE;
                        break;
                case Opt_fd_buffered_io:
                        match_int(args, &arg);
                        if (arg != 1) {
-                               printk(KERN_ERR "bogus fd_buffered_io=%d value\n", arg);
+                               pr_err("bogus fd_buffered_io=%d value\n", arg);
                                ret = -EINVAL;
                                goto out;
                        }
 
-                       printk(KERN_INFO "FILEIO: Using buffered I/O"
+                       pr_debug("FILEIO: Using buffered I/O"
                                " operations for struct fd_dev\n");
 
                        fd_dev->fbd_flags |= FDBD_USE_BUFFERED_IO;
@@ -594,10 +558,10 @@ out:
 
 static ssize_t fd_check_configfs_dev_params(struct se_hba *hba, struct se_subsystem_dev *se_dev)
 {
-       struct fd_dev *fd_dev = (struct fd_dev *) se_dev->se_dev_su_ptr;
+       struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
 
        if (!(fd_dev->fbd_flags & FBDF_HAS_PATH)) {
-               printk(KERN_ERR "Missing fd_dev_name=\n");
+               pr_err("Missing fd_dev_name=\n");
                return -EINVAL;
        }
 
@@ -620,17 +584,6 @@ static ssize_t fd_show_configfs_dev_params(
        return bl;
 }
 
-/*     fd_get_cdb(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static unsigned char *fd_get_cdb(struct se_task *task)
-{
-       struct fd_request *req = FILE_REQ(task);
-
-       return req->fd_scsi_cdb;
-}
-
 /*     fd_get_device_rev(): (Part of se_subsystem_api_t template)
  *
  *
@@ -652,25 +605,33 @@ static u32 fd_get_device_type(struct se_device *dev)
 static sector_t fd_get_blocks(struct se_device *dev)
 {
        struct fd_dev *fd_dev = dev->dev_ptr;
-       unsigned long long blocks_long = div_u64(fd_dev->fd_dev_size,
-                       dev->se_sub_dev->se_dev_attrib.block_size);
+       struct file *f = fd_dev->fd_file;
+       struct inode *i = f->f_mapping->host;
+       unsigned long long dev_size;
+       /*
+        * When using a file that references an underlying struct block_device,
+        * ensure dev_size is always based on the current inode size in order
+        * to handle underlying block_device resize operations.
+        */
+       if (S_ISBLK(i->i_mode))
+               dev_size = (i_size_read(i) - fd_dev->fd_block_size);
+       else
+               dev_size = fd_dev->fd_dev_size;
 
-       return blocks_long;
+       return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size);
 }
 
 static struct se_subsystem_api fileio_template = {
        .name                   = "fileio",
        .owner                  = THIS_MODULE,
        .transport_type         = TRANSPORT_PLUGIN_VHBA_PDEV,
+       .write_cache_emulated   = 1,
+       .fua_write_emulated     = 1,
        .attach_hba             = fd_attach_hba,
        .detach_hba             = fd_detach_hba,
        .allocate_virtdevice    = fd_allocate_virtdevice,
        .create_virtdevice      = fd_create_virtdevice,
        .free_device            = fd_free_device,
-       .dpo_emulated           = fd_emulated_dpo,
-       .fua_write_emulated     = fd_emulated_fua_write,
-       .fua_read_emulated      = fd_emulated_fua_read,
-       .write_cache_emulated   = fd_emulated_write_cache,
        .alloc_task             = fd_alloc_task,
        .do_task                = fd_do_task,
        .do_sync_cache          = fd_emulate_sync_cache,
@@ -678,7 +639,6 @@ static struct se_subsystem_api fileio_template = {
        .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,
-       .get_cdb                = fd_get_cdb,
        .get_device_rev         = fd_get_device_rev,
        .get_device_type        = fd_get_device_type,
        .get_blocks             = fd_get_blocks,