On Mon, 2013-02-25 at 14:03 +0800, Asias He wrote: > This patch adds support for emulation of WRITE_SAME w/ UNMAP=1 within > fd_execute_write_same_unmap() backend code. > > If the FILEIO backend is normal file, the emulation uses fallocate to > punch hole to reclaim the free space used by the file. If the FILEIO > backend is block device, the emulation uses blkdev_issue_discard(). > > Tested with 512, 1k, 2k, and 4k block_sizes. > > Changes in v2: > - Set the various dev->dev_attrib.*unmap* values (nab) > > Cc: Christoph Hellwig <hch@xxxxxx> > Cc: Martin K. Petersen <martin.petersen@xxxxxxxxxx> > Cc: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> > Signed-off-by: Asias He <asias@xxxxxxxxxx> > --- > drivers/target/target_core_file.c | 94 ++++++++++++++++++++++++++++++++++++--- > 1 file changed, 89 insertions(+), 5 deletions(-) > > diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c > index ca36a38..eafa1bf 100644 > --- a/drivers/target/target_core_file.c > +++ b/drivers/target/target_core_file.c > @@ -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> > > @@ -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; Ok, this should still be limited to 0x1000 (same as below) due to the vfs_writev() limitiation on number of struct iovecs. > } else { > if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) { > pr_err("FILEIO: Missing fd_dev_size=" > @@ -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; > } > Squashing the following into patch #1 in target-pending/queue. --nab diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index eafa1bf..eb6f16b 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -186,11 +186,6 @@ static int fd_configure_device(struct se_device *dev) 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=" @@ -212,13 +207,12 @@ static int fd_configure_device(struct se_device *dev) 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; } + /* + * 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; -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html