summaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-03-07 06:49:10 +0100
committerAl Viro <viro@zeniv.linux.org.uk>2018-03-12 16:59:12 +0100
commit0632a9ac7bc0a32f8251a53b3925775f0a7c4da6 (patch)
tree6eda70aec8d9d017ce6a4d9b6a442fd0a9da2194 /fs/dcache.c
parentfs: dcache: Use READ_ONCE when accessing i_dir_seq (diff)
downloadlinux-0632a9ac7bc0a32f8251a53b3925775f0a7c4da6.tar.xz
linux-0632a9ac7bc0a32f8251a53b3925775f0a7c4da6.zip
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>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 8945e6cabd93..78974248a148 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -470,30 +470,29 @@ static void dentry_lru_add(struct dentry *dentry)
*/
static void ___d_drop(struct dentry *dentry)
{
- if (!d_unhashed(dentry)) {
- struct hlist_bl_head *b;
- /*
- * Hashed dentries are normally on the dentry hashtable,
- * with the exception of those newly allocated by
- * d_obtain_root, which are always IS_ROOT:
- */
- if (unlikely(IS_ROOT(dentry)))
- b = &dentry->d_sb->s_roots;
- else
- b = d_hash(dentry->d_name.hash);
+ struct hlist_bl_head *b;
+ /*
+ * Hashed dentries are normally on the dentry hashtable,
+ * with the exception of those newly allocated by
+ * d_obtain_root, which are always IS_ROOT:
+ */
+ if (unlikely(IS_ROOT(dentry)))
+ b = &dentry->d_sb->s_roots;
+ else
+ b = d_hash(dentry->d_name.hash);
- hlist_bl_lock(b);
- __hlist_bl_del(&dentry->d_hash);
- hlist_bl_unlock(b);
- /* After this call, in-progress rcu-walk path lookup will fail. */
- write_seqcount_invalidate(&dentry->d_seq);
- }
+ hlist_bl_lock(b);
+ __hlist_bl_del(&dentry->d_hash);
+ hlist_bl_unlock(b);
}
void __d_drop(struct dentry *dentry)
{
- ___d_drop(dentry);
- dentry->d_hash.pprev = NULL;
+ if (!d_unhashed(dentry)) {
+ ___d_drop(dentry);
+ dentry->d_hash.pprev = NULL;
+ write_seqcount_invalidate(&dentry->d_seq);
+ }
}
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);
/* unhash both */
- /* ___d_drop does write_seqcount_barrier, but they're OK to nest. */
- ___d_drop(dentry);
- ___d_drop(target);
+ if (!d_unhashed(dentry))
+ ___d_drop(dentry);
+ if (!d_unhashed(target))
+ ___d_drop(target);
/* Switch the names.. */
if (exchange)