[Ocfs2-commits] khackel commits r932 - in branches/new-dir-format/src: . inc

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Mon May 24 17:34:50 CDT 2004


Author: khackel
Date: 2004-05-24 16:34:48 -0500 (Mon, 24 May 2004)
New Revision: 932

Modified:
   branches/new-dir-format/src/alloc.c
   branches/new-dir-format/src/dcache.c
   branches/new-dir-format/src/dir.c
   branches/new-dir-format/src/dlm.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/ocfs.h
   branches/new-dir-format/src/inc/proto.h
   branches/new-dir-format/src/inode.c
   branches/new-dir-format/src/io.c
   branches/new-dir-format/src/journal.c
   branches/new-dir-format/src/lockres.c
   branches/new-dir-format/src/namei.c
   branches/new-dir-format/src/nm.c
   branches/new-dir-format/src/osb.c
   branches/new-dir-format/src/proc.c
   branches/new-dir-format/src/super.c
   branches/new-dir-format/src/util.c
Log:
first commit of the new directory stuff
cuz people were getting antsy ;-)



Modified: branches/new-dir-format/src/alloc.c
===================================================================
--- branches/new-dir-format/src/alloc.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/alloc.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -184,11 +184,9 @@
 	__u32 num_upd;
 	__u32 i;
 	__u32 node_num;
-	ocfs_free_rec **free_dir_node = NULL;
 	ocfs_free_rec **free_ext_node = NULL;
 	ocfs_free_rec *free_vol_bits = NULL;
 	ocfs_free_rec *tmp_log;
-	struct inode **dirnode_inode = NULL;
 	struct inode **extnode_inode = NULL;
 	struct inode *vol_inode = NULL;
 	__u32 tmp_indx;
@@ -206,20 +204,14 @@
 		}						\
 	} while (0)
 
-	ALLOC_BLOCK(free_dir_node,
-		    OCFS_MAXIMUM_NODES * sizeof (ocfs_free_rec *), status);
 	ALLOC_BLOCK(free_ext_node,
 		    OCFS_MAXIMUM_NODES * sizeof (ocfs_free_rec *), status);
-	ALLOC_BLOCK(dirnode_inode,
-		    OCFS_MAXIMUM_NODES * sizeof (struct inode *), status);
 	ALLOC_BLOCK(extnode_inode,
 		    OCFS_MAXIMUM_NODES * sizeof (struct inode *), status);
 
 	/* init */
 	for (i = 0; i < OCFS_MAXIMUM_NODES; i++) {
-		free_dir_node[i] = NULL;
 		free_ext_node[i] = NULL;
-		dirnode_inode[i] = NULL;
 		extnode_inode[i] = NULL;
 	}
 
@@ -227,19 +219,6 @@
 	num_upd = free_log->num_updates;
 	for (i = 0; i < num_upd; i++) {
 		switch (free_log->update[i].type) {
-		    case DISK_ALLOC_DIR_NODE:
-			    node_num = free_log->update[i].node_num;
-			    if (free_dir_node[node_num] == NULL) {
-				    free_dir_node[node_num] =
-					ocfs_malloc (sizeof (ocfs_free_rec));
-				    if (free_dir_node[node_num] == NULL) {
-					    LOG_ERROR_STATUS (status = -ENOMEM);
-					    goto finally;
-				    }
-				    free_dir_node[node_num]->num_updates = 0;
-			    }
-			    tmp_log = free_dir_node[node_num];
-			    break;
 
 		    case DISK_ALLOC_EXTENT_NODE:
 			    node_num = free_log->update[i].node_num;
@@ -293,28 +272,6 @@
 	/* Get all the locks we need. do global bitmap last to
 	 * preserve lock ordering with extend/create */
 
-	lock_id = (OCFS_FILE_DIR_ALLOC_BITMAP * osb->sect_size) +
-		  osb->vol_layout.root_int_off;
-	for (i = 0; i < OCFS_MAXIMUM_NODES; i++, lock_id += osb->sect_size) {
-		if (free_dir_node[i] != NULL) {
-			dirnode_inode[i] = ocfs_iget(osb, lock_id, NULL);
-			if (!dirnode_inode[i]) {
-				status = -EINVAL;
-				LOG_ERROR_STATUS (status);
-				goto finally;
-			}
-			status = ocfs_acquire_lock (osb, lock_id,
-						    OCFS_DLM_EXCLUSIVE_LOCK,
-						    FLAG_FILE_CREATE,
-						    NULL, dirnode_inode[i]);
-			if (status < 0) {
-				if (status != -EINTR)
-					LOG_ERROR_STATUS (status);
-				goto finally;
-			}
-		}
-	}
-
 	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) {
@@ -364,10 +321,6 @@
 	/* 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_dir_node[i] != NULL)
-			ocfs_free_vol_block (osb, free_dir_node[i], i,
-					     DISK_ALLOC_DIR_NODE);
-
 		if (free_ext_node[i] != NULL)
 			ocfs_free_vol_block (osb, free_ext_node[i], i,
 					     DISK_ALLOC_EXTENT_NODE);
@@ -395,21 +348,6 @@
 		}
 	}
 
-	lock_id = (OCFS_FILE_DIR_ALLOC_BITMAP * osb->sect_size) +
-		  osb->vol_layout.root_int_off;
-	for (i = 0; i < OCFS_MAXIMUM_NODES; i++, lock_id += osb->sect_size) {
-		if (free_dir_node[i] != NULL) {
-			status = ocfs_release_lock (osb, lock_id,
-						    OCFS_DLM_EXCLUSIVE_LOCK,
-						    FLAG_FILE_CREATE,
-						    NULL, dirnode_inode[i]);
-			if (status < 0) {
-				LOG_ERROR_STATUS (status);
-				goto finally;
-			}
-		}
-	}
-
 	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) {
@@ -431,8 +369,6 @@
 	for (i = 0; i < OCFS_MAXIMUM_NODES; i++) {
 		if (extnode_inode[i])
 			iput(extnode_inode[i]);
-		if (dirnode_inode[i])
-			iput(dirnode_inode[i]);
 	}
 	if (globalbh)
 		brelse(globalbh);
@@ -440,13 +376,11 @@
 		iput(vol_inode);
 
 	for (i = 0; i < OCFS_MAXIMUM_NODES; i++) {
-		ocfs_safefree (free_dir_node[i]);
 		ocfs_safefree (free_ext_node[i]);
 	}
 
-	ocfs_safefree (free_dir_node);
 	ocfs_safefree (free_ext_node);
-	ocfs_safefree (dirnode_inode);
+	
 	ocfs_safefree (extnode_inode);
 
 	ocfs_safefree (free_vol_bits);
@@ -520,28 +454,17 @@
 	ocfs_alloc_bm AllocBitmap;
 	ocfs_alloc_bm *tmpbitmap = NULL;
 	__u32 i;
-	int needs_uninit = 0;
-	int needs_unlock = 0;
 
 	LOG_ENTRY ();
 
 	LOG_TRACE_ARGS("Free Log Details (type = %d):\n", Type);
 	LOG_TRACE_ARGS("num_updates = %u\n", FreeLog->num_updates);
 	for(i = 0; i < FreeLog->num_updates; i++)
-		LOG_TRACE_ARGS("(upd=%u, length=%llu, file_off=%llu, type=%d, node_num=%d)\n", i, FreeLog->update[i].length, FreeLog->update[i].file_off, FreeLog->update[i].type, FreeLog->update[i].node_num);
+		LOG_TRACE_ARGS("(upd=%u, length=%llu, file_off=%llu, type=%d, node_num=%d)\n", 
+			       i, FreeLog->update[i].length, FreeLog->update[i].file_off, 
+			       FreeLog->update[i].type, FreeLog->update[i].node_num);
 
 	switch (Type) {
-	    case DISK_ALLOC_DIR_NODE:
-		    fileId = OCFS_FILE_DIR_ALLOC_BITMAP + NodeNum;
-		    blockSize = (__u32) osb->vol_layout.dir_node_size;
-		    blockSizeBits = osb->dir_alloc_bits;
-
-		    if (!IS_VALID_NODE_NUM (NodeNum)) {
-			    LOG_ERROR_STATUS(status = -EINVAL);
-			    goto leave;
-		    }
-		    break;
-
 	    case DISK_ALLOC_EXTENT_NODE:
 		    fileId = OCFS_FILE_FILE_ALLOC_BITMAP + NodeNum;
 		    blockSize = (__u32) osb->vol_layout.file_node_size;
@@ -553,96 +476,73 @@
 		    }
 		    break;
 
-	    case DISK_ALLOC_VOLUME:
+	    case DISK_ALLOC_INODE:
+		    fileId = OCFS_INODE_BITMAP + NodeNum;
+		    blockSize = (__u32) osb->inode_size;
+		    blockSizeBits = osb->inode_alloc_bits;
 		    break;
 
+	    case DISK_ALLOC_VOLUME:
+		    down (&(osb->vol_alloc_sem));
+		    status = ocfs_free_main_bitmap(osb, FreeLog);
+		    up (&(osb->vol_alloc_sem));
+		    if (status < 0)
+			    LOG_ERROR_STATUS (status);
+		    goto leave;
 	    default:
 		    goto leave;
 	}
 
-	if (Type == DISK_ALLOC_VOLUME) {
-		down (&(osb->vol_alloc_sem));
-		needs_unlock = 1;
+	if (!IS_VALID_NODE_NUM (NodeNum)) {
+		LOG_ERROR_STATUS(status = -EINVAL);
+		goto leave;
+	}
 
-		/* don't need to read it here as
-		 * ocfs_free_main_bitmap handles that for us. */
-		tmpbitmap = &osb->cluster_bitmap;
-	} else {
-		down(&(osb->node_alloc_sem));
-		needs_unlock = 1;
+	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) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-
-		ocfs_initialize_bitmap(&AllocBitmap, fileSize * 8, allocSize * 8);
-		tmpbitmap = &AllocBitmap;
-		needs_uninit = 1;
-		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) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-
+	/* 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;
 	}
 
-	if (Type == DISK_ALLOC_VOLUME) {
-		status = ocfs_free_main_bitmap(osb, FreeLog);
-		if (status < 0){
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-	} else {
-		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);
-			}
-			
-			if (Type == DISK_ALLOC_VOLUME)
-				foundBit = (__u32) FreeLog->update[i].file_off;
-			else
-				foundBit = (__u32) 
-					(FreeLog->update[i].file_off >>
-					 blockSizeBits);
-			ocfs_clear_bits(tmpbitmap, (__u32) foundBit,
-				       (__u32) FreeLog->update[i].length);
-		}
-	}
+	ocfs_initialize_bitmap(&AllocBitmap, fileSize * 8, allocSize * 8);
+	tmpbitmap = &AllocBitmap;
+	bitmapblocks = (OCFS_ALIGN(tmpbitmap->validbits, OCFS_BITS_IN_CHUNK) / OCFS_BITS_IN_CHUNK);
 	
-	/* ocfs_free_main_bitmap handles all the reads/writes for the
-	 * main bitmap */
-	if (Type != DISK_ALLOC_VOLUME) {
-		/* 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);
-			goto leave;
-		}
+	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;
 	}
-leave:
-	if (needs_unlock) {
-		if (Type == DISK_ALLOC_VOLUME)
-			up (&(osb->vol_alloc_sem));
-		else
-			up (&(osb->node_alloc_sem));
+
+	for (i = 0; i < FreeLog->num_updates; i++) {
+		foundBit = (__u32) (FreeLog->update[i].file_off >> blockSizeBits);
+		ocfs_clear_bits(tmpbitmap, (__u32) foundBit,
+			       (__u32) FreeLog->update[i].length);
 	}
 
-	if (needs_uninit)
+	/* 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);
 
 	LOG_EXIT_STATUS (status);
@@ -2471,7 +2371,7 @@
 	__u64 cnt;
 	__u32 NumIndex;
 
-	LOG_ENTRY ();
+	LOG_ENTRY_ARGS("(vbo=%llu, sectors=%u, inode=%llu)\n", Vbo, sectors, GET_INODE_FEOFF(inode));
 
 	OCFS_ASSERT (osb);
 	OCFS_ASSERT (inode);
@@ -2937,20 +2837,24 @@
 
 	LOG_ENTRY_ARGS("(FileSize = (%llu), Type=%d)\n", FileSize,Type);
 
-	if (Type == DISK_ALLOC_DIR_NODE) {
-		bm_file = OCFS_FILE_DIR_ALLOC_BITMAP + NodeNum;
-		blockSize = (__u32) osb->vol_layout.dir_node_size;
-		blockSizeBits = osb->dir_alloc_bits;
-		alloc_file = OCFS_FILE_DIR_ALLOC + NodeNum;
-
-		atomic_inc(&osb->alloc_stats.dir_allocs);
-	} else if (Type == DISK_ALLOC_EXTENT_NODE) {
-		bm_file = OCFS_FILE_FILE_ALLOC_BITMAP + NodeNum;
-		alloc_file = OCFS_FILE_FILE_ALLOC + NodeNum;
-		blockSize = (__u32) osb->vol_layout.file_node_size;
-		blockSizeBits = osb->file_alloc_bits;
-
-		atomic_inc(&osb->alloc_stats.ext_allocs);
+	switch (Type) {
+		case DISK_ALLOC_EXTENT_NODE:
+			bm_file = OCFS_FILE_FILE_ALLOC_BITMAP + NodeNum;
+			alloc_file = OCFS_FILE_FILE_ALLOC + NodeNum;
+			blockSize = (__u32) osb->vol_layout.file_node_size;
+			blockSizeBits = osb->file_alloc_bits;
+			atomic_inc(&osb->alloc_stats.ext_allocs);
+			break;
+		case DISK_ALLOC_INODE:
+			bm_file = OCFS_INODE_BITMAP + NodeNum;
+			alloc_file = OCFS_INODE_FILE + NodeNum;
+			blockSize = (__u32) osb->inode_size;
+			blockSizeBits = osb->inode_alloc_bits;
+			break;
+		default:
+			status = -EINVAL;
+			LOG_ERROR_STATUS(status);
+			goto leave;
 	}
 
 	/* Allocate a block of size blocksize from the relevant file/bitmap */
@@ -3074,10 +2978,7 @@
 		foundBit = prevFileSize * 8;
 
 		delay_lockrel = 1;
-
-		if (Type == DISK_ALLOC_DIR_NODE)
-			atomic_inc(&osb->alloc_stats.dir_extends);
-		else
+		if (Type == DISK_ALLOC_EXTENT_NODE)
 			atomic_inc(&osb->alloc_stats.ext_extends);
 	}
 
@@ -3143,74 +3044,6 @@
 }				/* ocfs_alloc_node_block */
 
 /*
- * ocfs_free_directory_block()
- *
- */
-int ocfs_free_directory_block (ocfs_super * osb, ocfs_file_entry * fe, 
-			       ocfs_journal_handle *handle, 
-			       struct inode *inode)
-{
-	int status = 0;
-	struct buffer_head *dir_hdr_bh = NULL;
- 	ocfs_dir_node *dirnode = NULL;
-	__u64 currentDirNode;
-
-	LOG_ENTRY ();
-
-	currentDirNode = fe->u.child_dirnode;
-
-	status = ocfs_read_bh(osb, currentDirNode, &dir_hdr_bh, 
-			      OCFS_BH_COND_CACHED, inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto leave;
-	}
-
-	dirnode = (ocfs_dir_node *) OCFS_BH_GET_DATA_READ(dir_hdr_bh); /* read */
-
-	while ((dirnode->node_disk_off != INVALID_NODE_POINTER) &&
-	       (IS_VALID_DIR_NODE (dirnode))) {
-
-		status = ocfs_handle_add_commit_bits(handle, 1, 
-					  dirnode->alloc_file_off,
-					  dirnode->alloc_node,
-					  DISK_ALLOC_DIR_NODE);
-
-		currentDirNode = dirnode->next_node_ptr;
-		OCFS_BH_PUT_DATA(dir_hdr_bh);
-		dir_hdr_bh = NULL;
-		dirnode = NULL;
-		if (status < 0) {
-			LOG_ERROR_STATUS(status);
-			goto leave;
-		}
-
-		if (currentDirNode != INVALID_NODE_POINTER) {
-			status = ocfs_read_bh(osb, currentDirNode, &dir_hdr_bh,
-					      OCFS_BH_COND_CACHED, inode);
-			if (status < 0) {
-				LOG_ERROR_STATUS (status);
-				goto leave;
-			}
-			dirnode = (ocfs_dir_node *) OCFS_BH_GET_DATA_READ(dir_hdr_bh); /* read */
-			continue;
-		} else {
-			break;
-		}
-	}
-
-leave:
-	if (dir_hdr_bh) {
-		if (dirnode)
-			OCFS_BH_PUT_DATA(dir_hdr_bh);
-		brelse(dir_hdr_bh);
-	}
-
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_free_directory_block */
-
-/*
  * ocfs_free_file_extents()
  *
  */
@@ -3415,51 +3248,6 @@
 		goto bail;
 	}
 	OCFS_BH_PUT_DATA(local_alloc_bh);
-
-	if (bm_lock_bh) {
-		local_lock = 0;
-		bh = bm_lock_bh;
-	}
-	
-	if (bm_inode) {
-		atomic_inc(&bm_inode->i_count);
-		local_inode = bm_inode;
-	} else {
-		local_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET, NULL);
-		if (!local_inode) {
-			status = -EINVAL;
-			LOG_ERROR_STATUS(status);
-			goto bail;
-		}
-	}
-
-	if (local_lock) {
-		down (&(osb->vol_alloc_sem));
-
-		/* Get the allocation lock here */
-		status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
-					    OCFS_DLM_EXCLUSIVE_LOCK, 
-					    (in_recovery) ? FLAG_FILE_RECOVERY 
-					    : 0, &bh, local_inode);
-		if (status < 0) {
-			if (status != -EINTR)
-				LOG_ERROR_STATUS (status);
-			goto bail;
-		}
-		got_lock = 1;
-	}
-
-	bitmapblocks = (OCFS_ALIGN(osb->cluster_bitmap.validbits, 
-				   OCFS_BITS_IN_CHUNK) / OCFS_BITS_IN_CHUNK);
-
-	status = ocfs_read_bhs(osb, osb->vol_layout.bitmap_off, 
-			       bitmapblocks * osb->sect_size, 
-			       osb->cluster_bitmap.chunk, 0, NULL);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto bail;
-	}
-
 	if (!(*f)) {
 		*f = ocfs_alloc_bitmap_free_head();
 		if (*f == NULL) {
@@ -3500,24 +3288,6 @@
 	OCFS_BH_PUT_DATA(local_alloc_bh);
 
 bail:
-	if (local_lock) {
-		up (&(osb->vol_alloc_sem));
-
-		if (got_lock) {
-			tmpstat = ocfs_release_lock (osb, 
-						     OCFS_BITMAP_LOCK_OFFSET,
-						     OCFS_DLM_EXCLUSIVE_LOCK, 
-						     0, bh, local_inode);
-			if (tmpstat < 0)
-				LOG_ERROR_STATUS (tmpstat);
-		}
-		if (bh != NULL)
-			brelse(bh);
-	}
-
-	if (local_inode)
-		iput(local_inode);
-
 	LOG_EXIT_STATUS(status);
 	return(status);
 } /* ocfs_sync_local_to_main */
@@ -3997,7 +3767,7 @@
 	else
 		bh = osb->local_alloc_bh;
 
-	status = ocfs_sync_local_to_main(osb, &f, NULL, NULL, NULL,
+	status = ocfs_sync_local_to_main(osb, &f, bh, NULL, NULL,
 					 in_recovery);
 	if (status < 0)
 		LOG_ERROR_STATUS(status);

Modified: branches/new-dir-format/src/dcache.c
===================================================================
--- branches/new-dir-format/src/dcache.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/dcache.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -58,16 +58,15 @@
 
 	OCFS_ASSERT(osb);
 
-	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
+	if (inode == osb->root_inode) {
 		ret = 1;
 		goto bail;
 	}
 
 	/* did we or someone else delete this inode? */
 	if (INODE_DELETED(inode)) {
-		LOG_TRACE_ARGS("dentry_revalidate: inode %lu (%llu) deleted, "
-			       "returning false\n", inode->i_ino, 
-			       GET_INODE_FEOFF(inode));
+		LOG_TRACE_ARGS("dentry_revalidate: inode (%llu) deleted, "
+			       "returning false\n", GET_INODE_FEOFF(inode));
 		goto bail;
 	}
 

Modified: branches/new-dir-format/src/dir.c
===================================================================
--- branches/new-dir-format/src/dir.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/dir.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -28,173 +28,154 @@
 
 #define OCFS_DEBUG_CONTEXT    OCFS_DEBUG_CONTEXT_DIR
 
-static int ocfs_insert_dir_node (ocfs_super * osb, struct buffer_head *bhs[], ocfs_file_entry * InsertEntry, struct buffer_head *lockbh, __s32 * IndexOffset, struct buffer_head **insert_bh, ocfs_journal_handle * handle, struct inode *dir_inode, struct inode *file_inode);
-static int ocfs_search_dir_node (ocfs_super * osb, struct buffer_head *bhs[], struct qstr * SearchName, struct buffer_head ** found_fe_bh, ocfs_file * OFile, struct inode *dir_inode, int sync);
-static int ocfs_find_index (ocfs_super * osb, struct buffer_head *bhs[], 
-			     struct qstr * FileName, int *Index);
-#if 0
-static void ocfs_print_dir_node (ocfs_super * osb, ocfs_dir_node * DirNode);
-static void ocfs_print_file_entry (ocfs_file_entry * fe);
-#endif
+static unsigned char ocfs_filetype_table[] = {
+	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+};
 
 /*
  * ocfs_readdir()
  *
  */
-int ocfs_readdir (struct file *filp, void *dirent, filldir_t filldir)
+int ocfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 {
-	int pos;
-	struct super_block *sb;
-	ocfs_super *osb;
-	ocfs_file *ofile;
-	struct buffer_head *entry_bh = NULL;
-	ocfs_file_entry *entry = NULL;
-	int ret = 0;
+	int error = 0;
+	unsigned long offset, blk;
+	int i, num, stored;
+	struct buffer_head * bh, * tmp, * bha[16];
+	struct ocfs2_dir_entry * de;
+	int err;
 	struct inode *inode = filp->f_dentry->d_inode;
+	struct super_block * sb = inode->i_sb;
+	char *buf = NULL;
 
-	LOG_ENTRY_ARGS ("(0x%p, 0x%p, '%*s')\n", filp, dirent, 
-			filp->f_dentry->d_name.len, filp->f_dentry->d_name.name);
+	LOG_ENTRY_ARGS("dirino=%llu\n", GET_INODE_FEOFF(inode));
 
-	pos = filp->f_pos;
-	sb = inode->i_sb;
-	osb = OCFS_SB(sb);
+	stored = 0;
+	bh = NULL;
+	offset = filp->f_pos & (sb->s_blocksize - 1);
 
-	if (!osb) {
-		LOG_TRACE_STR ("Invalid OSB");
-		goto bail;
-	}
+	while (!error && !stored && filp->f_pos < inode->i_size) {
+		blk = (filp->f_pos) >> OCFS_SB(sb)->sect_size_bits;
+		bh = ocfs_bread (0, inode, blk, 0, &err, 0);
+		if (!bh) {
+			LOG_ERROR_ARGS ("directory #%llu contains a hole at offset %lu\n",
+					GET_INODE_FEOFF(inode), (unsigned long)filp->f_pos);
+			filp->f_pos += sb->s_blocksize - offset;
+			continue;
+		}
 
-	if (!S_ISDIR (inode->i_mode)) {
-		LOG_TRACE_STR ("Not a dir");
-		ret = -ENOTDIR;
-		goto bail;
-	}
+		/*
+		 * Do the readahead (8k)
+		 */
+		if (!offset) {
+			for (i = 16 >> (OCFS_SB(sb)->sect_size_bits - 9), num = 0;
+			     i > 0; i--) {
+				tmp = ocfs_bread (NULL, inode, ++blk, 0, &err, 1);
+				brelse (tmp);
+			}
+		}
 
-	switch (pos) {
-	    case 0:
-	    {
-		    if (filldir (dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
-			    break;
-		    pos++;
-		    filp->f_pos++;
-		    break;
-	    }
-	    case 1:
-	    {
-		    if (filldir (dirent, "..", 2, 1,
-				 filp->f_dentry->d_parent->d_inode->i_ino,
-				 DT_DIR) < 0)
-			    break;
-		    pos++;
-		    filp->f_pos++;
-		    break;
-	    }
-		    /* case 2: */
-	    default:
-	    {
-		    if (pos == 2) {
-			    if (filp->private_data)
-				    ocfs_release_ofile(((ocfs_file *) filp->private_data));
-			    filp->private_data = ocfs_allocate_ofile(OCFS_ATTRIB_DIRECTORY);
-			    if (filp->private_data == NULL) {
-				    LOG_TRACE_STR ("Failed to allocate OFile");
-				    ret = -ENOMEM;
-				    goto bail;
-			    }
-		    }
+		if (buf) {
+#warning take this out later
+			LOG_ERROR_ARGS("uhoh!  buf not null... block=%lu\n", bh->b_blocknr);
+			BUG();
+		}
+		buf = OCFS_BH_GET_DATA_READ(bh); /* read */
+revalidate:
+		/* If the dir block has changed since the last call to
+		 * readdir(2), then we might be pointing to an invalid
+		 * dirent right now.  Scan from the start of the block
+		 * to make sure. */
+		if (filp->f_version != inode->i_version) {
+			for (i = 0; i < sb->s_blocksize && i < offset; ) {
+				de = (struct ocfs2_dir_entry *) (bh->b_data + i);
+				/* It's too expensive to do a full
+				 * dirent test each time round this
+				 * loop, but we do have to test at
+				 * least that it is non-zero.  A
+				 * failure will be detected in the
+				 * dirent test below. */
+				if (le16_to_cpu(de->rec_len) <
+				    OCFS_DIR_REC_LEN(1))
+					break;
+				i += le16_to_cpu(de->rec_len);
+			}
+			offset = i;
+			filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
+				| offset;
+			filp->f_version = inode->i_version;
+		}
 
-		    ofile = (ocfs_file *) filp->private_data;
-		    while (1) {
-			    int r;
-			    ino_t ino;
-			    __u64 voteoff;
-			    /* TODO: find out if we need locking around this ofile */
-			    if (ofile->filldir.ino != 0) {
-				    r=filldir (dirent, ofile->filldir.fname, strlen (ofile->filldir.fname), 
-						ofile->filldir.pos, ofile->filldir.ino, DT_UNKNOWN);
-				    ofile->filldir.ino = 0;
-				    if (r < 0)
-					   LOG_ERROR_STR("filldir failed"); 
-			    } else {
-				    r = ocfs_find_files_on_disk (osb, NULL, &entry_bh, 
-								 ofile, inode, 1);
-				    if (r < 0)
-					    break;
-				    entry = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(entry_bh); /* read */
-
-				    voteoff = entry->this_sector;
-				    ino = ocfs_inode_hash_lookup_ino(osb, voteoff);
-				    r=filldir (dirent, entry->filename, strlen (entry->filename), filp->f_pos, ino, DT_UNKNOWN);
-			    	    if (r < 0) {
-				    	memcpy(ofile->filldir.fname, entry->filename, OCFS_MAX_FILENAME_LENGTH);
-				    	ofile->filldir.pos = filp->f_pos;
-				    	ofile->filldir.ino = ino;
-				    }
-			    	    OCFS_BH_PUT_DATA(entry_bh);
-				    brelse(entry_bh);
-			    	    entry_bh = NULL; entry = NULL;
-				    if (r < 0)
-				    	goto bail;
-			    }
-			    pos++;
-			    filp->f_pos++;
-		    }
-
-		    break;
-	    }
+		while (!error && filp->f_pos < inode->i_size 
+		       && offset < sb->s_blocksize) {
+			de = (struct ocfs2_dir_entry *) (bh->b_data + offset);
+			if (!ocfs_check_dir_entry (inode, de, bh, offset)) {
+				/* On error, skip the f_pos to the
+				   next block. */
+				filp->f_pos = (filp->f_pos |
+					       (sb->s_blocksize - 1)) + 1;
+				if (buf) {
+					OCFS_BH_PUT_DATA(bh);
+					buf = NULL;
+				}
+				brelse (bh);
+				return stored;
+			}
+			offset += le16_to_cpu(de->rec_len);
+			if (le64_to_cpu(de->inode)) {
+				/* We might block in the next section
+				 * if the data destination is
+				 * currently swapped out.  So, use a
+				 * version stamp to detect whether or
+				 * not the directory has been modified
+				 * during the copy operation.
+				 */
+				unsigned long version = filp->f_version;
+				unsigned char d_type = DT_UNKNOWN;
+				
+				if (de->file_type < OCFS_FT_MAX)
+					d_type = ocfs_filetype_table[de->file_type];
+				error = filldir(dirent, de->name,
+						de->name_len,
+						filp->f_pos,
+						ino_from_off(sb, le64_to_cpu(de->inode)),
+						d_type);
+				if (error)
+					break;
+				if (version != filp->f_version)
+					goto revalidate;
+				stored ++;
+			}
+			filp->f_pos += le16_to_cpu(de->rec_len);
+		}
+		if (buf) {
+			OCFS_BH_PUT_DATA(bh);
+			buf = NULL;
+		}
+		offset = 0;
+		brelse (bh);
 	}
+	UPDATE_ATIME(inode);
+	LOG_EXIT_STATUS(0);
+	return 0;
+}
 
-bail:
-	if (entry_bh) {
-		if (entry)
-			OCFS_BH_PUT_DATA(entry_bh);
-		brelse(entry_bh);
-	}
-	LOG_EXIT_INT (ret);
-	return ret;
-}				/* ocfs_readdir */
 
 /* ocfs_find_files_on_disk()
  * NOTE: this should always be called with inode->i_sem taken!
  */
 /* parent off changed to file entry offset of parent! */
-int ocfs_find_files_on_disk (ocfs_super * osb, struct qstr * file_name, struct buffer_head ** fe_bh, ocfs_file * ofile, struct inode *inode, int take_lock)
+int ocfs_find_files_on_disk (ocfs_super * osb, struct dentry * dentry, struct buffer_head ** fe_bh, struct inode *inode, struct inode *file_inode, int take_lock, struct buffer_head **dirent_bh, struct ocfs2_dir_entry **dirent)
 {
 	int status = -ENOENT;
-	__u64 thisDirNode;
 	int tmpstat;
-	int temp_bhs = 0;
 	int lock_acq = 0;
-	int sync = 1;
 	struct buffer_head *bh = NULL;
-	struct buffer_head **bhs = NULL;
-	int bufsz, nbhs, i;
 	__u32 lock_type = OCFS_DLM_ENABLE_CACHE_LOCK;
 	__u64 parent_off = GET_INODE_FEOFF(inode);
+	
+	LOG_ENTRY_ARGS ("(osb=%p, parent=%llu, dentry=%p, fe_bh=%p, inode=%p)\n", osb, parent_off, dentry, fe_bh, inode);
 
-	LOG_ENTRY_ARGS ("(osb=%p, parent=%llu, fname=%p, fe_bh=%p, ofile=%p, inode=%p)\n", osb, parent_off, file_name, fe_bh, ofile, inode);
-
-	nbhs = osb->vol_layout.dir_node_size >> osb->sect_size_bits;
-	bufsz = nbhs * (sizeof(struct buffer_head *));
-
-	thisDirNode = OCFS_I(inode)->u.child_dirnode;
-	if (ofile == NULL) {
-		temp_bhs = 1;
-		bhs = ocfs_malloc (bufsz);
-		if (bhs == NULL) {
-			temp_bhs = 0;
-			LOG_ERROR_STATUS(status = -ENOMEM);
-			goto leave;
-		}
-		memset(bhs, 0, bufsz);
-	} else {
-		if (ofile->curr_dir_off > 0)
-			thisDirNode = ofile->curr_dir_off;
-		bhs = ofile->curr_dir_buf;
-	}
-	OCFS_ASSERT(bhs);
-
-	sync = 0;
 	if (take_lock) {
 		/* Get a lock on the directory... */
 		status = ocfs_acquire_lock (osb, parent_off, lock_type, FLAG_DIR|FLAG_READDIR, 
@@ -206,33 +187,19 @@
 			goto leave;
 		}
 		lock_acq = 1;
-		// used to set sync if not locally owned
-		// should not need to anymore...
-		// sync = 1;
 	}
 
-	if (bhs[0]==NULL || bhs[0]->b_blocknr != (thisDirNode >> osb->sect_size_bits)) {
-		for (i=0; i<nbhs; i++) {
-			if (bhs[i]) {
-				brelse(bhs[i]);
-				bhs[i]=NULL;
-			}
-		}
-		status = ocfs_read_dirnode(osb, thisDirNode, sync, &bhs[0], inode);
-		if (status < 0) {
-			/* Volume should be disabled in this case */
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-	}
+	status = -ENOENT;
+	*dirent_bh = ocfs_find_entry (dentry, dirent);
+	if (!*dirent_bh || !*dirent)
+		goto leave;
 
-	status = 0;
-	/* if file_name is null here, it means that we want to walk the */
-	/* directory for all files if it is not null, it means we want */
-	/* a particular file */
-	if (!ocfs_search_dir_node (osb, bhs, file_name, fe_bh, ofile, inode, sync))
+	status = ocfs_read_bh(osb, (*dirent)->inode, fe_bh, OCFS_BH_CACHED, file_inode);
+	if (status < 0) {
+		brelse(*dirent_bh);
+		LOG_ERROR_STATUS(status);
 		status = -ENOENT;
-
+	}
 leave:
 
 	if (take_lock && lock_acq)
@@ -247,1078 +214,81 @@
 
 	if (bh != NULL)
 		brelse(bh);
-
-	/* if we won't be brelsing/freeing on file */
-	/* close do all of the cleanup here */
-	if (temp_bhs) {
-		for (i=0; i<nbhs; i++)
-			if (bhs[i])
-				brelse(bhs[i]);
-		ocfs_safefree(bhs);
+	if (status < 0) {
+		*dirent = NULL;
+		if (*dirent_bh) {
+			brelse(*dirent_bh);
+			*dirent_bh = NULL;
+		}
 	}
 
 	LOG_EXIT_STATUS (status);
 	return status;
 }				/* ocfs_find_files_on_disk */
 
-/* ocfs_initialize_dir_node()
- *
- */
-void ocfs_initialize_dir_node (ocfs_super * osb, ocfs_dir_node * dir_node, __u64 bitmap_off, __u64 file_off, __u32 node)
-{
-	LOG_ENTRY ();
 
-	memset (dir_node, 0, sizeof (ocfs_dir_node));
-	strcpy (dir_node->signature, OCFS_DIR_NODE_SIGNATURE);
-
-	dir_node->num_ents = (__u8) osb->max_dir_node_ent;
-	dir_node->node_disk_off = bitmap_off;
-	dir_node->alloc_file_off = file_off;
-	dir_node->alloc_node = node;
-
-	DISK_LOCK_CURRENT_MASTER (dir_node) = OCFS_INVALID_NODE_NUM;
-
-	dir_node->free_node_ptr = INVALID_NODE_POINTER;
-	dir_node->next_node_ptr = INVALID_NODE_POINTER;
-	dir_node->indx_node_ptr = INVALID_NODE_POINTER;
-	dir_node->next_del_ent_node = INVALID_NODE_POINTER;
-	dir_node->head_del_ent_node = INVALID_NODE_POINTER;
-
-	dir_node->first_del = INVALID_DIR_NODE_INDEX;
-	dir_node->index_dirty = 0;
-
-	LOG_EXIT ();
-	return;
-}				/* ocfs_initialize_dir_node */
-
 /*
- * ocfs_write_dir_node()
- *
+ * routine to check that the specified directory is empty (for rmdir)
  */
-static int ocfs_write_dir_node (ocfs_super * osb, struct buffer_head *bhs[], __s32 idx, struct inode *dir_inode, struct inode *file_inode)
+int empty_dir (struct inode * inode)
 {
-	int status = 0;
-	__u64 offset;
-	ocfs_dir_node *DirNode = NULL;
-	ocfs_file_entry *fe = NULL;
-	int sync_fe_write = 0;
-	
-	LOG_ENTRY ();
+	unsigned long offset;
+	struct buffer_head * bh;
+	struct ocfs2_dir_entry * de, * de1;
+	struct super_block * sb;
+	int err;
 
-	DirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_READ(bhs[0]); /* read */
-	
-	offset = DirNode->node_disk_off + ((idx + 1) * osb->sect_size);
-
-	OCFS_BH_PUT_DATA(bhs[0]);
-
-	if (idx != -1) {
-		fe = (ocfs_file_entry *)OCFS_BH_GET_DATA_READ(bhs[idx+1]); /* read */
-
-		if(!IS_VALID_FILE_ENTRY(fe)) {
-			OCFS_BH_PUT_DATA(bhs[idx+1]);
-			status = -EIO; // ???
-			goto bail;
-		}
-
-		sync_fe_write = 1;
-		
-		OCFS_BH_PUT_DATA(bhs[idx+1]);
+	sb = inode->i_sb;
+	if (inode->i_size < OCFS_DIR_REC_LEN(1) + OCFS_DIR_REC_LEN(2) ||
+	    !(bh = ocfs_bread (NULL, inode, 0, 0, &err, 0))) {
+	    	LOG_ERROR_ARGS ("bad directory (dir #%llu) - no data block\n", 
+				GET_INODE_FEOFF(inode));
+		return 1;
 	}
 
-	/* Write the file entry at idx, if given */
-	if (sync_fe_write) {
-		status = ocfs_write_bh (osb, bhs[idx+1], 0, file_inode);
-		if (status < 0)
-			LOG_ERROR_STATUS (status);
+	de = (struct ocfs2_dir_entry *) OCFS_BH_GET_DATA_READ(bh);
+	de1 = (struct ocfs2_dir_entry *)
+			((char *) de + le16_to_cpu(de->rec_len));
+	if (le64_to_cpu(de->inode) != GET_INODE_FEOFF(inode) || 
+			!le64_to_cpu(de1->inode) || 
+			strcmp (".", de->name) ||
+			strcmp ("..", de1->name)) {
+	    	LOG_ERROR_ARGS ("bad directory (dir #%llu) - no `.' or `..'\n",
+				GET_INODE_FEOFF(inode));
+		OCFS_BH_PUT_DATA(bh);
+		brelse (bh);
+		return 1;
 	}
-	
-	/* Write the first sector last */
-	status = ocfs_write_bh (osb, bhs[0], 0, dir_inode);
-	if (status < 0)
-		LOG_ERROR_STATUS (status);
-
-bail:
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_write_dir_node */
-
-
-/*
- * ocfs_search_dir_node()
- *
- */
-static int ocfs_search_dir_node (ocfs_super * osb, struct buffer_head *bhs[], struct qstr * SearchName, struct buffer_head ** found_fe_bh, ocfs_file * OFile, struct inode *dir_inode, int sync)
-{
-	__u32 start;
-	__u32 i;
-	ocfs_file_entry *fe;
-	int status;
-	int ret = 0;
-	ocfs_dir_node * DirNode = NULL, *tmp;
-
-	LOG_ENTRY ();
-
-	DirNode = (ocfs_dir_node *) ocfs_malloc(osb->sect_size);
-	if (DirNode == NULL) {
-		LOG_ERROR_STR("Out of memory");
-		ret = 0;
-		goto bail;
-	}
-
-	tmp = (ocfs_dir_node *)OCFS_BH_GET_DATA_READ(bhs[0]); /* read */
-	memcpy(DirNode, tmp, osb->sect_size);
-	OCFS_BH_PUT_DATA(bhs[0]);
-
-	if (OFile != NULL)
-		start = OFile->curr_byte_off;
-	else
-		start = 0;
-
-
-	if (!IS_VALID_DIR_NODE (DirNode)) {
-		LOG_TRACE_STR("Invalid Dir Node!\n");
-		ret = 0;
-		goto bail;
-	}
-
-	while (1) {
-		/* Iterate thru this dirnode and find a matching entry */
-		for (i = start; i < DirNode->num_ent_used; i++) {
-			int found = 1;
-
-			if (SearchName != NULL) {
-				found = ocfs_find_index (osb, bhs, SearchName, (int *) &i);
-			}
-
-			if (found) {
-				fe = FILEENT_GETBH(DirNode, bhs, i); /* read */
-	
-				if (fe->sync_flags & OCFS_SYNC_FLAG_NAME_DELETED ||
-				    !(fe->sync_flags & OCFS_SYNC_FLAG_VALID)) {
-					FILEENT_PUTBH(DirNode, bhs, i);
-					continue;
-				}
-
-				LOG_TRACE_ARGS ("Returning entry: %u, name: %s\n", i, fe->filename);
-				FILEENT_PUTBH(DirNode, bhs, i);
-				*found_fe_bh = bhs[DirNode->index[i]+1];
-				/* we get_bh this guy one more time
-				 * because the caller needs his own
-				 * reference as this is still also
-				 * part of the directory data. */
-				get_bh(*found_fe_bh);
-
-				if (OFile != NULL) {
-					OFile->curr_dir_off = DirNode->node_disk_off;
-					OFile->curr_byte_off = i + 1;
-				}
-				ret = 1;
-				goto bail;
-			} else
-				break;
-		}
-		if (DirNode->next_node_ptr != -1) {
-			__u64 next = DirNode->next_node_ptr;
-
-			/* dump what we've got */
-			for (i=0; i<256; i++) {
-				if (bhs[i]) {
-					brelse(bhs[i]);
-					bhs[i] = NULL;
-				}
-			}
-			status = ocfs_read_dirnode(osb, next, sync, bhs, dir_inode);
-			if (status < 0) {
-				LOG_ERROR_STR("failed to read directory");
-				ret = 0;
-				goto bail;
-			}
-
-			tmp = (ocfs_dir_node *)OCFS_BH_GET_DATA_READ(bhs[0]); /* read */
-			memcpy(DirNode, tmp, osb->sect_size);
-			OCFS_BH_PUT_DATA(bhs[0]);
-
-			if (!IS_VALID_DIR_NODE (DirNode)) {
-				LOG_TRACE_STR("Invalid Dir Node!\n");
-				ret = 0;
-				goto bail;
-			}
-			start = 0;
-			continue;
-		} else {
-			/* We are done... */
-			break;
-		}
-	}
-
-	if (OFile != NULL) {
-		OFile->curr_dir_off = DirNode->node_disk_off;
-		OFile->curr_byte_off = i + 1;
-	}
-
-bail:
-	if (DirNode)
-		ocfs_safefree(DirNode);
-
-	LOG_EXIT_INT (ret);
-	return ret;
-}				/* ocfs_search_dir_node */
-
-
-/*
- * ocfs_find_index()
- *
- * Locks the dirnode bh, and then only one fe at a time.
- */
-static int ocfs_find_index (ocfs_super * osb, struct buffer_head *bhs[], struct qstr * FileName, int *Index)
-{
-	int lowBnd, upBnd;
-	ocfs_file_entry *fe;
-	int res = -1, index = 0, start = 0;
-	int ret = 0;
-	struct qstr q;
-	ocfs_dir_node * DirNode = NULL;
-
-	LOG_ENTRY ();
-
-	DirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_READ(bhs[0]); /* read */
-	if (!IS_VALID_DIR_NODE (DirNode) || FileName==NULL) {
-		ret = 0;
-		goto bail;
-	}
-
-	if (*Index > 0)
-		start = *Index;
-
-	if (DirNode->index_dirty) {
-		for (index = start; index < DirNode->num_ent_used; index++) {
-			fe = FILEENT_GETBH(DirNode, bhs, index); /* read */
-
-			if ((fe->sync_flags & OCFS_SYNC_FLAG_NAME_DELETED) ||
-			    (!(fe->sync_flags & OCFS_SYNC_FLAG_VALID))) {
-				FILEENT_PUTBH(DirNode, bhs, index);
+	offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len);
+	de = (struct ocfs2_dir_entry *) ((char *) de1 + le16_to_cpu(de1->rec_len));
+	while (offset < inode->i_size ) {
+		if (!bh || (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
+			OCFS_BH_PUT_DATA(bh);
+			brelse (bh);
+			bh = ocfs_bread (NULL, inode, offset >> sb->s_blocksize_bits, 0, &err, 0);
+			if (!bh) {
+				LOG_ERROR_ARGS ("directory #%llu contains a hole at offset %lu\n",
+					GET_INODE_FEOFF(inode), offset);
+				offset += sb->s_blocksize;
 				continue;
 			}
-			q.name = fe->filename;
-			q.len = strlen(fe->filename);
-			res = ocfs_compare_qstr(&q, FileName);
-			FILEENT_PUTBH(DirNode, bhs, index);
-
-			if (!res) {
-				*Index = index;
-				ret = 1;
-				goto bail;
-			}
+			de = (struct ocfs2_dir_entry *) OCFS_BH_GET_DATA_READ(bh);
 		}
-		*Index = index;
-		ret = 0;
-		goto bail;
-	}
-
-	for (lowBnd = start, upBnd = (DirNode->num_ent_used - start); upBnd; upBnd >>= 1) {
-		index = lowBnd + (upBnd >> 1);
-		fe = FILEENT_GETBH(DirNode, bhs, index); /* read */
-
-		if ((fe->sync_flags & OCFS_SYNC_FLAG_NAME_DELETED) ||
-		    (!(fe->sync_flags & OCFS_SYNC_FLAG_VALID))) {
-
-			FILEENT_PUTBH(DirNode, bhs, index);
-
-			for (index = lowBnd; index < (lowBnd + upBnd); index++) {
-				fe = FILEENT_GETBH(DirNode, bhs, index); /* read */
-				if ((fe->sync_flags & OCFS_SYNC_FLAG_NAME_DELETED) ||
-				    (!(fe->sync_flags & OCFS_SYNC_FLAG_VALID))) {
-					FILEENT_PUTBH(DirNode, bhs, index);
-					continue;
-				}
-			       
-				q.name = fe->filename;
-				q.len = strlen(fe->filename);
-				res = ocfs_compare_qstr(&q, FileName);
-				FILEENT_PUTBH(DirNode, bhs, index);
-
-				if (!res) {
-					*Index = index;
-					ret = 1;
-					goto bail;
-				}
-				if (res < 0) {
-					*Index = index;
-					ret = 0;
-					goto bail;
-				}
-			}
-			*Index = lowBnd + upBnd - 1;
-			ret = 0;
-			goto bail;
+		if (!ocfs_check_dir_entry (inode, de, bh, offset)) {
+			OCFS_BH_PUT_DATA(bh);
+			brelse (bh);
+			return 1;
 		}
-
-		q.name = fe->filename;
-		q.len = strlen(fe->filename);
-		res = ocfs_compare_qstr(&q, FileName);
-		FILEENT_PUTBH(DirNode, bhs, index);
-
-		if (!res) {
-			*Index = index;
-			ret = 1;
-			goto bail;
+		if (le64_to_cpu(de->inode)) {
+			OCFS_BH_PUT_DATA(bh);
+			brelse (bh);
+			return 0;
 		}
-
-		if (res > 0) {
-			lowBnd = index + 1;
-			--upBnd;
-		}
+		offset += le16_to_cpu(de->rec_len);
+		de = (struct ocfs2_dir_entry *)
+				((char *) de + le16_to_cpu(de->rec_len));
 	}
-
-	*Index = index;
-
-bail:
-	if (DirNode)
-		OCFS_BH_PUT_DATA(bhs[0]);
-	LOG_EXIT_INT (ret);
-	return ret;
-}				/* ocfs_find_index */
-
-/*
- * ocfs_reindex_dir_node()
- *
- */
-int ocfs_reindex_dir_node (ocfs_super * osb, __u64 DirNodeOffset, struct buffer_head *bhs[], ocfs_journal_handle *handle, struct inode *dir_inode)
-{
-	int status = 0;
-	ocfs_dir_node *dir = NULL;
-	ocfs_file_entry *target = NULL;
-	ocfs_file_entry *fe;
-	__u32 i;
-	__u8 offset = 0;
-	int nbhs, bufsz;
-	struct buffer_head **arr = NULL;
-
-	LOG_ENTRY ();
-
-	nbhs = osb->vol_layout.dir_node_size >> osb->sect_size_bits;
-	bufsz = nbhs * (sizeof(struct buffer_head *));
-
-	if (bhs == NULL) {
-		arr = ocfs_malloc (bufsz);
-		if (arr == NULL) {
-			LOG_ERROR_STATUS (status = -ENOMEM);
-			goto leave;
-		}
-		memset(arr, 0, bufsz);
-		status = ocfs_read_dirnode(osb, DirNodeOffset, 0, arr, dir_inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-	} else
-		arr = bhs;
-
-	dir = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(arr[0]); /* write */
-	if (!IS_VALID_DIR_NODE (dir)) {
-		OCFS_BH_PUT_DATA(arr[0]);
-		LOG_ERROR_STATUS(status = -EINVAL);
-		goto leave;
-	}
-
-	if (dir->index_dirty) {
-		offset = dir->bad_off;
-
-		/* To preserve locking order, (we only want to lock 1
-		 * fe at a time, in incremental order), we copy this
-		 * one off. */
-		target = ocfs_allocate_file_entry();
-		if (target == NULL) {
-			OCFS_BH_PUT_DATA(arr[0]);
-			LOG_ERROR_STATUS(status = -ENOMEM);
-			goto leave;
-		}
-		memcpy(target, OCFS_BH_GET_DATA_READ(arr[offset+1]), 
-		       sizeof(ocfs_file_entry)); /* read */
-		OCFS_BH_PUT_DATA(arr[offset+1]);
-
-		for (i = 0; i < dir->num_ent_used; i++) {
-			/* don't need to check ourselves */
-			if (dir->index[i] == offset)
-				continue;
-
-			fe = FILEENT_GETBH(dir, arr, i); /* read */
-
-			if ((fe->sync_flags & OCFS_SYNC_FLAG_NAME_DELETED) ||
-			    (!(fe->sync_flags & OCFS_SYNC_FLAG_VALID))) {
-				FILEENT_PUTBH(dir, arr, i);
-				continue;
-			}
-
-			/* find the first file entry that is alphabetically */
-			/* less than the target file entry */
-			if (strcmp (fe->filename, target->filename) < 0) {
-				FILEENT_PUTBH(dir, arr, i);
-				break;
-			}
-			FILEENT_PUTBH(dir, arr, i);
-		}
-
-		if (i < dir->num_ent_used - 1) {
-			memmove (&dir->index[i+1], &dir->index[i], 
-				 dir->num_ent_used - i);
-			dir->index[i] = offset;
-		}
-
-		dir->index_dirty = 0;
-		OCFS_BH_PUT_DATA(arr[0]);
-	} else
-		OCFS_BH_PUT_DATA(arr[0]);
-
-leave:
-	if (bhs == NULL)
-		ocfs_safefree (arr);
-	if (target)
-		ocfs_release_file_entry(target);
-
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_reindex_dir_node */
-
-/*
- * ocfs_insert_dir_node()
- *
- */
-static int ocfs_insert_dir_node (ocfs_super * osb, struct buffer_head *bhs[], ocfs_file_entry * InsertEntry, struct buffer_head *lockbh, __s32 * IndexOffset, struct buffer_head **insert_bh, ocfs_journal_handle * handle, struct inode *dir_inode, struct inode *file_inode)
-{
-	int status = 0;
-	ocfs_file_entry *fe;
-	int res = 0;
-	int index = -1;
-	ocfs_file_entry *lastEntry;
-	__u8 freeOffset;
-	struct qstr q;
-	ocfs_dir_node * DirNode = NULL;
-
-	LOG_ENTRY ();
-
-	DirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(bhs[0]); /* write */
-
-	if (!IS_VALID_DIR_NODE (DirNode)) {
-		LOG_ERROR_STATUS(status = -EINVAL);
-		OCFS_BH_PUT_DATA(bhs[0]);
-		goto bail;
-	}
-
-	if (DirNode->index_dirty) {
-		__u64 off = DirNode->node_disk_off;
-
-		OCFS_BH_PUT_DATA(bhs[0]);
-		status = ocfs_reindex_dir_node (osb, off, bhs, handle, dir_inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto bail;
-		}
-		DirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(bhs[0]); /* write */
-	}
-
-	/* Should status be updated here? */
-	if (DirNode->num_ent_used >= osb->max_dir_node_ent) {
-		OCFS_BH_PUT_DATA(bhs[0]);
-		status = -ENOSPC;
-		LOG_TRACE_STR("DirNode->num_ent_used >= osb->max_dir_node_ent");
-		goto bail;
-	}
-	
-	/* find a place to add the new file entry. */
-	if (DirNode->num_ent_used) {
-		/* make sure we're not already in this dirnode. */
-		q.name = InsertEntry->filename;
-		q.len = strlen(InsertEntry->filename);
-		OCFS_BH_PUT_DATA(bhs[0]);
-		if (ocfs_find_index (osb, bhs, &q, &index)) {
-			/* Already inserted... */
-			status = -EEXIST;
-			goto bail;
-		}
-		DirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(bhs[0]); /* write */
-		
-		if (index < DirNode->num_ent_used) {
-			fe = FILEENT_GETBH(DirNode, bhs, index); /* read */
-
-			res = strcmp (fe->filename, InsertEntry->filename);
-			FILEENT_PUTBH(DirNode, bhs, index);
-			if (res > 0) {
-				/* We are greater than the entry in question we
-				 * should be less than the one next to it */
-				index++;
-			}
-		}
-	} else {
-		index = 0;
-	}
-	
-	if (index < DirNode->num_ent_used) {
-		/* shimmy everything over, we're putting 
-		 * the new fe in the middle somewhere */
-		memmove (&DirNode->index[index + 1],
-			 &DirNode->index[index],
-			 DirNode->num_ent_used - index);
-	}
-	
-	if (DirNode->num_ent_used) {
-		if (DirNode->num_del) {
-			/* Insert at first deleted & change first deleted */
-			freeOffset = DirNode->first_del;
-			DirNode->num_del--;
-			if (DirNode->num_del) {
-				lastEntry = (ocfs_file_entry *)OCFS_BH_GET_DATA_READ(bhs[freeOffset+1]); /* read */
-				DirNode->first_del = lastEntry->next_del;
-				OCFS_BH_PUT_DATA(bhs[freeOffset+1]);
-			}
-		} else {
-			/* Insert at end and change the index */
-			freeOffset = DirNode->num_ent_used;
-		}
-	} else {
-		freeOffset = 0;
-	}
-	
-	set_buffer_uptodate(bhs[freeOffset+1]);
-	status = ocfs_journal_access(handle, bhs[freeOffset+1], 
-				     OCFS_JOURNAL_ACCESS_CREATE);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto bail;
-	}
-	
-	/* we know which entry we're using so return it. */
-	*IndexOffset = freeOffset;
-	if (insert_bh) {
-		/* note that if you asked for insert_bh, we did an
-		 * additional get_bh */
-		get_bh(bhs[freeOffset+1]);
-		*insert_bh = bhs[freeOffset+1];
-	}
-
-	/* Put the entry at the end */
-	lastEntry = (ocfs_file_entry *)OCFS_BH_GET_DATA_WRITE(bhs[freeOffset+1]); /* write */ /* journal access */
-	InsertEntry->dir_node_ptr = DirNode->node_disk_off;
-	memcpy (lastEntry, InsertEntry, osb->sect_size);
-	OCFS_SET_FLAG (lastEntry->sync_flags, OCFS_SYNC_FLAG_VALID);
-	lastEntry->this_sector = InsertEntry->this_sector = 
-		DirNode->node_disk_off + ((freeOffset + 1) * osb->sect_size);
-	OCFS_BH_PUT_DATA(bhs[freeOffset+1]);
-	
-	status = ocfs_journal_dirty(handle, bhs[freeOffset+1]);
-
-	DirNode->index[index] = freeOffset;
-	DirNode->num_ent_used++;
-	OCFS_BH_PUT_DATA(bhs[0]);
-
-	/* in case we fail, we want to make sure we don't return a bh. */
-	if ((status < 0) && insert_bh) {
-		if (*insert_bh)
-			brelse(*insert_bh);
-		*insert_bh = NULL;
-	}
-bail:
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_insert_dir_node */
-
-/* 
- * there are 3 buffer heads of interest in ocfs_del_file_entry:
- *    febh:   the actual file entry to delete (EntryToDel)
- *    lockbh: the ocfs_dir_node locked for this delete (LockNode)
- *    dirbh:  the ocfs_dir_node that owns EntryToDel, if NULL
- *            then PDirNode is the same as LockNode, otherwise
- *            dirbh is the bh for PDirNode
- */
-
-/*
- * ocfs_remove_file()
- * only removes the file entry, not the extents or dirnodes.
- */
-int ocfs_remove_file (ocfs_super * osb, struct buffer_head *febh, struct buffer_head *lockbh, ocfs_journal_handle *handle, struct inode *dir_inode, struct inode *file_inode)
-{
-	int status = 0;
-	__u32 offset;
-	int index = 0;
-	ocfs_file_entry * EntryToDel = NULL;
-	ocfs_dir_node * LockNode = NULL;
-	ocfs_dir_node *PDirNode = NULL;
-	struct buffer_head *dirbh = NULL;
-	struct buffer_head **dirbhs = NULL;
-	__u64 lock_off, head_del, parent_off;
-	const int numbhs = 256;
-	const int length = numbhs * sizeof(struct buffer_head *);
-
-	LOG_ENTRY ();
-
-	/* alloc a whole dirnode of bhs even tho I will only use 2 :( */
-	dirbhs = (struct buffer_head **) ocfs_malloc (length);
-	if (dirbhs == NULL) {
-		LOG_ERROR_STATUS (status = -ENOMEM);
-		goto leave;
-	}
-	memset(dirbhs, 0, length);
-	
-	/* briefly grab LockNode and get useful bits of info. */
-	LockNode = (ocfs_dir_node *) OCFS_BH_GET_DATA_READ(lockbh); /* read */
-	if (!IS_VALID_DIR_NODE(LockNode))
-		BUG();
-
-	lock_off = LockNode->node_disk_off;
-	head_del = LockNode->head_del_ent_node;
-	OCFS_BH_PUT_DATA(lockbh);
-	LockNode = NULL;
-
-	status= ocfs_journal_access(handle, lockbh, OCFS_JOURNAL_ACCESS_WRITE);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-
-	EntryToDel = (ocfs_file_entry *) OCFS_BH_GET_DATA_WRITE(febh); /* write */
-
-	/* if fe comes from lower down in the dir chain, get the ocfs_dir_node 
-	 * for that chain.  otherwise, use the lockbh (toplevel) */
-	if (EntryToDel->dir_node_ptr == lock_off) {
-		dirbhs[0] = lockbh;
-	} else {
-		status = ocfs_read_bh(osb, EntryToDel->dir_node_ptr, 
-				      &dirbh, OCFS_BH_CACHED, dir_inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-		dirbhs[0] = dirbh;
-
-		status= ocfs_journal_access(handle, dirbhs[0], 
-					    OCFS_JOURNAL_ACCESS_WRITE);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-	}
-	PDirNode = (ocfs_dir_node *) OCFS_BH_GET_DATA_WRITE(dirbhs[0]); /* write */ /* journal access */
-	parent_off = PDirNode->node_disk_off;
-	offset= ((EntryToDel->this_sector - parent_off) >> osb->sect_size_bits) - 1;
-	for (index = 0; index < PDirNode->num_ent_used; index++)
-		if (PDirNode->index[index] == offset)
-			break;
-
-	if (index == PDirNode->num_ent_used) {
-		LOG_TRACE_STR("index == PDirNode->num_ent_used");
-		goto leave;
-	}
-
-	if (febh->b_blocknr != (EntryToDel->this_sector >> osb->sect_size_bits)) {
-		LOG_TRACE_STR("febh->b_blocknr != (EntryToDel->this_sector >> osb->sect_size_bits)");
-		goto leave;
-	}
-
-	dirbhs[offset+1] = febh;
-
-	memmove (&PDirNode->index[index], &PDirNode->index[index + 1],
-		 PDirNode->num_ent_used - (index + 1));
-
-	PDirNode->num_ent_used--;
-	if (PDirNode->num_ent_used == 0) {
-		PDirNode->num_del = 0;
-	} else {
-		/* Insert this dir node as one containing a deleted
-		 * entry if the count on the root dir node for deleted
-		 * entries is 0 */
-		if (PDirNode->num_del != 0) {
-			PDirNode->num_del++;
-			EntryToDel->sync_flags = OCFS_SYNC_FLAG_DELETED;
-			EntryToDel->next_del = PDirNode->first_del;
-			PDirNode->first_del = offset;
-		} else {
-			PDirNode->num_del++;
-			EntryToDel->sync_flags = OCFS_SYNC_FLAG_DELETED;
-			EntryToDel->next_del = INVALID_DIR_NODE_INDEX;
-			PDirNode->first_del = offset;
-		}
-	}
-	
-	OCFS_BH_PUT_DATA(febh);
-	OCFS_BH_PUT_DATA(dirbhs[0]);
-	EntryToDel = NULL;
-	PDirNode = NULL;
-
-	LockNode = (ocfs_dir_node *) OCFS_BH_GET_DATA_WRITE(lockbh); /* write */ /* journal access */
-	if (LockNode->head_del_ent_node == INVALID_NODE_POINTER)
-		LockNode->head_del_ent_node = parent_off;
-
-	OCFS_BH_PUT_DATA(lockbh);
-	LockNode = NULL;
-
-	status = ocfs_journal_dirty(handle, dirbhs[0]);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-	status = ocfs_journal_dirty(handle, lockbh);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-
-leave:
-
-	if (EntryToDel)
-		OCFS_BH_PUT_DATA(febh);
-	if (PDirNode)
-		OCFS_BH_PUT_DATA(dirbhs[0]);
-	if (dirbh)
-		brelse(dirbh);
-
-	ocfs_safefree(dirbhs);
-	
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_remove_file */
-
-
-
-/*
- * ocfs_insert_file()
- *
- */
-int ocfs_insert_file (ocfs_super * osb, ocfs_file_entry * InsertEntry, struct buffer_head **insert_bh, ocfs_journal_handle * handle, struct inode *dir_inode, struct inode *file_inode)
-{
-	int status = 0;
-	__u64 bitmapOffset = 0;
-	__s32 indexOffset = -1;
-	ocfs_dir_node *pNewDirNode = NULL;
-	ocfs_dir_node *DirNode = NULL;
-	ocfs_dir_node *LockNode = NULL;
-	__u64 dir_off;
-	int parent_is_lock_node;
-	struct buffer_head **bhs = NULL;
-	const int numbhs = 256;
-	const int length = numbhs * sizeof(struct buffer_head *);
-	int i = 0;
-	int dirtyall = 0;
-	void *buf;
-	__u64 locknode_off, dir_next_node, new_head_del = 0;
-	__u64 locknode_head_del;
-	__u8 dir_num_ent_used;
-	unsigned long blk;
-	struct buffer_head *lock_bh = NULL;
-
-	LOG_ENTRY ();
-
-	/* NOTE:
-	 * Since the LockNode and the DirNode may point to the same
-	 * buffer, it is very important to never do a GET_DATA on both
-	 * at the same time. That is why we only briefly kmap these,
-	 * work on them, and unmap. Also, we may do a getblk on this
-	 * buffer more than once, but the bh refcount should be ok
-	 * since we brelse it here, then again when the
-	 * ocfs_release_lock happens. */
-
-	dir_off = OCFS_I(dir_inode)->u.child_dirnode;
-	status = ocfs_read_bh(osb, dir_off, &lock_bh, OCFS_BH_CACHED, 
-			      dir_inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto leave;
-	}
-
-	/* alloc bhs */
-	bhs = (struct buffer_head **)ocfs_malloc(length);
-	if (bhs == NULL) {
-		LOG_ERROR_STATUS (status = -ENOMEM);
-		goto leave;
-	}
-	memset(bhs, 0, length);
-	
-	if (insert_bh != NULL)
-		*insert_bh = NULL;
-
-	/* deal with a few fields on the file entry to be inserted */
-	if (!IS_VALID_FILE_ENTRY(InsertEntry)) {
-		LOG_ERROR_STR ("Invalid file entry");
-		status = -EFAIL;
-		goto leave;
-	}
-	DISK_LOCK_WRITER_NODE (InsertEntry) = osb->node_num;
-	DISK_LOCK_READER_NODE (InsertEntry) = osb->node_num;
-
-	/* route the new file entry to the proper dir_off */
-	LockNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_READ(lock_bh); /* read */
-	if (!IS_VALID_DIR_NODE(LockNode)) {
-		LOG_ERROR_STR ("Invalid dir node");
-		status = -EFAIL;
-		goto leave;
-	}
-
-	locknode_off = LockNode->node_disk_off;
-	locknode_head_del = LockNode->head_del_ent_node;
-
-	LOG_TRACE_ARGS("ocfs_insert_file: head_del=%llu, free_node=%llu, locknode=%llu\n",
-		       LockNode->head_del_ent_node, LockNode->free_node_ptr,
-		       locknode_off);
-
-	if (locknode_head_del != INVALID_NODE_POINTER)
-		dir_off = locknode_head_del;
-	else if (LockNode->free_node_ptr != INVALID_NODE_POINTER)
-		dir_off = LockNode->free_node_ptr;
-	else
-		dir_off = locknode_off;
-	
-	LOG_TRACE_ARGS("ocfs_insert_file: dir_off selected was %llu\n", dir_off);
-
-	parent_is_lock_node = (dir_off == locknode_off);
-	OCFS_BH_PUT_DATA(lock_bh);
-	LockNode = NULL;
-
-	/* get the bhs for dir_off */
-	status = ocfs_read_dirnode(osb, dir_off, 0, bhs, dir_inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-
-	/* see if it fits at dir_off */
-	DirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_READ(bhs[0]); /* read */
-	dir_num_ent_used = DirNode->num_ent_used;
-	dir_next_node = DirNode->next_node_ptr;
-	OCFS_BH_PUT_DATA(bhs[0]);
-	DirNode = NULL;
-
-	if (dir_off != locknode_head_del || dir_num_ent_used < osb->max_dir_node_ent) {
-		LOG_TRACE_ARGS("ocfs_insert_file: going to got_dirnode, numentused=%d\n", 
-			       dir_num_ent_used);
-		goto got_dirnode;
-	}
-
-	/* we read the head_del_ent_node or the free_node_ptr, but */
-	/* hit the old BUG. there are no free slots at dir_off. */
-	/* need to search. */
-
-	/* dump the bhs already found */
-	for (i=0; i<256; i++) {
-		brelse(bhs[i]);
-		bhs[i] = NULL;
-	}
-
-	/* start from locknode, travel along next_node_ptr */
-	dir_off = locknode_off;
-	while (1) {
-		LOG_TRACE_ARGS("ocfs_insert_file: now checking %llu\n", dir_off);
-		status = ocfs_read_dirnode(osb, dir_off, 0, bhs, dir_inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-
-		DirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_READ(bhs[0]); /* read */
-		dir_num_ent_used = DirNode->num_ent_used;
-		dir_next_node = DirNode->next_node_ptr;
-		OCFS_BH_PUT_DATA(bhs[0]);
-		DirNode = NULL;
-
-		if (dir_num_ent_used < osb->max_dir_node_ent) {
-			LOG_TRACE_ARGS("ocfs_insert_file: num_ent_used for %llu is good (%d)\n",
-	       			       dir_off, 
-				       dir_num_ent_used);
-			new_head_del = dir_off;
-			break;
-		}
-		LOG_TRACE_ARGS("ocfs_insert_file: next_node pointer for %llu is %llu\n", dir_off, dir_next_node);
-		dir_off = dir_next_node;
-		if (dir_off == INVALID_NODE_POINTER) {
-			new_head_del = INVALID_NODE_POINTER;
-			break;
-		}
-		for (i=0; i<256; i++) {
-			brelse(bhs[i]);
-			bhs[i] = NULL;
-		}
-	}
-		
-	DirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_READ(bhs[0]); /* read */
-	dir_num_ent_used = DirNode->num_ent_used;
-	dir_next_node = DirNode->next_node_ptr;
-	parent_is_lock_node = (DirNode->node_disk_off == locknode_off);
-	OCFS_BH_PUT_DATA(bhs[0]);
-	DirNode = NULL;
-
-got_dirnode:
-	/* it's legal to do this twice on the same buffer, so
-	 * don't worry about whether they're the same. */
-	status = ocfs_journal_access(handle, bhs[0], 
-				     OCFS_JOURNAL_ACCESS_WRITE);
-	if (!status)
-		status = ocfs_journal_access(handle, lock_bh, 
-					     OCFS_JOURNAL_ACCESS_WRITE);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto leave;
-	}
-
-	/* we always want to mark lock_bh at least once as it's going
-	 * to the journal, so leave this get_data_write outside of the
-	 * if statement. */
-	LockNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(lock_bh); /* write */ /* journal access */
-	if (new_head_del != 0)
-		LockNode->head_del_ent_node = new_head_del;
-	OCFS_BH_PUT_DATA(lock_bh);
-	LockNode = NULL;
-
-	/* If we have a list of dir nodes go to the last dirnode */
-	/* and insert in that. */
-	/* We should not find this entry already inserted */
-	if (dir_num_ent_used < osb->max_dir_node_ent) {
-		LOG_TRACE_ARGS("ocfs_insert_file: CASE 1\n");
-		status = ocfs_insert_dir_node (osb, bhs, InsertEntry, lock_bh,
-					&indexOffset, insert_bh, handle, dir_inode, file_inode);
-		if (status < 0) {
-			/* Should we not remove the head from the
-			 * current transaction before leaving? */
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-	} else {
-		/* ran out of room, file entry will not be inserted */
-		/* into DirNode but instead into pNewDirNode */
-		struct buffer_head **newbhs = NULL;
-		__u64 new_disk_off;
-
-		LOG_TRACE_ARGS("ocfs_insert_file: CASE 2\n");
-		newbhs = (struct buffer_head **)ocfs_malloc(length);
-		if (newbhs == NULL) {
-			LOG_ERROR_STATUS (status = -ENOMEM);
-			goto leave;
-		}
-		memset(newbhs, 0, length);
-
-		if (dir_next_node != INVALID_NODE_POINTER) {
-			/* already allocated a new block */
-			LOG_TRACE_ARGS("ocfs_insert_file: CASE 2A\n");
-			status = ocfs_read_dirnode(osb, dir_next_node, 0, newbhs, dir_inode);
-			if (status < 0) {
-				ocfs_safefree(newbhs);
-				LOG_ERROR_STATUS (status);
-				goto leave;
-			}
-			status = ocfs_journal_access(handle, newbhs[0],
-						    OCFS_JOURNAL_ACCESS_WRITE);
-			if (status < 0) {
-				for (i=0; i<numbhs; i++)
-					brelse(newbhs[i]);
-				ocfs_safefree(newbhs);
-				LOG_ERROR_STATUS (status);
-				goto leave;
-			}
-		} else {
-			/* Allocate a new dir node */
-			__u64 fileOffset = 0;
-
-			LOG_TRACE_ARGS("ocfs_insert_file: CASE 2B\n");
-
-			down(&osb->node_alloc_sem);
-			status = ocfs_alloc_node_block(osb, 
-						osb->vol_layout.dir_node_size,
-						&bitmapOffset, &fileOffset, 
-						osb->node_num,
-						DISK_ALLOC_DIR_NODE, handle);
-			up(&osb->node_alloc_sem);
-			if (status < 0) {
-				ocfs_safefree(newbhs);
-				LOG_ERROR_STATUS (status);
-				goto leave;
-			}
-
-			dirtyall = 1;
-			blk = (unsigned long)(bitmapOffset >> osb->sect_size_bits);
-			for (i = 0; i < numbhs; i++) {
-				newbhs[i] = getblk(OCFS_GET_BLOCKDEV(osb->sb),
-						   blk++, 
-						   osb->sb->s_blocksize);
-				set_buffer_uptodate(newbhs[i]);
-				/* clear all 128k, all garbage currently */
-				status = ocfs_journal_access(handle, newbhs[i],
-						   OCFS_JOURNAL_ACCESS_CREATE);
-				if (status < 0) {
-					while (i >= 0)
-						brelse(newbhs[i--]);
-					ocfs_safefree(newbhs);
-					LOG_ERROR_STATUS (status);
-					goto leave;
-				}
-				buf = OCFS_BH_GET_DATA_WRITE(newbhs[i]); /* write */
-				memset(buf, 0, osb->sect_size);
-				OCFS_BH_PUT_DATA(newbhs[i]);
-			}
-			pNewDirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(newbhs[0]); /* write */
-			ocfs_initialize_dir_node (osb, pNewDirNode, 
-						  bitmapOffset, fileOffset, 
-						  osb->node_num);
-			OCFS_BH_PUT_DATA(newbhs[0]);
-			pNewDirNode = NULL;
-		}
-
-		pNewDirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(newbhs[0]); /* write */
-		new_disk_off = pNewDirNode->node_disk_off;
-		OCFS_BH_PUT_DATA(newbhs[0]);
-		pNewDirNode = NULL;
-
-		status = ocfs_insert_dir_node (osb, newbhs, InsertEntry, 
-					       lock_bh, &indexOffset, 
-					       insert_bh, handle, dir_inode, 
-					       file_inode);
-
-		if (status >= 0) {
-			LockNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(lock_bh); /* write */
-			LockNode->free_node_ptr = new_disk_off;
-			OCFS_BH_PUT_DATA(lock_bh);
-			LockNode = NULL;
-
-			/* Setup the pointer to this new directory block */
-			DirNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(bhs[0]); /* write */
-			DirNode->next_node_ptr = new_disk_off;
-			OCFS_BH_PUT_DATA(bhs[0]);
-			DirNode = NULL;
-
-			status = ocfs_journal_dirty(handle, newbhs[0]);
-			if (dirtyall)
-				for(i=1;i<numbhs;i++)
-					status = ocfs_journal_dirty(handle, 
-								    newbhs[i]);
-		}
-
-		for (i = 0; i < numbhs; i++)
-			if (newbhs[i])
-				brelse(newbhs[i]);
-
-		ocfs_safefree(newbhs);
-
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-
-		indexOffset = -1;
-	}
-
-	status = ocfs_journal_dirty(handle, bhs[0]);
-	if (!status)
-		status = ocfs_journal_dirty(handle, lock_bh);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto leave;
-	}
-leave:
-	if (bhs) {
-		for (i=0; i<numbhs; i++)
-			brelse(bhs[i]);
-		ocfs_safefree(bhs);
-	}
-
-	if (lock_bh)
-		brelse(lock_bh);
-
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_insert_file */
+	OCFS_BH_PUT_DATA(bh);
+	brelse (bh);
+	return 1;
+}

Modified: branches/new-dir-format/src/dlm.c
===================================================================
--- branches/new-dir-format/src/dlm.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/dlm.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -1120,8 +1120,8 @@
 			}
 		}
 
-		LOG_ERROR_ARGS("DISKVOTE!!: lock_type=%u, flags=%08x, offset=%llu, inode=%lu\n",
-		       lock_type, flags, lock_id, inode?inode->i_ino:0);
+		LOG_ERROR_ARGS("DISKVOTE!!: lock_type=%u, flags=%08x, offset=%llu, inode=%llu\n",
+		       lock_type, flags, lock_id, inode?GET_INODE_FEOFF(inode):0ULL);
 		LOG_ERROR_ARGS("DISKVOTE!!: this=%d, master=%d, locktype=%d, ronode=%d, romap=%08x\n",
 		       osb->node_num, lockres->master_node_num, lockres->lock_type, 
 		       lockres->readonly_node, (__u32)(lockres->readonly_map & 0xFFFFFFFFULL));
@@ -1217,8 +1217,8 @@
 		if (OCFS_BH_GET_DATA_WRITE_TRYLOCK(bh) == NULL) {
 			tries++;
 			ocfs_release_lockres(lockres); // ocfs_release_lock
-			LOG_ERROR_ARGS("failed to get bh sem (%llu), attempt %d, trying again\n",
-				       (unsigned long long)bh->b_blocknr, tries);
+			LOG_ERROR_ARGS("failed to get bh sem (%lu), attempt %d, trying again\n",
+				       bh->b_blocknr, tries);
 			ocfs_sleep(100);
 			goto again;
 		}
@@ -1300,7 +1300,7 @@
 	int tmpstat;
 	ocfs_file_entry *fe = NULL;
 	__u64 lock_id;
-	__u32 lock_write_flags = DLOCK_FLAG_MASTER | DLOCK_FLAG_LOCK;
+	__u32 lock_write_flags = DLOCK_FLAG_MASTER | DLOCK_FLAG_LOCK | DLOCK_FLAG_OPEN_MAP;
 	__u32 lock_type = requested_lock;
 	int need_to_zap_buffers = 0, need_lock_write = 1;
 	int is_readdir = (flags & FLAG_READDIR) ? 1 : 0;
@@ -1391,8 +1391,8 @@
 	}
 
 
-	LOG_ERROR_ARGS("DISKVOTE!!: req_lock=%u, flags=%08x, offset=%llu, inode=%lu\n",
-		       requested_lock, flags, lock_id, inode?inode->i_ino:0);
+	LOG_ERROR_ARGS("DISKVOTE!!: req_lock=%u, flags=%08x, offset=%llu, inode=%llu\n",
+		       requested_lock, flags, lock_id, inode?GET_INODE_FEOFF(inode):0ULL);
 	LOG_ERROR_ARGS("DISKVOTE!!: this=%d, master=%d, locktype=%d, ronode=%d, romap=%08x\n",
 		       osb->node_num, lockres->master_node_num, lockres->lock_type, 
 		       lockres->readonly_node, (__u32)(lockres->readonly_map & 0xFFFFFFFFULL));

Modified: branches/new-dir-format/src/file.c
===================================================================
--- branches/new-dir-format/src/file.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/file.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -119,7 +119,7 @@
 
 	OCFS_BH_PUT_DATA(fe_bh);
 
-	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER)
+	if (inode == osb->root_inode)
 		goto leave;
 
 	if (local_handle) {
@@ -194,13 +194,6 @@
 	down (&(OCFS_I(inode)->priv_sem));
 	have_oin_sem = 1;
 
-	if (OCFS_I(inode)->oin_flags & OCFS_OIN_DELETE_ON_CLOSE) {
-		LOG_ERROR_STR ("oin deleted");
-		up(&inode->i_sem);
-		status = -ENOENT;
-		goto leave;
-	}
-
 	/* first open, we've gotta update the lock state. */
 	if (!OCFS_I(inode)->open_hndl_cnt) {
 		status = ocfs_read_bh(osb, GET_INODE_FEOFF(inode), &fe_bh, 
@@ -338,7 +331,6 @@
  */
 int ocfs_file_release (struct inode *inode, struct file *file)
 {
-	ocfs_file *ofile = NULL;
 	ocfs_super * osb;
 	struct dentry *dentry;
 	int last_close = 0;
@@ -348,32 +340,11 @@
 
 	dentry = file->f_dentry;
 
-	if (file->private_data)
-		ofile = (ocfs_file *) file->private_data;
-
 	osb = OCFS_SB(inode->i_sb);
 
 	/* dir */
 	if (S_ISDIR (inode->i_mode)) {
 		/* fix all this - need a real open/close for directories */
-		if (ofile) {
-			if (ofile->curr_dir_buf) {
-				const int nbhs = osb->vol_layout.dir_node_size >> osb->sect_size_bits;
-				struct buffer_head **bhs;
-				int i;
-
-				bhs = (struct buffer_head **)ofile->curr_dir_buf;
-				for (i=0; i<nbhs; i++) {
-					if (bhs[i]) {
-						brelse(bhs[i]);
-						bhs[i]=NULL;
-					}
-				}
-				ocfs_safefree (ofile->curr_dir_buf);
-				ofile->curr_dir_buf = NULL;
-			}
-			ocfs_release_ofile (ofile);
-		}
 		goto bail;
 	}
 
@@ -382,7 +353,7 @@
 	if (!OCFS_I(inode)->open_hndl_cnt) 
 		last_close = 1;
 
-	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
+	if (inode == osb->root_inode) {
 		up (&(OCFS_I(inode)->priv_sem));
 		goto bail;
 	}
@@ -409,9 +380,9 @@
 		down(&recovery_list_sem);
 		spin_lock(&oin_num_ext_lock);
 		if (OCFS_I(inode)->num_extends) {
-			LOG_TRACE_ARGS("ocfs2: closing inode %lu -- had %u "
+			LOG_TRACE_ARGS("ocfs2: closing inode %llu -- had %u "
 				       "extends pending from another node!\n", 
-				       inode->i_ino, 
+				       GET_INODE_FEOFF(inode),
 				       OCFS_I(inode)->num_extends);
 			OCFS_I(inode)->num_extends = 0;
 			list_del(&OCFS_I(inode)->recovery_list);
@@ -1558,7 +1529,7 @@
 		goto bail;
 
 	osb = OCFS_SB(inode->i_sb);
-	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER)
+	if (inode == osb->root_inode)
 		goto bail;
 
 	/* yay, locking hell! Why do we hit disk for this?! */

Modified: branches/new-dir-format/src/hash.c
===================================================================
--- branches/new-dir-format/src/hash.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/hash.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -35,19 +35,14 @@
 extern int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
 #endif
 
-struct _ocfs_inode_num;
 
-static int ocfs_inode_hash_prune_all(ocfs_inode_hash *h);
-static struct _ocfs_inode_num * __ocfs_inode_hash_lookup(ocfs_inode_hash *h, 
-						 __u64 off);
-static inline struct _ocfs_inode_num * __ocfs_inode_hash_remove(ocfs_inode_hash *h, 
-						  __u64 off);
+/*
+ *
+ * BH SEM HASH
+ *
+ */ 
 
 
-
-/* bh semaphore hashtable stuff */
-
-
 static ocfs_bh_sem *ocfs_bh_sem_alloc(void)
 {
 	return kmem_cache_alloc(OcfsGlobalCtxt.bh_sem_cache, GFP_NOFS);
@@ -67,8 +62,8 @@
 {
 	if (atomic_dec_and_lock(&sem->s_refcnt, &OcfsGlobalCtxt.bh_sem_hash_lock)) {
 		if (buffer_modified(sem->s_bh)) {
-			LOG_ERROR_ARGS("putting last refcount of a modified buffer!  block %llu\n",
-				       (unsigned long long)sem->s_bh->b_blocknr);
+			LOG_ERROR_ARGS("putting last refcount of a modified buffer!  block %lu\n",
+				       sem->s_bh->b_blocknr);
 		}
 		put_bh(sem->s_bh);
 		sem->s_bh = NULL;
@@ -166,11 +161,9 @@
 				sem->s_bh = bh;
 			}
 			if (sem->s_bh != bh) {
-				LOG_ERROR_ARGS("bad bh_sem->bh: sem(%p,%llu,%llu), new(%p,%llu)\n",
-					       sem->s_bh,
-					       (unsigned long long)(sem->s_bh ? sem->s_bh->b_blocknr : 0),
-					       (unsigned long long)sem->s_blocknr,
-					       bh, (unsigned long long)bh->b_blocknr);
+				LOG_ERROR_ARGS("bad bh_sem->bh: sem(%p,%lu,%lu), new(%p,%lu)\n",
+					       sem->s_bh, sem->s_bh ? sem->s_bh->b_blocknr : 0, 
+					       sem->s_blocknr, bh, bh->b_blocknr);
 				BUG();
 			}
 			break;
@@ -200,9 +193,9 @@
 		//	      sem->s_pid);
 			      
 		if (buffer_modified(sem->s_bh) && sem->s_pid == 0) {
-			LOG_ERROR_ARGS("found a%s sem with a modified bh but no pid!!! (block=%llu)\n", 
+			LOG_ERROR_ARGS("found a%s sem with a modified bh but no pid!!! (block=%lu)\n", 
 				       newsem != sem ? "n old" : " new",
-				       (unsigned long long)sem->s_bh->b_blocknr);
+				       sem->s_bh->b_blocknr);
 		}
 	} else {
 		/* first pass. not found. do alloc */
@@ -425,8 +418,8 @@
 			/* only do one buffer at a time. */
 			spin_unlock(&OcfsGlobalCtxt.bh_sem_hash_lock);
 
-			LOG_ERROR_ARGS("blocknr = %llu, pid = %d\n", 
-				       (unsigned long long)sem->s_bh->b_blocknr, pid);
+			LOG_ERROR_ARGS("blocknr = %lu, pid = %d\n", 
+				       sem->s_bh->b_blocknr, pid);
 			ocfs_clear_buffer_modified(sem->s_bh);
 			ocfs_bh_sem_put(sem);
 			goto again;
@@ -464,9 +457,8 @@
 		sem = list_entry (iter, ocfs_bh_sem, s_list);
 		if (atomic_read(&sem->s_refcnt) < 1) {
 			if (sem->s_bh) {
-				LOG_ERROR_ARGS("killing off bh_sem with bh still attached! block=%llu, count=%d\n",
-					       (unsigned long long)sem->s_bh->b_blocknr,
-					       atomic_read(&sem->s_bh->b_count));
+				LOG_ERROR_ARGS("killing off bh_sem with bh still attached! block=%lu, count=%d\n",
+					       sem->s_bh->b_blocknr, atomic_read(&sem->s_bh->b_count));
 			}
 			list_del(&sem->s_list);
 			list_add(&sem->s_list, &tmp);
@@ -509,8 +501,7 @@
 	struct task_struct *tsk = current;
 	DECLARE_WAITQUEUE(wait, tsk);
 
-	LOG_ENTRY_ARGS("(block=%llu, sem->s_pid=%d)\n",
-		       (unsigned long long)bh->b_blocknr, 
+	LOG_ENTRY_ARGS("(block=%lu, sem->s_pid=%d)\n", bh->b_blocknr, 
 		       sem->s_pid );
 
 	add_wait_queue(&sem->s_wait, &wait);
@@ -543,13 +534,11 @@
 			if (buffer_modified(bh) && 
 			    sem->s_pid != current->pid && sem->s_pid != 0) {
 #ifdef BH_SEM_DEBUG
-				LOG_ERROR_ARGS("possible deadlock: block=%llu, owner=%d, this=%d, modifier='%s'\n",
-					(unsigned long long)bh->b_blocknr,
-					sem->s_pid, current->pid, sem->s_modifier);
+				LOG_ERROR_ARGS("possible deadlock: block=%lu, owner=%d, this=%d, modifier='%s'\n",
+				       bh->b_blocknr, sem->s_pid, current->pid, sem->s_modifier);
 #else
-				LOG_ERROR_ARGS("possible deadlock: block=%llu, owner=%d, this=%d\n",
-					(unsigned long long)bh->b_blocknr,
-					sem->s_pid, current->pid);
+				LOG_ERROR_ARGS("possible deadlock: block=%lu, owner=%d, this=%d\n",
+				       bh->b_blocknr, sem->s_pid, current->pid);
 #endif
 			}
 		}
@@ -588,558 +577,3 @@
 	}
 	LOG_EXIT();
 }
-
-static inline ocfs_inode_num *ocfs_create_inode_num(void)
-{
-	ocfs_inode_num *inum = NULL;
-
-	inum = kmem_cache_alloc(OcfsGlobalCtxt.inum_cache, GFP_NOFS);
-	if (inum == NULL) {
-		LOG_ERROR_STATUS(-ENOMEM);
-		goto bail;
-	}
-	memset(inum, 0, sizeof(ocfs_inode_num));
-
-	INIT_LIST_HEAD(&inum->i_list);
-	inum->i_state = INUM_UNBOUND;
-	inum->i_inode = NULL;
-	inum->i_feoff = 0;
-
-bail:
-	return(inum);
-}
-
-#define ocfs_free_inode_num(inum)					      \
-	kmem_cache_free(OcfsGlobalCtxt.inum_cache, inum)
-
-/* 
- * ocfs_inode_hash_init()
- *
- * init the inode hash off an osb
- */
-int ocfs_inode_hash_init(ocfs_super *osb)
-{
-	ocfs_inode_hash *h = &osb->inode_hash;
-	int i, status = 0;
-
-	LOG_ENTRY();
-
-	spin_lock_init(&h->lock);
-	h->num_ents = 0;
-
-	/* we only want one page for the hash. */
-	h->hash = (struct list_head *)__get_free_pages(GFP_KERNEL, 0);
-	if (!h->hash) {
-		LOG_ERROR_STATUS(status = -ENOMEM);
-		goto bail;
-	}
-
-	h->size = PAGE_SIZE / sizeof(struct list_head);
-
-	LOG_TRACE_ARGS("h->size = %d\n", h->size);
-
-	for (i = 0; i < h->size; i++)
-		INIT_LIST_HEAD(&(h->hash[i]));
-
-bail:
-	LOG_EXIT_STATUS(status);
-	return status;
-} /* ocfs_inode_hash_init */
-
-/* 
- * ocfs_inode_hash_prune_all
- *
- * forcefully prunes the hash -- anything left with ANY refcount will
- * be deleted. Returns the number of hash items we had to prune. 
- */
-static int ocfs_inode_hash_prune_all(ocfs_inode_hash *h)
-{
-	int retval = 0;
-	int i = 0;
-	struct list_head *head;
-	struct list_head *iter = NULL;
-	struct list_head *tmpiter = NULL;
-	ocfs_inode_num *inum;
-	LIST_HEAD(tmp);
-
-	LOG_ENTRY();
-
-	spin_lock(&h->lock);
-
-	for(i = 0; i < h->size; i++) {
-		head = &h->hash[i];
-
-		if (list_empty(head))
-			continue;
-
-		list_for_each_safe(iter, tmpiter, head) {
-			inum = list_entry(iter, ocfs_inode_num, i_list);
-
-			list_del(&inum->i_list);
-			list_add(&inum->i_list, &tmp);
-
-			retval++;
-			h->num_ents--;
-		}
-	}
-
-	spin_unlock(&h->lock);
-
-	list_for_each_safe(iter, tmpiter, &tmp) {
-		inum = list_entry(iter, ocfs_inode_num, i_list);
-		list_del(&inum->i_list);
-
-		if (inum->i_inode) {
-			/* this log_error_args is mainly for debugging */
-			if (atomic_read(&inum->i_inode->i_count) > 1)
-				LOG_ERROR_ARGS("inode (%lu) with i_count = %u "
-					  "left in system, fileoff = %llu)\n", 
-					  inum->i_inode->i_ino,
-					  atomic_read(&inum->i_inode->i_count),
-					  inum->i_feoff);
-
-			iput(inum->i_inode);
-		}
-		ocfs_free_inode_num(inum);
-	}
-
-	LOG_EXIT_STATUS(retval);
-	return retval;
-} /* ocfs_inode_hash_prune_all */
-
-/*
- * ocfs_inode_hash_destroy()
- */
-void ocfs_inode_hash_destroy(ocfs_inode_hash *h)
-{
-	int n;
-
-	LOG_ENTRY();
-
-	/* by shutdown, we shouldn't have anything left in the hash. */
-	n = ocfs_inode_hash_prune_all(h);
-	if (n)
-		LOG_TRACE_ARGS("%d items pruned from inode hash.\n", n);
-
-	spin_lock(&h->lock);
-	free_pages((unsigned long) h->hash, 0);
-	h->hash = NULL;
-	h->num_ents = 0;
-	h->size = 0;
-
-	LOG_EXIT();
-	return;
-} /* ocfs_inode_hash_destroy */
-
-#define OCFS_INODE_HASH(h, off) ((__u32)(off >> 9) % (h->size))
-
-/*
- * __ocfs_inode_hash_lookup()
- *
- * You MUST be holding the inode hash lock before calling this! 
- */
-static ocfs_inode_num * __ocfs_inode_hash_lookup(ocfs_inode_hash *h, 
-						 __u64 off)
-{
-	ocfs_inode_num *inum = NULL;
-	int bucket;
-	struct list_head *head;
-	struct list_head *iter = NULL;
-
-	bucket = OCFS_INODE_HASH(h, off);
-
-	head = &h->hash[bucket];
-
-	if (list_empty(head))
-		goto bail;
-
-	list_for_each(iter, head) {
-		inum = list_entry(iter, ocfs_inode_num, i_list);
-
-		if (inum->i_feoff == off)
-			break;
-		inum = NULL;
-	}
-
-bail:
-	return(inum);
-} /* __ocfs_inode_hash_lookup */
-
-#if 0
-static ocfs_inode_num * __ocfs_inode_hash_feoff_lookup(ocfs_inode_hash *h, 
-						       __u64 feoff)
-{
-	ocfs_inode_num *inum = NULL;
-	int bucket;
-	struct list_head *head;
-	struct list_head *iter = NULL;
-
-	for(bucket = 0; bucket < h->size; bucket++) {
-		head = &h->hash[bucket];
-
-		if (list_empty(head))
-			continue;
-
-		list_for_each(iter, head) {
-			inum = list_entry(iter, ocfs_inode_num, i_list);
-
-			if (inum->i_feoff == feoff)
-				break;
-			inum = NULL;
-		}
-		
-		if (inum)
-			break;
-	}
-
-	return(inum);
-} /* __ocfs_inode_hash_feoff_lookup */
-#endif
-
-/*
- * ocfs_inode_hash_lookup()
- *
- */
-struct inode *ocfs_inode_hash_lookup(ocfs_super *osb, 
-				     __u64 offset)
-{
-	ocfs_inode_num *inum = NULL;
-	ocfs_inode_hash *h = &osb->inode_hash;
-	struct inode * inode = NULL;
-
-//	LOG_ENTRY_ARGS("(offset=%llu, reverse = %s)\n", offset,
-//		       reverse ? "true" : "false");
-
-search:
-	spin_lock(&h->lock);
-
-	inum = __ocfs_inode_hash_lookup(h, offset);
-
-	if (inum) {
-		if (inum->i_state == INUM_UNBOUND) {
-			spin_unlock(&h->lock);
-			LOG_TRACE_ARGS("waiting for inum (%lu, %llu) to be "
-				       "bound\n", inum->i_ino, offset);
-
-			yield();
-			goto search;
-		}
-
-		inode = inum->i_inode;
-		if (ocfs_inc_icount(inode) < 0)
-			BUG();
-	}
-
-	spin_unlock(&h->lock);
-
-//	LOG_EXIT_PTR(inode);
-	return(inode);
-}
-
-/* used for filldir. We don't want the whole inode just i_ino if it
- * exists, otherwise we return an unused inode number */
-ino_t ocfs_inode_hash_lookup_ino(ocfs_super *osb, __u64 off)
-{
-	ocfs_inode_num *inum = NULL;
-	ocfs_inode_hash *h = &osb->inode_hash;
-	ino_t ino = OCFS_UNUSED_INODE_NUMBER;
-
-	LOG_ENTRY_ARGS("(off=%llu)\n", off);
-
-	spin_lock(&h->lock);
-
-	inum = __ocfs_inode_hash_lookup(h, off);
-
-	if (inum)
-		ino = inum->i_ino;
-
-	spin_unlock(&h->lock);
-
-	LOG_EXIT_ULONG(ino);
-
-	return(ino);
-}
-
-static inline void ocfs_debug_print_inum(ocfs_inode_num *inum, 
-					 struct inode * inode)
-{
-
-	if (inum) {
-		printk("ocfs2: inum info\n");
-		printk("       i_state   = %s\n", (inum->i_state == INUM_BOUND)
-		       ? "INUM_BOUND" : "INUM_UNBOUND");
-		printk("       i_ino     = %lu\n", inum->i_ino);
-		printk("       i_feoff   = %llu\n", inum->i_feoff);
-		printk("       i_inode   = 0x%p\n", inum->i_inode);
-	}
-
-	if (!inode)
-		return;
-
-	if (inum && inode != inum->i_inode)
-		printk("ocfs: Inode pointer (0x%p) is different from inum!\n", 
-		       inode);
-	printk("ocfs: inode info\n");
-	printk("       inode     = 0x%p\n", inode);
-	printk("       i_ino     = %lu\n", inode->i_ino);
-	printk("       feoff     = %llu\n", OCFS_I(inode)->feoff);
-	printk("       i_count   = %u\n", atomic_read(&inode->i_count));
-	printk("       deleted   = %s\n", INODE_DELETED(inode) ? "yes" : "no");
-	return;
-}
-
-/*
- * ocfs_inode_hash_insert()
- *
- * returns the inode number for that offset if it already exists in
- * the hash, otherwise inserts a new inode and returns the inode
- * number passed in. 
- */
-unsigned long ocfs_inode_hash_insert(ocfs_super *osb,
-				     __u64 offset)
-{
-	ocfs_inode_hash *h = &osb->inode_hash;
-	ocfs_inode_num *inum = NULL;
-	ocfs_inode_num *new_inum = NULL;
-	struct list_head *head;
-	int bucket;
-	unsigned long ino = 0;
-	struct super_block *sb = osb->sb;
-
-	LOG_ENTRY_ARGS("(offset = %llu)\n)", offset);
-
-again:
-	spin_lock(&h->lock);
-
-	inum = __ocfs_inode_hash_lookup(h, offset);
-
-	/* whoa, offset better be the same! */
-	if (inum && (inum->i_feoff != offset)) {
-		LOG_ERROR_ARGS("inum=%p, i_feoff=%llu, fe_off=%llu)\n",
-			       inum, inum ? inum->i_feoff : 0ULL,
-			       offset);
-		BUG();
-	}
-
-	/* (second pass) we didn't find anything, insert new one. */
-	if (inum == NULL && new_inum) {
-		bucket = OCFS_INODE_HASH(h, offset);
-		head = &h->hash[bucket];
-
-		list_add(&new_inum->i_list, head);
-		h->num_ents++;
-	}
-
-	spin_unlock(&h->lock);
-
-	/* if this is our first pass and we haven't found anything,
-	 * create it now and go back up to try an insert. */
-	if (inum == NULL && new_inum == NULL) {
-		new_inum = ocfs_create_inode_num();
-
-		/* root inode always has the same inode number. */
-		if (offset == OCFS_ROOT_INODE_FE_OFF)
-			ino = OCFS_ROOT_INODE_NUMBER;
-		else
-			ino = iunique(sb, OCFS_ROOT_INODE_NUMBER);
-		new_inum->i_ino = ino;
-		new_inum->i_feoff = offset;
-
-		goto again;
-	}
-
-	/* we created a new one to add, but someone added it before we
-	 * could start our second pass, so just clean up. */
-	if (inum && new_inum) {
-		ocfs_free_inode_num(new_inum);
-		new_inum = NULL;
-	}
-
-	/* if we never did an insert, then return the looked up ino. */
-	if (inum) {
-		ino = inum->i_ino;
-		LOG_TRACE_ARGS("Returning an inum that was already in the "
-			       "hash (%lu)\n", ino);
-	}
-
-	LOG_EXIT_ULONG(ino);
-
-	return ino;
-} /* ocfs_inode_hash_insert */
-
-/*
- * bind an inode to an inum.
- */
-void ocfs_inode_hash_bind(ocfs_super *osb, __u64 feoff, struct inode *inode)
-{
-	ocfs_inode_hash *h = &osb->inode_hash;
-	ocfs_inode_num *inum = NULL;
-
-	LOG_ENTRY_ARGS("(feoff=%llu, inode->i_ino = %lu)\n",
-		       feoff, inode->i_ino);
-
-	spin_lock(&h->lock);
-
-	inum = __ocfs_inode_hash_lookup(h, feoff);
-
-	if (!inum) {
-		printk("ocfs2: lost inum (feoff = %llu)! AIEEEE!\n", 
-		       feoff);
-		ocfs_debug_print_inum(inum, inode);
-		BUG();
-	}
-
-	if ((inum->i_feoff != feoff) 
-	    || (GET_INODE_FEOFF(inode) != feoff)) {
-		LOG_ERROR_ARGS("passed=%llu, on inode=%llu, "
-			       "(inum feoff = %llu)\n",
-			       feoff, GET_INODE_FEOFF(inode),
-			       inum->i_feoff);
-		BUG();
-	}
-
-	if (inum->i_ino != inode->i_ino) {
-		LOG_ERROR_ARGS("inode numbers don't match! "
-			       "(inum=%lu, inode=%lu)\n", 
-			       inum->i_ino, inode->i_ino);
-		LOG_ERROR_ARGS("passed=%llu, on inode=%llu, "
-			       "(inum feoff = %llu)\n",
-			       feoff, GET_INODE_FEOFF(inode),
-			       inum->i_feoff);
-		BUG();
-	}
-
-	if (inum->i_state == INUM_UNBOUND) {
-		inum->i_inode = inode;
-		inum->i_state = INUM_BOUND;
-		if (ocfs_inc_icount(inode) < 0)
-			BUG();
-
-		LOG_TRACE_ARGS("bound to ino %lu, feoff=%llu)\n",
-			       inode->i_ino, inum->i_feoff);
-	} else if (inum->i_inode != inode) {
-		LOG_ERROR_ARGS("Inum is bound to a different inode! "
-			       "(%llu) (%lu) (%lu) (deleted = %u)\n",
-			       feoff, inode->i_ino, 
-			       inum->i_inode->i_ino, 
-			       INODE_DELETED(inum->i_inode));
-		ocfs_debug_print_inum(inum, inode);
-		BUG();
-	}
-
-	spin_unlock(&h->lock);
-
-	LOG_EXIT();
-	return;
-}
-
-/* 
- * __ocfs_inode_hash_remove()
- *
- * only return inum if we're supposed to free it, otherwise return NULL. 
- */
-static inline ocfs_inode_num * __ocfs_inode_hash_remove(ocfs_inode_hash *h, 
-						  __u64 off)
-{
-	ocfs_inode_num *inum;
-
-	inum = __ocfs_inode_hash_lookup(h, off);
-
-	if (inum == NULL) {
-		printk("ocfs2: Cannot remove a nonexistent inum from hash!"
-		       "(%llu)\n", off);
-		BUG();
-	}
-
-	list_del(&inum->i_list);
-	h->num_ents--;
-
-	return(inum);
-} /* __ocfs_inode_hash_remove */
-
-/*
- * ocfs_inode_hash_remove()
- */
-void ocfs_inode_hash_remove(ocfs_inode_hash *h, __u64 off)
-{
-	ocfs_inode_num *inum = NULL;
-
-	LOG_ENTRY_ARGS("(off = %llu)\n", off);
-
-	spin_lock(&h->lock);
-
-	inum = __ocfs_inode_hash_remove(h, off);
-
-	spin_unlock(&h->lock);
-
-	if (!inum->i_inode || inum->i_state == INUM_UNBOUND)
-		LOG_ERROR_ARGS("deleting inum in unbound state! (state = %d, "
-			       "feoff = %llu, i_ino = %lu\n",
-			       inum->i_state, inum->i_feoff, inum->i_ino);
-
-	if (inum->i_inode)
-		iput(inum->i_inode);
-
-	ocfs_free_inode_num(inum);
-
-	LOG_EXIT();
-	return;
-} /* ocfs_inode_hash_remove */
-
-/* 
- * ocfs_inode_rehash()
- *
- * update the offset value returned by a lookup on this key. Used
- * during rename. 
- *
- * TODO: This should also take an inode argument and reset
- * the offset on that while holding the hash lock. 
- */
-int ocfs_inode_rehash(ocfs_inode_hash *h, 
-		      __u64 oldoff, 
-		      __u64 newoff)
-{
-	int status = 0;
-	ocfs_inode_num *inum = NULL;
-	ocfs_inode_num *target = NULL;
-	struct list_head *head;
-	int bucket;
-
-	LOG_ENTRY_ARGS("(oldoff = %llu, newoff = %llu)\n", oldoff, newoff);
-
-	spin_lock(&h->lock);
-
-	/* Sanity check. If we're going to be moving buckets, make
-	 * sure someone else isn't in the new one. */
-	if (newoff != oldoff) {
-		target = __ocfs_inode_hash_lookup(h, newoff);
-		if (target) {
-			LOG_ERROR_ARGS("Rehashing on top of an existing inum!"
-				       "oldoff = %llu, newoff = %llu\n", 
-				       oldoff, newoff);
-			BUG();
-		}
-	}
-
-	inum = __ocfs_inode_hash_lookup(h, oldoff);
-	if (inum == NULL)
-		BUG();
-
-	if (inum->i_state != INUM_BOUND)
-		BUG();
-
-	list_del(&inum->i_list);
-
-	inum->i_feoff = newoff;
-
-	bucket = OCFS_INODE_HASH(h, newoff);
-	head = &h->hash[bucket];
-	list_add(&inum->i_list, head);
-
-	spin_unlock(&h->lock);
-
-	LOG_EXIT_STATUS(status);
-	return status;
-} /* ocfs_inode_rehash */
-
-

Modified: branches/new-dir-format/src/inc/io.h
===================================================================
--- branches/new-dir-format/src/inc/io.h	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/inc/io.h	2004-05-24 21:34:48 UTC (rev 932)
@@ -54,16 +54,6 @@
 		    int                  flags, 
 		    struct inode         *inode);
 
-struct inode * ocfs_get_fileent_inode(ocfs_super *osb, int idx, struct buffer_head *bhs[], 
-				     struct inode *parent);
-
-void ocfs_put_fileent_inode(int idx, struct inode *arr[]);
-
-int ocfs_write_dirnode(ocfs_super * osb, struct buffer_head *bhs[], struct inode *hdr_inode);
-
-int ocfs_read_dirnode(ocfs_super * osb, __u64 off,int sync, struct buffer_head *bhs[], struct inode *hdr_inode);
-
-
 void ocfs_end_buffer_io_sync     (struct buffer_head   *bh, 
 				  int                   uptodate);
 
@@ -71,6 +61,7 @@
 #define OCFS_BH_COND_CACHED       2
 #define OCFS_BH_CONCURRENT_WRITE  4     /* This should only be used by ocfs_worker */
 #define OCFS_BH_IGNORE_JBD        8     /* This should only be used by ocfs_checkpoint_handle! */
+#define OCFS_BH_READAHEAD         16	/* use this to pass READA down to submit_bh */
 
 
 #define OCFS_NONCACHED(osb,off)  ((off) < (osb)->vol_layout.data_start_off)
@@ -293,8 +284,7 @@
 
 #define OCFS_DO_HEX_DUMP(bh)						      \
 do {									      \
-	printk("bh->b_blocknr = %llu, bh->b_data:\n",			      \
-	       (unsigned long long)bh->b_blocknr);			      \
+	printk("bh->b_blocknr = %lu, bh->b_data:\n", bh->b_blocknr);	      \
 	for(i = 0; i < 512; i++) {					      \
 		printk("%03x ", bh->b_data[i]);				      \
 		if ( ((i+1) % 16) == 0 )				      \
@@ -303,50 +293,6 @@
 	printk("\n");							      \
 } while (0)
 
-/* we should take this out later */
-static inline int check_rootdir_overwrite(struct buffer_head *bh)
-{
-	int i;
-
-	if (bh->b_blocknr >= 4720 && bh->b_blocknr < (4720+256)) {
-		ocfs_dir_node *dir = (ocfs_dir_node *)bh->b_data;
-		ocfs_file_entry *fe = (ocfs_file_entry *)bh->b_data;
-		
-		if (strncmp("DIRNV20", dir->signature, strlen("DIRNV20"))==0) {
-			if (dir->node_disk_off >> 9 != 4720) {
-				OCFS_DO_HEX_DUMP(bh);
-				printk("uh oh!  dirnode disk off is incorrect!  %u\n",(__u32)(dir->node_disk_off>>9));
-				BUG();
-			} else if (bh->b_blocknr != 4720) {
-				OCFS_DO_HEX_DUMP(bh);
-				printk("uh oh!  dirnode is being written at blocknr=%llu!\n", (unsigned long long)bh->b_blocknr);
-				BUG();
-			}
-		} else if (strncmp("FIL", fe->signature, strlen("FIL"))==0) {
-			if (fe->this_sector >> 9 != bh->b_blocknr) {
-				OCFS_DO_HEX_DUMP(bh);
-				printk("uh oh!  fe->this_sector (%u) != blocknr (%llu)\n",
-				       (__u32)(fe->this_sector>>9),
-				       (unsigned long long)bh->b_blocknr);
-				BUG();
-			} else if (fe->u.child_dirnode >> 9 == 4720) {
-				OCFS_DO_HEX_DUMP(bh);
-				printk("uh oh!  fe->child_dirnode recurses!!!\n");
-				BUG();
-			}
-		} else if (bh->b_blocknr == 4720) {
-			OCFS_DO_HEX_DUMP(bh);
-			printk("uh oh!  invalid type being written to dirnode!\n");
-			printk("signature: '%c%c%c%c%c%c%c'\n", 
-			       dir->signature[0], dir->signature[1], dir->signature[2],
-			       dir->signature[3], dir->signature[4], dir->signature[5], dir->signature[6]);
-			printk("fooblydoo flippity floppety floo. supercalafragilicousexpialdizzle\n");
-			BUG();
-		}
-	}
-	return 0;
-}
-
 static inline int ocfs_write_bh (ocfs_super * osb, struct buffer_head *bh, 
 				 int flags, struct inode *inode)
 {

Modified: branches/new-dir-format/src/inc/ocfs.h
===================================================================
--- branches/new-dir-format/src/inc/ocfs.h	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/inc/ocfs.h	2004-05-24 21:34:48 UTC (rev 932)
@@ -262,6 +262,8 @@
 #define  OCFS_DEFAULT_DIR_NODE_SIZE  (512 * OCFS_DEFAULT_DIR_NODE_SECTS)
 #define  OCFS_DEFAULT_FILE_NODE_SIZE (512)
 
+#define OCFS_DEFAULT_INODE_SIZE	     (512)
+
 /*
 ** The following flag values reflect the operation to be performed
 **   by ocfs_create_modify_file
@@ -284,8 +286,8 @@
 #define  FLAG_FAST_PATH_LOCK      0x00004000
 #define  FLAG_FILE_UNUSED5        0x00008000
 #define  FLAG_FILE_UNUSED6        0x00010000
-#define  FLAG_DEL_NAME            0x00020000
-#define  FLAG_DEL_INODE           0x00040000
+//#define  FLAG_DEL_NAME            0x00020000
+//#define  FLAG_DEL_INODE           0x00040000
 #define  FLAG_FILE_UNUSED7        0x00080000
 #define  FLAG_FILE_UNUSED8        0x00100000
 #define  FLAG_FILE_UNUSED9        0x00200000
@@ -432,10 +434,6 @@
 #define  OCFS_FLAG_MEM_LISTS_INITIALIZED          (0x00000002)
 #define  OCFS_FLAG_SHUTDOWN_VOL_THREAD            (0x00000004)
 
-/* ocfs_dir_node->dir_node_flags flags */
-#define  DIR_NODE_FLAG_ROOT           0x01
-#define  DIR_NODE_FLAG_ORPHAN         0x02
-
 /*
 ** Information on Publish sector of each node
 */
@@ -476,9 +474,7 @@
 #define  OCFS_ATTRIB_SYMLINK               (0x100)
 #define  OCFS_ATTRIB_SOCKET                (0x200)
 
-#define  INVALID_DIR_NODE_INDEX              -1
 #define  INVALID_NODE_POINTER                -1
-#define  OCFS_DIR_NODE_SIGNATURE             "DIRNV20"
 #define  OCFS_FILE_ENTRY_SIGNATURE           "FIL"
 #define  OCFS_EXTENT_HEADER_SIGNATURE        "EXTHDR2"
 #define  OCFS_EXTENT_DATA_SIGNATURE          "EXTDAT1"
@@ -498,8 +494,8 @@
 #define EWARNING                   998
 
 #define OCFS_MAGIC                 0xa156f7eb
-#define OCFS_ROOT_INODE_NUMBER     2
-#define OCFS_ROOT_INODE_FE_OFF      1536
+#define OCFS_ROOT_INODE_NUMBER     3
+#define OCFS_ROOT_INODE_FE_OFF(osb) (OCFS_ROOT_INODE_NUMBER << osb->sb->s_blocksize_bits)
 #define OCFS_LINUX_MAX_FILE_SIZE   9223372036854775807LL
 #define INITIAL_EXTENT_MAP_SIZE    10
 
@@ -536,10 +532,6 @@
 #ifndef  _OCFSDEF_H_
 #define  _OCFSDEF_H_
 
-#define  IS_VALID_DIR_NODE(ptr)                                       \
-		 (!strncmp((ptr)->signature, OCFS_DIR_NODE_SIGNATURE, \
-			   strlen(OCFS_DIR_NODE_SIGNATURE)))
-
 /* sm - ocfs 1.0 fails to set fe->sig for dirs */
 #define  IS_VALID_FILE_ENTRY(ptr)     \
 			(((ptr)->attribs & OCFS_ATTRIB_DIRECTORY) ||	\
@@ -757,58 +749,7 @@
 
 #endif
 
-/* ofile macros */
-#ifdef OCFS_MEM_DBG
-#define ocfs_allocate_ofile(flag)    ((ocfs_file *)({ \
-	ocfs_file *of = NULL; \
-	of = ocfs_dbg_slab_alloc(OcfsGlobalCtxt.ofile_cache, __FILE__, __LINE__); \
-	if (of != NULL) { \
-	  memset (of, 0, sizeof (ocfs_file)); \
-	  of->obj_id.type = OCFS_TYPE_OFILE; \
-	  of->obj_id.size = sizeof (ocfs_file); \
-	  if (flag==OCFS_ATTRIB_DIRECTORY) { \
-	    int sz = OCFS_DEFAULT_DIR_NODE_SECTS * sizeof(struct buffer_head *); \
-	    of->curr_dir_buf = ocfs_malloc(sz); \
-	    if (of->curr_dir_buf == NULL) { \
-	      ocfs_safefree(of); \
-	      of = NULL; \
-	    } else \
-	      memset(of->curr_dir_buf, 0, sz); \
-	  } \
-	} \
-	of; }))
 
-#define ocfs_release_ofile(of) ({ \
-	OCFS_ASSERT (of); \
-	ocfs_safefree (of->curr_dir_buf); \
-	ocfs_dbg_slab_free (OcfsGlobalCtxt.ofile_cache, of); })
-#else  /* !OCFS_MEM_DBG */
-#define ocfs_allocate_ofile(flag)    ((ocfs_file *)({ \
-	ocfs_file *of = NULL; \
-	of = kmem_cache_alloc (OcfsGlobalCtxt.ofile_cache, GFP_NOFS); \
-	if (of != NULL) { \
-	  memset (of, 0, sizeof (ocfs_file)); \
-	  of->obj_id.type = OCFS_TYPE_OFILE; \
-	  of->obj_id.size = sizeof (ocfs_file); \
-	  if (flag==OCFS_ATTRIB_DIRECTORY) { \
-	    int sz = OCFS_DEFAULT_DIR_NODE_SECTS * sizeof(struct buffer_head *); \
-	    of->curr_dir_buf = ocfs_malloc(sz); \
-	    if (of->curr_dir_buf == NULL) { \
-	      ocfs_safefree(of); \
-	      of = NULL; \
-	    } else \
-	      memset(of->curr_dir_buf, 0, sz); \
-	  } \
-	} \
-	of; }))
-
-#define ocfs_release_ofile(of) ({ \
-	OCFS_ASSERT (of); \
-	ocfs_safefree (of->curr_dir_buf); \
-	kmem_cache_free (OcfsGlobalCtxt.ofile_cache, of); })
-#endif
-
-
 /* file entry macros */
 #ifdef OCFS_MEM_DBG
 #define ocfs_allocate_file_entry()  ((ocfs_file_entry *)({ \
@@ -1616,6 +1557,7 @@
 	} u;     
 
 	ocfs_lock_res     i_lockres;
+	__u32 		  i_dir_start_lookup;
 } ocfs_inode_private;
 
 /* Eventually, the 'flags' and 'oin_flags' fields need to be
@@ -1635,7 +1577,7 @@
 /* set on init_private, cleared on clear_inode */
 #define OCFS_INODE_INITIALIZED      0x00000004
 /* is this a system file? */
-#define OCFS_INODE_SYSFILE          0x00000008
+#define OCFS_INODE_SYSTEM_FILE      0x00000008
 
 #define GET_INODE_CLEAN_SEQ(i)  (atomic_t *)(&(OCFS_I(i)->i_clean_buffer_seq))
 
@@ -1656,6 +1598,19 @@
 
 #define GET_INODE_FEOFF(i) OCFS_I(i)->feoff
 
+static inline unsigned long ino_from_fe_off(struct inode *inode)
+{
+	return (unsigned long)((GET_INODE_FEOFF(inode) >> 
+				inode->i_sb->s_blocksize_bits) & (__u64)ULONG_MAX);
+}
+
+static inline unsigned long ino_from_off(struct super_block *sb, __u64 off)
+{
+	return (unsigned long)((off >> sb->s_blocksize_bits) & (__u64)ULONG_MAX);
+}
+
+
+
 #warning take this out when all the lockres stuff checks out
 #define GET_INODE_LOCKRES(i) ({ if (i==NULL) BUG(); (&(OCFS_I(i)->i_lockres)); })
 
@@ -1768,6 +1723,18 @@
 	atomic_t ext_extends;
 } ocfs_alloc_stats;
 
+enum {
+	GLOBAL_BITMAP_SYSTEM_INODE = 0,
+	FILE_ALLOC_BITMAP_SYSTEM_INODE,
+	INODE_ALLOC_BITMAP_SYSTEM_INODE,
+	JOURNAL_SYSTEM_INODE,
+#if 0
+	DIR_ALLOC_BITMAP_SYSTEM_INODE,
+#endif
+	NUM_SYSTEM_INODES
+};
+
+
 /*
  * ocfs_super
  *
@@ -1788,6 +1755,7 @@
 	struct list_head cache_lock_list;
 	struct super_block *sb;
 	struct inode *root_inode;
+	struct inode *system_inodes[NUM_SYSTEM_INODES];
 	ocfs_vol_layout vol_layout;
 	ocfs_vol_node_map vol_node_map;
 	struct semaphore cfg_lock;
@@ -1804,6 +1772,8 @@
 	__u32 cluster_size_bits;
 	__u32 dir_alloc_bits;
 	__u32 file_alloc_bits;
+	__u32 inode_alloc_bits;
+	__u32 inode_size;
 	int needs_flush;
 
 	ocfs_alloc_bm cluster_bitmap;
@@ -1872,11 +1842,9 @@
 	struct semaphore global_res;
 	struct list_head osb_next;	/* List of all volumes */
 	kmem_cache_t *inode_cache;
-	kmem_cache_t *ofile_cache;
 	kmem_cache_t *fe_cache;
 	kmem_cache_t *extent_cache;
 	kmem_cache_t *bh_sem_cache;
-	kmem_cache_t *inum_cache;
 	__u32 flags;
 	__u32 pref_node_num;		/* preferred... osb has the real one */
 	ocfs_guid guid;			/* uniquely identifies a node */
@@ -2027,8 +1995,10 @@
 			__u32 used_bits;
 			__u32 total_bits;
 		} bitinfo;
-	} u;     
-/* sizeof(fe) = 496 bytes */
+	} u;
+        __u64 alloc_file_off;             // NUMBER RANGE(0,ULONG_LONG_MAX)
+        __u32 alloc_node;                 // NUMBER RANGE(0,31)
+/* sizeof(fe) = 508 bytes */
 }
 ocfs_file_entry;			  // END CLASS
 
@@ -2063,50 +2033,7 @@
 OCFS_GCC_ATTR_PACKED
 ocfs_index_hdr;
 
-/* not sizeof-safe across platforms */
-typedef struct _ocfs_dir_node		// CLASS
-{
-	ocfs_disk_lock disk_lock;       // DISKLOCK
-	__u8 signature[8];               // CHAR[8]
-	__u64 alloc_file_off;             // NUMBER RANGE(0,ULONG_LONG_MAX) 
-	__u32 alloc_node;                 // NUMBER RANGE(0,31)
-	__u64 free_node_ptr;              /* Used in topmost dirnode,
-					   * points to last dirnode in
-					   * chain, or -1 if only
-					   * one. */
-	__u64 node_disk_off;              // DISKPTR
-	__s64 next_node_ptr;              // DISKPTR 
-	__s64 indx_node_ptr;              // DISKPTR
 
-	__s64 next_del_ent_node;          /* Used in non-topmost
-					   * dirnodes, continues the
-					   * chain of dirnodes which
-					   * have had fe's deleted
-					   * from. -1 means end of list. */
-	__s64 head_del_ent_node;          /* Used in topmost dirnode,
-					   * points to head of a list
-					   * of dirnodes which we've
-					   * deleted from. -1 if never
-					   * deleted, or we've only
-					   * got one dirnode. */
-	__u8 first_del;                  // DIRNODEINDEX
-	__u8 num_del;                    // NUMBER RANGE(0,254)
-	__u8 num_ents;	                // NUMBER RANGE(0,254)
-	__u8 depth;		        // UNUSED
-	__u8 num_ent_used;	        // NUMBER RANGE(0,254)
-	__u8 dir_node_flags;	        // DIRFLAG
-	__u8 sync_flags;		 // SYNCFLAG
-	__u8 index[256];                 // DIRINDEX
-	__u8 index_dirty;                // NUMBER RANGE(0,1)
-	__u8 bad_off;                    // NUMBER RANGE(0,254)
-	__u8 reserved[127];              // UNUSED
-	__u8 file_ent[1];                // UNUSED
-}
-OCFS_GCC_ATTR_PACKALGN
-ocfs_dir_node;				// END CLASS
-
-
-
 typedef struct _ocfs_extent_group			// CLASS
 {
 	__u8 signature[8];				// CHAR ARRAY[8]
@@ -2296,9 +2223,12 @@
 
 
 /* these three used as 'type' in ocfs_bitmap_update */
+#if 0
 #define  DISK_ALLOC_DIR_NODE      1
+#endif
 #define  DISK_ALLOC_EXTENT_NODE   2
 #define  DISK_ALLOC_VOLUME        3
+#define  DISK_ALLOC_INODE	  4
 
 /* a bitmap update, currently used for freeing bits */
 typedef struct ocfs_bitmap_update
@@ -2450,9 +2380,58 @@
 	char nodename[255];	/* node name */
 };
 
+/*
+ * ocfs directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+#define OCFS_FT_UNKNOWN		0
+#define OCFS_FT_REG_FILE	1
+#define OCFS_FT_DIR		2
+#define OCFS_FT_CHRDEV		3
+#define OCFS_FT_BLKDEV		4
+#define OCFS_FT_FIFO		5
+#define OCFS_FT_SOCK		6
+#define OCFS_FT_SYMLINK		7
 
+#define OCFS_FT_MAX		8
 
+/*
+ * OCFS_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define OCFS_DIR_PAD			4
+#define OCFS_DIR_ROUND			(OCFS_DIR_PAD - 1)
+#define OCFS_DIR_REC_LEN(name_len)	(((name_len) + 12 + OCFS_DIR_ROUND) & \
+					 ~OCFS_DIR_ROUND)
+#define OCFS_LINK_MAX 32000
 
+
+struct ocfs2_dir_entry {
+	__u64   inode;                  /* Inode number */
+	__u16   rec_len;                /* Directory entry length */
+	__u8    name_len;               /* Name length */
+	__u8    file_type;
+	char    name[OCFS_MAX_FILENAME_LENGTH];    /* File name */
+};
+
+#define S_SHIFT 12
+static unsigned char ocfs_type_by_mode[S_IFMT >> S_SHIFT] = {
+	[S_IFREG >> S_SHIFT]    OCFS_FT_REG_FILE,
+	[S_IFDIR >> S_SHIFT]    OCFS_FT_DIR,
+	[S_IFCHR >> S_SHIFT]    OCFS_FT_CHRDEV,
+	[S_IFBLK >> S_SHIFT]    OCFS_FT_BLKDEV,
+	[S_IFIFO >> S_SHIFT]    OCFS_FT_FIFO,
+	[S_IFSOCK >> S_SHIFT]   OCFS_FT_SOCK,
+	[S_IFLNK >> S_SHIFT]    OCFS_FT_SYMLINK,
+};
+
+static inline void ocfs_set_de_type(struct super_block *sb, struct ocfs2_dir_entry *de, umode_t mode) {
+	de->file_type = ocfs_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+}
+
+
+
 typedef struct _ocfs_find_inode_args
 {
 	__u64 feoff;
@@ -2472,7 +2451,12 @@
 }
 ocfs_timeout;
 
+#define NAMEI_RA_CHUNKS  2
+#define NAMEI_RA_BLOCKS  4
+#define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+#define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
 
+
 #define __ocfs_wait(wq, condition, timeo, ret)			\
 do {								\
 	ocfs_timeout __to;					\
@@ -2539,17 +2523,6 @@
 })
 
 
-static inline int ocfs_get_max_dir_index(ocfs_dir_node *dir) 
-{
-	int i;
-	int ret = -1;
-	for (i=0; i<dir->num_ent_used; i++)
-		if ((int)dir->index[i] > ret)
-			ret = (int)dir->index[i];
-
-	return ret;
-}
-
 static inline int ocfs_is_local_cache_lock(ocfs_super *osb, struct inode *inode)
 {
 	ocfs_lock_res *lockres = GET_INODE_LOCKRES(inode);

Modified: branches/new-dir-format/src/inc/proto.h
===================================================================
--- branches/new-dir-format/src/inc/proto.h	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/inc/proto.h	2004-05-24 21:34:48 UTC (rev 932)
@@ -33,7 +33,6 @@
 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_alloc_node_block (ocfs_super * osb, __u64 FileSize, __u64 * DiskOffset, __u64 * file_off, __u32 NodeNum, __u32 Type, ocfs_journal_handle *handle);
-int ocfs_free_directory_block (ocfs_super * osb, ocfs_file_entry * fe, ocfs_journal_handle *handle, struct inode *inode);
 int ocfs_free_file_extents (ocfs_super * osb, struct buffer_head *fe_bh, ocfs_journal_handle *handle, struct inode *inode);
 
 int ocfs_lookup_obj_for_proc (ocfs_vote_obj *obj, ocfs_vote_obj_lookup_data *data);
@@ -90,6 +89,8 @@
 void ocfs_clear_inode (struct inode *inode);
 int ocfs_block_symlink (struct inode *inode, const char *symname, int len);
 ssize_t ocfs_rw_direct (int rw, struct file *filp, char *buf, size_t size, loff_t * offp);
+struct buffer_head *ocfs_bread(ocfs_journal_handle *handle, struct inode * inode, 
+			       int block, int create, int *err, int reada);
 
 
 int ocfs_submit_vol_metadata(ocfs_super *osb, ocfs_offset_map *map_buf, __u32 num);
@@ -197,7 +198,6 @@
 int ocfs_get_system_file_size (ocfs_super * osb, __u32 FileId, __u64 * Length, __u64 * AllocSize);
 __u64 ocfs_file_to_disk_off (ocfs_super * osb, __u32 FileId, __u64 Offset);
 
-void ocfs_initialize_dir_node (ocfs_super * osb, ocfs_dir_node * dir_node, __u64 bitmap_off, __u64 file_off, __u32 node);
 int ocfs_compare_qstr (struct qstr * s1, struct qstr * s2);
 void ocfs_truncate_inode_pages(struct inode *inode, loff_t off);
 
@@ -233,12 +233,9 @@
 int ocfs_rename (struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry);
 int ocfs_symlink (struct inode *dir, struct dentry *dentry, const char *symname);
 
-int ocfs_find_files_on_disk (ocfs_super * osb, struct qstr * file_name, struct buffer_head ** fe_bh, ocfs_file * ofile, struct inode *inode, int take_lock);
+int ocfs_find_files_on_disk (ocfs_super * osb, struct dentry * dentry, struct buffer_head ** fe_bh, struct inode *inode, struct inode *file_inode, int take_lock, struct buffer_head **dirent_bh, struct ocfs2_dir_entry **dirent);
 int ocfs_write_force_dir_node (ocfs_super * osb, struct buffer_head *bhs[], __s32 idx);
-int ocfs_insert_file (ocfs_super * osb, ocfs_file_entry * InsertEntry, struct buffer_head **insert_bh, ocfs_journal_handle * handle, struct inode *dir_inode, struct inode *file_inode);
-int ocfs_reindex_dir_node (ocfs_super * osb, __u64 DirNodeOffset, struct buffer_head *bhs[], ocfs_journal_handle *handle, struct inode *dir_inode);
 int ocfs_recover_dir_node (ocfs_super * osb, __u64 OrigDirNodeOffset, __u64 SavedDirNodeOffset);
-int ocfs_remove_file (ocfs_super * osb, struct buffer_head *febh, struct buffer_head *lockbh, ocfs_journal_handle *handle, struct inode *dir_inode, struct inode *file_inode);
 
 
 
@@ -260,20 +257,8 @@
 
 void ocfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate);
 
-int ocfs_inode_hash_init(ocfs_super *osb);
-void ocfs_inode_hash_destroy(ocfs_inode_hash *h);
-unsigned long ocfs_inode_hash_insert(ocfs_super *osb,
-				     __u64 offset);
-void ocfs_inode_hash_bind(ocfs_super *osb, __u64 feoff, struct inode *inode);
-void ocfs_inode_hash_remove(ocfs_inode_hash *h, __u64 off);
-int ocfs_inode_rehash(ocfs_inode_hash *h, 
-		      __u64 oldoff, 
-		      __u64 newoff);
 struct inode *ocfs_iget(ocfs_super *osb, __u64 feoff, 
 			struct buffer_head *fe_bh);
-struct inode *ocfs_inode_hash_lookup(ocfs_super *osb, 
-				     __u64 offset);
-ino_t ocfs_inode_hash_lookup_ino(ocfs_super *osb, __u64 off);
 
 void ocfs_init_timeout(ocfs_timeout *to);
 void ocfs_set_timeout(ocfs_timeout *to, __u32 timeout);
@@ -285,4 +270,10 @@
 
 int ocfs_inode_revalidate(struct dentry *dentry);
 
+struct buffer_head * ocfs_find_entry (struct dentry *dentry, struct ocfs2_dir_entry ** res_dir);
+int ocfs_check_dir_entry (struct inode * dir, struct ocfs2_dir_entry * de, struct buffer_head * bh, unsigned long offset);
+int empty_dir (struct inode * inode);
+int ocfs_orphan_add(ocfs_journal_handle *handle, struct inode *inode);
+int ocfs_orphan_del(ocfs_journal_handle *handle, struct inode *inode);
+
 #endif /* _PROTO_H_ */

Modified: branches/new-dir-format/src/inode.c
===================================================================
--- branches/new-dir-format/src/inode.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/inode.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -162,7 +162,7 @@
 
 	/* Shortcut: if they ask for the root dirnode, just return
 	 * it. */
-	if (feoff == OCFS_ROOT_INODE_FE_OFF) {
+	if (feoff == OCFS_ROOT_INODE_FE_OFF(osb)) {
 		LOG_TRACE_ARGS("Asked for root dirnode (%llu)\n",
 			       feoff);
 
@@ -216,42 +216,33 @@
 	if (feoff < osb->vol_layout.root_start_off)
 		flags |= OCFS_FIND_INODE_FLAG_SYSFILE;
 
-	inode = ocfs_inode_hash_lookup(osb, feoff);
-	if (!inode) {
-		/* we should put this guy in the hash now... */
-		LOG_TRACE_STR("calling iget4");
+	args.feoff = feoff;
+	args.fe_bh = fe_bh;
+	args.flags = flags;
+	args.ino = ino_from_off(sb, feoff);
 
-		args.feoff = feoff;
-		args.fe_bh = fe_bh;
-		args.flags = flags;
-
-		/* alright, allocate a new inode number for this guy
-		 * and insert it into the hash. It's not bound yet --
-		 * read_inode2 binds the actual inode to it. */
-		args.ino = ocfs_inode_hash_insert(osb, feoff);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-		inode = iget5_locked (sb, args.ino, ocfs_find_actor, 
-				      ocfs_init_locked_inode, &args);
+	inode = iget5_locked (sb, args.ino, ocfs_find_actor, 
+			      ocfs_init_locked_inode, &args);
 #else
-		inode = iget4 (sb, args.ino, ocfs_find_inode, &args);
+	inode = iget4 (sb, args.ino, ocfs_find_inode, &args);
 #endif
-		if (inode == NULL) {
-			LOG_ERROR_STR("access error");
-			inode = NULL;
-			goto bail;
-		}
-		if (is_bad_inode (inode)) {
-			LOG_ERROR_STR("access error (bad inode)");
-			iput (inode);
-			inode = NULL;
-			goto bail;
-		}
+	if (inode == NULL) {
+		LOG_ERROR_STR("access error");
+		inode = NULL;
+		goto bail;
 	}
+	if (is_bad_inode (inode)) {
+		LOG_ERROR_STR("access error (bad inode)");
+		iput (inode);
+		inode = NULL;
+		goto bail;
+	}
 
 bail:
 	if (inode) {
-		LOG_TRACE_ARGS("returning inode with number %lu\n", 
-			       inode->i_ino);
+		LOG_TRACE_ARGS("returning inode with number %llu\n", 
+			       GET_INODE_FEOFF(inode));
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 		/* inode was *not* in the inode cache. 2.6.x requires
 		 * us to do our own read_inode call and unlock it
@@ -299,9 +290,6 @@
 
 	args = (ocfs_find_inode_args *) opaque;
 
-	if (ino != inode->i_ino)
-		goto bail;
-
 	if (GET_INODE_FEOFF(inode) != args->feoff) {
 		LOG_ERROR_STATUS(-EINVAL);
 		goto bail;
@@ -361,7 +349,6 @@
 	struct super_block *sb;
 	ocfs_super *osb;
 	__u64 offset;
-	unsigned long uniq_ino;
 
 	LOG_ENTRY_ARGS ("(0x%p, %u, size:%llu)\n", inode, mode, fe->file_size);
 
@@ -406,15 +393,15 @@
 	if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
 		OCFS_I(inode)->oin_flags |= OCFS_OIN_DIRECTORY;
 
-	if (create_ino) {
-		uniq_ino = ocfs_inode_hash_insert(osb, offset);
-		inode->i_ino = uniq_ino;
-		/* caller needs to know to call inode_hash_bind! */
-	}
+	if (create_ino)
+		inode->i_ino = ino_from_off(inode->i_sb, offset);
+
 	LOG_TRACE_ARGS("offset = %llu, ino = %lu, create_ino = %s\n",
-		       offset, inode->i_ino, 
+		       offset, inode->i_ino,
 		       create_ino ? "true" : "false");
 
+	printk("populate inode: setting nlink from %d to %d for %llu\n", inode->i_nlink, fe->link_cnt, offset);
+	inode->i_nlink = fe->link_cnt;
 	switch (inode->i_mode & S_IFMT) {
 	    case S_IFREG:
 		    atomic_set(GET_INODE_CLEAN_SEQ(inode), atomic_read(&osb->clean_buffer_seq));
@@ -423,10 +410,15 @@
 		    inode->i_size = fe->file_size;
 		    break;
 	    case S_IFDIR:
+		    if (inode->i_nlink < 2) {
+			    LOG_ERROR_ARGS("inlink=%d for %llu\n", inode->i_nlink, 
+					   offset);
+			    inode->i_nlink = 2;
+		    }
 		    atomic_set(GET_INODE_CLEAN_SEQ(inode), atomic_read(&osb->clean_buffer_seq));
 		    inode->i_op = &ocfs_dir_iops;
 		    inode->i_fop = &ocfs_dops;
-		    inode->i_size = OCFS_DEFAULT_DIR_NODE_SIZE;
+		    inode->i_size = fe->file_size;
 		    break;
 	    case S_IFLNK:
 		    atomic_set(GET_INODE_CLEAN_SEQ(inode), atomic_read(&osb->clean_buffer_seq));
@@ -561,10 +553,8 @@
 		BUG();
 
 	if (sysfile)
-		OCFS_SET_FLAG(OCFS_I(inode)->flags, OCFS_INODE_SYSFILE);
+		OCFS_SET_FLAG(OCFS_I(inode)->flags, OCFS_INODE_SYSTEM_FILE);
 
-	ocfs_inode_hash_bind(osb, feoff, inode);
-
 	ocfs_init_lockres (osb, inode);
 
 bail:
@@ -597,7 +587,7 @@
 	int ret = 0;
 	ocfs_file_entry *fe = NULL;
 
-	LOG_ENTRY_ARGS ("(0x%p, %lu, 0x%p)\n", inode, inode->i_ino, opaque);
+	LOG_ENTRY_ARGS ("(0x%p, %lu, %llu, 0x%p)\n", inode, inode->i_ino, GET_INODE_FEOFF(inode), opaque);
 
 	if (inode == NULL)
 		goto bail;
@@ -649,26 +639,9 @@
 {
 	ocfs_super *osb;
 
-	LOG_ENTRY_ARGS ("(0x%p, inode_i_ino=%lu)\n", inode, inode->i_ino);
+	LOG_ENTRY_ARGS ("(0x%p, i_ino=%llu)\n", inode, GET_INODE_FEOFF(inode));
 	LOG_TRACE_ARGS ("put_inode: count=%d\n", atomic_read(&inode->i_count));
 	osb = OCFS_SB(inode->i_sb);
-
-	/* Ok, if after this iput we would be the last holder of the
-	 * root inode, then we know we're unmounting so just dump it
-	 * now. */
-	if ((inode->i_ino == OCFS_ROOT_INODE_NUMBER) 
-	    && (atomic_read(&inode->i_count) == 2)) {
-		LOG_TRACE_STR("Oop, iputing the root inode!");
-		/* this is fun. Bring up the refcount for our call to
-		 * hash_remove so the iput inside of that function
-		 * doesn't throw us into recursion :) */
-		if (ocfs_inc_icount(inode) < 0)
-			BUG();
-		ocfs_inode_hash_remove(&osb->inode_hash, 
-				       GET_INODE_FEOFF(inode));
-		atomic_dec(&inode->i_count);
-	}
-
 	LOG_EXIT ();
 	return;
 }				/* ocfs_put_inode */
@@ -697,14 +670,14 @@
 	if (!inode)
 		goto bail;
 
-	LOG_TRACE_ARGS("Clearing inode %lu feoff: %llu)\n", inode->i_ino, 
+	LOG_TRACE_ARGS("Clearing inode feoff: %llu)\n", 
 		       GET_INODE_FEOFF(inode));
 
 	/* we should not really be using osb in this context. */
 	osb = OCFS_SB(inode->i_sb);
 
 	if (!inode->u.generic_ip) {
-		LOG_ERROR_ARGS("inode %lu has no generic_ip!\n", inode->i_ino);
+		LOG_ERROR_ARGS("inode %llu has no generic_ip!\n", GET_INODE_FEOFF(inode));
 		goto bail;
 	}
 
@@ -721,7 +694,7 @@
 		goto bail;
 	}
 
-	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
+	if (inode == osb->root_inode) {
 		LOG_TRACE_STR("this is the root inode, doing cleanup now!");
 		ocfs_sync_blockdev(inode->i_sb);
 		LOG_TRACE_STR ("syncing past root inode");
@@ -841,8 +814,8 @@
 	__u64 entryOffset;
 	struct buffer_head *bh = NULL;
 
-	LOG_ENTRY_ARGS ("(0x%p, %llu, 0x%p, %d)\n", inode,
-			(unsigned long long)iblock, bh_result, create);
+	LOG_ENTRY_ARGS ("(0x%p, %ld, 0x%p, %d)\n", inode, iblock, bh_result,
+			create);
 
 	if (!inode) {
 		LOG_ERROR_STR ("bad inode");
@@ -852,8 +825,7 @@
 	osb = OCFS_SB(inode->i_sb);
 
 	if ((iblock << 9) > PATH_MAX + 1) {
-		LOG_ERROR_ARGS ("file offset > PATH_MAX: %llu",
-				(unsigned long long)iblock << 9);
+		LOG_ERROR_ARGS ("file offset > PATH_MAX: %lu", iblock << 9);
 		goto bail;
 	}
 
@@ -874,8 +846,8 @@
 
 	if ((iblock << 9) >= (__s64)fe->alloc_size) {
 		OCFS_BH_PUT_DATA(bh);
-		LOG_ERROR_ARGS ("file offset is outside the allocated size: %llu",
-		     (unsigned long long)iblock << 9);
+		LOG_ERROR_ARGS ("file offset is outside the allocated size: %lu",
+		     iblock << 9);
 		goto bail;
 	}
 
@@ -892,6 +864,85 @@
 	return err;
 }				/* ocfs_symlink_get_block */
 
+
+/* TODO: this should probably be merged into ocfs_get_block */
+struct buffer_head *ocfs_bread(ocfs_journal_handle *handle, struct inode * inode, 
+			       int block, int create, int *err, int reada)
+{
+	struct buffer_head * bh = NULL;
+	int fatal = 0, tmperr = 0, new = 0;
+	ocfs_super *osb = NULL;
+	__s64 vbo = 0LL, lbo = 0LL;
+	int readflags = OCFS_BH_CACHED;
+
+	osb = OCFS_SB(inode->i_sb);
+	vbo = (__s64) block << inode->i_sb->s_blocksize_bits;
+
+	OCFS_ASSERT(!create || handle);
+
+#warning only turn this on if we know we can deal with read_bh returning nothing
+#if 0
+	if (reada)
+		readflags |= OCFS_BH_READAHEAD;
+#endif
+
+	if (vbo >= inode->i_size) {
+		if (!create) {
+			*err = -ENOSPC;
+			return NULL;
+		}
+		new = 1;
+	}
+
+	// ???: do we need priv_sem?  should have i_sem i think
+	if (vbo >= OCFS_I(inode)->alloc_size) {
+		*err = ocfs_extend_file(osb, vbo + 512LL, GET_INODE_FEOFF(inode),
+				       handle, inode, NULL);
+		if (*err < 0) {
+			*err = -ENOSPC;
+			return NULL;
+		}
+		// fe->file_size will be vbo+512 here, and alloc_size will be whatever
+		// i_size will be changed by caller (ocfs_add_entry) if we return !NULL
+	}
+
+	// do we need extend sem?  no extend dlm message for dirs
+	tmperr = ocfs_lookup_file_allocation(osb, vbo, &lbo, 1, NULL, inode);
+	if (tmperr < 0)
+		goto fail;
+
+	tmperr = ocfs_read_bh(osb, lbo, &bh, readflags, inode);
+	if (tmperr < 0)
+		goto fail;
+
+	tmperr = 0;
+	if (new) {
+		fatal = ocfs_journal_access(handle, bh,
+					   OCFS_JOURNAL_ACCESS_CREATE);
+		if (!fatal) {
+			char *buf = OCFS_BH_GET_DATA_WRITE(bh);  /* write */
+			memset(buf, 0, osb->sect_size);
+			set_buffer_uptodate(bh);
+			OCFS_BH_PUT_DATA(bh);
+			fatal = ocfs_journal_dirty(handle, bh);
+		}
+	}
+
+	if (fatal)
+		goto fail;
+
+	*err = 0;
+	return bh;
+
+fail:
+	if (bh) {
+		brelse (bh);
+		bh = NULL;
+	}
+	*err = -EIO;
+	return NULL;
+}
+
 /*
  * ocfs_get_block()
  *
@@ -905,8 +956,8 @@
 	__u32 len;
 	int oin_locked = 0;
 
-	LOG_ENTRY_ARGS ("(0x%p, %llu, 0x%p, %d)\n", inode,
-			(unsigned long long)iblock, bh_result, create);
+	LOG_ENTRY_ARGS ("(0x%p, %ld, 0x%p, %d)\n", inode, iblock, bh_result,
+			create);
 
 	if (S_ISLNK (inode->i_mode)) {
 		err = ocfs_symlink_get_block (inode, iblock, bh_result, create);
@@ -982,7 +1033,7 @@
 	int err = 0;
 	struct inode *inode = mapping->host;
 
-	LOG_ENTRY_ARGS("(block = %llu)\n", (unsigned long long)block);
+	LOG_ENTRY_ARGS("(block = %lu)\n", block);
 
 	if (!inode) {
 		LOG_ERROR_STR ("bmap: bad inode");
@@ -1657,8 +1708,8 @@
 	int needs_trunc;
 	ocfs_super *osb;
 
-	LOG_ENTRY_ARGS("(inode = 0x%p, ino = %lu)\n", inode, 
-		       inode ? inode->i_ino : 0);
+	LOG_ENTRY_ARGS("(inode = 0x%p, ino = %llu)\n", inode, 
+		       inode ? GET_INODE_FEOFF(inode) : 0ULL);
 
 	if (!inode) {
 		LOG_TRACE_STR("eep, no inode!\n");
@@ -1733,14 +1784,14 @@
 	 * in here! */
 	offset = GET_INODE_FEOFF(inode);
 	if (offset == 0) {
-		LOG_ERROR_ARGS("inode %lu has zero offset\n", inode->i_ino);
+		LOG_ERROR_ARGS("inode %llu has zero offset\n", GET_INODE_FEOFF(inode));
 		status = -EINVAL;
 		goto leave;
 	}
 
 	if (INODE_DELETED(inode)) {
-		LOG_TRACE_ARGS("Inode %lu was marked as deleted!", 
-			       inode->i_ino);
+		LOG_TRACE_ARGS("Inode %llu was marked as deleted!", 
+			       GET_INODE_FEOFF(inode));
 		status = -ENOENT;
 		goto leave;
 	}
@@ -1769,6 +1820,7 @@
 		goto leave;
 	}
 
+#if 0
 	disk_len = strlen(fe->filename);
 
 	status = -ENOENT;
@@ -1787,12 +1839,15 @@
 		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)) ||
 	    inode->i_uid != fe->uid ||
-	    inode->i_gid != fe->gid || inode->i_mode != fe->prot_bits){
+	    inode->i_gid != fe->gid || 
+	    inode->i_mode != fe->prot_bits ||
+	    inode->i_nlink != fe->link_cnt){
 
 		if (OCFS_I(inode)->alloc_size > (__s64)fe->alloc_size){
 			ocfs_extent_map_destroy (&OCFS_I(inode)->map);
@@ -1802,8 +1857,9 @@
 		LOG_TRACE_STR("Allocsize, filesize or seq no did not match");
 		OCFS_I(inode)->alloc_size = fe->alloc_size;
 		inode->i_size = fe->file_size;
+printk("verifyupdate: setting nlink from %d to %d for %llu\n", inode->i_nlink, fe->link_cnt, GET_INODE_FEOFF(inode));
+		inode->i_nlink = fe->link_cnt;
 		OCFS_I(inode)->chng_seq_num = DISK_LOCK_SEQNUM (fe);
-
 		inode->i_blocks = (inode->i_size + osb->sect_size) >> osb->sect_size_bits;
 		inode->i_uid = fe->uid;
 		inode->i_gid = fe->gid;
@@ -1821,8 +1877,6 @@
 
 		switch (fe->attribs) {
 		case OCFS_ATTRIB_DIRECTORY:
-			inode->i_size = OCFS_DEFAULT_DIR_NODE_SIZE;
-			inode->i_blocks = (inode->i_size + osb->sect_size) >> osb->sect_size_bits;
 			inode->i_mode |= S_IFDIR;
 			break;
 		case OCFS_ATTRIB_SYMLINK:

Modified: branches/new-dir-format/src/io.c
===================================================================
--- branches/new-dir-format/src/io.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/io.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -28,448 +28,7 @@
 
 #define OCFS_DEBUG_CONTEXT    OCFS_DEBUG_CONTEXT_IO
 
-static int ocfs_read_bhs_iarr (ocfs_super * osb, __u64 off, __u64 len, 
-				 struct buffer_head *bhs[], int flags, 
-				 struct inode *inodes[]);
-static int ocfs_write_bhs_iarr (ocfs_super * osb, struct buffer_head *bhs[], 
-				  int nr, int flags, struct inode *inodes[]);
 
-
-void ocfs_put_fileent_inode(int idx, struct inode **arr)
-{
-	switch (idx) {
-		case 0:
-		case 255:
-			break;
-		default:
-			/* release the ref from the get */
-			if (arr[idx]) {
-				struct inode *i = arr[idx];
-				if (i->i_state == I_CLEAR ||
-				    atomic_read(&i->i_count)==0) {
-					LOG_ERROR_ARGS("about to iput inode (%lu,%d,%s) one too many times!\n",
-						       i->i_ino, atomic_read(&i->i_count), 
-						       i->i_state == I_CLEAR ? "clear" : "not clear");
-					BUG();
-				}
-				iput(i);
-			}
-			break;
-	}
-}
-
-struct inode * ocfs_get_fileent_inode(ocfs_super *osb, int idx, struct buffer_head *bhs[], 
-					     struct inode *parent)
-{
-	unsigned long top = bhs[0]->b_blocknr;
-	struct inode *retval = NULL;
-
-	switch (idx) {
-		case 0:
-		case 255:
-			retval = parent;
-			break;
-		default:
-			/* this will iget() the inode if non-NULL */
-			retval = ocfs_inode_hash_lookup(osb, (top+idx) << 9);
-			break;
-	}
-	return retval;
-}
-
-/* caching for dirnodes is now straighforward */
-/* if there is an inode for a given offset, use its seqnum to determine caching */
-/* if there is no inode, then it is definitely a sync read (barring buffer_jbd) */
-
-int ocfs_write_dirnode(ocfs_super * osb, struct buffer_head *bhs[],
-		      struct inode *hdr_inode)
-{
-	int status, i;
-	struct inode **arr = NULL;
-	
-	LOG_ENTRY();
-
-	arr = (struct inode **) ocfs_malloc (256 * sizeof(struct inode *));
-	if (!arr) {
-		LOG_ERROR_STATUS(status = -ENOMEM);
-		goto bail;
-	}
-
-	for (i=0; i< 256; i++)
-		arr[i] = ocfs_get_fileent_inode(osb, i, bhs, hdr_inode);
-		
-	status = ocfs_write_bhs_iarr (osb, bhs, 256, 0, arr);
-	if (status < 0)
-		LOG_ERROR_STATUS(status);
-
-	for (i=0; i<256; i++)
-		ocfs_put_fileent_inode(i, arr);
-	ocfs_safefree(arr);
-
-bail:
-	LOG_EXIT_STATUS(status);	
-	return status;
-}
-
-int ocfs_read_dirnode(ocfs_super * osb, __u64 off, int sync, 
-		      struct buffer_head *bhs[], struct inode *hdr_inode)
-{
-	int status, i, max, total=1;
-	struct inode **arr = NULL;
-	ocfs_dir_node *dir;
-	unsigned long blk;
-
-	LOG_ENTRY();
-
-	if (sync) {
-		status = ocfs_read_bhs (osb, off, osb->vol_layout.dir_node_size,
-					bhs, 0, hdr_inode);
-		if (status < 0)
-			LOG_ERROR_STATUS(status);
-		goto bail;
-	}
-
-
-	status = ocfs_read_bh (osb, off, &bhs[0], OCFS_BH_CACHED, hdr_inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto bail;
-	}
-
-	dir = (ocfs_dir_node *) OCFS_BH_GET_DATA_READ(bhs[0]);
-	max = ocfs_get_max_dir_index(dir);
-	max++; // zero-indexed
-	OCFS_BH_PUT_DATA(bhs[0]);
-
-	if (max > 0) {
-		total = max+1;
-		arr = (struct inode **) ocfs_malloc (total * sizeof(struct inode *));
-		if (!arr) {
-			LOG_ERROR_STATUS(status = -ENOMEM);
-			goto bail;
-		}
-	
-		for (i=0; i<total; i++) {
-			arr[i] = ocfs_get_fileent_inode(osb, i, bhs, hdr_inode);
-		}
-	
-		/* read only as many blocks as maximum of dir index */
-		status = ocfs_read_bhs_iarr (osb, 
-					     off + 512ULL, 
-					     max << 9, 
-					     &bhs[1], 
-					     OCFS_BH_CACHED, 
-					     &arr[1]);
-		if (status < 0)
-			LOG_ERROR_STATUS(status);
-	
-		for (i=0; i<total; i++)
-			ocfs_put_fileent_inode(i, arr);
-	
-		ocfs_safefree(arr);
-	} else {
-		total = 1;
-	}
-	
-	/* fill in the remainder of the blocks not read from disk */
-	for (i=total, blk = ((unsigned long)(off >> 9) + total); i<256; i++, blk++) {
-		bhs[i] = getblk (OCFS_GET_BLOCKDEV(osb->sb), blk, 512);
-		if (!buffer_uptodate(bhs[i]) && !buffer_jbd(bhs[i]) 
-		    && !buffer_dirty(bhs[i]))
-			memset(bhs[i]->b_data, 'P', 512);
-	}
-bail:
-	LOG_EXIT_STATUS(status);
-	return status;
-}
-
-
-static int ocfs_write_bhs_iarr (ocfs_super * osb, struct buffer_head *bhs[], 
-				  int nr, int flags, struct inode *inodes[])
-{
-	int status = 0;
-	int i;
-	struct super_block *sb;
-	ocfs_blockdev dev;
-	struct buffer_head *bh;
-
-#ifdef OCFS_DBG_TIMING
-	my_timing_t begin, end; 
-#endif
-	
-	LOG_ENTRY_ARGS("(bh[0]->b_blocknr = %llu, nr=%d, flags=%u, inodes=%p)\n", 
-		       (unsigned long long)bhs[0]->b_blocknr, nr, flags, inodes);
-#ifdef OCFS_DBG_TIMING
-	rdtsc (begin.lohi[0], begin.lohi[1]);
-#endif
-
-	if (osb == NULL || osb->sb == NULL || bhs == NULL) {
-		LOG_TRACE_STR("osb == NULL || osb->sb == NULL || bhs == "
-		       "NULL");
-		status = -EINVAL;
-		LOG_ERROR_STATUS(status);
-		goto bail;
-	}
-
-	if (nr > 256)
-		LOG_TRACE_ARGS ("Getting write for %d blocks\n", nr);
-
-	sb = osb->sb;
-	dev = OCFS_GET_BLOCKDEV(sb);
-
-	/* we don't ever want cached writes -- those should go to the
-	 * journal so we can control when they actually hit disk and
-	 * so we can make sure they never get overwritten by a
-	 * subsequent read. */
-	if ((flags & OCFS_BH_CACHED) || (flags & OCFS_BH_COND_CACHED)) {
-		LOG_TRACE_STR("asking for a cached write!");
-		status = -EINVAL;
-		LOG_ERROR_STATUS(status);
-		goto bail;
-	}
-
-	for (i = 0 ; i < nr ; i++) {
-		bh = bhs[i];
-		if (bh == NULL) {
-			LOG_TRACE_STR("bh == NULL");
-			status = -EIO;
-			LOG_ERROR_STATUS(status);
-			goto bail;
-		}
-
-		check_rootdir_overwrite(bh);
-
-		if (check_block_zero_write(bh) < 0) {
-			status = -EIO;	
-			LOG_ERROR_STATUS(status);
-			goto bail;
-		}
-
-		if (flags & OCFS_BH_CONCURRENT_WRITE)
-			goto skip_modified_check;
-
-		/* Make sure the buffer is locked for modify, and
-		 * we're the ones with the write lock on this
-		 * buffer. */
-		if (!buffer_modified(bh)) {
-			printk("ocfs2: modified bit is NOT set on buffer "
-			       "(bh->b_blocknr = %llu)!\n",
-			       (unsigned long long)bh->b_blocknr);
-			BUG();
-		}
-		if (ocfs_bh_sem_lock_modify(bh) == OCFS_BH_SEM_WAIT_ON_MODIFY){
-			printk("ocfs2: someone else owns this buffer"
-			       "(bh->b_blocknr = %llu)!\n",
-			       (unsigned long long)bh->b_blocknr);
-			BUG();
-		}
-		ocfs_bh_sem_unlock(bh);
-
-skip_modified_check:
-		if (!(flags & OCFS_BH_IGNORE_JBD) && buffer_jbd(bh)) {
-#ifdef VERBOSE_BH_JBD_TRACE
-			LOG_TRACE_ARGS("trying to write a jbd managed bh "
-				       "(blocknr = %llu), nr=%d\n", 
-				       (unsigned long long)bh->b_blocknr, nr);
-#endif
-			continue;
-		}
-
-		lock_buffer(bh);
-		set_buffer_uptodate(bh);
-
-		/* remove from dirty list before I/O. */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)		
-		/*
-		 * mark_buffer_clean() doesn't exist in 2.6.x kernels.
-		 * Not many places actually used mark_buffer_clean, but
-		 * at least reiserfs uses clear_buffer_dirty() as
-		 * a replacment.
-		 */
-		clear_buffer_dirty(bh);
-#else
-		mark_buffer_clean(bh);
-#endif
-
-		bh->b_end_io = ocfs_end_buffer_io_sync;
-		submit_bh(WRITE, bh);
-	}
-
-	for (i = (nr-1) ; i >= 0; i--) {
-		bh = bhs[i];
-
-		wait_on_buffer(bh);
-
-		if (inodes[i])
-			SET_BH_SEQNUM(inodes[i], bh);
-		else
-			CLEAR_BH_SEQNUM(bh);
-
-		if (!(flags & OCFS_BH_CONCURRENT_WRITE))
-			ocfs_clear_buffer_modified(bh);
-	}
-	
-bail:
-
-#ifdef OCFS_DBG_TIMING
-	IO_FUNC_TIMING_PRINT("ocfs_write_bhs_iarr", status);
-#endif
-
-	LOG_EXIT_STATUS(status);
-	return status;
-}
-
-/*
- * ocfs_read_bhs_iarr()
- *
- */
-static int ocfs_read_bhs_iarr (ocfs_super * osb, __u64 off, __u64 len, 
-				 struct buffer_head *bhs[], int flags, 
-				 struct inode *inodes[])
-{
-	int status = 0;
-	struct super_block *sb;
-	int nr, i, ignore_cache = 0;
-	__u64 blocknum;
-	ocfs_blockdev dev;
-	struct buffer_head *bh;
-
-#ifdef OCFS_DBG_TIMING
-	my_timing_t begin, end; 
-#endif
-	LOG_ENTRY_ARGS("(off=(%llu), len=(%llu), flags=%d, inodes=%p)\n", off, 
-		       len, flags, inodes);
-#ifdef OCFS_DBG_TIMING
-	rdtsc (begin.lohi[0], begin.lohi[1]);
-#endif
-
-	if (len % 512) {
-		LOG_TRACE_ARGS("len %% 512 (len=%llu)\n", len);
-		status = -EINVAL;
-		LOG_ERROR_STATUS(status);
-		goto bail;
-	}
-
-	if (osb == NULL || osb->sb == NULL || bhs == NULL) {
-		LOG_TRACE_STR("osb == NULL || osb->sb == NULL || bhs == NULL "
-			      "|| num == NULL");
-		status = -EINVAL;
-		LOG_ERROR_STATUS(status);
-		goto bail;
-	}
-
-	if ((flags & OCFS_BH_COND_CACHED) && 
-	    (off >= osb->vol_layout.bitmap_off))
-			flags |= OCFS_BH_CACHED;
-
-	if (OCFS_NONCACHED(osb, off)) {
-		if (flags & OCFS_BH_CACHED)
-			LOG_TRACE_STR("hey bozo you are trying to write "
-				      "a system thingy cached!");
-		flags &= ~OCFS_BH_CACHED;
-	}
-
-	sb = osb->sb;
-	dev = OCFS_GET_BLOCKDEV(sb);
-	blocknum = off >> sb->s_blocksize_bits;
-
-	nr = (len + 511) >> 9;
-	if (nr == 0) {
-		LOG_TRACE_STR("No buffers will be read!!!");
-		LOG_TRACE_ARGS("Len=%llu Off=%llu numbuffers=%u "
-			       "blocknum=%llu\n", len, off, 
-			       nr, blocknum);
-		status = 0;
-		goto bail;
-	}
-
-	for (i = 0 ; i < nr ; i++) {
-		if (bhs[i] == NULL) {
-			bhs[i] = getblk (dev, blocknum++, sb->s_blocksize);
-			if (bhs[i] == NULL) {
-				LOG_TRACE_STR("bh == NULL");
-				status = -EIO;
-				LOG_ERROR_STATUS(status);
-				goto bail;
-			}
-		}
-		bh = bhs[i];
-		ignore_cache = 0;
-
-		/* Lock everyone else out of this bh */
-		OCFS_BH_GET_DATA_READ(bh);
-	
-		if (!inodes[i]) {
-			ignore_cache = 1;
-		} else if (flags & OCFS_BH_CACHED && !TEST_BH_SEQNUM(inodes[i], bh)) {
-#ifdef VERBOSE_BH_SEQNUM_TRACE
-			LOG_TRACE_ARGS("(read) bh (%llu) seqnum (%lu) does not "
-			       	"match inode (%u)\n",
-				(unsigned long long)bh->b_blocknr, 
-			       	(bh->b_state & STATE_BIT_MASK) >> 19,
-			       	atomic_read(GET_INODE_CLEAN_SEQ(inodes[i])));
-#endif
-			ignore_cache = 1;
-		}
-
-		if ((flags & OCFS_BH_CACHED) && (!buffer_uptodate(bh)))
-			ignore_cache = 1;
-
-		if (buffer_jbd(bh)) {
-#ifdef VERBOSE_BH_JBD_TRACE
-			if (!(flags & OCFS_BH_CACHED) || ignore_cache)
-				LOG_TRACE_ARGS("trying to sync read a jbd "
-					       "managed bh (blocknr = %llu)\n",
-					       (unsigned long long)bh->b_blocknr);
-#endif
-			continue;
-		}
-
-		if (!(flags & OCFS_BH_CACHED) || ignore_cache) {
-			if (buffer_dirty(bh)) {
-				/* This should probably be a BUG, or
-				 * at least return an error. */
-				LOG_TRACE_ARGS("asking me to sync read a "
-					      "dirty buffer! (blocknr = %llu)\n",
-					      (unsigned long long)bh->b_blocknr);
-				continue;
-			}
-
-			lock_buffer(bh);
-			clear_buffer_uptodate(bh);
-			bh->b_end_io = ocfs_end_buffer_io_sync;
-			submit_bh(READ, bh);
-			continue;
-		}
-	}
-
-	status = 0;
-
-	for (i = (nr-1); i >= 0; i--) {
-		bh = bhs[i];
-
-		wait_on_buffer(bh);
-
-		if (inodes[i])
-			SET_BH_SEQNUM(inodes[i], bh);
-		else
-			CLEAR_BH_SEQNUM(bh);
-
-		OCFS_BH_PUT_DATA(bh);
-	}
-	LOG_TRACE_ARGS("off=(%llu), len=(%llu), cached=%s\n", off, len, 
-		       (!(flags & OCFS_BH_CACHED) || ignore_cache) ? "no" : "yes");
-
-bail:
-
-#ifdef OCFS_DBG_TIMING
-	IO_FUNC_TIMING_PRINT("ocfs_read_bhs_iarr", status);
-#endif
-
-	LOG_EXIT_STATUS(status);
-	return status;
-}
-
 int ocfs_write_bhs (ocfs_super * osb, struct buffer_head *bhs[], 
 				  int nr, int flags, struct inode *inode)
 {
@@ -483,8 +42,8 @@
 	my_timing_t begin, end; 
 #endif
 	
-	LOG_ENTRY_ARGS("(bh[0]->b_blocknr = %llu, nr=%d, flags=%u, inode=%p)\n", 
-		       (unsigned long long)bhs[0]->b_blocknr, nr, flags, inode);
+	LOG_ENTRY_ARGS("(bh[0]->b_blocknr = %lu, nr=%d, flags=%u, inode=%p)\n", 
+		       bhs[0]->b_blocknr, nr, flags, inode);
 #ifdef OCFS_DBG_TIMING
 	rdtsc (begin.lohi[0], begin.lohi[1]);
 #endif
@@ -523,8 +82,6 @@
 			goto bail;
 		}
 
-		check_rootdir_overwrite(bh);
-
 		if (check_block_zero_write(bh) < 0) {
 			status = -EIO;	
 			LOG_ERROR_STATUS(status);
@@ -539,14 +96,12 @@
 		 * buffer. */
 		if (!buffer_modified(bh)) {
 			printk("ocfs2: modified bit is NOT set on buffer "
-			       "(bh->b_blocknr = %llu)!\n",
-			       (unsigned long long)bh->b_blocknr);
+			       "(bh->b_blocknr = %lu)!\n", bh->b_blocknr);
 			BUG();
 		}
 		if (ocfs_bh_sem_lock_modify(bh) == OCFS_BH_SEM_WAIT_ON_MODIFY){
 			printk("ocfs2: someone else owns this buffer"
-			       "(bh->b_blocknr = %llu)!\n",
-			       (unsigned long long)bh->b_blocknr);
+			       "(bh->b_blocknr = %lu)!\n", bh->b_blocknr);
 			BUG();
 		}
 		ocfs_bh_sem_unlock(bh);
@@ -555,8 +110,8 @@
 		if (!(flags & OCFS_BH_IGNORE_JBD) && buffer_jbd(bh)) {
 #ifdef VERBOSE_BH_JBD_TRACE
 			LOG_TRACE_ARGS("trying to write a jbd managed bh "
-				       "(blocknr = %llu), nr=%d\n", 
-				       (unsigned long long)bh->b_blocknr, nr);
+				       "(blocknr = %lu), nr=%d\n", 
+				       bh->b_blocknr, nr);
 #endif
 			continue;
 		}
@@ -689,9 +244,8 @@
 		if (flags & OCFS_BH_CACHED && inode && 
 		    !TEST_BH_SEQNUM(inode, bh)) {
 #ifdef VERBOSE_BH_SEQNUM_TRACE
-			LOG_TRACE_ARGS("(read) bh (%llu) seqnum (%lu) does not "
-				       "match inode (%u)\n",
-				       (unsigned long long)bh->b_blocknr, 
+			LOG_TRACE_ARGS("(read) bh (%lu) seqnum (%lu) does not "
+				       "match inode (%u)\n", bh->b_blocknr, 
 				       (bh->b_state & STATE_BIT_MASK) >> 19,
 				       atomic_read(GET_INODE_CLEAN_SEQ(inode)));
 #endif
@@ -705,8 +259,8 @@
 #ifdef VERBOSE_BH_JBD_TRACE
 			if (!(flags & OCFS_BH_CACHED) || ignore_cache)
 				LOG_TRACE_ARGS("trying to sync read a jbd "
-					       "managed bh (blocknr = %llu)\n",
-					       (unsigned long long)bh->b_blocknr);
+					       "managed bh (blocknr = %lu)\n",
+					       bh->b_blocknr);
 #endif
 			continue;
 		}
@@ -716,15 +270,18 @@
 				/* This should probably be a BUG, or
 				 * at least return an error. */
 				LOG_TRACE_ARGS("asking me to sync read a "
-					      "dirty buffer! (blocknr = %llu)\n",
-					      (unsigned long long)bh->b_blocknr);
+					      "dirty buffer! (blocknr = %lu)\n",
+					      bh->b_blocknr);
 				continue;
 			}
 
 			lock_buffer(bh);
 			clear_buffer_uptodate(bh);
 			bh->b_end_io = ocfs_end_buffer_io_sync;
-			submit_bh(READ, bh);
+			if (flags & OCFS_BH_READAHEAD)
+				submit_bh(READA, bh);
+			else
+				submit_bh(READ, bh);
 			continue;
 		}
 	}

Modified: branches/new-dir-format/src/journal.c
===================================================================
--- branches/new-dir-format/src/journal.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/journal.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -365,9 +365,6 @@
 	else
 		kern_handle->h_sync = 0;
 
-	for(i = 0; i < handle->num_buffs; i++)
-		check_rootdir_overwrite(handle->buffs[i]);
-
 	/* actually stop the transaction. if we've set h_sync,
 	 * it'll have been commited when we return */
 	retval = journal_stop(kern_handle);
@@ -536,9 +533,9 @@
 			CLEAR_BH_SEQNUM(bh);
 
 			if (buffer_jbd(bh))
-				LOG_ERROR_ARGS("Buffer %llu has JBD bit set "
+				LOG_ERROR_ARGS("Buffer %lu has JBD bit set "
 					       "after a journal_forget!\n",
-					       (unsigned long long)bh->b_blocknr);
+					       bh->b_blocknr);
 
 			lock_buffer(bh);
 			clear_buffer_uptodate(bh);
@@ -638,9 +635,9 @@
 	int i;
 	int found = 0;
 
-	LOG_ENTRY_ARGS("(bh->b_blocknr=%llu, type=%d (\"%s\"), "
+	LOG_ENTRY_ARGS("(bh->b_blocknr=%lu, type=%d (\"%s\"), "
 		       "bh->b_size = %hu)\n", 
-		       (unsigned long long)bh->b_blocknr, type, 
+		       bh->b_blocknr, type, 
 		       (type == OCFS_JOURNAL_ACCESS_CREATE) ? 
 		       "OCFS_JOURNAL_ACCESS_CREATE" : 
 		       "OCFS_JOURNAL_ACCESS_WRITE", bh->b_size);
@@ -648,8 +645,7 @@
 	/* we can safely remove this assertion after testing. */
 	if (!buffer_uptodate(bh)) {
 		printk("ocfs2: giving me a buffer that's not uptodate!\n");
-		printk("ocfs2: b_blocknr=%llu\n",
-		       (unsigned long long)bh->b_blocknr);
+		printk("ocfs2: b_blocknr=%lu\n", bh->b_blocknr);
 		BUG();
 	}
 	/* by taking a "read" lock, we prevent anyone from doing any
@@ -684,15 +680,13 @@
 		 *
 		 * Otherwise, we make a copy of the data in the buffer. */
 		if (!buffer_jbd(bh) && type == OCFS_JOURNAL_ACCESS_CREATE) {
-			LOG_TRACE_ARGS("Making block (%llu) a forget block at "
-				       "position %d\n",
-				       (unsigned long long)bh->b_blocknr, i);
+			LOG_TRACE_ARGS("Making block (%lu) a forget block at "
+				       "position %d\n", bh->b_blocknr, i);
 			handle->co_buffs[i].data = NULL;
 			handle->co_buffs[i].forget = 1;
 		} else {
-			LOG_TRACE_ARGS("Copying block (%llu) out to position"
-				       "%d\n",
-				       (unsigned long long)bh->b_blocknr, i);
+			LOG_TRACE_ARGS("Copying block (%lu) out to position"
+				       "%d\n", 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) {
@@ -743,8 +737,7 @@
 	int status = -1;
 	int i;
 
-	LOG_ENTRY_ARGS("(bh->b_blocknr=%llu)\n",
-		       (unsigned long long)bh->b_blocknr);
+	LOG_ENTRY_ARGS("(bh->b_blocknr=%lu)\n", bh->b_blocknr);
 
 	if (handle->num_buffs >= handle->max_buffs) {
 		LOG_ERROR_STR("Cannot add buffer to full transaction!");
@@ -757,9 +750,8 @@
 	 */
 	for(i = 0; i < handle->num_buffs; i++) {
 		if (handle->buffs[i] == bh) {
-			LOG_TRACE_ARGS("block (%llu) already added to dirty "
-				       "list!\n",
-				       (unsigned long long)bh->b_blocknr);
+			LOG_TRACE_ARGS("block (%lu) already added to dirty "  \
+				       "list!\n", bh->b_blocknr);
 			goto call_jbd;
 		}
 	}
@@ -778,8 +770,7 @@
 	status = journal_dirty_metadata(handle->k_handle, bh);
 	if (status < 0) {
 		LOG_ERROR_ARGS("Could not dirty metadata buffer. "
-			       "(bh->b_blocknr=%llu)\n",
-			       (unsigned long long)bh->b_blocknr);
+			       "(bh->b_blocknr=%lu)\n", bh->b_blocknr);
 		LOG_TRACE_ARGS("Setting handle->buffs[%d] = NULL\n", i);
 		brelse(bh);
 		handle->buffs[i] = NULL;
@@ -787,8 +778,6 @@
 		goto done;
 	}
 
-	check_rootdir_overwrite(bh);
-
 	status = 0;
 done:
 	LOG_EXIT_STATUS(status);
@@ -804,8 +793,7 @@
 {
 	ocfs_journal_lock *lock;
 
-	LOG_ENTRY_ARGS("(id=%llu, type=%u, flags=%u, bh=%p)\n",
-		       (unsigned long long)bh->b_blocknr, type, flags, bh);
+	LOG_ENTRY_ARGS("(id=%lu, type=%u, flags=%u, bh=%p)\n", bh->b_blocknr, type, flags, bh);
 
 	lock = ocfs_malloc(sizeof(ocfs_journal_lock));
 	if (lock == NULL) {

Modified: branches/new-dir-format/src/lockres.c
===================================================================
--- branches/new-dir-format/src/lockres.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/lockres.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -49,7 +49,7 @@
 	struct buffer_head *tmpbh = NULL, **b = NULL;
 	ocfs_file_entry *fe;
 	int flags;
-	ocfs_lock_res *lockres = GET_INODE_LOCKRES(inode);
+	ocfs_lock_res *lockres = GET_INODE_LOCKRES(inode);;
 
 	LOG_ENTRY_ARGS ("(0x%p, %llu, 0x%p, 0x%p, 0x%p)\n", osb,
 			lock_id, lockres, bh, updated);

Modified: branches/new-dir-format/src/namei.c
===================================================================
--- branches/new-dir-format/src/namei.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/namei.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -30,9 +30,16 @@
 
 extern spinlock_t oin_num_ext_lock;
 
-static int ocfs_fe_smash (ocfs_super * osb, __u32 flags, ocfs_journal_handle *passed_handle, struct dentry *dentry, struct inode *parent_inode);
-static int ocfs_rename_file (ocfs_super * osb, ocfs_journal_handle *handle, 
-struct dentry *dentry, __u64 file_off, struct inode *dir_inode);
+static int inline search_dirblock(struct buffer_head * bh, struct inode *dir, struct dentry *dentry, unsigned long offset, struct ocfs2_dir_entry ** res_dir);
+static int ocfs_delete_entry (ocfs_journal_handle *handle, struct inode * dir, struct ocfs2_dir_entry * de_del, struct buffer_head * bh);
+static int ocfs_add_entry (ocfs_journal_handle *handle, struct dentry *dentry, struct inode *inode, __u64 inode_off);
+static inline int ocfs_match (int len, const char * const name, struct ocfs2_dir_entry * de);
+
+
+
+
+static int ocfs_mknod_locked(ocfs_super *osb, struct inode *dir, struct dentry *dentry, int mode, ocfs_dev dev, struct buffer_head **new_fe_bh, ocfs_journal_handle *handle, struct inode *inode);
+
 static int ocfs_mknod_locked(ocfs_super *osb, struct inode *dir, 
 			     struct dentry *dentry, int mode, 
 			     ocfs_dev dev,
@@ -46,10 +53,6 @@
 			    __u64 id2, __u32 type2, __u32 flags2, 
 			    struct buffer_head **bh2,
 		     	    struct inode *inode2);
-static int ocfs_fix_extent_pointers(ocfs_super *osb, 
-				    ocfs_journal_handle *handle,
-				    struct buffer_head *fe_bh,
-				    struct inode *inode);
 
 static struct dentry_operations ocfs_dentry_ops = {
 	.d_revalidate = ocfs_dentry_revalidate	// let's test it out!
@@ -67,11 +70,12 @@
 {
 	int status;
 	ocfs_file_entry *fe = NULL;
-	struct buffer_head *fe_bh = NULL;
+	struct buffer_head *fe_bh = NULL, *dirent_bh = NULL;
 	struct inode *inode = NULL;
 	struct super_block *sb = dir->i_sb;
 	struct dentry *ret;
 	ocfs_super *osb = OCFS_SB(sb);
+	struct ocfs2_dir_entry *dirent = NULL;
 
 	LOG_ENTRY_ARGS ("(0x%p, 0x%p, '%*s')\n", dir, dentry,
 			dentry->d_name.len, dentry->d_name.name);
@@ -85,8 +89,8 @@
 	LOG_TRACE_ARGS("about to call find_files_on_disk with inode=%p\n", 
 		       dir);
 
-	status = ocfs_find_files_on_disk (osb, &(dentry->d_name), 
-					  &fe_bh, NULL, dir, 1);
+	inode = NULL;  // no inode yet 
+	status = ocfs_find_files_on_disk (osb, dentry, &fe_bh, dir, inode, 1, &dirent_bh, &dirent);
 	if (status < 0)
 		goto bail_add;
 	
@@ -114,6 +118,8 @@
 bail:
 	if (fe_bh)
 		brelse(fe_bh);
+	if (dirent_bh)
+		brelse(dirent_bh);
 	
 	LOG_EXIT_PTR (ret);
 	return ret;
@@ -124,8 +130,7 @@
 {
 	int status = 0;
 	struct buffer_head *parent_fe_bh = NULL;
-	__u64 parent_off;
-	__u64 file_off = 0;
+	__u64 parent_off, file_off;
 	ocfs_journal_handle *handle = NULL;
 	ocfs_super *osb;
 	ocfs_file_entry *fe = NULL;
@@ -194,12 +199,10 @@
 
 	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(new_fe_bh); /* read */
 
-	file_off = fe->this_sector;
-
 	ocfs_populate_inode (inode, fe, mode, 1);
 	insert_inode_hash (inode);
-	ocfs_inode_hash_bind(osb, GET_INODE_FEOFF(inode), inode);
 
+	file_off = fe->this_sector;
 	handle->new_file_lockid = fe->this_sector;
 	OCFS_BH_PUT_DATA(new_fe_bh);
 	fe = NULL;
@@ -209,6 +212,61 @@
 	status = ocfs_update_lockres (osb, GET_INODE_FEOFF(inode), 
 				      &new_fe_bh, NULL, 0, inode, 0, 0);
 
+	if (S_ISDIR (mode)) {
+		struct buffer_head *newdirbh = NULL;
+		int retval = 0;
+		struct ocfs2_dir_entry *de = NULL;
+
+		newdirbh = ocfs_bread (handle, inode, 0, 1, &retval, 0);
+		if (!newdirbh) {
+			LOG_ERROR_STATUS(status = retval);
+			goto leave;
+		}
+		status = ocfs_journal_access(handle, newdirbh, OCFS_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			brelse(newdirbh);
+			LOG_ERROR_STATUS(status);
+			goto leave;
+		}
+		de = (struct ocfs2_dir_entry *) OCFS_BH_GET_DATA_WRITE(newdirbh); /* write */
+		de->inode = cpu_to_le64(file_off);
+		de->name_len = 1;
+		de->rec_len = cpu_to_le16(OCFS_DIR_REC_LEN(de->name_len));
+		strcpy (de->name, ".");
+		ocfs_set_de_type(dir->i_sb, de, S_IFDIR);
+		de = (struct ocfs2_dir_entry *) ((char *) de + le16_to_cpu(de->rec_len));
+		de->inode = cpu_to_le64(parent_off);
+		de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize-OCFS_DIR_REC_LEN(1));
+		de->name_len = 2;
+		strcpy (de->name, "..");
+		ocfs_set_de_type(dir->i_sb, de, S_IFDIR);
+		inode->i_nlink = 2;
+		OCFS_BH_PUT_DATA(newdirbh);
+		status = ocfs_journal_dirty(handle, newdirbh);
+		brelse (newdirbh);
+		if (status < 0) {
+			LOG_ERROR_STATUS(status);
+			goto leave;
+		}
+		inode->i_size = inode->i_sb->s_blocksize;
+	
+		status = ocfs_journal_access(handle, parent_fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			LOG_ERROR_STATUS(status);
+			goto leave;
+		}
+		fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_WRITE(parent_fe_bh); /* write */
+		fe->link_cnt++;
+		OCFS_BH_PUT_DATA(parent_fe_bh);
+		fe = NULL;
+		status = ocfs_journal_dirty(handle, parent_fe_bh);
+		if (status < 0) {
+			LOG_ERROR_STATUS(status);
+			goto leave;
+		}
+		dir->i_nlink++;
+	}
+
 	d_instantiate (dentry, inode);
 	ocfs_commit_trans(handle);
 
@@ -249,29 +307,46 @@
  */
 static int ocfs_mknod_locked(ocfs_super *osb, struct inode *dir, 
 			     struct dentry *dentry, int mode, 
-			     ocfs_dev dev,
-			     struct buffer_head **new_fe_bh, 
+			     ocfs_dev dev, struct buffer_head **new_fe_bh, 
 			     ocfs_journal_handle *handle,
 			     struct inode *inode)
 {
 	int status = 0;
 	ocfs_file_entry *fe = NULL;
-	struct buffer_head *fe_bh = NULL;
-	int i;
-	unsigned long blk;
+	__u64 bitmapOffset = 0;
+	__u64 fileOffset = 0;
 
 	LOG_ENTRY_ARGS ("(0x%p, 0x%p, %d, %d, '%*s')\n", dir, dentry, mode,
 			dev, dentry->d_name.len, dentry->d_name.name);
 
-	if (new_fe_bh)
-		*new_fe_bh = NULL;
+	OCFS_ASSERT(new_fe_bh);
+	*new_fe_bh = NULL;
 
-	if ((fe = ocfs_allocate_file_entry ()) == NULL) {
-		LOG_ERROR_STATUS (status = -ENOMEM);
+	down(&osb->node_alloc_sem);
+	status = ocfs_alloc_node_block (osb, osb->inode_size,
+					&bitmapOffset, &fileOffset, osb->node_num, 
+					DISK_ALLOC_INODE, handle);
+	up(&osb->node_alloc_sem);
+	if (status < 0) {
+		LOG_ERROR_STATUS (status);
 		goto leave;
 	}
+		
+	status = ocfs_read_bh(osb, bitmapOffset, new_fe_bh,
+				      OCFS_BH_CACHED, inode);
 
-	memset (fe, 0, sizeof (ocfs_file_entry));
+	status = ocfs_journal_access(handle, *new_fe_bh, OCFS_JOURNAL_ACCESS_CREATE);
+	if (status < 0) {
+		LOG_ERROR_STATUS (status);
+		goto leave;
+	}
+
+	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_WRITE(*new_fe_bh); /* write */
+	memset (fe, 0, osb->sect_size);
+	inode->i_ino = ino_from_off(osb->sb, bitmapOffset);
+	fe->this_sector = bitmapOffset;
+	fe->alloc_file_off = fileOffset;
+	fe->alloc_node = osb->node_num;
 	fe->uid = current->fsuid;
 	fe->gid = current->fsgid;
 	fe->prot_bits = mode & 0007777;
@@ -283,9 +358,8 @@
 		fe->dev_minor = MINOR (dir->i_sb->s_dev);
 	}
 
-	if (S_ISLNK (mode) || S_ISDIR (mode) || S_ISREG (mode)) {
+	if (S_ISLNK (mode) || S_ISDIR (mode) || S_ISREG (mode)) 
 		atomic_set(GET_INODE_CLEAN_SEQ(inode), atomic_read(&osb->clean_buffer_seq));
-	}
 
 	if (S_ISLNK (mode))
 		fe->attribs |= OCFS_ATTRIB_SYMLINK;
@@ -302,9 +376,11 @@
 	else
 		fe->attribs |= OCFS_ATTRIB_REG;
 
-	strncpy (fe->filename, dentry->d_name.name, dentry->d_name.len); 
-	fe->filename[dentry->d_name.len]='\0';
-	fe->filename_len = dentry->d_name.len;
+	if (S_ISDIR (mode))
+		fe->link_cnt = 2;
+	else
+		fe->link_cnt = 1;
+
 	fe->local_ext = 1;
 	fe->granularity = -1;
 	fe->next_free_ext = 0;
@@ -318,103 +394,34 @@
 	DISK_LOCK_READER_NODE (fe) = osb->node_num;
 	DISK_LOCK_WRITER_NODE (fe) = osb->node_num;
 	DISK_LOCK_OIN_MAP(fe) = (1 << osb->node_num);
-
 	fe->create_time = fe->modify_time = OCFS_CURRENT_TIME;
+	fe->dir_node_ptr = GET_INODE_FEOFF(dir);
+	OCFS_BH_PUT_DATA(*new_fe_bh);
+	fe = NULL;
 
-	if (S_ISDIR (mode)) {
-		__u64 bitmapOffset;
-		__u64 fileOffset = 0;
-		ocfs_dir_node *new_dir = NULL;
-		struct buffer_head **dirbhs = NULL;
-		int numblks;
-		int bufsize;
-		void *tmp;
-
-		numblks = osb->vol_layout.dir_node_size >> osb->sect_size_bits;
-		bufsize = numblks * sizeof(struct buffer_head *);
-		dirbhs  = ocfs_malloc(bufsize);
-		if (dirbhs == NULL) {
-			LOG_ERROR_STATUS (status = -ENOMEM);
-			goto leave;
-		}
-		memset(dirbhs, 0, bufsize);
-
-		/* allocate directory space and setup pointers */
-		down(&osb->node_alloc_sem);
-		status = ocfs_alloc_node_block (osb, osb->vol_layout.dir_node_size, &bitmapOffset, &fileOffset, osb->node_num, DISK_ALLOC_DIR_NODE, handle);
-		up(&osb->node_alloc_sem);
-		if (status < 0) {
-			ocfs_safefree (dirbhs);
-//			OCFS_BH_PUT_DATA(lock_bh);
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-
-		fe->alloc_size = osb->vol_layout.dir_node_size;
-		fe->u.child_dirnode = bitmapOffset;
-		fe->file_size = osb->vol_layout.dir_node_size;
-		fe->next_del = INVALID_DIR_NODE_INDEX;
-		
-		blk = (unsigned long)(bitmapOffset >> osb->sect_size_bits);
-		for (i = 0; i < numblks; i++) {
-			dirbhs[i] = getblk (OCFS_GET_BLOCKDEV(osb->sb), 
-					    blk++, osb->sb->s_blocksize);
-
-			set_buffer_uptodate(dirbhs[i]);
-			status = ocfs_journal_access(handle, dirbhs[i], 
-					     OCFS_JOURNAL_ACCESS_CREATE);
-			if (status < 0) {
-				while (i >= 0)
-					brelse(dirbhs[i--]);
-				ocfs_safefree(dirbhs);
-				LOG_ERROR_STATUS(status);
-				goto leave;
-			}
-			tmp = OCFS_BH_GET_DATA_WRITE(dirbhs[i]); /* write */
-			memset(tmp, 0, osb->sect_size);
-			OCFS_BH_PUT_DATA(dirbhs[i]);
-			status = ocfs_journal_dirty(handle, dirbhs[i]);
-			if (status < 0) {
-				while (i >= 0)
-					brelse(dirbhs[i--]);
-				ocfs_safefree(dirbhs);
-				LOG_ERROR_STATUS(status);
-				goto leave;
-			}
-
-		}
-
-		new_dir = (ocfs_dir_node *) OCFS_BH_GET_DATA_WRITE(dirbhs[0]); /* write */
-		ocfs_initialize_dir_node (osb, new_dir, bitmapOffset, 
-					  fileOffset, osb->node_num);
-
-		DISK_LOCK_CURRENT_MASTER (new_dir) = osb->node_num;
-		DISK_LOCK_FILE_LOCK (new_dir) = OCFS_DLM_ENABLE_CACHE_LOCK;
-		new_dir->dir_node_flags |= DIR_NODE_FLAG_ROOT;
-
-		OCFS_BH_PUT_DATA(dirbhs[0]);
-		new_dir = NULL;
-
-		/* cleanup after ourselves */
-		for(i=0; i < numblks; i++)
-			brelse(dirbhs[i]);
-
-		ocfs_safefree (dirbhs);
+	status = ocfs_journal_dirty(handle, *new_fe_bh);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto leave;
 	}
 
-	status = ocfs_insert_file (osb, fe, &fe_bh, handle, dir, inode);
+	status = ocfs_add_entry (handle, dentry, inode, bitmapOffset);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
 		goto leave;
 	}
 
-	if (new_fe_bh)
-		*new_fe_bh = fe_bh;
-
-	SET_BH_SEQNUM(inode, fe_bh);
+	SET_BH_SEQNUM(inode, *new_fe_bh);
 leave:
-	ocfs_release_file_entry(fe);
-
+	if (fe) {
+		OCFS_BH_PUT_DATA(*new_fe_bh);
+		fe = NULL;
+	}
+	
+	if (status < 0 && *new_fe_bh) {
+		brelse(*new_fe_bh);
+		*new_fe_bh = NULL;
+	}
 	LOG_EXIT_STATUS (status);
 	return status;
 }				/* ocfs_mknod_locked */
@@ -475,92 +482,252 @@
  */
 int ocfs_unlink (struct inode *dir, struct dentry *dentry)
 {
-	int status;
-	struct inode *inode;
+	int status, tmpstat;
+	int got_parent = 0, got_file = 0;
+	struct inode *inode = dentry->d_inode;
 	int retval = -EBUSY;
-	ocfs_super *osb = NULL;
-	__u64 fileOff;
-	int do_release = 0;
+	ocfs_super *osb = OCFS_SB(dir->i_sb);
+	__u64 fileOff = GET_INODE_FEOFF(inode);
 	struct inode *parentInode = dentry->d_parent->d_inode;
+	ocfs_file_entry *fe = NULL;
+	__u32 lockFlags = (S_ISDIR (inode->i_mode) ? (FLAG_FILE_DELETE | FLAG_DIR) : FLAG_FILE_DELETE);
+	struct buffer_head *fe_bh = NULL;
+	struct buffer_head *parent_node_bh = NULL; /* parent locknode */
+	ocfs_journal_handle *handle = NULL;
+	__u64 parent_off = GET_INODE_FEOFF(parentInode);
+	__u64 parent_dirnode_off = OCFS_I(parentInode)->u.child_dirnode;
+	struct ocfs2_dir_entry *dirent = NULL;
+	struct buffer_head *dirent_bh = NULL;
+	int drop_inode = 0, dec_parent = 0;
 
+
 	LOG_ENTRY_ARGS ("(0x%p, 0x%p, '%*s')\n", dir, dentry,
 			dentry->d_name.len, dentry->d_name.name);
 
-	inode = dentry->d_inode;
-	osb = OCFS_SB(dir->i_sb);
+	LOG_TRACE_ARGS("ino = %llu\n", fileOff);
 
-	fileOff = GET_INODE_FEOFF(inode);
-	if (fileOff == -1)
-		BUG();
-
-	LOG_TRACE_ARGS("fileOff = %llu, ino = %lu\n", fileOff, inode->i_ino);
-
 	status = -EBUSY;
 
-	if (!ocfs_empty(dentry)) {
+	if (!empty_dir(inode)) {
 		LOG_TRACE_STR ("dentry is not empty, cannot delete");
+		goto bail;
 	} else if (OCFS_I(inode)->open_hndl_cnt > 0) {
 		LOG_TRACE_ARGS ("Cannot remove an open file (open_hndl_cnt = %u, fileOff = %llu, d_count=%u)\n", OCFS_I(inode)->open_hndl_cnt, fileOff, atomic_read(&dentry->d_count));
-	} else if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
+		goto bail;
+	} else if (inode == osb->root_inode) {
 		LOG_TRACE_STR ("Cannot delete the root directory");
 		status = -EPERM;
-	} else if (OCFS_I(inode)->oin_flags & OCFS_OIN_DELETE_ON_CLOSE) {
-		LOG_TRACE_STR ("OCFS_OIN_DELETE_ON_CLOSE set");
-		status = 0;
-		do_release = 1;
-	} else {
-		status = -EFAIL;
-		do_release = 1;
+		goto bail;
+	}
+	status = -EFAIL;
 
-		spin_lock(&oin_num_ext_lock);
-		if (OCFS_I(inode)->num_extends) {
-			LOG_ERROR_ARGS ("Cannot remove a file with = "
-					"%u, pending extends (fileOff "
-					"= %llu)\n", 
-					OCFS_I(inode)->num_extends,
-					fileOff);
-			spin_unlock(&oin_num_ext_lock);
-			status = -EBUSY;
-			goto bail;
-		}
+	spin_lock(&oin_num_ext_lock);
+	if (OCFS_I(inode)->num_extends) {
+		LOG_ERROR_ARGS ("Cannot remove a file with = "
+				"%u, pending extends (fileOff "
+				"= %llu)\n", 
+				OCFS_I(inode)->num_extends,
+				fileOff);
 		spin_unlock(&oin_num_ext_lock);
+		status = -EBUSY;
+		goto bail;
+	}
+	spin_unlock(&oin_num_ext_lock);
 
-		down (&(OCFS_I(inode)->priv_sem));
-		OCFS_SET_FLAG (OCFS_I(inode)->oin_flags, OCFS_OIN_DELETE_ON_CLOSE);
-		up (&(OCFS_I(inode)->priv_sem));
+	handle = ocfs_start_trans(osb, OCFS_FILE_DELETE_CREDITS);
+	if (handle == NULL) {
+		LOG_ERROR_STATUS (status = -ENOMEM);
+		goto leave;
+	}
 
-		status = ocfs_fe_smash (osb, 0, NULL, dentry, parentInode);
+	/* lock parent directory, yes we use FLAG_FILE_CREATE even
+	 * though we're deleting ;) */
+	status = ocfs_acquire_lock(osb, parent_off, OCFS_DLM_EXCLUSIVE_LOCK,
+				   FLAG_FILE_CREATE|FLAG_DIR, NULL, 
+				   parentInode);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto leave;
+	}
+	got_parent = 1;
 
+	/* this will re-read the directory now with the EXCLUSIVE */
+	/* lock already held; it will also return the fe_bh to us */
+	status = ocfs_find_files_on_disk (osb, dentry, &fe_bh, parentInode, 
+					  inode, 0, &dirent_bh, &dirent);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto leave;
+	}
+
+	status = ocfs_acquire_lock (osb, fileOff, OCFS_DLM_EXCLUSIVE_LOCK,
+			lockFlags, &fe_bh, inode);
+	if (status < 0) {
+		if (status != -EINTR)
+			LOG_ERROR_STATUS (status);
+		goto leave;
+	}
+	got_file = 1;
+	
+	if (S_ISDIR (inode->i_mode)) {
+	       	if (!empty_dir(inode)) {
+			status = -ENOTEMPTY;
+			goto leave;
+		} else if (inode->i_nlink != 2) {
+			status = -ENOTEMPTY;
+			goto leave;
+		}
+	}
+
+	status = ocfs_journal_access(handle, fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		LOG_ERROR_STATUS (status);
+		goto leave;
+	}
+
+	/* need to preserve locking order, so take a 'write' lock on
+	 * the dirnode sector first. it won't get passed to
+	 * journal_dirty until ocfs_remove_file so clean up the write
+	 * lock on errors before that */
+	status = ocfs_read_bh(osb, parent_dirnode_off, &parent_node_bh, 
+			      OCFS_BH_CACHED, parentInode);
+	if (status < 0) {
+		LOG_ERROR_STATUS (status);
+		goto leave;
+	}
+	OCFS_BH_GET_DATA_WRITE(parent_node_bh);
+	OCFS_BH_PUT_DATA(parent_node_bh);
+
+	/* we call ocfs_clear_buffer_modified in several error cases
+	 * here if we set the modify bit on this buffer, but haven't
+	 * journal_dirtied it yet. Otherwise, it'll stay modified even
+	 * after the abort_trans. */
+	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_WRITE(fe_bh); /* write */
+	if (S_ISDIR (inode->i_mode))
+		fe->link_cnt = 0;
+	else 
+		fe->link_cnt--;
+	if (!fe->link_cnt) {
+		drop_inode = 1;
+		OCFS_SET_FLAG (fe->sync_flags, OCFS_SYNC_FLAG_MARK_FOR_DELETION);
+		fe->sync_flags &= (~OCFS_SYNC_FLAG_VALID);
+	}
+	OCFS_BH_PUT_DATA(fe_bh);
+
+	if (drop_inode) {
+		/* Free up all the bits in the bitmap. */
+		/* mark all the extents (and extent metadata) for
+	 	* this file so we can remove them after commit. */
+		/* TODO: delay this.  see orphan comment below */
+		status = ocfs_free_file_extents (osb, fe_bh, handle, inode);
 		if (status < 0) {
-			if (status != -ENOTEMPTY && status != -EPERM &&
-		    	    status != -EBUSY && status != -EINTR)
+			ocfs_clear_buffer_modified(fe_bh);
+			ocfs_clear_buffer_modified(parent_node_bh);
+			LOG_ERROR_STATUS (status);
+			goto leave;
+		}
+	
+		/* delete the name from the parent dir */
+		status = ocfs_delete_entry (handle, parentInode, dirent, dirent_bh);
+		if (status < 0) {
+			LOG_ERROR_STATUS(status);
+			goto leave;
+		}
+		/* 
+	 	* TODO: we should link this entry into the local orphan dir after
+	 	* deleting the name from the parent.  do NOT do the free_file_extents
+	 	* in this function.  delay it until triggered by orphan_del (by 
+	 	* delete_inode, truncate or similar)
+	 	*/
+		if (S_ISDIR (inode->i_mode)) {
+			ocfs_file_entry *dirfe;
+			status = ocfs_journal_access(handle, parent_node_bh, 
+						     OCFS_JOURNAL_ACCESS_WRITE);
+			if (status < 0) {
 				LOG_ERROR_STATUS(status);
+				goto leave;
+			}
+			dirfe = (ocfs_file_entry *) OCFS_BH_GET_DATA_WRITE(parent_node_bh);
+			dirfe->link_cnt--;
+			OCFS_BH_PUT_DATA(parent_node_bh);
+			status = ocfs_journal_dirty(handle, fe_bh);
+			if (status < 0) {
+				LOG_ERROR_STATUS(status);
+				goto leave;
+			}
+			dec_parent=1;
+		}
+	}
 
-			down (&(OCFS_I(inode)->priv_sem));
-			OCFS_CLEAR_FLAG (OCFS_I(inode)->oin_flags, OCFS_OIN_DELETE_ON_CLOSE);
-			up (&(OCFS_I(inode)->priv_sem));
-			goto bail;
-		} 
+	status = ocfs_journal_dirty(handle, fe_bh);
+	if (status < 0)
+		LOG_ERROR_STATUS(status);
+
+leave:
+	if (handle) {
+		if (status < 0)
+			ocfs_abort_trans(handle);
+		else
+			ocfs_commit_trans(handle);
 	}
 
-	if (do_release)
-	{
-		inode->i_nlink--;
-		retval = 0;
+	/* need this to alert dentry-owners on other nodes */
+	/* Release the file lock if we acquired it */
+	if (got_file) {
+		tmpstat = ocfs_release_lock(osb, fileOff, 
+					    OCFS_DLM_EXCLUSIVE_LOCK, 
+					    lockFlags, fe_bh, inode);
+		if (tmpstat < 0)
+			LOG_ERROR_STATUS(tmpstat);
+
 	}
 
+	if (got_parent) {
+		tmpstat = ocfs_release_lock(osb, parent_off, 
+					    OCFS_DLM_EXCLUSIVE_LOCK,
+					    FLAG_FILE_CREATE|FLAG_DIR, 
+					    NULL, parentInode);
+		if (tmpstat < 0)
+			LOG_ERROR_STATUS(tmpstat);
+
+	}
+
+	if (status >= 0) {
+		// already checked to make sure dir has nlink==2
+		if (S_ISDIR (inode->i_mode))
+			inode->i_nlink = 0;
+		else
+			inode->i_nlink--;
+		if (dec_parent)
+			dir->i_nlink--;
+#warning is INODE_DELETED needed anymore?
+		if (drop_inode) 
+			SET_INODE_DELETED(inode);
+	}
 bail:
 	if (status < 0 && status != -ENOTEMPTY && 
-	    status != -EPERM && status != -EBUSY)
+	    status != -EPERM && status != -EBUSY && status != -EINTR) {
+		LOG_ERROR_STATUS(status);
 		retval = -EBUSY;
-	else
+	} else
 		retval = status;
 
+	if (fe_bh)
+		brelse(fe_bh);
+
+	if (dirent_bh)
+		brelse(dirent_bh);
+
+	if (parent_node_bh)
+		brelse(parent_node_bh);
+
+
 #ifndef BH_SEM_LEAK_CHECKING
 	if (retval < 0)
 #endif
 		ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
 
+
 	LOG_EXIT_INT (retval);
 	return retval;
 }				/* ocfs_unlink */
@@ -657,135 +824,11 @@
 	return(status);
 } /* ocfs_double_lock */
 
-/*
- * ocfs_fix_extent_pointers
- *
- * If you move a file entry from one directory to another, the files
- * offset changes (obviously). This function updates all the
- * up_hdr_node_ptr's on any extents hanging off that file entry.
- */
-static int ocfs_fix_extent_pointers(ocfs_super *osb, 
-				    ocfs_journal_handle *handle,
-				    struct buffer_head *fe_bh,
-				    struct inode *inode)
-{
-	int status = 0;
-	ocfs_file_entry *fe = NULL;
-	__u64 new_ptr;
-	struct buffer_head *extent_bh = NULL;
-	ocfs_extent_group *extent = NULL;
-	int i;
 
-	LOG_ENTRY();
 
-	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh);
-
-	if (!IS_VALID_FILE_ENTRY(fe)) {
-		LOG_ERROR_STATUS(status = -EINVAL);
-		goto bail;
-	}
-
-	LOG_TRACE_ARGS("fe->this_sector = %llu, fe->local_ext = %s, "
-		       "fe->next_free_ext = %u\n",
-		       fe->this_sector, 
-		       (fe->local_ext) ? "true" : "false",
-		       fe->next_free_ext);
-
-	/* If we have local extents, then don't even worry about
-	 * this. Directories, by definition, always have local_ext
-	 * true, so we don't need a seperate check for them. */
-	if (fe->local_ext)
-		goto bail;
-
-
-	new_ptr = fe->this_sector;
-
-	for(i = 0; i < fe->next_free_ext; i++) {
-		status = ocfs_read_bh(osb, fe->extents[i].disk_off, &extent_bh,
-				      OCFS_BH_CACHED, inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS(status);
-			goto bail;
-		}
-
-		status = ocfs_journal_access(handle, extent_bh, 
-					     OCFS_JOURNAL_ACCESS_WRITE);
-		if (status < 0) {
-			LOG_ERROR_STATUS(status);
-			goto bail;
-		}
-
-		extent = (ocfs_extent_group *) OCFS_BH_GET_DATA_WRITE(extent_bh);
-		if ((!IS_VALID_EXTENT_HEADER(extent)) 
-		    && (!IS_VALID_EXTENT_DATA(extent))) {
-			LOG_ERROR_STATUS(status = -EINVAL);
-			OCFS_BH_PUT_DATA(extent_bh);
-			ocfs_clear_buffer_modified(extent_bh);
-			goto bail;
-		}
-
-		/* this next line does the real work of the function. */
-		extent->up_hdr_node_ptr = new_ptr;
-
-		OCFS_BH_PUT_DATA(extent_bh);
-		extent = NULL;
-
-		status = ocfs_journal_dirty(handle, extent_bh);
-		if (status < 0) {
-			LOG_ERROR_STATUS(status);
-			goto bail;
-		}
-
-		brelse(extent_bh);
-		extent_bh = NULL;
-	}
-bail:
-	if (fe)
-		OCFS_BH_PUT_DATA(fe_bh);
-
-	if (extent_bh) {
-		if (extent)
-			OCFS_BH_PUT_DATA(extent_bh);
-		brelse(extent_bh);
-	}
-	LOG_EXIT_STATUS(status);
-	return(status);
-}
-
-static int ocfs_ugly_rename_thingy(ocfs_super *osb, __u64 oldoff, __u64 newoff);
-
-static int ocfs_ugly_rename_thingy(ocfs_super *osb, __u64 oldoff, __u64 newoff)
-{
-	int status = 0;
-	ocfs_journal *journal = &osb->journal;
-	ocfs_journal_handle *handle=NULL;
-	ocfs_journal_lock *j_lock;
-	struct list_head *tmp1, *tmp2;
-
-	LOG_ENTRY();
-
-	/* and now for an ugly journal hack! */
-	down(&journal->commit_sem);
-	list_for_each(tmp1, &(journal->commited)) {
-		handle = list_entry(tmp1, ocfs_journal_handle, h_list);
-		
-		list_for_each(tmp2, &handle->locks) {
-			j_lock = list_entry(tmp2, ocfs_journal_lock, 
-					    lock_list);
-			if (j_lock->bh) {
-				brelse(j_lock->bh);
-				j_lock->bh = NULL;
-			}
-		}
-
-	}
-
-	up(&journal->commit_sem);
-
-	LOG_EXIT_STATUS(status);
-	return(status);
-}
-
+#define PARENT_INO(buffer) \
+	((struct ocfs2_dir_entry *) ((char *) buffer + \
+	le16_to_cpu(((struct ocfs2_dir_entry *) buffer)->rec_len)))->inode
 /*
  * ocfs_rename()
  *
@@ -802,21 +845,22 @@
 	ocfs_file_entry *tmpfe = NULL;
 	ocfs_super *osb = NULL;
 	__u64 oldOffset, newDirOff, oldDirOff;
-	__u64 tmpoff = 0;
-	int kill_newfe = 0;
-	int delete_target_oin = 0;
-	ocfs_bitmap_free_head *free_head = NULL;
+	__u64 newfe_lockid = 0;
 	ocfs_journal_handle *handle = NULL;
 	__u32 dir_lock_flags = FLAG_FILE_CREATE | FLAG_DIR;
 	struct buffer_head *old_dir_bh = NULL;
 	struct buffer_head *new_dir_bh = NULL;
 	__u32 oldfe_flags = 0;
-	__u32 oldfe_lockid = 0;
 	__u32 newfe_flags = 0;
-	__u32 newfe_lockid = 0;
-	int needs_trunc = 0;
+	int needs_trunc = 0, drop_inode = 0;
 	int got_oldlock = 0, got_newlock = 0;
-
+	struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry 
+							       // and new_dentry
+	struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above
+	struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
+						    // this is the 1st dirent bh
+	nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink;
+	
 	LOG_ENTRY_ARGS ("(0x%p, 0x%p, 0x%p, 0x%p, from='%*s' to='%*s')\n",
 			old_dir, old_dentry, new_dir, new_dentry,
 			old_dentry->d_name.len, old_dentry->d_name.name,
@@ -832,6 +876,7 @@
 
 	/* new parent dir offset */
 	newDirOff = GET_INODE_FEOFF(new_dir);
+	
 
 	if (new_inode) {
 		if (ocfs_inc_icount(new_inode) < 0)
@@ -847,7 +892,7 @@
 	}
 
 	if (new_inode && S_ISDIR (old_inode->i_mode) && 
-	    !ocfs_empty (new_dentry)) {
+	    !empty_dir (new_inode)) {
 		status = -ENOTEMPTY;
 		LOG_TRACE_STR ("New (directory) dentry NOT empty!");
 		goto bail;
@@ -869,16 +914,12 @@
 	/* Locking hierarchy will be broken */
 	
 	if (new_inode) {
-		if (!(OCFS_I(new_inode)->oin_flags & OCFS_OIN_DELETE_ON_CLOSE)) {
-			/* OIN exists and it's not marked for deletion! */
-			down (&(OCFS_I(new_inode)->priv_sem));
-			status = ocfs_verify_update_inode (osb, new_inode, 
-							   &needs_trunc, 0);
-			up (&(OCFS_I(new_inode)->priv_sem));
-			delete_target_oin = 1;
-			if (needs_trunc)
-				ocfs_truncate_inode_pages(new_inode, 0);
-		}
+		down (&(OCFS_I(new_inode)->priv_sem));
+		status = ocfs_verify_update_inode (osb, new_inode, 
+						   &needs_trunc, 0);
+		up (&(OCFS_I(new_inode)->priv_sem));
+		if (needs_trunc)
+			ocfs_truncate_inode_pages(new_inode, 0);
 	}
 
 	/* start our transaction */
@@ -909,14 +950,13 @@
 
 	if (S_ISDIR(old_inode->i_mode))
 		oldfe_flags = FLAG_DIR;
-	oldfe_lockid = GET_INODE_FEOFF(old_inode);
 
 	if (old_dir != new_dir)
 		oldfe_flags |= FLAG_FILE_DELETE;
 	else
 		oldfe_flags |= FLAG_FILE_RENAME;
 
-	status = ocfs_acquire_lock(osb, oldfe_lockid, OCFS_DLM_EXCLUSIVE_LOCK,
+	status = ocfs_acquire_lock(osb, oldOffset, OCFS_DLM_EXCLUSIVE_LOCK,
 				   oldfe_flags, NULL, old_inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
@@ -924,11 +964,38 @@
 	}
 	got_oldlock = 1;
 
+	if (S_ISDIR(old_inode->i_mode)) {
+		status = -EIO;
+		old_inode_de_bh = ocfs_bread (handle, old_inode, 0, 0, &status, 0);
+		if (!old_inode_de_bh)
+			goto finally;
+		if (le64_to_cpu(PARENT_INO(old_inode_de_bh->b_data)) != 
+		    GET_INODE_FEOFF(old_dir))
+			goto finally;
+		status = -EMLINK;
+		if (!new_inode && new_dir!=old_dir &&
+		    new_dir->i_nlink >= OCFS_LINK_MAX)
+			goto finally;
+	}
+	
+	status = -ENOENT;
+	old_de_bh = ocfs_find_entry (old_dentry, &old_de);
+	if (!old_de_bh)
+		goto finally;
+
+	/*
+	 *  Check for inode number is _not_ due to possible IO errors.
+	 *  We might rmdir the source, keep it as pwd of some process
+	 *  and merrily kill the link to whatever was created under the
+	 *  same name. Goodbye sticky bit ;-<
+	 */
+	if (le64_to_cpu(old_de->inode) != GET_INODE_FEOFF(old_inode))
+		goto finally;
+
 	/* check if the target already exists (in which case we need
 	 * to delete it */
-	status = ocfs_find_files_on_disk(osb, &(new_dentry->d_name),
-					 &newfe_bh, NULL, new_dir, 0);
-
+	status = ocfs_find_files_on_disk(osb, new_dentry, &newfe_bh, 
+					 new_dir, new_inode, 0, &new_de_bh, &new_de);
 	/* The only error we allow here is -ENOENT because the new
 	 * file not existing is perfectly valid. */
 	if ((status < 0) && (status != -ENOENT)) {
@@ -938,12 +1005,10 @@
 		goto finally;
 	} 
 
-	if (status == 0)
-		kill_newfe = 1;
-
 	/* In case we need to overwrite an existing file, we blow it
 	 * away first */
-	if (kill_newfe) {
+	if (new_de) {
+		/* TODO: change this block to the ext3-style orphan model */
 		newfe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(newfe_bh); /* read */
 		if (newfe->attribs & OCFS_ATTRIB_DIRECTORY)
 			newfe_flags = FLAG_DIR;
@@ -951,13 +1016,11 @@
 		newfe_lockid = newfe->this_sector;
 
 		OCFS_BH_PUT_DATA(newfe_bh);
-		brelse(newfe_bh);
-		newfe_bh = NULL;
 		newfe = NULL;
 
 		status = ocfs_acquire_lock(osb, newfe_lockid, 
 					   OCFS_DLM_EXCLUSIVE_LOCK, 
-					   newfe_flags, NULL, 
+					   newfe_flags, &newfe_bh, 
 					   new_inode);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
@@ -965,161 +1028,159 @@
 		}
 		got_newlock = 1;
 
-		status = ocfs_fe_smash (osb, 0, handle, new_dentry,
-					new_dir);
+		status = ocfs_journal_access(handle, newfe_bh, OCFS_JOURNAL_ACCESS_WRITE);
 		if (status < 0) {
 			LOG_ERROR_STATUS (status);
 			goto finally;
 		}
-	}
+	
+		/* need to preserve locking order, so take a 'write' lock on
+		 * the dirnode sector first. it won't get passed to
+		 * journal_dirty until ocfs_remove_file so clean up the write
+		 * lock on errors before that */
+		OCFS_BH_GET_DATA_WRITE(new_dir_bh);
+		OCFS_BH_PUT_DATA(new_dir_bh);
 
-
-	/* If we're moving to a different directory, all we've gotta
-	 * do is copy the fe information from the old directory to the
-	 * new one. */
-	if (old_dir != new_dir) {
-		/* Delete the file Entry only on the source directory */
-		LOG_TRACE_STR ("Source & Target Directories are different");
-
-		status = ocfs_fe_smash (osb, FLAG_DEL_NAME | FLAG_DEL_INODE, 
-					handle, old_dentry, old_dir);
-		if (status < 0) {
-			if (status != -ENOTEMPTY && status != -EINTR && 
-			    status != -EBUSY)
-				LOG_ERROR_STATUS (status);
+		/* we call ocfs_clear_buffer_modified in several error cases
+		 * here if we set the modify bit on this buffer, but haven't
+		 * journal_dirtied it yet. Otherwise, it'll stay modified even
+		 * after the abort_trans. */
+		newfe = (ocfs_file_entry *) OCFS_BH_GET_DATA_WRITE(newfe_bh); /* write */
+		if (S_ISDIR (new_inode->i_mode) && !empty_dir(new_inode)) {
+			status = -ENOTEMPTY;
+			OCFS_BH_PUT_DATA(newfe_bh);
+			ocfs_clear_buffer_modified(new_dir_bh);
 			goto finally;
 		}
 
-		/* we copy this all into a temporary fe because we
-		 * don't want to modify the old on as it points to
-		 * buffer head data which might get pushed to disk as
-		 * a part of a journal operation. */
-		tmpfe = ocfs_allocate_file_entry ();
-		if (tmpfe == NULL) {
-			LOG_ERROR_STATUS (status = -ENOMEM);
-			goto finally;
+		if (S_ISDIR (new_inode->i_mode))
+			newfe->link_cnt = 0;
+		else
+			newfe->link_cnt--;
+		if (!newfe->link_cnt) {
+			OCFS_SET_FLAG (newfe->sync_flags, OCFS_SYNC_FLAG_MARK_FOR_DELETION);
+			newfe->sync_flags &= (~OCFS_SYNC_FLAG_VALID);
+			drop_inode = 1;
 		}
+		OCFS_BH_PUT_DATA(newfe_bh);
 
-		status = ocfs_read_bh(osb, oldOffset, &oldfe_bh, 
-				      OCFS_BH_CACHED, old_inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS(status);
-			goto finally;
+		if (drop_inode) {	
+			/* Free up all the bits in the bitmap. */
+			/* mark all the extents (and extent metadata) for
+		 	* this file so we can remove them after commit. */
+			/* TODO: delay this.  see orphan comment below */
+			status = ocfs_free_file_extents (osb, newfe_bh, handle, new_inode);
+			if (status < 0) {
+				ocfs_clear_buffer_modified(newfe_bh);
+				ocfs_clear_buffer_modified(new_dir_bh);
+				LOG_ERROR_STATUS (status);
+				goto finally;
+			}
+	
+			/* 
+	 		* TODO: we should link this entry into the local orphan dir after
+	 		* deleting the name from the parent.  do NOT do the free_file_extents
+	 		* in this function.  delay it until triggered by orphan_del (by 
+	 		* delete_inode, truncate or similar)
+	 		*/
+			status = ocfs_journal_dirty(handle, newfe_bh);
+			if (status < 0) {
+				LOG_ERROR_STATUS (status);
+				goto finally;
+			}
 		}
 
-		oldfe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(oldfe_bh); /* read */
-		memcpy(tmpfe, oldfe, sizeof(ocfs_file_entry));
-		OCFS_BH_PUT_DATA(oldfe_bh);
-		oldfe = NULL;
-
-		tmpfe->sync_flags &= ~OCFS_SYNC_FLAG_VALID;
-		strncpy(tmpfe->filename, new_dentry->d_name.name, 
-			new_dentry->d_name.len);
-		tmpfe->filename[new_dentry->d_name.len] = '\0';
-		tmpfe->filename_len = new_dentry->d_name.len;
-		DISK_LOCK_CURRENT_MASTER (tmpfe) = osb->node_num;
-		DISK_LOCK_FILE_LOCK (tmpfe) = OCFS_DLM_ENABLE_CACHE_LOCK;
-		DISK_LOCK_READER_NODE (tmpfe) = osb->node_num;
-		DISK_LOCK_WRITER_NODE (tmpfe) = osb->node_num;
-		DISK_LOCK_OIN_MAP(tmpfe) = (1 << osb->node_num);
-		tmpfe->modify_time = OCFS_CURRENT_TIME;
-
-		tmpoff = tmpfe->this_sector;
-
-		down(&old_inode->i_sem);
-		/* we take oin->priv_sem because we want to lock out
-		 * verify_update_oin, which reads fe_off from the
-		 * inode, but doesn't always have i_sem. */
-		down(&OCFS_I(old_inode)->priv_sem);
-
-		status = ocfs_insert_file(osb, tmpfe, &insert_bh, 
-					 handle, new_dir, old_inode);
+		/* change the dirent to point to the correct inode */
+		status = ocfs_journal_access(handle, new_de_bh, OCFS_JOURNAL_ACCESS_WRITE);
 		if (status < 0) {
-			up(&OCFS_I(old_inode)->priv_sem);
-			up(&old_inode->i_sem);
 			LOG_ERROR_STATUS (status);
 			goto finally;
 		}
-
-		status = ocfs_fix_extent_pointers(osb, handle, insert_bh,
-						  old_inode);
+		new_de->inode = le64_to_cpu(GET_INODE_FEOFF(old_inode));
+		new_de->file_type = old_de->file_type;
+		new_dir->i_version = ++event;
+		status = ocfs_journal_dirty(handle, new_de_bh);
 		if (status < 0) {
-			up(&OCFS_I(old_inode)->priv_sem);
-			up(&old_inode->i_sem);
-			LOG_ERROR_STATUS (status);
+			LOG_ERROR_STATUS(status);
 			goto finally;
 		}
-		LOG_TRACE_ARGS("(after) tmpfe->this_sector = %llu\n", 
-			       tmpfe->this_sector);
 
-		/* move the inode offset over to the new entry */
-		status = ocfs_ugly_rename_thingy(osb, 
-						  GET_INODE_FEOFF(old_inode), 
-						  tmpfe->this_sector);
-		if (status < 0) {
-			up(&OCFS_I(old_inode)->priv_sem);
-			up(&old_inode->i_sem);
-			LOG_ERROR_STATUS (status);
-			goto finally;
-		}
-
-		SET_INODE_FEOFF(old_inode, tmpfe->this_sector);
-		OCFS_I(old_inode)->u.fe_private = tmpfe->u.fe_private;
-		ocfs_inode_rehash(&osb->inode_hash, tmpoff, 
-				  tmpfe->this_sector);
-
-		up(&OCFS_I(old_inode)->priv_sem);
-		up(&old_inode->i_sem);
 	} else {
-		/* Ok, we're moving inside of the same directory --
-		 * this is easy then -- we just change the name on the
-		 * fe. */ 
-		/* Write the new file name to disk */
-		LOG_TRACE_STR ("Source & Target Directories are same");
-		status = ocfs_rename_file(osb, handle, new_dentry, oldOffset, 
-					  new_dir);
-		if (status < 0) 
-			LOG_ERROR_STATUS (status);
-	}
+		/* if the name was not found in new_dir, add it now */
+		status = ocfs_add_entry (handle, new_dentry, old_inode, oldOffset);
+	} 
+	
 
 finally:
 	if (status < 0) {
 		ocfs_abort_trans(handle);
 		goto bail;
-	} else {
-		/* commit_trans */
-		ocfs_commit_trans(handle);
+	}
 
-		/* free bits, if we deleted anything */
-		if (free_head) {
-			status = ocfs_process_bitmap_free_head(osb, free_head);
-			if (status < 0)
-				LOG_ERROR_STATUS(status);
-		}
+	old_inode->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(old_inode);
 
-		if (new_inode)
-			fsync_inode_buffers(old_inode);
+	/* now that the name has been added to new_dir, remove the old name */
+	status = ocfs_delete_entry(handle, old_dir, old_de, old_de_bh);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto finally;
 	}
 
-	old_inode->i_nlink++;
 	if (new_inode) {
-		new_dir->i_mtime = new_dir->i_ctime = CURRENT_TIME;
-		if (S_ISDIR (old_inode->i_mode))
+		new_inode->i_nlink--; 
+		new_inode->i_ctime = CURRENT_TIME;
+	}
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	if (old_inode_de_bh) {
+		status = ocfs_journal_access(handle, old_inode_de_bh, OCFS_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			LOG_ERROR_STATUS (status);
+			// BAD
+			goto bail;
+		}
+		PARENT_INO(old_inode_de_bh->b_data) = le64_to_cpu(GET_INODE_FEOFF(new_dir));
+		status = ocfs_journal_dirty(handle, old_inode_de_bh);
+		if (status < 0) {
+			LOG_ERROR_STATUS(status);
+			// BAD
+			goto bail;
+		}
+		old_dir->i_nlink--;
+		if (new_inode) {
 			new_inode->i_nlink--;
-		new_inode->i_nlink--;
-	} else {
-		if (S_ISDIR (old_inode->i_mode))
+		} else {
 			new_dir->i_nlink++;
+			mark_inode_dirty(new_dir);
+		}
 	}
-	old_inode->i_nlink--;
-	if (S_ISDIR (old_inode->i_mode)) {
-		new_dir->i_mtime = new_dir->i_ctime = CURRENT_TIME;
-		old_dir->i_nlink--;
+	mark_inode_dirty(old_dir);
+	if (new_inode) {
+		mark_inode_dirty(new_inode);
+		if (!new_inode->i_nlink)
+			ocfs_orphan_add(handle, new_inode);
 	}
 
+	if (old_dir != new_dir) {
+		if (new_dir_nlink != new_dir->i_nlink)
+			LOG_ERROR_ARGS("need to change nlink for new dir %llu from %d to %d\n",
+				       GET_INODE_FEOFF(new_dir), new_dir_nlink, new_dir->i_nlink);
+	}
+	if (old_dir_nlink != old_dir->i_nlink)
+		LOG_ERROR_ARGS("need to change nlink for old dir %llu from %d to %d\n",
+			       GET_INODE_FEOFF(old_dir), old_dir_nlink, old_dir->i_nlink);
+
+	/* commit_trans */
+	ocfs_commit_trans(handle);
+
+	if (new_inode)
+		fsync_inode_buffers(old_inode);
+
+	status = 0;
+
 bail:
 	if (got_oldlock) {
-		ocfs_release_lock(osb, oldfe_lockid, 
+		ocfs_release_lock(osb, oldOffset, 
 				  OCFS_DLM_EXCLUSIVE_LOCK, 
 				  oldfe_flags, NULL, old_inode);
 	}
@@ -1151,8 +1212,12 @@
 		brelse(old_dir_bh);
 	if (new_dir_bh)
 		brelse(new_dir_bh);
-	if (free_head)
-		ocfs_free_bitmap_free_head(free_head);
+	if (new_de_bh)
+		brelse(new_de_bh);
+	if (old_de_bh)
+		brelse(old_de_bh);
+	if (old_inode_de_bh)
+		brelse(old_inode_de_bh);
 
 #ifndef BH_SEM_LEAK_CHECKING
 	if (status < 0)
@@ -1269,7 +1334,6 @@
 	}
 
 	insert_inode_hash (inode);
-	ocfs_inode_hash_bind(osb, GET_INODE_FEOFF(inode), inode);
 	d_instantiate (dentry, inode);
 
 abort_trans:
@@ -1309,409 +1373,469 @@
 }				/* ocfs_symlink */
 
 
-/* ocfs_rename_file()
- *
- */
-static int ocfs_rename_file (ocfs_super * osb, ocfs_journal_handle *handle, struct dentry *dentry, __u64 file_off, struct inode *dir_inode)
+
+int ocfs_check_dir_entry (struct inode * dir, struct ocfs2_dir_entry * de, struct buffer_head * bh, unsigned long offset)
 {
-	int status = 0;
-	ocfs_dir_node *pLockNode = NULL;
-	ocfs_file_entry *fe = NULL;
-	__u32 index;
-	struct buffer_head *fe_bh = NULL, *dirbh = NULL;
-	int cache_lock = 0, needs_reindex = 0;
-	__u64 dir_node_ptr = 0;
-	int flags = 0;
-	struct qstr *file_name = &(dentry->d_name);
-	struct inode *inode = dentry->d_inode;
+	const char * error_msg = NULL;
+	const int rlen = le16_to_cpu(de->rec_len);
+	
+	if (rlen < OCFS_DIR_REC_LEN(1))
+		error_msg = "rec_len is smaller than minimal";
+	else if (rlen % 4 != 0)
+		error_msg = "rec_len % 4 != 0";
+	else if (rlen < OCFS_DIR_REC_LEN(de->name_len))
+		error_msg = "rec_len is too small for name_len";
+	else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
+		error_msg = "directory entry across blocks";
+	
+	if (error_msg != NULL)
+		LOG_ERROR_ARGS("bad entry in directory #%llu: %s - "
+			"offset=%lu, inode=%llu, rec_len=%d, name_len=%d",
+			GET_INODE_FEOFF(dir), error_msg, offset,
+			le64_to_cpu(de->inode),
+			rlen, de->name_len);
+	return error_msg == NULL ? 1 : 0;
+}
 
-	LOG_ENTRY ();
+static inline int ocfs_match (int len, const char * const name, struct ocfs2_dir_entry * de)
+{
+	if (len != de->name_len)
+		return 0;
+	if (!de->inode)
+		return 0;
+	return !memcmp(name, de->name, len);
+}
 
-	status = ocfs_read_bh (osb, file_off, &fe_bh, OCFS_BH_CACHED, inode);
-	if (status < 0) {
-		if (status != -EINTR)
-			LOG_ERROR_STATUS (status);
-		goto leave;
-	}
 
-	fe = (ocfs_file_entry *)OCFS_BH_GET_DATA_READ(fe_bh); /* read */
-	if (!IS_VALID_FILE_ENTRY(fe))
-		BUG();
-	dir_node_ptr = fe->dir_node_ptr;
-	OCFS_BH_PUT_DATA(fe_bh);
-	fe = NULL;
+static int ocfs_add_entry (ocfs_journal_handle *handle, struct dentry *dentry, struct inode *inode, __u64 inode_off)
+{
+	struct inode *dir = dentry->d_parent->d_inode;
+	const char *name = dentry->d_name.name;
+	int namelen = dentry->d_name.len;
+	unsigned long offset;
+	unsigned short rec_len;
+	struct buffer_head * bh;
+	struct ocfs2_dir_entry * de, * de1;
+	struct super_block * sb;
+	int retval, status;
+	char *buf = NULL;
 
-	status = ocfs_read_bh (osb, dir_node_ptr, &dirbh, OCFS_BH_CACHED, 
-			       inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto leave;
-	}
+	sb = dir->i_sb;
 
-	status = ocfs_journal_access(handle, dirbh, OCFS_JOURNAL_ACCESS_WRITE);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-	status = ocfs_journal_access(handle, fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
+	if (!namelen)
+		return -EINVAL;
+	bh = ocfs_bread (handle, dir, 0, 0, &retval, 0);
+	if (!bh)
+		return retval;
+	rec_len = OCFS_DIR_REC_LEN(namelen);
+	offset = 0;
+	de = (struct ocfs2_dir_entry *) bh->b_data;
+	while (1) {
+		if ((char *)de >= sb->s_blocksize + bh->b_data) {
+			brelse (bh);
+			bh = NULL;
+			bh = ocfs_bread (handle, dir, offset >> sb->s_blocksize_bits, 1, &retval, 0);
+			if (!bh)
+				return retval;
+			if (dir->i_size <= offset) {
+				if (dir->i_size == 0) {
+					brelse(bh);
+					return -ENOENT;
+				}
 
-	/* preserve bh lock ordering so grab the write on dirbh 1st. */
-	pLockNode = (ocfs_dir_node *)OCFS_BH_GET_DATA_WRITE(dirbh); /* write */
-	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_WRITE(fe_bh); /* write */
+				/* create next block */
+				status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
+				if (buf) {
+#warning removemelater
+					LOG_ERROR_ARGS("oops.  block=%lu\n", bh->b_blocknr);
+					BUG();
+				}
+				buf = OCFS_BH_GET_DATA_WRITE(bh); /* write */
+				de = (struct ocfs2_dir_entry *) bh->b_data;
+				de->inode = 0;
+				de->rec_len = le16_to_cpu(sb->s_blocksize);
+				dir->i_size = offset + sb->s_blocksize;
+				OCFS_BH_PUT_DATA(bh);
+				buf = NULL;
+			} else {
+				/* move to next block */
+				buf = OCFS_BH_GET_DATA_READ(bh); /* read */
+				de = (struct ocfs2_dir_entry *) bh->b_data;
+				OCFS_BH_PUT_DATA(bh);
+				buf = NULL;
+			}
+			
+		}
+		if (buf) {
+#warning removemelater
+			LOG_ERROR_ARGS("oops.  block=%lu\n", bh->b_blocknr);
+			BUG();
+		}
+		buf = OCFS_BH_GET_DATA_READ(bh); /* read */
+		if (!ocfs_check_dir_entry (dir, de, bh, offset)) {
+			OCFS_BH_PUT_DATA(bh);
+			buf = NULL;
+			brelse (bh);
+			return -ENOENT;
+		}
+		if (ocfs_match (namelen, name, de)) {
+			OCFS_BH_PUT_DATA(bh);
+			buf = NULL;
+			brelse (bh);
+			return -EEXIST;
+		}
+		if ((le64_to_cpu(de->inode) == 0 && le16_to_cpu(de->rec_len) >= rec_len) ||
+		    (le16_to_cpu(de->rec_len) >= OCFS_DIR_REC_LEN(de->name_len) + rec_len)) {
+			OCFS_BH_PUT_DATA(bh);
+			buf = NULL;
+			status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
+			buf = OCFS_BH_GET_DATA_WRITE(bh); /* write */
+			/* By now the buffer is marked for journaling */
+			offset += le16_to_cpu(de->rec_len);
+			if (le64_to_cpu(de->inode)) {
+				de1 = (struct ocfs2_dir_entry *) ((char *) de +
+					OCFS_DIR_REC_LEN(de->name_len));
+				de1->rec_len =
+					cpu_to_le16(le16_to_cpu(de->rec_len) -
+					OCFS_DIR_REC_LEN(de->name_len));
+				de->rec_len = cpu_to_le16(OCFS_DIR_REC_LEN(de->name_len));
+				de = de1;
+			}
+			de->file_type = OCFS_FT_UNKNOWN;
+			if (inode_off) {
+				de->inode = cpu_to_le64(inode_off);
+				ocfs_set_de_type(dir->i_sb, de, inode->i_mode);
+			} else
+				de->inode = 0;
+			de->name_len = namelen;
+			memcpy (de->name, name, namelen);
+			OCFS_BH_PUT_DATA(bh);
+			buf = NULL;
 
-	if (!IS_VALID_DIR_NODE(pLockNode))
-		BUG();
-
-	/* Change the actual name now */
-	fe->filename[0] = '\0';
-	strncpy (fe->filename, file_name->name, file_name->len);
-	fe->filename[file_name->len] = '\0';
-	DISK_LOCK_SEQNUM (fe) = 0;
-	SET_VALID_BIT (fe->sync_flags);
-	fe->sync_flags &= ~(OCFS_SYNC_FLAG_CHANGE);
-
-	/* mark the dirnode as dirty */
-	pLockNode->index_dirty = 1;
-	pLockNode->bad_off = (fe->this_sector - dir_node_ptr) >> osb->sect_size_bits;
-	pLockNode->bad_off -= 1;
-	cache_lock = (DISK_LOCK_FILE_LOCK (pLockNode) == OCFS_DLM_ENABLE_CACHE_LOCK);
-
-	for (index = 0; index < pLockNode->num_ent_used; index++) {
-		if (pLockNode->index[index] == pLockNode->bad_off)
-			break;
-	}
-	needs_reindex = (index < pLockNode->num_ent_used);
-
-	if (needs_reindex) {
-		memmove (&pLockNode->index[index], 
-			 &pLockNode->index[index + 1],
-			 pLockNode->num_ent_used - (index + 1));
-		pLockNode->index[pLockNode->num_ent_used - 1] = pLockNode->bad_off;
-		/* is this a safe cast? */
-		flags = OCFS_FE_CACHE_FLAGS(osb, ((ocfs_file_entry *) pLockNode));
-	}
-
-	OCFS_BH_PUT_DATA(dirbh);
-	status = ocfs_journal_dirty(handle, dirbh);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-
-	flags = OCFS_FE_CACHE_FLAGS(osb, fe);
-	OCFS_BH_PUT_DATA(fe_bh);
-	fe = NULL;
-	status = ocfs_journal_dirty(handle, fe_bh);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-
-	if (needs_reindex) {
-		status = ocfs_reindex_dir_node (osb, dir_node_ptr, NULL, handle, dir_inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
+			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+			dir->i_version = ++event;
+			status = ocfs_journal_dirty(handle, bh);
+			brelse(bh);
+			return 0;
 		}
+		offset += le16_to_cpu(de->rec_len);
+		de = (struct ocfs2_dir_entry *) ((char *) de + le16_to_cpu(de->rec_len));
+		OCFS_BH_PUT_DATA(bh);
+		buf = NULL;
 	}
+	if (buf)
+		OCFS_BH_PUT_DATA(bh);
+	buf = NULL;
+	brelse (bh);
+	return -ENOSPC;
+}
 
-leave:
-	if (fe != NULL)
-		OCFS_BH_PUT_DATA(fe_bh);
 
-	if (fe_bh)
-		brelse(fe_bh);
-	if (dirbh)
-		brelse(dirbh);
-
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_rename_file */
-
-/* This is broken as it only checks the 1st dir node, and doesn't even
- * check the right field. Also, it will change with the new directory
- * structures. Return a negative value on error, 0 on empty or a positive 
- * value on not empty. */
-static int ocfs_is_dir_empty(ocfs_super *osb, struct inode *dir_inode, __u64 dir_node_off)
+/*
+ * ocfs_delete_entry deletes a directory entry by merging it with the
+ * previous entry
+ */
+static int ocfs_delete_entry (ocfs_journal_handle *handle, struct inode * dir, struct ocfs2_dir_entry * de_del, struct buffer_head * bh)
 {
-	int status;
-	struct buffer_head *dir_node_bh = NULL;
-	__u8 numused;
-	ocfs_dir_node *dirnode;
+	struct ocfs2_dir_entry * de, * pde;
+	int i, status = -ENOENT;
 
-	LOG_ENTRY_ARGS("(dir_node_off == %llu)\n", dir_node_off);
-
-	status = ocfs_read_bh(osb, dir_node_off, &dir_node_bh, OCFS_BH_CACHED, 
-			      dir_inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto bail;
+	i = 0;
+	pde = NULL;
+	de = (struct ocfs2_dir_entry *) OCFS_BH_GET_DATA_READ(bh); /* read */
+	while (i < bh->b_size) {
+		if (!ocfs_check_dir_entry(dir, de, bh, i)) {
+			OCFS_BH_PUT_DATA(bh);
+			status = -EIO;
+			goto bail;
+		}
+		if (de == de_del)  {
+			OCFS_BH_PUT_DATA(bh);
+			status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
+			if (status < 0) {
+				status = -EIO;
+				goto bail;
+			}
+			OCFS_BH_GET_DATA_WRITE(bh); /* write */
+			if (pde)
+				pde->rec_len = cpu_to_le16(le16_to_cpu(pde->rec_len) +
+						    le16_to_cpu(de->rec_len));
+			else
+				de->inode = 0;
+			OCFS_BH_PUT_DATA(bh);
+			dir->i_version = ++event;
+			status = ocfs_journal_dirty(handle, bh);
+			goto bail;
+		}
+		i += le16_to_cpu(de->rec_len);
+		pde = de;
+		de = (struct ocfs2_dir_entry *)((char *) de + le16_to_cpu(de->rec_len));
 	}
-
-	dirnode = (ocfs_dir_node *)OCFS_BH_GET_DATA_READ(dir_node_bh);/* read */
-	if (!IS_VALID_DIR_NODE(dirnode)) {
-		OCFS_BH_PUT_DATA(dir_node_bh);
-		status = -EIO;
-		LOG_TRACE_STR("Uhoh, invalid dirnode found!");
-		goto bail;
-	}
-
-	numused = dirnode->num_ent_used;
-	OCFS_BH_PUT_DATA(dir_node_bh);
-
-	status = (int) numused;
+	OCFS_BH_PUT_DATA(bh);
 bail:
-	if (dir_node_bh)
-		brelse(dir_node_bh);
-
-	LOG_EXIT_STATUS(status);
-	return(status);
+	return status;
 }
 
-/* ocfs_fe_smash()
- *
- * Flags for 'flags' field (no flags means do everything)
- * FLAG_DEL_NAME    - Only want to remove the file entry -- do not free 
- *                    any extents. this flag is used during rename.
- *
- * FLAG_DEL_INODE   - Do not remove the inode from our inode hash.
- *
- * Two functions call this: ocfs_unlink (no flags) and ocfs_rename
- * (uses both flags under different circumstances).
- *
- * Removes a file entry and (possibly) it's extents. Calls
- * commit_trans or abort_trans to do the actual work.
- *
- * If we're passed a journal handle, then we assume that everything
- * has been setup for us and we don't bother to do any
- * locking. Otherwise we start and commit/abort our own transaction
- * and lock our own stuff. If you give us a handle, we'll also try
- * to pass back a bitmap_free_head (if it's not passed as NULL)
- *
+/*
+ * Returns 0 if not found, -1 on failure, and 1 on success
  */
-static int ocfs_fe_smash (ocfs_super * osb, __u32 flags, ocfs_journal_handle *passed_handle, struct dentry *dentry, struct inode *parent_inode)
+static int inline search_dirblock(struct buffer_head * bh,
+				  struct inode *dir,
+				  struct dentry *dentry,
+				  unsigned long offset,
+				  struct ocfs2_dir_entry ** res_dir)
 {
-	int status = 0;
-	int tmpstat;
-	ocfs_file_entry *fe = NULL;
-	__u32 lockFlags = 0;
-	int local_handle = 0, is_dir;
-	struct buffer_head *fe_bh = NULL;
-	struct buffer_head *parent_node_bh = NULL; /* parent locknode */
-	ocfs_journal_handle *handle = NULL;
-	struct inode *inode = dentry->d_inode;
-	int got_parent = 0, got_file = 0;
-	__u64 file_off = GET_INODE_FEOFF(inode);
-	__u64 parent_off = GET_INODE_FEOFF(parent_inode);
-	__u64 parent_dirnode_off = OCFS_I(parent_inode)->u.child_dirnode;
+	struct ocfs2_dir_entry * de;
+	char * dlimit;
+	int de_len;
+	const char *name = dentry->d_name.name;
+	int namelen = dentry->d_name.len;
+	int ret = 0;
 
-	LOG_ENTRY ();
+	de = (struct ocfs2_dir_entry *) OCFS_BH_GET_DATA_READ(bh); /* read */
+	dlimit = (char *)de + dir->i_sb->s_blocksize;
+	while ((char *) de < dlimit) {
+		/* this code is executed quadratically often */
+		/* do minimal checking `by hand' */
 
-	if (passed_handle) {
-		status = ocfs_read_bh (osb, file_off, &fe_bh, OCFS_BH_CACHED, inode);
-		if (status < 0) {
-			LOG_ERROR_STATUS (status);
-			goto leave;
+		if ((char *) de + namelen <= dlimit &&
+		    ocfs_match (namelen, name, de)) {
+			/* found a match - just to be sure, do a full check */
+			if (!ocfs_check_dir_entry(dir, de, bh, offset)) {
+				ret = -1;
+				goto bail;
+			}
+			*res_dir = de;
+			ret = 1;
+			goto bail;
 		}
-		handle = passed_handle;
-		goto skip_lock;
+		/* prevent looping on a bad block */
+		de_len = le16_to_cpu(de->rec_len);
+		if (de_len <= 0) {
+			ret = -1;
+			goto bail;
+		}
+		offset += de_len;
+		de = (struct ocfs2_dir_entry *) ((char *) de + de_len);
 	}
+bail:
+	OCFS_BH_PUT_DATA(bh);
+	return ret;
+}
 
-	handle = ocfs_start_trans(osb, OCFS_FILE_DELETE_CREDITS);
-	if (handle == NULL) {
-		LOG_ERROR_STATUS (status = -ENOMEM);
-		goto leave;
-	}
-	local_handle = 1;
 
-	/* lock parent directory, yes we use FLAG_FILE_CREATE even
-	 * though we're deleting ;) */
-	status = ocfs_acquire_lock(osb, parent_off, OCFS_DLM_EXCLUSIVE_LOCK,
-				   FLAG_FILE_CREATE|FLAG_DIR, NULL, 
-				   parent_inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto leave;
-	}
-	got_parent = 1;
 
-	/* this will re-read the directory now with the EXCLUSIVE */
-	/* lock already held; it will also return the fe_bh to us */
-	status = ocfs_find_files_on_disk (osb, &(dentry->d_name), &fe_bh, NULL,
-					  parent_inode, 0);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto leave;
-	}
+struct buffer_head * ocfs_find_entry (struct dentry *dentry,
+					struct ocfs2_dir_entry ** res_dir)
+{
+	struct super_block * sb;
+	struct buffer_head * bh_use[NAMEI_RA_SIZE];
+	struct buffer_head * bh, *ret = NULL;
+	unsigned long start, block, b;
+	int ra_max = 0;		/* Number of bh's in the readahead
+				   buffer, bh_use[] */
+	int ra_ptr = 0;		/* Current index into readahead
+				   buffer */
+	int num = 0;
+	int nblocks, i, err;
+	struct inode *dir = dentry->d_parent->d_inode;
 
-	if (S_ISDIR (inode->i_mode))
-		lockFlags = (FLAG_FILE_DELETE | FLAG_DIR);
-	else
-		lockFlags = (FLAG_FILE_DELETE);
+	*res_dir = NULL;
+	sb = dir->i_sb;
 
-	status = ocfs_acquire_lock (osb, file_off, OCFS_DLM_EXCLUSIVE_LOCK,
-			lockFlags, &fe_bh, inode);
-	if (status < 0) {
-		if (status != -EINTR)
-			LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-	got_file = 1;
+	nblocks = dir->i_size >> OCFS_SB(sb)->sect_size_bits;
+	start = OCFS_I(dir)->i_dir_start_lookup;
+	if (start >= nblocks)
+		start = 0;
+	block = start;
+restart:
+	do {
+		/*
+		 * We deal with the read-ahead logic here.
+		 */
+		if (ra_ptr >= ra_max) {
+			/* Refill the readahead buffer */
+			ra_ptr = 0;
+			b = block;
+			for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) {
+				/*
+				 * Terminate if we reach the end of the
+				 * directory and must wrap, or if our
+				 * search has finished at this block.
+				 */
+				if (b >= nblocks || (num && block == start)) {
+					bh_use[ra_max] = NULL;
+					break;
+				}
+				num++;
+		
+#warning questionable readahead stuff here	
+				bh = ocfs_bread(NULL, dir, b++, 0, &err, 1);
+				bh_use[ra_max] = bh;
+#if 0		// ???
+				if (bh)
+					ll_rw_block(READ, 1, &bh);
+#endif
+			}
+		}
+		if ((bh = bh_use[ra_ptr++]) == NULL)
+			goto next;
+		wait_on_buffer(bh);
+		if (!buffer_uptodate(bh)) {
+			/* read error, skip block & hope for the best */
+			brelse(bh);
+			goto next;
+		}
+		i = search_dirblock(bh, dir, dentry,
+			    block << OCFS_SB(sb)->sect_size_bits, res_dir);
+		if (i == 1) {
+			OCFS_I(dir)->i_dir_start_lookup = block;
+			ret = bh;
+			goto cleanup_and_exit;
+		} else {
+			brelse(bh);
+			if (i < 0)
+				goto cleanup_and_exit;
+		}
+	next:
+		if (++block >= nblocks)
+			block = 0;
+	} while (block != start);
 
-skip_lock:
-	status = ocfs_journal_access(handle, fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
+	/*
+	 * If the directory has grown while we were searching, then
+	 * search the last part of the directory before giving up.
+	 */
+	block = nblocks;
+	nblocks = dir->i_size >> OCFS_SB(sb)->sect_size_bits;
+	if (block < nblocks) {
+		start = 0;
+		goto restart;
 	}
+		
+cleanup_and_exit:
+	/* Clean up the read-ahead blocks */
+	for (; ra_ptr < ra_max; ra_ptr++)
+		brelse (bh_use[ra_ptr]);
+	return ret;
+}
 
-	/* need to preserve locking order, so take a 'write' lock on
-	 * the dirnode sector first. it won't get passed to
-	 * journal_dirty until ocfs_remove_file so clean up the write
-	 * lock on errors before that */
-	status = ocfs_read_bh(osb, parent_dirnode_off, &parent_node_bh, 
-			      OCFS_BH_CACHED, parent_inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-	OCFS_BH_GET_DATA_WRITE(parent_node_bh);
-	OCFS_BH_PUT_DATA(parent_node_bh);
 
-	/* we call ocfs_clear_buffer_modified in several error cases
-	 * here if we set the modify bit on this buffer, but haven't
-	 * journal_dirtied it yet. Otherwise, it'll stay modified even
-	 * after the abort_trans. */
-	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_WRITE(fe_bh); /* write */
-	is_dir = S_ISDIR (inode->i_mode);
 
-	if (fe->attribs & OCFS_ATTRIB_DIRECTORY && !is_dir)
-		BUG();
+int ocfs_orphan_add(ocfs_journal_handle *handle, struct inode *inode)
+{
+	LOG_ERROR_ARGS("need to add %llu to orphan dir, i_nlink=%d\n",
+			GET_INODE_FEOFF(inode), inode->i_nlink);
+	return 0;
+}
 
-	if (is_dir && !(flags & FLAG_DEL_NAME)) {
-		int numused;
+int ocfs_orphan_del(ocfs_journal_handle *handle, struct inode *inode)
+{
+	return 0;
+}
 
-		numused = ocfs_is_dir_empty(osb, inode, fe->u.child_dirnode);
-		if (numused) {
-			if (numused > 0)
-				status = -ENOTEMPTY;
-			else {
-				status = numused;
-				LOG_ERROR_STATUS(status);
-			}
-			OCFS_BH_PUT_DATA(fe_bh);
-			ocfs_clear_buffer_modified(parent_node_bh);
-			goto leave;
-		}
-	}
+#if 0
+static int ocfs_link (struct dentry * old_dentry,
+		struct inode * dir, struct dentry *dentry)
+{
+	ocfs_journal_handle *handle = NULL;
+	struct inode *inode = old_dentry->d_inode;
+	int err;
+	__u64 parent_off=0ULL, fe_off=0ULL;
+	int tmpstat;
+	struct buffer_head *bh = NULL;
+	ocfs_file_entry *fe = NULL;
 
-	if (flags & FLAG_DEL_NAME) {
-		/* Ok, we don't want to kill it's extents (I.E. we're
-		 * doing a rename so skip the 1st part of this function. */
-		status = 0;
-		OCFS_BH_PUT_DATA(fe_bh);
-		ocfs_clear_buffer_modified(parent_node_bh);
-		goto delete_entry;
-	}
+	if (S_ISDIR(inode->i_mode))
+		return -EPERM;
 
-	if (fe->link_cnt) {
-		/* Decrement Link count when implementing links... TODO*/
-		OCFS_SET_FLAG (fe->sync_flags, OCFS_SYNC_FLAG_NAME_DELETED);
-		fe->sync_flags &= (~OCFS_SYNC_FLAG_VALID);
-	} else {
-		OCFS_SET_FLAG (fe->sync_flags, OCFS_SYNC_FLAG_MARK_FOR_DELETION);
-		fe->sync_flags &= (~OCFS_SYNC_FLAG_VALID);
-	}
-	OCFS_BH_PUT_DATA(fe_bh);
+	if (inode->i_nlink >= OCFS_LINK_MAX)
+		return -EMLINK;
 
-	/* Free up all the bits in the bitmap. */
-	if (is_dir) {
-		/* Iterate through all the dir nodes for this
-		 * directory and mark them to be freed */
-		fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh); /* read */
-		status = ocfs_free_directory_block (osb, fe, handle, inode);
-		OCFS_BH_PUT_DATA(fe_bh);
-		if (status < 0) {
-			OCFS_BH_PUT_DATA(fe_bh);
-			ocfs_clear_buffer_modified(parent_node_bh);
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
-	} else {
-		/* mark all the extents (and extent metadata) for
-		 * this file so we can remove them after commit. */
-		status = ocfs_free_file_extents (osb, fe_bh, handle, inode);
-		if (status < 0) {
-			ocfs_clear_buffer_modified(fe_bh);
-			ocfs_clear_buffer_modified(parent_node_bh);
-			LOG_ERROR_STATUS (status);
-			goto leave;
-		}
+#define OCFS_DATA_TRANS_BLOCKS          (3 * 8 - 2)
+	handle = ocfs_start_trans(osb, OCFS_DATA_TRANS_BLOCKS);
+	if (handle == NULL) {
+		return -ENOMEM;
 	}
+	
+	/* lock the parent directory */
+	parent_off = GET_INODE_FEOFF(dir);
+	err = ocfs_acquire_lock (osb, parent_off, 
+				    OCFS_DLM_ENABLE_CACHE_LOCK,
+				    FLAG_FILE_CREATE | FLAG_DIR, 
+				    NULL, dir);
+	if (err < 0) {
+		parent_off = 0ULL;
+		if (err != -EINTR)
+			LOG_ERROR_STATUS (err);
+		goto bail;
+	}
 
-delete_entry:
-	/* remove the fe from the dirnode.*/
-	status = ocfs_remove_file(osb, fe_bh, parent_node_bh, handle, 
-				  parent_inode, inode);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto leave;
+	/* lock the file entry */
+	fe_off = GET_INODE_FEOFF(inode);
+	err = ocfs_acquire_lock (osb, fe_off, 
+				    OCFS_DLM_ENABLE_CACHE_LOCK,
+				    FLAG_FILE_CREATE, 
+				    &bh, inode);
+	if (err < 0) {
+		fe_off = 0ULL;
+		if (err != -EINTR)
+			LOG_ERROR_STATUS (err);
+		goto bail;
 	}
 
-	status = ocfs_journal_dirty(handle, fe_bh);
-	if (status < 0)
-		LOG_ERROR_STATUS(status);
+	err = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
+	if (err < 0)
+		goto bail;
 
-leave:
+	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_WRITE(bh);
+	fe->link_cnt++;
+	inode->i_nlink = fe->link_cnt;
+	inode->i_ctime = CURRENT_TIME;
+	atomic_inc(&inode->i_count);
+	OCFS_BH_PUT_DATA(bh);
 
-	if (inode && status == 0 && !(flags & FLAG_DEL_INODE)) {
-		SET_INODE_DELETED(inode);
-//		printk("ocfs2: removing inode %lu, voteoff = %llu, "
-//		       "feoff = %llu, count = %u\n", inode->i_ino, 
-//		       GET_INODE_VOTEOFF(inode), 
-//		       GET_INODE_FEOFF(inode), 
-//		       atomic_read(&inode->i_count));
-		ocfs_inode_hash_remove(&osb->inode_hash, 
-				       GET_INODE_FEOFF(inode));
+	err = ocfs_journal_dirty(handle, bh);
+	if (err < 0) {
+		inode->i_nlink--;
+		goto bail;
 	}
 
-	if (local_handle && handle && (status < 0))
+	err = ocfs_add_entry(handle, dentry, inode);
+	if (err)
+		inode->i_nlink--;
+	else 	
+		d_instantiate(dentry, inode);
+bail:
+	if (err < 0)
 		ocfs_abort_trans(handle);
-	else if (local_handle && handle) 
+	else
 		ocfs_commit_trans(handle);
 
-	/* NEW: adding a fake release lock for the dead file entry here */
-	/* need this to alert dentry-owners on other nodes */
-	/* Release the file lock if we acquired it */
-	if (got_file) {
-		tmpstat = ocfs_release_lock(osb, file_off, 
-					    OCFS_DLM_EXCLUSIVE_LOCK, 
-					    lockFlags, fe_bh, inode);
+	if (parent_off) {
+		tmpstat = ocfs_release_lock (osb, parent_off, 
+					     OCFS_DLM_ENABLE_CACHE_LOCK,
+					     FLAG_FILE_CREATE | FLAG_DIR, 
+					     NULL, dir);
 		if (tmpstat < 0)
-			LOG_ERROR_STATUS(tmpstat);
-
+			LOG_ERROR_STATUS (tmpstat);
 	}
-
-	if (got_parent) {
-		tmpstat = ocfs_release_lock(osb, parent_off, 
-					    OCFS_DLM_EXCLUSIVE_LOCK,
-					    FLAG_FILE_CREATE|FLAG_DIR, 
-					    NULL, parent_inode);
+	if (fe_off) {
+		tmpstat = ocfs_release_lock (osb, fe_off, 
+					     OCFS_DLM_ENABLE_CACHE_LOCK,
+					     FLAG_FILE_CREATE, 
+					     bh, inode);
 		if (tmpstat < 0)
-			LOG_ERROR_STATUS(tmpstat);
-
+			LOG_ERROR_STATUS (tmpstat);
 	}
 
-	if (fe_bh)
-		brelse(fe_bh);
+	if (bh)
+		brelse(bh);
 
-	if (parent_node_bh)
-		brelse(parent_node_bh);
+	// is this right?!
+	if (err)
+		iput(inode);
 
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_fe_smash */
+	return err;
+}
+#endif

Modified: branches/new-dir-format/src/nm.c
===================================================================
--- branches/new-dir-format/src/nm.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/nm.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -814,15 +814,14 @@
 			}
 
 			/* If the inode exists and we we're going to
-			 * vote yes on the delete, then lets remove it
-			 * from the hash now. It will retain a single
+			 * vote yes on the delete, then lets mark it
+			 * deleted now. It will retain a single
 			 * reference for the rest of this function (we
 			 * can sync it and change nlink) which we iput
 			 * before exit. */
 			if (inode && vote_response == FLAG_VOTE_NODE) {
+#warning is this needed anymore?
 				SET_INODE_DELETED(inode);
-				ocfs_inode_hash_remove(&osb->inode_hash, 
-						     GET_INODE_FEOFF(inode));
 			}
 
 			if (!lockres) {
@@ -982,7 +981,7 @@
 			}
 	
 			fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh); /* read */
-			is_dir = IS_VALID_DIR_NODE(fe);
+			is_dir = fe->attribs & OCFS_ATTRIB_DIRECTORY;
 			is_locked = DISK_LOCK_FILE_LOCK (fe) > OCFS_DLM_NO_LOCK;
 			if (vote_type == CHANGE_MASTER) {
 				OCFS_BH_PUT_DATA(fe_bh);

Modified: branches/new-dir-format/src/osb.c
===================================================================
--- branches/new-dir-format/src/osb.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/osb.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -143,19 +143,23 @@
 	if (vol_layout->file_node_size == 0) 
 		vol_layout->file_node_size = OCFS_DEFAULT_FILE_NODE_SIZE;
 
+	osb->inode_size = OCFS_DEFAULT_INODE_SIZE;
+
 	/* get some pseudo constants for >> bits */
 	osb->sect_size_bits = ocfs_get_right_shift_bits(sect_size);
 	osb->cluster_size_bits = ocfs_get_right_shift_bits(vol_layout->cluster_size);
 	osb->dir_alloc_bits = ocfs_get_right_shift_bits(vol_layout->dir_node_size);
 	osb->file_alloc_bits = ocfs_get_right_shift_bits(vol_layout->file_node_size);
-	printk("sectbits=%d, clusterbits=%d, dirbits=%d, filebits=%d\n",
+	osb->inode_alloc_bits = ocfs_get_right_shift_bits(osb->inode_size);
+	printk("sectbits=%d, clusterbits=%d, dirbits=%d, filebits=%d, inodebits=%d\n",
 	       osb->sect_size_bits, osb->cluster_size_bits, 
-	       osb->dir_alloc_bits, osb->file_alloc_bits);
+	       osb->dir_alloc_bits, osb->file_alloc_bits, osb->inode_alloc_bits);
 	
 	OCFS_ASSERT(osb->sect_size_bits);
 	OCFS_ASSERT(osb->cluster_size_bits);
 	OCFS_ASSERT(osb->dir_alloc_bits);
 	OCFS_ASSERT(osb->file_alloc_bits);
+	OCFS_ASSERT(osb->inode_alloc_bits);
 
 
 	osb->max_dir_node_ent = (__u32) (vol_layout->dir_node_size >> osb->sect_size_bits) - 2;
@@ -224,13 +228,6 @@
 	for(i = 0; i < OCFS_MAXIMUM_NODES; i++)
 		osb->last_publ_seq_num[i] = (__u64) (-1);
 
-	/* init the inode hash */
-	status = ocfs_inode_hash_init(osb);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto finally;
-	}
-
 	/* We might need to add a variable in Global List of osb to */
 	/* delay any creation, if any other node is already creating a file */
 

Modified: branches/new-dir-format/src/proc.c
===================================================================
--- branches/new-dir-format/src/proc.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/proc.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -170,9 +170,7 @@
 		item = list_entry (iter, alloc_item, list);
 		switch (item->type) {
 		    case SLAB_ITEM:
-			if (item->u.slab == OcfsGlobalCtxt.ofile_cache)
-				slabname = "ofile";
-			else if (item->u.slab == OcfsGlobalCtxt.fe_cache)
+			if (item->u.slab == OcfsGlobalCtxt.fe_cache)
 				slabname = "fe";
 			else
 				slabname = "unknown";

Modified: branches/new-dir-format/src/super.c
===================================================================
--- branches/new-dir-format/src/super.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/super.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -142,6 +142,7 @@
 #endif
 
 static int ocfs_init_system_inodes(ocfs_super *osb);
+static int ocfs_release_system_inodes(ocfs_super *osb);
 
 static struct super_operations ocfs_sops = {
 	.statfs = ocfs_statfs,
@@ -190,10 +191,6 @@
 
 	LOG_ENTRY();
 
-	/* Why the iputs below? Because we get an extra reference
-	 * which we don't need (the purpose of this function is to
-	 * just get the system inodes in the inode hash) */
-
 	/* the vol bitmap */
 	sys_off = OCFS_BITMAP_LOCK_OFFSET;
 	new = ocfs_iget(osb, sys_off, NULL);
@@ -202,7 +199,7 @@
 		LOG_ERROR_STATUS(status);
 		goto bail;
 	}
-	iput(new);
+	osb->system_inodes[GLOBAL_BITMAP_SYSTEM_INODE] = new;
 
 	/* file alloc bitmap */
 	sys_off = osb->vol_layout.root_int_off + 
@@ -214,8 +211,9 @@
 		LOG_ERROR_STATUS(status);
 		goto bail;
 	}
-	iput(new);
+	osb->system_inodes[FILE_ALLOC_BITMAP_SYSTEM_INODE] = new;
 
+#if 0
 	/* dir alloc bitmap */
 	sys_off = osb->vol_layout.root_int_off + 
 		((OCFS_FILE_DIR_ALLOC_BITMAP + osb->node_num) 
@@ -226,8 +224,21 @@
 		LOG_ERROR_STATUS(status);
 		goto bail;
 	}
-	iput(new);
+	osb->system_inodes[DIR_ALLOC_BITMAP_SYSTEM_INODE] = new;
+#endif
 
+	/* inode alloc bitmap */
+	sys_off = osb->vol_layout.root_int_off + 
+		((OCFS_INODE_BITMAP + osb->node_num) 
+		 * osb->sect_size);
+	new = ocfs_iget(osb, sys_off, NULL);
+	if (!new) {
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+	osb->system_inodes[INODE_ALLOC_BITMAP_SYSTEM_INODE] = new;
+
 	/* journal file */
 	sys_off = osb->vol_layout.root_int_off + 
 		((OCFS_JOURNAL_FILE + osb->node_num) * osb->sect_size);
@@ -237,14 +248,31 @@
 		LOG_ERROR_STATUS(status);
 		goto bail;
 	}
-	iput(new);
+	osb->system_inodes[JOURNAL_SYSTEM_INODE] = new;
 
 bail:
 	LOG_EXIT_STATUS(status);
 	return(status);
 } /* ocfs_init_system_inodes */
 
+
 /*
+ * ocfs_release_system_inodes()
+ */
+static int ocfs_release_system_inodes(ocfs_super *osb)
+{
+	int status = 0, i;
+
+	LOG_ENTRY();
+
+	for (i=0; i<NUM_SYSTEM_INODES; i++) {
+		iput(osb->system_inodes[i]);
+	}
+	LOG_EXIT_STATUS(status);
+	return(status);
+} /* ocfs_release_system_inodes */
+
+/*
  * __ocfs_read_super()
  *
  */
@@ -476,7 +504,7 @@
 	init_MUTEX (&(OcfsGlobalCtxt.global_res));
 	OCFS_SET_FLAG (OcfsGlobalCtxt.flags, OCFS_FLAG_GLBL_CTXT_RESOURCE_INITIALIZED);
 
-	/* Initialize the memory slabs for oin, ofile, and file entry */
+	/* Initialize the memory slabs for oin and file entry */
 	status = ocfs_initialize_mem_lists ();
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
@@ -791,10 +819,6 @@
 		 sizeof(ocfs_inode_private), 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
 		 NULL, NULL);
 
-	OcfsGlobalCtxt.ofile_cache = kmem_cache_create ("ocfs2_ofile",
-		sizeof (ocfs_file) + OCFS_POINTER_SIZE, 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
-		NULL, NULL);
-
 	OcfsGlobalCtxt.fe_cache = kmem_cache_create ("ocfs2_fileentry",
 		512, 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN, NULL, NULL);
 
@@ -806,10 +830,6 @@
 		sizeof(ocfs_bh_sem), 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
 		NULL, NULL);
 
-	OcfsGlobalCtxt.inum_cache = kmem_cache_create("ocfs2_inum", 
-		sizeof(ocfs_inode_num), 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN, 
-		NULL, NULL);
-	
 	OCFS_SET_FLAG (OcfsGlobalCtxt.flags, OCFS_FLAG_MEM_LISTS_INITIALIZED);
 
 	return 0;
@@ -822,11 +842,9 @@
 static void ocfs_free_mem_lists (void)
 {
 	kmem_cache_destroy (OcfsGlobalCtxt.inode_cache);
-	kmem_cache_destroy (OcfsGlobalCtxt.ofile_cache);
 	kmem_cache_destroy (OcfsGlobalCtxt.fe_cache);
 	kmem_cache_destroy (OcfsGlobalCtxt.extent_cache);
 	kmem_cache_destroy (OcfsGlobalCtxt.bh_sem_cache);
-	kmem_cache_destroy (OcfsGlobalCtxt.inum_cache);
 	OCFS_CLEAR_FLAG (OcfsGlobalCtxt.flags, OCFS_FLAG_MEM_LISTS_INITIALIZED);
 }				/* ocfs_free_mem_lists */
 
@@ -1005,7 +1023,7 @@
 	osb->vol_state = VOLUME_ENABLED;
 	up (&(osb->osb_res));
 
-	inode = ocfs_iget(osb, OCFS_ROOT_INODE_FE_OFF, NULL);
+	inode = ocfs_iget(osb, OCFS_ROOT_INODE_FE_OFF(osb), NULL);
 	if (!inode) {
 		status = -EIO;
 		LOG_ERROR_STATUS (status);
@@ -1152,9 +1170,6 @@
 //    list_del(&osb->osb_next);  /* this has been moved into ocfs_delete_osb */
 	up (&(OcfsGlobalCtxt.global_res));
 
-	/* destroy the inode hash */
-	ocfs_inode_hash_destroy(&osb->inode_hash);
-
 	osb->vol_state = VOLUME_DISMOUNTED;
 	if (AcquiredOSB) {
 		up (&(osb->osb_res));
@@ -1173,6 +1188,8 @@
 		ocfs_safefree (p);
 	}
 
+	ocfs_release_system_inodes(osb);
+
 	ocfs_delete_osb (osb);
 	ocfs_safefree (osb);
 	sb->s_dev = 0;

Modified: branches/new-dir-format/src/util.c
===================================================================
--- branches/new-dir-format/src/util.c	2004-05-24 21:26:32 UTC (rev 931)
+++ branches/new-dir-format/src/util.c	2004-05-24 21:34:48 UTC (rev 932)
@@ -326,7 +326,8 @@
 
 void ocfs_truncate_inode_pages(struct inode *inode, loff_t off)
 {
-	LOG_TRACE_ARGS ("truncating pages for inode %lu (%p) from offset %llu\n", inode->i_ino, inode, off);
+	LOG_TRACE_ARGS ("truncating pages for inode %llu (%p) from offset %llu\n", 
+			GET_INODE_FEOFF(inode), inode, off);
 	truncate_inode_pages(&inode->i_data, off);
 }				/* ocfs_truncate_inode_pages */
 



More information about the Ocfs2-commits mailing list