[dm-devel] [PATCH 1/3] block: invalidate the page cache when issuing BLKZEROOUT.

Bart Van Assche bart.vanassche at gmail.com
Mon Jun 20 12:35:29 UTC 2016


On 06/17/2016 03:18 AM, Darrick J. Wong wrote:
> Invalidate the page cache (as a regular O_DIRECT write would do) to avoid
> returning stale cache contents at a later time.
>
> v5: Refactor the 4.4 refactoring of the ioctl code into separate functions.
> Split the page invalidation and the new ioctl into separate patches.
>
> Signed-off-by: Darrick J. Wong <darrick.wong at oracle.com>
> Reviewed-by: Christoph Hellwig <hch at lst.de>
> ---
>  block/ioctl.c |   29 +++++++++++++++++++++++------
>  1 file changed, 23 insertions(+), 6 deletions(-)
>
>
> diff --git a/block/ioctl.c b/block/ioctl.c
> index ed2397f..d001f52 100644
> --- a/block/ioctl.c
> +++ b/block/ioctl.c
> @@ -225,7 +225,9 @@ static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode,
>  		unsigned long arg)
>  {
>  	uint64_t range[2];
> -	uint64_t start, len;
> +	struct address_space *mapping;
> +	uint64_t start, end, len;
> +	int ret;
>
>  	if (!(mode & FMODE_WRITE))
>  		return -EBADF;
> @@ -235,18 +237,33 @@ static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode,
>
>  	start = range[0];
>  	len = range[1];
> +	end = start + len - 1;
>
>  	if (start & 511)
>  		return -EINVAL;
>  	if (len & 511)
>  		return -EINVAL;
> -	start >>= 9;
> -	len >>= 9;
> -
> -	if (start + len > (i_size_read(bdev->bd_inode) >> 9))
> +	if (end >= (uint64_t)i_size_read(bdev->bd_inode))
> +		return -EINVAL;
> +	if (end < start)
>  		return -EINVAL;
>
> -	return blkdev_issue_zeroout(bdev, start, len, GFP_KERNEL, false);
> +	/* Invalidate the page cache, including dirty pages */
> +	mapping = bdev->bd_inode->i_mapping;
> +	truncate_inode_pages_range(mapping, start, end);
> +
> +	ret = blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL,
> +				    false);
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * Invalidate again; if someone wandered in and dirtied a page,
> +	 * the caller will be given -EBUSY.
> +	 */
> +	return invalidate_inode_pages2_range(mapping,
> +					     start >> PAGE_SHIFT,
> +					     end >> PAGE_SHIFT);
>  }

Hello Darrick,

Maybe this has already been discussed, but anyway: in the POSIX spec 
(http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html) I 
found the following: "This volume of POSIX.1-2008 does not specify 
behavior of concurrent writes to a file from multiple processes. 
Applications should use some form of concurrency control."

Do we really need the invalidate_inode_pages2_range() call?

Thanks,

Bart.




More information about the dm-devel mailing list