aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/suballoc.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2010-03-25 22:09:29 -0400
committerTao Ma <tao.ma@oracle.com>2010-03-25 22:09:29 -0400
commit8b06bc592ebc5a31e8d0b9c2ab17c6e78dde1f86 (patch)
treeb05dc205b03329aa3e0c0963b76317fc91973a04 /fs/ocfs2/suballoc.c
parent2b6cb576aa80611f1f6a3c88708d1e68a8d97985 (diff)
ocfs2: Grow discontig block groups in one transaction.
Rather than extending the transaction every time we add an extent to a discontiguous block group, we grab enough credits to fill the extent list up front. This means we can free the bits in the same transaction if we end up not getting enough space. Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r--fs/ocfs2/suballoc.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 7809f41bcbfc..e5403acdb3f5 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -523,12 +523,6 @@ static int ocfs2_block_group_grow_discontig(handle_t *handle,
523 523
524 while ((needed > 0) && (le16_to_cpu(el->l_next_free_rec) < 524 while ((needed > 0) && (le16_to_cpu(el->l_next_free_rec) <
525 le16_to_cpu(el->l_count))) { 525 le16_to_cpu(el->l_count))) {
526 status = ocfs2_extend_trans(handle, OCFS2_SUBALLOC_ALLOC);
527 if (status) {
528 mlog_errno(status);
529 goto bail;
530 }
531
532 if (min_bits > needed) 526 if (min_bits > needed)
533 min_bits = needed; 527 min_bits = needed;
534 status = ocfs2_block_group_claim_bits(osb, handle, ac, 528 status = ocfs2_block_group_claim_bits(osb, handle, ac,
@@ -556,11 +550,12 @@ bail:
556 return status; 550 return status;
557} 551}
558 552
559static void ocfs2_bg_alloc_cleanup(struct inode *alloc_inode, 553static void ocfs2_bg_alloc_cleanup(handle_t *handle,
560 struct buffer_head *bg_bh, 554 struct ocfs2_alloc_context *cluster_ac,
561 struct ocfs2_cached_dealloc_ctxt *dealloc) 555 struct inode *alloc_inode,
556 struct buffer_head *bg_bh)
562{ 557{
563 int i; 558 int i, ret;
564 struct ocfs2_group_desc *bg; 559 struct ocfs2_group_desc *bg;
565 struct ocfs2_extent_list *el; 560 struct ocfs2_extent_list *el;
566 struct ocfs2_extent_rec *rec; 561 struct ocfs2_extent_rec *rec;
@@ -572,9 +567,13 @@ static void ocfs2_bg_alloc_cleanup(struct inode *alloc_inode,
572 el = &bg->bg_list; 567 el = &bg->bg_list;
573 for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) { 568 for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
574 rec = &el->l_recs[i]; 569 rec = &el->l_recs[i];
575 ocfs2_cache_cluster_dealloc(dealloc, 570 ret = ocfs2_free_clusters(handle, cluster_ac->ac_inode,
576 le64_to_cpu(rec->e_blkno), 571 cluster_ac->ac_bh,
577 le32_to_cpu(rec->e_leaf_clusters)); 572 le64_to_cpu(rec->e_blkno),
573 le32_to_cpu(rec->e_leaf_clusters));
574 if (ret)
575 mlog_errno(ret);
576 /* Try all the clusters to free */
578 } 577 }
579 578
580 ocfs2_remove_from_cache(INODE_CACHE(alloc_inode), bg_bh); 579 ocfs2_remove_from_cache(INODE_CACHE(alloc_inode), bg_bh);
@@ -585,8 +584,7 @@ static struct buffer_head *
585ocfs2_block_group_alloc_discontig(handle_t *handle, 584ocfs2_block_group_alloc_discontig(handle_t *handle,
586 struct inode *alloc_inode, 585 struct inode *alloc_inode,
587 struct ocfs2_alloc_context *ac, 586 struct ocfs2_alloc_context *ac,
588 struct ocfs2_chain_list *cl, 587 struct ocfs2_chain_list *cl)
589 struct ocfs2_cached_dealloc_ctxt *dealloc)
590{ 588{
591 int status; 589 int status;
592 u32 bit_off, num_bits; 590 u32 bit_off, num_bits;
@@ -601,6 +599,13 @@ ocfs2_block_group_alloc_discontig(handle_t *handle,
601 goto bail; 599 goto bail;
602 } 600 }
603 601
602 status = ocfs2_extend_trans(handle,
603 ocfs2_calc_bg_discontig_credits(osb->sb));
604 if (status) {
605 mlog_errno(status);
606 goto bail;
607 }
608
604 /* Claim the first region */ 609 /* Claim the first region */
605 status = ocfs2_block_group_claim_bits(osb, handle, ac, min_bits, 610 status = ocfs2_block_group_claim_bits(osb, handle, ac, min_bits,
606 &bit_off, &num_bits); 611 &bit_off, &num_bits);
@@ -638,7 +643,7 @@ ocfs2_block_group_alloc_discontig(handle_t *handle,
638 643
639bail: 644bail:
640 if (status) 645 if (status)
641 ocfs2_bg_alloc_cleanup(alloc_inode, bg_bh, dealloc); 646 ocfs2_bg_alloc_cleanup(handle, ac, alloc_inode, bg_bh);
642 return status ? ERR_PTR(status) : bg_bh; 647 return status ? ERR_PTR(status) : bg_bh;
643} 648}
644 649
@@ -660,14 +665,11 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
660 u64 bg_blkno; 665 u64 bg_blkno;
661 struct buffer_head *bg_bh = NULL; 666 struct buffer_head *bg_bh = NULL;
662 struct ocfs2_group_desc *bg; 667 struct ocfs2_group_desc *bg;
663 struct ocfs2_cached_dealloc_ctxt dealloc;
664 668
665 BUG_ON(ocfs2_is_cluster_bitmap(alloc_inode)); 669 BUG_ON(ocfs2_is_cluster_bitmap(alloc_inode));
666 670
667 mlog_entry_void(); 671 mlog_entry_void();
668 672
669 ocfs2_init_dealloc_ctxt(&dealloc);
670
671 cl = &fe->id2.i_chain; 673 cl = &fe->id2.i_chain;
672 status = ocfs2_reserve_clusters_with_limit(osb, 674 status = ocfs2_reserve_clusters_with_limit(osb,
673 le16_to_cpu(cl->cl_cpg), 675 le16_to_cpu(cl->cl_cpg),
@@ -699,8 +701,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
699 if (IS_ERR(bg_bh) && (PTR_ERR(bg_bh) == -ENOSPC)) 701 if (IS_ERR(bg_bh) && (PTR_ERR(bg_bh) == -ENOSPC))
700 bg_bh = ocfs2_block_group_alloc_discontig(handle, 702 bg_bh = ocfs2_block_group_alloc_discontig(handle,
701 alloc_inode, 703 alloc_inode,
702 ac, cl, 704 ac, cl);
703 &dealloc);
704 if (IS_ERR(bg_bh)) { 705 if (IS_ERR(bg_bh)) {
705 status = PTR_ERR(bg_bh); 706 status = PTR_ERR(bg_bh);
706 bg_bh = NULL; 707 bg_bh = NULL;
@@ -750,11 +751,6 @@ bail:
750 if (handle) 751 if (handle)
751 ocfs2_commit_trans(osb, handle); 752 ocfs2_commit_trans(osb, handle);
752 753
753 if (ocfs2_dealloc_has_cluster(&dealloc)) {
754 ocfs2_schedule_truncate_log_flush(osb, 1);
755 ocfs2_run_deallocs(osb, &dealloc);
756 }
757
758 if (ac) 754 if (ac)
759 ocfs2_free_alloc_context(ac); 755 ocfs2_free_alloc_context(ac);
760 756