freeze_bdev() with read-only mounted device(*) does not change sb->s_frozen from SB_UNFROZEN to SB_FREEZE_TRANS.
Because of this behavior, xfs_freeze can break read-only filesystem. Because xfs_thaw does nothing for the filesystem whose sb->s_frozen is SB_UNFROZEN. So frozen read-only XFS filesystem will never be unfrozen. Thus we cannot do any unmount/remount operations for that filesystem. This patch updates sb->s_frozen when freeze_bdev() is called for read-only mounted device, too. (*) freezing read-only filesystem is not so pointless. Because it can prevent from someone trying to remount read/write while freezing. Cc: David Chinner <[EMAIL PROTECTED]> Cc: Tim Shimmin <[EMAIL PROTECTED]> Cc: Christoph Hellwig <[EMAIL PROTECTED]> Signed-off-by: Akinobu Mita <[EMAIL PROTECTED]> --- fs/buffer.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) Index: 2.6-git/fs/buffer.c =================================================================== --- 2.6-git.orig/fs/buffer.c +++ 2.6-git/fs/buffer.c @@ -190,21 +190,28 @@ struct super_block *freeze_bdev(struct b down(&bdev->bd_mount_sem); sb = get_super(bdev); - if (sb && !(sb->s_flags & MS_RDONLY)) { - sb->s_frozen = SB_FREEZE_WRITE; - smp_wmb(); - - __fsync_super(sb); + if (!sb) + goto out; + if (sb->s_flags & MS_RDONLY) { sb->s_frozen = SB_FREEZE_TRANS; smp_wmb(); + goto out; + } - sync_blockdev(sb->s_bdev); + sb->s_frozen = SB_FREEZE_WRITE; + smp_wmb(); - if (sb->s_op->write_super_lockfs) - sb->s_op->write_super_lockfs(sb); - } + __fsync_super(sb); + + sb->s_frozen = SB_FREEZE_TRANS; + smp_wmb(); + sync_blockdev(sb->s_bdev); + + if (sb->s_op->write_super_lockfs) + sb->s_op->write_super_lockfs(sb); +out: sync_blockdev(bdev); return sb; /* thaw_bdev releases s->s_umount and bd_mount_sem */ } - 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/