add patch set-ext4_dax_aops-for-dax-files
[ext4-patch-queue.git] / calculate-superblock-checksum-after-update-free-blocks-inodes
blob53d4db245d26d63b20d813f25375d72f848a22b6
1 ext4: recalucate superblock checksum after updating free blocks/inodes
3 When mounting the superblock, ext4_fill_super() calculates the free
4 blocks and free inodes and stores them in the superblock.  It's not
5 strictly necessary, since we don't use them any more, but it's nice to
6 keep them roughly aligned to reality.
8 Since it's not critical for file system correctness, the code doesn't
9 call ext4_commit_super().  The problem is that it's in
10 ext4_commit_super() that we recalculate the superblock checksum.  So
11 if we're not going to call ext4_commit_super(), we need to call
12 ext4_superblock_csum_set() to make sure the superblock checksum is
13 consistent.
15 Most of the time, this doesn't matter, since we end up calling
16 ext4_commit_super() very soon thereafter, and definitely by the time
17 the file system is unmounted.  However, it doesn't work in this
18 sequence:
20 mke2fs -Fq -t ext4 /dev/vdc 128M
21 mount /dev/vdc /vdc
22 cp xfstests/git-versions /vdc
23 godown /vdc
24 umount /vdc
25 mount /dev/vdc
26 tune2fs -l /dev/vdc
28 With this commit, the "tune2fs -l" no longer fails.
30 Reported-by: Chengguang Xu <cgxu519@gmx.com>
31 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
32 Cc: stable@vger.kernel.org
36 ---
37  fs/ext4/super.c | 2 ++
38  1 file changed, 2 insertions(+)
40 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
41 index f7750bc5b85a..e41da553b430 100644
42 --- a/fs/ext4/super.c
43 +++ b/fs/ext4/super.c
44 @@ -4378,11 +4378,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
45         block = ext4_count_free_clusters(sb);
46         ext4_free_blocks_count_set(sbi->s_es, 
47                                    EXT4_C2B(sbi, block));
48 +       ext4_superblock_csum_set(sb);
49         err = percpu_counter_init(&sbi->s_freeclusters_counter, block,
50                                   GFP_KERNEL);
51         if (!err) {
52                 unsigned long freei = ext4_count_free_inodes(sb);
53                 sbi->s_es->s_free_inodes_count = cpu_to_le32(freei);
54 +               ext4_superblock_csum_set(sb);
55                 err = percpu_counter_init(&sbi->s_freeinodes_counter, freei,
56                                           GFP_KERNEL);
57         }