aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2009-05-17 15:38:01 -0400
committerTheodore Ts'o <tytso@mit.edu>2009-05-17 15:38:01 -0400
commit6fd058f7791087648c683eb8572edf3be3c4c23c (patch)
tree0d80791532d2d022c91f20013003716eaf0afb40 /fs/ext4/super.c
parent2ac3b6e00acb46406c993d57921f86a594aafe08 (diff)
ext4: Add a comprehensive block validity check to ext4_get_blocks()
To catch filesystem bugs or corruption which could lead to the filesystem getting severly damaged, this patch adds a facility for tracking all of the filesystem metadata blocks by contiguous regions in a red-black tree. This allows quick searching of the tree to locate extents which might overlap with filesystem metadata blocks. This facility is also used by the multi-block allocator to assure that it is not allocating blocks out of the system zone, as well as by the routines used when reading indirect blocks and extents information from disk to make sure their contents are valid. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index dc34ed3d1327..600b7ad699b5 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -568,6 +568,7 @@ static void ext4_put_super(struct super_block *sb)
568 struct ext4_super_block *es = sbi->s_es; 568 struct ext4_super_block *es = sbi->s_es;
569 int i, err; 569 int i, err;
570 570
571 ext4_release_system_zone(sb);
571 ext4_mb_release(sb); 572 ext4_mb_release(sb);
572 ext4_ext_release(sb); 573 ext4_ext_release(sb);
573 ext4_xattr_put_super(sb); 574 ext4_xattr_put_super(sb);
@@ -1055,6 +1056,7 @@ enum {
1055 Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, 1056 Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize,
1056 Opt_usrquota, Opt_grpquota, Opt_i_version, 1057 Opt_usrquota, Opt_grpquota, Opt_i_version,
1057 Opt_stripe, Opt_delalloc, Opt_nodelalloc, 1058 Opt_stripe, Opt_delalloc, Opt_nodelalloc,
1059 Opt_block_validity, Opt_noblock_validity,
1058 Opt_inode_readahead_blks, Opt_journal_ioprio 1060 Opt_inode_readahead_blks, Opt_journal_ioprio
1059}; 1061};
1060 1062
@@ -1114,6 +1116,8 @@ static const match_table_t tokens = {
1114 {Opt_resize, "resize"}, 1116 {Opt_resize, "resize"},
1115 {Opt_delalloc, "delalloc"}, 1117 {Opt_delalloc, "delalloc"},
1116 {Opt_nodelalloc, "nodelalloc"}, 1118 {Opt_nodelalloc, "nodelalloc"},
1119 {Opt_block_validity, "block_validity"},
1120 {Opt_noblock_validity, "noblock_validity"},
1117 {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, 1121 {Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
1118 {Opt_journal_ioprio, "journal_ioprio=%u"}, 1122 {Opt_journal_ioprio, "journal_ioprio=%u"},
1119 {Opt_auto_da_alloc, "auto_da_alloc=%u"}, 1123 {Opt_auto_da_alloc, "auto_da_alloc=%u"},
@@ -1508,6 +1512,12 @@ set_qf_format:
1508 case Opt_delalloc: 1512 case Opt_delalloc:
1509 set_opt(sbi->s_mount_opt, DELALLOC); 1513 set_opt(sbi->s_mount_opt, DELALLOC);
1510 break; 1514 break;
1515 case Opt_block_validity:
1516 set_opt(sbi->s_mount_opt, BLOCK_VALIDITY);
1517 break;
1518 case Opt_noblock_validity:
1519 clear_opt(sbi->s_mount_opt, BLOCK_VALIDITY);
1520 break;
1511 case Opt_inode_readahead_blks: 1521 case Opt_inode_readahead_blks:
1512 if (match_int(&args[0], &option)) 1522 if (match_int(&args[0], &option))
1513 return 0; 1523 return 0;
@@ -2826,6 +2836,13 @@ no_journal:
2826 } else if (test_opt(sb, DELALLOC)) 2836 } else if (test_opt(sb, DELALLOC))
2827 printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); 2837 printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n");
2828 2838
2839 err = ext4_setup_system_zone(sb);
2840 if (err) {
2841 printk(KERN_ERR "EXT4-fs: failed to initialize system "
2842 "zone (%d)\n", err);
2843 goto failed_mount4;
2844 }
2845
2829 ext4_ext_init(sb); 2846 ext4_ext_init(sb);
2830 err = ext4_mb_init(sb, needs_recovery); 2847 err = ext4_mb_init(sb, needs_recovery);
2831 if (err) { 2848 if (err) {
@@ -2875,6 +2892,7 @@ cantfind_ext4:
2875 2892
2876failed_mount4: 2893failed_mount4:
2877 printk(KERN_ERR "EXT4-fs (device %s): mount failed\n", sb->s_id); 2894 printk(KERN_ERR "EXT4-fs (device %s): mount failed\n", sb->s_id);
2895 ext4_release_system_zone(sb);
2878 if (sbi->s_journal) { 2896 if (sbi->s_journal) {
2879 jbd2_journal_destroy(sbi->s_journal); 2897 jbd2_journal_destroy(sbi->s_journal);
2880 sbi->s_journal = NULL; 2898 sbi->s_journal = NULL;
@@ -3515,6 +3533,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
3515 sb->s_flags &= ~MS_RDONLY; 3533 sb->s_flags &= ~MS_RDONLY;
3516 } 3534 }
3517 } 3535 }
3536 ext4_setup_system_zone(sb);
3518 if (sbi->s_journal == NULL) 3537 if (sbi->s_journal == NULL)
3519 ext4_commit_super(sb, 1); 3538 ext4_commit_super(sb, 1);
3520 3539
@@ -3927,13 +3946,16 @@ static int __init init_ext4_fs(void)
3927{ 3946{
3928 int err; 3947 int err;
3929 3948
3949 err = init_ext4_system_zone();
3950 if (err)
3951 return err;
3930 ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj); 3952 ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);
3931 if (!ext4_kset) 3953 if (!ext4_kset)
3932 return -ENOMEM; 3954 goto out4;
3933 ext4_proc_root = proc_mkdir("fs/ext4", NULL); 3955 ext4_proc_root = proc_mkdir("fs/ext4", NULL);
3934 err = init_ext4_mballoc(); 3956 err = init_ext4_mballoc();
3935 if (err) 3957 if (err)
3936 return err; 3958 goto out3;
3937 3959
3938 err = init_ext4_xattr(); 3960 err = init_ext4_xattr();
3939 if (err) 3961 if (err)
@@ -3958,6 +3980,11 @@ out1:
3958 exit_ext4_xattr(); 3980 exit_ext4_xattr();
3959out2: 3981out2:
3960 exit_ext4_mballoc(); 3982 exit_ext4_mballoc();
3983out3:
3984 remove_proc_entry("fs/ext4", NULL);
3985 kset_unregister(ext4_kset);
3986out4:
3987 exit_ext4_system_zone();
3961 return err; 3988 return err;
3962} 3989}
3963 3990
@@ -3972,6 +3999,7 @@ static void __exit exit_ext4_fs(void)
3972 exit_ext4_mballoc(); 3999 exit_ext4_mballoc();
3973 remove_proc_entry("fs/ext4", NULL); 4000 remove_proc_entry("fs/ext4", NULL);
3974 kset_unregister(ext4_kset); 4001 kset_unregister(ext4_kset);
4002 exit_ext4_system_zone();
3975} 4003}
3976 4004
3977MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); 4005MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");