autofs: don't bother with atomics for ino->count
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 18 Sep 2019 03:31:27 +0000 (23:31 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 18 Sep 2019 03:31:27 +0000 (23:31 -0400)
All writers are serialized on inode->i_rwsem.  So are the readers
outside of expire.c.  And the readers in expire.c are in the
code that really doesn't care about narrow races - it's looking
for expiry candidates and its callers have to cope with the
possibility of a good candidate becoming busy right under them.

No point bothering with atomic operations - just use int and
mark the non-serialized readers with READ_ONCE().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/autofs/autofs_i.h
fs/autofs/expire.c
fs/autofs/root.c

index 8bcec8d..054f97b 100644 (file)
@@ -63,7 +63,7 @@ struct autofs_info {
 
        struct autofs_sb_info *sbi;
        unsigned long last_used;
-       atomic_t count;
+       int count;
 
        kuid_t uid;
        kgid_t gid;
index 2866fab..31d616a 100644 (file)
@@ -211,7 +211,7 @@ static int autofs_tree_busy(struct vfsmount *mnt,
                        }
                } else {
                        struct autofs_info *ino = autofs_dentry_ino(p);
-                       unsigned int ino_count = atomic_read(&ino->count);
+                       unsigned int ino_count = READ_ONCE(ino->count);
 
                        /* allow for dget above and top is already dgot */
                        if (p == top)
@@ -379,7 +379,7 @@ static struct dentry *should_expire(struct dentry *dentry,
                /* Not a forced expire? */
                if (!(how & AUTOFS_EXP_FORCED)) {
                        /* ref-walk currently on this dentry? */
-                       ino_count = atomic_read(&ino->count) + 1;
+                       ino_count = READ_ONCE(ino->count) + 1;
                        if (d_count(dentry) > ino_count)
                                return NULL;
                }
@@ -396,7 +396,7 @@ static struct dentry *should_expire(struct dentry *dentry,
                /* Not a forced expire? */
                if (!(how & AUTOFS_EXP_FORCED)) {
                        /* ref-walk currently on this dentry? */
-                       ino_count = atomic_read(&ino->count) + 1;
+                       ino_count = READ_ONCE(ino->count) + 1;
                        if (d_count(dentry) > ino_count)
                                return NULL;
                }
index ae1d112..5aaa173 100644 (file)
@@ -569,9 +569,9 @@ static int autofs_dir_symlink(struct inode *dir,
        d_add(dentry, inode);
 
        dget(dentry);
-       atomic_inc(&ino->count);
+       ino->count++;
        p_ino = autofs_dentry_ino(dentry->d_parent);
-       atomic_inc(&p_ino->count);
+       p_ino->count++;
 
        dir->i_mtime = current_time(dir);
 
@@ -609,9 +609,9 @@ static int autofs_dir_unlink(struct inode *dir, struct dentry *dentry)
        if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -EACCES;
 
-       atomic_dec(&ino->count);
+       ino->count--;
        p_ino = autofs_dentry_ino(dentry->d_parent);
-       atomic_dec(&p_ino->count);
+       p_ino->count--;
        dput(ino->dentry);
 
        d_inode(dentry)->i_size = 0;
@@ -669,7 +669,7 @@ static void autofs_clear_leaf_automount_flags(struct dentry *dentry)
        /* only consider parents below dentrys in the root */
        if (IS_ROOT(parent->d_parent))
                return;
-       if (atomic_read(&autofs_dentry_ino(parent)->count) == 2)
+       if (autofs_dentry_ino(parent)->count == 2)
                managed_dentry_set_managed(parent);
 }
 
@@ -691,7 +691,7 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
        if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -EACCES;
 
-       if (atomic_read(&ino->count) != 1)
+       if (ino->count != 1)
                return -ENOTEMPTY;
 
        spin_lock(&sbi->lookup_lock);
@@ -702,9 +702,9 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
        if (sbi->version < 5)
                autofs_clear_leaf_automount_flags(dentry);
 
-       atomic_dec(&ino->count);
+       ino->count--;
        p_ino = autofs_dentry_ino(dentry->d_parent);
-       atomic_dec(&p_ino->count);
+       p_ino->count--;
        dput(ino->dentry);
        d_inode(dentry)->i_size = 0;
        clear_nlink(d_inode(dentry));
@@ -750,9 +750,9 @@ static int autofs_dir_mkdir(struct inode *dir,
                autofs_set_leaf_automount_flags(dentry);
 
        dget(dentry);
-       atomic_inc(&ino->count);
+       ino->count++;
        p_ino = autofs_dentry_ino(dentry->d_parent);
-       atomic_inc(&p_ino->count);
+       p_ino->count++;
        inc_nlink(dir);
        dir->i_mtime = current_time(dir);