Filesystem with frozen but unlinked files cannot be forced into a fully consistent state. Also handling of closing such files on frozen filesystem is problematic since fput() can be called with mmap_sem held and protection against frozen filesystem ranks above it. Signed-off-by: Jan Kara <jack@xxxxxxx> --- fs/super.c | 26 +++++++++++++++++++------- 1 files changed, 19 insertions(+), 7 deletions(-) diff --git a/fs/super.c b/fs/super.c index 0830afb..e0f5992 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1415,16 +1415,22 @@ int freeze_super(struct super_block *sb) /* All writers are done so after syncing there won't be dirty data */ sync_filesystem(sb); + /* + * Check whether there are some open unlinked files (since all writers + * are blocked, new ones cannot be created now so the check is + * reliable). In that case filesystem cannot be forced into a + * consistent state so we just bail out. + */ + if (atomic_long_read(&sb->s_remove_count)) { + ret = -EBUSY; + goto bail; + } + if (sb->s_op->freeze_fs) { ret = sb->s_op->freeze_fs(sb); if (ret) { - printk(KERN_ERR - "VFS:Filesystem freeze failed\n"); - sb->s_writers.frozen = SB_UNFROZEN; - smp_wmb(); - wake_up(&sb->s_writers.wait_unfrozen); - deactivate_locked_super(sb); - return ret; + printk(KERN_ERR "VFS: Filesystem freeze failed\n"); + goto bail; } } /* @@ -1434,6 +1440,12 @@ int freeze_super(struct super_block *sb) sb->s_writers.frozen = SB_FREEZE_COMPLETE; up_write(&sb->s_umount); return 0; +bail: + sb->s_writers.frozen = SB_UNFROZEN; + smp_wmb(); + wake_up(&sb->s_writers.wait_unfrozen); + deactivate_locked_super(sb); + return ret; } EXPORT_SYMBOL(freeze_super); -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html