Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 367350
b: refs/heads/master
c: 70d3ae5
h: refs/heads/master
v: v3
  • Loading branch information
Asias He authored and Nicholas Bellinger committed Apr 25, 2013
1 parent 5b9ce17 commit c224567
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c0c2dd499b7ae3d4d314ef2965ee2387848a39d9
refs/heads/master: 70d3ae5c80758cb2bf3cf1e0d5b2c89d040de90b
94 changes: 89 additions & 5 deletions trunk/drivers/target/target_core_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/falloc.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>

Expand Down Expand Up @@ -166,6 +167,30 @@ static int fd_configure_device(struct se_device *dev)
" block_device blocks: %llu logical_block_size: %d\n",
dev_size, div_u64(dev_size, fd_dev->fd_block_size),
fd_dev->fd_block_size);
/*
* Check if the underlying struct block_device request_queue supports
* the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
* in ATA and we need to set TPE=1
*/
if (blk_queue_discard(q)) {
dev->dev_attrib.max_unmap_lba_count =
q->limits.max_discard_sectors;
/*
* Currently hardcoded to 1 in Linux/SCSI code..
*/
dev->dev_attrib.max_unmap_block_desc_count = 1;
dev->dev_attrib.unmap_granularity =
q->limits.discard_granularity >> 9;
dev->dev_attrib.unmap_granularity_alignment =
q->limits.discard_alignment;
pr_debug("IFILE: BLOCK Discard support available,"
" disabled by default\n");
}
/*
* Enable write same emulation for IBLOCK and use 0xFFFF as
* the smaller WRITE_SAME(10) only has a two-byte block count.
*/
dev->dev_attrib.max_write_same_len = 0xFFFF;
} else {
if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) {
pr_err("FILEIO: Missing fd_dev_size="
Expand All @@ -176,6 +201,23 @@ static int fd_configure_device(struct se_device *dev)

dev->dev_attrib.hw_block_size = FD_BLOCKSIZE;
dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS;

/*
* Limit UNMAP emulation to 8k Number of LBAs (NoLB)
*/
dev->dev_attrib.max_unmap_lba_count = 0x2000;
/*
* Currently hardcoded to 1 in Linux/SCSI code..
*/
dev->dev_attrib.max_unmap_block_desc_count = 1;
dev->dev_attrib.unmap_granularity = 1;
dev->dev_attrib.unmap_granularity_alignment = 0;

/*
* Limit WRITE_SAME w/ UNMAP=0 emulation to 8k Number of LBAs (NoLB)
* based upon struct iovec limit for vfs_writev()
*/
dev->dev_attrib.max_write_same_len = 0x1000;
}

fd_dev->fd_block_size = dev->dev_attrib.hw_block_size;
Expand All @@ -190,11 +232,6 @@ static int fd_configure_device(struct se_device *dev)

fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
fd_dev->fd_queue_depth = dev->queue_depth;
/*
* Limit WRITE_SAME w/ UNMAP=0 emulation to 8k Number of LBAs (NoLB)
* based upon struct iovec limit for vfs_writev()
*/
dev->dev_attrib.max_write_same_len = 0x1000;

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,
Expand Down Expand Up @@ -441,6 +478,52 @@ fd_execute_write_same(struct se_cmd *cmd)
return 0;
}

static sense_reason_t
fd_execute_write_same_unmap(struct se_cmd *cmd)
{
struct se_device *se_dev = cmd->se_dev;
struct fd_dev *fd_dev = FD_DEV(se_dev);
struct file *file = fd_dev->fd_file;
struct inode *inode = file->f_mapping->host;
sector_t nolb = sbc_get_write_same_sectors(cmd);
int ret;

if (!nolb) {
target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0;
}

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

ret = blkdev_issue_discard(bdev, cmd->t_task_lba,
nolb, GFP_KERNEL, 0);
if (ret < 0) {
pr_warn("FILEIO: blkdev_issue_discard() failed: %d\n",
ret);
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
}
} else {
/* The backend is normal file, use fallocate */
loff_t pos = cmd->t_task_lba * se_dev->dev_attrib.block_size;
unsigned int len = nolb * se_dev->dev_attrib.block_size;
int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;

if (!file->f_op->fallocate)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

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

target_complete_cmd(cmd, GOOD);
return 0;
}

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

static sense_reason_t
Expand Down

0 comments on commit c224567

Please sign in to comment.