Commit d1f53233 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'work.splice_read' of git://git.kernel.org/pub/scm/linux/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
parents 2eee010d a949e639
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+25 −64
Original line number Diff line number Diff line
@@ -1138,10 +1138,6 @@ restart:
			range_lock_init(&range, *ppos, *ppos + count - 1);

		vio->vui_fd  = LUSTRE_FPRIVATE(file);
		vio->vui_io_subtype = args->via_io_subtype;

		switch (vio->vui_io_subtype) {
		case IO_NORMAL:
		vio->vui_iter = args->u.normal.via_iter;
		vio->vui_iocb = args->u.normal.via_iocb;
		/*
@@ -1163,19 +1159,9 @@ restart:
			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();
		}
		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);
		if (range_locked) {
			CDEBUG(D_VFSTRACE, "Range unlock [%llu, %llu]\n",
@@ -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;

@@ -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;

@@ -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)
@@ -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
};
@@ -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,
@@ -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,
+2 −13
Original line number Diff line number Diff line
@@ -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;
};

@@ -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);
+0 −14
Original line number Diff line number Diff line
@@ -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.
 */
@@ -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;
@@ -110,8 +98,6 @@ struct vvp_io {
		} write;
	} u;

	enum vvp_io_subtype	vui_io_subtype;

	/**
	 * Layout version when this IO is initialized
	 */
+4 −41
Original line number Diff line number Diff line
@@ -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
@@ -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;

@@ -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);
}

@@ -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);
@@ -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();
	}

out:
	if (result >= 0) {
Loading