diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2009-05-07 15:37:36 +0200 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-05-11 14:13:10 +0200 |
commit | 6818173bd658439b83896a2a7586f64ab51bf29c (patch) | |
tree | 17d25ee77485af18da1a80cb7f1d8ec581c6abfc /drivers | |
parent | 7c77f0b3f9208c339a4b40737bb2cb0f0319bb8d (diff) |
splice: implement default splice_read method
If f_op->splice_read() is not implemented, fall back to a plain read.
Use vfs_readv() to read into previously allocated pages.
This will allow splice and functions using splice, such as the loop
device, to work on all filesystems. This includes "direct_io" files
in fuse which bypass the page cache.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/loop.c | 11 |
1 files changed, 1 insertions, 10 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 9ca4bb01465..801f4ab8330 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -709,10 +709,6 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) goto out_putf; - /* new backing store needs to support loop (eg splice_read) */ - if (!inode->i_fop->splice_read) - goto out_putf; - /* size of the new backing store needs to be the same */ if (get_loop_size(lo, file) != get_loop_size(lo, old_file)) goto out_putf; @@ -788,12 +784,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, error = -EINVAL; if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { const struct address_space_operations *aops = mapping->a_ops; - /* - * If we can't read - sorry. If we only can't write - well, - * it's going to be read-only. - */ - if (!file->f_op->splice_read) - goto out_putf; + if (aops->write_begin) lo_flags |= LO_FLAGS_USE_AOPS; if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) |