From: Al Viro Date: Sun, 6 Sep 2020 21:38:17 +0000 (-0400) Subject: LU-13745 llite: switch generic_file_splice_read() to use of ->read_iter() X-Git-Tag: 2.13.57~167 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=1635dc9de0bc1d6701ca5f4bc0d342fca416f89a LU-13745 llite: switch generic_file_splice_read() to use of ->read_iter() ... and kill the ->splice_read() instances that can be switched to it * Special Note * Using generic_file_splice_read() breaks Lustre but in my testing on RHEL7 not provding a ->splice_read, which results in default_file_splice_read() to be used seems to work. Linux-commit: 82c156f853840645604acd7c2cebcb75ed1b6652 Change-Id: I28bd2fe43fec25e881c78b41c58c59ac5e74eb49 Signed-off-by: Al Viro Reviewed-on: https://review.whamcloud.com/39272 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Wang Shilong Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index be33743..e9b2928 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -1547,6 +1547,19 @@ fop_iterate_shared, [ ]) # LC_FOP_ITERATE_SHARED # +# LC_EXPORT_DEFAULT_FILE_SPLICE_READ +# +# 4.8-rc8 commit 82c156f853840645604acd7c2cebcb75ed1b6652 switched +# generic_file_splice_read() to using ->read_iter. We can test this +# change since default_file_splice_read() is no longer exported. +# +AC_DEFUN([LC_EXPORT_DEFAULT_FILE_SPLICE_READ], [ +LB_CHECK_EXPORT([default_file_splice_read], [fs/splice.c], + [AC_DEFINE(HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT, 1, + [default_file_splice_read is exported])]) +]) # LC_EXPORT_DEFAULT_FILE_SPLCE_READ + +# # LC_HAVE_POSIX_ACL_VALID_USER_NS # # 4.8 posix_acl_valid takes struct user_namespace @@ -2387,6 +2400,7 @@ AC_DEFUN([LC_PROG_LINUX], [ LC_FOP_ITERATE_SHARED # 4.8 + LC_EXPORT_DEFAULT_FILE_SPLICE_READ LC_HAVE_POSIX_ACL_VALID_USER_NS LC_D_COMPARE_4ARGS LC_FULL_NAME_HASH_3ARGS diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 9067dfd..a48c0f8 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1481,8 +1481,8 @@ void ll_io_init(struct cl_io *io, struct file *file, enum cl_io_type iot, IS_SYNC(inode)); #ifdef HAVE_GENERIC_WRITE_SYNC_2ARGS io->u.ci_wr.wr_sync |= !!(args && - args->via_io_subtype == IO_NORMAL && - args->u.normal.via_iocb->ki_flags & IOCB_DSYNC); + (args->u.normal.via_iocb->ki_flags & + IOCB_DSYNC)); #endif } @@ -1559,8 +1559,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, iot == CIT_READ ? "read" : "write", *ppos, count); io = vvp_env_thread_io(env); - if (args->via_io_subtype == IO_NORMAL && - file->f_flags & O_DIRECT) { + if (file->f_flags & O_DIRECT) { if (!is_sync_kiocb(args->u.normal.via_iocb)) is_aio = true; ci_aio = cl_aio_alloc(args->u.normal.via_iocb); @@ -1584,34 +1583,22 @@ restart: range_lock_init(&range, *ppos, *ppos + count - 1); vio->vui_fd = file->private_data; - 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; - /* 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 "RL_FMT"\n", - RL_PARA(&range)); - rc = range_lock(&lli->lli_write_tree, &range); - if (rc < 0) - GOTO(out, rc); + 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 "RL_FMT"\n", + RL_PARA(&range)); + rc = range_lock(&lli->lli_write_tree, &range); + if (rc < 0) + GOTO(out, rc); - range_locked = true; - } - 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 subtype %u\n", vio->vui_io_subtype); - LBUG(); + range_locked = true; } ll_cl_add(file, env, io, LCC_RW); @@ -1643,7 +1630,7 @@ restart: count -= io->ci_nob; /* prepare IO restart */ - if (count > 0 && args->via_io_subtype == IO_NORMAL) + if (count > 0) args->u.normal.via_iter = vio->vui_iter; } out: @@ -1822,7 +1809,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; @@ -1957,7 +1944,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; @@ -2129,46 +2116,6 @@ static ssize_t ll_file_write(struct file *file, const char __user *buf, } #endif /* !HAVE_FILE_OPERATIONS_READ_WRITE_ITER */ -/* - * 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; - __u16 refcheck; - bool cached; - - ENTRY; - - result = pcc_file_splice_read(in_file, ppos, pipe, - count, flags, &cached); - if (cached) - RETURN(result); - - ll_ras_enter(in_file, *ppos, count); - - 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); - - if (result > 0) - ll_rw_stats_tally(ll_i2sbi(file_inode(in_file)), current->pid, - in_file->private_data, *ppos, result, - READ); - RETURN(result); -} - int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry, __u64 flags, struct lov_user_md *lum, int lum_size) { @@ -5289,7 +5236,11 @@ struct file_operations ll_file_operations = { .release = ll_file_release, .mmap = ll_file_mmap, .llseek = ll_file_seek, - .splice_read = ll_file_splice_read, +#ifndef HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT + .splice_read = generic_file_splice_read, +#else + .splice_read = pcc_file_splice_read, +#endif .fsync = ll_fsync, .flush = ll_flush, .fallocate = ll_fallocate, @@ -5314,7 +5265,11 @@ 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, +#ifndef HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT + .splice_read = generic_file_splice_read, +#else + .splice_read = pcc_file_splice_read, +#endif .fsync = ll_fsync, .flush = ll_flush, .flock = ll_file_flock, @@ -5342,7 +5297,11 @@ 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, +#ifndef HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT + .splice_read = generic_file_splice_read, +#else + .splice_read = pcc_file_splice_read, +#endif .fsync = ll_fsync, .flush = ll_flush, .flock = ll_file_noflock, diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 130a6a7..38d7495 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -1237,17 +1237,11 @@ extern struct inode_operations ll_fast_symlink_inode_operations; */ struct vvp_io_args { /** normal/sendfile/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; }; @@ -1283,14 +1277,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_io_init(struct cl_io *io, struct file *file, enum cl_io_type iot, diff --git a/lustre/llite/pcc.c b/lustre/llite/pcc.c index b80173e..cfad000 100644 --- a/lustre/llite/pcc.c +++ b/lustre/llite/pcc.c @@ -1793,36 +1793,34 @@ out: RETURN(rc); } +#ifdef HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT ssize_t pcc_file_splice_read(struct file *in_file, loff_t *ppos, struct pipe_inode_info *pipe, - size_t count, unsigned int flags, - bool *cached) + size_t count, unsigned int flags) { struct inode *inode = file_inode(in_file); struct ll_file_data *fd = in_file->private_data; struct file *pcc_file = fd->fd_pcc_file.pccf_file; + bool cached = false; ssize_t result; ENTRY; - *cached = false; - if (!pcc_file) - RETURN(0); - - if (!file_inode(pcc_file)->i_fop->splice_read) - RETURN(-ENOTSUPP); + if (!pcc_file) { + RETURN(default_file_splice_read(in_file, ppos, pipe, + count, flags)); + } - pcc_io_init(inode, PIT_SPLICE_READ, cached); - if (!*cached) + pcc_io_init(inode, PIT_SPLICE_READ, &cached); + if (!cached) RETURN(0); - result = file_inode(pcc_file)->i_fop->splice_read(pcc_file, - ppos, pipe, count, - flags); + result = default_file_splice_read(pcc_file, ppos, pipe, count, flags); pcc_io_fini(inode); RETURN(result); } +#endif /* HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT */ int pcc_fsync(struct file *file, loff_t start, loff_t end, int datasync, bool *cached) diff --git a/lustre/llite/pcc.h b/lustre/llite/pcc.h index 4b05c40..067daef 100644 --- a/lustre/llite/pcc.h +++ b/lustre/llite/pcc.h @@ -183,8 +183,10 @@ enum pcc_io_type { PIT_FAULT, /* fsync system call handling */ PIT_FSYNC, +#ifdef HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT /* splice_read system call */ PIT_SPLICE_READ, +#endif /* open system call */ PIT_OPEN }; @@ -240,9 +242,11 @@ ssize_t pcc_file_write_iter(struct kiocb *iocb, struct iov_iter *iter, int pcc_inode_getattr(struct inode *inode, u32 request_mask, unsigned int flags, bool *cached); int pcc_inode_setattr(struct inode *inode, struct iattr *attr, bool *cached); +#ifdef HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT ssize_t pcc_file_splice_read(struct file *in_file, loff_t *ppos, struct pipe_inode_info *pipe, size_t count, - unsigned int flags, bool *cached); + unsigned int flags); +#endif int pcc_fsync(struct file *file, loff_t start, loff_t end, int datasync, bool *cached); int pcc_file_mmap(struct file *file, struct vm_area_struct *vma, bool *cached); diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index a78f87c..0cee30b 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -627,7 +627,6 @@ static void ll_readahead_handle_work(struct work_struct *wq) memcpy(ll_i2info(inode)->lli_jobid, work->lrw_jobid, sizeof(work->lrw_jobid)); - vvp_env_io(env)->vui_io_subtype = IO_NORMAL; vvp_env_io(env)->vui_fd = fd; io->ci_state = CIS_LOCKED; io->ci_async_readahead = true; diff --git a/lustre/llite/vvp_internal.h b/lustre/llite/vvp_internal.h index 363a0f3..6fbffa2 100644 --- a/lustre/llite/vvp_internal.h +++ b/lustre/llite/vvp_internal.h @@ -46,13 +46,6 @@ struct obd_device; struct obd_export; struct page; -enum vvp_io_subtype { - /** normal IO */ - IO_NORMAL, - /** io started from splice_{read|write} */ - IO_SPLICE, -}; - /** * IO state private to VVP layer. */ @@ -91,10 +84,6 @@ struct vvp_io { struct cl_page_list ft_queue; } fault; struct { - struct pipe_inode_info *vui_pipe; - unsigned int vui_flags; - } splice; - struct { struct cl_page_list vui_queue; unsigned long vui_written; unsigned long vui_read; @@ -103,8 +92,6 @@ struct vvp_io { } readwrite; /* normal io */ } u; - enum vvp_io_subtype vui_io_subtype; - /** * Layout version when this IO is initialized */ diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index d7e8a38..b8793f6 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -57,18 +57,6 @@ static struct vvp_io *cl2vvp_io(const struct lu_env *env, } /** - * 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 * correctness of layout. It works because swapping layout processes @@ -458,9 +446,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); - /* nfs or loop back device write */ if (vio->vui_iter == NULL) RETURN(0); @@ -538,15 +523,11 @@ 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; - /* * Since 3.16(26978b8b4) vfs revert iov iter to * original position even io succeed, so instead @@ -562,7 +543,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 == NULL) + if (!vio->vui_iter) return; iov_iter_truncate(vio->vui_iter, size); @@ -827,8 +808,7 @@ static int vvp_io_read_start(const struct lu_env *env, file_dentry(file)->d_name.name, pos, pos + cnt); - if (vio->vui_io_subtype == IO_NORMAL) - trunc_sem_down_read(&lli->lli_trunc_sem); + trunc_sem_down_read(&lli->lli_trunc_sem); if (io->ci_async_readahead) { file_accessed(file); @@ -869,27 +849,9 @@ 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); - iter = *vio->vui_iter; - result = generic_file_read_iter(vio->vui_iocb, &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(); - } - GOTO(out, result); - + LASSERT(vio->vui_iocb->ki_pos == pos); + iter = *vio->vui_iter; + result = generic_file_read_iter(vio->vui_iocb, &iter); out: if (result >= 0) { if (result < cnt) @@ -898,9 +860,7 @@ out: result = 0; } else if (result == -EIOCBQUEUED) { io->ci_nob += vio->u.readwrite.vui_read; - if (vio->vui_iocb) - vio->vui_iocb->ki_pos = pos + - vio->u.readwrite.vui_read; + vio->vui_iocb->ki_pos = pos + vio->u.readwrite.vui_read; } return result; @@ -1232,8 +1192,7 @@ static int vvp_io_write_start(const struct lu_env *env, ENTRY; - if (vio->vui_io_subtype == IO_NORMAL) - trunc_sem_down_read(&lli->lli_trunc_sem); + trunc_sem_down_read(&lli->lli_trunc_sem); if (!can_populate_pages(env, io, inode)) RETURN(0); @@ -1365,12 +1324,10 @@ static int vvp_io_write_start(const struct lu_env *env, static void vvp_io_rw_end(const struct lu_env *env, const struct cl_io_slice *ios) { - struct vvp_io *vio = cl2vvp_io(env, ios); struct inode *inode = vvp_object_inode(ios->cis_obj); struct ll_inode_info *lli = ll_i2info(inode); - if (vio->vui_io_subtype == IO_NORMAL) - trunc_sem_up_read(&lli->lli_trunc_sem); + trunc_sem_up_read(&lli->lli_trunc_sem); } static int vvp_io_kernel_fault(struct vvp_fault_io *cfio)