Skip to content

Commit

Permalink
Merge branch 'work.splice_read' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/viro/vfs

Pull VFS splice updates from Al Viro:
 "There's a bunch of branches this cycle, both mine and from other folks
  and I'd rather send pull requests separately.

  This one is the conversion of ->splice_read() to ITER_PIPE iov_iter
  (and introduction of such). Gets rid of a lot of code in fs/splice.c
  and elsewhere; there will be followups, but these are for the next
  cycle...  Some pipe/splice-related cleanups from Miklos in the same
  branch as well"

* 'work.splice_read' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  pipe: fix comment in pipe_buf_operations
  pipe: add pipe_buf_steal() helper
  pipe: add pipe_buf_confirm() helper
  pipe: add pipe_buf_release() helper
  pipe: add pipe_buf_get() helper
  relay: simplify relay_file_read()
  switch default_file_splice_read() to use of pipe-backed iov_iter
  switch generic_file_splice_read() to use of ->read_iter()
  new iov_iter flavour: pipe-backed
  fuse_dev_splice_read(): switch to add_to_pipe()
  skb_splice_bits(): get rid of callback
  new helper: add_to_pipe()
  splice: lift pipe_lock out of splice_to_pipe()
  splice: switch get_iovec_page_array() to iov_iter
  splice_to_pipe(): don't open-code wakeup_pipe_readers()
  consistent treatment of EFAULT on O_DIRECT read/write
  • Loading branch information
torvalds committed Oct 7, 2016
2 parents 2eee010 + a949e63 commit d1f5323
Show file tree
Hide file tree
Showing 30 changed files with 746 additions and 1,077 deletions.
2 changes: 1 addition & 1 deletion drivers/char/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
return 0;

/* Try lock this page */
if (buf->ops->steal(pipe, buf) == 0) {
if (pipe_buf_steal(pipe, buf) == 0) {
/* Get reference and unlock page for moving */
get_page(buf->page);
unlock_page(buf->page);
Expand Down
89 changes: 25 additions & 64 deletions drivers/staging/lustre/lustre/llite/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1138,45 +1138,31 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
range_lock_init(&range, *ppos, *ppos + count - 1);

vio->vui_fd = LUSTRE_FPRIVATE(file);
vio->vui_io_subtype = args->via_io_subtype;
vio->vui_iter = args->u.normal.via_iter;
vio->vui_iocb = args->u.normal.via_iocb;
/*
* Direct IO reads must also take range lock,
* or multiple reads will try to work on the same pages
* See LU-6227 for details.
*/
if (((iot == CIT_WRITE) ||
(iot == CIT_READ && (file->f_flags & O_DIRECT))) &&
!(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
CDEBUG(D_VFSTRACE, "Range lock [%llu, %llu]\n",
range.rl_node.in_extent.start,
range.rl_node.in_extent.end);
result = range_lock(&lli->lli_write_tree,
&range);
if (result < 0)
goto out;

switch (vio->vui_io_subtype) {
case IO_NORMAL:
vio->vui_iter = args->u.normal.via_iter;
vio->vui_iocb = args->u.normal.via_iocb;
/*
* Direct IO reads must also take range lock,
* or multiple reads will try to work on the same pages
* See LU-6227 for details.
*/
if (((iot == CIT_WRITE) ||
(iot == CIT_READ && (file->f_flags & O_DIRECT))) &&
!(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
CDEBUG(D_VFSTRACE, "Range lock [%llu, %llu]\n",
range.rl_node.in_extent.start,
range.rl_node.in_extent.end);
result = range_lock(&lli->lli_write_tree,
&range);
if (result < 0)
goto out;

range_locked = true;
}
down_read(&lli->lli_trunc_sem);
break;
case IO_SPLICE:
vio->u.splice.vui_pipe = args->u.splice.via_pipe;
vio->u.splice.vui_flags = args->u.splice.via_flags;
break;
default:
CERROR("Unknown IO type - %u\n", vio->vui_io_subtype);
LBUG();
range_locked = true;
}
down_read(&lli->lli_trunc_sem);
ll_cl_add(file, env, io);
result = cl_io_loop(env, io);
ll_cl_remove(file, env);
if (args->via_io_subtype == IO_NORMAL)
up_read(&lli->lli_trunc_sem);
up_read(&lli->lli_trunc_sem);
if (range_locked) {
CDEBUG(D_VFSTRACE, "Range unlock [%llu, %llu]\n",
range.rl_node.in_extent.start,
Expand Down Expand Up @@ -1235,7 +1221,7 @@ static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
if (IS_ERR(env))
return PTR_ERR(env);

args = ll_env_args(env, IO_NORMAL);
args = ll_env_args(env);
args->u.normal.via_iter = to;
args->u.normal.via_iocb = iocb;

Expand All @@ -1259,7 +1245,7 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (IS_ERR(env))
return PTR_ERR(env);

args = ll_env_args(env, IO_NORMAL);
args = ll_env_args(env);
args->u.normal.via_iter = from;
args->u.normal.via_iocb = iocb;

Expand All @@ -1269,31 +1255,6 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
return result;
}

/*
* Send file content (through pagecache) somewhere with helper
*/
static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos,
struct pipe_inode_info *pipe, size_t count,
unsigned int flags)
{
struct lu_env *env;
struct vvp_io_args *args;
ssize_t result;
int refcheck;

env = cl_env_get(&refcheck);
if (IS_ERR(env))
return PTR_ERR(env);

args = ll_env_args(env, IO_SPLICE);
args->u.splice.via_pipe = pipe;
args->u.splice.via_flags = flags;

result = ll_file_io_generic(env, args, in_file, CIT_READ, ppos, count);
cl_env_put(env, &refcheck);
return result;
}

int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry,
__u64 flags, struct lov_user_md *lum,
int lum_size)
Expand Down Expand Up @@ -3267,7 +3228,7 @@ struct file_operations ll_file_operations = {
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
.splice_read = ll_file_splice_read,
.splice_read = generic_file_splice_read,
.fsync = ll_fsync,
.flush = ll_flush
};
Expand All @@ -3280,7 +3241,7 @@ struct file_operations ll_file_operations_flock = {
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
.splice_read = ll_file_splice_read,
.splice_read = generic_file_splice_read,
.fsync = ll_fsync,
.flush = ll_flush,
.flock = ll_file_flock,
Expand All @@ -3296,7 +3257,7 @@ struct file_operations ll_file_operations_noflock = {
.release = ll_file_release,
.mmap = ll_file_mmap,
.llseek = ll_file_seek,
.splice_read = ll_file_splice_read,
.splice_read = generic_file_splice_read,
.fsync = ll_fsync,
.flush = ll_flush,
.flock = ll_file_noflock,
Expand Down
15 changes: 2 additions & 13 deletions drivers/staging/lustre/lustre/llite/llite_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -908,17 +908,11 @@ void vvp_write_complete(struct vvp_object *club, struct vvp_page *page);
*/
struct vvp_io_args {
/** normal/splice */
enum vvp_io_subtype via_io_subtype;

union {
struct {
struct kiocb *via_iocb;
struct iov_iter *via_iter;
} normal;
struct {
struct pipe_inode_info *via_pipe;
unsigned int via_flags;
} splice;
} u;
};

Expand Down Expand Up @@ -946,14 +940,9 @@ static inline struct ll_thread_info *ll_env_info(const struct lu_env *env)
return lti;
}

static inline struct vvp_io_args *ll_env_args(const struct lu_env *env,
enum vvp_io_subtype type)
static inline struct vvp_io_args *ll_env_args(const struct lu_env *env)
{
struct vvp_io_args *via = &ll_env_info(env)->lti_args;

via->via_io_subtype = type;

return via;
return &ll_env_info(env)->lti_args;
}

void ll_queue_done_writing(struct inode *inode, unsigned long flags);
Expand Down
14 changes: 0 additions & 14 deletions drivers/staging/lustre/lustre/llite/vvp_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,6 @@ struct obd_device;
struct obd_export;
struct page;

/* specific architecture can implement only part of this list */
enum vvp_io_subtype {
/** normal IO */
IO_NORMAL,
/** io started from splice_{read|write} */
IO_SPLICE
};

/**
* IO state private to IO state private to VVP layer.
*/
Expand Down Expand Up @@ -98,10 +90,6 @@ struct vvp_io {
*/
bool ft_flags_valid;
} fault;
struct {
struct pipe_inode_info *vui_pipe;
unsigned int vui_flags;
} splice;
struct {
struct cl_page_list vui_queue;
unsigned long vui_written;
Expand All @@ -110,8 +98,6 @@ struct vvp_io {
} write;
} u;

enum vvp_io_subtype vui_io_subtype;

/**
* Layout version when this IO is initialized
*/
Expand Down
45 changes: 4 additions & 41 deletions drivers/staging/lustre/lustre/llite/vvp_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,6 @@ static struct vvp_io *cl2vvp_io(const struct lu_env *env,
return vio;
}

/**
* True, if \a io is a normal io, False for splice_{read,write}
*/
static int cl_is_normalio(const struct lu_env *env, const struct cl_io *io)
{
struct vvp_io *vio = vvp_env_io(env);

LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE);

return vio->vui_io_subtype == IO_NORMAL;
}

/**
* For swapping layout. The file's layout may have changed.
* To avoid populating pages to a wrong stripe, we have to verify the
Expand Down Expand Up @@ -390,9 +378,6 @@ static int vvp_mmap_locks(const struct lu_env *env,

LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE);

if (!cl_is_normalio(env, io))
return 0;

if (!vio->vui_iter) /* nfs or loop back device write */
return 0;

Expand Down Expand Up @@ -461,15 +446,10 @@ static void vvp_io_advance(const struct lu_env *env,
const struct cl_io_slice *ios,
size_t nob)
{
struct vvp_io *vio = cl2vvp_io(env, ios);
struct cl_io *io = ios->cis_io;
struct cl_object *obj = ios->cis_io->ci_obj;

struct vvp_io *vio = cl2vvp_io(env, ios);
CLOBINVRNT(env, obj, vvp_object_invariant(obj));

if (!cl_is_normalio(env, io))
return;

iov_iter_reexpand(vio->vui_iter, vio->vui_tot_count -= nob);
}

Expand All @@ -478,7 +458,7 @@ static void vvp_io_update_iov(const struct lu_env *env,
{
size_t size = io->u.ci_rw.crw_count;

if (!cl_is_normalio(env, io) || !vio->vui_iter)
if (!vio->vui_iter)
return;

iov_iter_truncate(vio->vui_iter, size);
Expand Down Expand Up @@ -715,25 +695,8 @@ static int vvp_io_read_start(const struct lu_env *env,

/* BUG: 5972 */
file_accessed(file);
switch (vio->vui_io_subtype) {
case IO_NORMAL:
LASSERT(vio->vui_iocb->ki_pos == pos);
result = generic_file_read_iter(vio->vui_iocb, vio->vui_iter);
break;
case IO_SPLICE:
result = generic_file_splice_read(file, &pos,
vio->u.splice.vui_pipe, cnt,
vio->u.splice.vui_flags);
/* LU-1109: do splice read stripe by stripe otherwise if it
* may make nfsd stuck if this read occupied all internal pipe
* buffers.
*/
io->ci_continue = 0;
break;
default:
CERROR("Wrong IO type %u\n", vio->vui_io_subtype);
LBUG();
}
LASSERT(vio->vui_iocb->ki_pos == pos);
result = generic_file_read_iter(vio->vui_iocb, vio->vui_iter);

out:
if (result >= 0) {
Expand Down
23 changes: 1 addition & 22 deletions fs/coda/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,6 @@ coda_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
return vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos);
}

static ssize_t
coda_file_splice_read(struct file *coda_file, loff_t *ppos,
struct pipe_inode_info *pipe, size_t count,
unsigned int flags)
{
ssize_t (*splice_read)(struct file *, loff_t *,
struct pipe_inode_info *, size_t, unsigned int);
struct coda_file_info *cfi;
struct file *host_file;

cfi = CODA_FTOC(coda_file);
BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
host_file = cfi->cfi_container;

splice_read = host_file->f_op->splice_read;
if (!splice_read)
splice_read = default_file_splice_read;

return splice_read(host_file, ppos, pipe, count, flags);
}

static ssize_t
coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
{
Expand Down Expand Up @@ -225,6 +204,6 @@ const struct file_operations coda_file_operations = {
.open = coda_open,
.release = coda_release,
.fsync = coda_fsync,
.splice_read = coda_file_splice_read,
.splice_read = generic_file_splice_read,
};

3 changes: 3 additions & 0 deletions fs/direct-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, bool is_async)
if ((dio->op == REQ_OP_READ) &&
((offset + transferred) > dio->i_size))
transferred = dio->i_size - offset;
/* ignore EFAULT if some IO has been done */
if (unlikely(ret == -EFAULT) && transferred)
ret = 0;
}

if (ret == 0)
Expand Down
Loading

0 comments on commit d1f5323

Please sign in to comment.