[PATCH 2/4] kernfs: Prepare directory revisions for lockless reads
Shakeel Butt <[email protected]>
| Newsgroups | org.kernel.vger.cgroups,dev.linux.lists.driver-core,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Negative dentry revalidation only needs to sample the parent directory generation and compare it with the value recorded at lookup time. Annotate those accesses with READ_ONCE() and WRITE_ONCE() so the comparison can safely move outside kernfs_rwsem. Revision updates remain serialized by kernfs_rwsem. Assert that writer contract in kernfs_inc_rev(); the read half of the increment stays plain because the semaphore excludes other writers. Signed-off-by: Shakeel Butt <[email protected]> --- fs/kernfs/kernfs-internal.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index aa784b540b36..20a0cf42ba8d 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -147,20 +147,19 @@ static inline struct kernfs_node *kernfs_dentry_node(struct dentry *dentry) static inline void kernfs_set_rev(struct kernfs_node *parent, struct dentry *dentry) { - dentry->d_time = parent->dir.rev; + WRITE_ONCE(dentry->d_time, READ_ONCE(parent->dir.rev)); } static inline void kernfs_inc_rev(struct kernfs_node *parent) { - parent->dir.rev++; + lockdep_assert_held_write(&parent->dir.root->kernfs_rwsem); + WRITE_ONCE(parent->dir.rev, parent->dir.rev + 1); } static inline bool kernfs_dir_changed(struct kernfs_node *parent, struct dentry *dentry) { - if (parent->dir.rev != dentry->d_time) - return true; - return false; + return READ_ONCE(parent->dir.rev) != READ_ONCE(dentry->d_time); } extern const struct super_operations kernfs_sops; -- 2.53.0-Meta