diff options
Diffstat (limited to 'fs/ocfs2/resize.c')
-rw-r--r-- | fs/ocfs2/resize.c | 76 |
1 files changed, 22 insertions, 54 deletions
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index ffd48db229a7..424adaa5f900 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c | |||
@@ -106,8 +106,8 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle, | |||
106 | mlog_entry("(new_clusters=%d, first_new_cluster = %u)\n", | 106 | mlog_entry("(new_clusters=%d, first_new_cluster = %u)\n", |
107 | new_clusters, first_new_cluster); | 107 | new_clusters, first_new_cluster); |
108 | 108 | ||
109 | ret = ocfs2_journal_access(handle, bm_inode, group_bh, | 109 | ret = ocfs2_journal_access_gd(handle, bm_inode, group_bh, |
110 | OCFS2_JOURNAL_ACCESS_WRITE); | 110 | OCFS2_JOURNAL_ACCESS_WRITE); |
111 | if (ret < 0) { | 111 | if (ret < 0) { |
112 | mlog_errno(ret); | 112 | mlog_errno(ret); |
113 | goto out; | 113 | goto out; |
@@ -141,8 +141,8 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle, | |||
141 | } | 141 | } |
142 | 142 | ||
143 | /* update the inode accordingly. */ | 143 | /* update the inode accordingly. */ |
144 | ret = ocfs2_journal_access(handle, bm_inode, bm_bh, | 144 | ret = ocfs2_journal_access_di(handle, bm_inode, bm_bh, |
145 | OCFS2_JOURNAL_ACCESS_WRITE); | 145 | OCFS2_JOURNAL_ACCESS_WRITE); |
146 | if (ret < 0) { | 146 | if (ret < 0) { |
147 | mlog_errno(ret); | 147 | mlog_errno(ret); |
148 | goto out_rollback; | 148 | goto out_rollback; |
@@ -314,6 +314,10 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) | |||
314 | 314 | ||
315 | fe = (struct ocfs2_dinode *)main_bm_bh->b_data; | 315 | fe = (struct ocfs2_dinode *)main_bm_bh->b_data; |
316 | 316 | ||
317 | /* main_bm_bh is validated by inode read inside ocfs2_inode_lock(), | ||
318 | * so any corruption is a code bug. */ | ||
319 | BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); | ||
320 | |||
317 | if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != | 321 | if (le16_to_cpu(fe->id2.i_chain.cl_cpg) != |
318 | ocfs2_group_bitmap_size(osb->sb) * 8) { | 322 | ocfs2_group_bitmap_size(osb->sb) * 8) { |
319 | mlog(ML_ERROR, "The disk is too old and small. " | 323 | mlog(ML_ERROR, "The disk is too old and small. " |
@@ -322,30 +326,18 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) | |||
322 | goto out_unlock; | 326 | goto out_unlock; |
323 | } | 327 | } |
324 | 328 | ||
325 | if (!OCFS2_IS_VALID_DINODE(fe)) { | ||
326 | OCFS2_RO_ON_INVALID_DINODE(main_bm_inode->i_sb, fe); | ||
327 | ret = -EIO; | ||
328 | goto out_unlock; | ||
329 | } | ||
330 | |||
331 | first_new_cluster = le32_to_cpu(fe->i_clusters); | 329 | first_new_cluster = le32_to_cpu(fe->i_clusters); |
332 | lgd_blkno = ocfs2_which_cluster_group(main_bm_inode, | 330 | lgd_blkno = ocfs2_which_cluster_group(main_bm_inode, |
333 | first_new_cluster - 1); | 331 | first_new_cluster - 1); |
334 | 332 | ||
335 | ret = ocfs2_read_block(main_bm_inode, lgd_blkno, &group_bh); | 333 | ret = ocfs2_read_group_descriptor(main_bm_inode, fe, lgd_blkno, |
334 | &group_bh); | ||
336 | if (ret < 0) { | 335 | if (ret < 0) { |
337 | mlog_errno(ret); | 336 | mlog_errno(ret); |
338 | goto out_unlock; | 337 | goto out_unlock; |
339 | } | 338 | } |
340 | |||
341 | group = (struct ocfs2_group_desc *)group_bh->b_data; | 339 | group = (struct ocfs2_group_desc *)group_bh->b_data; |
342 | 340 | ||
343 | ret = ocfs2_check_group_descriptor(inode->i_sb, fe, group); | ||
344 | if (ret) { | ||
345 | mlog_errno(ret); | ||
346 | goto out_unlock; | ||
347 | } | ||
348 | |||
349 | cl_bpc = le16_to_cpu(fe->id2.i_chain.cl_bpc); | 341 | cl_bpc = le16_to_cpu(fe->id2.i_chain.cl_bpc); |
350 | if (le16_to_cpu(group->bg_bits) / cl_bpc + new_clusters > | 342 | if (le16_to_cpu(group->bg_bits) / cl_bpc + new_clusters > |
351 | le16_to_cpu(fe->id2.i_chain.cl_cpg)) { | 343 | le16_to_cpu(fe->id2.i_chain.cl_cpg)) { |
@@ -398,41 +390,16 @@ static int ocfs2_check_new_group(struct inode *inode, | |||
398 | struct buffer_head *group_bh) | 390 | struct buffer_head *group_bh) |
399 | { | 391 | { |
400 | int ret; | 392 | int ret; |
401 | struct ocfs2_group_desc *gd; | 393 | struct ocfs2_group_desc *gd = |
394 | (struct ocfs2_group_desc *)group_bh->b_data; | ||
402 | u16 cl_bpc = le16_to_cpu(di->id2.i_chain.cl_bpc); | 395 | u16 cl_bpc = le16_to_cpu(di->id2.i_chain.cl_bpc); |
403 | unsigned int max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * | ||
404 | le16_to_cpu(di->id2.i_chain.cl_bpc); | ||
405 | |||
406 | 396 | ||
407 | gd = (struct ocfs2_group_desc *)group_bh->b_data; | 397 | ret = ocfs2_check_group_descriptor(inode->i_sb, di, group_bh); |
398 | if (ret) | ||
399 | goto out; | ||
408 | 400 | ||
409 | ret = -EIO; | 401 | ret = -EINVAL; |
410 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) | 402 | if (le16_to_cpu(gd->bg_chain) != input->chain) |
411 | mlog(ML_ERROR, "Group descriptor # %llu isn't valid.\n", | ||
412 | (unsigned long long)le64_to_cpu(gd->bg_blkno)); | ||
413 | else if (di->i_blkno != gd->bg_parent_dinode) | ||
414 | mlog(ML_ERROR, "Group descriptor # %llu has bad parent " | ||
415 | "pointer (%llu, expected %llu)\n", | ||
416 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
417 | (unsigned long long)le64_to_cpu(gd->bg_parent_dinode), | ||
418 | (unsigned long long)le64_to_cpu(di->i_blkno)); | ||
419 | else if (le16_to_cpu(gd->bg_bits) > max_bits) | ||
420 | mlog(ML_ERROR, "Group descriptor # %llu has bit count of %u\n", | ||
421 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
422 | le16_to_cpu(gd->bg_bits)); | ||
423 | else if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) | ||
424 | mlog(ML_ERROR, "Group descriptor # %llu has bit count %u but " | ||
425 | "claims that %u are free\n", | ||
426 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
427 | le16_to_cpu(gd->bg_bits), | ||
428 | le16_to_cpu(gd->bg_free_bits_count)); | ||
429 | else if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) | ||
430 | mlog(ML_ERROR, "Group descriptor # %llu has bit count %u but " | ||
431 | "max bitmap bits of %u\n", | ||
432 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | ||
433 | le16_to_cpu(gd->bg_bits), | ||
434 | 8 * le16_to_cpu(gd->bg_size)); | ||
435 | else if (le16_to_cpu(gd->bg_chain) != input->chain) | ||
436 | mlog(ML_ERROR, "Group descriptor # %llu has bad chain %u " | 403 | mlog(ML_ERROR, "Group descriptor # %llu has bad chain %u " |
437 | "while input has %u set.\n", | 404 | "while input has %u set.\n", |
438 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 405 | (unsigned long long)le64_to_cpu(gd->bg_blkno), |
@@ -451,6 +418,7 @@ static int ocfs2_check_new_group(struct inode *inode, | |||
451 | else | 418 | else |
452 | ret = 0; | 419 | ret = 0; |
453 | 420 | ||
421 | out: | ||
454 | return ret; | 422 | return ret; |
455 | } | 423 | } |
456 | 424 | ||
@@ -568,8 +536,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) | |||
568 | cl = &fe->id2.i_chain; | 536 | cl = &fe->id2.i_chain; |
569 | cr = &cl->cl_recs[input->chain]; | 537 | cr = &cl->cl_recs[input->chain]; |
570 | 538 | ||
571 | ret = ocfs2_journal_access(handle, main_bm_inode, group_bh, | 539 | ret = ocfs2_journal_access_gd(handle, main_bm_inode, group_bh, |
572 | OCFS2_JOURNAL_ACCESS_WRITE); | 540 | OCFS2_JOURNAL_ACCESS_WRITE); |
573 | if (ret < 0) { | 541 | if (ret < 0) { |
574 | mlog_errno(ret); | 542 | mlog_errno(ret); |
575 | goto out_commit; | 543 | goto out_commit; |
@@ -584,8 +552,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) | |||
584 | goto out_commit; | 552 | goto out_commit; |
585 | } | 553 | } |
586 | 554 | ||
587 | ret = ocfs2_journal_access(handle, main_bm_inode, main_bm_bh, | 555 | ret = ocfs2_journal_access_di(handle, main_bm_inode, main_bm_bh, |
588 | OCFS2_JOURNAL_ACCESS_WRITE); | 556 | OCFS2_JOURNAL_ACCESS_WRITE); |
589 | if (ret < 0) { | 557 | if (ret < 0) { |
590 | mlog_errno(ret); | 558 | mlog_errno(ret); |
591 | goto out_commit; | 559 | goto out_commit; |