take write_seqcount_invalidate() into __d_drop()

... and reorder it with making d_unhashed() true.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2018-03-07 00:49:10 -05:00
parent 8cc07c808c
commit 0632a9ac7b

View File

@ -470,30 +470,29 @@ static void dentry_lru_add(struct dentry *dentry)
*/ */
static void ___d_drop(struct dentry *dentry) static void ___d_drop(struct dentry *dentry)
{ {
if (!d_unhashed(dentry)) { struct hlist_bl_head *b;
struct hlist_bl_head *b; /*
/* * Hashed dentries are normally on the dentry hashtable,
* Hashed dentries are normally on the dentry hashtable, * with the exception of those newly allocated by
* with the exception of those newly allocated by * d_obtain_root, which are always IS_ROOT:
* d_obtain_root, which are always IS_ROOT: */
*/ if (unlikely(IS_ROOT(dentry)))
if (unlikely(IS_ROOT(dentry))) b = &dentry->d_sb->s_roots;
b = &dentry->d_sb->s_roots; else
else b = d_hash(dentry->d_name.hash);
b = d_hash(dentry->d_name.hash);
hlist_bl_lock(b); hlist_bl_lock(b);
__hlist_bl_del(&dentry->d_hash); __hlist_bl_del(&dentry->d_hash);
hlist_bl_unlock(b); hlist_bl_unlock(b);
/* After this call, in-progress rcu-walk path lookup will fail. */
write_seqcount_invalidate(&dentry->d_seq);
}
} }
void __d_drop(struct dentry *dentry) void __d_drop(struct dentry *dentry)
{ {
___d_drop(dentry); if (!d_unhashed(dentry)) {
dentry->d_hash.pprev = NULL; ___d_drop(dentry);
dentry->d_hash.pprev = NULL;
write_seqcount_invalidate(&dentry->d_seq);
}
} }
EXPORT_SYMBOL(__d_drop); EXPORT_SYMBOL(__d_drop);
@ -2853,9 +2852,10 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
write_seqcount_begin_nested(&target->d_seq, DENTRY_D_LOCK_NESTED); write_seqcount_begin_nested(&target->d_seq, DENTRY_D_LOCK_NESTED);
/* unhash both */ /* unhash both */
/* ___d_drop does write_seqcount_barrier, but they're OK to nest. */ if (!d_unhashed(dentry))
___d_drop(dentry); ___d_drop(dentry);
___d_drop(target); if (!d_unhashed(target))
___d_drop(target);
/* Switch the names.. */ /* Switch the names.. */
if (exchange) if (exchange)