|
@@ -761,6 +761,8 @@ repeat:
|
|
|
/* Slow case: now with the dentry lock held */
|
|
|
rcu_read_unlock();
|
|
|
|
|
|
+ WARN_ON(d_in_lookup(dentry));
|
|
|
+
|
|
|
/* Unreachable? Get rid of it */
|
|
|
if (unlikely(d_unhashed(dentry)))
|
|
|
goto kill_it;
|
|
@@ -1746,6 +1748,7 @@ type_determined:
|
|
|
static void __d_instantiate(struct dentry *dentry, struct inode *inode)
|
|
|
{
|
|
|
unsigned add_flags = d_flags_for_inode(inode);
|
|
|
+ WARN_ON(d_in_lookup(dentry));
|
|
|
|
|
|
spin_lock(&dentry->d_lock);
|
|
|
hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
|
|
@@ -2361,12 +2364,20 @@ void d_rehash(struct dentry * entry)
|
|
|
}
|
|
|
EXPORT_SYMBOL(d_rehash);
|
|
|
|
|
|
+void __d_lookup_done(struct dentry *dentry)
|
|
|
+{
|
|
|
+ dentry->d_flags &= ~DCACHE_PAR_LOOKUP;
|
|
|
+ /* more stuff will land here */
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(__d_lookup_done);
|
|
|
|
|
|
/* inode->i_lock held if inode is non-NULL */
|
|
|
|
|
|
static inline void __d_add(struct dentry *dentry, struct inode *inode)
|
|
|
{
|
|
|
spin_lock(&dentry->d_lock);
|
|
|
+ if (unlikely(d_in_lookup(dentry)))
|
|
|
+ __d_lookup_done(dentry);
|
|
|
if (inode) {
|
|
|
unsigned add_flags = d_flags_for_inode(inode);
|
|
|
hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
|
|
@@ -2612,6 +2623,8 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
|
|
|
BUG_ON(d_ancestor(target, dentry));
|
|
|
|
|
|
dentry_lock_for_move(dentry, target);
|
|
|
+ if (unlikely(d_in_lookup(target)))
|
|
|
+ __d_lookup_done(target);
|
|
|
|
|
|
write_seqcount_begin(&dentry->d_seq);
|
|
|
write_seqcount_begin_nested(&target->d_seq, DENTRY_D_LOCK_NESTED);
|