Messages in this thread Patch in this message |  | | Date | Mon, 13 Aug 2001 21:35:09 -0400 (EDT) | From | Alexander Viro <> | Subject | [PATCH] (10/11) fs/super.c fixes |
| |
Part 10/11
Long-promised cleanup: lock_super(sb);unlock_super(sb); is gone from get_super(). ->s_umount gives all needed exclusion.
And here comes the rest of ->s_count story: we lump all permanent references together, but now we count them as 1+BIGNUM. Now conversion of temporary reference to permanent one can recognize dying superblocks by s_count alone. We don't have to rely on mount_sem for that. Check grab_super() and the very beginning of kill_super() for details - it's quite straightforward. That's where we need atomicity of s_active, BTW.
diff -urN S9-pre3-dquot/fs/super.c S9-pre3-s_count/fs/super.c --- S9-pre3-dquot/fs/super.c Mon Aug 13 21:21:28 2001 +++ S9-pre3-s_count/fs/super.c Mon Aug 13 21:21:29 2001 @@ -732,10 +732,6 @@ s = find_super(dev); if (s) { spin_unlock(&sb_lock); - /* Yes, it sucks. As soon as we get refcounting... */ - /* Almost there - next two lines will go away RSN */ - lock_super(s); - unlock_super(s); down_read(&s->s_umount); if (s->s_root) return s; @@ -818,6 +814,7 @@ spin_lock(&sb_lock); list_add (&s->s_list, super_blocks.prev); list_add (&s->s_instances, &type->fs_supers); + s->s_count += S_BIAS; spin_unlock(&sb_lock); down_write(&s->s_umount); lock_super(s); @@ -839,6 +836,7 @@ spin_lock(&sb_lock); list_del(&s->s_list); list_del(&s->s_instances); + s->s_count -= S_BIAS; spin_unlock(&sb_lock); put_super(s); return NULL; @@ -879,13 +877,13 @@ spin_unlock(&sb_lock); down_write(&sb->s_umount); if (sb->s_root) { - /* Still relying on mount_sem */ - if (atomic_read(&sb->s_active) > 1) { - spin_lock(&sb_lock); + spin_lock(&sb_lock); + if (sb->s_count > S_BIAS) { sb->s_count--; spin_unlock(&sb_lock); return 1; } + spin_unlock(&sb_lock); } atomic_dec(&sb->s_active); put_super(sb); @@ -970,6 +968,7 @@ s->s_type = fs_type; list_add (&s->s_list, super_blocks.prev); list_add (&s->s_instances, &fs_type->fs_supers); + s->s_count += S_BIAS; spin_unlock(&sb_lock); @@ -993,6 +992,7 @@ spin_lock(&sb_lock); list_del(&s->s_list); list_del(&s->s_instances); + s->s_count -= S_BIAS; spin_unlock(&sb_lock); put_super(s); out1: @@ -1061,6 +1061,7 @@ s->s_type = fs_type; list_add (&s->s_list, super_blocks.prev); list_add (&s->s_instances, &fs_type->fs_supers); + s->s_count += S_BIAS; spin_unlock(&sb_lock); lock_super(s); if (!fs_type->read_super(s, data, 0)) @@ -1078,6 +1079,7 @@ spin_lock(&sb_lock); list_del(&s->s_list); list_del(&s->s_instances); + s->s_count -= S_BIAS; spin_unlock(&sb_lock); put_super(s); put_unnamed_dev(dev); @@ -1094,8 +1096,12 @@ struct file_system_type *fs = sb->s_type; struct super_operations *sop = sb->s_op; - if (!atomic_dec_and_test(&sb->s_active)) + if (!atomic_dec_and_lock(&sb->s_active, &sb_lock)) return; + + sb->s_count -= S_BIAS; + spin_unlock(&sb_lock); + down_write(&sb->s_umount); lock_kernel(); sb->s_root = NULL; diff -urN S9-pre3-dquot/include/linux/fs.h S9-pre3-s_count/include/linux/fs.h --- S9-pre3-dquot/include/linux/fs.h Mon Aug 13 21:21:28 2001 +++ S9-pre3-s_count/include/linux/fs.h Mon Aug 13 21:21:29 2001 @@ -660,6 +660,7 @@ extern spinlock_t sb_lock; #define sb_entry(list) list_entry((list), struct super_block, s_list) +#define S_BIAS (1<<30) struct super_block { struct list_head s_list; /* Keep this first */ kdev_t s_dev;
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |