Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 367351
b: refs/heads/master
c: 5064276
h: refs/heads/master
i:
  367349: 5b9ce17
  367347: 83acd1c
  367343: 4d4b07d
v: v3
  • Loading branch information
Asias He authored and Nicholas Bellinger committed Apr 25, 2013
1 parent c224567 commit 1f83bdd
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 70d3ae5c80758cb2bf3cf1e0d5b2c89d040de90b
refs/heads/master: 506427628afeb5d70eefdac1fe4c2a1ffb27df5f
111 changes: 111 additions & 0 deletions trunk/drivers/target/target_core_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <linux/falloc.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <asm/unaligned.h>

#include <target/target_core_base.h>
#include <target/target_core_backend.h>
Expand Down Expand Up @@ -524,6 +525,115 @@ fd_execute_write_same_unmap(struct se_cmd *cmd)
return 0;
}

static sense_reason_t
fd_execute_unmap(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
struct fd_dev *fd_dev = FD_DEV(dev);
struct file *file = fd_dev->fd_file;
struct inode *inode = file->f_mapping->host;
unsigned char *buf, *ptr = NULL;
sector_t lba;
int size;
u32 range;
sense_reason_t ret = 0;
int dl, bd_dl, err;

/* 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;
}

if (S_ISBLK(inode->i_mode)) {
/* The backend is block device, use discard */
struct block_device *bdev = inode->i_bdev;

err = blkdev_issue_discard(bdev, lba, range, GFP_KERNEL, 0);
if (err < 0) {
pr_err("FILEIO: blkdev_issue_discard() failed: %d\n",
err);
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
goto err;
}
} else {
/* The backend is normal file, use fallocate */
loff_t pos = lba * dev->dev_attrib.block_size;
unsigned int len = range * dev->dev_attrib.block_size;
int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;

if (!file->f_op->fallocate) {
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
goto err;
}
err = file->f_op->fallocate(file, mode, pos, len);
if (err < 0) {
pr_warn("FILEIO: fallocate() failed: %d\n", err);
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
goto err;
}
}

ptr += 16;
size -= 16;
}

err:
transport_kunmap_data_sg(cmd);
if (!ret)
target_complete_cmd(cmd, GOOD);
return ret;
}

static sense_reason_t
fd_execute_rw(struct se_cmd *cmd)
{
Expand Down Expand Up @@ -684,6 +794,7 @@ static struct sbc_ops fd_sbc_ops = {
.execute_sync_cache = fd_execute_sync_cache,
.execute_write_same = fd_execute_write_same,
.execute_write_same_unmap = fd_execute_write_same_unmap,
.execute_unmap = fd_execute_unmap,
};

static sense_reason_t
Expand Down

0 comments on commit 1f83bdd

Please sign in to comment.