Patch turns s_lock+s_wait combination into semaphore. wait_on_super() is dead. lock_super() is down(&sb->s_lock), unlock_super() is up(...). One place is still ugly - get_super(), but that'll have to wait until we add reference counters on superblocks. For the time being get_super() behaviour stays unchanged (i.e. all races with umount() are still there). Please, apply it - it doesn't break anything in tree, unlikely to break anything 3rd-party and any potential breakage there will be caught by compiler. Al diff -urN S5-pre2/fs/ext2/super.c S5-pre2-s_lock/fs/ext2/super.c --- S5-pre2/fs/ext2/super.c Sat Apr 28 02:12:56 2001 +++ S5-pre2-s_lock/fs/ext2/super.c Tue May 15 18:12:35 2001 @@ -76,9 +76,6 @@ va_start (args, fmt); vsprintf (error_buf, fmt, args); va_end (args); - /* this is to prevent panic from syncing this filesystem */ - if (sb->s_lock) - sb->s_lock=0; sb->s_flags |= MS_RDONLY; panic ("EXT2-fs panic (device %s): %s: %s\n", bdevname(sb->s_dev), function, error_buf); diff -urN S5-pre2/fs/reiserfs/prints.c S5-pre2-s_lock/fs/reiserfs/prints.c --- S5-pre2/fs/reiserfs/prints.c Sat Apr 28 02:12:56 2001 +++ S5-pre2-s_lock/fs/reiserfs/prints.c Tue May 15 18:12:35 2001 @@ -349,8 +349,6 @@ #endif /* this is to prevent panic from syncing this filesystem */ - if (sb && sb->s_lock) - sb->s_lock=0; if (sb) sb->s_flags |= MS_RDONLY; diff -urN S5-pre2/fs/super.c S5-pre2-s_lock/fs/super.c --- S5-pre2/fs/super.c Tue May 15 03:51:04 2001 +++ S5-pre2-s_lock/fs/super.c Tue May 15 18:12:35 2001 @@ -580,30 +580,7 @@ #undef MANGLE #undef FREEROOM } - -/** - * __wait_on_super - wait on a superblock - * @sb: superblock to wait on - * - * Waits for a superblock to become unlocked and then returns. It does - * not take the lock. This is an internal function. See wait_on_super(). - */ -void __wait_on_super(struct super_block * sb) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(&sb->s_wait, &wait); -repeat: - set_current_state(TASK_UNINTERRUPTIBLE); - if (sb->s_lock) { - schedule(); - goto repeat; - } - remove_wait_queue(&sb->s_wait, &wait); - current->state = TASK_RUNNING; -} - /* * Note: check the dirty flag before waiting, so we don't * hold up the sync while mounting a device. (The newly @@ -648,7 +625,9 @@ s = sb_entry(super_blocks.next); while (s != sb_entry(&super_blocks)) if (s->s_dev == dev) { - wait_on_super(s); + /* Yes, it sucks. As soon as we get refcounting... */ + lock_super(s); + unlock_super(s); if (s->s_dev == dev) return s; goto restart; @@ -700,9 +679,7 @@ s = sb_entry(s->s_list.next)) { if (s->s_dev) continue; - if (!s->s_lock) - return s; - printk("VFS: empty superblock %p locked!\n", s); + return s; } /* Need a new one... */ if (nr_super_blocks >= max_super_blocks) @@ -714,10 +691,14 @@ INIT_LIST_HEAD(&s->s_dirty); INIT_LIST_HEAD(&s->s_locked_inodes); list_add (&s->s_list, super_blocks.prev); - init_waitqueue_head(&s->s_wait); INIT_LIST_HEAD(&s->s_files); INIT_LIST_HEAD(&s->s_mounts); init_rwsem(&s->s_umount); + sema_init(&s->s_lock, 1); + sema_init(&s->s_vfs_rename_sem,1); + sema_init(&s->s_nfsd_free_path_sem,1); + sema_init(&s->s_dquot.dqio_sem, 1); + sema_init(&s->s_dquot.dqoff_sem, 1); } return s; } @@ -734,11 +715,7 @@ s->s_bdev = bdev; s->s_flags = flags; s->s_dirt = 0; - sema_init(&s->s_vfs_rename_sem,1); - sema_init(&s->s_nfsd_free_path_sem,1); s->s_type = type; - sema_init(&s->s_dquot.dqio_sem, 1); - sema_init(&s->s_dquot.dqoff_sem, 1); s->s_dquot.flags = 0; s->s_maxbytes = MAX_NON_LFS; lock_super(s); diff -urN S5-pre2/fs/ufs/super.c S5-pre2-s_lock/fs/ufs/super.c --- S5-pre2/fs/ufs/super.c Sat Apr 28 02:12:56 2001 +++ S5-pre2-s_lock/fs/ufs/super.c Tue May 15 18:12:35 2001 @@ -230,9 +230,6 @@ va_start (args, fmt); vsprintf (error_buf, fmt, args); va_end (args); - /* this is to prevent panic from syncing this filesystem */ - if (sb->s_lock) - sb->s_lock = 0; sb->s_flags |= MS_RDONLY; printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n", kdevname(sb->s_dev), function, error_buf); diff -urN S5-pre2/include/linux/fs.h S5-pre2-s_lock/include/linux/fs.h --- S5-pre2/include/linux/fs.h Tue May 15 03:51:04 2001 +++ S5-pre2-s_lock/include/linux/fs.h Tue May 15 18:12:35 2001 @@ -652,7 +652,6 @@ kdev_t s_dev; unsigned long s_blocksize; unsigned char s_blocksize_bits; - unsigned char s_lock; unsigned char s_dirt; unsigned long long s_maxbytes; /* Max file size */ struct file_system_type *s_type; @@ -662,7 +661,7 @@ unsigned long s_magic; struct dentry *s_root; struct rw_semaphore s_umount; - wait_queue_head_t s_wait; + struct semaphore s_lock; struct list_head s_dirty; /* dirty inodes */ struct list_head s_locked_inodes;/* inodes being synced */ diff -urN S5-pre2/include/linux/locks.h S5-pre2-s_lock/include/linux/locks.h --- S5-pre2/include/linux/locks.h Thu May 3 15:24:14 2001 +++ S5-pre2-s_lock/include/linux/locks.h Tue May 15 18:12:35 2001 @@ -39,30 +39,15 @@ * a super-block (although even this isn't done right now. * nfs may need it). */ -extern void __wait_on_super(struct super_block *); - -extern inline void wait_on_super(struct super_block * sb) -{ - if (sb->s_lock) - __wait_on_super(sb); -} extern inline void lock_super(struct super_block * sb) { - if (sb->s_lock) - __wait_on_super(sb); - sb->s_lock = 1; + down(&sb->s_lock); } extern inline void unlock_super(struct super_block * sb) { - sb->s_lock = 0; - /* - * No need of any barrier, we're protected by - * the big kernel lock here... unfortunately :) - */ - if (waitqueue_active(&sb->s_wait)) - wake_up(&sb->s_wait); + up(&sb->s_lock); } #endif /* _LINUX_LOCKS_H */ diff -urN S5-pre2/kernel/ksyms.c S5-pre2-s_lock/kernel/ksyms.c --- S5-pre2/kernel/ksyms.c Tue May 15 03:51:04 2001 +++ S5-pre2-s_lock/kernel/ksyms.c Tue May 15 18:12:35 2001 @@ -478,7 +478,6 @@ /* Added to make file system as module */ EXPORT_SYMBOL(sys_tz); -EXPORT_SYMBOL(__wait_on_super); EXPORT_SYMBOL(file_fsync); EXPORT_SYMBOL(fsync_inode_buffers); EXPORT_SYMBOL(clear_inode); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/