summaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_iblock.c
diff options
context:
space:
mode:
authorAsias He <asias@redhat.com>2013-02-25 14:03:46 +0800
committerNicholas Bellinger <nab@linux-iscsi.org>2013-04-25 01:05:24 -0700
commit86d7182985d25900929adce14fffd729cc8c6fb8 (patch)
tree8e5e755c5badf3a09b5b0c4e6c2f76c72c080dcf /drivers/target/target_core_iblock.c
parentdbc21c5abbeb4419da5a54157c4b7a0ec0dee185 (diff)
downloadlinux-86d7182985d25900929adce14fffd729cc8c6fb8.tar.bz2
target: Add sbc_execute_unmap() helper
iblock_execute_unmap() and fd_execute_unmap share a lot of code. Add sbc_execute_unmap() helper to remove duplicated code for iblock_execute_unmap() and fd_execute_unmap(). Cc: Christoph Hellwig <hch@lst.de> Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Asias He <asias@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_iblock.c')
-rw-r--r--drivers/target/target_core_iblock.c81
1 files changed, 4 insertions, 77 deletions
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 96a9b620e89a..07f5f94634bb 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -380,9 +380,10 @@ iblock_execute_sync_cache(struct se_cmd *cmd)
}
static sense_reason_t
-iblock_do_unmap(struct se_cmd *cmd, struct block_device *bdev,
+iblock_do_unmap(struct se_cmd *cmd, void *priv,
sector_t lba, sector_t nolb)
{
+ struct block_device *bdev = priv;
int ret;
ret = blkdev_issue_discard(bdev, lba, nolb, GFP_KERNEL, 0);
@@ -397,83 +398,9 @@ iblock_do_unmap(struct se_cmd *cmd, struct block_device *bdev,
static sense_reason_t
iblock_execute_unmap(struct se_cmd *cmd)
{
- struct se_device *dev = cmd->se_dev;
- struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
- unsigned char *buf, *ptr = NULL;
- sector_t lba;
- int size;
- u32 range;
- sense_reason_t ret = 0;
- int dl, bd_dl;
-
- /* We never set ANC_SUP */
- if (cmd->t_task_cdb[1])
- return TCM_INVALID_CDB_FIELD;
-
- if (cmd->data_length == 0) {
- target_complete_cmd(cmd, SAM_STAT_GOOD);
- return 0;
- }
-
- if (cmd->data_length < 8) {
- pr_warn("UNMAP parameter list length %u too small\n",
- cmd->data_length);
- return TCM_PARAMETER_LIST_LENGTH_ERROR;
- }
-
- buf = transport_kmap_data_sg(cmd);
- if (!buf)
- return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-
- dl = get_unaligned_be16(&buf[0]);
- bd_dl = get_unaligned_be16(&buf[2]);
-
- 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->dev_attrib.max_unmap_block_desc_count) {
- ret = TCM_INVALID_PARAMETER_LIST;
- goto err;
- }
-
- /* First UNMAP block descriptor starts at 8 byte offset */
- ptr = &buf[8];
- pr_debug("UNMAP: Sub: %s Using dl: %u bd_dl: %u size: %u"
- " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr);
-
- while (size >= 16) {
- lba = get_unaligned_be64(&ptr[0]);
- range = get_unaligned_be32(&ptr[8]);
- pr_debug("UNMAP: Using lba: %llu and range: %u\n",
- (unsigned long long)lba, range);
-
- if (range > dev->dev_attrib.max_unmap_lba_count) {
- ret = TCM_INVALID_PARAMETER_LIST;
- goto err;
- }
-
- if (lba + range > dev->transport->get_blocks(dev) + 1) {
- ret = TCM_ADDRESS_OUT_OF_RANGE;
- goto err;
- }
-
- ret = iblock_do_unmap(cmd, ib_dev->ibd_bd, lba, range);
- if (ret)
- goto err;
-
- ptr += 16;
- size -= 16;
- }
+ struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd;
-err:
- transport_kunmap_data_sg(cmd);
- if (!ret)
- target_complete_cmd(cmd, GOOD);
- return ret;
+ return sbc_execute_unmap(cmd, iblock_do_unmap, bdev);
}
static sense_reason_t