aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorJohann Lombardi <johann@whamcloud.com>2011-05-24 18:31:25 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-05-24 18:31:25 -0400
commitc5e06d101aaf72f1f2192a661414459775e9bd74 (patch)
tree96d05d41be2bfea6d51be915ce196f033a5d9bf3 /fs/ext4/super.c
parentd02a9391f79cab65cde74cd9e8ccd2290a565229 (diff)
ext4: add support for multiple mount protection
Prevent an ext4 filesystem from being mounted multiple times. A sequence number is stored on disk and is periodically updated (every 5 seconds by default) by a mounted filesystem. At mount time, we now wait for s_mmp_update_interval seconds to make sure that the MMP sequence does not change. In case of failure, the nodename, bdevname and the time at which the MMP block was last updated is displayed. Signed-off-by: Andreas Dilger <adilger@whamcloud.com> Signed-off-by: Johann Lombardi <johann@whamcloud.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 266174b268cc..d9937df7f5cf 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -822,6 +822,8 @@ static void ext4_put_super(struct super_block *sb)
822 invalidate_bdev(sbi->journal_bdev); 822 invalidate_bdev(sbi->journal_bdev);
823 ext4_blkdev_remove(sbi); 823 ext4_blkdev_remove(sbi);
824 } 824 }
825 if (sbi->s_mmp_tsk)
826 kthread_stop(sbi->s_mmp_tsk);
825 sb->s_fs_info = NULL; 827 sb->s_fs_info = NULL;
826 /* 828 /*
827 * Now that we are completely done shutting down the 829 * Now that we are completely done shutting down the
@@ -3486,6 +3488,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3486 EXT4_HAS_INCOMPAT_FEATURE(sb, 3488 EXT4_HAS_INCOMPAT_FEATURE(sb,
3487 EXT4_FEATURE_INCOMPAT_RECOVER)); 3489 EXT4_FEATURE_INCOMPAT_RECOVER));
3488 3490
3491 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_MMP) &&
3492 !(sb->s_flags & MS_RDONLY))
3493 if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
3494 goto failed_mount3;
3495
3489 /* 3496 /*
3490 * The first inode we look at is the journal inode. Don't try 3497 * The first inode we look at is the journal inode. Don't try
3491 * root first: it may be modified in the journal! 3498 * root first: it may be modified in the journal!
@@ -3733,6 +3740,8 @@ failed_mount3:
3733 percpu_counter_destroy(&sbi->s_freeinodes_counter); 3740 percpu_counter_destroy(&sbi->s_freeinodes_counter);
3734 percpu_counter_destroy(&sbi->s_dirs_counter); 3741 percpu_counter_destroy(&sbi->s_dirs_counter);
3735 percpu_counter_destroy(&sbi->s_dirtyblocks_counter); 3742 percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
3743 if (sbi->s_mmp_tsk)
3744 kthread_stop(sbi->s_mmp_tsk);
3736failed_mount2: 3745failed_mount2:
3737 for (i = 0; i < db_count; i++) 3746 for (i = 0; i < db_count; i++)
3738 brelse(sbi->s_group_desc[i]); 3747 brelse(sbi->s_group_desc[i]);
@@ -4268,7 +4277,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
4268 int enable_quota = 0; 4277 int enable_quota = 0;
4269 ext4_group_t g; 4278 ext4_group_t g;
4270 unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; 4279 unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
4271 int err; 4280 int err = 0;
4272#ifdef CONFIG_QUOTA 4281#ifdef CONFIG_QUOTA
4273 int i; 4282 int i;
4274#endif 4283#endif
@@ -4394,6 +4403,13 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
4394 goto restore_opts; 4403 goto restore_opts;
4395 if (!ext4_setup_super(sb, es, 0)) 4404 if (!ext4_setup_super(sb, es, 0))
4396 sb->s_flags &= ~MS_RDONLY; 4405 sb->s_flags &= ~MS_RDONLY;
4406 if (EXT4_HAS_INCOMPAT_FEATURE(sb,
4407 EXT4_FEATURE_INCOMPAT_MMP))
4408 if (ext4_multi_mount_protect(sb,
4409 le64_to_cpu(es->s_mmp_block))) {
4410 err = -EROFS;
4411 goto restore_opts;
4412 }
4397 enable_quota = 1; 4413 enable_quota = 1;
4398 } 4414 }
4399 } 4415 }