diff options
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r-- | fs/ocfs2/suballoc.c | 363 |
1 files changed, 226 insertions, 137 deletions
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index c5ff18b46b57..a69628603e18 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "ocfs2.h" | 35 | #include "ocfs2.h" |
36 | 36 | ||
37 | #include "alloc.h" | 37 | #include "alloc.h" |
38 | #include "blockcheck.h" | ||
38 | #include "dlmglue.h" | 39 | #include "dlmglue.h" |
39 | #include "inode.h" | 40 | #include "inode.h" |
40 | #include "journal.h" | 41 | #include "journal.h" |
@@ -145,62 +146,183 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl) | |||
145 | return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); | 146 | return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); |
146 | } | 147 | } |
147 | 148 | ||
148 | /* somewhat more expensive than our other checks, so use sparingly. */ | 149 | #define do_error(fmt, ...) \ |
149 | int ocfs2_check_group_descriptor(struct super_block *sb, | 150 | do{ \ |
150 | struct ocfs2_dinode *di, | 151 | if (clean_error) \ |
151 | struct ocfs2_group_desc *gd) | 152 | mlog(ML_ERROR, fmt "\n", ##__VA_ARGS__); \ |
153 | else \ | ||
154 | ocfs2_error(sb, fmt, ##__VA_ARGS__); \ | ||
155 | } while (0) | ||
156 | |||
157 | static int ocfs2_validate_gd_self(struct super_block *sb, | ||
158 | struct buffer_head *bh, | ||
159 | int clean_error) | ||
152 | { | 160 | { |
153 | unsigned int max_bits; | 161 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; |
154 | 162 | ||
155 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { | 163 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { |
156 | OCFS2_RO_ON_INVALID_GROUP_DESC(sb, gd); | 164 | do_error("Group descriptor #%llu has bad signature %.*s", |
157 | return -EIO; | 165 | (unsigned long long)bh->b_blocknr, 7, |
166 | gd->bg_signature); | ||
167 | return -EINVAL; | ||
158 | } | 168 | } |
159 | 169 | ||
170 | if (le64_to_cpu(gd->bg_blkno) != bh->b_blocknr) { | ||
171 | do_error("Group descriptor #%llu has an invalid bg_blkno " | ||
172 | "of %llu", | ||
173 | (unsigned long long)bh->b_blocknr, | ||
174 | (unsigned long long)le64_to_cpu(gd->bg_blkno)); | ||
175 | return -EINVAL; | ||
176 | } | ||
177 | |||
178 | if (le32_to_cpu(gd->bg_generation) != OCFS2_SB(sb)->fs_generation) { | ||
179 | do_error("Group descriptor #%llu has an invalid " | ||
180 | "fs_generation of #%u", | ||
181 | (unsigned long long)bh->b_blocknr, | ||
182 | le32_to_cpu(gd->bg_generation)); | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { | ||
187 | do_error("Group descriptor #%llu has bit count %u but " | ||
188 | "claims that %u are free", | ||
189 | (unsigned long long)bh->b_blocknr, | ||
190 | le16_to_cpu(gd->bg_bits), | ||
191 | le16_to_cpu(gd->bg_free_bits_count)); | ||
192 | return -EINVAL; | ||
193 | } | ||
194 | |||
195 | if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) { | ||
196 | do_error("Group descriptor #%llu has bit count %u but " | ||
197 | "max bitmap bits of %u", | ||
198 | (unsigned long long)bh->b_blocknr, | ||
199 | le16_to_cpu(gd->bg_bits), | ||
200 | 8 * le16_to_cpu(gd->bg_size)); | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int ocfs2_validate_gd_parent(struct super_block *sb, | ||
208 | struct ocfs2_dinode *di, | ||
209 | struct buffer_head *bh, | ||
210 | int clean_error) | ||
211 | { | ||
212 | unsigned int max_bits; | ||
213 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; | ||
214 | |||
160 | if (di->i_blkno != gd->bg_parent_dinode) { | 215 | if (di->i_blkno != gd->bg_parent_dinode) { |
161 | ocfs2_error(sb, "Group descriptor # %llu has bad parent " | 216 | do_error("Group descriptor #%llu has bad parent " |
162 | "pointer (%llu, expected %llu)", | 217 | "pointer (%llu, expected %llu)", |
163 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 218 | (unsigned long long)bh->b_blocknr, |
164 | (unsigned long long)le64_to_cpu(gd->bg_parent_dinode), | 219 | (unsigned long long)le64_to_cpu(gd->bg_parent_dinode), |
165 | (unsigned long long)le64_to_cpu(di->i_blkno)); | 220 | (unsigned long long)le64_to_cpu(di->i_blkno)); |
166 | return -EIO; | 221 | return -EINVAL; |
167 | } | 222 | } |
168 | 223 | ||
169 | max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc); | 224 | max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc); |
170 | if (le16_to_cpu(gd->bg_bits) > max_bits) { | 225 | if (le16_to_cpu(gd->bg_bits) > max_bits) { |
171 | ocfs2_error(sb, "Group descriptor # %llu has bit count of %u", | 226 | do_error("Group descriptor #%llu has bit count of %u", |
172 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 227 | (unsigned long long)bh->b_blocknr, |
173 | le16_to_cpu(gd->bg_bits)); | 228 | le16_to_cpu(gd->bg_bits)); |
174 | return -EIO; | 229 | return -EINVAL; |
175 | } | 230 | } |
176 | 231 | ||
177 | if (le16_to_cpu(gd->bg_chain) >= | 232 | if (le16_to_cpu(gd->bg_chain) >= |
178 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { | 233 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { |
179 | ocfs2_error(sb, "Group descriptor # %llu has bad chain %u", | 234 | do_error("Group descriptor #%llu has bad chain %u", |
180 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 235 | (unsigned long long)bh->b_blocknr, |
181 | le16_to_cpu(gd->bg_chain)); | 236 | le16_to_cpu(gd->bg_chain)); |
182 | return -EIO; | 237 | return -EINVAL; |
183 | } | 238 | } |
184 | 239 | ||
185 | if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { | 240 | return 0; |
186 | ocfs2_error(sb, "Group descriptor # %llu has bit count %u but " | 241 | } |
187 | "claims that %u are free", | ||
188 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
189 | le16_to_cpu(gd->bg_bits), | ||
190 | le16_to_cpu(gd->bg_free_bits_count)); | ||
191 | return -EIO; | ||
192 | } | ||
193 | 242 | ||
194 | if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) { | 243 | #undef do_error |
195 | ocfs2_error(sb, "Group descriptor # %llu has bit count %u but " | 244 | |
196 | "max bitmap bits of %u", | 245 | /* |
197 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 246 | * This version only prints errors. It does not fail the filesystem, and |
198 | le16_to_cpu(gd->bg_bits), | 247 | * exists only for resize. |
199 | 8 * le16_to_cpu(gd->bg_size)); | 248 | */ |
200 | return -EIO; | 249 | int ocfs2_check_group_descriptor(struct super_block *sb, |
250 | struct ocfs2_dinode *di, | ||
251 | struct buffer_head *bh) | ||
252 | { | ||
253 | int rc; | ||
254 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; | ||
255 | |||
256 | BUG_ON(!buffer_uptodate(bh)); | ||
257 | |||
258 | /* | ||
259 | * If the ecc fails, we return the error but otherwise | ||
260 | * leave the filesystem running. We know any error is | ||
261 | * local to this block. | ||
262 | */ | ||
263 | rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &gd->bg_check); | ||
264 | if (rc) { | ||
265 | mlog(ML_ERROR, | ||
266 | "Checksum failed for group descriptor %llu\n", | ||
267 | (unsigned long long)bh->b_blocknr); | ||
268 | } else | ||
269 | rc = ocfs2_validate_gd_self(sb, bh, 1); | ||
270 | if (!rc) | ||
271 | rc = ocfs2_validate_gd_parent(sb, di, bh, 1); | ||
272 | |||
273 | return rc; | ||
274 | } | ||
275 | |||
276 | static int ocfs2_validate_group_descriptor(struct super_block *sb, | ||
277 | struct buffer_head *bh) | ||
278 | { | ||
279 | int rc; | ||
280 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; | ||
281 | |||
282 | mlog(0, "Validating group descriptor %llu\n", | ||
283 | (unsigned long long)bh->b_blocknr); | ||
284 | |||
285 | BUG_ON(!buffer_uptodate(bh)); | ||
286 | |||
287 | /* | ||
288 | * If the ecc fails, we return the error but otherwise | ||
289 | * leave the filesystem running. We know any error is | ||
290 | * local to this block. | ||
291 | */ | ||
292 | rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &gd->bg_check); | ||
293 | if (rc) | ||
294 | return rc; | ||
295 | |||
296 | /* | ||
297 | * Errors after here are fatal. | ||
298 | */ | ||
299 | |||
300 | return ocfs2_validate_gd_self(sb, bh, 0); | ||
301 | } | ||
302 | |||
303 | int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di, | ||
304 | u64 gd_blkno, struct buffer_head **bh) | ||
305 | { | ||
306 | int rc; | ||
307 | struct buffer_head *tmp = *bh; | ||
308 | |||
309 | rc = ocfs2_read_block(inode, gd_blkno, &tmp, | ||
310 | ocfs2_validate_group_descriptor); | ||
311 | if (rc) | ||
312 | goto out; | ||
313 | |||
314 | rc = ocfs2_validate_gd_parent(inode->i_sb, di, tmp, 0); | ||
315 | if (rc) { | ||
316 | brelse(tmp); | ||
317 | goto out; | ||
201 | } | 318 | } |
202 | 319 | ||
203 | return 0; | 320 | /* If ocfs2_read_block() got us a new bh, pass it up. */ |
321 | if (!*bh) | ||
322 | *bh = tmp; | ||
323 | |||
324 | out: | ||
325 | return rc; | ||
204 | } | 326 | } |
205 | 327 | ||
206 | static int ocfs2_block_group_fill(handle_t *handle, | 328 | static int ocfs2_block_group_fill(handle_t *handle, |
@@ -225,10 +347,10 @@ static int ocfs2_block_group_fill(handle_t *handle, | |||
225 | goto bail; | 347 | goto bail; |
226 | } | 348 | } |
227 | 349 | ||
228 | status = ocfs2_journal_access(handle, | 350 | status = ocfs2_journal_access_gd(handle, |
229 | alloc_inode, | 351 | alloc_inode, |
230 | bg_bh, | 352 | bg_bh, |
231 | OCFS2_JOURNAL_ACCESS_CREATE); | 353 | OCFS2_JOURNAL_ACCESS_CREATE); |
232 | if (status < 0) { | 354 | if (status < 0) { |
233 | mlog_errno(status); | 355 | mlog_errno(status); |
234 | goto bail; | 356 | goto bail; |
@@ -358,8 +480,8 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
358 | 480 | ||
359 | bg = (struct ocfs2_group_desc *) bg_bh->b_data; | 481 | bg = (struct ocfs2_group_desc *) bg_bh->b_data; |
360 | 482 | ||
361 | status = ocfs2_journal_access(handle, alloc_inode, | 483 | status = ocfs2_journal_access_di(handle, alloc_inode, |
362 | bh, OCFS2_JOURNAL_ACCESS_WRITE); | 484 | bh, OCFS2_JOURNAL_ACCESS_WRITE); |
363 | if (status < 0) { | 485 | if (status < 0) { |
364 | mlog_errno(status); | 486 | mlog_errno(status); |
365 | goto bail; | 487 | goto bail; |
@@ -441,11 +563,11 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, | |||
441 | ac->ac_alloc_slot = slot; | 563 | ac->ac_alloc_slot = slot; |
442 | 564 | ||
443 | fe = (struct ocfs2_dinode *) bh->b_data; | 565 | fe = (struct ocfs2_dinode *) bh->b_data; |
444 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 566 | |
445 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); | 567 | /* The bh was validated by the inode read inside |
446 | status = -EIO; | 568 | * ocfs2_inode_lock(). Any corruption is a code bug. */ |
447 | goto bail; | 569 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); |
448 | } | 570 | |
449 | if (!(fe->i_flags & cpu_to_le32(OCFS2_CHAIN_FL))) { | 571 | if (!(fe->i_flags & cpu_to_le32(OCFS2_CHAIN_FL))) { |
450 | ocfs2_error(alloc_inode->i_sb, "Invalid chain allocator %llu", | 572 | ocfs2_error(alloc_inode->i_sb, "Invalid chain allocator %llu", |
451 | (unsigned long long)le64_to_cpu(fe->i_blkno)); | 573 | (unsigned long long)le64_to_cpu(fe->i_blkno)); |
@@ -790,10 +912,9 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, | |||
790 | int offset, start, found, status = 0; | 912 | int offset, start, found, status = 0; |
791 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; | 913 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; |
792 | 914 | ||
793 | if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { | 915 | /* Callers got this descriptor from |
794 | OCFS2_RO_ON_INVALID_GROUP_DESC(osb->sb, bg); | 916 | * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ |
795 | return -EIO; | 917 | BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg)); |
796 | } | ||
797 | 918 | ||
798 | found = start = best_offset = best_size = 0; | 919 | found = start = best_offset = best_size = 0; |
799 | bitmap = bg->bg_bitmap; | 920 | bitmap = bg->bg_bitmap; |
@@ -858,11 +979,9 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle, | |||
858 | 979 | ||
859 | mlog_entry_void(); | 980 | mlog_entry_void(); |
860 | 981 | ||
861 | if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { | 982 | /* All callers get the descriptor via |
862 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); | 983 | * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ |
863 | status = -EIO; | 984 | BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg)); |
864 | goto bail; | ||
865 | } | ||
866 | BUG_ON(le16_to_cpu(bg->bg_free_bits_count) < num_bits); | 985 | BUG_ON(le16_to_cpu(bg->bg_free_bits_count) < num_bits); |
867 | 986 | ||
868 | mlog(0, "block_group_set_bits: off = %u, num = %u\n", bit_off, | 987 | mlog(0, "block_group_set_bits: off = %u, num = %u\n", bit_off, |
@@ -871,10 +990,10 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle, | |||
871 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | 990 | if (ocfs2_is_cluster_bitmap(alloc_inode)) |
872 | journal_type = OCFS2_JOURNAL_ACCESS_UNDO; | 991 | journal_type = OCFS2_JOURNAL_ACCESS_UNDO; |
873 | 992 | ||
874 | status = ocfs2_journal_access(handle, | 993 | status = ocfs2_journal_access_gd(handle, |
875 | alloc_inode, | 994 | alloc_inode, |
876 | group_bh, | 995 | group_bh, |
877 | journal_type); | 996 | journal_type); |
878 | if (status < 0) { | 997 | if (status < 0) { |
879 | mlog_errno(status); | 998 | mlog_errno(status); |
880 | goto bail; | 999 | goto bail; |
@@ -931,21 +1050,10 @@ static int ocfs2_relink_block_group(handle_t *handle, | |||
931 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; | 1050 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; |
932 | struct ocfs2_group_desc *prev_bg = (struct ocfs2_group_desc *) prev_bg_bh->b_data; | 1051 | struct ocfs2_group_desc *prev_bg = (struct ocfs2_group_desc *) prev_bg_bh->b_data; |
933 | 1052 | ||
934 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 1053 | /* The caller got these descriptors from |
935 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); | 1054 | * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ |
936 | status = -EIO; | 1055 | BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg)); |
937 | goto out; | 1056 | BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(prev_bg)); |
938 | } | ||
939 | if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { | ||
940 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); | ||
941 | status = -EIO; | ||
942 | goto out; | ||
943 | } | ||
944 | if (!OCFS2_IS_VALID_GROUP_DESC(prev_bg)) { | ||
945 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, prev_bg); | ||
946 | status = -EIO; | ||
947 | goto out; | ||
948 | } | ||
949 | 1057 | ||
950 | mlog(0, "Suballoc %llu, chain %u, move group %llu to top, prev = %llu\n", | 1058 | mlog(0, "Suballoc %llu, chain %u, move group %llu to top, prev = %llu\n", |
951 | (unsigned long long)le64_to_cpu(fe->i_blkno), chain, | 1059 | (unsigned long long)le64_to_cpu(fe->i_blkno), chain, |
@@ -956,8 +1064,8 @@ static int ocfs2_relink_block_group(handle_t *handle, | |||
956 | bg_ptr = le64_to_cpu(bg->bg_next_group); | 1064 | bg_ptr = le64_to_cpu(bg->bg_next_group); |
957 | prev_bg_ptr = le64_to_cpu(prev_bg->bg_next_group); | 1065 | prev_bg_ptr = le64_to_cpu(prev_bg->bg_next_group); |
958 | 1066 | ||
959 | status = ocfs2_journal_access(handle, alloc_inode, prev_bg_bh, | 1067 | status = ocfs2_journal_access_gd(handle, alloc_inode, prev_bg_bh, |
960 | OCFS2_JOURNAL_ACCESS_WRITE); | 1068 | OCFS2_JOURNAL_ACCESS_WRITE); |
961 | if (status < 0) { | 1069 | if (status < 0) { |
962 | mlog_errno(status); | 1070 | mlog_errno(status); |
963 | goto out_rollback; | 1071 | goto out_rollback; |
@@ -971,8 +1079,8 @@ static int ocfs2_relink_block_group(handle_t *handle, | |||
971 | goto out_rollback; | 1079 | goto out_rollback; |
972 | } | 1080 | } |
973 | 1081 | ||
974 | status = ocfs2_journal_access(handle, alloc_inode, bg_bh, | 1082 | status = ocfs2_journal_access_gd(handle, alloc_inode, bg_bh, |
975 | OCFS2_JOURNAL_ACCESS_WRITE); | 1083 | OCFS2_JOURNAL_ACCESS_WRITE); |
976 | if (status < 0) { | 1084 | if (status < 0) { |
977 | mlog_errno(status); | 1085 | mlog_errno(status); |
978 | goto out_rollback; | 1086 | goto out_rollback; |
@@ -986,8 +1094,8 @@ static int ocfs2_relink_block_group(handle_t *handle, | |||
986 | goto out_rollback; | 1094 | goto out_rollback; |
987 | } | 1095 | } |
988 | 1096 | ||
989 | status = ocfs2_journal_access(handle, alloc_inode, fe_bh, | 1097 | status = ocfs2_journal_access_di(handle, alloc_inode, fe_bh, |
990 | OCFS2_JOURNAL_ACCESS_WRITE); | 1098 | OCFS2_JOURNAL_ACCESS_WRITE); |
991 | if (status < 0) { | 1099 | if (status < 0) { |
992 | mlog_errno(status); | 1100 | mlog_errno(status); |
993 | goto out_rollback; | 1101 | goto out_rollback; |
@@ -1008,7 +1116,7 @@ out_rollback: | |||
1008 | bg->bg_next_group = cpu_to_le64(bg_ptr); | 1116 | bg->bg_next_group = cpu_to_le64(bg_ptr); |
1009 | prev_bg->bg_next_group = cpu_to_le64(prev_bg_ptr); | 1117 | prev_bg->bg_next_group = cpu_to_le64(prev_bg_ptr); |
1010 | } | 1118 | } |
1011 | out: | 1119 | |
1012 | mlog_exit(status); | 1120 | mlog_exit(status); |
1013 | return status; | 1121 | return status; |
1014 | } | 1122 | } |
@@ -1138,8 +1246,8 @@ static int ocfs2_alloc_dinode_update_counts(struct inode *inode, | |||
1138 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; | 1246 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; |
1139 | struct ocfs2_chain_list *cl = (struct ocfs2_chain_list *) &di->id2.i_chain; | 1247 | struct ocfs2_chain_list *cl = (struct ocfs2_chain_list *) &di->id2.i_chain; |
1140 | 1248 | ||
1141 | ret = ocfs2_journal_access(handle, inode, di_bh, | 1249 | ret = ocfs2_journal_access_di(handle, inode, di_bh, |
1142 | OCFS2_JOURNAL_ACCESS_WRITE); | 1250 | OCFS2_JOURNAL_ACCESS_WRITE); |
1143 | if (ret < 0) { | 1251 | if (ret < 0) { |
1144 | mlog_errno(ret); | 1252 | mlog_errno(ret); |
1145 | goto out; | 1253 | goto out; |
@@ -1170,21 +1278,17 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | |||
1170 | u16 found; | 1278 | u16 found; |
1171 | struct buffer_head *group_bh = NULL; | 1279 | struct buffer_head *group_bh = NULL; |
1172 | struct ocfs2_group_desc *gd; | 1280 | struct ocfs2_group_desc *gd; |
1281 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)ac->ac_bh->b_data; | ||
1173 | struct inode *alloc_inode = ac->ac_inode; | 1282 | struct inode *alloc_inode = ac->ac_inode; |
1174 | 1283 | ||
1175 | ret = ocfs2_read_block(alloc_inode, gd_blkno, &group_bh); | 1284 | ret = ocfs2_read_group_descriptor(alloc_inode, di, gd_blkno, |
1285 | &group_bh); | ||
1176 | if (ret < 0) { | 1286 | if (ret < 0) { |
1177 | mlog_errno(ret); | 1287 | mlog_errno(ret); |
1178 | return ret; | 1288 | return ret; |
1179 | } | 1289 | } |
1180 | 1290 | ||
1181 | gd = (struct ocfs2_group_desc *) group_bh->b_data; | 1291 | gd = (struct ocfs2_group_desc *) group_bh->b_data; |
1182 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { | ||
1183 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, gd); | ||
1184 | ret = -EIO; | ||
1185 | goto out; | ||
1186 | } | ||
1187 | |||
1188 | ret = ac->ac_group_search(alloc_inode, group_bh, bits_wanted, min_bits, | 1292 | ret = ac->ac_group_search(alloc_inode, group_bh, bits_wanted, min_bits, |
1189 | ac->ac_max_block, bit_off, &found); | 1293 | ac->ac_max_block, bit_off, &found); |
1190 | if (ret < 0) { | 1294 | if (ret < 0) { |
@@ -1241,19 +1345,14 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1241 | bits_wanted, chain, | 1345 | bits_wanted, chain, |
1242 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno); | 1346 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno); |
1243 | 1347 | ||
1244 | status = ocfs2_read_block(alloc_inode, | 1348 | status = ocfs2_read_group_descriptor(alloc_inode, fe, |
1245 | le64_to_cpu(cl->cl_recs[chain].c_blkno), | 1349 | le64_to_cpu(cl->cl_recs[chain].c_blkno), |
1246 | &group_bh); | 1350 | &group_bh); |
1247 | if (status < 0) { | 1351 | if (status < 0) { |
1248 | mlog_errno(status); | 1352 | mlog_errno(status); |
1249 | goto bail; | 1353 | goto bail; |
1250 | } | 1354 | } |
1251 | bg = (struct ocfs2_group_desc *) group_bh->b_data; | 1355 | bg = (struct ocfs2_group_desc *) group_bh->b_data; |
1252 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); | ||
1253 | if (status) { | ||
1254 | mlog_errno(status); | ||
1255 | goto bail; | ||
1256 | } | ||
1257 | 1356 | ||
1258 | status = -ENOSPC; | 1357 | status = -ENOSPC; |
1259 | /* for now, the chain search is a bit simplistic. We just use | 1358 | /* for now, the chain search is a bit simplistic. We just use |
@@ -1271,18 +1370,13 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1271 | next_group = le64_to_cpu(bg->bg_next_group); | 1370 | next_group = le64_to_cpu(bg->bg_next_group); |
1272 | prev_group_bh = group_bh; | 1371 | prev_group_bh = group_bh; |
1273 | group_bh = NULL; | 1372 | group_bh = NULL; |
1274 | status = ocfs2_read_block(alloc_inode, | 1373 | status = ocfs2_read_group_descriptor(alloc_inode, fe, |
1275 | next_group, &group_bh); | 1374 | next_group, &group_bh); |
1276 | if (status < 0) { | 1375 | if (status < 0) { |
1277 | mlog_errno(status); | 1376 | mlog_errno(status); |
1278 | goto bail; | 1377 | goto bail; |
1279 | } | 1378 | } |
1280 | bg = (struct ocfs2_group_desc *) group_bh->b_data; | 1379 | bg = (struct ocfs2_group_desc *) group_bh->b_data; |
1281 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); | ||
1282 | if (status) { | ||
1283 | mlog_errno(status); | ||
1284 | goto bail; | ||
1285 | } | ||
1286 | } | 1380 | } |
1287 | if (status < 0) { | 1381 | if (status < 0) { |
1288 | if (status != -ENOSPC) | 1382 | if (status != -ENOSPC) |
@@ -1324,10 +1418,10 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1324 | 1418 | ||
1325 | /* Ok, claim our bits now: set the info on dinode, chainlist | 1419 | /* Ok, claim our bits now: set the info on dinode, chainlist |
1326 | * and then the group */ | 1420 | * and then the group */ |
1327 | status = ocfs2_journal_access(handle, | 1421 | status = ocfs2_journal_access_di(handle, |
1328 | alloc_inode, | 1422 | alloc_inode, |
1329 | ac->ac_bh, | 1423 | ac->ac_bh, |
1330 | OCFS2_JOURNAL_ACCESS_WRITE); | 1424 | OCFS2_JOURNAL_ACCESS_WRITE); |
1331 | if (status < 0) { | 1425 | if (status < 0) { |
1332 | mlog_errno(status); | 1426 | mlog_errno(status); |
1333 | goto bail; | 1427 | goto bail; |
@@ -1392,11 +1486,11 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
1392 | BUG_ON(!ac->ac_bh); | 1486 | BUG_ON(!ac->ac_bh); |
1393 | 1487 | ||
1394 | fe = (struct ocfs2_dinode *) ac->ac_bh->b_data; | 1488 | fe = (struct ocfs2_dinode *) ac->ac_bh->b_data; |
1395 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 1489 | |
1396 | OCFS2_RO_ON_INVALID_DINODE(osb->sb, fe); | 1490 | /* The bh was validated by the inode read during |
1397 | status = -EIO; | 1491 | * ocfs2_reserve_suballoc_bits(). Any corruption is a code bug. */ |
1398 | goto bail; | 1492 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); |
1399 | } | 1493 | |
1400 | if (le32_to_cpu(fe->id1.bitmap1.i_used) >= | 1494 | if (le32_to_cpu(fe->id1.bitmap1.i_used) >= |
1401 | le32_to_cpu(fe->id1.bitmap1.i_total)) { | 1495 | le32_to_cpu(fe->id1.bitmap1.i_total)) { |
1402 | ocfs2_error(osb->sb, "Chain allocator dinode %llu has %u used " | 1496 | ocfs2_error(osb->sb, "Chain allocator dinode %llu has %u used " |
@@ -1725,19 +1819,17 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, | |||
1725 | 1819 | ||
1726 | mlog_entry_void(); | 1820 | mlog_entry_void(); |
1727 | 1821 | ||
1728 | if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { | 1822 | /* The caller got this descriptor from |
1729 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); | 1823 | * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ |
1730 | status = -EIO; | 1824 | BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg)); |
1731 | goto bail; | ||
1732 | } | ||
1733 | 1825 | ||
1734 | mlog(0, "off = %u, num = %u\n", bit_off, num_bits); | 1826 | mlog(0, "off = %u, num = %u\n", bit_off, num_bits); |
1735 | 1827 | ||
1736 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | 1828 | if (ocfs2_is_cluster_bitmap(alloc_inode)) |
1737 | journal_type = OCFS2_JOURNAL_ACCESS_UNDO; | 1829 | journal_type = OCFS2_JOURNAL_ACCESS_UNDO; |
1738 | 1830 | ||
1739 | status = ocfs2_journal_access(handle, alloc_inode, group_bh, | 1831 | status = ocfs2_journal_access_gd(handle, alloc_inode, group_bh, |
1740 | journal_type); | 1832 | journal_type); |
1741 | if (status < 0) { | 1833 | if (status < 0) { |
1742 | mlog_errno(status); | 1834 | mlog_errno(status); |
1743 | goto bail; | 1835 | goto bail; |
@@ -1782,29 +1874,26 @@ int ocfs2_free_suballoc_bits(handle_t *handle, | |||
1782 | 1874 | ||
1783 | mlog_entry_void(); | 1875 | mlog_entry_void(); |
1784 | 1876 | ||
1785 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 1877 | /* The alloc_bh comes from ocfs2_free_dinode() or |
1786 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); | 1878 | * ocfs2_free_clusters(). The callers have all locked the |
1787 | status = -EIO; | 1879 | * allocator and gotten alloc_bh from the lock call. This |
1788 | goto bail; | 1880 | * validates the dinode buffer. Any corruption that has happended |
1789 | } | 1881 | * is a code bug. */ |
1882 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); | ||
1790 | BUG_ON((count + start_bit) > ocfs2_bits_per_group(cl)); | 1883 | BUG_ON((count + start_bit) > ocfs2_bits_per_group(cl)); |
1791 | 1884 | ||
1792 | mlog(0, "%llu: freeing %u bits from group %llu, starting at %u\n", | 1885 | mlog(0, "%llu: freeing %u bits from group %llu, starting at %u\n", |
1793 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, count, | 1886 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, count, |
1794 | (unsigned long long)bg_blkno, start_bit); | 1887 | (unsigned long long)bg_blkno, start_bit); |
1795 | 1888 | ||
1796 | status = ocfs2_read_block(alloc_inode, bg_blkno, &group_bh); | 1889 | status = ocfs2_read_group_descriptor(alloc_inode, fe, bg_blkno, |
1890 | &group_bh); | ||
1797 | if (status < 0) { | 1891 | if (status < 0) { |
1798 | mlog_errno(status); | 1892 | mlog_errno(status); |
1799 | goto bail; | 1893 | goto bail; |
1800 | } | 1894 | } |
1801 | |||
1802 | group = (struct ocfs2_group_desc *) group_bh->b_data; | 1895 | group = (struct ocfs2_group_desc *) group_bh->b_data; |
1803 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, group); | 1896 | |
1804 | if (status) { | ||
1805 | mlog_errno(status); | ||
1806 | goto bail; | ||
1807 | } | ||
1808 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); | 1897 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); |
1809 | 1898 | ||
1810 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, | 1899 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, |
@@ -1815,8 +1904,8 @@ int ocfs2_free_suballoc_bits(handle_t *handle, | |||
1815 | goto bail; | 1904 | goto bail; |
1816 | } | 1905 | } |
1817 | 1906 | ||
1818 | status = ocfs2_journal_access(handle, alloc_inode, alloc_bh, | 1907 | status = ocfs2_journal_access_di(handle, alloc_inode, alloc_bh, |
1819 | OCFS2_JOURNAL_ACCESS_WRITE); | 1908 | OCFS2_JOURNAL_ACCESS_WRITE); |
1820 | if (status < 0) { | 1909 | if (status < 0) { |
1821 | mlog_errno(status); | 1910 | mlog_errno(status); |
1822 | goto bail; | 1911 | goto bail; |