The fact that S_BIAS is very large is only used four times,
all(*) with:
if (s->s_count > S_BIAS) {
atomic_inc(&s->s_active);
The statement "s->s_count > S_BIAS" is exactly equivalent
to "atomic_read(&s->s_active) != 0", as the bias is subtracted
as soon as s_active becomes zero.
So the above test can more simply become:
if (atomic_inc_not_zero(&s->s_active)) {
With this in place, S_BIAS does not need to be large, and a value of
'1' will suit. This simplifies code in a number of places and
removes the need to take a spinlock in several cases.
(*) full disclosure: in two cases (inotify) it is
if (s->s_count >= S_BIAS {
however the logic still holds - that can only be true if
s_active is not zero.
Signed-off-by: NeilBrown <neilb@suse.de>
---
fs/notify/inotify/inotify.c | 33 ++++++++++++++-------------------
fs/super.c | 16 +++++-----------
include/linux/fs.h | 1 -
3 files changed, 19 insertions(+), 31 deletions(-)
diff --git a/fs/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c
index 40b1cf9..44256e5 100644
--- a/fs/notify/inotify/inotify.c
+++ b/fs/notify/inotify/inotify.c
@@ -110,14 +110,10 @@ EXPORT_SYMBOL_GPL(get_inotify_watch);
int pin_inotify_watch(struct inotify_watch *watch)
{
struct super_block *sb = watch->inode->i_sb;
- spin_lock(&sb_lock);
- if (sb->s_count >= S_BIAS) {
- atomic_inc(&sb->s_active);
- spin_unlock(&sb_lock);
+ if (atomic_inc_not_zero(&sb->s_active)) {
atomic_inc(&watch->count);
return 1;
}
- spin_unlock(&sb_lock);
return 0;
}
@@ -518,16 +514,17 @@ EXPORT_SYMBOL_GPL(inotify_init_watch);
* ->s_umount, which will almost certainly wait until the superblock is shut
* down and the watch in question is pining for fjords. That's fine, but
* there is a problem - we might have hit the window between ->s_active
- * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock
- * is past the point of no return and is heading for shutdown) ...