Don't hold lock_super() while running ->sync_fs(). It can deadlock, because: a) ext3_sync_fs() has to wait until a transaction has finished. b) a transaction cannot finish when someone else holds lock_super(). Because lock_super() is used in the block allocator. Documentation/filesystems/Locking | 2 ++ fs/buffer.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) --- linux-2.4.20-ext3merge/Documentation/filesystems/Locking.=K0030=.orig 2002-12-16 17:09:44.000000000 +0000 +++ linux-2.4.20-ext3merge/Documentation/filesystems/Locking 2002-12-16 17:09:44.000000000 +0000 @@ -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) --- linux-2.4.20-ext3merge/fs/buffer.c.=K0030=.orig 2002-12-16 17:09:44.000000000 +0000 +++ linux-2.4.20-ext3merge/fs/buffer.c 2002-12-16 17:09:44.000000000 +0000 @@ -328,9 +328,9 @@ lock_super(sb); 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_super(sb); unlock_kernel(); return sync_buffers(dev, 1);