-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#define VM_FAULT_RETRY 0
#endif
+/* Kernel 3.1 kills LOOKUP_CONTINUE, LOOKUP_PARENT is equivalent to it.
+ * seem kernel commit 49084c3bb2055c401f3493c13edae14d49128ca0 */
+#ifndef LOOKUP_CONTINUE
+#define LOOKUP_CONTINUE LOOKUP_PARENT
+#endif
+
/** Only used on client-side for indicating the tail of dir hash/offset. */
#define LL_DIR_END_OFF 0x7fffffffffffffffULL
#define LL_DIR_END_OFF_32BIT 0x7fffffffUL
__u64 lli_open_fd_write_count;
__u64 lli_open_fd_exec_count;
/* Protects access to och pointers and their usage counters, also
- * atomicity of check-update of lli_smd */
+ * atomicity of check-update of lli_has_smd */
cfs_mutex_t lli_och_mutex;
struct inode lli_vfs_inode;
* cleanup the dir readahead. */
void *d_opendir_key;
struct ll_statahead_info *d_sai;
- __u64 d_sa_pos;
struct posix_acl *d_def_acl;
/* protect statahead stuff. */
cfs_spinlock_t d_sa_lock;
#define lli_readdir_mutex u.d.d_readdir_mutex
#define lli_opendir_key u.d.d_opendir_key
#define lli_sai u.d.d_sai
-#define lli_sa_pos u.d.d_sa_pos
#define lli_def_acl u.d.d_def_acl
#define lli_sa_lock u.d.d_sa_lock
#define lli_opendir_pid u.d.d_opendir_pid
cfs_rw_semaphore_t f_trunc_sem;
cfs_mutex_t f_write_mutex;
- /* for writepage() only to communicate to fsync */
- int f_async_rc;
- int f_write_rc;
+ cfs_rw_semaphore_t f_glimpse_sem;
+ cfs_time_t f_glimpse_time;
+ cfs_list_t f_agl_list;
+ __u64 f_agl_index;
- cfs_rw_semaphore_t f_glimpse_sem;
- cfs_time_t f_glimpse_time;
- cfs_list_t f_agl_list;
- __u64 f_agl_index;
+ /* for writepage() only to communicate to fsync */
+ int f_async_rc;
+
+ /*
+ * whenever a process try to read/write the file, the
+ * jobid of the process will be saved here, and it'll
+ * be packed into the write PRC when flush later.
+ *
+ * so the read/write statistics for jobid will not be
+ * accurate if the file is shared by different jobs.
+ */
+ char f_jobid[JOBSTATS_JOBID_SIZE];
} f;
#define lli_size_sem u.f.f_size_sem
#define lli_maxbytes u.f.f_maxbytes
#define lli_trunc_sem u.f.f_trunc_sem
#define lli_write_mutex u.f.f_write_mutex
-#define lli_async_rc u.f.f_async_rc
-#define lli_write_rc u.f.f_write_rc
-#define lli_glimpse_sem u.f.f_glimpse_sem
-#define lli_glimpse_time u.f.f_glimpse_time
-#define lli_agl_list u.f.f_agl_list
-#define lli_agl_index u.f.f_agl_index
+#define lli_glimpse_sem u.f.f_glimpse_sem
+#define lli_glimpse_time u.f.f_glimpse_time
+#define lli_agl_list u.f.f_agl_list
+#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
- } u;
+ } u;
/* XXX: For following frequent used members, although they maybe special
* used for non-directory object, it is some time-wasting to check
* In the future, if more members are added only for directory,
* some of the following members can be moved into u.f.
*/
- struct lov_stripe_md *lli_smd;
- struct cl_object *lli_clob;
+ bool lli_has_smd;
+ struct cl_object *lli_clob;
+
+ /* mutex to request for layout lock exclusively. */
+ cfs_mutex_t lli_layout_mutex;
};
/*
* Locking to guarantee consistency of non-atomic updates to long long i_size,
- * consistency between file size and KMS, and consistency within
- * ->lli_smd->lsm_oinfo[]'s.
+ * consistency between file size and KMS.
*
- * Implemented by ->lli_size_sem and ->lsm_sem, nested in that order.
+ * Implemented by ->lli_size_sem and ->lsm_lock, nested in that order.
*/
-void ll_inode_size_lock(struct inode *inode, int lock_lsm);
-void ll_inode_size_unlock(struct inode *inode, int unlock_lsm);
+void ll_inode_size_lock(struct inode *inode);
+void ll_inode_size_unlock(struct inode *inode);
// FIXME: replace the name of this with LL_I to conform to kernel stuff
// static inline struct ll_inode_info *LL_I(struct inode *inode)
#define LL_SBI_64BIT_HASH 0x4000 /* support 64-bits dir hash/offset */
#define LL_SBI_AGL_ENABLED 0x8000 /* enable agl */
#define LL_SBI_VERBOSE 0x10000 /* verbose mount/umount */
+#define LL_SBI_LAYOUT_LOCK 0x20000 /* layout lock support */
+#define LL_SBI_USER_FID2PATH 0x40000 /* allow fid2path by unprivileged users */
/* default value for ll_sb_info->contention_time */
#define SBI_DEFAULT_CONTENTION_SECONDS 60
struct lprocfs_stats *ll_stats; /* lprocfs stats counter */
- unsigned long ll_async_page_max;
- unsigned long ll_async_page_count;
+ struct cl_client_lru ll_lru;
struct lprocfs_stats *ll_ra_stats;
* clustred nfs */
struct rmtacl_ctl_table ll_rct;
struct eacl_table ll_et;
- struct vfsmount *ll_mnt;
};
#define LL_DEFAULT_MAX_RW_CHUNK (32 * 1024 * 1024)
unsigned long ras_consecutive_stride_requests;
};
-struct ll_file_dir {
- __u64 lfd_pos;
- __u64 lfd_next;
-};
-
extern cfs_mem_cache_t *ll_file_data_slab;
struct lustre_handle;
struct ll_file_data {
struct ll_readahead_state fd_ras;
int fd_omode;
struct ccc_grouplock fd_grouplock;
- struct ll_file_dir fd_dir;
+ __u64 lfd_pos;
__u32 fd_flags;
struct file *fd_file;
+ /* Indicate whether need to report failure when close.
+ * true: failure is known, not report again.
+ * false: unknown failure, should report. */
+ bool fd_write_failed;
};
struct lov_stripe_md;
void ll_release_page(struct page *page, int remove);
extern struct file_operations ll_dir_operations;
extern struct inode_operations ll_dir_inode_operations;
-struct page *ll_get_dir_page(struct file *filp, struct inode *dir, __u64 hash,
+struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
struct ll_dir_chain *chain);
-int ll_readdir(struct file *filp, void *cookie, filldir_t filldir);
+int ll_dir_read(struct inode *inode, __u64 *_pos, void *cookie,
+ filldir_t filldir);
int ll_get_mdt_idx(struct inode *inode);
/* llite/namei.c */
int lookup_flags);
int ll_lookup_it_finish(struct ptlrpc_request *request,
struct lookup_intent *it, void *data);
-struct dentry *ll_find_alias(struct inode *inode, struct dentry *de);
+struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de);
/* llite/rw.c */
int ll_prepare_write(struct file *, struct page *, unsigned from, unsigned to);
int ll_commit_write(struct file *, struct page *, unsigned from, unsigned to);
int ll_writepage(struct page *page, struct writeback_control *wbc);
+int ll_writepages(struct address_space *, struct writeback_control *wbc);
void ll_removepage(struct page *page);
int ll_readpage(struct file *file, struct page *page);
void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras);
-void ll_truncate(struct inode *inode);
int ll_file_punch(struct inode *, loff_t, int);
ssize_t ll_file_lockless_io(struct file *, char *, size_t, loff_t *, int);
void ll_clear_file_contended(struct inode*);
int ll_merge_lvb(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 obd_export *exp, void *arg);
+int ll_fid2path(struct inode *inode, void *arg);
/* llite/dcache.c */
+
int ll_dops_init(struct dentry *de, int block, int init_sa);
-extern cfs_spinlock_t ll_lookup_lock;
extern struct dentry_operations ll_d_ops;
void ll_intent_drop_lock(struct lookup_intent *);
void ll_intent_release(struct lookup_intent *);
-int ll_drop_dentry(struct dentry *dentry);
-void ll_unhash_aliases(struct inode *);
+void ll_invalidate_aliases(struct inode *);
void ll_frob_intent(struct lookup_intent **itp, struct lookup_intent *deft);
void ll_lookup_finish_locks(struct lookup_intent *it, struct dentry *dentry);
+#ifdef HAVE_D_COMPARE_7ARGS
+int ll_dcompare(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *d_name);
+#else
int ll_dcompare(struct dentry *parent, struct qstr *d_name, struct qstr *name);
+#endif
int ll_revalidate_it_finish(struct ptlrpc_request *request,
struct lookup_intent *it, struct dentry *de);
void ll_clear_inode(struct inode *inode);
int ll_setattr_raw(struct dentry *dentry, struct iattr *attr);
int ll_setattr(struct dentry *de, struct iattr *attr);
-#ifndef HAVE_STATFS_DENTRY_PARAM
-int ll_statfs(struct super_block *sb, struct kstatfs *sfs);
-#else
int ll_statfs(struct dentry *de, struct kstatfs *sfs);
-#endif
int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
__u64 max_age, __u32 flags);
void ll_update_inode(struct inode *inode, struct lustre_md *md);
#endif
int ll_remount_fs(struct super_block *sb, int *flags, char *data);
int ll_show_options(struct seq_file *seq, struct vfsmount *vfs);
+void ll_dirty_page_discard_warn(cfs_page_t *page, int ioret);
int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
struct super_block *);
void lustre_dump_dentry(struct dentry *, int recur);
int mode, __u32 opc, void *data);
void ll_finish_md_op_data(struct md_op_data *op_data);
int ll_get_obd_name(struct inode *inode, unsigned int cmd, unsigned long arg);
+char *ll_get_fsname(struct super_block *sb, char *buf, int buflen);
/* llite/llite_nfs.c */
extern struct export_operations lustre_export_operations;
__u64 end, ldlm_mode_t mode);
void policy_from_vma(ldlm_policy_data_t *policy,
struct vm_area_struct *vma, unsigned long addr, size_t count);
-struct vm_area_struct *our_vma(unsigned long addr, size_t count);
+struct vm_area_struct *our_vma(struct mm_struct *mm, unsigned long addr,
+ size_t count);
static inline void ll_invalidate_page(struct page *vmpage)
{
return LUSTRE_FPRIVATE(attr->ia_file);
}
-static inline void cl_isize_lock(struct inode *inode, int lsmlock)
+static inline void cl_isize_lock(struct inode *inode)
{
- ll_inode_size_lock(inode, lsmlock);
+ ll_inode_size_lock(inode);
}
-static inline void cl_isize_unlock(struct inode *inode, int lsmlock)
+static inline void cl_isize_unlock(struct inode *inode)
{
- ll_inode_size_unlock(inode, lsmlock);
+ ll_inode_size_unlock(inode);
}
static inline void cl_isize_write_nolock(struct inode *inode, loff_t kms)
static inline void cl_isize_write(struct inode *inode, loff_t kms)
{
- ll_inode_size_lock(inode, 0);
- i_size_write(inode, kms);
- ll_inode_size_unlock(inode, 0);
+ ll_inode_size_lock(inode);
+ i_size_write(inode, kms);
+ ll_inode_size_unlock(inode);
}
#define cl_isize_read(inode) i_size_read(inode)
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);
+
/** direct write pages */
struct ll_dio_pages {
/** page array to be written. we don't support
*bits = it->d.lustre.it_lock_bits;
}
-static inline void ll_dentry_rehash(struct dentry *dentry, int locked)
+static inline void ll_lock_dcache(struct inode *inode)
{
- if (!locked) {
- cfs_spin_lock(&ll_lookup_lock);
- spin_lock(&dcache_lock);
- }
- if (d_unhashed(dentry))
- d_rehash_cond(dentry, 0);
- if (!locked) {
- spin_unlock(&dcache_lock);
- cfs_spin_unlock(&ll_lookup_lock);
- }
+#ifdef HAVE_DCACHE_LOCK
+ spin_lock(&dcache_lock);
+#else
+ spin_lock(&inode->i_lock);
+#endif
}
-static inline void ll_dentry_reset_flags(struct dentry *dentry, __u64 bits)
+static inline void ll_unlock_dcache(struct inode *inode)
{
- if (bits & MDS_INODELOCK_LOOKUP &&
- dentry->d_flags & DCACHE_LUSTRE_INVALID) {
- lock_dentry(dentry);
- dentry->d_flags &= ~DCACHE_LUSTRE_INVALID;
- unlock_dentry(dentry);
- }
+#ifdef HAVE_DCACHE_LOCK
+ spin_unlock(&dcache_lock);
+#else
+ spin_unlock(&inode->i_lock);
+#endif
+}
+
+static inline int d_lustre_invalid(const struct dentry *dentry)
+{
+ return dentry->d_flags & DCACHE_LUSTRE_INVALID;
+}
+
+static inline void __d_lustre_invalidate(struct dentry *dentry)
+{
+ dentry->d_flags |= DCACHE_LUSTRE_INVALID;
}
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0)
+/*
+ * Mark dentry INVALID, if dentry refcount is zero (this is normally case for
+ * 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)
+{
+ 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);
+ __d_lustre_invalidate(dentry);
+ if (d_refcount(dentry) == 0)
+ __d_drop(dentry);
+ spin_unlock(&dentry->d_lock);
+}
+
+static inline void d_lustre_revalidate(struct dentry *dentry)
+{
+ spin_lock(&dentry->d_lock);
+ dentry->d_flags &= ~DCACHE_LUSTRE_INVALID;
+ spin_unlock(&dentry->d_lock);
+}
+
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0)
/* Compatibility for old (1.8) compiled userspace quota code */
struct if_quotactl_18 {
__u32 qc_cmd;
/* End compatibility for old (1.8) compiled userspace quota code */
#else
#warning "remove old LL_IOC_QUOTACTL_18 compatibility code"
-#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0) */
+#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) */
+
+int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf);
+int ll_layout_refresh(struct inode *inode, __u32 *gen);
#endif /* LLITE_INTERNAL_H */