Commit e101875d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] sync_fs deadlock fix

Running a `mount -o remount' against ext3 deadlocks if there is heavy
write activity.  It's a sort of AB/BA deadlock caused by calling
log_wait_commit() under lock_super().  The caller holds lock_super()
and is waiting for a commit, but the commit cannot complete because
lock_super() is also used in the block allocator.

The way we fixed this in tha past is to drop the superblock lock inside
ext3.  The way this patch fixes it is to arrange for lock_super() to
not be held around the ->sync_fs() call.

Also: sync_filesystems is on the sys_sync() path and is racy wrt
unmount.  Check sb->s_root after taking sb->s_umount.
parent d8ce4c5f
......@@ -92,7 +92,7 @@ prototypes:
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
void (*sync_fs) (struct super_block *sb, int wait);
int (*sync_fs) (struct super_block *sb, int wait);
int (*statfs) (struct super_block *, struct statfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *);
......
......@@ -221,9 +221,9 @@ int fsync_super(struct super_block *sb)
lock_super(sb);
if (sb->s_dirt && sb->s_op->write_super)
sb->s_op->write_super(sb);
unlock_super(sb);
if (sb->s_op->sync_fs)
sb->s_op->sync_fs(sb, 1);
unlock_super(sb);
sync_blockdev(sb->s_bdev);
sync_inodes_sb(sb, 1);
......
......@@ -192,8 +192,6 @@ void generic_shutdown_super(struct super_block *sb)
if (sop->write_super && sb->s_dirt)
sop->write_super(sb);
if (sop->sync_fs)
sop->sync_fs(sb, 1);
if (sop->put_super)
sop->put_super(sb);
......@@ -327,11 +325,12 @@ void sync_filesystems(int wait)
continue;
sb->s_need_sync_fs = 0;
if (sb->s_flags & MS_RDONLY)
continue; /* hm. Was remounted r/w meanwhile */
continue; /* hm. Was remounted r/o meanwhile */
sb->s_count++;
spin_unlock(&sb_lock);
down_read(&sb->s_umount);
sb->s_op->sync_fs(sb, wait);
if (sb->s_root)
sb->s_op->sync_fs(sb, wait);
drop_super(sb);
goto restart;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment