diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/block_dev.c | 37 | 
1 files changed, 35 insertions, 2 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index b3c1d3dae77d..1a1e5e3b1eaf 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1661,6 +1661,39 @@ static int blkdev_mmap(struct file *file, struct vm_area_struct *vma)  	return ret;  } +static ssize_t blkdev_splice_read(struct file *file, loff_t *ppos, +				  struct pipe_inode_info *pipe, size_t len, +				  unsigned int flags) +{ +	ssize_t ret; +	struct block_device *bdev = I_BDEV(file->f_mapping->host); + +	percpu_down_read(&bdev->bd_block_size_semaphore); + +	ret = generic_file_splice_read(file, ppos, pipe, len, flags); + +	percpu_up_read(&bdev->bd_block_size_semaphore); + +	return ret; +} + +static ssize_t blkdev_splice_write(struct pipe_inode_info *pipe, +				   struct file *file, loff_t *ppos, size_t len, +				   unsigned int flags) +{ +	ssize_t ret; +	struct block_device *bdev = I_BDEV(file->f_mapping->host); + +	percpu_down_read(&bdev->bd_block_size_semaphore); + +	ret = generic_file_splice_write(pipe, file, ppos, len, flags); + +	percpu_up_read(&bdev->bd_block_size_semaphore); + +	return ret; +} + +  /*   * Try to release a page associated with block device when the system   * is under memory pressure. @@ -1699,8 +1732,8 @@ const struct file_operations def_blk_fops = {  #ifdef CONFIG_COMPAT  	.compat_ioctl	= compat_blkdev_ioctl,  #endif -	.splice_read	= generic_file_splice_read, -	.splice_write	= generic_file_splice_write, +	.splice_read	= blkdev_splice_read, +	.splice_write	= blkdev_splice_write,  };  int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)  | 
