#include <linux/file.h>
#include <linux/sched.h>
#include <linux/user_namespace.h>
-#ifdef HAVE_UIDGID_HEADER
-# include <linux/uidgid.h>
-#endif
+#include <linux/uidgid.h>
#include <uapi/linux/lustre/lustre_ioctl.h>
#include <lustre_swab.h>
if (obj == NULL)
RETURN_EXIT;
- if (!req_capsule_has_field(&req->rq_pill, &RMF_NIOBUF_INLINE,
- RCL_SERVER))
+ if (!req_capsule_field_present(&req->rq_pill, &RMF_NIOBUF_INLINE,
+ RCL_SERVER))
RETURN_EXIT;
rnb = req_capsule_server_get(&req->rq_pill, &RMF_NIOBUF_INLINE);
* client PAGE_SIZE to be used on that client, if server's PAGE_SIZE is
* smaller then offset may be not aligned and that data is just ignored.
*/
- if (rnb->rnb_offset % PAGE_SIZE)
+ if (rnb->rnb_offset & ~PAGE_MASK)
RETURN_EXIT;
/* Server returns whole file or just file tail if it fills in reply
data = (char *)rnb + sizeof(*rnb);
lnb.lnb_file_offset = rnb->rnb_offset;
- start = lnb.lnb_file_offset / PAGE_SIZE;
+ start = lnb.lnb_file_offset >> PAGE_SHIFT;
index = 0;
- LASSERT(lnb.lnb_file_offset % PAGE_SIZE == 0);
+ LASSERT((lnb.lnb_file_offset & ~PAGE_MASK) == 0);
lnb.lnb_page_offset = 0;
do {
lnb.lnb_data = data + (index << PAGE_SHIFT);
} else {
LASSERT(*och_usecount == 0);
if (!it->it_disposition) {
- struct ll_dentry_data *ldd = ll_d2d(file->f_path.dentry);
+ struct dentry *dentry = file_dentry(file);
+ struct ll_dentry_data *ldd;
+
/* We cannot just request lock handle now, new ELC code
means that one of other OPEN locks for this file
could be cancelled, and since blocking ast handler
* lookup path only, since ll_iget_for_nfs always calls
* ll_d_init().
*/
+ ldd = ll_d2d(dentry);
if (ldd && ldd->lld_nfs_dentry) {
ldd->lld_nfs_dentry = 0;
- it->it_flags |= MDS_OPEN_LOCK;
+ if (!filename_is_volatile(dentry->d_name.name,
+ dentry->d_name.len,
+ NULL))
+ it->it_flags |= MDS_OPEN_LOCK;
}
- /*
+ /*
* Always specify MDS_OPEN_BY_FID because we don't want
* to get file with different fid.
*/
it->it_flags |= MDS_OPEN_BY_FID;
- rc = ll_intent_file_open(file_dentry(file), NULL, 0,
- it);
+ rc = ll_intent_file_open(dentry, NULL, 0, it);
if (rc)
GOTO(out_openerr, rc);
GOTO(out_och_free, rc);
mutex_unlock(&lli->lli_och_mutex);
- fd = NULL;
- /* Must do this outside lli_och_mutex lock to prevent deadlock where
- different kind of OPEN lock for this same inode gets cancelled
- by ldlm_cancel_lru */
- if (!S_ISREG(inode->i_mode))
- GOTO(out_och_free, rc);
+ /* 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
+ different kind of OPEN lock for this same inode gets cancelled
+ by ldlm_cancel_lru */
+ if (!S_ISREG(inode->i_mode))
+ GOTO(out_och_free, rc);
cl_lov_delay_create_clear(&file->f_flags);
GOTO(out_och_free, rc);
* POSIX. Solving this problem needs to send an RPC to MDT for each
* read, this will hurt performance.
*/
- if (inode->i_atime.tv_sec < lli->lli_atime ||
- lli->lli_update_atime) {
+ if (ll_file_test_and_clear_flag(lli, LLIF_UPDATE_ATIME) ||
+ inode->i_atime.tv_sec < lli->lli_atime)
inode->i_atime.tv_sec = lli->lli_atime;
- lli->lli_update_atime = 0;
- }
+
inode->i_mtime.tv_sec = lli->lli_mtime;
inode->i_ctime.tv_sec = lli->lli_ctime;
int rc = 0;
unsigned retried = 0;
bool restarted = false;
+ unsigned ignore_lockless = 0;
ENTRY;
restart:
io = vvp_env_thread_io(env);
ll_io_init(io, file, iot, args);
+ io->ci_ignore_lockless = ignore_lockless;
io->ci_ndelay_tried = retried;
if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
file->f_path.dentry->d_name.name,
iot, rc, result, io->ci_need_restart);
- if ((rc == 0 || rc == -ENODATA) && count > 0 && io->ci_need_restart) {
+ if ((rc == 0 || rc == -ENODATA || rc == -ENOLCK) &&
+ count > 0 && io->ci_need_restart) {
CDEBUG(D_VFSTRACE,
"%s: restart %s from %lld, count: %zu, ret: %zd, rc: %d\n",
file_dentry(file)->d_name.name,
*ppos, count, result, rc);
/* preserve the tried count for FLR */
retried = io->ci_ndelay_tried;
+ ignore_lockless = io->ci_ignore_lockless;
restarted = true;
goto restart;
}