summaryrefslogtreecommitdiff
path: root/include/linux/dcache.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/dcache.h')
-rw-r--r--include/linux/dcache.h38
1 files changed, 37 insertions, 1 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 4bb4de8d95ea..f8506e8dd4d4 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -123,7 +123,10 @@ struct dentry {
unsigned long d_time; /* used by d_revalidate */
void *d_fsdata; /* fs-specific data */
- struct list_head d_lru; /* LRU list */
+ union {
+ struct list_head d_lru; /* LRU list */
+ wait_queue_head_t *d_wait; /* in-lookup ones only */
+ };
struct list_head d_child; /* child of parent list */
struct list_head d_subdirs; /* our children */
/*
@@ -131,6 +134,7 @@ struct dentry {
*/
union {
struct hlist_node d_alias; /* inode alias list */
+ struct hlist_bl_node d_in_lookup_hash; /* only for in-lookup ones */
struct rcu_head d_rcu;
} d_u;
};
@@ -232,6 +236,8 @@ struct dentry_operations {
#define DCACHE_ENCRYPTED_WITH_KEY 0x04000000 /* dir is encrypted with a valid key */
#define DCACHE_OP_REAL 0x08000000
+#define DCACHE_PAR_LOOKUP 0x10000000 /* being looked up (with parent locked shared) */
+
extern seqlock_t rename_lock;
/*
@@ -248,6 +254,8 @@ extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op
/* allocate/de-allocate */
extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *);
+extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *,
+ wait_queue_head_t *);
extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *);
extern struct dentry * d_exact_alias(struct dentry *, struct inode *);
@@ -367,6 +375,22 @@ static inline void dont_mount(struct dentry *dentry)
spin_unlock(&dentry->d_lock);
}
+extern void __d_lookup_done(struct dentry *);
+
+static inline int d_in_lookup(struct dentry *dentry)
+{
+ return dentry->d_flags & DCACHE_PAR_LOOKUP;
+}
+
+static inline void d_lookup_done(struct dentry *dentry)
+{
+ if (unlikely(d_in_lookup(dentry))) {
+ spin_lock(&dentry->d_lock);
+ __d_lookup_done(dentry);
+ spin_unlock(&dentry->d_lock);
+ }
+}
+
extern void dput(struct dentry *);
static inline bool d_managed(const struct dentry *dentry)
@@ -565,4 +589,16 @@ static inline struct dentry *d_real(struct dentry *dentry)
return dentry;
}
+static inline struct inode *vfs_select_inode(struct dentry *dentry,
+ unsigned open_flags)
+{
+ struct inode *inode = d_inode(dentry);
+
+ if (inode && unlikely(dentry->d_flags & DCACHE_OP_SELECT_INODE))
+ inode = dentry->d_op->d_select_inode(dentry, open_flags);
+
+ return inode;
+}
+
+
#endif /* __LINUX_DCACHE_H */