]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/target/target_core_iblock.c
Merge branch 'for-3.7/core' of git://git.kernel.dk/linux-block
[karo-tx-linux.git] / drivers / target / target_core_iblock.c
index e58cd7d2fce48e6a4461b3372e1cf94e07a7a1cc..57d7674c50133c67430019efb98966b6013fa9e3 100644 (file)
@@ -325,17 +325,30 @@ static int iblock_execute_unmap(struct se_cmd *cmd)
        struct iblock_dev *ibd = dev->dev_ptr;
        unsigned char *buf, *ptr = NULL;
        sector_t lba;
-       int size = cmd->data_length;
+       int size;
        u32 range;
        int ret = 0;
        int dl, bd_dl;
 
+       if (cmd->data_length < 8) {
+               pr_warn("UNMAP parameter list length %u too small\n",
+                       cmd->data_length);
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               return -EINVAL;
+       }
+
        buf = transport_kmap_data_sg(cmd);
 
        dl = get_unaligned_be16(&buf[0]);
        bd_dl = get_unaligned_be16(&buf[2]);
 
-       size = min(size - 8, bd_dl);
+       size = cmd->data_length - 8;
+       if (bd_dl > size)
+               pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n",
+                       cmd->data_length, bd_dl);
+       else
+               size = bd_dl;
+
        if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
                cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
                ret = -EINVAL;
@@ -441,14 +454,11 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
                                ret = -EEXIST;
                                goto out;
                        }
-                       arg_p = match_strdup(&args[0]);
-                       if (!arg_p) {
-                               ret = -ENOMEM;
+                       if (match_strlcpy(ib_dev->ibd_udev_path, &args[0],
+                               SE_UDEV_PATH_LEN) == 0) {
+                               ret = -EINVAL;
                                break;
                        }
-                       snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN,
-                                       "%s", arg_p);
-                       kfree(arg_p);
                        pr_debug("IBLOCK: Referencing UDEV path: %s\n",
                                        ib_dev->ibd_udev_path);
                        ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH;
@@ -635,6 +645,12 @@ static int iblock_execute_rw(struct se_cmd *cmd)
                goto fail;
        cmd->priv = ibr;
 
+       if (!sgl_nents) {
+               atomic_set(&ibr->pending, 1);
+               iblock_complete_cmd(cmd);
+               return 0;
+       }
+
        bio = iblock_get_bio(cmd, block_lba, sgl_nents);
        if (!bio)
                goto fail_free_ibr;
@@ -747,8 +763,6 @@ static struct se_subsystem_api iblock_template = {
        .name                   = "iblock",
        .owner                  = THIS_MODULE,
        .transport_type         = TRANSPORT_PLUGIN_VHBA_PDEV,
-       .write_cache_emulated   = 1,
-       .fua_write_emulated     = 1,
        .attach_hba             = iblock_attach_hba,
        .detach_hba             = iblock_detach_hba,
        .allocate_virtdevice    = iblock_allocate_virtdevice,