mutex_unlock(&lli->lli_och_mutex);
- /* lockless for direct IO so that it can do IO in parallel */
- if (file->f_flags & O_DIRECT)
- fd->fd_flags |= LL_FILE_LOCKLESS_IO;
fd = NULL;
/* Must do this outside lli_och_mutex lock to prevent deadlock where
/* already get lease, handle lease lock */
ll_set_lock_data(sbi->ll_md_exp, inode, &it, NULL);
- if (it.it_lock_mode == 0 ||
- it.it_lock_bits != MDS_INODELOCK_OPEN) {
+ if (!it.it_lock_mode ||
+ !(it.it_lock_bits & MDS_INODELOCK_OPEN)) {
/* open lock must return for lease */
CERROR(DFID "lease granted but no open lock, %d/%llu.\n",
PFID(ll_inode2fid(inode)), it.it_lock_mode,
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
}
struct cl_io *io;
ssize_t result = 0;
int rc = 0;
- unsigned int retried = 0, ignore_lockless = 0;
+ unsigned int retried = 0, dio_lock = 0;
bool is_aio = false;
struct cl_dio_aio *ci_aio = NULL;
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);
io = vvp_env_thread_io(env);
ll_io_init(io, file, iot, args);
io->ci_aio = ci_aio;
- io->ci_ignore_lockless = ignore_lockless;
+ io->ci_dio_lock = dio_lock;
io->ci_ndelay_tried = retried;
if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
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:
*ppos, count, result, rc);
/* preserve the tried count for FLR */
retried = io->ci_ndelay_tried;
- ignore_lockless = io->ci_ignore_lockless;
+ dio_lock = io->ci_dio_lock;
goto restart;
}
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)
{
}
}
+loff_t ll_lseek(struct inode *inode, loff_t offset, int whence)
+{
+ struct lu_env *env;
+ struct cl_io *io;
+ struct cl_lseek_io *lsio;
+ __u16 refcheck;
+ int rc;
+ loff_t retval;
+
+ ENTRY;
+
+ env = cl_env_get(&refcheck);
+ if (IS_ERR(env))
+ RETURN(PTR_ERR(env));
+
+ io = vvp_env_thread_io(env);
+ io->ci_obj = ll_i2info(inode)->lli_clob;
+
+ lsio = &io->u.ci_lseek;
+ lsio->ls_start = offset;
+ lsio->ls_whence = whence;
+ lsio->ls_result = -ENXIO;
+
+ do {
+ rc = cl_io_init(env, io, CIT_LSEEK, io->ci_obj);
+ if (!rc)
+ rc = cl_io_loop(env, io);
+ else
+ rc = io->ci_result;
+ retval = rc ? : lsio->ls_result;
+ cl_io_fini(env, io);
+ } while (unlikely(io->ci_need_restart));
+
+ cl_env_put(env, &refcheck);
+
+ RETURN(retval);
+}
+
static loff_t ll_file_seek(struct file *file, loff_t offset, int origin)
{
struct inode *inode = file_inode(file);
- loff_t retval, eof = 0;
+ loff_t retval = offset, eof = 0;
ktime_t kstart = ktime_get();
ENTRY;
- retval = offset + ((origin == SEEK_END) ? i_size_read(inode) :
- (origin == SEEK_CUR) ? file->f_pos : 0);
+
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), to=%llu=%#llx(%d)\n",
PFID(ll_inode2fid(inode)), inode, retval, retval,
origin);
- if (origin == SEEK_END || origin == SEEK_HOLE || origin == SEEK_DATA) {
+ if (origin == SEEK_END) {
retval = ll_glimpse_size(inode);
if (retval != 0)
RETURN(retval);
eof = i_size_read(inode);
}
- retval = generic_file_llseek_size(file, offset, origin,
- ll_file_maxbytes(inode), eof);
+ if (origin == SEEK_HOLE || origin == SEEK_DATA) {
+ if (offset < 0)
+ return -ENXIO;
+
+ /* flush local cache first if any */
+ cl_sync_file_range(inode, offset, OBD_OBJECT_EOF,
+ CL_FSYNC_LOCAL, 0);
+
+ retval = ll_lseek(inode, offset, origin);
+ if (retval < 0)
+ return retval;
+ retval = vfs_setpos(file, retval, ll_file_maxbytes(inode));
+ } else {
+ retval = generic_file_llseek_size(file, offset, origin,
+ ll_file_maxbytes(inode), eof);
+ }
if (retval >= 0)
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LLSEEK,
ktime_us_delta(ktime_get(), kstart));
};
struct ptlrpc_request *req = NULL;
struct md_op_data *op_data;
+ const char *name = NULL;
+ size_t namelen = 0;
int rc = 0;
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p),name=%s\n",
PFID(ll_inode2fid(inode)), inode, dentry->d_name.name);
- if (exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID)
+ if (exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID) {
parent = dentry->d_parent->d_inode;
- else
+ name = dentry->d_name.name;
+ namelen = dentry->d_name.len;
+ } else {
parent = inode;
+ }
- /* Call getattr by fid, so do not provide name at all. */
- op_data = ll_prep_md_op_data(NULL, parent, inode, NULL, 0, 0,
+ op_data = ll_prep_md_op_data(NULL, parent, inode, name, namelen, 0,
LUSTRE_OPC_ANY, NULL);
if (IS_ERR(op_data))
RETURN(PTR_ERR(op_data));
+ /* Call getattr by fid */
+ if (exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID)
+ op_data->op_flags = MF_GETATTR_BY_FID;
rc = md_intent_lock(exp, op_data, &oit, &req, &ll_md_blocking_ast, 0);
ll_finish_md_op_data(op_data);
if (rc < 0) {
RETURN(0);
down_read(&lli->lli_lsm_sem);
- rc = md_merge_attr(ll_i2mdexp(inode), &lli->lli_fid, lli->lli_lsm_md,
+ rc = md_merge_attr(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
&attr, ll_md_blocking_ast);
up_read(&lli->lli_lsm_sem);
if (rc != 0)
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_FALLOCATE, 1);
rc = cl_falloc(inode, mode, offset, len);
+ /*
+ * ENOTSUPP (524) is an NFSv3 specific error code erroneously
+ * used by Lustre in several places. Retuning it here would
+ * confuse applications that explicity test for EOPNOTSUPP
+ * (95) and fall back to ftruncate().
+ */
+ if (rc == -ENOTSUPP)
+ rc = -EOPNOTSUPP;
RETURN(rc);
}
rc = ll_do_fiemap(inode, fiemap, num_bytes);
+ if (IS_ENCRYPTED(inode)) {
+ int i;
+
+ for (i = 0; i < fiemap->fm_mapped_extents; i++)
+ fiemap->fm_extents[i].fe_flags |=
+ FIEMAP_EXTENT_DATA_ENCRYPTED |
+ FIEMAP_EXTENT_ENCODED;
+ }
+
fieinfo->fi_flags = fiemap->fm_flags;
fieinfo->fi_extents_mapped = fiemap->fm_mapped_extents;
if (extent_count > 0 &&
.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,