]) # 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
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
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
}
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);
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);
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:
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;
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;
}
#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)
{
.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,
.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,
.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,
*/
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;
};
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,
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)
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
};
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);
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;
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.
*/
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;
} readwrite; /* normal io */
} u;
- enum vvp_io_subtype vui_io_subtype;
-
/**
* Layout version when this IO is initialized
*/
}
/**
- * 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
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);
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
{
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);
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);
/* 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)
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;
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);
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)