diff -ruN linux-2.4.20.orig/Documentation/filesystems/Locking linux-2.4.20/Documentation/filesystems/Locking --- linux-2.4.20.orig/Documentation/filesystems/Locking Thu Nov 28 16:53:08 2002 +++ linux-2.4.20/Documentation/filesystems/Locking Tue Dec 17 22:22:04 2002 @@ -93,6 +93,7 @@ void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); void (*write_super) (struct super_block *); + int (*sync_fs) (struct super_block *); int (*statfs) (struct super_block *, struct statfs *); int (*remount_fs) (struct super_block *, int *, char *); void (*clear_inode) (struct inode *); @@ -108,6 +109,7 @@ clear_inode: no put_super: yes yes maybe (see below) write_super: yes yes maybe (see below) +write_super: yes no maybe (see below) statfs: yes no no remount_fs: yes yes maybe (see below) umount_begin: yes no maybe (see below) diff -ruN linux-2.4.20.orig/fs/buffer.c linux-2.4.20/fs/buffer.c --- linux-2.4.20.orig/fs/buffer.c Tue Dec 17 22:37:37 2002 +++ linux-2.4.20/fs/buffer.c Tue Dec 17 22:22:04 2002 @@ -328,6 +328,8 @@ if (sb->s_dirt && sb->s_op && sb->s_op->write_super) sb->s_op->write_super(sb); unlock_super(sb); + if (sb->s_op && sb->s_op->sync_fs) + sb->s_op->sync_fs(sb); unlock_kernel(); return sync_buffers(dev, 1); @@ -346,7 +348,7 @@ lock_kernel(); sync_inodes(dev); DQUOT_SYNC(dev); - sync_supers(dev); + sync_supers(dev, 1); unlock_kernel(); return sync_buffers(dev, 1); @@ -2861,7 +2863,7 @@ { lock_kernel(); sync_unlocked_inodes(); - sync_supers(0); + sync_supers(0, 0); unlock_kernel(); for (;;) { diff -ruN linux-2.4.20.orig/fs/ext3/namei.c linux-2.4.20/fs/ext3/namei.c --- linux-2.4.20.orig/fs/ext3/namei.c Thu Nov 28 16:53:15 2002 +++ linux-2.4.20/fs/ext3/namei.c Tue Dec 17 22:22:10 2002 @@ -429,8 +429,11 @@ { int err = ext3_add_entry(handle, dentry, inode); if (!err) { - d_instantiate(dentry, inode); - return 0; + err = ext3_mark_inode_dirty(handle, inode); + if (err == 0) { + d_instantiate(dentry, inode); + return 0; + } } ext3_dec_count(handle, inode); iput(inode); @@ -465,7 +468,6 @@ inode->i_fop = &ext3_file_operations; inode->i_mapping->a_ops = &ext3_aops; err = ext3_add_nondir(handle, dentry, inode); - ext3_mark_inode_dirty(handle, inode); } ext3_journal_stop(handle, dir); return err; @@ -490,7 +492,6 @@ if (!IS_ERR(inode)) { init_special_inode(inode, mode, rdev); err = ext3_add_nondir(handle, dentry, inode); - ext3_mark_inode_dirty(handle, inode); } ext3_journal_stop(handle, dir); return err; @@ -934,7 +935,6 @@ } inode->u.ext3_i.i_disksize = inode->i_size; err = ext3_add_nondir(handle, dentry, inode); - ext3_mark_inode_dirty(handle, inode); out_stop: ext3_journal_stop(handle, dir); return err; @@ -971,7 +971,6 @@ atomic_inc(&inode->i_count); err = ext3_add_nondir(handle, dentry, inode); - ext3_mark_inode_dirty(handle, inode); ext3_journal_stop(handle, dir); return err; } diff -ruN linux-2.4.20.orig/fs/ext3/super.c linux-2.4.20/fs/ext3/super.c --- linux-2.4.20.orig/fs/ext3/super.c Thu Nov 28 16:53:15 2002 +++ linux-2.4.20/fs/ext3/super.c Tue Dec 17 22:20:48 2002 @@ -47,6 +47,8 @@ static void ext3_clear_journal_err(struct super_block * sb, struct ext3_super_block * es); +static int ext3_sync_fs(struct super_block * sb); + #ifdef CONFIG_JBD_DEBUG int journal_no_write[2]; @@ -454,6 +456,7 @@ delete_inode: ext3_delete_inode, /* BKL not held. We take it */ put_super: ext3_put_super, /* BKL held */ write_super: ext3_write_super, /* BKL held */ + sync_fs: ext3_sync_fs, write_super_lockfs: ext3_write_super_lockfs, /* BKL not held. Take it */ unlockfs: ext3_unlockfs, /* BKL not held. We take it */ statfs: ext3_statfs, /* BKL held */ @@ -1577,24 +1580,22 @@ * This implicitly triggers the writebehind on sync(). */ -static int do_sync_supers = 0; -MODULE_PARM(do_sync_supers, "i"); -MODULE_PARM_DESC(do_sync_supers, "Write superblocks synchronously"); - void ext3_write_super (struct super_block * sb) { + if (down_trylock(&sb->s_lock) == 0) + BUG(); + sb->s_dirt = 0; + log_start_commit(EXT3_SB(sb)->s_journal, NULL); +} + +static int ext3_sync_fs(struct super_block *sb) +{ tid_t target; - if (down_trylock(&sb->s_lock) == 0) - BUG(); /* aviro detector */ sb->s_dirt = 0; target = log_start_commit(EXT3_SB(sb)->s_journal, NULL); - - if (do_sync_supers) { - unlock_super(sb); - log_wait_commit(EXT3_SB(sb)->s_journal, target); - lock_super(sb); - } + log_wait_commit(EXT3_SB(sb)->s_journal, target); + return 0; } /* diff -ruN linux-2.4.20.orig/fs/super.c linux-2.4.20/fs/super.c --- linux-2.4.20.orig/fs/super.c Tue Dec 17 22:37:37 2002 +++ linux-2.4.20/fs/super.c Tue Dec 17 22:20:48 2002 @@ -465,7 +465,7 @@ * hold up the sync while mounting a device. (The newly * mounted device won't need syncing.) */ -void sync_supers(kdev_t dev) +void sync_supers(kdev_t dev, int wait) { struct super_block * sb; @@ -474,6 +474,8 @@ if (sb) { if (sb->s_dirt) write_super(sb); + if (wait && sb->s_op && sb->s_op->sync_fs) + sb->s_op->sync_fs(sb); drop_super(sb); } return; @@ -487,6 +489,8 @@ spin_unlock(&sb_lock); down_read(&sb->s_umount); write_super(sb); + if (wait && sb->s_op && sb->s_op->sync_fs) + sb->s_op->sync_fs(sb); drop_super(sb); goto restart; } else diff -ruN linux-2.4.20.orig/include/linux/fs.h linux-2.4.20/include/linux/fs.h --- linux-2.4.20.orig/include/linux/fs.h Tue Dec 17 22:37:37 2002 +++ linux-2.4.20/include/linux/fs.h Tue Dec 17 22:21:43 2002 @@ -926,6 +926,7 @@ void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); void (*write_super) (struct super_block *); + int (*sync_fs) (struct super_block *); void (*write_super_lockfs) (struct super_block *); void (*unlockfs) (struct super_block *); int (*statfs) (struct super_block *, struct statfs *); @@ -1273,7 +1274,7 @@ extern int inode_has_buffers(struct inode *); extern int filemap_fdatasync(struct address_space *); extern int filemap_fdatawait(struct address_space *); -extern void sync_supers(kdev_t); +extern void sync_supers(kdev_t dev, int wait); extern void sync_supers_lockfs(kdev_t); extern void unlockfs(kdev_t); extern int bmap(struct inode *, int);