mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
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: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -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,
|
|||||||
}
|
}
|
||||||
} 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,
|
|||||||
/* 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,
|
|||||||
/* 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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user