diff options
author | Darrick J. Wong <djwong@us.ibm.com> | 2012-04-29 18:33:10 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-04-29 18:33:10 -0400 |
commit | 41a246d1ff75a95d2be3191ca6e6db139dc0f430 (patch) | |
tree | 0b5150f476dd69726ffe7ea1ba83832c42b441be /fs/ext4/ialloc.c | |
parent | 814525f4df50a196464ce2c7abe91f693203060f (diff) |
ext4: calculate and verify checksums for inode bitmaps
Compute and verify the checksum of the inode bitmap; the checkum is
stored in the block group descriptor.
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/ialloc.c')
-rw-r--r-- | fs/ext4/ialloc.c | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 8207dfab2682..fb897ec183c8 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -82,12 +82,17 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb, | |||
82 | ext4_free_inodes_set(sb, gdp, 0); | 82 | ext4_free_inodes_set(sb, gdp, 0); |
83 | ext4_itable_unused_set(sb, gdp, 0); | 83 | ext4_itable_unused_set(sb, gdp, 0); |
84 | memset(bh->b_data, 0xff, sb->s_blocksize); | 84 | memset(bh->b_data, 0xff, sb->s_blocksize); |
85 | ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh, | ||
86 | EXT4_INODES_PER_GROUP(sb) / 8); | ||
85 | return 0; | 87 | return 0; |
86 | } | 88 | } |
87 | 89 | ||
88 | memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); | 90 | memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); |
89 | ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8, | 91 | ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8, |
90 | bh->b_data); | 92 | bh->b_data); |
93 | ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh, | ||
94 | EXT4_INODES_PER_GROUP(sb) / 8); | ||
95 | gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); | ||
91 | 96 | ||
92 | return EXT4_INODES_PER_GROUP(sb); | 97 | return EXT4_INODES_PER_GROUP(sb); |
93 | } | 98 | } |
@@ -128,12 +133,12 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
128 | return NULL; | 133 | return NULL; |
129 | } | 134 | } |
130 | if (bitmap_uptodate(bh)) | 135 | if (bitmap_uptodate(bh)) |
131 | return bh; | 136 | goto verify; |
132 | 137 | ||
133 | lock_buffer(bh); | 138 | lock_buffer(bh); |
134 | if (bitmap_uptodate(bh)) { | 139 | if (bitmap_uptodate(bh)) { |
135 | unlock_buffer(bh); | 140 | unlock_buffer(bh); |
136 | return bh; | 141 | goto verify; |
137 | } | 142 | } |
138 | 143 | ||
139 | ext4_lock_group(sb, block_group); | 144 | ext4_lock_group(sb, block_group); |
@@ -141,6 +146,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
141 | ext4_init_inode_bitmap(sb, bh, block_group, desc); | 146 | ext4_init_inode_bitmap(sb, bh, block_group, desc); |
142 | set_bitmap_uptodate(bh); | 147 | set_bitmap_uptodate(bh); |
143 | set_buffer_uptodate(bh); | 148 | set_buffer_uptodate(bh); |
149 | set_buffer_verified(bh); | ||
144 | ext4_unlock_group(sb, block_group); | 150 | ext4_unlock_group(sb, block_group); |
145 | unlock_buffer(bh); | 151 | unlock_buffer(bh); |
146 | return bh; | 152 | return bh; |
@@ -154,7 +160,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
154 | */ | 160 | */ |
155 | set_bitmap_uptodate(bh); | 161 | set_bitmap_uptodate(bh); |
156 | unlock_buffer(bh); | 162 | unlock_buffer(bh); |
157 | return bh; | 163 | goto verify; |
158 | } | 164 | } |
159 | /* | 165 | /* |
160 | * submit the buffer_head for reading | 166 | * submit the buffer_head for reading |
@@ -171,6 +177,20 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
171 | block_group, bitmap_blk); | 177 | block_group, bitmap_blk); |
172 | return NULL; | 178 | return NULL; |
173 | } | 179 | } |
180 | |||
181 | verify: | ||
182 | ext4_lock_group(sb, block_group); | ||
183 | if (!buffer_verified(bh) && | ||
184 | !ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh, | ||
185 | EXT4_INODES_PER_GROUP(sb) / 8)) { | ||
186 | ext4_unlock_group(sb, block_group); | ||
187 | put_bh(bh); | ||
188 | ext4_error(sb, "Corrupt inode bitmap - block_group = %u, " | ||
189 | "inode_bitmap = %llu", block_group, bitmap_blk); | ||
190 | return NULL; | ||
191 | } | ||
192 | ext4_unlock_group(sb, block_group); | ||
193 | set_buffer_verified(bh); | ||
174 | return bh; | 194 | return bh; |
175 | } | 195 | } |
176 | 196 | ||
@@ -276,6 +296,8 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
276 | ext4_used_dirs_set(sb, gdp, count); | 296 | ext4_used_dirs_set(sb, gdp, count); |
277 | percpu_counter_dec(&sbi->s_dirs_counter); | 297 | percpu_counter_dec(&sbi->s_dirs_counter); |
278 | } | 298 | } |
299 | ext4_inode_bitmap_csum_set(sb, block_group, gdp, bitmap_bh, | ||
300 | EXT4_INODES_PER_GROUP(sb) / 8); | ||
279 | gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); | 301 | gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); |
280 | ext4_unlock_group(sb, block_group); | 302 | ext4_unlock_group(sb, block_group); |
281 | 303 | ||
@@ -751,7 +773,7 @@ got: | |||
751 | goto fail; | 773 | goto fail; |
752 | 774 | ||
753 | /* Update the relevant bg descriptor fields */ | 775 | /* Update the relevant bg descriptor fields */ |
754 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { | 776 | if (ext4_has_group_desc_csum(sb)) { |
755 | int free; | 777 | int free; |
756 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); | 778 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); |
757 | 779 | ||
@@ -782,7 +804,9 @@ got: | |||
782 | atomic_inc(&sbi->s_flex_groups[f].used_dirs); | 804 | atomic_inc(&sbi->s_flex_groups[f].used_dirs); |
783 | } | 805 | } |
784 | } | 806 | } |
785 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { | 807 | if (ext4_has_group_desc_csum(sb)) { |
808 | ext4_inode_bitmap_csum_set(sb, group, gdp, inode_bitmap_bh, | ||
809 | EXT4_INODES_PER_GROUP(sb) / 8); | ||
786 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); | 810 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); |
787 | ext4_unlock_group(sb, group); | 811 | ext4_unlock_group(sb, group); |
788 | } | 812 | } |