diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-03-07 06:49:10 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-03-12 16:59:12 +0100 |
commit | 0632a9ac7bc0a32f8251a53b3925775f0a7c4da6 (patch) | |
tree | 6eda70aec8d9d017ce6a4d9b6a442fd0a9da2194 /fs/dcache.c | |
parent | fs: dcache: Use READ_ONCE when accessing i_dir_seq (diff) | |
download | linux-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.c | 44 |
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) |