aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/ialloc.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2012-04-29 18:33:10 -0400
committerTheodore Ts'o <tytso@mit.edu>2012-04-29 18:33:10 -0400
commit41a246d1ff75a95d2be3191ca6e6db139dc0f430 (patch)
tree0b5150f476dd69726ffe7ea1ba83832c42b441be /fs/ext4/ialloc.c
parent814525f4df50a196464ce2c7abe91f693203060f (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.c34
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
181verify:
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 }