diff options
author | David Howells <dhowells@redhat.com> | 2015-03-05 14:09:22 +0000 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-15 15:05:28 -0400 |
commit | 4bf46a272647d89e780126b52eda04737defd9f4 (patch) | |
tree | 989bac3ffce8a0f7f9184e14afb2dd9c28693cfe /include/linux/dcache.h | |
parent | 525d27b23555419e0e7b73fb6e78d4d678cb4f32 (diff) | |
download | linux-4bf46a272647d89e780126b52eda04737defd9f4.tar.gz linux-4bf46a272647d89e780126b52eda04737defd9f4.tar.bz2 linux-4bf46a272647d89e780126b52eda04737defd9f4.zip |
VFS: Impose ordering on accesses of d_inode and d_flags
Impose ordering on accesses of d_inode and d_flags to avoid the need to do
this:
if (!dentry->d_inode || d_is_negative(dentry)) {
when this:
if (d_is_negative(dentry)) {
should suffice.
This check is especially problematic if a dentry can have its type field set
to something other than DENTRY_MISS_TYPE when d_inode is NULL (as in
unionmount).
What we really need to do is stick a write barrier between setting d_inode and
setting d_flags and a read barrier between reading d_flags and reading
d_inode.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/linux/dcache.h')
-rw-r--r-- | include/linux/dcache.h | 21 |
1 files changed, 3 insertions, 18 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index e83768ee38fc..df334cbacc6d 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -404,26 +404,11 @@ static inline bool d_mountpoint(const struct dentry *dentry) /* * Directory cache entry type accessor functions. */ -static inline void __d_set_type(struct dentry *dentry, unsigned type) -{ - dentry->d_flags = (dentry->d_flags & ~DCACHE_ENTRY_TYPE) | type; -} - -static inline void __d_clear_type(struct dentry *dentry) -{ - __d_set_type(dentry, DCACHE_MISS_TYPE); -} - -static inline void d_set_type(struct dentry *dentry, unsigned type) -{ - spin_lock(&dentry->d_lock); - __d_set_type(dentry, type); - spin_unlock(&dentry->d_lock); -} - static inline unsigned __d_entry_type(const struct dentry *dentry) { - return dentry->d_flags & DCACHE_ENTRY_TYPE; + unsigned type = READ_ONCE(dentry->d_flags); + smp_rmb(); + return type & DCACHE_ENTRY_TYPE; } static inline bool d_is_miss(const struct dentry *dentry) |