aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/fs/super.c b/fs/super.c
index c248ac6a1a21..89afca5055ab 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -944,6 +944,96 @@ out:
944 944
945EXPORT_SYMBOL_GPL(vfs_kern_mount); 945EXPORT_SYMBOL_GPL(vfs_kern_mount);
946 946
947/**
948 * freeze_super -- lock the filesystem and force it into a consistent state
949 * @super: the super to lock
950 *
951 * Syncs the super to make sure the filesystem is consistent and calls the fs's
952 * freeze_fs. Subsequent calls to this without first thawing the fs will return
953 * -EBUSY.
954 */
955int freeze_super(struct super_block *sb)
956{
957 int ret;
958
959 atomic_inc(&sb->s_active);
960 down_write(&sb->s_umount);
961 if (sb->s_frozen) {
962 deactivate_locked_super(sb);
963 return -EBUSY;
964 }
965
966 if (sb->s_flags & MS_RDONLY) {
967 sb->s_frozen = SB_FREEZE_TRANS;
968 smp_wmb();
969 up_write(&sb->s_umount);
970 return 0;
971 }
972
973 sb->s_frozen = SB_FREEZE_WRITE;
974 smp_wmb();
975
976 sync_filesystem(sb);
977
978 sb->s_frozen = SB_FREEZE_TRANS;
979 smp_wmb();
980
981 sync_blockdev(sb->s_bdev);
982 if (sb->s_op->freeze_fs) {
983 ret = sb->s_op->freeze_fs(sb);
984 if (ret) {
985 printk(KERN_ERR
986 "VFS:Filesystem freeze failed\n");
987 sb->s_frozen = SB_UNFROZEN;
988 deactivate_locked_super(sb);
989 return ret;
990 }
991 }
992 up_write(&sb->s_umount);
993 return 0;
994}
995EXPORT_SYMBOL(freeze_super);
996
997/**
998 * thaw_super -- unlock filesystem
999 * @sb: the super to thaw
1000 *
1001 * Unlocks the filesystem and marks it writeable again after freeze_super().
1002 */
1003int thaw_super(struct super_block *sb)
1004{
1005 int error;
1006
1007 down_write(&sb->s_umount);
1008 if (sb->s_frozen == SB_UNFROZEN) {
1009 up_write(&sb->s_umount);
1010 return -EINVAL;
1011 }
1012
1013 if (sb->s_flags & MS_RDONLY)
1014 goto out;
1015
1016 if (sb->s_op->unfreeze_fs) {
1017 error = sb->s_op->unfreeze_fs(sb);
1018 if (error) {
1019 printk(KERN_ERR
1020 "VFS:Filesystem thaw failed\n");
1021 sb->s_frozen = SB_FREEZE_TRANS;
1022 up_write(&sb->s_umount);
1023 return error;
1024 }
1025 }
1026
1027out:
1028 sb->s_frozen = SB_UNFROZEN;
1029 smp_wmb();
1030 wake_up(&sb->s_wait_unfrozen);
1031 deactivate_locked_super(sb);
1032
1033 return 0;
1034}
1035EXPORT_SYMBOL(thaw_super);
1036
947static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) 1037static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
948{ 1038{
949 int err; 1039 int err;