aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-03-09 19:52:39 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2016-03-14 00:17:38 -0400
commited782b5a70a016dbfe503089fd5c11dd74953cc4 (patch)
treeb71d827f20323980723d707009f371908b9c4179
parentdon't bother with __d_instantiate(dentry, NULL) (diff)
downloadlinux-dev-ed782b5a70a016dbfe503089fd5c11dd74953cc4.tar.xz
linux-dev-ed782b5a70a016dbfe503089fd5c11dd74953cc4.zip
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>
-rw-r--r--fs/dcache.c24
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);