[Ocfs2-commits] mfasheh commits r943 - in branches/new-dir-format/src: . inc

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Wed May 26 20:07:48 CDT 2004


Author: mfasheh
Date: 2004-05-26 19:07:46 -0500 (Wed, 26 May 2004)
New Revision: 943

Modified:
   branches/new-dir-format/src/Makefile
   branches/new-dir-format/src/alloc.c
   branches/new-dir-format/src/bitmap.c
   branches/new-dir-format/src/file.c
   branches/new-dir-format/src/hash.c
   branches/new-dir-format/src/inc/io.h
   branches/new-dir-format/src/inc/journal.h
   branches/new-dir-format/src/inc/ocfs.h
   branches/new-dir-format/src/inc/proto.h
   branches/new-dir-format/src/inode.c
   branches/new-dir-format/src/journal.c
   branches/new-dir-format/src/namei.c
   branches/new-dir-format/src/osb.c
   branches/new-dir-format/src/sysfile.c
Log:
* sync new-dir-format with trunk as of yesterday

* Fix a bug where the file type wasn't being properly set in
  ocfs_add_entry()

* Clean up the ocfs_file_entry structure a bit.



Modified: branches/new-dir-format/src/Makefile
===================================================================
--- branches/new-dir-format/src/Makefile	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/Makefile	2004-05-27 00:07:46 UTC (rev 943)
@@ -64,6 +64,9 @@
 #GLOBAL_DEFINES += -DVERBOSE_BH_SEM
 #GLOBAL_DEFINES += -DBH_SEM_DEBUG
 
+#off by default as it's expensive
+#GLOBAL_DEFINES += -DBH_SEM_LEAK_CHECKING
+
 ifneq ($(OCFS_PROCESSOR),ia64)
 #GLOBAL_DEFINES += -DOCFS_DBG_TIMING
 endif
@@ -222,7 +225,7 @@
 
 build-modules:
 	$(MAKE) -C $(KDIR) SUBDIRS=$(CURDIR) modules
-	
+
 endif # OCFS_KERNEL_2_6
 
 INSTALL_RULES = install-ocfs

Modified: branches/new-dir-format/src/alloc.c
===================================================================
--- branches/new-dir-format/src/alloc.c	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/alloc.c	2004-05-27 00:07:46 UTC (rev 943)
@@ -36,6 +36,27 @@
 /* Tracing */
 #define OCFS_DEBUG_CONTEXT    OCFS_DEBUG_CONTEXT_ALLOC
 
+/* Remove this after the bh_sem hash is removed. */
+static inline int ocfs_ugly_hack(ocfs_journal_handle *handle,
+				 struct buffer_head *bh)
+{
+	int status = 0;
+	status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		LOG_ERROR_STATUS (status);
+		return(status);
+	}
+	OCFS_BH_GET_DATA_WRITE(bh);
+	OCFS_BH_PUT_DATA(bh);
+	status = ocfs_journal_dirty(handle, bh);
+	if (status < 0) {
+		LOG_ERROR_STATUS (status);	
+		return(status);
+	}
+
+	return(status);
+}
+
 static int ocfs_kill_this_tree(ocfs_super *osb, struct buffer_head *extent_grp_bh, 
 			       ocfs_journal_handle *handle, struct inode *inode);
 static int ocfs_allocate_new_data_node (ocfs_super * osb, 
@@ -52,7 +73,8 @@
 static int _squish_extent_entries(ocfs_super *osb, ocfs_alloc_ext *extarr, 
 				  __u8 *freeExtent, 
 				  ocfs_journal_handle *handle,
-				  __u64 FileSize, int flag, struct inode *inode) ;
+				  __u64 FileSize, int flag, 
+				  struct inode *inode);
 
 static int ocfs_fix_extent_group(ocfs_super *osb, struct buffer_head *group_bh, struct inode *inode);
 
@@ -64,12 +86,14 @@
 
 static int ocfs_update_last_ext_ptr(ocfs_super *osb, ocfs_file_entry *fe, struct inode *inode);
 
-static int ocfs_free_vol_block (ocfs_super * osb, ocfs_free_rec * FreeLog, 
-				__u32 NodeNum, __u32 Type);
+static int ocfs_free_vol_block (ocfs_super * osb, ocfs_journal_handle *handle,
+				ocfs_free_rec * FreeLog, __u32 NodeNum, 
+				__u32 Type);
 
 static int ocfs_free_disk_bitmap (ocfs_super * osb, ocfs_free_rec *free_log);
 
 static inline int ocfs_free_main_bitmap(ocfs_super *osb, 
+					ocfs_journal_handle *handle, 
 					ocfs_free_rec *freelog);
 
 static int ocfs_alloc_new_window(ocfs_super *osb, struct buffer_head *lock_bh,
@@ -78,8 +102,6 @@
 static int ocfs_sync_local_to_main(ocfs_super *osb, 
 				   ocfs_bitmap_free_head **f, 
 				   struct buffer_head *local_alloc_bh, 
-				   struct buffer_head *bm_lock_bh,
-				   struct inode *bm_inode,
 				   int in_recovery);
 static __u32 ocfs_alloc_count_bits(ocfs_local_alloc *alloc);
 static void ocfs_clear_local_alloc(ocfs_local_alloc *alloc);
@@ -98,8 +120,6 @@
 	LOG_ENTRY_ARGS("(osb=0x%p, f=0x%p, f->num_logs = %d)\n", osb, f,
 		       f->num_logs);
 
-	ocfs_take_trans_lock(osb);
-
 	list_for_each_safe(p, n, &(f->free_logs)) {
 		LOG_TRACE_ARGS("f->num_logs = %d\n", f->num_logs);
 		log = list_entry(p, ocfs_free_rec, log_list);
@@ -111,8 +131,6 @@
 		f->num_logs--;
 	}
 
-	ocfs_release_trans_lock(osb);
-
 	LOG_EXIT_STATUS(status);
 	return(status);
 }
@@ -192,6 +210,11 @@
 	__u32 tmp_indx;
 	__u64 lock_id;
 	struct buffer_head *globalbh = NULL;
+	ocfs_journal_handle *handle = NULL;
+	int credits = 33; /* one for each potential sysfile fe. This
+			   * goes away when ocfs_ugly_hack goes
+			   * away. */
+	struct buffer_head *ugly_hack_bh = NULL;
 
 	LOG_ENTRY_ARGS ("(0x%p, 0x%p)\n", osb, free_log);
 
@@ -215,11 +238,9 @@
 		extnode_inode[i] = NULL;
 	}
 
-	/* alloc memory */
 	num_upd = free_log->num_updates;
 	for (i = 0; i < num_upd; i++) {
 		switch (free_log->update[i].type) {
-
 		    case DISK_ALLOC_EXTENT_NODE:
 			    node_num = free_log->update[i].node_num;
 			    if (free_ext_node[node_num] == NULL) {
@@ -232,6 +253,8 @@
 				    free_ext_node[node_num]->num_updates = 0;
 			    }
 			    tmp_log = free_ext_node[node_num];
+
+			    credits++;
 			    break;
 
 		    case DISK_ALLOC_VOLUME:
@@ -245,6 +268,9 @@
 				    free_vol_bits->num_updates = 0;
 			    }
 			    tmp_log = free_vol_bits;
+
+			    credits += 1 + free_log->update[i].length / 
+				    OCFS_BITS_IN_CHUNK;
 			    break;
 
 		    default:
@@ -252,6 +278,7 @@
 			    break;
 		}
 
+
 		if (tmp_log) {
 			ocfs_bitmap_update *fb1, *fb2;
 
@@ -269,9 +296,17 @@
 		}
 	}
 
+	/* start the transaction here to preserve ordering with the
+	 * bitmap i_sems... */
+	handle = ocfs_start_trans(osb, credits);
+	if (!handle) {
+		status = -ENOMEM;
+		LOG_ERROR_STATUS(status);
+		goto finally;
+	}
+
 	/* Get all the locks we need. do global bitmap last to
 	 * preserve lock ordering with extend/create */
-
 	lock_id = (OCFS_FILE_FILE_ALLOC_BITMAP * osb->sect_size) +
 		  osb->vol_layout.root_int_off;
 	for (i = 0; i < OCFS_MAXIMUM_NODES; i++, lock_id += osb->sect_size) {
@@ -280,17 +315,27 @@
 			if (!extnode_inode[i]) {
 				status = -EINVAL;
 				LOG_ERROR_STATUS (status);
-				goto finally;
+				goto abort;
 			}
+			down(&extnode_inode[i]->i_sem);
+
 			status = ocfs_acquire_lock (osb, lock_id,
 				 		    OCFS_DLM_EXCLUSIVE_LOCK,
 						    FLAG_FILE_CREATE,
-						    NULL, extnode_inode[i]);
+						    &ugly_hack_bh, 
+						    extnode_inode[i]);
 			if (status < 0) {
+				up(&extnode_inode[i]->i_sem);
+				iput(extnode_inode[i]);
+				extnode_inode[i] = NULL;
 				if (status != -EINTR)
 					LOG_ERROR_STATUS (status);
-				goto finally;
+				goto abort;
 			}
+
+			ocfs_ugly_hack(handle, ugly_hack_bh);
+			brelse(ugly_hack_bh);
+			ugly_hack_bh = NULL;
 		}
 	}
 
@@ -299,49 +344,76 @@
 		if (!vol_inode) {
 			status = -EINVAL;
 			LOG_ERROR_STATUS (status);
-			goto finally;
+			goto abort;
 		}
+		down(&vol_inode->i_sem);
 
 		status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
 					    OCFS_DLM_EXCLUSIVE_LOCK,
 					    FLAG_FILE_CREATE,
 					    &globalbh, vol_inode);
 		if (status < 0) {
+			up(&vol_inode->i_sem);
+			iput(vol_inode);
+			vol_inode = NULL;
+
 			if (status != -EINTR)
 				LOG_ERROR_STATUS (status);
-			goto finally;
+			goto abort;
 		}
+		ocfs_ugly_hack(handle, globalbh);
+		brelse(ugly_hack_bh);
+		ugly_hack_bh = NULL;
 	}
 
 
 	/* free vol block */
 	if (free_vol_bits != NULL)
-		ocfs_free_vol_block (osb, free_vol_bits, -1, DISK_ALLOC_VOLUME);
+		ocfs_free_vol_block (osb, handle, free_vol_bits, -1, 
+				     DISK_ALLOC_VOLUME);
 
 	/* We can potentiallly loose some allocation for dirNodes or extent */
 	/* nodes but they should not be much...  */
 	for (i = 0; i < OCFS_MAXIMUM_NODES; i++) {
 		if (free_ext_node[i] != NULL)
-			ocfs_free_vol_block (osb, free_ext_node[i], i,
+			ocfs_free_vol_block (osb, handle, free_ext_node[i], i,
 					     DISK_ALLOC_EXTENT_NODE);
 	}
 
 	/* release all locks */
-	if (free_vol_bits != NULL) {
+	if (free_vol_bits) {
 		ocfs_file_entry *bm_lock;
 
+		status = ocfs_journal_access(handle, globalbh, 
+					     OCFS_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			LOG_ERROR_STATUS(status);
+			goto abort;
+		}
+
 		bm_lock = (ocfs_file_entry *)OCFS_BH_GET_DATA_WRITE(globalbh);   /* write */
 		bm_lock->u.bitinfo.used_bits = ocfs_count_bits(&osb->cluster_bitmap);
 		OCFS_BH_PUT_DATA(globalbh);
 
-		status = ocfs_write_bh(osb, globalbh, 0, NULL);
+		status = ocfs_journal_dirty(handle, globalbh);
 		if (status < 0) {
 			LOG_ERROR_STATUS (status);
-			goto finally;
+			goto abort;
 		}
+	}
+
+	ocfs_commit_trans(handle);
+
+	handle = NULL;
+abort:
+	if (handle)
+		ocfs_abort_trans(handle);
+
+	if (free_vol_bits) {
 		status = ocfs_release_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
 					    OCFS_DLM_EXCLUSIVE_LOCK,
-					    FLAG_FILE_CREATE, globalbh, vol_inode);
+					    FLAG_FILE_CREATE, globalbh, 
+					    vol_inode);
 		if (status < 0) {
 			LOG_ERROR_STATUS (status);
 			goto finally;
@@ -367,13 +439,18 @@
 finally:
 
 	for (i = 0; i < OCFS_MAXIMUM_NODES; i++) {
-		if (extnode_inode[i])
+		if (extnode_inode[i]) {
+			up(&extnode_inode[i]->i_sem);
 			iput(extnode_inode[i]);
+		}
 	}
+	if (vol_inode) {
+		up(&vol_inode->i_sem);
+		iput(vol_inode);
+	}
+
 	if (globalbh)
 		brelse(globalbh);
-	if (vol_inode)
-		iput(vol_inode);
 
 	for (i = 0; i < OCFS_MAXIMUM_NODES; i++) {
 		ocfs_safefree (free_ext_node[i]);
@@ -389,7 +466,9 @@
 	return status;
 }				/* ocfs_free_disk_bitmap */
 
-static inline int ocfs_free_main_bitmap(ocfs_super *osb, ocfs_free_rec *freelog) 
+static inline int ocfs_free_main_bitmap(ocfs_super *osb, 
+					ocfs_journal_handle *handle, 
+					ocfs_free_rec *freelog) 
 {
 	int i;
 	ocfs_alloc_bm *bitmap;
@@ -401,12 +480,7 @@
 	bitmap = &osb->cluster_bitmap;
 
 	bitmapblocks = (OCFS_ALIGN(bitmap->validbits, OCFS_BITS_IN_CHUNK) / OCFS_BITS_IN_CHUNK);
-	/* TODO: Fix this so that we only read and write which sectors
-	 * off disk that we actually need instead of the whole honkin'
-	 * bitmap at once... 
-	 *
-	 * Also, can the reads/writes be cached?
-	 */
+
 	status = ocfs_read_bhs(osb, osb->vol_layout.bitmap_off, 
 			       bitmapblocks * osb->sect_size, 
 			       bitmap->chunk, 0, NULL);
@@ -416,21 +490,8 @@
 	}
 
 	for (i = 0; i < freelog->num_updates; i++)
-		ocfs_clear_bits(bitmap, freelog->update[i].file_off, freelog->update[i].length);
+		ocfs_clear_bits(handle, bitmap, freelog->update[i].file_off, freelog->update[i].length);
 
-	/* we don't know which blocks we've changed and which
-	 * haven't, so just write them all out */
-	for(i = 0; i < bitmapblocks; i++) {
-		OCFS_BH_GET_DATA_WRITE(bitmap->chunk[i]);
-		OCFS_BH_PUT_DATA(bitmap->chunk[i]);
-	}
-
-	status = ocfs_write_bhs(osb, bitmap->chunk, bitmapblocks, 0, NULL);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto bail;
-	}
-
 	status = 0;
 bail:
 	LOG_EXIT_STATUS(status);
@@ -441,7 +502,7 @@
  * ocfs_free_vol_block()
  *
  */
-static int ocfs_free_vol_block (ocfs_super * osb, ocfs_free_rec * FreeLog, __u32 NodeNum, __u32 Type)
+static int ocfs_free_vol_block (ocfs_super * osb, ocfs_journal_handle *handle, ocfs_free_rec * FreeLog, __u32 NodeNum, __u32 Type)
 {
 	int status = 0;
 	__u64 fileSize = 0;
@@ -483,9 +544,7 @@
 		    break;
 
 	    case DISK_ALLOC_VOLUME:
-		    down (&(osb->vol_alloc_sem));
-		    status = ocfs_free_main_bitmap(osb, FreeLog);
-		    up (&(osb->vol_alloc_sem));
+		    status = ocfs_free_main_bitmap(osb, handle, FreeLog);
 		    if (status < 0)
 			    LOG_ERROR_STATUS (status);
 		    goto leave;
@@ -498,13 +557,10 @@
 		goto leave;
 	}
 
-	down(&(osb->node_alloc_sem));
-
 	/* Read in the bitmap file for the dir alloc and look
 	   for the required space, if found */
 	status = ocfs_get_system_file_size (osb, fileId, &fileSize, &allocSize);
 	if (status < 0) {
-		up (&(osb->node_alloc_sem));
 		LOG_ERROR_STATUS (status);
 		goto leave;
 	}
@@ -512,35 +568,26 @@
 	ocfs_initialize_bitmap(&AllocBitmap, fileSize * 8, allocSize * 8);
 	tmpbitmap = &AllocBitmap;
 	bitmapblocks = (OCFS_ALIGN(tmpbitmap->validbits, OCFS_BITS_IN_CHUNK) / OCFS_BITS_IN_CHUNK);
-	
+
 	status = ocfs_read_system_file(osb, fileId, AllocBitmap.chunk,
 				       bitmapblocks * osb->sect_size, 
 				       offset);
 	if (status < 0) {
-		up (&(osb->node_alloc_sem));
 		LOG_ERROR_STATUS (status);
 		goto leave;
 	}
 
 	for (i = 0; i < FreeLog->num_updates; i++) {
+		if (FreeLog->update[i].file_off == 0 && Type == 0) {
+			LOG_ERROR_ARGS ("offset=0, type=%x, blksz=%d", Type,
+					blockSize);
+		}
+		
 		foundBit = (__u32) (FreeLog->update[i].file_off >> blockSizeBits);
-		ocfs_clear_bits(tmpbitmap, (__u32) foundBit,
-			       (__u32) FreeLog->update[i].length);
+		ocfs_clear_bits(handle, tmpbitmap, (__u32) foundBit,
+				(__u32) FreeLog->update[i].length);
 	}
 
-	/* we don't know which blocks we've changed and which
- 	* haven't, so just write them all out */
-	for(i = 0; i < bitmapblocks; i++) {
-		OCFS_BH_GET_DATA_WRITE(tmpbitmap->chunk[i]);
-		OCFS_BH_PUT_DATA(tmpbitmap->chunk[i]);
-	}
-	status = ocfs_write_bhs(osb, tmpbitmap->chunk, bitmapblocks, 
-				0, NULL);
-	if (status < 0)
-		LOG_ERROR_STATUS (status);
-
-	up (&(osb->node_alloc_sem));
-
 leave:
 	if (tmpbitmap)
 		ocfs_uninitialize_bitmap(tmpbitmap);
@@ -638,10 +685,6 @@
 		set_buffer_uptodate(header_bhs[i]);
 		OCFS_BH_PUT_DATA(header_bhs[i]);
 	}
-
-	if (fileOffset == 0) {
-		LOG_ERROR_ARGS ("offset=0, file=%s", FileEntry->filename);
-	}
 	
 	if (extent_header != NULL) {
 		k = extent_header->next_free_ext;
@@ -851,10 +894,6 @@
 		OCFS_BH_PUT_DATA(bhs[i]);
 	}
 
-	if (fileOffset == 0) {
-		LOG_TRACE_ARGS ("offset=0, file=%s\n", fe->filename);
-	}
-
 	if (physicalOffset == 0) {
 		LOG_ERROR_STATUS(status = -ENOMEM);
 		goto finally;
@@ -1419,7 +1458,8 @@
 	    diskOffsetTobeFreed, lengthTobeFreed = 0, 
 	    actualSize = 0, origLength = 0;
 
-	LOG_ENTRY ();
+	LOG_ENTRY_ARGS("(*freeExtent = %u, FileSize = %llu, flag = %d)\n", 
+		       *freeExtent, FileSize, flag);
 
 	firstfree = *freeExtent;
 
@@ -2607,19 +2647,18 @@
  * 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.
  */
-int ocfs_find_contiguous_space_from_bitmap (ocfs_super * osb, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count, int sysfile, struct buffer_head *lock_bh, struct inode *bitmap_inode)
+int ocfs_find_contiguous_space_from_bitmap (ocfs_super * osb, ocfs_journal_handle *handle, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count, int sysfile, struct buffer_head *lock_bh, struct inode *bitmap_inode)
 {
-	int status = 0, tmpstat, startbh, numblocks;
+	int status = 0, startbh, numblocks;
 	__u32 bitoffset = 0, ClusterCount = 0;
 	__u64 ByteCount = 0;
 	__u32 LargeAlloc = 0;
 	static __u32 LargeAllocOffset = 0;
 	static __u32 SmallAllocOffset = 0;
-	int bLockAcquired = 0;
 	struct buffer_head *bh = NULL;
 	ocfs_file_entry *bm_lock = NULL;
 	__u32 bitmapblocks; /* we only care about the valid blocks */
-	int local_lock = 1;
+	int local_lock = 0;
 	int local_inode = 0;
 	__u32 five_percent;
 
@@ -2627,12 +2666,6 @@
 
 	OCFS_ASSERT (osb);
 
-	if (lock_bh) {
-		local_lock = 0;
-		bh = lock_bh;
-	} else /* local lock */
-		down (&(osb->vol_alloc_sem));
-
 	if (!bitmap_inode) {
 		bitmap_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET, NULL);
 		if (!bitmap_inode) {
@@ -2643,7 +2676,13 @@
 		local_inode = 1;
 	}
 
-	if (local_lock) {
+	if (lock_bh) {
+		bh = lock_bh;
+	} else { /* local lock */
+		local_lock = 1;
+
+		down(&bitmap_inode->i_sem);
+
 		/* Get the allocation lock here */
 		status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
 					    OCFS_DLM_EXCLUSIVE_LOCK, 0, 
@@ -2653,8 +2692,16 @@
 				LOG_ERROR_STATUS (status);
 			goto leave;
 		}
-		bLockAcquired = 1;
+		ocfs_journal_add_lock(handle, OCFS_DLM_EXCLUSIVE_LOCK, 
+				      0, bh, bitmap_inode);
 	}
+
+	status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto leave;
+	}
+
 	bm_lock = (ocfs_file_entry *)OCFS_BH_GET_DATA_WRITE(bh); /* write */
 
 	ClusterCount = (__u32) ((__u64) (file_size + (osb->vol_layout.cluster_size-1)) >> 
@@ -2743,7 +2790,7 @@
 
 	LOG_TRACE_ARGS ("setting at bit offset=%u\n", bitoffset);
 
-	ocfs_set_bits (&osb->cluster_bitmap, bitoffset, ClusterCount);
+	ocfs_set_bits (handle, &osb->cluster_bitmap, bitoffset, ClusterCount);
 
 	/* Ok, write out the bitmap now. We optimize only by writing
 	 * out the bitmap blocks which have changed, and not all of
@@ -2752,22 +2799,13 @@
 	numblocks = OCFS_GLOBAL_OFF_TO_CHUNK(bitoffset + ClusterCount - 1) - startbh + 1;
 
 	LOG_TRACE_ARGS("bitoffset = %u, ClusterCount = %u, startbh = %u, numblocks = %u\n", bitoffset, ClusterCount, startbh, numblocks);
-	
-	status = ocfs_write_bhs(osb, &osb->cluster_bitmap.chunk[startbh], 
-				numblocks, 0, NULL);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
 
 	/* write the bitmap size info to the lock sector */
-	/* TODO: optimize by making this part of ocfs_release_lock 
-	 * for now, it will be back-to-back writes to same sector */
 	bm_lock->u.bitinfo.used_bits = ocfs_count_bits(&osb->cluster_bitmap);
 	OCFS_BH_PUT_DATA(bh);
 	bm_lock = NULL;
 
-	status = ocfs_write_bh (osb, bh, 0, NULL);
+	status = ocfs_journal_dirty(handle, bh);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
 		goto leave;
@@ -2782,16 +2820,8 @@
 		OCFS_BH_PUT_DATA(bh);
 
 	if (local_lock) {
-		up (&(osb->vol_alloc_sem));
+		up (&bitmap_inode->i_sem);
 
-		if (bLockAcquired) {
-			tmpstat = ocfs_release_lock(osb, 
-						    OCFS_BITMAP_LOCK_OFFSET,
-						    OCFS_DLM_EXCLUSIVE_LOCK, 
-						    0, bh, bitmap_inode);
-			if (tmpstat < 0)
-				LOG_ERROR_STATUS (tmpstat);
-		}
 		if (bh != NULL)
 			brelse(bh);
 	}
@@ -2811,7 +2841,6 @@
 int ocfs_alloc_node_block (ocfs_super * osb, __u64 FileSize, __u64 * DiskOffset, __u64 * file_off, __u32 NodeNum, __u32 Type, ocfs_journal_handle *handle)
 {
 	int status = 0;
-	int tmpstat = 0;
 	int startbh, numblocks;
 	__u64 fileSize = 0;
 	__u64 offset = 0;
@@ -2826,7 +2855,6 @@
 	__u32 numBits = 0;
 	__u32 foundBit = -1;
 	__u32 blockSize = 0, blockSizeBits = 0;
-	int bLockAcquired = 0;
 	__u32 bm_file = 0;
 	__u32 alloc_file = 0;
 	struct buffer_head *bh = NULL;
@@ -2876,8 +2904,17 @@
 		LOG_ERROR_STATUS (status);
 		goto leave;
 	}
-	bLockAcquired = 1;
 
+	ocfs_journal_add_lock(handle, OCFS_DLM_EXCLUSIVE_LOCK, 
+			      FLAG_FILE_CREATE, 
+			      bh, inode);
+
+	status = ocfs_ugly_hack(handle, bh);
+	if (status < 0) {
+		LOG_ERROR_STATUS (status);
+		goto leave;
+	}
+
 	numBits = ((FileSize + (blockSize-1)) >> blockSizeBits);
 	numBytes = numBits << blockSizeBits;
 
@@ -2984,20 +3021,12 @@
 
 	LOG_TRACE_ARGS ("byte offset=%d\n", foundBit);
 
-	ocfs_set_bits (&bitmap, (__u32) foundBit, (__u32) numBits);
+	ocfs_set_bits (handle, &bitmap, (__u32) foundBit, (__u32) numBits);
 
 	/* only write out what has changed... */
 	startbh = OCFS_GLOBAL_OFF_TO_CHUNK(foundBit);
 	numblocks = OCFS_GLOBAL_OFF_TO_CHUNK(foundBit + numBits - 1) - startbh + 1;
 
-	/* Write the bitmap file back */
-	status = ocfs_write_bhs(osb, &bitmap.chunk[startbh], numblocks, 
-				0, NULL);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto leave;
-	}
-
 	LOG_TRACE_ARGS ("offset=%u, type=%x, blksz=%u, foundbit=%u, fileid=%u\n",
 			foundBit * blockSize, Type, blockSize, foundBit, alloc_file);
 	*DiskOffset = ocfs_file_to_disk_off (osb, (alloc_file),
@@ -3019,23 +3048,9 @@
 	if (needs_uninit)
 		ocfs_uninitialize_bitmap(&bitmap);
 
-	if (bLockAcquired && delay_lockrel) {
-		ocfs_journal_add_lock(handle, OCFS_DLM_EXCLUSIVE_LOCK, 
-				      FLAG_FILE_CREATE, 
-				      bh, inode);
-		tmpstat = 0;
-	} else if (bLockAcquired) {
-		tmpstat =
-		    ocfs_release_lock (osb, lockId, OCFS_DLM_EXCLUSIVE_LOCK,
-				     FLAG_FILE_CREATE, bh, inode);
-
-	}
-
 	if (inode)
 		iput(inode);
 
-	if (tmpstat < 0)
-		status = tmpstat;
 	if (bh != NULL)
 		brelse(bh);
 
@@ -3223,18 +3238,12 @@
 static int ocfs_sync_local_to_main(ocfs_super *osb, 
 				   ocfs_bitmap_free_head **f, 
 				   struct buffer_head *local_alloc_bh, 
-				   struct buffer_head *bm_lock_bh,
-				   struct inode *bm_inode,
 				   int in_recovery)
 {
-	int status = 0, tmpstat;
-	__u32 bitmapblocks;
-	struct buffer_head *bh = NULL;
+	int status = 0;
 	int bit_off, left;
 	ocfs_local_alloc *alloc = NULL;
-	int local_lock = 1, got_lock = 0;
 	void *bitmap;
-	struct inode *local_inode = NULL;
 
 	LOG_ENTRY();
 
@@ -3248,6 +3257,7 @@
 		goto bail;
 	}
 	OCFS_BH_PUT_DATA(local_alloc_bh);
+
 	if (!(*f)) {
 		*f = ocfs_alloc_bitmap_free_head();
 		if (*f == NULL) {
@@ -3288,6 +3298,7 @@
 	OCFS_BH_PUT_DATA(local_alloc_bh);
 
 bail:
+
 	LOG_EXIT_STATUS(status);
 	return(status);
 } /* ocfs_sync_local_to_main */
@@ -3319,7 +3330,8 @@
 		       "new window.\n", alloc_bytes, 
 		       ocfs_local_alloc_window_bits(osb));
 
-	status = ocfs_find_contiguous_space_from_bitmap(osb, alloc_bytes, 
+	status = ocfs_find_contiguous_space_from_bitmap(osb, handle, 
+							alloc_bytes, 
 							&cluster_off, 
 							&cluster_count, 0, 
 							lock_bh, bm_inode);
@@ -3345,18 +3357,7 @@
 	LOG_TRACE_ARGS("window alloc_size = %u\n", alloc->alloc_size);
 
 	OCFS_BH_PUT_DATA(osb->local_alloc_bh);
-	status = ocfs_handle_add_abort_bits(handle, cluster_count, 
-					    alloc->bitmap_start, -1, 
-					    DISK_ALLOC_VOLUME);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
 
-		/* In case of this error, we want to shutdown the
-		 * local alloc bitmap. We'll let shutdown handling
-		 * deal with freeing newly allocated bits. */
-		ocfs_free_bitmap_free_head(handle->abort_bits);
-		handle->abort_bits = NULL;
-	}
 bail:
 	LOG_EXIT_STATUS(status);
 	return(status);
@@ -3440,7 +3441,7 @@
 	void *bitmap;
 
 	LOG_ENTRY_ARGS("(bitswanted = %u)\n", bitswanted);
-	
+
 	if (!osb->have_local_alloc)
 		BUG();
 
@@ -3506,35 +3507,37 @@
 		OCFS_BH_PUT_DATA(osb->local_alloc_bh);
 		alloc = NULL;
 
-		/* lock bitmap here */
-		down (&(osb->vol_alloc_sem));
-
 		if (!main_bm_inode)
 			main_bm_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET,
 						  NULL);
 
 		if (!main_bm_inode) {
-			up (&(osb->vol_alloc_sem));
 			status = -EINVAL;
 			LOG_ERROR_STATUS (status);
 			goto bail;
 		}
 
+		/* lock bitmap here */
+		down(&main_bm_inode->i_sem);
+
 		/* Get the allocation lock here */
 		status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
 					    OCFS_DLM_EXCLUSIVE_LOCK, 0, 
 					    &main_bm_bh, 
 					    main_bm_inode);
 		if (status < 0) {
-			up (&(osb->vol_alloc_sem));
+			up(&main_bm_inode->i_sem);
+			main_bm_bh = NULL;
 			if (status != -EINTR)
 				LOG_ERROR_STATUS (status);
 			goto bail;
 		}
 
+		ocfs_journal_add_lock(handle, OCFS_DLM_EXCLUSIVE_LOCK, 0,
+				      main_bm_bh, main_bm_inode);
+
 		status = ocfs_sync_local_to_main(osb, &(handle->commit_bits),
-						 NULL, main_bm_bh, 
-						 main_bm_inode, 0);
+						 NULL, 0);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
 			goto bail;
@@ -3586,15 +3589,7 @@
 bail:
 	/* if we locked the main bitmap, cleanup after ourselves. */
 	if (main_bm_bh) {
-		up (&(osb->vol_alloc_sem));
-
-		tmpstat = ocfs_release_lock (osb, 
-					     OCFS_BITMAP_LOCK_OFFSET,
-					     OCFS_DLM_EXCLUSIVE_LOCK, 
-					     0, main_bm_bh, 
-					     main_bm_inode);
-		if (tmpstat < 0)
-			LOG_ERROR_STATUS (tmpstat);
+		up(&main_bm_inode->i_sem);
 		brelse(main_bm_bh);
 	}
 
@@ -3665,7 +3660,8 @@
 	}
 
 	if (use_global) {
-		status = ocfs_find_contiguous_space_from_bitmap(osb, file_size,
+		status = ocfs_find_contiguous_space_from_bitmap(osb, handle, 
+								file_size,
 								cluster_off, 
 								cluster_count, 
 								sysfile, NULL,
@@ -3767,8 +3763,7 @@
 	else
 		bh = osb->local_alloc_bh;
 
-	status = ocfs_sync_local_to_main(osb, &f, bh, NULL, NULL,
-					 in_recovery);
+	status = ocfs_sync_local_to_main(osb, &f, bh, in_recovery);
 	if (status < 0)
 		LOG_ERROR_STATUS(status);
 	else if (f)

Modified: branches/new-dir-format/src/bitmap.c
===================================================================
--- branches/new-dir-format/src/bitmap.c	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/bitmap.c	2004-05-27 00:07:46 UTC (rev 943)
@@ -123,6 +123,33 @@
 	LOG_EXIT();
 }
 
+/* 
+ * More or less lifted from ext3. I'll leave their description below:
+ * 
+ * For ext3 allocations, we must not reuse any blocks which are
+ * allocated in the bitmap buffer's "last committed data" copy.  This
+ * prevents deletes from freeing up the page for reuse until we have
+ * committed the delete transaction.
+ *
+ * If we didn't do this, then deleting something and reallocating it as
+ * data would allow the old block to be overwritten before the
+ * transaction committed (because we force data to disk before commit).
+ * This would lead to corruption if we crashed between overwriting the
+ * data and committing the delete. 
+ *
+ * @@@ We may want to make this allocation behaviour conditional on
+ * data-writes at some point, and disable it for metadata allocations or
+ * sync-data inodes.
+ */
+static int ocfs_test_allocatable(int nr, struct buffer_head *bh)
+{
+	if (test_bit(nr, (unsigned long *)bh->b_data))
+		return 0;
+	if (!buffer_jbd(bh) || !bh2jh(bh)->b_committed_data)
+		return 1;
+	return !test_bit(nr, (unsigned long *)bh2jh(bh)->b_committed_data);
+}
+
 /*
  * ocfs_find_clear_bits()
  *
@@ -174,6 +201,7 @@
 		   localstart: if the current one is a zero
 		*/
 		if (bitoff >= size) {
+nextbh:
 			/* we've hit the end of our bh. */
 			OCFS_BH_PUT_DATA(currbh);
 			/*LOG_TRACE_ARGS("bitoff >= size (%u)\n", bitoff,c);*/
@@ -196,7 +224,17 @@
 			continue;
 		}
 
-		if (bitoff == localstart) {
+		if (!ocfs_test_allocatable(bitoff, currbh)) {
+			/* We found a zero, but we can't use it as it
+			 * hasn't been put to disk yet! */
+			count = 0;
+			localstart = bitoff + 1;
+			/* In doing this, we might go over our current bh. */
+			if (localstart >= size)
+				goto nextbh;
+
+			globaloff = OCFS_CHUNK_TO_GLOBAL_OFF(c, bitoff) + 1;
+		} else if (bitoff == localstart) {
 			/*LOG_TRACE_ARGS("bitoff == localstart (%u)\n", 
 			  bitoff);*/
 			/* cool, we have another zero! */
@@ -263,19 +301,20 @@
 }				/* ocfs_count_bits */
 
 #ifdef __KERNEL__
-
-/* HEY LOOK! These two functions are IDENTICAL except for one line!
+/* HEY LOOK! These two functions are IDENTICAL except for three lines!
  * We'd never do that... no, never... */
 
 /*
  * ocfs_set_bits()
  *
  */
-void ocfs_set_bits (ocfs_alloc_bm * bitmap, __u32 start, __u32 num)
+void ocfs_set_bits (ocfs_journal_handle *handle, ocfs_alloc_bm * bitmap, 
+		    __u32 start, __u32 num)
 {
 	struct buffer_head *currbh = NULL;
 	void *buff;
 	int i, local;
+	int status;
 
 	LOG_ENTRY_ARGS ("(0x%p, %u, %u)\n", bitmap, start, num);
 
@@ -289,6 +328,12 @@
 	local = OCFS_GLOBAL_OFF_TO_LOCAL(start);
 	currbh = bitmap->chunk[i];
 
+	status = ocfs_journal_access(handle, currbh, OCFS_JOURNAL_ACCESS_UNDO);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
 	buff = OCFS_BH_GET_DATA_WRITE(currbh); /* write */
 
 	while (num--) {
@@ -296,13 +341,33 @@
 		if (local >= OCFS_BITS_IN_CHUNK && num != 0) {
 			local = 0;
 			OCFS_BH_PUT_DATA(currbh);
+			status = ocfs_journal_dirty(handle, currbh);
+			if (status < 0) {
+				LOG_ERROR_STATUS(status);
+				goto bail;
+			}
+
 			i++;
 			currbh = bitmap->chunk[i];
+
+			status = ocfs_journal_access(handle, currbh, 
+						     OCFS_JOURNAL_ACCESS_UNDO);
+			if (status < 0) {
+				LOG_ERROR_STATUS(status);
+				goto bail;
+			}
 			buff = OCFS_BH_GET_DATA_WRITE(currbh); /* write */
 		}
 	}
 
 	OCFS_BH_PUT_DATA(currbh);
+
+	status = ocfs_journal_dirty(handle, currbh);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
 bail:
 	LOG_EXIT ();
 	return;
@@ -312,11 +377,13 @@
  * ocfs_clear_bits()
  *
  */
-void ocfs_clear_bits (ocfs_alloc_bm * bitmap, __u32 start, __u32 num)
+void ocfs_clear_bits (ocfs_journal_handle *handle, ocfs_alloc_bm * bitmap, 
+		      __u32 start, __u32 num)
 {
 	struct buffer_head *currbh = NULL;
 	void *buff;
 	int i, local;
+	int status;
 
 	LOG_ENTRY_ARGS ("(0x%p, %u, %u)\n", bitmap, start, num);
 
@@ -330,20 +397,52 @@
 	local = OCFS_GLOBAL_OFF_TO_LOCAL(start);
 	currbh = bitmap->chunk[i];
 
+	status = ocfs_journal_access(handle, currbh, OCFS_JOURNAL_ACCESS_UNDO);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
 	buff = OCFS_BH_GET_DATA_WRITE(currbh); /* write */
 
 	while (num--) {
-		clear_bit (local++, buff);
+		clear_bit (local, buff);
+		set_bit(local, 
+			(unsigned long *)bh2jh(currbh)->b_committed_data);
+		local++;
+
 		if (local >= OCFS_BITS_IN_CHUNK && num != 0) {
 			local = 0;
 			OCFS_BH_PUT_DATA(currbh);
+
+			status = ocfs_journal_dirty(handle, currbh);
+			if (status < 0) {
+				LOG_ERROR_STATUS(status);
+				goto bail;
+			}
+
 			i++;
 			currbh = bitmap->chunk[i];
+
+			status = ocfs_journal_access(handle, currbh,
+						     OCFS_JOURNAL_ACCESS_UNDO);
+			if (status < 0) {
+				LOG_ERROR_STATUS(status);
+				goto bail;
+			}
+
 			buff = OCFS_BH_GET_DATA_WRITE(currbh); /* write */
 		}
 	}
 
 	OCFS_BH_PUT_DATA(currbh);
+
+	status = ocfs_journal_dirty(handle, currbh);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+
 bail:
 	LOG_EXIT ();
 	return;

Modified: branches/new-dir-format/src/file.c
===================================================================
--- branches/new-dir-format/src/file.c	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/file.c	2004-05-27 00:07:46 UTC (rev 943)
@@ -957,9 +957,11 @@
 	LOG_ENTRY_ARGS ("(file_off = %llu, file_size = %llu\n", 
 		   file_off, file_size);
 
-	new_alloc_size = (file_size + (osb->vol_layout.cluster_size - 1)) >> 
-				osb->cluster_size_bits;
+	new_alloc_size = ((file_size + (osb->vol_layout.cluster_size - 1)) >> 
+			  osb->cluster_size_bits) << osb->cluster_size_bits;
 
+	LOG_TRACE_ARGS("new_alloc_size = %llu\n", new_alloc_size);
+
 	status = ocfs_read_bh (osb, file_off, &bh, OCFS_BH_CACHED, inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
@@ -1107,6 +1109,9 @@
 	struct buffer_head *bh = NULL;
 	int flags = 0;
 	ocfs_journal_handle *handle = NULL;
+	int credits;
+	struct inode *ext_alloc_inode = NULL;
+	__u64 ext_alloc_off;
 
 	LOG_ENTRY ();
 
@@ -1126,17 +1131,21 @@
 
 	if (!IS_VALID_FILE_ENTRY(fileEntry)) {
 		printk("fe->signature=%8s\n", fileEntry->signature);
-		printk("fe->filename=%8s\n", fileEntry->filename);
 		LOG_ERROR_ARGS ("Invalid fe at offset %llu", file_off);
 		status = -EFAIL;
 		OCFS_BH_PUT_DATA(bh);
 		goto leave;
 	}
+
+	allocSize = file_size - fileEntry->alloc_size;
 	OCFS_BH_PUT_DATA(bh);
 	fileEntry = NULL;
 
 
 	if (passed_handle == NULL) {
+		credits = ocfs_calc_extend_credits(((__u32) allocSize), 
+						   osb->vol_layout.cluster_size);
+
 		/* cannot call start_trans with a locked buffer head. */
 		handle = ocfs_start_trans(osb, OCFS_FILE_EXTEND_CREDITS);
 		if (handle == NULL) {
@@ -1239,12 +1248,19 @@
 			}
 		}
 
-		down (&osb->node_alloc_sem);
+		ext_alloc_off = ((OCFS_FILE_FILE_ALLOC_BITMAP + osb->node_num) * osb->sect_size) + osb->vol_layout.root_int_off;
+		ext_alloc_inode = ocfs_iget(osb, ext_alloc_off, NULL);
+		if (!ext_alloc_inode) {
+			status = -EFAIL;
+			LOG_ERROR_STATUS(status);
+			goto leave;
+		}
+
+		down(&ext_alloc_inode->i_sem);
 		status = ocfs_allocate_extent (osb, bh, handle,
 					actualDiskOffset, actualLength, inode);
-		up (&osb->node_alloc_sem);
+		up(&ext_alloc_inode->i_sem);
 		if (status < 0) {
-			OCFS_BH_PUT_DATA(bh);
 			LOG_ERROR_STATUS (status);
 			goto leave;
 		}
@@ -1317,6 +1333,9 @@
 	if (bh != NULL)
 		brelse(bh);
 
+	if (ext_alloc_inode)
+		iput(ext_alloc_inode);
+
 	LOG_EXIT_STATUS (status);
 	return status;
 }				/* ocfs_extend_file */

Modified: branches/new-dir-format/src/hash.c
===================================================================
--- branches/new-dir-format/src/hash.c	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/hash.c	2004-05-27 00:07:46 UTC (rev 943)
@@ -431,9 +431,12 @@
 	if (++bucket < OcfsGlobalCtxt.bh_sem_hash_sz)
 		goto again;
 
-	if (found)
+	if (found) {
 		LOG_ERROR_ARGS("Found %d modified buffers!\n", found);
-
+#ifdef BH_SEM_LEAK_CHECKING
+		BUG();
+#endif
+	}
 	return found;
 } /* ocfs_bh_sem_hash_cleanup_pid() */
 

Modified: branches/new-dir-format/src/inc/io.h
===================================================================
--- branches/new-dir-format/src/inc/io.h	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/inc/io.h	2004-05-27 00:07:46 UTC (rev 943)
@@ -222,10 +222,12 @@
 	ocfs_bh_sem_unlock(bh);
 }
 
+#define STATE_BH_BITS	8
+#define USED_BH_BITS	23 /* Number of BH bits used up through JBD */
 
-#define STATE_BIT_MAX           (1 << 12)
-#define STATE_BIT_MAX_MASK      ((1 << 12)-1)
-#define STATE_BIT_MASK		((~0UL)<<19)
+#define STATE_BIT_MAX           (1 << STATE_BH_BITS)
+#define STATE_BIT_MAX_MASK      ((1 << STATE_BH_BITS)-1)
+#define STATE_BIT_MASK		((~0UL) << USED_BH_BITS)
 
 
 static inline void CLEAR_BH_SEQNUM(struct buffer_head *bh)
@@ -237,7 +239,7 @@
 static inline void SET_BH_SEQNUM(struct inode *inode, struct buffer_head *bh)
 {
 	unsigned int seq = (atomic_read(GET_INODE_CLEAN_SEQ(inode)) & 
-			    STATE_BIT_MAX_MASK) << 19;
+			    STATE_BIT_MAX_MASK) << USED_BH_BITS;
 
 	CLEAR_BH_SEQNUM(bh);
 	bh->b_state |= seq;
@@ -246,7 +248,8 @@
 static inline int TEST_BH_SEQNUM(struct inode *inode, struct buffer_head *bh)
 {
 	int ret;
-	unsigned int seq = (bh->b_state & STATE_BIT_MASK) >> 19;
+	unsigned int seq =
+		(bh->b_state & STATE_BIT_MASK) >> USED_BH_BITS;
 
 	ret = (seq == atomic_read(GET_INODE_CLEAN_SEQ(inode)));
 	return ret;

Modified: branches/new-dir-format/src/inc/journal.h
===================================================================
--- branches/new-dir-format/src/inc/journal.h	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/inc/journal.h	2004-05-27 00:07:46 UTC (rev 943)
@@ -153,10 +153,6 @@
 						     * freed ONLY if
 						     * we commit the
 						     * handle. */
-	struct _ocfs_bitmap_free_head *abort_bits;  /* bits to be
-						     * freed ONLY if
-						     * we abort the
-						     * handle. */
 	__u64                new_file_lockid;  /* offset for the 
 						* most recently 
 						* created file
@@ -200,21 +196,6 @@
 						  type);		      \
 	rv;								      \
 })
-#define ocfs_handle_add_abort_bits(handle, len, fileoff, nodenum, type)      \
-({									      \
-	int rv = 0;							      \
-	if (!handle->abort_bits) 					      \
-		handle->abort_bits = ocfs_alloc_bitmap_free_head();	      \
-									      \
-	if (!handle->abort_bits)					      \
-		rv = -ENOMEM;						      \
-	else								      \
-		rv = ocfs_add_to_bitmap_free_head(handle->osb,		      \
-						  handle->abort_bits,	      \
-						  len, fileoff, nodenum,      \
-						  type);		      \
-	rv;								      \
-})
 
 /* 
  *  Journal Configuration Management:
@@ -285,6 +266,7 @@
  */
 #define OCFS_JOURNAL_ACCESS_CREATE 0
 #define OCFS_JOURNAL_ACCESS_WRITE  1
+#define OCFS_JOURNAL_ACCESS_UNDO   2
 int                  ocfs_journal_access(ocfs_journal_handle *handle, 
 					 struct buffer_head *bh, int type);
 /*
@@ -344,17 +326,42 @@
 
 /* locknode + new fe + dirnode head + new dirnode for parent directory
  * + extending (diralloc, filealloc, dirallocbitmap, fileallocbitmap)
- * + a second dirnode for handling mkdir + some fuzz. */
+ * + a second dirnode for handling mkdir + 2 * 2 = 4 blocks for
+ * setting the bits in the dir alloc bitmap and the metadata alloc
+ * bitmap if dir alloc needs to be extended + some fuzz. */
 #define OCFS_MKNOD_CREDITS (1 + 1 + (OCFS_DEFAULT_DIR_NODE_SECTS*2) +	      \
 			    (OCFS_SINGLE_FILE_EXTEND_CREDITS * 4) +	      \
 			    OCFS_JOURNAL_FUZZ_CREDITS)
 
 /* single file metadata updates * 3 because we might have to extend
  * the file alloc and file alloc bitmap files + possible update to
- * local bitmap. */
+ * local bitmap. + 2 blocks for bits to set in the metadata alloc
+ * bitmap file */
 #define OCFS_FILE_EXTEND_CREDITS (OCFS_SINGLE_FILE_EXTEND_CREDITS * 3         \
-				  + 1 + OCFS_JOURNAL_FUZZ_CREDITS)
+				  + 1 + 2 + OCFS_JOURNAL_FUZZ_CREDITS)
 
+/* Now that we journal bitmap writes, this might get a bit more
+ * complicated, use this function to determine how many credits are
+ * needed for an extend. Unfortunately, we're in bytes because the
+ * rest of the file system is. 
+ *
+ * PLEASE can we fix up our include file mess so this can be a static inline?!
+ */
+static inline int ocfs_calc_extend_credits(__u32 bytes_wanted, 
+					   __u32 cluster_size)
+{
+	int bitmap_blocks;
+	unsigned int bits_wanted;
+
+	bits_wanted = OCFS_ALIGN(bytes_wanted, cluster_size) / cluster_size;
+	/* take advantage of the fact that we always allocate in one 
+	 * large chunk. */
+	bitmap_blocks = 1 + OCFS_ALIGN(bits_wanted, OCFS_BITS_IN_CHUNK) /
+			OCFS_BITS_IN_CHUNK;
+
+	return(bitmap_blocks + OCFS_FILE_EXTEND_CREDITS);
+}
+
 /* fe, anything along new 'edge' of tree + fuzz*/
 #define OCFS_FILE_TRUNCATE_CREDITS (1 + 4 + OCFS_JOURNAL_FUZZ_CREDITS)
 
@@ -362,10 +369,11 @@
 #define OCFS_FILE_DELETE_CREDITS  (1 + 1 + 1 + OCFS_JOURNAL_FUZZ_CREDITS)
 
 /* need to create a new file and extend it to hold the info for the
- * symlink. we wind up with twice the fuzz because we reuse some
- * macros so we subtract one.*/
+ * symlink we add one for a potential write of the main bitmap. Since
+ * we wind up with twice the fuzz because we reuse some macros so we
+ * subtract one.*/
 #define OCFS_SYMLINK_CREDITS (OCFS_MKNOD_CREDITS + OCFS_FILE_EXTEND_CREDITS   \
-			      - OCFS_JOURNAL_FUZZ_CREDITS)
+			      + 1 - OCFS_JOURNAL_FUZZ_CREDITS)
 
 /* fe change, locknode change, dirnode head, times two plus a possible
  * delete, three to fix the up_node_hdr_ptr values of any extents

Modified: branches/new-dir-format/src/inc/ocfs.h
===================================================================
--- branches/new-dir-format/src/inc/ocfs.h	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/inc/ocfs.h	2004-05-27 00:07:46 UTC (rev 943)
@@ -97,6 +97,43 @@
 #endif
 #include <linux/smp_lock.h>
 
+
+#define OCFS_BITMAP_CHUNK   (512) /* size of a chunk, in bytes */
+#define OCFS_BITS_IN_CHUNK  (OCFS_BITMAP_CHUNK * 8)
+//#define OCFS_BITMAP_NUM_BH  (ONE_MEGA_BYTE / OCFS_BITMAP_CHUNK)
+/* Lovely convenience macros. If we move to a scheme where
+ * OCFS_BITS_IN_CHUNK or OCFS_BITMAP_NUM_BH are not constant, this'll
+ * be nice. */
+#define OCFS_CHUNK_TO_GLOBAL_OFF(index, localoffset)                    \
+	((index) * OCFS_BITS_IN_CHUNK + (localoffset))
+#define OCFS_GLOBAL_OFF_TO_CHUNK(globaloffset)                          \
+	((globaloffset) / OCFS_BITS_IN_CHUNK)
+#define OCFS_GLOBAL_OFF_TO_LOCAL(globaloffset)                          \
+	((globaloffset) % OCFS_BITS_IN_CHUNK)
+#define OCFS_BITMAP_RANGE_BITS(startbh, startoff, endbh, endoff)        \
+	(OCFS_CHUNK_TO_GLOBAL_OFF((endbh), (endoff)) -                      \
+	 OCFS_CHUNK_TO_GLOBAL_OFF((startbh), (startoff)))
+
+typedef struct _ocfs_alloc_bm
+{
+	__u32 validbits; /* number of valid bits */
+	__u32 allocbits; /* number of allocated bits */
+	__u32 failed;
+	__u32 ok_retries;
+	/* 'numbh' is the number of buffer heads in chunk. We keep
+	 * around enough buffer heads to cover the entire alloc'd size
+	 * of the bitmap, even though we may only ever care about the
+	 * valid size */
+	__u32 numbh;
+	struct buffer_head **chunk;
+}
+ocfs_alloc_bm;
+
+#define  OCFS_ALIGN(val, align)        \
+	       ((__u64)val  +            \
+		(((__u64)val % align) ? (align - ((__u64)val % align)): 0))
+
+
 #include "journal.h"
 
 
@@ -601,11 +638,6 @@
 		(((__u64)buf % OCFS_SECTOR_SIZE) ?    \
 		 (OCFS_SECTOR_SIZE - ((__u64)buf % OCFS_SECTOR_SIZE)):0))
 
-
-#define  OCFS_ALIGN(val, align)        \
-	       ((__u64)val  +            \
-		(((__u64)val % align) ? (align - ((__u64)val % align)): 0))
-
 /*
 ** Structures...
 */
@@ -1394,38 +1426,6 @@
 }
 BARF_BARF_BARF;
 
-
-#define OCFS_BITMAP_CHUNK   (512) /* size of a chunk, in bytes */
-#define OCFS_BITS_IN_CHUNK  (OCFS_BITMAP_CHUNK * 8)
-//#define OCFS_BITMAP_NUM_BH  (ONE_MEGA_BYTE / OCFS_BITMAP_CHUNK)
-/* Lovely convenience macros. If we move to a scheme where
- * OCFS_BITS_IN_CHUNK or OCFS_BITMAP_NUM_BH are not constant, this'll
- * be nice. */
-#define OCFS_CHUNK_TO_GLOBAL_OFF(index, localoffset)                    \
-	((index) * OCFS_BITS_IN_CHUNK + (localoffset))
-#define OCFS_GLOBAL_OFF_TO_CHUNK(globaloffset)                          \
-	((globaloffset) / OCFS_BITS_IN_CHUNK)
-#define OCFS_GLOBAL_OFF_TO_LOCAL(globaloffset)                          \
-	((globaloffset) % OCFS_BITS_IN_CHUNK)
-#define OCFS_BITMAP_RANGE_BITS(startbh, startoff, endbh, endoff)        \
-	(OCFS_CHUNK_TO_GLOBAL_OFF((endbh), (endoff)) -                      \
-	 OCFS_CHUNK_TO_GLOBAL_OFF((startbh), (startoff)))
-
-typedef struct _ocfs_alloc_bm
-{
-	__u32 validbits; /* number of valid bits */
-	__u32 allocbits; /* number of allocated bits */
-	__u32 failed;
-	__u32 ok_retries;
-	/* 'numbh' is the number of buffer heads in chunk. We keep
-	 * around enough buffer heads to cover the entire alloc'd size
-	 * of the bitmap, even though we may only ever care about the
-	 * valid size */
-	__u32 numbh;
-	struct buffer_head **chunk;
-}
-ocfs_alloc_bm;
-
 typedef struct _ocfs_extent
 {
 	struct list_head list;
@@ -1784,8 +1784,6 @@
 	__u32 recovery_map;
 	int disable_recovery;
 	atomic_t num_recovery_threads;
-	struct semaphore node_alloc_sem;
-	struct semaphore vol_alloc_sem;
 	struct timer_list lock_timer;
 	atomic_t lock_stop;
 	wait_queue_head_t lock_event;
@@ -1967,8 +1965,7 @@
 	__u8 next_free_ext;             // NUMBER RANGE(0,OCFS_MAX_FILE_ENTRY_EXTENTS) 
 	__s8 next_del;                  // DIRNODEINDEX
 	__s32 granularity;	        // NUMBER RANGE(-1,3)
-	__u8 filename[OCFS_MAX_FILENAME_LENGTH];  // CHAR[OCFS_MAX_FILENAME_LENGTH]
-	__u16 filename_len;               // NUMBER RANGE(0,OCFS_MAX_FILENAME_LENGTH)
+	__u8 reserved0[257];  // CHAR[OCFS_MAX_FILENAME_LENGTH]
 	__u64 file_size;                  // NUMBER RANGE(0,ULONG_LONG_MAX)
 	__u64 alloc_size;		        // NUMBER RANGE(0,ULONG_LONG_MAX)
 	__u64 create_time;                // DATE
@@ -1990,7 +1987,6 @@
 	__u8 fe_reserved1[4];		  // UNUSED
 	union {
 		__u64 fe_private;
-		__u64 child_dirnode;              // NUMBER RANGE(0,ULONG_LONG_MAX)
 		struct _bitinfo {
 			__u32 used_bits;
 			__u32 total_bits;

Modified: branches/new-dir-format/src/inc/proto.h
===================================================================
--- branches/new-dir-format/src/inc/proto.h	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/inc/proto.h	2004-05-27 00:07:46 UTC (rev 943)
@@ -31,7 +31,7 @@
 int ocfs_free_extents_for_truncate (ocfs_super * osb, ocfs_file_entry * FileEntry, ocfs_journal_handle *handle, struct inode *inode);
 int ocfs_lookup_file_allocation (ocfs_super * osb, __s64 Vbo, __s64 * Lbo, __u32 sectors, u32 *sector_count, struct inode *inode);
 int ocfs_get_leaf_extent (ocfs_super * osb, ocfs_file_entry * FileEntry, __s64 Vbo, struct buffer_head **data_extent_bh, struct inode *inode);
-int ocfs_find_contiguous_space_from_bitmap (ocfs_super * osb, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count,int sysfile, struct buffer_head *lock_bh, struct inode *bitmap_inode);
+int ocfs_find_contiguous_space_from_bitmap (ocfs_super * osb, ocfs_journal_handle *handle, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count,int sysfile, struct buffer_head *lock_bh, struct inode *bitmap_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_free_file_extents (ocfs_super * osb, struct buffer_head *fe_bh, ocfs_journal_handle *handle, struct inode *inode);
 
@@ -188,8 +188,8 @@
 void ocfs_reinitialize_bitmap(ocfs_alloc_bm *bitmap, __u32 validbits, __u32 allocbits);
 int ocfs_find_clear_bits (ocfs_super *osb, ocfs_alloc_bm * bitmap, __u32 numBits, __u32 offset, __u32 sysonly);
 int ocfs_count_bits (ocfs_alloc_bm * bitmap);
-void ocfs_set_bits (ocfs_alloc_bm * bitmap, __u32 start, __u32 num);
-void ocfs_clear_bits (ocfs_alloc_bm * bitmap, __u32 start, __u32 num);
+void ocfs_set_bits (ocfs_journal_handle *handle, ocfs_alloc_bm * bitmap, __u32 start, __u32 num);
+void ocfs_clear_bits (ocfs_journal_handle *handle, ocfs_alloc_bm * bitmap, __u32 start, __u32 num);
 
 int ocfs_get_config (ocfs_super * osb);
 int ocfs_chk_update_config (ocfs_super * osb);

Modified: branches/new-dir-format/src/inode.c
===================================================================
--- branches/new-dir-format/src/inode.c	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/inode.c	2004-05-27 00:07:46 UTC (rev 943)
@@ -1819,27 +1819,6 @@
 		goto leave;
 	}
 
-#if 0
-	disk_len = strlen(fe->filename);
-
-	status = -ENOENT;
-	list_for_each_safe (iter, temp_iter, &(inode->i_dentry)) {
-		struct dentry *dentry = list_entry (iter, struct dentry, d_alias);
-		if (dentry->d_name.len == disk_len &&
-		    strncmp(dentry->d_name.name, fe->filename, disk_len)==0)
-				status = 0;
-	}
-
-	/* isn't it OK for an inode to have no dentry yet? */
-	if (list_empty(&inode->i_dentry))
-		status = 0;
-
-	if (status < 0) {
-		LOG_TRACE_STR ("file entry name did not match inode");
-		goto leave;
-	}
-#endif
-
 	if ((OCFS_I(inode)->alloc_size != (__s64) fe->alloc_size) ||
 	    (inode->i_size != (__s64) fe->file_size) ||
 	    (OCFS_I(inode)->chng_seq_num != DISK_LOCK_SEQNUM (fe)) ||

Modified: branches/new-dir-format/src/journal.c
===================================================================
--- branches/new-dir-format/src/journal.c	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/journal.c	2004-05-27 00:07:46 UTC (rev 943)
@@ -92,7 +92,7 @@
 
 	retval->journal = &osb->journal;
 	retval->osb = osb;
-	retval->commit_bits = retval->abort_bits = NULL;
+	retval->commit_bits = NULL;
 
 	/* actually start the transaction now */
 	retval->k_handle = journal_start(journal, max_buffs);
@@ -339,7 +339,7 @@
 	int retval, i;
 	int checkpoint, sync;
 	ocfs_journal *journal;
-	ocfs_bitmap_free_head *commit_head, *abort_head;
+	ocfs_bitmap_free_head *commit_head;
 
 	LOG_ENTRY();
 
@@ -440,8 +440,7 @@
 
 	/* save off while we still have trans lock */
 	commit_head = handle->commit_bits;
-	abort_head = handle->abort_bits;
-	handle->commit_bits = handle->abort_bits = NULL;
+	handle->commit_bits = NULL;
 
 	/* This has to happen after we release the other locks. */
 	ocfs_release_trans_lock(osb);
@@ -452,7 +451,6 @@
 		ocfs_process_bitmap_free_head(osb, commit_head);
 	}
 	ocfs_free_bitmap_free_head(commit_head);
-	ocfs_free_bitmap_free_head(abort_head);
 
 	if (checkpoint)
 		ocfs_free(handle);
@@ -575,28 +573,20 @@
 	osb->journal.curr = NULL;
 	up(&osb->journal.commit_sem);
 
-	/* Ok, we now want to fill our buffers with the older (but
-	 * valid) data, instead of leaving them with the aborted
-	 * data. To do so we want to first checkpoint the valid
-	 * transactions in the journal so that we know that disk
-	 * reflects the latest correct blocks. After that, we just
-	 * repopulate the buffers from disk. */
-	journal_lock_updates(journal->k_journal);
-	retval = journal_flush(journal->k_journal);
-	journal_unlock_updates(journal->k_journal);
-	if (retval < 0)
-		LOG_ERROR_STATUS(retval);
+	if (handle->num_buffs) {
+		/* Ok, we now want to fill our buffers with the older (but
+		 * valid) data, instead of leaving them with the aborted
+		 * data. To do so we want to first checkpoint the valid
+		 * transactions in the journal so that we know that disk
+		 * reflects the latest correct blocks. After that, we just
+		 * repopulate the buffers from disk. */
+		journal_lock_updates(journal->k_journal);
+		retval = journal_flush(journal->k_journal);
+		journal_unlock_updates(journal->k_journal);
+		if (retval < 0)
+			LOG_ERROR_STATUS(retval);
+	}
 
-	/* If we ever worry about abort performance, I'm 90% sure this
-	 * read is not necessary. */
-	if (handle->num_buffs != 0)
-		retval = ocfs_read_bhs(osb, 
-				       handle->buffs[0]->b_blocknr * osb->sect_size,
-				       handle->num_buffs * osb->sect_size, 
-				       handle->buffs, 0, NULL);
-	if (retval < 0)
-		LOG_ERROR_STATUS(retval);
-
 	for(i = 0; i < handle->num_buffs; i++) {
 		ocfs_clear_buffer_modified(handle->buffs[i]);
 		brelse(handle->buffs[i]);
@@ -610,12 +600,8 @@
 	/* This has to happen after we release the other locks. */
 	ocfs_release_trans_lock(osb);
 
-	/* no need to save off commit or abort heads here; not on any lists */
-	if (handle->abort_bits && (retval == 0))
-		ocfs_process_bitmap_free_head(osb, handle->abort_bits);
-
+	/* Should only be processed in commit. */
 	ocfs_free_bitmap_free_head(handle->commit_bits);
-	ocfs_free_bitmap_free_head(handle->abort_bits);
 
 	if (handle->buffs)
 		ocfs_free(handle->buffs);
@@ -685,8 +671,11 @@
 			handle->co_buffs[i].data = NULL;
 			handle->co_buffs[i].forget = 1;
 		} else {
-			LOG_TRACE_ARGS("Copying block (%lu) out to position"
-				       "%d\n", bh->b_blocknr, i);
+			/* WRITE or UNDO access */
+			LOG_TRACE_ARGS("Copying block (%llu) out to position "
+				       "%d\n",
+				       (unsigned long long)bh->b_blocknr, i);
+
 			/* This malloc should just be a slab. */
 			handle->co_buffs[i].data = ocfs_malloc(bh->b_size);
 			if (handle->co_buffs[i].data == NULL) {
@@ -707,6 +696,14 @@
 #endif
 		break;
 
+	case OCFS_JOURNAL_ACCESS_UNDO:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+		status = journal_get_undo_access(handle->k_handle, bh, NULL);
+#else
+		status = journal_get_undo_access(handle->k_handle, bh);
+#endif
+		break;
+
 	default:
 		status = -EINVAL;
 		LOG_ERROR_STR("Uknown access type!");
@@ -878,15 +875,6 @@
 	}
 	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(bh); /* read */
 
-	/* for version 2.0, must be "JournalFile###" */
-	if (strncmp(fe->filename, OCFS_JOURNAL_FILENAME, 
-		    strlen(OCFS_JOURNAL_FILENAME))) {
-		LOG_ERROR_ARGS("Incorrect journal version!  (%*s)\n",
-			       OCFS_MAX_FILENAME_LENGTH-1,
-			       fe->filename);
-		status = -EINVAL;
-	}
-
 	/* should be exactly eight megs.  need to run tuneocfs otherwise. */
 	if (fe->file_size != OCFS_JOURNAL_DEFAULT_SIZE) {
 		LOG_ERROR_ARGS("Journal file size (%llu) is not the default (%u).  "

Modified: branches/new-dir-format/src/namei.c
===================================================================
--- branches/new-dir-format/src/namei.c	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/namei.c	2004-05-27 00:07:46 UTC (rev 943)
@@ -311,6 +311,8 @@
 	ocfs_file_entry *fe = NULL;
 	__u64 bitmapOffset = 0;
 	__u64 fileOffset = 0;
+	__u64 inode_alloc_off;
+	struct inode *inode_alloc_inode = NULL;
 
 	LOG_ENTRY_ARGS ("(0x%p, 0x%p, %d, %d, '%*s')\n", dir, dentry, mode,
 			dev, dentry->d_name.len, dentry->d_name.name);
@@ -318,11 +320,20 @@
 	OCFS_ASSERT(new_fe_bh);
 	*new_fe_bh = NULL;
 
-	down(&osb->node_alloc_sem);
+	inode_alloc_off = ((OCFS_INODE_BITMAP + osb->node_num) * osb->sect_size) + osb->vol_layout.root_int_off;
+	inode_alloc_inode = ocfs_iget(osb, inode_alloc_off, NULL);
+	if (!inode_alloc_inode) {
+		status = -EFAIL;
+		LOG_ERROR_STATUS(status);
+		goto leave;
+	}
+
+	down(&inode_alloc_inode->i_sem);
 	status = ocfs_alloc_node_block (osb, osb->inode_size,
-					&bitmapOffset, &fileOffset, osb->node_num, 
-					DISK_ALLOC_INODE, handle);
-	up(&osb->node_alloc_sem);
+					&bitmapOffset, &fileOffset, 
+					osb->node_num, DISK_ALLOC_INODE, 
+					handle);
+	up(&inode_alloc_inode->i_sem);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
 		goto leave;
@@ -401,6 +412,10 @@
 		goto leave;
 	}
 
+	/* Inode is not yet fully populated, but we need some fields
+	 * for add_entry. */
+	inode->i_mode = mode;
+
 	status = ocfs_add_entry (handle, dentry, inode, bitmapOffset, parent_fe_bh);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
@@ -418,6 +433,9 @@
 		brelse(*new_fe_bh);
 		*new_fe_bh = NULL;
 	}
+	if (inode_alloc_inode)
+		iput(inode_alloc_inode);
+
 	LOG_EXIT_STATUS (status);
 	return status;
 }				/* ocfs_mknod_locked */

Modified: branches/new-dir-format/src/osb.c
===================================================================
--- branches/new-dir-format/src/osb.c	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/osb.c	2004-05-27 00:07:46 UTC (rev 943)
@@ -73,8 +73,6 @@
 	init_MUTEX (&(osb->extend_sem));
 	init_MUTEX (&(osb->cfg_lock));
 	init_MUTEX (&(osb->vote_sem));
-	init_MUTEX (&(osb->node_alloc_sem));
-	init_MUTEX (&(osb->vol_alloc_sem));
 	init_MUTEX (&(osb->local_alloc_sem));
 
 	spin_lock_init(&osb->recovery_map_lock);

Modified: branches/new-dir-format/src/sysfile.c
===================================================================
--- branches/new-dir-format/src/sysfile.c	2004-05-26 20:37:34 UTC (rev 942)
+++ branches/new-dir-format/src/sysfile.c	2004-05-27 00:07:46 UTC (rev 943)
@@ -281,7 +281,7 @@
 		__u64 numClusterAlloc = 0, BitmapOffset = 0;
 
 		status =
-		    ocfs_find_contiguous_space_from_bitmap (osb,
+			ocfs_find_contiguous_space_from_bitmap (osb, handle,
 						   FileSize - alloc_size,
 						   &BitmapOffset,
 						   &numClusterAlloc, 1, 
@@ -305,6 +305,7 @@
 		}
 		
 		if (zero) {
+			/* I think at this point, this can be journalled too */
 			numbhs = actualLength >> osb->sect_size_bits;
 
 			bhs = ocfs_malloc(numbhs*sizeof(struct buffer_head *));



More information about the Ocfs2-commits mailing list