From: Hongchao Zhang Date: Thu, 27 Feb 2014 14:00:11 +0000 (+0800) Subject: LU-4557 ldiskfs: init statfs variables after journal X-Git-Tag: 2.5.57~34 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=0e5a1df5ff7176e93c32d9636c42d55173cb7a92 LU-4557 ldiskfs: init statfs variables after journal in ext4_fill_super, the variables related to statfs should be initialized after journal recovery is completed. otherwise, if a large number of blocks were being allocated before the filesystem crashed, then the blocks and inode counters may become negative during use and report incorrect values to statfs call. Change-Id: Id7e3f61ce73f5499a6176c336c7931a47f6f76de Signed-off-by: Hongchao Zhang Reviewed-on: http://review.whamcloud.com/9277 Tested-by: Jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Emoly Liu --- diff --git a/ldiskfs/kernel_patches/patches/rhel6.3/ext4-init-statfs-after-journal.patch b/ldiskfs/kernel_patches/patches/rhel6.3/ext4-init-statfs-after-journal.patch new file mode 100644 index 0000000..777a225 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel6.3/ext4-init-statfs-after-journal.patch @@ -0,0 +1,52 @@ +--- linux-stage.orig/fs/ext4/super.c 2014-02-14 04:48:50.707992991 +0800 ++++ linux-stage/fs/ext4/super.c 2014-02-14 04:49:53.341999568 +0800 +@@ -3456,24 +3456,6 @@ static int ext4_fill_super(struct super_ + get_random_bytes(&sbi->s_next_generation, sizeof(u32)); + spin_lock_init(&sbi->s_next_gen_lock); + +- err = percpu_counter_init(&sbi->s_freeblocks_counter, +- ext4_count_free_blocks(sb)); +- if (!err) { +- err = percpu_counter_init(&sbi->s_freeinodes_counter, +- ext4_count_free_inodes(sb)); +- } +- if (!err) { +- err = percpu_counter_init(&sbi->s_dirs_counter, +- ext4_count_dirs(sb)); +- } +- if (!err) { +- err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); +- } +- if (err) { +- ext4_msg(sb, KERN_ERR, "insufficient memory"); +- goto failed_mount3; +- } +- + sbi->s_stripe = ext4_get_stripe_size(sbi); + sbi->s_max_writeback_mb_bump = 128; + +@@ -3555,6 +3537,24 @@ static int ext4_fill_super(struct super_ + goto no_journal; + } + ++ err = percpu_counter_init(&sbi->s_freeblocks_counter, ++ ext4_count_free_blocks(sb)); ++ if (!err) { ++ err = percpu_counter_init(&sbi->s_freeinodes_counter, ++ ext4_count_free_inodes(sb)); ++ } ++ if (!err) { ++ err = percpu_counter_init(&sbi->s_dirs_counter, ++ ext4_count_dirs(sb)); ++ } ++ if (!err) { ++ err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); ++ } ++ if (err) { ++ ext4_msg(sb, KERN_ERR, "insufficient memory"); ++ goto failed_mount4; ++ } ++ + if (ext4_blocks_count(es) > 0xffffffffULL && + !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, + JBD2_FEATURE_INCOMPAT_64BIT)) { diff --git a/ldiskfs/kernel_patches/patches/sles11sp2/ext4-init-statfs-after-journal.patch b/ldiskfs/kernel_patches/patches/sles11sp2/ext4-init-statfs-after-journal.patch new file mode 100644 index 0000000..31c89d4 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/sles11sp2/ext4-init-statfs-after-journal.patch @@ -0,0 +1,52 @@ +--- linux-stage.orig/fs/ext4/super.c ++++ linux-stage/fs/ext4/super.c +@@ -3383,24 +3424,6 @@ static int ext4_fill_super(struct super_ + get_random_bytes(&sbi->s_next_generation, sizeof(u32)); + spin_lock_init(&sbi->s_next_gen_lock); + +- err = percpu_counter_init(&sbi->s_freeblocks_counter, +- ext4_count_free_blocks(sb)); +- if (!err) { +- err = percpu_counter_init(&sbi->s_freeinodes_counter, +- ext4_count_free_inodes(sb)); +- } +- if (!err) { +- err = percpu_counter_init(&sbi->s_dirs_counter, +- ext4_count_dirs(sb)); +- } +- if (!err) { +- err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); +- } +- if (err) { +- ext4_msg(sb, KERN_ERR, "insufficient memory"); +- goto failed_mount3; +- } +- + sbi->s_stripe = ext4_get_stripe_size(sbi); + sbi->s_max_writeback_mb_bump = 128; + +@@ -3482,6 +3505,24 @@ static int ext4_fill_super(struct super_ + goto no_journal; + } + ++ err = percpu_counter_init(&sbi->s_freeblocks_counter, ++ ext4_count_free_blocks(sb)); ++ if (!err) { ++ err = percpu_counter_init(&sbi->s_freeinodes_counter, ++ ext4_count_free_inodes(sb)); ++ } ++ if (!err) { ++ err = percpu_counter_init(&sbi->s_dirs_counter, ++ ext4_count_dirs(sb)); ++ } ++ if (!err) { ++ err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); ++ } ++ if (err) { ++ ext4_msg(sb, KERN_ERR, "insufficient memory"); ++ goto failed_mount3; ++ } ++ + if (ext4_blocks_count(es) > 0xffffffffULL && + !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, + JBD2_FEATURE_INCOMPAT_64BIT)) { diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.4.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.4.series index f8a63af..3d90e9c 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.4.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.4.series @@ -47,3 +47,4 @@ rhel6.3/ext4-max-dir-size.patch rhel6.4/ext4-max-dir-size-options.patch rhel6.3/ext4-not-discard-preallocation-umount.patch rhel6.3/ext4-journal-path-opt.patch +rhel6.3/ext4-init-statfs-after-journal.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.5.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.5.series index fbbac67..b2e9827 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.5.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.5.series @@ -48,3 +48,4 @@ rhel6.3/ext4-max-dir-size.patch rhel6.4/ext4-max-dir-size-options.patch rhel6.3/ext4-not-discard-preallocation-umount.patch rhel6.3/ext4-journal-path-opt.patch +rhel6.3/ext4-init-statfs-after-journal.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.series index 4f85148..a231a6f 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.series @@ -46,3 +46,4 @@ rhel6.3/ext4-max-dir-size.patch rhel6.3/ext4-max-dir-size-options.patch rhel6.3/ext4-not-discard-preallocation-umount.patch rhel6.3/ext4-journal-path-opt.patch +rhel6.3/ext4-init-statfs-after-journal.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series index f75456b..81f6a0e 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles11.series @@ -46,3 +46,4 @@ rhel6.3/ext4-max-dir-size.patch sles11sp1/ext4-max-dir-size-options.patch rhel6.3/ext4-not-discard-preallocation-umount.patch rhel6.3/ext4-journal-path-opt.patch +rhel6.3/ext4-init-statfs-after-journal.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11sp3.series b/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11sp3.series index e69fa59..99bb623 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11sp3.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.0-sles11sp3.series @@ -43,3 +43,4 @@ rhel6.3/ext4-max-dir-size.patch sles11sp2/ext4-max-dir-size-options.patch rhel6.3/ext4-not-discard-preallocation-umount.patch rhel6.3/ext4-journal-path-opt.patch +sles11sp2/ext4-init-statfs-after-journal.patch