Re: [PATCH] target/file: Add WRITE_SAME w/ UNMAP=1 emulation support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2013-02-21 at 13:57 +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.
> 
> 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 | 48 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 48 insertions(+)
> 
> diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
> index 94383a5..2a9ce12 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>
>  
> @@ -442,6 +443,52 @@ fd_execute_write_same(struct se_cmd *cmd)
>  }
>  
>  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 = spc_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;
> +}
> +

So you'll also need to set the various dev->dev_attrib.*unmap* values
for EVPD Block Limits at fd_configure_device() time..  Check out
iblock_configure_device() to see how this is currently done for the
underlying struct block_device case from request_queue->limits.

For the fallocate() case, you'll need to add some sane defaults here
too.

As for the direct blkdev_issue_discard usage() within FILEIO code, I
don't have a problem with it, but I'd really like to get hch's feedback
here..

--nab







> +static sense_reason_t
>  fd_execute_rw(struct se_cmd *cmd)
>  {
>  	struct scatterlist *sgl = cmd->t_data_sg;
> @@ -600,6 +647,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


--
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


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux