diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-03-09 19:52:39 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-03-14 00:17:38 -0400 |
commit | ed782b5a70a016dbfe503089fd5c11dd74953cc4 (patch) | |
tree | b71d827f20323980723d707009f371908b9c4179 /fs/dcache.c | |
parent | de689f5e366373682e95059e9b89d981187e4544 (diff) |
dcache.c: new helper: __d_add()
d_add() with inode->i_lock already held; common to d_add() and
d_splice_alias(). All ->lookup() instances that end up hashing
the dentry they are given will hash it here.
This almost completes the preparations to parallel lookups
proper - the only remaining bit is taking security_d_instantiate()
past d_rehash() and doing rehashing without dropping ->d_lock.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 57da4127ea04..32ceae3e6112 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2360,6 +2360,19 @@ void d_rehash(struct dentry * entry) } EXPORT_SYMBOL(d_rehash); + +/* inode->i_lock held if inode is non-NULL */ + +static inline void __d_add(struct dentry *dentry, struct inode *inode) +{ + if (inode) { + __d_instantiate(dentry, inode); + spin_unlock(&inode->i_lock); + } + security_d_instantiate(dentry, inode); + d_rehash(dentry); +} + /** * d_add - add dentry to hash queues * @entry: dentry to add @@ -2371,8 +2384,9 @@ EXPORT_SYMBOL(d_rehash); void d_add(struct dentry *entry, struct inode *inode) { - d_instantiate(entry, inode); - d_rehash(entry); + if (inode) + spin_lock(&inode->i_lock); + __d_add(entry, inode); } EXPORT_SYMBOL(d_add); @@ -2798,12 +2812,8 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) return new; } } - /* already taking inode->i_lock, so d_add() by hand */ - __d_instantiate(dentry, inode); - spin_unlock(&inode->i_lock); out: - security_d_instantiate(dentry, inode); - d_rehash(dentry); + __d_add(dentry, inode); return NULL; } EXPORT_SYMBOL(d_splice_alias); |