aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/localalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/localalloc.c')
-rw-r--r--fs/ocfs2/localalloc.c64
1 files changed, 53 insertions, 11 deletions
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index 7e7dd65d97ef..7fe8149a0002 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -52,7 +52,8 @@ static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc);
52 52
53static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb, 53static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
54 struct ocfs2_dinode *alloc, 54 struct ocfs2_dinode *alloc,
55 u32 numbits); 55 u32 *numbits,
56 struct ocfs2_alloc_reservation *resv);
56 57
57static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc); 58static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc);
58 59
@@ -262,6 +263,8 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
262 263
263 osb->local_alloc_state = OCFS2_LA_DISABLED; 264 osb->local_alloc_state = OCFS2_LA_DISABLED;
264 265
266 ocfs2_resmap_uninit(&osb->osb_la_resmap);
267
265 main_bm_inode = ocfs2_get_system_file_inode(osb, 268 main_bm_inode = ocfs2_get_system_file_inode(osb,
266 GLOBAL_BITMAP_SYSTEM_INODE, 269 GLOBAL_BITMAP_SYSTEM_INODE,
267 OCFS2_INVALID_SLOT); 270 OCFS2_INVALID_SLOT);
@@ -493,7 +496,7 @@ static int ocfs2_local_alloc_in_range(struct inode *inode,
493 alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; 496 alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
494 la = OCFS2_LOCAL_ALLOC(alloc); 497 la = OCFS2_LOCAL_ALLOC(alloc);
495 498
496 start = ocfs2_local_alloc_find_clear_bits(osb, alloc, bits_wanted); 499 start = ocfs2_local_alloc_find_clear_bits(osb, alloc, &bits_wanted, NULL);
497 if (start == -1) { 500 if (start == -1) {
498 mlog_errno(-ENOSPC); 501 mlog_errno(-ENOSPC);
499 return 0; 502 return 0;
@@ -659,7 +662,8 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
659 alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; 662 alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
660 la = OCFS2_LOCAL_ALLOC(alloc); 663 la = OCFS2_LOCAL_ALLOC(alloc);
661 664
662 start = ocfs2_local_alloc_find_clear_bits(osb, alloc, bits_wanted); 665 start = ocfs2_local_alloc_find_clear_bits(osb, alloc, &bits_wanted,
666 ac->ac_resv);
663 if (start == -1) { 667 if (start == -1) {
664 /* TODO: Shouldn't we just BUG here? */ 668 /* TODO: Shouldn't we just BUG here? */
665 status = -ENOSPC; 669 status = -ENOSPC;
@@ -669,8 +673,6 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
669 673
670 bitmap = la->la_bitmap; 674 bitmap = la->la_bitmap;
671 *bit_off = le32_to_cpu(la->la_bm_off) + start; 675 *bit_off = le32_to_cpu(la->la_bm_off) + start;
672 /* local alloc is always contiguous by nature -- we never
673 * delete bits from it! */
674 *num_bits = bits_wanted; 676 *num_bits = bits_wanted;
675 677
676 status = ocfs2_journal_access_di(handle, 678 status = ocfs2_journal_access_di(handle,
@@ -682,6 +684,9 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
682 goto bail; 684 goto bail;
683 } 685 }
684 686
687 ocfs2_resmap_claimed_bits(&osb->osb_la_resmap, ac->ac_resv, start,
688 bits_wanted);
689
685 while(bits_wanted--) 690 while(bits_wanted--)
686 ocfs2_set_bit(start++, bitmap); 691 ocfs2_set_bit(start++, bitmap);
687 692
@@ -711,13 +716,17 @@ static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc)
711} 716}
712 717
713static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb, 718static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
714 struct ocfs2_dinode *alloc, 719 struct ocfs2_dinode *alloc,
715 u32 numbits) 720 u32 *numbits,
721 struct ocfs2_alloc_reservation *resv)
716{ 722{
717 int numfound, bitoff, left, startoff, lastzero; 723 int numfound, bitoff, left, startoff, lastzero;
724 int local_resv = 0;
725 struct ocfs2_alloc_reservation r;
718 void *bitmap = NULL; 726 void *bitmap = NULL;
727 struct ocfs2_reservation_map *resmap = &osb->osb_la_resmap;
719 728
720 mlog_entry("(numbits wanted = %u)\n", numbits); 729 mlog_entry("(numbits wanted = %u)\n", *numbits);
721 730
722 if (!alloc->id1.bitmap1.i_total) { 731 if (!alloc->id1.bitmap1.i_total) {
723 mlog(0, "No bits in my window!\n"); 732 mlog(0, "No bits in my window!\n");
@@ -725,6 +734,30 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
725 goto bail; 734 goto bail;
726 } 735 }
727 736
737 if (!resv) {
738 local_resv = 1;
739 ocfs2_resv_init_once(&r);
740 ocfs2_resv_set_type(&r, OCFS2_RESV_FLAG_TMP);
741 resv = &r;
742 }
743
744 numfound = *numbits;
745 if (ocfs2_resmap_resv_bits(resmap, resv, &bitoff, &numfound) == 0) {
746 if (numfound < *numbits)
747 *numbits = numfound;
748 goto bail;
749 }
750
751 /*
752 * Code error. While reservations are enabled, local
753 * allocation should _always_ go through them.
754 */
755 BUG_ON(osb->osb_resv_level != 0);
756
757 /*
758 * Reservations are disabled. Handle this the old way.
759 */
760
728 bitmap = OCFS2_LOCAL_ALLOC(alloc)->la_bitmap; 761 bitmap = OCFS2_LOCAL_ALLOC(alloc)->la_bitmap;
729 762
730 numfound = bitoff = startoff = 0; 763 numfound = bitoff = startoff = 0;
@@ -750,7 +783,7 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
750 startoff = bitoff+1; 783 startoff = bitoff+1;
751 } 784 }
752 /* we got everything we needed */ 785 /* we got everything we needed */
753 if (numfound == numbits) { 786 if (numfound == *numbits) {
754 /* mlog(0, "Found it all!\n"); */ 787 /* mlog(0, "Found it all!\n"); */
755 break; 788 break;
756 } 789 }
@@ -759,12 +792,18 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
759 mlog(0, "Exiting loop, bitoff = %d, numfound = %d\n", bitoff, 792 mlog(0, "Exiting loop, bitoff = %d, numfound = %d\n", bitoff,
760 numfound); 793 numfound);
761 794
762 if (numfound == numbits) 795 if (numfound == *numbits) {
763 bitoff = startoff - numfound; 796 bitoff = startoff - numfound;
764 else 797 *numbits = numfound;
798 } else {
799 numfound = 0;
765 bitoff = -1; 800 bitoff = -1;
801 }
766 802
767bail: 803bail:
804 if (local_resv)
805 ocfs2_resv_discard(resmap, resv);
806
768 mlog_exit(bitoff); 807 mlog_exit(bitoff);
769 return bitoff; 808 return bitoff;
770} 809}
@@ -1087,6 +1126,9 @@ retry_enospc:
1087 memset(OCFS2_LOCAL_ALLOC(alloc)->la_bitmap, 0, 1126 memset(OCFS2_LOCAL_ALLOC(alloc)->la_bitmap, 0,
1088 le16_to_cpu(la->la_size)); 1127 le16_to_cpu(la->la_size));
1089 1128
1129 ocfs2_resmap_restart(&osb->osb_la_resmap, cluster_count,
1130 OCFS2_LOCAL_ALLOC(alloc)->la_bitmap);
1131
1090 mlog(0, "New window allocated:\n"); 1132 mlog(0, "New window allocated:\n");
1091 mlog(0, "window la_bm_off = %u\n", 1133 mlog(0, "window la_bm_off = %u\n",
1092 OCFS2_LOCAL_ALLOC(alloc)->la_bm_off); 1134 OCFS2_LOCAL_ALLOC(alloc)->la_bm_off);