summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2018-02-19 14:16:47 -0500
committerTheodore Ts'o <tytso@mit.edu>2018-02-19 14:16:47 -0500
commit044e6e3d74a3d7103a0c8a9305dfd94d64000660 (patch)
tree0979b1eb9ecf8bacd28b0eced5cf53463eb1856c
parent85e0c4e89c1b864e763c4e3bb15d0b6d501ad5d9 (diff)
ext4: don't update checksum of new initialized bitmaps
When reading the inode or block allocation bitmap, if the bitmap needs to be initialized, do not update the checksum in the block group descriptor. That's because we're not set up to journal those changes. Instead, just set the verified bit on the bitmap block, so that it's not necessary to validate the checksum. When a block or inode allocation actually happens, at that point the checksum will be calculated, and update of the bg descriptor block will be properly journalled. Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@vger.kernel.org
-rw-r--r--fs/ext4/balloc.c3
-rw-r--r--fs/ext4/ialloc.c47
2 files changed, 4 insertions, 46 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index f9b3e0a83526..f82c4966f4ce 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -243,8 +243,6 @@ static int ext4_init_block_bitmap(struct super_block *sb,
243 */ 243 */
244 ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group), 244 ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group),
245 sb->s_blocksize * 8, bh->b_data); 245 sb->s_blocksize * 8, bh->b_data);
246 ext4_block_bitmap_csum_set(sb, block_group, gdp, bh);
247 ext4_group_desc_csum_set(sb, block_group, gdp);
248 return 0; 246 return 0;
249} 247}
250 248
@@ -448,6 +446,7 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
448 err = ext4_init_block_bitmap(sb, bh, block_group, desc); 446 err = ext4_init_block_bitmap(sb, bh, block_group, desc);
449 set_bitmap_uptodate(bh); 447 set_bitmap_uptodate(bh);
450 set_buffer_uptodate(bh); 448 set_buffer_uptodate(bh);
449 set_buffer_verified(bh);
451 ext4_unlock_group(sb, block_group); 450 ext4_unlock_group(sb, block_group);
452 unlock_buffer(bh); 451 unlock_buffer(bh);
453 if (err) { 452 if (err) {
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 7830d28df331..3fa93665b4a3 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -66,44 +66,6 @@ void ext4_mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
66 memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); 66 memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
67} 67}
68 68
69/* Initializes an uninitialized inode bitmap */
70static int ext4_init_inode_bitmap(struct super_block *sb,
71 struct buffer_head *bh,
72 ext4_group_t block_group,
73 struct ext4_group_desc *gdp)
74{
75 struct ext4_group_info *grp;
76 struct ext4_sb_info *sbi = EXT4_SB(sb);
77 J_ASSERT_BH(bh, buffer_locked(bh));
78
79 /* If checksum is bad mark all blocks and inodes use to prevent
80 * allocation, essentially implementing a per-group read-only flag. */
81 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
82 grp = ext4_get_group_info(sb, block_group);
83 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
84 percpu_counter_sub(&sbi->s_freeclusters_counter,
85 grp->bb_free);
86 set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
87 if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
88 int count;
89 count = ext4_free_inodes_count(sb, gdp);
90 percpu_counter_sub(&sbi->s_freeinodes_counter,
91 count);
92 }
93 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
94 return -EFSBADCRC;
95 }
96
97 memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
98 ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8,
99 bh->b_data);
100 ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh,
101 EXT4_INODES_PER_GROUP(sb) / 8);
102 ext4_group_desc_csum_set(sb, block_group, gdp);
103
104 return 0;
105}
106
107void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate) 69void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate)
108{ 70{
109 if (uptodate) { 71 if (uptodate) {
@@ -187,17 +149,14 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
187 149
188 ext4_lock_group(sb, block_group); 150 ext4_lock_group(sb, block_group);
189 if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { 151 if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
190 err = ext4_init_inode_bitmap(sb, bh, block_group, desc); 152 memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
153 ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb),
154 sb->s_blocksize * 8, bh->b_data);
191 set_bitmap_uptodate(bh); 155 set_bitmap_uptodate(bh);
192 set_buffer_uptodate(bh); 156 set_buffer_uptodate(bh);
193 set_buffer_verified(bh); 157 set_buffer_verified(bh);
194 ext4_unlock_group(sb, block_group); 158 ext4_unlock_group(sb, block_group);
195 unlock_buffer(bh); 159 unlock_buffer(bh);
196 if (err) {
197 ext4_error(sb, "Failed to init inode bitmap for group "
198 "%u: %d", block_group, err);
199 goto out;
200 }
201 return bh; 160 return bh;
202 } 161 }
203 ext4_unlock_group(sb, block_group); 162 ext4_unlock_group(sb, block_group);