Commit 850d71ac authored by Al Viro's avatar Al Viro

autofs: don't bother with atomics for ino->count

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent c3aed166
...@@ -63,7 +63,7 @@ struct autofs_info { ...@@ -63,7 +63,7 @@ struct autofs_info {
struct autofs_sb_info *sbi; struct autofs_sb_info *sbi;
unsigned long last_used; unsigned long last_used;
atomic_t count; int count;
kuid_t uid; kuid_t uid;
kgid_t gid; kgid_t gid;
......
...@@ -211,7 +211,7 @@ static int autofs_tree_busy(struct vfsmount *mnt, ...@@ -211,7 +211,7 @@ static int autofs_tree_busy(struct vfsmount *mnt,
} }
} else { } else {
struct autofs_info *ino = autofs_dentry_ino(p); 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 */ /* allow for dget above and top is already dgot */
if (p == top) if (p == top)
...@@ -379,7 +379,7 @@ static struct dentry *should_expire(struct dentry *dentry, ...@@ -379,7 +379,7 @@ static struct dentry *should_expire(struct dentry *dentry,
/* Not a forced expire? */ /* Not a forced expire? */
if (!(how & AUTOFS_EXP_FORCED)) { if (!(how & AUTOFS_EXP_FORCED)) {
/* ref-walk currently on this dentry? */ /* 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) if (d_count(dentry) > ino_count)
return NULL; return NULL;
} }
...@@ -396,7 +396,7 @@ static struct dentry *should_expire(struct dentry *dentry, ...@@ -396,7 +396,7 @@ static struct dentry *should_expire(struct dentry *dentry,
/* Not a forced expire? */ /* Not a forced expire? */
if (!(how & AUTOFS_EXP_FORCED)) { if (!(how & AUTOFS_EXP_FORCED)) {
/* ref-walk currently on this dentry? */ /* 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) if (d_count(dentry) > ino_count)
return NULL; return NULL;
} }
......
...@@ -569,9 +569,9 @@ static int autofs_dir_symlink(struct inode *dir, ...@@ -569,9 +569,9 @@ static int autofs_dir_symlink(struct inode *dir,
d_add(dentry, inode); d_add(dentry, inode);
dget(dentry); dget(dentry);
atomic_inc(&ino->count); ino->count++;
p_ino = autofs_dentry_ino(dentry->d_parent); p_ino = autofs_dentry_ino(dentry->d_parent);
atomic_inc(&p_ino->count); p_ino->count++;
dir->i_mtime = current_time(dir); dir->i_mtime = current_time(dir);
...@@ -609,9 +609,9 @@ static int autofs_dir_unlink(struct inode *dir, struct dentry *dentry) ...@@ -609,9 +609,9 @@ static int autofs_dir_unlink(struct inode *dir, struct dentry *dentry)
if (sbi->flags & AUTOFS_SBI_CATATONIC) if (sbi->flags & AUTOFS_SBI_CATATONIC)
return -EACCES; return -EACCES;
atomic_dec(&ino->count); ino->count--;
p_ino = autofs_dentry_ino(dentry->d_parent); p_ino = autofs_dentry_ino(dentry->d_parent);
atomic_dec(&p_ino->count); p_ino->count--;
dput(ino->dentry); dput(ino->dentry);
d_inode(dentry)->i_size = 0; d_inode(dentry)->i_size = 0;
...@@ -669,7 +669,7 @@ static void autofs_clear_leaf_automount_flags(struct dentry *dentry) ...@@ -669,7 +669,7 @@ static void autofs_clear_leaf_automount_flags(struct dentry *dentry)
/* only consider parents below dentrys in the root */ /* only consider parents below dentrys in the root */
if (IS_ROOT(parent->d_parent)) if (IS_ROOT(parent->d_parent))
return; return;
if (atomic_read(&autofs_dentry_ino(parent)->count) == 2) if (autofs_dentry_ino(parent)->count == 2)
managed_dentry_set_managed(parent); managed_dentry_set_managed(parent);
} }
...@@ -691,7 +691,7 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -691,7 +691,7 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
if (sbi->flags & AUTOFS_SBI_CATATONIC) if (sbi->flags & AUTOFS_SBI_CATATONIC)
return -EACCES; return -EACCES;
if (atomic_read(&ino->count) != 1) if (ino->count != 1)
return -ENOTEMPTY; return -ENOTEMPTY;
spin_lock(&sbi->lookup_lock); spin_lock(&sbi->lookup_lock);
...@@ -702,9 +702,9 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry) ...@@ -702,9 +702,9 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
if (sbi->version < 5) if (sbi->version < 5)
autofs_clear_leaf_automount_flags(dentry); autofs_clear_leaf_automount_flags(dentry);
atomic_dec(&ino->count); ino->count--;
p_ino = autofs_dentry_ino(dentry->d_parent); p_ino = autofs_dentry_ino(dentry->d_parent);
atomic_dec(&p_ino->count); p_ino->count--;
dput(ino->dentry); dput(ino->dentry);
d_inode(dentry)->i_size = 0; d_inode(dentry)->i_size = 0;
clear_nlink(d_inode(dentry)); clear_nlink(d_inode(dentry));
...@@ -750,9 +750,9 @@ static int autofs_dir_mkdir(struct inode *dir, ...@@ -750,9 +750,9 @@ static int autofs_dir_mkdir(struct inode *dir,
autofs_set_leaf_automount_flags(dentry); autofs_set_leaf_automount_flags(dentry);
dget(dentry); dget(dentry);
atomic_inc(&ino->count); ino->count++;
p_ino = autofs_dentry_ino(dentry->d_parent); p_ino = autofs_dentry_ino(dentry->d_parent);
atomic_inc(&p_ino->count); p_ino->count++;
inc_nlink(dir); inc_nlink(dir);
dir->i_mtime = current_time(dir); dir->i_mtime = current_time(dir);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment