[Ocfs2-commits] mfasheh commits r1488 - branches/dlm-changes/src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Fri Sep 24 18:29:46 CDT 2004


Author: mfasheh
Date: 2004-09-24 18:29:44 -0500 (Fri, 24 Sep 2004)
New Revision: 1488

Modified:
   branches/dlm-changes/src/alloc.c
   branches/dlm-changes/src/alloc.h
Log:
* The Big Tamale. Data allocation functions have changed drastically: 
  - We now support discontiguous allocation of data, though you can
    still ask for a 'minimum' set of bits (system files may use this
    - all others have a minimum of '1').
  - Take allocation cluster locks outside of journal transactions. This is
    the general path we want to go in (for all locks), eventually squeezing
    the code that makes changes into tight spots nested within start_trans /
    commit_trans. We otherwise deadlock heavily as releasing a cluster lock    
    is impossible while a transaction is in progress. 
  - To facilitate this new locking scheme, we have a reserve / claim api by 
    which our code can get clusters.       

* ocfs_find_contiguous_space_from_bitmap stays for now as the local alloc   
  code still uses it. A TODO item is to change that stuff to use the new api
  against the main bitmap (trivial).



Modified: branches/dlm-changes/src/alloc.c
===================================================================
--- branches/dlm-changes/src/alloc.c	2004-09-24 23:19:23 UTC (rev 1487)
+++ branches/dlm-changes/src/alloc.c	2004-09-24 23:29:44 UTC (rev 1488)
@@ -42,6 +42,7 @@
 #include "extmap.h"
 #include "inode.h"
 #include "util.h"
+#include "suballoc.h"
 #include "sysfile.h"
 #include "file.h"
 
@@ -55,6 +56,14 @@
 			       struct buffer_head *extent_grp_bh, 
 			       ocfs_journal_handle *handle,
 			       struct inode *inode);
+
+static int ocfs_create_new_meta_bhs(ocfs_super *osb, 
+				    ocfs_journal_handle *handle,
+				    struct inode *inode,
+				    int wanted, 
+				    ocfs2_alloc_context *meta_ac,
+				    struct buffer_head *bhs[]);
+
 static int ocfs_allocate_new_data_node(ocfs_super *osb, 
 				       ocfs2_dinode *fe,
 				       u64 new_blkno,
@@ -62,13 +71,16 @@
 				       struct buffer_head *eb_bh, 
 				       u64 *new_eb_blkno, 
       				       ocfs_journal_handle *handle,
-				       struct inode *inode);
+				       struct inode *inode,
+				       ocfs2_alloc_context *meta_ac);
 
 static int ocfs_grow_extent_tree(ocfs_super *osb,
 				 struct buffer_head *fe_bh,
 				 ocfs_journal_handle *handle,
 				 u64 blkno,
-			       	 u32 new_clusters, struct inode *inode);
+			       	 u32 new_clusters, 
+				 struct inode *inode,
+				 ocfs2_alloc_context *meta_ac);
 
 static int _squish_extent_entries(ocfs_super *osb,
 				  ocfs2_extent_rec *extarr, 
@@ -100,6 +112,14 @@
 					ocfs_journal_handle *handle, 
 					ocfs_free_rec *freelog);
 
+/* The largest cluster size where we even consider using local alloc. */
+#define OCFS_LOCAL_ALLOC_MAX_CSIZE    (128 * 1024)
+/* The largest allocation to use the local bitmap for. */
+#define OCFS_LOCAL_ALLOC_MAX_ALLOC    (2 * 1024 * 1024)
+static inline int ocfs_local_alloc_window_bits(ocfs_super *osb);
+static inline int ocfs_alloc_should_use_local(ocfs_super *osb, u64 bits);
+static int ocfs_local_alloc_full_window_change(ocfs_super *osb, 
+					       struct inode * local_alloc_inode);
 static int ocfs_alloc_new_window(ocfs_super *osb, struct buffer_head *lock_bh,
 				 struct inode *bm_inode,
 				 ocfs_journal_handle *handle);
@@ -109,15 +129,38 @@
 					 int in_recovery);
 static __u32 ocfs_alloc_count_bits(ocfs2_dinode *alloc);
 static void ocfs_clear_local_alloc(ocfs2_dinode *alloc);
-static int ocfs_find_space_from_local(ocfs_super *osb, __u32 bitswanted,
-				      u32 *bitoff, u32 *bitcount, 
-				      ocfs_journal_handle *handle);
 static int ocfs_local_find_clear_bits(ocfs_super *osb,
 				      ocfs2_dinode *alloc,
 				      __u32 numbits);
 static int ocfs_extent_contig(struct inode *inode, ocfs2_extent_rec *ext,
 			      u64 blkno);
 
+static inline int ocfs_alloc_should_use_local(ocfs_super *osb, u64 bits);
+
+static int ocfs_reserve_main_bitmap_bits(ocfs_super *osb, 
+					 ocfs_journal_handle *handle,
+					 u32 bits_wanted,
+					 ocfs2_alloc_context *ac);
+
+static int ocfs_reserve_local_bits(ocfs_super *osb, 
+				   ocfs_journal_handle *passed_handle,
+				   u32 bits_wanted,
+				   ocfs2_alloc_context *ac);
+
+static int ocfs_claim_main_bitmap_bits(ocfs_super *osb,
+				       ocfs_journal_handle *handle,
+				       ocfs2_alloc_context *ac,
+				       u32 min_bits,
+				       u32 *bit_off,
+				       u32 *num_bits);
+
+static int ocfs_claim_local_bitmap_bits(ocfs_super *osb,
+					ocfs_journal_handle *handle,
+					ocfs2_alloc_context *ac,
+					u32 min_bits,
+					u32 *bit_off,
+					u32 *num_bits);
+
 static int ocfs_extent_contig(struct inode *inode, ocfs2_extent_rec *ext,
 			      u64 blkno)
 {
@@ -218,11 +261,11 @@
 	int status = 0;
 	__u32 num_upd;
 	__u32 i;
-	__u32 node_num;
+//	__u32 node_num;
 	ocfs_free_rec **ext_alloc_free = NULL;
 	ocfs_free_rec **inode_alloc_free = NULL;
 	ocfs_free_rec *free_vol_bits = NULL;
-	ocfs_free_rec *tmp_log;
+	ocfs_free_rec *tmp_log = NULL;
 	struct inode **ext_alloc_inode = NULL;
 	struct inode **inode_alloc_inode = NULL;
 	struct inode *vol_inode = NULL;
@@ -266,6 +309,7 @@
 	for (i = 0; i < num_upd; i++) {
 		switch (free_log->update[i].type) {
 		    case DISK_ALLOC_INODE:
+#if 0
 			    node_num = free_log->update[i].node_num;
 			    if (inode_alloc_free[node_num] == NULL) {
 				    inode_alloc_free[node_num] =
@@ -279,9 +323,11 @@
 			    tmp_log = inode_alloc_free[node_num];
 
 			    credits++;
+#endif
 			    break;
 
 		    case DISK_ALLOC_EXTENT_NODE:
+#if 0
 			    node_num = free_log->update[i].node_num;
 			    if (ext_alloc_free[node_num] == NULL) {
 				    ext_alloc_free[node_num] =
@@ -295,6 +341,7 @@
 			    tmp_log = ext_alloc_free[node_num];
 
 			    credits++;
+#endif
 			    break;
 
 		    case DISK_ALLOC_VOLUME:
@@ -671,7 +718,45 @@
 	return status;
 }			/* ocfs_free_vol_block */
 
+/*
+ * How many free extents have we got before we need more meta data?
+ */
+int ocfs_num_free_extents(ocfs_super *osb, 
+			  struct inode *inode,
+			  ocfs2_dinode *fe)
+{
+	int retval;
+	ocfs2_extent_list *el;
+	ocfs2_extent_block *eb;
+	struct buffer_head *eb_bh = NULL;
 
+	LOG_ENTRY();
+
+	OCFS_ASSERT(IS_VALID_FILE_ENTRY(fe));
+
+	if (fe->i_last_eb_blk) {
+		retval = ocfs_read_bh(osb, fe->i_last_eb_blk << osb->sb->s_blocksize_bits, &eb_bh, OCFS_BH_CACHED, inode);
+		if (retval < 0) {
+			LOG_ERROR_STATUS(retval);
+			goto bail;
+		}
+		eb = (ocfs2_extent_block *) eb_bh->b_data;
+		el = &(eb->h_list);
+	} else
+		el = &(fe->id2.i_list);
+
+	OCFS_ASSERT(el->l_tree_depth == 0);
+
+	retval = el->l_count - el->l_next_free_rec;
+
+bail:
+	if (eb_bh)
+		brelse(eb_bh);
+
+	LOG_EXIT_STATUS(retval);
+	return(retval);
+}
+
 /* ocfs_allocate_new_data_node()
  * 
  */
@@ -682,26 +767,24 @@
 				       struct buffer_head *eb_bh, 
 				       u64 *new_eb_blkno,
 				       ocfs_journal_handle *handle,
-				       struct inode *inode)
+				       struct inode *inode,
+				       ocfs2_alloc_context *meta_ac)
 {
 	int status = 0;
 	__u32 k, i;
 	__u32 depth;
-	int allocSize;
 	u64 parent_blk;
-	__u64 physicalOffset;
-	u64 phys_blkno;
-	__u64 fileOffset = 0;
 	int new_blocks = 0;
 	ocfs2_extent_block *eb = NULL;
 	ocfs2_extent_list *el1, *el2 = NULL;
 	struct buffer_head **eb_bhs = NULL;
 	struct buffer_head *bh = NULL;
-	int bh_locked = 0;
 	int size;
 
 	LOG_ENTRY ();
-	
+
+	OCFS_ASSERT(meta_ac);
+
 	if (eb_bh) {
 		status = ocfs_journal_access(handle, eb_bh, 
 					     OCFS_JOURNAL_ACCESS_WRITE);
@@ -713,7 +796,6 @@
 
 		eb = (ocfs2_extent_block *) eb_bh->b_data;
 		el1 = &eb->h_list;
-		bh_locked = 1;
 	}
 	else
 		el1 = &fe->id2.i_list;
@@ -726,18 +808,7 @@
 		parent_blk = fe->i_blkno;
 
 	new_blocks = depth;
-	allocSize = new_blocks << osb->sb->s_blocksize_bits;
 
-	/* allocate contiguous blocks on disk */
-	status = ocfs_alloc_node_block(osb, allocSize, &physicalOffset, 
-				       &fileOffset, osb->node_num, 
-				       DISK_ALLOC_EXTENT_NODE, handle);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto finally;
-	}
-	phys_blkno = physicalOffset >> osb->sb->s_blocksize_bits;
-
 	size = sizeof(struct buffer_head *) * new_blocks;
 	eb_bhs = kmalloc(size, GFP_KERNEL);
 	if (eb_bhs == NULL) {
@@ -747,57 +818,37 @@
 	}
 	memset(eb_bhs, 0, size);
 
-	status = ocfs_read_bhs(osb,
-			       phys_blkno << osb->sb->s_blocksize_bits,
-			       (u64)new_blocks << osb->sb->s_blocksize_bits,
-			       eb_bhs, OCFS_BH_CACHED, inode);
+	status = ocfs_create_new_meta_bhs(osb, handle, inode, new_blocks, meta_ac, eb_bhs);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
 		goto finally;
 	}
 
-	/* zero them all out */
-	for(i = 0; i < new_blocks; i++) {
-		status = ocfs_journal_access(handle, eb_bhs[i], 
-					     OCFS_JOURNAL_ACCESS_CREATE);
-		if (status < 0) {
-			LOG_ERROR_STATUS(status);
-			goto finally;
-		}
-
-		memset(eb_bhs[i]->b_data, 0, osb->sb->s_blocksize);
-		set_buffer_uptodate(eb_bhs[i]);
-	}
-	
 	k = el1->l_next_free_rec;
 	el1->l_recs[k].e_cpos = fe->i_clusters;
 	el1->l_recs[k].e_clusters = new_clusters;
-	el1->l_recs[k].e_blkno = phys_blkno;
+	el1->l_recs[k].e_blkno = 
+		((ocfs2_extent_block *) eb_bhs[0]->b_data)->h_blkno;
 	el1->l_next_free_rec++;
 
 	/* Fill in all the headers and the leaf */
 	for (i = 0; i < depth; i++) {
-		ocfs2_extent_block *eb;
+		ocfs2_extent_block *eb, *tmpeb;
 
 		eb = (ocfs2_extent_block *) eb_bhs[i]->b_data;
 
 		eb->h_parent_blk = parent_blk;
-		eb->h_suballoc_blkno =
-			(fileOffset >> osb->sb->s_blocksize_bits) + i;
-		eb->h_suballoc_node = osb->node_num;
-		eb->h_blkno = phys_blkno + i;
-		strcpy(eb->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE);
 
 		el2 = &eb->h_list;
-		el2->l_count = ocfs2_extent_recs_per_eb(osb->sb);
 		el2->l_next_free_rec = 1;
 		el2->l_recs[0].e_cpos = fe->i_clusters;
 		el2->l_recs[0].e_clusters = new_clusters;
 		el2->l_tree_depth = (depth - (i + 1));
 
 		if (el2->l_tree_depth) {
+			tmpeb = (ocfs2_extent_block *) eb_bhs[i+1]->b_data;
 			/* fill in each header */
-			el2->l_recs[0].e_blkno = phys_blkno + (i + 1);
+			el2->l_recs[0].e_blkno = tmpeb->h_blkno;
 		} else {
 			/* fill in the leaf */
 			el2->l_recs[0].e_blkno = new_blkno;
@@ -821,7 +872,6 @@
 		u64 tmp_blk = eb->h_parent_blk;
 		int tree_depth = el1->l_tree_depth;
 
-		bh_locked = 0;
 		eb = NULL;
 
 	       	el1 = &fe->id2.i_list;
@@ -894,6 +944,92 @@
 	return status;
 }				/* ocfs_allocate_new_data_node */
 
+/* expects array to already be malloced 
+ *
+ * sets h_signature, h_blkno, h_suballoc_bit, h_suballoc_node, and
+ * l_count for you 
+ */
+static int ocfs_create_new_meta_bhs(ocfs_super *osb, 
+				    ocfs_journal_handle *handle,
+				    struct inode *inode,
+				    int wanted, 
+				    ocfs2_alloc_context *meta_ac,
+				    struct buffer_head *bhs[])
+{
+	int count, status, i;
+	u16 suballoc_bit_start;
+	u32 num_got;
+	u64 first_blkno;
+	ocfs2_extent_block *eb;
+
+	LOG_ENTRY();
+
+	count = 0;
+	while (count < wanted) {
+		status = ocfs_claim_metadata(osb, 
+					     handle, 
+					     meta_ac,
+					     wanted - count, 
+					     &suballoc_bit_start, 
+					     &num_got,
+					     &first_blkno);
+		if (status < 0) {
+			LOG_ERROR_STATUS (status);
+			goto bail;
+		}
+
+		for(i = count;  i < (num_got + count); i++) {
+			bhs[i] = sb_getblk(osb->sb, first_blkno);
+			if (bhs[i] == NULL) {
+				status = -EIO;
+				LOG_ERROR_STATUS(status);
+				goto bail;
+			}
+			set_buffer_uptodate(bhs[i]);
+			SET_BH_SEQNUM(inode, bhs[i]);
+
+			status = ocfs_journal_access(handle, bhs[i],
+						     OCFS_JOURNAL_ACCESS_CREATE);
+			if (status < 0) {
+				LOG_ERROR_STATUS(status);
+				goto bail;
+			}
+
+			memset(bhs[i]->b_data, 0, osb->sb->s_blocksize);
+			eb = (ocfs2_extent_block *) bhs[i]->b_data;
+			/* Ok, setup the minimal stuff here. */
+			strcpy(eb->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE);
+			eb->h_blkno = first_blkno;
+
+#ifndef OCFS_USE_ALL_METADATA_SUBALLOCATORS
+			/* we always use node zeros suballocator */
+			eb->h_suballoc_node = 0;
+#else
+			eb->h_suballoc_node = osb->node_num;
+#endif
+			eb->h_suballoc_bit = suballoc_bit_start;
+			eb->h_list.l_count = ocfs2_extent_recs_per_eb(osb->sb);
+
+			suballoc_bit_start++;
+			first_blkno++;
+		}
+
+		count += num_got;
+	}
+
+	status = 0;
+bail:
+	if (status < 0) {
+		for(i = 0; i < wanted; i++) {
+			if (bhs[i])
+				brelse(bhs[i]);
+			bhs[i] = NULL;
+		}
+	}
+	LOG_EXIT_STATUS(status);
+	return(status);
+}
+
 /* ocfs_grow_extent_tree()
  *
  */
@@ -901,16 +1037,15 @@
 				 struct buffer_head *fe_bh,
 				 ocfs_journal_handle *handle,
 				 u64 blkno, u32 new_clusters,
-				 struct inode *inode)
+				 struct inode *inode,
+				 ocfs2_alloc_context *meta_ac)
 {
 	int status = 0;
 	__s32 k, i;
 	ocfs2_extent_block *eb1 = NULL;
 	ocfs2_extent_block *eb2 = NULL;
 	ocfs2_extent_list *ebl, *fel;
-	__u64 physicalOffset;
-	__u64 fileOffset = 0;
-	u64 phys_blkno, parent_blk, last_eb_blkno;
+	u64 parent_blk, last_eb_blkno;
 	u64 new_parent_blk = 0;
 	struct buffer_head **bhs = NULL;
 	int numbhs = 0;
@@ -919,6 +1054,8 @@
 	LOG_ENTRY_ARGS("(0x%p, 0x%p, %llu, %u\n", osb, fe, blkno,
 		       new_clusters);
 
+	OCFS_ASSERT(meta_ac);
+
 	fe = (ocfs2_dinode *) fe_bh->b_data;
 
 	fel = &fe->id2.i_list;
@@ -932,35 +1069,12 @@
 	}
 	memset(bhs, 0, numbhs * sizeof(*bhs));
 
-	/* Allocate the space from the Extent file. This function should */
-	/* return contigous disk blocks requested. */
-	status = ocfs_alloc_node_block(osb,
-				       numbhs << osb->sb->s_blocksize_bits,
-				       &physicalOffset, &fileOffset,
-				       osb->node_num, 
-			       	       DISK_ALLOC_EXTENT_NODE, handle);
+	status = ocfs_create_new_meta_bhs(osb, handle, inode, numbhs, meta_ac, bhs);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
 		goto finally;
 	}
-	phys_blkno = physicalOffset >> osb->sb->s_blocksize_bits;
 
-	for (i = 0; i < numbhs; i++) {
-		bhs[i] = sb_getblk(osb->sb, phys_blkno + i);
-		if (bhs[i] == NULL) {
-			status = -EIO;
-			LOG_ERROR_STATUS(status);
-			goto finally;
-		}
-		memset(bhs[i]->b_data, 0, osb->sb->s_blocksize);
-		set_buffer_uptodate(bhs[i]);
-	}
-
-	if (phys_blkno == 0) {
-		LOG_ERROR_STATUS(status = -ENOMEM);
-		goto finally;
-	}
-
 	eb1 = (ocfs2_extent_block *) bhs[0]->b_data;
 	/* Copy the File Entry information in to the newly allocated sector */
 	ebl = &eb1->h_list;
@@ -971,56 +1085,45 @@
 	}
 
 	last_eb_blkno = fe->i_last_eb_blk;
-	eb1->h_blkno =
-		physicalOffset >> osb->sb->s_blocksize_bits;
 	new_parent_blk = eb1->h_blkno;
-	eb1->h_suballoc_blkno =
-		fileOffset >> osb->sb->s_blocksize_bits;
-	eb1->h_suballoc_node = osb->node_num;
 	eb1->h_next_leaf_blk = 0;
 	fel->l_tree_depth++;
 
 	LOG_TRACE_ARGS ("Tree depth is: %d\n", fel->l_tree_depth);
 
-	/* If tree_depth is one now, the for loop will not execute. */
-	/* First time a file is created, tree_depth = 0 */
-
 	parent_blk = fe->i_blkno;
 
+	/* If tree_depth is one now, the for loop will not execute. *
+	 * First time a file is created, tree_depth = 0 */
 	for (i = 0; i < (fel->l_tree_depth - 1); i++) {
+		ocfs2_extent_block *tmpeb;
+
 		eb2 = (ocfs2_extent_block *) bhs[i]->b_data;
 		ebl = &eb2->h_list;
 
 		ebl->l_tree_depth = (fel->l_tree_depth - 1) - i;
 		ebl->l_count = ocfs2_extent_recs_per_eb(osb->sb);
 
-		strcpy(eb2->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE);
-
 		if (i == 0) {
-			ebl->l_recs[fel->l_count].e_blkno =
-				phys_blkno + 1;
+			tmpeb = (ocfs2_extent_block *) bhs[1]->b_data;
+			ebl->l_recs[fel->l_count].e_blkno = 
+				tmpeb->h_blkno + 1;
 			ebl->l_recs[fel->l_count].e_cpos =
 				fe->i_clusters;
 			ebl->l_recs[fel->l_count].e_clusters =
 				new_clusters;
 			ebl->l_next_free_rec = fel->l_count + 1;
 
-			eb2->h_blkno =
-				physicalOffset >> osb->sb->s_blocksize_bits;
 			eb2->h_parent_blk = parent_blk;
 
 			parent_blk = last_eb_blkno = eb2->h_blkno;
 		} else {
-			ebl->l_recs[0].e_blkno = phys_blkno + (i + 1);
+			tmpeb = (ocfs2_extent_block *) bhs[i + 1]->b_data;
+			ebl->l_recs[0].e_blkno = tmpeb->h_blkno;
 			ebl->l_recs[0].e_cpos = fe->i_clusters;
 			ebl->l_recs[0].e_clusters = new_clusters;
 			ebl->l_next_free_rec = 1;
 
-			eb2->h_suballoc_blkno =
-				(fileOffset >> osb->sb->s_blocksize_bits) + i;
-			eb2->h_suballoc_node = osb->node_num;
-			eb2->h_blkno = 
-				(physicalOffset >> osb->sb->s_blocksize_bits) + i;
 			eb2->h_parent_blk = parent_blk;
 
 			parent_blk = last_eb_blkno = eb2->h_blkno;
@@ -1038,7 +1141,6 @@
 	/* For the time being we are assuming that the newly allocated Extent */
 	/* will have one more entry to accomodate the latest allocation */
 
-	strcpy(eb1->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE);
 	ebl->l_tree_depth = 0;
 	ebl->l_count = ocfs2_extent_recs_per_eb(osb->sb);
 
@@ -1047,23 +1149,17 @@
 	ebl->l_recs[i].e_blkno = blkno;
 	ebl->l_next_free_rec = i + 1;
 
-	eb1->h_suballoc_blkno =
-		(fileOffset >> osb->sb->s_blocksize_bits) +
-		numbhs - 1;
-	eb1->h_suballoc_node = osb->node_num;
-	eb1->h_blkno =
-		(physicalOffset >> osb->sb->s_blocksize_bits) +
-		numbhs - 1;
 	eb1->h_parent_blk = parent_blk;
 	eb1->h_next_leaf_blk = 0;
 
 	parent_blk = last_eb_blkno = eb1->h_blkno;
 
-	/* This needs to be a sync write OR journalled to be safe. */
-	status = ocfs_write_bhs(osb, bhs, numbhs, inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto finally;
+	for(i = 0; i < numbhs; i++) {
+		status = ocfs_journal_dirty(handle, bhs[i]);
+		if (status < 0) {
+			LOG_ERROR_STATUS (status);
+			goto finally;
+		}
 	}
 
 	/* Update the Previous Last Data Extent with this new Data
@@ -1151,7 +1247,8 @@
 	LOG_TRACE_ARGS("fe->i_clusters = %u\n", fe->i_clusters);
 	fel->l_recs[0].e_cpos = 0;  /* FIXME: not needed */
 	fel->l_recs[0].e_clusters = fe->i_clusters + new_clusters;
-	fel->l_recs[0].e_blkno = phys_blkno;
+	eb1 = (ocfs2_extent_block *) bhs[0]->b_data;
+	fel->l_recs[0].e_blkno = eb1->h_blkno;
 	fel->l_next_free_rec = 1;
 	fe->i_last_eb_blk = last_eb_blkno;
 
@@ -1169,7 +1266,8 @@
 int ocfs_allocate_extent(ocfs_super *osb, struct buffer_head *fe_bh,
 			 ocfs_journal_handle *handle,
 			 u64 blkno, u32 new_clusters,
-			 struct inode *inode)
+			 struct inode *inode,
+			 ocfs2_alloc_context *meta_ac)
 {
 	int status = 0;
 	int IncreaseTreeDepth = 0;
@@ -1364,7 +1462,7 @@
 						     new_clusters,
 						     eb2_bh,
 						     &new_eb_blkno,
-						     handle, inode);
+						     handle, inode, meta_ac);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
 			goto finally;
@@ -1478,7 +1576,7 @@
 
 		status = ocfs_grow_extent_tree(osb, fe_bh, handle,
 					       blkno, new_clusters,
-					       inode);
+					       inode, meta_ac);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
 			goto finally;
@@ -1719,7 +1817,7 @@
 free_meta:
 		/* Free the metadata associated with this extent group */
 		status = ocfs_handle_add_commit_bits(handle, 1,
-						     cur_eb->h_suballoc_blkno << osb->sb->s_blocksize_bits,
+						     cur_eb->h_suballoc_bit,
 						     cur_eb->h_suballoc_node,
 						     DISK_ALLOC_EXTENT_NODE);
 		if (status < 0) {
@@ -2159,7 +2257,7 @@
 				LOG_TRACE_ARGS("Popping this header (%llu)\n",
 					       alloc_eb->h_blkno);
 
-				status = ocfs_handle_add_commit_bits(handle, 1, alloc_eb->h_suballoc_blkno << osb->sb->s_blocksize_bits, alloc_eb->h_suballoc_node, DISK_ALLOC_EXTENT_NODE);
+				status = ocfs_handle_add_commit_bits(handle, 1, alloc_eb->h_suballoc_bit, alloc_eb->h_suballoc_node, DISK_ALLOC_EXTENT_NODE);
 				if (status < 0) {
 					LOG_ERROR_STATUS (status);
 					goto bail;
@@ -2862,465 +2960,533 @@
 	return (status);
 }				/* ocfs_get_leaf_extent */
 
+void ocfs_free_alloc_context(ocfs2_alloc_context *ac)
+{
+	if (ac->ac_inode)
+		iput(ac->ac_inode);
+	if (ac->ac_bh)
+		brelse(ac->ac_bh);
+	kfree(ac);
+}
+
 /*
- * ocfs_find_contiguous_space_from_bitmap()
- *
- * This function looks for free space in the volume based on the bitmap.
- * It looks for contiguous space only and if it finds the space available
- * it returns a cluster bitmap offset. Each bit in Cluster bitmap represents
- * memory equal to cluster size (specified during format).
- *
- * TODO: The Bitmap stuff needs to be changed for handling more than 32 bits...
- * Although we can go upto 4k(clustersize) * 8 * 4M(max 32 bits for now...)
- *
- * Returns 0 on success, < 0 on error.
- *
- * Pass in 'lock_bh' and bitmap_inode only if you've already taken the 
- * vol_alloc semaphore, and you've done the acquire_lock on the bitmap.
+ * min_bits - minimum contiguous chunk from this total allocation we
+ * can handle. set to what we asked for originally for a full
+ * contig. allocation, set to '1' to indicate we can deal with extents
+ * of any size.
  */
-static int ocfs_find_contiguous_space_from_bitmap(ocfs_super *osb,
-					   ocfs_journal_handle *handle,
-					   __u64 file_size,
-					   u32 *cluster_off,
-					   u32 *cluster_count,
-					   int sysfile,
-					   struct buffer_head *lock_bh,
-					   struct inode *bitmap_inode)
+int ocfs_claim_bits(ocfs_super *osb, 
+		    ocfs_journal_handle *handle, 
+		    ocfs2_alloc_context *ac,
+		    u32 min_bits,
+		    u32 *bit_off,
+		    u32 *num_bits)
 {
-	int status = 0, startbh, numblocks;
-	u32 bitoffset = 0, ClusterCount = 0;
-	__u64 ByteCount = 0;
-	__u32 LargeAlloc = 0;
-	static __u32 LargeAllocOffset = 0;
-	static __u32 SmallAllocOffset = 0;
-	struct buffer_head *bh = NULL;
-	ocfs2_dinode *bm_lock;
-	__u32 bitmapblocks; /* we only care about the valid blocks */
-	int local_lock = 0;
-	int local_inode = 0;
-	__u32 five_percent, free_bits;
+	int status;
 
-	LOG_ENTRY ();
+	LOG_ENTRY();
 
-	OCFS_ASSERT (osb);
+	OCFS_ASSERT(ac);
+	OCFS_ASSERT(ac->ac_bits_given < ac->ac_bits_wanted);
 
-	if ((bitmap_inode && !lock_bh) || (lock_bh && !bitmap_inode))
-		BUG();
+	OCFS_ASSERT(ac->ac_which == OCFS_AC_USE_LOCAL 
+		    || ac->ac_which == OCFS_AC_USE_MAIN);
+	OCFS_ASSERT(ac->ac_handle == handle);
 
-	if (!bitmap_inode) {
-		bitmap_inode = ocfs_get_system_file_inode(osb, GLOBAL_BITMAP_SYSTEM_INODE, -1);
-		if (!bitmap_inode) {
-			status = -EINVAL;
-			LOG_ERROR_STR("Could not get bitmap inode!");
-			goto leave;
-		}
-		local_inode = 1;
+	if (ac->ac_which == OCFS_AC_USE_LOCAL) {
+		status = ocfs_claim_local_bitmap_bits(osb, 
+						      handle, 
+						      ac, 
+						      min_bits,
+						      bit_off, 
+						      num_bits);
+	} else {
+		status = ocfs_claim_main_bitmap_bits(osb, 
+						     handle, 
+						     ac,
+						     min_bits,
+						     bit_off,
+						     num_bits);
 	}
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
 
-	if (lock_bh) {
-		bh = lock_bh;
-	} else { /* local lock */
-		local_lock = 1;
+	ac->ac_bits_given += *num_bits;
 
-		/* Get the allocation lock here */
-		status = ocfs_acquire_lock(osb, OCFS_LKM_EXMODE, 
-					   0, &bh, bitmap_inode);
-		if (status < 0) {
-			if (status != -EINTR)
-				LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-		ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, 
-				      0, bitmap_inode);
-		ocfs_handle_add_inode(handle, bitmap_inode);
+bail:
+	LOG_EXIT_STATUS(status);
+	return(status);
+}
+
+static int ocfs_claim_main_bitmap_bits(ocfs_super *osb,
+				       ocfs_journal_handle *handle,
+				       ocfs2_alloc_context *ac,
+				       u32 min_bits,
+				       u32 *bit_off,
+				       u32 *num_bits)
+{
+	int status, num_blocks;
+	u32 bits_wanted;
+	u32 best_fit_bits;
+	ocfs2_dinode *fe;
+	struct inode *bitmap_inode;
+	struct buffer_head *bh;
+
+	LOG_ENTRY();
+	OCFS_ASSERT(ac->ac_which == OCFS_AC_USE_MAIN);
+
+	bitmap_inode = ac->ac_inode;
+	bits_wanted = ac->ac_bits_wanted;
+	bh = ac->ac_bh;
+	fe = (ocfs2_dinode *) bh->b_data;
+
+	num_blocks = ocfs_blocks_for_bits(osb->sb,
+					  osb->cluster_bitmap.validbits);
+	/* Ok, somewhat lame, but we submit the whole bitmap for reading here*/
+	status = ocfs_read_bhs(osb, osb->bitmap_blkno << osb->sb->s_blocksize_bits, num_blocks << osb->sb->s_blocksize_bits, osb->cluster_bitmap.chunk, OCFS_BH_CACHED, bitmap_inode);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
 	}
 
+	best_fit_bits = bits_wanted;
+	status = ocfs_find_clear_bits (osb, &osb->cluster_bitmap,
+				       bits_wanted, 0, bit_off, 
+				       &best_fit_bits);
+	if (status < 0) {
+		osb->cluster_bitmap.failed++;
+		LOG_TRACE_STR("Running out of space!");
+		goto bail;
+	}
+
+	if (best_fit_bits < min_bits) {
+		LOG_ERROR_ARGS ("Cannot allocate %u contiguous clusters for "
+				"system file\n", min_bits);
+		status = -ENOSPC;
+		goto bail;
+	}
+
+#warning this is not an error
+	if (best_fit_bits != bits_wanted)
+		LOG_ERROR_ARGS("discontiguous allocation done: wanted = %u, "
+			       "best_fit = %u, bit_off = %u!\n", 
+			       bits_wanted, best_fit_bits, *bit_off);
+
+	/* when we do discontig. just change this line. */
+	*num_bits = best_fit_bits;
+
+	/* cool, we've got some. set them now. */
 	status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
-		goto leave;
+		goto bail;
 	}
 
-	bm_lock = (ocfs2_dinode *) bh->b_data;
+	fe->id1.bitmap1.i_used += *num_bits;
 
-	ClusterCount = (u32) ((u64) (file_size + (osb->s_clustersize-1)) >> 
-				osb->s_clustersize_bits);
-	if (ClusterCount == 0) {
-		LOG_ERROR_STR ("DISK_FULL?: ClusterCount==0");
-		status = 0;
-		goto leave;
+	status = ocfs_journal_dirty(handle, bh);
+	if (status < 0) {
+		LOG_ERROR_STATUS (status);
+		goto bail;
 	}
-	ByteCount = (u64)ClusterCount << osb->s_clustersize_bits;
-	if (ByteCount == 0) {
-		LOG_ERROR_STR ("DISK_FULL?: Bytecount==0");
-		status = 0;
-		goto leave;
-	}
 
-	free_bits = le32_to_cpu(bm_lock->id1.bitmap1.i_total) - 
-		le32_to_cpu(bm_lock->id1.bitmap1.i_used);
-	if ( (sysfile && ClusterCount > free_bits) || 
-	     (!sysfile && ClusterCount > 
-	         (free_bits - ((8 * ONE_MEGA_BYTE) >> osb->s_clustersize_bits))) ){
-		LOG_ERROR_ARGS("Disk Full: ClusterCount=%u, free_bits=%u, sysfile=%s\n",
-			       ClusterCount, free_bits, sysfile?"yes":"no");
+	ocfs_set_bits(osb->sb, handle, &osb->cluster_bitmap, *bit_off,
+		      *num_bits);
+	atomic_inc(&osb->alloc_stats.bitmap_data);
+
+#warning "implement this"
+	/* At this point, we should see if local alloc was switched
+	 * off, and turn it back on if we have enough free bits in the
+	 * main bitmap.*/
+	status = 0;
+bail:
+	LOG_EXIT_STATUS(status);
+	return(status);
+}
+
+static int ocfs_claim_local_bitmap_bits(ocfs_super *osb,
+					ocfs_journal_handle *handle,
+					ocfs2_alloc_context *ac,
+					u32 min_bits,
+					u32 *bit_off,
+					u32 *num_bits)
+{
+	int status, start;
+	struct inode *local_alloc_inode;
+	u32 bits_wanted;
+	void *bitmap;
+	ocfs2_dinode *alloc;
+
+	LOG_ENTRY();
+	OCFS_ASSERT(ac->ac_which == OCFS_AC_USE_LOCAL);
+
+	bits_wanted = ac->ac_bits_wanted;
+	local_alloc_inode = ac->ac_inode;
+	alloc = (ocfs2_dinode *) osb->local_alloc_bh->b_data;
+
+	start = ocfs_local_find_clear_bits(osb, alloc, bits_wanted);
+	if (start == -1) {
+		/* TODO: Shouldn't we just BUG here? */
 		status = -ENOSPC;
-		goto leave;
+		LOG_ERROR_STATUS(status);
+		goto bail;
 	}
-	
-	/* This function will check for clear bits in the Bitmap for
-	 * consecutive */
-	/* clear bits equal to ClusterCount */
 
-	/* If we create a chunk that is larger than 5% of the
-	 * disksize, then start */
-	/* allocation at 5%, so that small files stay in the beginning
-	 * as much as possible */
+	bitmap = LOCAL_ALLOC(alloc)->la_bitmap;
+	*bit_off = LOCAL_ALLOC(alloc)->la_bm_off + start;
+	/* local alloc is always contiguous by nature -- we never
+	 * delete bits from it! */
+	*num_bits = bits_wanted;
 
-	five_percent = le32_to_cpu(bm_lock->id1.bitmap1.i_total) / 20;
-	if (ClusterCount > five_percent) {
-		LargeAlloc = 1;
-		LargeAllocOffset = five_percent;
+	status = ocfs_journal_access(handle, osb->local_alloc_bh, 
+				     OCFS_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
 	}
 
-	bitmapblocks =
-		ocfs_blocks_for_bits(osb->sb,
- 				     osb->cluster_bitmap.validbits);
-	
-	/* Ok, somewhat lame, but we submit the whole bitmap for reading here*/
-	if (ocfs_read_bhs(osb, osb->bitmap_blkno << osb->sb->s_blocksize_bits, 
-			  bitmapblocks << osb->sb->s_blocksize_bits,
-			  osb->cluster_bitmap.chunk, OCFS_BH_CACHED, bitmap_inode)) {
-		LOG_ERROR_STATUS(-EIO);
-		goto leave;
+	while(bits_wanted--)
+		set_bit(start++, bitmap);
+
+	status = ocfs_journal_dirty(handle, osb->local_alloc_bh);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
 	}
-	
-	bitoffset = ocfs_find_clear_bits (osb, &osb->cluster_bitmap, 
-					  ClusterCount,
-					  LargeAlloc ? LargeAllocOffset :
-					  SmallAllocOffset, sysfile ? 0 :
-					  ((8 * ONE_MEGA_BYTE) >>
-					   osb->s_clustersize_bits));
 
-	/* if fails we should try again from the beginning of the disk. */
-	/* in the end we pass # of bits we want to keep for system
-	 * file extention only.  */
-	/* Right now if we run out of diskspace, we still have 8mb
-	 * free for a systemfile */
+	status = 0;
+bail:
+	LOG_EXIT_STATUS(status);
+	return(status);
+}
 
-	if (bitoffset == -1 && LargeAlloc) {
-		LOG_TRACE_STR("Running low on diskspace.");
-		osb->cluster_bitmap.failed++;
-		bitoffset = ocfs_find_clear_bits (osb, &osb->cluster_bitmap,
-						  ClusterCount, 0,
-						  sysfile ? 0 :
-						  ((8 * ONE_MEGA_BYTE) >>
-						   osb->s_clustersize_bits));
+/* caller is responsible for freeing 'ac' when he's done with it. */
+int ocfs_reserve_bits(ocfs_super *osb, 
+		      ocfs_journal_handle *handle,
+		      u32 bits_wanted,
+		      ocfs2_alloc_context **ac)
+{
+	int status;
+
+	LOG_ENTRY();
+	OCFS_ASSERT(handle);
+
+	*ac = kmalloc(sizeof(ocfs2_alloc_context), GFP_KERNEL);
+	if (!(*ac)) {
+		status = -ENOMEM;
+		LOG_ERROR_STATUS(status);
+		goto bail;
 	}
+	memset(*ac, 0, sizeof(ocfs2_alloc_context));
+	(*ac)->ac_bits_wanted = bits_wanted;
+	(*ac)->ac_handle = handle;
 
-	/* It returns -1 on failure, otherwise bitoffset points at the */
-	/* location inb bitmap from where there are ClusterCount no of bits */
-	/* are free.  */
+	status = -ENOSPC;
+	if (ocfs_alloc_should_use_local(osb, bits_wanted)) {
+		status = ocfs_reserve_local_bits(osb, 
+						 handle, 
+						 bits_wanted, 
+						 *ac);
+		if ((status < 0) && (status != -ENOMEM)) {
+			LOG_ERROR_STATUS(status);
+			goto bail;
+		}
+		if (status == 0)
+			(*ac)->ac_which = OCFS_AC_USE_LOCAL;
+	}
 
-	if (bitoffset == -1) {
-		if (sysfile)
-			LOG_ERROR_ARGS ("Cannot allocate %u contiguous clusters for system file\n",
-					ClusterCount);
-		status = -ENOSPC;
-		goto leave;
+	if (status == -ENOSPC) {
+		status = ocfs_reserve_main_bitmap_bits(osb, 
+						       handle, 
+						       bits_wanted,
+						       *ac);
+		if (status < 0) {
+			LOG_ERROR_STATUS(status);
+			goto bail;
+		}
+		(*ac)->ac_which = OCFS_AC_USE_MAIN;
 	}
 
-	LOG_TRACE_ARGS ("setting %u bits at bit offset=%u\n", ClusterCount, bitoffset);
+	status = 0;
+bail:
+	if ((status < 0) && *ac) {
+		ocfs_free_alloc_context(*ac);
+		*ac = NULL;
+	}
 
-	ocfs_set_bits(osb->sb, handle, &osb->cluster_bitmap, bitoffset,
-		      ClusterCount);
+	LOG_EXIT_STATUS(status);
+	return(status);
+}
 
-	/* Ok, write out the bitmap now. We optimize only by writing
-	 * out the bitmap blocks which have changed, and not all of
-	 * them like before. */
-	numblocks = ocfs_bitmap_blocks_affected(osb->sb,
-						bitoffset,
-						ClusterCount,
-						&startbh);
+static int ocfs_reserve_main_bitmap_bits(ocfs_super *osb, 
+					 ocfs_journal_handle *handle,
+					 u32 bits_wanted,
+					 ocfs2_alloc_context *ac)
+{
+	int status = 0;
+	struct inode *bitmap_inode;
+	struct buffer_head *bh = NULL;
+	ocfs2_dinode *fe;
+	u32 free_bits;
 
-	LOG_TRACE_ARGS("bitoffset = %u, ClusterCount = %u, startbh = %u, numblocks = %u\n", bitoffset, ClusterCount, startbh, numblocks);
+	LOG_ENTRY();
 
-	/* write the bitmap size info to the lock sector */
-	bm_lock->id1.bitmap1.i_used =
-		ocfs_count_bits(osb->sb, &osb->cluster_bitmap);
+	OCFS_ASSERT(!(handle->flags & OCFS_HANDLE_STARTED));
 
-	status = ocfs_journal_dirty(handle, bh);
+	bitmap_inode = ocfs_get_system_file_inode(osb, 
+						  GLOBAL_BITMAP_SYSTEM_INODE, 
+						  -1);
+	if (!bitmap_inode) {
+		status = -EINVAL;
+		LOG_ERROR_STR("Could not get bitmap inode!");
+		goto bail;
+	}
+
+	status = ocfs_acquire_lock(osb, OCFS_LKM_EXMODE, 
+				   0, &bh, bitmap_inode);
 	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
+		if (status != -EINTR)
+			LOG_ERROR_STATUS (status);
+		goto bail;
 	}
+	ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, 
+			     0, bitmap_inode);
+	ocfs_handle_add_inode(handle, bitmap_inode);
 
-	*cluster_off = bitoffset;
-	*cluster_count = ClusterCount;
-	status = 0;
+	fe = (ocfs2_dinode *) bh->b_data;
+	free_bits = le32_to_cpu(fe->id1.bitmap1.i_total) - 
+		le32_to_cpu(fe->id1.bitmap1.i_used);
 
-leave:
-	if (local_lock && bh)
-		brelse(bh);
+	if (bits_wanted > free_bits) {
+		LOG_ERROR_ARGS("Disk Full: wanted=%u, free_bits=%u\n",
+			       bits_wanted, free_bits);
+		status = -ENOSPC;
+		goto bail;
+	}
 
-	if (local_inode)
+	/* Ok, done - we've determined that there's enough space in
+	 * the bitmap. Actually finding it is the job of the
+	 * allocation function now. We keep things locked so that the
+	 * bitmap can't change underneath us. */
+	ac->ac_inode = igrab(bitmap_inode);
+	get_bh(bh);
+	ac->ac_bh = bh;
+
+bail:
+	if (bitmap_inode)
 		iput(bitmap_inode);
+	if (bh)
+		brelse(bh);
 
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_find_contiguous_space_from_bitmap */
+	LOG_EXIT_STATUS(status);
+	return(status);
+}
 
-/*
- * ocfs_alloc_node_block()
+/* 
+ * ocfs_reserve_local_bits
  *
- * You need to be holding node_alloc_sem!
+ * make sure we've got at least bitswanted contiguous bits in the
+ * local alloc. You lose them when you drop ip_io_sem.
+ * 
+ * We will add ourselves to the transaction passed in, but may start
+ * our own in order to shift windows.
+ *
+ * When we stop being lame and support multiple chunks of
+ * discontiguous space, we this turns into a really simple check of
+ * ->la_bits_set
  */
-int ocfs_alloc_node_block(ocfs_super *osb, __u64 bytes_wanted,
-			  __u64 *DiskOffset, __u64 *file_off,
-			  __u32 NodeNum, __u32 Type,
-			  ocfs_journal_handle *handle)
+static int ocfs_reserve_local_bits(ocfs_super *osb, 
+				   ocfs_journal_handle *passed_handle,
+				   u32 bits_wanted,
+				   ocfs2_alloc_context *ac)
 {
-	int status = 0;
-	int startbh, numblocks;
-	__u64 fileSize = 0;
-	__u64 numBytes = 0;
-	__u64 allocSize = 0;
-	__u64 prevFileSize = 0;
-	__u64 extent;
-	__u64 newFileSize;
-	__u64 bitMapSize;
-	ocfs_alloc_bm bitmap;
-	__u32 numBits = 0;
-	__u32 foundBit = -1;
-	__u32 blockSize = 0, blockSizeBits = 0;
-	int bm_file = 0;
-	int alloc_file = 0;
-	struct buffer_head *bh = NULL;
-	struct buffer_head *alloc_bh = NULL;
-	ocfs2_dinode *fe = NULL;
-	ocfs2_dinode *alloc_fe = NULL;
-	int needs_uninit = 0;
-	int delay_lockrel = 0;
-	struct inode *inode = NULL; /* alloc bitmap file inode */
-	struct inode *alloc_inode = NULL; /* alloc file inode */
+	int status;
+	struct inode *local_alloc_inode = NULL;
+	int startoff;
+	ocfs2_dinode *alloc;
 
-	LOG_ENTRY_ARGS("(bytes_wanted = (%llu), Type=%d)\n", bytes_wanted,Type);
+	LOG_ENTRY();
 
-	switch (Type) {
-		case DISK_ALLOC_EXTENT_NODE:
-			bm_file = EXTENT_ALLOC_BITMAP_SYSTEM_INODE;
-			alloc_file = EXTENT_ALLOC_SYSTEM_INODE;
-			blockSize = osb->sb->s_blocksize;
-			blockSizeBits = osb->sb->s_blocksize_bits;
-			atomic_inc(&osb->alloc_stats.ext_allocs);
-			break;
-		case DISK_ALLOC_INODE:
-			bm_file = INODE_ALLOC_BITMAP_SYSTEM_INODE;
-			alloc_file = INODE_ALLOC_SYSTEM_INODE;
-			blockSize = osb->sb->s_blocksize;
-			blockSizeBits = osb->sb->s_blocksize_bits;
-			atomic_inc(&osb->alloc_stats.inode_allocs);
-			break;
-		default:
-			status = -EINVAL;
-			LOG_ERROR_STATUS(status);
-			goto leave;
+	OCFS_ASSERT(passed_handle);
+	OCFS_ASSERT(ac);
+	OCFS_ASSERT(!(passed_handle->flags & OCFS_HANDLE_STARTED));
+
+	if (!osb->have_local_alloc) {
+		status = -ENOSPC;
+		goto bail;
 	}
 
-	inode = ocfs_get_system_file_inode(osb, bm_file, NodeNum);
-	if (!inode) {
-		LOG_ERROR_STATUS(status=-EINVAL);
-		goto leave;
+#warning "isn't it about time we turned this check off?"
+	if (bits_wanted > ocfs_clusters_for_bytes(osb->sb, 
+						 OCFS_LOCAL_ALLOC_MAX_ALLOC)) {
+		LOG_TRACE_STR("Asking for more than max local alloction!\n");
+		status = -ENOSPC;
+		goto bail;
 	}
-	alloc_inode = ocfs_get_system_file_inode(osb, alloc_file, NodeNum);
-	if (!alloc_inode) {
-		LOG_ERROR_STATUS(status=-EINVAL);
-		goto leave;
+
+	if (bits_wanted > ocfs_local_alloc_window_bits(osb)) {
+		LOG_TRACE_STR("Asking for more than my max window size!\n");
+		status = -ENOSPC;
+		goto bail;
 	}
 
-	/* Allocate a block of size blocksize from the relevant file/bitmap */
-	OCFS_ASSERT (blockSize);
+	local_alloc_inode = 
+		ocfs_get_system_file_inode(osb, 
+					   LOCAL_ALLOC_SYSTEM_INODE,
+					   osb->node_num);
+	if (!local_alloc_inode) {
+		status = -ENOENT;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+	ocfs_handle_add_inode(passed_handle, local_alloc_inode);
 
-	status = ocfs_acquire_lock (osb, OCFS_LKM_EXMODE,
-			     0, &bh, inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
+	alloc = (ocfs2_dinode *) osb->local_alloc_bh->b_data;
+	startoff = ocfs_local_find_clear_bits(osb, alloc, bits_wanted);
+	if (startoff == -1) {
+		/* uhoh, window change time. */
+		status = 
+			ocfs_local_alloc_full_window_change(osb, 
+							    local_alloc_inode);
+		if (status < 0) {
+			LOG_ERROR_STATUS(status);
+			goto bail;
+		}
 	}
-	ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, 
-			     0, inode);
-	ocfs_handle_add_inode(handle, inode);
 
-	numBits = ((bytes_wanted + (blockSize-1)) >> blockSizeBits);
-	numBytes = (u64)numBits << blockSizeBits;
+	ac->ac_inode = igrab(local_alloc_inode);
+	get_bh(osb->local_alloc_bh);
+	ac->ac_bh = osb->local_alloc_bh;
 
-	/* Read in the bitmap file for the alloc and look for the
-	 * required space, if found */
-	fe = (ocfs2_dinode *) bh->b_data;
-	prevFileSize = fileSize = fe->i_size;
-	allocSize = (u64)fe->i_clusters << osb->s_clustersize_bits;
+	status = 0;
+bail:
+	if (local_alloc_inode)
+		iput(local_alloc_inode);
 
-	if ((fileSize != 0) && (allocSize != 0)) {
-		ocfs_initialize_bitmap(osb->sb, &bitmap,
-				       (__u32)fileSize * 8,
-				       (__u32)allocSize * 8);
-		needs_uninit = 1;
+	LOG_EXIT_STATUS(status);
+	return(status);
+}
 
-		status = ocfs_read_system_file(osb, bm_file, NodeNum,
-					       bitmap.chunk, allocSize);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
+/*
+ * ocfs_find_contiguous_space_from_bitmap()
+ *
+ * Used only from local alloc right now. Eventually will go away, so
+ * don't add more callers to this function. Use the reserve / claim
+ * apis instead as they'll even get you distcongiuous areas.
+ *
+ * TODO: The Bitmap stuff needs to be changed for handling more than 32 bits...
+ * Although we can go upto 4k(clustersize) * 8 * 4M(max 32 bits for now...)
+ *
+ * Returns 0 on success, < 0 on error.
+ */
+static int ocfs_find_contiguous_space_from_bitmap(ocfs_super *osb,
+					   ocfs_journal_handle *handle,
+					   __u64 file_size,
+					   u32 *cluster_off,
+					   u32 *cluster_count,
+					   struct buffer_head *bh,
+					   struct inode *bitmap_inode)
+{
+	int status = 0, startbh, numblocks;
+	u32 bitoffset = 0, num_clusters = 0;
+	ocfs2_dinode *bm_lock;
+	__u32 bitmapblocks; /* we only care about the valid blocks */
+	__u32 free_bits;
 
-		foundBit = ocfs_find_clear_bits(osb, &bitmap, numBits, 0, 0);
-	}
+	LOG_ENTRY ();
 
-	/* It returns -1 on failure , otherwise ByteOffset points at the */
-	/* location in bitmap from where there are ClusterCount no of bits */
-	/* are free. */
+	OCFS_ASSERT(osb);
+	OCFS_ASSERT(bh);
+	OCFS_ASSERT(bitmap_inode);
+	OCFS_ASSERT(handle);
 
-	if (foundBit == -1) {
-		/* if not found add more allocation to the file and try again. */
-		//extent = ONE_MEGA_BYTE;
-		extent = ( ((numBits * blockSize) + (ONE_MEGA_BYTE-1)) >> 20 ) << 20;
+	status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto leave;
+	}
 
-#warning maybe take this out and put a verifyupdateinode in here
-		status = ocfs_read_bh(osb,
-				      OCFS_I(alloc_inode)->ip_blkno << alloc_inode->i_sb->s_blocksize_bits, 
-			&alloc_bh, OCFS_BH_CACHED, alloc_inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
+	bm_lock = (ocfs2_dinode *) bh->b_data;
 
-		alloc_fe = (ocfs2_dinode *) alloc_bh->b_data;
-		newFileSize = alloc_fe->i_size;
-		allocSize = (u64)alloc_fe->i_clusters << osb->s_clustersize_bits;
-		if (newFileSize != alloc_inode->i_size ||
-		    allocSize != OCFS_I(alloc_inode)->ip_alloc_size) {
-			LOG_ERROR_ARGS("aha! alloc inode was out of date! "
-			       		"newFileSize=%llu, i_size=%llu, "
-			       		"allocSize=%llu, ip_alloc_size=%llu\n",
-			       		newFileSize, alloc_inode->i_size,
-			       		allocSize, OCFS_I(alloc_inode)->ip_alloc_size);
-		}
+	num_clusters = (u32) ((u64) (file_size + (osb->s_clustersize-1)) >> 
+				osb->s_clustersize_bits);
+	if (num_clusters == 0) {
+		LOG_ERROR_STR ("DISK_FULL?: num_clusters==0");
+		status = 0;
+		goto leave;
+	}
 
-		//newFileSize = alloc_inode->i_size;
-		//allocSize = OCFS_I(alloc_inode)->alloc_size;
+	free_bits = le32_to_cpu(bm_lock->id1.bitmap1.i_total) - 
+		le32_to_cpu(bm_lock->id1.bitmap1.i_used);
 
-		/* This is for OUI optimzation to allocate more disk
-		 * space for directory allocations */
-		
-		if (allocSize > 0)
-			extent *= 2;
-		
-		LOG_TRACE_ARGS("extending the alloc file to %llu\n",
-		       newFileSize + extent);
-		status = ocfs_extend_file(osb, newFileSize + extent, 
-					  handle, alloc_inode, NULL, 1,
-					  NULL);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-		
-		newFileSize += extent;
-		bitMapSize = newFileSize >> (blockSizeBits+3);
+	if (num_clusters > free_bits) {
+		LOG_ERROR_ARGS("Disk Full: num_clusters=%u, free_bits=%u\n",
+			       num_clusters, free_bits);
+		status = -ENOSPC;
+		goto leave;
+	}
 
-		/* Does this need the buffer_head? if so, we need to
-		 * do a put_data first! */
-		/* Calculate the new bitmap size */
-		
-		LOG_TRACE_ARGS("extending the bitmap file to %llu\n", bitMapSize);
-		status = ocfs_extend_file(osb, bitMapSize,
-					  handle, inode, NULL, 1, bh);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-		fe = (ocfs2_dinode *) bh->b_data;
-		/* we wrote it back out in ocfs_extend_system_file so
-		 * we can trust the sizes here */
-		fileSize = fe->i_size;
-		allocSize = (u64)fe->i_clusters << osb->s_clustersize_bits;
-		LOG_TRACE_ARGS("fileSize=%llu, allocSize=%llu\n",
-		       fileSize, allocSize);
+	bitmapblocks =
+		ocfs_blocks_for_bits(osb->sb,
+ 				     osb->cluster_bitmap.validbits);
 
-		if (needs_uninit)
-			ocfs_reinitialize_bitmap(osb->sb, &bitmap,
-						 fileSize * 8, 
-						 allocSize * 8);
-		else
-			ocfs_initialize_bitmap(osb->sb, &bitmap,
-					       fileSize * 8, 
-					       allocSize * 8);
-		needs_uninit = 1;
+	/* Ok, somewhat lame, but we submit the whole bitmap for reading here*/
+	if (ocfs_read_bhs(osb, osb->bitmap_blkno << osb->sb->s_blocksize_bits, 
+			  bitmapblocks << osb->sb->s_blocksize_bits,
+			  osb->cluster_bitmap.chunk, OCFS_BH_CACHED, bitmap_inode)) {
+		LOG_ERROR_STATUS(-EIO);
+		goto leave;
+	}
 
-		status = ocfs_read_system_file(osb, bm_file, NodeNum, 
-					       bitmap.chunk, allocSize);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-		
-		foundBit = ocfs_find_clear_bits(osb, &bitmap, numBits, 0, 0);
-
-		delay_lockrel = 1;
-		if (Type == DISK_ALLOC_EXTENT_NODE)
-			atomic_inc(&osb->alloc_stats.ext_extends);
-		else if (Type == DISK_ALLOC_INODE)
-			atomic_inc(&osb->alloc_stats.inode_extends);
+	status = 0;
+	status = ocfs_find_clear_bits (osb, &osb->cluster_bitmap, 
+				       num_clusters,
+				       0, &bitoffset, 
+				       NULL);
+	if (status < 0) {
+		osb->cluster_bitmap.failed++;
+		LOG_ERROR_ARGS("Cannot allocate %u contiguous clusters"
+			       "for system file\n", num_clusters);
+		status = -ENOSPC;
+		goto leave;
 	}
 
-	LOG_TRACE_ARGS ("bit offset=%d, num=%d\n", foundBit, numBits);
+	LOG_TRACE_ARGS ("setting %u bits at bit offset=%u\n", 
+			num_clusters, bitoffset);
 
-	ocfs_set_bits(osb->sb, handle, &bitmap, foundBit, numBits);
+	ocfs_set_bits(osb->sb, handle, &osb->cluster_bitmap, bitoffset,
+		      num_clusters);
 
-	/* only write out what has changed... */
+	/* Ok, write out the bitmap now. We optimize only by writing
+	 * out the bitmap blocks which have changed, and not all of
+	 * them like before. */
 	numblocks = ocfs_bitmap_blocks_affected(osb->sb,
-						foundBit,
-						numBits,
+						bitoffset,
+						num_clusters,
 						&startbh);
 
-	LOG_TRACE_ARGS ("offset=%u, type=%x, blksz=%u, foundbit=%u, fileid=%u\n",
-			foundBit * blockSize, Type, blockSize, foundBit, alloc_file);
+	LOG_TRACE_ARGS("bitoffset = %u, num_clusters = %u, startbh = %u, numblocks = %u\n", bitoffset, num_clusters, startbh, numblocks);
 
-	status = ocfs_lookup_file_allocation(osb, foundBit * blockSize, 
-					     DiskOffset, osb->sb->s_blocksize, NULL,
-					     alloc_inode, 1);
-	if (status < 0 || *DiskOffset == 0) {
-		if (!status)
-			status = -EINVAL;
-		LOG_ERROR_STATUS(status);
+	/* write the bitmap size info to the lock sector */
+	bm_lock->id1.bitmap1.i_used =
+		ocfs_count_bits(osb->sb, &osb->cluster_bitmap);
+
+	status = ocfs_journal_dirty(handle, bh);
+	if (status < 0) {
+		LOG_ERROR_STATUS (status);
 		goto leave;
 	}
 
-	*file_off = (__u64) ((__u64) foundBit * (__u64) blockSize);
+	*cluster_off = bitoffset;
+	*cluster_count = num_clusters;
+	status = 0;
 
-	/* this can just fall through */
-	if (*file_off == 0) {
-		LOG_TRACE_ARGS ("offset=%llu, type=%x, blksz=%u, foundbit=%u\n",
-			*file_off, Type, blockSize, foundBit);
-	}
-
 leave:
-	if (needs_uninit)
-		ocfs_uninitialize_bitmap(&bitmap);
-
-	if (inode)
-		iput(inode);
-	if (alloc_inode)
-		iput(alloc_inode);
-
-	if (bh != NULL)
-		brelse(bh);
-	if (alloc_bh != NULL)
-		brelse(alloc_bh);
-
 	LOG_EXIT_STATUS (status);
 	return status;
-}				/* ocfs_alloc_node_block */
+}				/* ocfs_find_contiguous_space_from_bitmap */
 
 /*
  * ocfs_free_file_extents()
@@ -3402,11 +3568,6 @@
  * local alloc bitmaps. These are intended to be easily
  * tunable. Possibly even remove them once we've found a good mix. */
 
-/* The largest cluster size where we even consider using local alloc. */
-#define OCFS_LOCAL_ALLOC_MAX_CSIZE    (128 * 1024)
-/* The largest allocation to use the local bitmap for. */
-#define OCFS_LOCAL_ALLOC_MAX_ALLOC    (2 * 1024 * 1024)
-
 /* 
  * ocfs_local_alloc_window_bits
  * 
@@ -3442,6 +3603,15 @@
 	return(numbits);
 } /* ocfs_local_alloc_window_bits */
 
+static inline int ocfs_alloc_should_use_local(ocfs_super *osb, u64 bits)
+{
+	if (osb->have_local_alloc 
+	    && ((bits<<osb->s_clustersize_bits) <= OCFS_LOCAL_ALLOC_MAX_ALLOC)
+	    && (bits <= ocfs_local_alloc_window_bits(osb)))
+		return(1);
+	return(0);
+}
+
 /*
  * ocfs_alloc_count_bits
  */
@@ -3670,8 +3840,9 @@
 	status = ocfs_find_contiguous_space_from_bitmap(osb, handle, 
 							alloc_bytes, 
 							&cluster_off, 
-							&cluster_count, 0, 
-							lock_bh, bm_inode);
+							&cluster_count,
+							lock_bh, 
+							bm_inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto bail;
@@ -3763,237 +3934,94 @@
 	return(bitoff);
 } /* ocfs_local_find_clear_bits */
 
-/*
- * ocfs_find_space_from_local
- */
-static int ocfs_find_space_from_local(ocfs_super *osb, u32 bitswanted, 
-				      u32 *bitoff, u32 *bitcount, 
-				      ocfs_journal_handle *handle)
+/* Note that we do *NOT* lock the local alloc inode here as
+ * it's been locked already for us. */
+static int ocfs_local_alloc_full_window_change(ocfs_super *osb, 
+					       struct inode *local_alloc_inode)
 {
-	ocfs2_dinode *alloc;
-	int status = 0, tmpstat;
-	int startoff, tmpoff;
-	__u32 tmpwanted;
-	/* main bitmap variables. */
+	int status = 0;
 	struct buffer_head *main_bm_bh = NULL;
 	struct inode *main_bm_inode = NULL;
-	void *bitmap;
+	ocfs_journal_handle *handle = NULL;
+	ocfs2_dinode *alloc;
 
-	LOG_ENTRY_ARGS("(bitswanted = %u)\n", bitswanted);
+	LOG_ENTRY();
 
-	if (!osb->have_local_alloc) {
-		status = -ENOSPC;
+	main_bm_inode = ocfs_get_system_file_inode(osb, 
+						   GLOBAL_BITMAP_SYSTEM_INODE, 
+						   -1);
+	if (!main_bm_inode) {
+		status = -EINVAL;
+		LOG_ERROR_STATUS (status);
 		goto bail;
 	}
 
-	if (bitswanted > ocfs_local_alloc_window_bits(osb)) {
-		LOG_TRACE_STR("Asking for more than my max window size!\n");
-		status = -ENOSPC;
+	handle = ocfs_alloc_handle(osb);
+	if (!handle) {
+		status = -ENOMEM;
+		LOG_ERROR_STATUS (status);
 		goto bail;
 	}
 
+	/* Get the allocation lock here */
+	status = ocfs_acquire_lock(osb, OCFS_LKM_EXMODE, 
+				   0, &main_bm_bh, main_bm_inode);
+	if (status < 0) {
+		main_bm_bh = NULL;
+		if (status != -EINTR)
+			LOG_ERROR_STATUS (status);
+		goto bail;
+	}
+	ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, 
+			     0, main_bm_inode);
+	ocfs_handle_add_inode(handle, main_bm_inode);
+
+	handle = ocfs_start_trans(osb, handle, OCFS_WINDOW_MOVE_CREDITS);
+	if (!handle) {
+		status = -ENOMEM;
+		LOG_ERROR_STATUS (status);
+		goto bail;
+	}
+
 	status = ocfs_journal_access(handle, osb->local_alloc_bh, 
 				     OCFS_JOURNAL_ACCESS_WRITE);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto bail;
 	}
-
 	alloc = (ocfs2_dinode *) osb->local_alloc_bh->b_data;
-tryagain:
-	/* If we need to initialize a new window, do so now. */
-	if (LOCAL_ALLOC(alloc)->la_bm_bits == 0) {
-		LOG_TRACE_STR("Allocating a new window...");
 
-		status = ocfs_alloc_new_window(osb, main_bm_bh, main_bm_inode, 
-					       handle);
-		if (status < 0) {
-			if (status != -ENOSPC)
-				LOG_ERROR_STATUS(status);
-
-			/* it may not have been dirtied yet... */
-			tmpstat = ocfs_journal_dirty(handle, 
-						     osb->local_alloc_bh);
-			if (tmpstat < 0)
-				LOG_ERROR_STATUS(tmpstat);
-
-			goto bail;
-		}
-		atomic_inc(&osb->alloc_stats.moves);
+	status = ocfs_sync_local_to_main(osb, handle, alloc, main_bm_inode);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
 	}
 
-	/* Alright, try to satisfy the request. */
-	startoff = ocfs_local_find_clear_bits(osb, alloc, bitswanted);
-	if (startoff == -1) {
-		/* we couldn't get enough bits from the local
-		 * alloc. Lets sync what we've got to the main bitmap,
-		 * clear the local out and try again. */
-		LOG_TRACE_STR("Could not find enough contiguous bits in local "
-			      "alloc bitmap, trying to move my window.");
+	ocfs_clear_local_alloc(alloc);
 
-		if (!main_bm_inode)
-			main_bm_inode = ocfs_get_system_file_inode(osb, GLOBAL_BITMAP_SYSTEM_INODE, -1);
-
-		if (!main_bm_inode) {
-			status = -EINVAL;
-			LOG_ERROR_STATUS (status);
-			goto bail;
-		}
-
-		/* Get the allocation lock here */
-		status = ocfs_acquire_lock(osb, OCFS_LKM_EXMODE, 
-					   0, &main_bm_bh, main_bm_inode);
-		if (status < 0) {
-			main_bm_bh = NULL;
-			if (status != -EINTR)
-				LOG_ERROR_STATUS (status);
-			goto bail;
-		}
-		ocfs_handle_add_lock(handle, OCFS_LKM_EXMODE, 
-				     0, main_bm_inode);
-		ocfs_handle_add_inode(handle, main_bm_inode);
-
-		status = ocfs_sync_local_to_main(osb, handle, alloc,
-						 main_bm_inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS(status);
-			goto bail;
-		}
-
-		ocfs_clear_local_alloc(alloc);
-
-		goto tryagain;
-	}
-
-	LOG_TRACE_ARGS("Found %u bits, starting at local alloc offset %d\n",
-		       bitswanted, startoff);
-
-	/* Ok, if we've got this far then the search suceeded and we
-	 * can mark the bitmap. */
-	bitmap = LOCAL_ALLOC(alloc)->la_bitmap;
-	tmpoff = startoff;
-	tmpwanted = bitswanted;
-	while(tmpwanted--) {
-		/* LOG_TRACE_ARGS("setting bit %d\n", tmpoff); */
-		set_bit(tmpoff++, bitmap);
-	}
-	LOCAL_ALLOC(alloc)->la_bits_set += bitswanted;
-
-	*bitoff = LOCAL_ALLOC(alloc)->la_bm_off + startoff;
-	*bitcount = bitswanted;
-
 	status = ocfs_journal_dirty(handle, osb->local_alloc_bh);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto bail;
 	}
-bail:
-	/* if we locked the main bitmap, cleanup after ourselves. */
-	if (main_bm_bh)
-		brelse(main_bm_bh);
 
-	if (main_bm_inode)
-		iput(main_bm_inode);
-
-	LOG_EXIT_STATUS(status);
-	return(status);
-} /* ocfs_find_space_from_local */
-
-
-/*
- * ocfs_find_space
- *
- * A drop-in replacement for
- * ocfs_find_contiguous_space_from_bitmap. We will in fact, call
- * ocfs_find_contiguous_space_from_bitmap if you don't give us a
- * journal handle, or if the local bitmap isn't loaded, or if the
- * allocation is simply to big to fit in the local one. otherwise,
- * we'll try to use our local alloc instead.
- *
- */
-int ocfs_find_space(ocfs_super *osb, __u64 file_size,
-		    u32 *cluster_off, u32 *cluster_count, int sysfile,
-		    ocfs_journal_handle *handle)
-{
-	int status = 0;
-	u32 bitswanted;
-	int use_global = 1;
-	struct inode *local_alloc_inode = NULL;
-
-	LOG_ENTRY_ARGS("(file_size = (%llu), handle = 0x%p, sysfile = %s)\n", 
-		       file_size, handle, sysfile ? "true" : "false");
-
-	if (file_size == 0) {
-		LOG_ERROR_STR ("asking for an allocation of zero bytes...");
-		status = 0;
+	status = ocfs_alloc_new_window(osb, main_bm_bh, main_bm_inode, handle);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
 		goto bail;
 	}
 
-	/* need to calculate a couple of things for below... */
-	bitswanted = ocfs_clusters_for_bytes(osb->sb, file_size);
+	atomic_inc(&osb->alloc_stats.moves);
 
-	/* Ok, now decide if we can use local alloc bitmap.
-	 * We *always* use global bitmap for clustersize > 128k,
-	 * file_size > 2mb, so force it under these conditions. */
-	if (handle 
-	    && osb->have_local_alloc
-	    && file_size <= OCFS_LOCAL_ALLOC_MAX_ALLOC) {
-		use_global = 0;
-
-		local_alloc_inode = 
-			ocfs_get_system_file_inode(osb, 
-						   LOCAL_ALLOC_SYSTEM_INODE,
-						   osb->node_num);
-
-		if (!local_alloc_inode) {
-			status = -EFAIL;
-			LOG_ERROR_STATUS(status);
-			goto bail;
-		}
-		ocfs_handle_add_inode(handle, local_alloc_inode);
-
-		/* If the local alloc has been disabled while we were
-		 * waiting for another process to finish with it, then
-		 * find_space_from_local will return -ENOSPC and we'll
-		 * continue with the global. */
-		status = ocfs_find_space_from_local(osb, bitswanted, 
-						    cluster_off, cluster_count,
-						    handle);
-		/* If we've run out of space for our local alloc, lets
-		 * try the global one just in case... */
-		if (status == -ENOSPC)
-			use_global = 1;
-		else if (status < 0) {
-			LOG_ERROR_STATUS(status);
-			goto bail;
-		}
-		atomic_inc(&osb->alloc_stats.local_data);
-	}
-
-	if (use_global) {
-		status = ocfs_find_contiguous_space_from_bitmap(osb, handle, 
-								file_size,
-								cluster_off, 
-								cluster_count, 
-								sysfile, NULL,
-								NULL);
-		if (!status)
-			atomic_inc(&osb->alloc_stats.bitmap_data);
-
-	}
-
-	if (status < 0)
-		LOG_ERROR_STATUS(status);
-
-	LOG_TRACE_ARGS("Returning *cluster_off = %u, *cluster_count"
-		       "= %u\n", *cluster_off, *cluster_count);
+	ocfs_commit_trans(handle);
+	status = 0;
 bail:
-	if (local_alloc_inode)
-		iput(local_alloc_inode);
+	if ((status < 0) && handle)
+		ocfs_abort_trans(handle);
 
 	LOG_EXIT_STATUS(status);
 	return(status);
-} /* ocfs_find_space */
+}
 
 /* 
  * ocfs_load_local_alloc 

Modified: branches/dlm-changes/src/alloc.h
===================================================================
--- branches/dlm-changes/src/alloc.h	2004-09-24 23:19:23 UTC (rev 1487)
+++ branches/dlm-changes/src/alloc.h	2004-09-24 23:29:44 UTC (rev 1488)
@@ -33,17 +33,12 @@
 				 ocfs_bitmap_free_head *f,
 				 __u32 len, __u32 fileoff,
 				 __u32 nodenum, __u32 type);
+struct _ocfs2_alloc_context;
 int ocfs_allocate_extent(ocfs_super *osb, struct buffer_head *fe_bh,
 			 ocfs_journal_handle *handle,
 			 u64 blkno, u32 new_clusters,
-			 struct inode *inode);
-int ocfs_alloc_node_block(ocfs_super *osb, __u64 FileSize,
-			  __u64 *DiskOffset, __u64 *file_off,
-			  __u32 NodeNum, __u32 Type,
-			  ocfs_journal_handle *handle);
-int ocfs_find_space(ocfs_super *osb, __u64 file_size,
-		    u32 *cluster_off, u32 *cluster_count, int sysfile,
-		    ocfs_journal_handle *handle);
+			 struct inode *inode, 
+			 struct _ocfs2_alloc_context *meta_ac);
 int ocfs_free_extents_for_truncate(ocfs_super *osb,
 				   ocfs2_dinode *fe,
 				   ocfs_journal_handle *handle,
@@ -67,4 +62,40 @@
 			     ocfs_bitmap_free_head **bits_to_free);
 void ocfs_shutdown_local_alloc(ocfs_super *osb);
 
+typedef struct _ocfs2_alloc_context {
+	struct inode *ac_inode;    /* which bitmap are we allocating from? */
+	struct buffer_head *ac_bh; /* file entry bh */
+	u32    ac_bits_wanted;
+	u32    ac_bits_given;
+#define OCFS_AC_USE_LOCAL 1
+#define OCFS_AC_USE_MAIN  2
+#define OCFS_AC_USE_INODE 3
+#define OCFS_AC_USE_META  4
+	u32    ac_which;
+	ocfs_journal_handle *ac_handle; /* debugging mostly. */
+} ocfs2_alloc_context;
+
+void ocfs_free_alloc_context(ocfs2_alloc_context *ac);
+static inline int ocfs_alloc_context_bits_left(ocfs2_alloc_context *ac)
+{
+	return(ac->ac_bits_wanted - ac->ac_bits_given);
+}
+int ocfs_reserve_bits(ocfs_super *osb, 
+		      ocfs_journal_handle *handle,
+		      u32 bits_wanted,
+		      ocfs2_alloc_context **ac);
+int ocfs_claim_bits(ocfs_super *osb, 
+		    ocfs_journal_handle *handle, 
+		    ocfs2_alloc_context *ac,
+		    u32 min_bits,
+		    u32 *bit_off,
+		    u32 *num_bits);
+int ocfs_num_free_extents(ocfs_super *osb, 
+			  struct inode *inode,
+			  ocfs2_dinode *fe);
+/* how many new metadata chunks would an allocation need at maximum? */
+static inline int ocfs2_extend_meta_needed(ocfs2_dinode *fe)
+{
+	return(fe->id2.i_list.l_tree_depth + 2);
+}
 #endif /* OCFS2_ALLOC_H */



More information about the Ocfs2-commits mailing list