* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#ifndef LLITE_INTERNAL_H
#define LLITE_INTERNAL_H
-
-#include <lustre_acl.h>
-
#include <lustre_debug.h>
#include <lustre_ver.h>
#include <lustre_disk.h> /* for s2sbi */
/* for writepage() only to communicate to fsync */
int f_async_rc;
+ /* volatile file criteria is based on file name, this
+ * flag is used to keep the test result, so the strcmp
+ * is done only once
+ */
+ bool f_volatile;
/*
* whenever a process try to read/write the file, the
* jobid of the process will be saved here, and it'll
#define lli_agl_index u.f.f_agl_index
#define lli_async_rc u.f.f_async_rc
#define lli_jobid u.f.f_jobid
+#define lli_volatile u.f.f_volatile
} u;
#define LL_SBI_LAYOUT_LOCK 0x20000 /* layout lock support */
#define LL_SBI_USER_FID2PATH 0x40000 /* allow fid2path by unprivileged users */
+#define LL_SBI_FLAGS { \
+ "nolck", \
+ "checksum", \
+ "flock", \
+ "xattr", \
+ "acl", \
+ "rmt_client", \
+ "mds_capa", \
+ "oss_capa", \
+ "flock", \
+ "lru_resize", \
+ "lazy_statfs", \
+ "som", \
+ "32bit_api", \
+ "64bit_hash", \
+ "agl", \
+ "verbose", \
+ "layout", \
+ "user_fid2path" }
+
/* default value for ll_sb_info->contention_time */
#define SBI_DEFAULT_CONTENTION_SECONDS 60
/* default value for lockless_truncate_enable */
struct lu_fid ll_root_fid; /* root object fid */
int ll_flags;
+ int ll_umounting:1;
cfs_list_t ll_conn_chain; /* per-conn chain of SBs */
struct lustre_client_ocd ll_lco;
int lookup_flags);
#endif
struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de);
+int ll_rmdir_entry(struct inode *dir, char *name, int namelen);
/* llite/rw.c */
int ll_prepare_write(struct file *, struct page *, unsigned from, unsigned to);
struct ptlrpc_request **request);
int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
int set_default);
-int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmm,
+int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
int *lmm_size, struct ptlrpc_request **request);
#ifdef HAVE_FILE_FSYNC_4ARGS
int ll_fsync(struct file *file, loff_t start, loff_t end, int data);
#endif
int ll_do_fiemap(struct inode *inode, struct ll_user_fiemap *fiemap,
int num_bytes);
-int ll_merge_lvb(struct inode *inode);
+int ll_merge_lvb(const struct lu_env *env, struct inode *inode);
int ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg);
int ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg);
int ll_fid2path(struct inode *inode, void *arg);
+int ll_data_version(struct inode *inode, __u64 *data_version, int extent_lock);
/* llite/dcache.c */
int ll_fill_super(struct super_block *sb, struct vfsmount *mnt);
void ll_put_super(struct super_block *sb);
void ll_kill_super(struct super_block *sb);
+struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock);
struct inode *ll_inode_from_lock(struct ldlm_lock *lock);
void ll_clear_inode(struct inode *inode);
int ll_setattr_raw(struct dentry *dentry, struct iattr *attr);
/* llite/llite_nfs.c */
extern struct export_operations lustre_export_operations;
__u32 get_uuid2int(const char *name, int len);
+struct inode *search_inode_for_lustre(struct super_block *sb,
+ const struct lu_fid *fid);
/* llite/special.c */
extern struct inode_operations ll_special_inode_operations;
cfs_waitq_t sai_waitq; /* stat-ahead wait queue */
struct ptlrpc_thread sai_thread; /* stat-ahead thread */
struct ptlrpc_thread sai_agl_thread; /* AGL thread */
- cfs_list_t sai_entries_sent; /* entries sent out */
+ cfs_list_t sai_entries; /* entry list */
cfs_list_t sai_entries_received; /* entries returned */
cfs_list_t sai_entries_stated; /* entries stated */
cfs_list_t sai_entries_agl; /* AGL entries to be sent */
#define cl_isize_read(inode) i_size_read(inode)
-static inline int cl_merge_lvb(struct inode *inode)
+static inline int cl_merge_lvb(const struct lu_env *env, struct inode *inode)
{
- return ll_merge_lvb(inode);
+ return ll_merge_lvb(env, inode);
}
#define cl_inode_atime(inode) LTIME_S((inode)->i_atime)
struct obd_capa *cl_capa_lookup(struct inode *inode, enum cl_req_type crt);
int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end,
- enum cl_fsync_mode mode);
+ enum cl_fsync_mode mode, int ignore_layout);
/** direct write pages */
struct ll_dio_pages {
static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode,
struct lookup_intent *it, __u64 *bits)
{
- if (!it->d.lustre.it_lock_set) {
- CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
- inode, inode->i_ino, inode->i_generation);
- md_set_lock_data(exp, &it->d.lustre.it_lock_handle,
- inode, &it->d.lustre.it_lock_bits);
- it->d.lustre.it_lock_set = 1;
- }
-
- if (bits != NULL)
- *bits = it->d.lustre.it_lock_bits;
+ if (!it->d.lustre.it_lock_set) {
+ struct lustre_handle handle;
+
+ /* If this inode is a remote object, it will get two
+ * separate locks in different namespaces, Master MDT,
+ * where the name entry is, will grant LOOKUP lock,
+ * remote MDT, where the object is, will grant
+ * UPDATE|PERM lock. The inode will be attched to both
+ * LOOKUP and PERM locks, so revoking either locks will
+ * case the dcache being cleared */
+ if (it->d.lustre.it_remote_lock_mode) {
+ handle.cookie = it->d.lustre.it_remote_lock_handle;
+ CDEBUG(D_DLMTRACE, "setting l_data to inode %p"
+ "(%lu/%u) for remote lock "LPX64"\n", inode,
+ inode->i_ino, inode->i_generation,
+ handle.cookie);
+ md_set_lock_data(exp, &handle.cookie, inode, NULL);
+ }
+
+ handle.cookie = it->d.lustre.it_lock_handle;
+
+ CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)"
+ " for lock "LPX64"\n", inode, inode->i_ino,
+ inode->i_generation, handle.cookie);
+
+ md_set_lock_data(exp, &handle.cookie, inode,
+ &it->d.lustre.it_lock_bits);
+ it->d.lustre.it_lock_set = 1;
+ }
+
+ if (bits != NULL)
+ *bits = it->d.lustre.it_lock_bits;
}
static inline void ll_lock_dcache(struct inode *inode)
* ll_md_blocking_ast), unhash this dentry, and let dcache to reclaim it later;
* else dput() of the last refcount will unhash this dentry and kill it.
*/
-static inline void d_lustre_invalidate(struct dentry *dentry)
+static inline void d_lustre_invalidate(struct dentry *dentry, int nested)
{
CDEBUG(D_DENTRY, "invalidate dentry %.*s (%p) parent %p inode %p "
"refc %d\n", dentry->d_name.len, dentry->d_name.name, dentry,
dentry->d_parent, dentry->d_inode, d_refcount(dentry));
- spin_lock(&dentry->d_lock);
+ spin_lock_nested(&dentry->d_lock,
+ nested ? DENTRY_D_LOCK_NESTED : DENTRY_D_LOCK_NORMAL);
__d_lustre_invalidate(dentry);
if (d_refcount(dentry) == 0)
__d_drop(dentry);
#warning "remove old LL_IOC_QUOTACTL_18 compatibility code"
#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) */
-#define LL_LAYOUT_GEN_ZERO ((__u32)-1)
+enum {
+ LL_LAYOUT_GEN_NONE = ((__u32)-2), /* layout lock was cancelled */
+ LL_LAYOUT_GEN_EMPTY = ((__u32)-1) /* for empty layout */
+};
+
int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf);
int ll_layout_refresh(struct inode *inode, __u32 *gen);