Skip to content

Commit

Permalink
ovl: add splice file read write helper
Browse files Browse the repository at this point in the history
Now overlayfs falls back to use default file splice read
and write, which is not compatiple with overlayfs, returning
EFAULT. xfstests generic/591 can reproduce part of this.

Tested this patch with xfstests auto group tests.

Signed-off-by: Murphy Zhou <jencce.kernel@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
  • Loading branch information
Murphy Zhou authored and Miklos Szeredi committed Jan 24, 2020
1 parent 2406a30 commit 1a980b8
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions fs/overlayfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <linux/xattr.h>
#include <linux/uio.h>
#include <linux/uaccess.h>
#include <linux/splice.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include "overlayfs.h"

struct ovl_aio_req {
Expand Down Expand Up @@ -362,6 +365,48 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
return ret;
}

static ssize_t ovl_splice_read(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len,
unsigned int flags)
{
ssize_t ret;
struct fd real;
const struct cred *old_cred;

ret = ovl_real_fdget(in, &real);
if (ret)
return ret;

old_cred = ovl_override_creds(file_inode(in)->i_sb);
ret = generic_file_splice_read(real.file, ppos, pipe, len, flags);
revert_creds(old_cred);

ovl_file_accessed(in);
fdput(real);
return ret;
}

static ssize_t
ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
loff_t *ppos, size_t len, unsigned int flags)
{
struct fd real;
const struct cred *old_cred;
ssize_t ret;

ret = ovl_real_fdget(out, &real);
if (ret)
return ret;

old_cred = ovl_override_creds(file_inode(out)->i_sb);
ret = iter_file_splice_write(pipe, real.file, ppos, len, flags);
revert_creds(old_cred);

ovl_file_accessed(out);
fdput(real);
return ret;
}

static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{
struct fd real;
Expand Down Expand Up @@ -718,6 +763,8 @@ const struct file_operations ovl_file_operations = {
.fadvise = ovl_fadvise,
.unlocked_ioctl = ovl_ioctl,
.compat_ioctl = ovl_compat_ioctl,
.splice_read = ovl_splice_read,
.splice_write = ovl_splice_write,

.copy_file_range = ovl_copy_file_range,
.remap_file_range = ovl_remap_file_range,
Expand Down

0 comments on commit 1a980b8

Please sign in to comment.