[Ocfs2-commits] mfasheh commits r872 - in trunk/src: . inc

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Apr 27 21:37:05 CDT 2004


Author: mfasheh
Date: 2004-04-27 20:37:04 -0500 (Tue, 27 Apr 2004)
New Revision: 872

Modified:
   trunk/src/alloc.c
   trunk/src/dlm.c
   trunk/src/hash.c
   trunk/src/inc/ocfs.h
   trunk/src/inc/proto.h
   trunk/src/inode.c
   trunk/src/journal.c
   trunk/src/namei.c
   trunk/src/nm.c
   trunk/src/oin.c
   trunk/src/osb.c
   trunk/src/super.c
   trunk/src/sysfile.c
Log:
* turn ocfs_get_inode_from_offset into ocfs_iget. All functions can call
  this to create an inode now, and the 2.4.x/2.6.x paths are unified at last.
  The function will try it's hardest to create an inode based on the
  information provided.

* Teach the ocfs inode stuff about system files. We can now create inodes
  for them on demand, including objects which have no file entry, such as the
  volume bitmap.

* Unify the 2.6.x and 2.4.x read_inode functionality into
  __ocfs_read_inode2.

* Add ocfs_read_inode_nofe to "read" inodes that have no file entry.

* create the most commonly used system file inodes at startup -- vol bitmap, 
  dir alloc bitmap, metadata alloc bitmap and journal inode (that one was
  already being created, but move it to ocfs_init_system_inodes)

* All calls to ocfs_acquire_lock have an inode now. This is absolutely
  necessary as fe_off needs to be properly propagated during votes and this
  can't happen without an inode. The same goes for ocfs_release_lock.

* remove a redundant variable in ocfs_inode_open()



Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/alloc.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -71,11 +71,13 @@
 					ocfs_free_rec *freelog);
 
 static int ocfs_alloc_new_window(ocfs_super *osb, struct buffer_head *lock_bh,
+				 struct inode *bm_inode,
 				 ocfs_journal_handle *hanlde);
 static int ocfs_sync_local_to_main(ocfs_super *osb, 
 				   ocfs_bitmap_free_head **f, 
 				   struct buffer_head *local_alloc_bh, 
 				   struct buffer_head *bm_lock_bh,
+				   struct inode *bm_inode,
 				   bool in_recovery);
 static __u32 ocfs_alloc_count_bits(ocfs_local_alloc *alloc);
 static void ocfs_clear_local_alloc(ocfs_local_alloc *alloc);
@@ -186,6 +188,9 @@
 	ocfs_lock_res **extnode_lockres = NULL;
 	ocfs_lock_res *vol_lockres = NULL;
 	ocfs_free_rec *tmp_log;
+	struct inode **dirnode_inode = NULL;
+	struct inode **extnode_inode = NULL;
+	struct inode *vol_inode = NULL;
 	__u32 tmp_indx;
 	__u64 lock_id;
 	struct buffer_head *globalbh = NULL;
@@ -209,11 +214,17 @@
 		    OCFS_MAXIMUM_NODES * sizeof (ocfs_lock_res *), status);
 	ALLOC_BLOCK(extnode_lockres,
 		    OCFS_MAXIMUM_NODES * sizeof (ocfs_lock_res *), 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;
 	}
 
 	/* alloc memory */
@@ -290,10 +301,18 @@
 		  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, 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,
-						    &(dirnode_lockres[i]), NULL, NULL);
+						    &(dirnode_lockres[i]), 
+						    NULL, dirnode_inode[i]);
 			if (status < 0) {
 				if (status != -EINTR)
 					LOG_ERROR_STATUS (status);
@@ -306,10 +325,18 @@
 		  osb->vol_layout.root_int_off;
 	for (i = 0; i < OCFS_MAXIMUM_NODES; i++, lock_id += osb->sect_size) {
 		if (free_ext_node[i] != NULL) {
+			extnode_inode[i] = ocfs_iget(osb, lock_id, lock_id, 
+						     NULL);
+			if (!extnode_inode[i]) {
+				status = -EINVAL;
+				LOG_ERROR_STATUS (status);
+				goto finally;
+			}
 			status = ocfs_acquire_lock (osb, lock_id,
 				 		    OCFS_DLM_EXCLUSIVE_LOCK,
 						    FLAG_FILE_CREATE,
-						    &(extnode_lockres[i]), NULL, NULL);
+						    &(extnode_lockres[i]), 
+						    NULL, extnode_inode[i]);
 			if (status < 0) {
 				if (status != -EINTR)
 					LOG_ERROR_STATUS (status);
@@ -319,9 +346,17 @@
 	}
 
 	if (free_vol_bits != NULL) {
+		vol_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET, 0, NULL);
+		if (!vol_inode) {
+			status = -EINVAL;
+			LOG_ERROR_STATUS (status);
+			goto finally;
+		}
+
 		status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
 					    OCFS_DLM_EXCLUSIVE_LOCK,
-					    FLAG_FILE_CREATE, &vol_lockres, &globalbh, NULL);
+					    FLAG_FILE_CREATE, &vol_lockres, 
+					    &globalbh, vol_inode);
 		if (status < 0) {
 			if (status != -EINTR)
 				LOG_ERROR_STATUS (status);
@@ -361,7 +396,7 @@
 		}
 		status = ocfs_release_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
 					    OCFS_DLM_EXCLUSIVE_LOCK,
-					    FLAG_FILE_CREATE, vol_lockres, globalbh, NULL);
+					    FLAG_FILE_CREATE, vol_lockres, globalbh, vol_inode);
 		if (status < 0) {
 			LOG_ERROR_STATUS (status);
 			goto finally;
@@ -375,7 +410,8 @@
 			status = ocfs_release_lock (osb, lock_id,
 						    OCFS_DLM_EXCLUSIVE_LOCK,
 						    FLAG_FILE_CREATE,
-						    dirnode_lockres[i], NULL, NULL);
+						    dirnode_lockres[i], NULL, 
+						    dirnode_inode[i]);
 			if (status < 0) {
 				LOG_ERROR_STATUS (status);
 				goto finally;
@@ -390,7 +426,8 @@
 			status = ocfs_release_lock (osb, lock_id,
 						    OCFS_DLM_EXCLUSIVE_LOCK,
 						    FLAG_FILE_CREATE,
-						    extnode_lockres[i], NULL, NULL);
+						    extnode_lockres[i], NULL,
+						    extnode_inode[i]);
 			if (status < 0) {
 				LOG_ERROR_STATUS (status);
 				goto finally;
@@ -406,9 +443,15 @@
 			ocfs_put_lockres (dirnode_lockres[i]);
 		if (free_ext_node[i])
 			ocfs_put_lockres (extnode_lockres[i]);
+		if (extnode_inode[i])
+			iput(extnode_inode[i]);
+		if (dirnode_inode[i])
+			iput(dirnode_inode[i]);
 	}
 	if (globalbh)
 		brelse(globalbh);
+	if (vol_inode)
+		iput(vol_inode);
 
 	ocfs_put_lockres (vol_lockres);
 
@@ -421,6 +464,8 @@
 	ocfs_safefree (free_ext_node);
 	ocfs_safefree (dirnode_lockres);
 	ocfs_safefree (extnode_lockres);
+	ocfs_safefree (dirnode_inode);
+	ocfs_safefree (extnode_inode);
 
 	ocfs_safefree (free_vol_bits);
 
@@ -2703,10 +2748,10 @@
  *
  * Returns 0 on success, < 0 on error.
  *
- * Pass in 'lock_bh' only if you've already taken the vol_alloc
- * semaphore, and you've done the acquire_lock on the bitmap.
+ * Pass in 'lock_bh' and bitmap_inode only if you've already taken the 
+ * vol_alloc semaphore, and you've done the acquire_lock on the bitmap.
  */
-int ocfs_find_contiguous_space_from_bitmap (ocfs_super * osb, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count, bool sysfile, struct buffer_head *lock_bh)
+int ocfs_find_contiguous_space_from_bitmap (ocfs_super * osb, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count, bool sysfile, struct buffer_head *lock_bh, struct inode *bitmap_inode)
 {
 	int status = 0, tmpstat, startbh, numblocks;
 	__u32 bitoffset = 0, ClusterCount = 0;
@@ -2720,6 +2765,7 @@
         ocfs_bitmap_lock *bm_lock = NULL;
 	__u32 bitmapblocks; /* we only care about the valid blocks */
 	bool local_lock = true;
+	bool local_inode = false;
 
 	LOG_ENTRY ();
 
@@ -2728,15 +2774,24 @@
 	if (lock_bh) {
 		local_lock = false;
 		bh = lock_bh;
+	} else /* local lock */
+		ocfs_down_sem (&(osb->vol_alloc_lock), true);
+
+	if (!bitmap_inode) {
+		bitmap_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET, 0, NULL);
+		if (!bitmap_inode) {
+			status = -EINVAL;
+			LOG_ERROR_STR("Could not get bitmap inode!");
+			goto leave;
+		}
+		local_inode = true;
 	}
 
 	if (local_lock) {
-		ocfs_down_sem (&(osb->vol_alloc_lock), true);
-
 		/* Get the allocation lock here */
 		status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
 					    OCFS_DLM_EXCLUSIVE_LOCK, 0, 
-					    &lockres, &bh, NULL);
+					    &lockres, &bh, bitmap_inode);
 		if (status < 0) {
 			if (status != -EINTR)
 				LOG_ERROR_STATUS (status);
@@ -2878,7 +2933,7 @@
 						    OCFS_BITMAP_LOCK_OFFSET,
 						    OCFS_DLM_EXCLUSIVE_LOCK, 
 						    0, lockres, bh, 
-						    NULL);
+						    bitmap_inode);
 			if (tmpstat < 0)
 				LOG_ERROR_STATUS (tmpstat);
 		}
@@ -2887,6 +2942,9 @@
 		ocfs_put_lockres (lockres);
 	}
 
+	if (local_inode)
+		iput(bitmap_inode);
+
 	LOG_EXIT_STATUS (status);
 	return status;
 }				/* ocfs_find_contiguous_space_from_bitmap */
@@ -2921,6 +2979,7 @@
 	ocfs_file_entry *fe = NULL;
 	bool needs_uninit = false;
 	bool delay_lockrel = false;
+	struct inode *inode = NULL; /* alloc bitmap file inode */
 
 	LOG_ENTRY_ARGS("(FileSize = (%llu), Type=%d)\n", FileSize,Type);
 
@@ -2943,10 +3002,16 @@
 	OCFS_ASSERT (blockSize);
 
 	lockId = (bm_file * OCFS_SECTOR_SIZE) + osb->vol_layout.root_int_off;
+	inode = ocfs_iget(osb, lockId, lockId, NULL);
+	if (!inode) {
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto leave;
+	}
 
 	/* Get a lock on the file */
 	status = ocfs_acquire_lock (osb, lockId, OCFS_DLM_EXCLUSIVE_LOCK,
-			     FLAG_FILE_CREATE, &lockres, &bh, NULL);
+			     FLAG_FILE_CREATE, &lockres, &bh, inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
 		goto leave;
@@ -3110,16 +3175,19 @@
 	if (bLockAcquired && delay_lockrel) {
 		ocfs_journal_add_lock(handle, OCFS_DLM_EXCLUSIVE_LOCK, 
 				      FLAG_FILE_CREATE, 
-				      lockres, bh, NULL);
+				      lockres, bh, inode);
 		tmpstat = 0;
 	} else 	if (bLockAcquired) {
 		tmpstat =
 		    ocfs_release_lock (osb, lockId, OCFS_DLM_EXCLUSIVE_LOCK,
-				     FLAG_FILE_CREATE, lockres, bh, NULL);
+				     FLAG_FILE_CREATE, lockres, bh, inode);
 
 		ocfs_put_lockres (lockres);
 	}
 
+	if (inode)
+		iput(inode);
+
 	if (tmpstat < 0)
 		status = tmpstat;
 	if (bh != NULL)
@@ -3383,6 +3451,7 @@
 				   ocfs_bitmap_free_head **f, 
 				   struct buffer_head *local_alloc_bh, 
 				   struct buffer_head *bm_lock_bh,
+				   struct inode *bm_inode,
 				   bool in_recovery)
 {
 	int status = 0, tmpstat;
@@ -3393,6 +3462,7 @@
 	ocfs_local_alloc *alloc = NULL;
 	bool local_lock = true;
 	void *bitmap;
+	struct inode *local_inode = NULL;
 
 	LOG_ENTRY();
 
@@ -3411,6 +3481,18 @@
 		local_lock = false;
 		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, 0, NULL);
+		if (!local_inode) {
+			status = -EINVAL;
+			LOG_ERROR_STATUS(status);
+			goto bail;
+		}
+	}
 
 	if (local_lock) {
 		ocfs_down_sem (&(osb->vol_alloc_lock), true);
@@ -3420,7 +3502,7 @@
 					    OCFS_DLM_EXCLUSIVE_LOCK, 
 					    (in_recovery) ? FLAG_FILE_RECOVERY 
 					    : 0, 
-					    &lockres, &bh, NULL);
+					    &lockres, &bh, local_inode);
 		if (status < 0) {
 			if (status != -EINTR)
 				LOG_ERROR_STATUS (status);
@@ -3486,7 +3568,8 @@
 			tmpstat = ocfs_release_lock (osb, 
 						     OCFS_BITMAP_LOCK_OFFSET,
 						     OCFS_DLM_EXCLUSIVE_LOCK, 
-						     0, lockres, bh, NULL);
+						     0, lockres, bh, 
+						     local_inode);
 			if (tmpstat < 0)
 				LOG_ERROR_STATUS (tmpstat);
 			ocfs_put_lockres (lockres);
@@ -3495,6 +3578,9 @@
 			brelse(bh);
 	}
 
+	if (local_inode)
+		iput(local_inode);
+
 	LOG_EXIT_STATUS(status);
 	return(status);
 } /* ocfs_sync_local_to_main */
@@ -3505,6 +3591,7 @@
  * pass it the bitmap lock in lock_bh if you have it. 
  */
 static int ocfs_alloc_new_window(ocfs_super *osb, struct buffer_head *lock_bh, 
+				 struct inode *bm_inode, 
 				 ocfs_journal_handle *handle)
 {
 	int status = 0;
@@ -3529,7 +3616,7 @@
 	status = ocfs_find_contiguous_space_from_bitmap(osb, alloc_bytes, 
 							&cluster_off, 
 							&cluster_count, false, 
-							lock_bh);
+							lock_bh, bm_inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto bail;
@@ -3642,6 +3729,7 @@
 	__u32 tmpwanted;
 	/* main bitmap variables. */
 	struct buffer_head *main_bm_bh = NULL;
+	struct inode *main_bm_inode = NULL;
 	ocfs_lock_res *lockres = NULL;
 	void *bitmap;
 
@@ -3671,7 +3759,8 @@
 		alloc = NULL;
 		LOG_TRACE_STR("Allocating a new window...");
 
-		status = ocfs_alloc_new_window(osb, main_bm_bh, handle);
+		status = ocfs_alloc_new_window(osb, main_bm_bh, main_bm_inode, 
+					       handle);
 		if (status < 0) {
 			if (status == -ENOSPC) {
 				/* TODO: Remove this printk */
@@ -3713,10 +3802,22 @@
 		/* lock bitmap here */
 		ocfs_down_sem (&(osb->vol_alloc_lock), true);
 
+		if (!main_bm_inode)
+			main_bm_inode = ocfs_iget(osb, OCFS_BITMAP_LOCK_OFFSET,
+						  0, NULL);
+
+		if (!main_bm_inode) {
+			ocfs_up_sem (&(osb->vol_alloc_lock));
+			status = -EINVAL;
+			LOG_ERROR_STATUS (status);
+			goto bail;
+		}
+
 		/* Get the allocation lock here */
 		status = ocfs_acquire_lock (osb, OCFS_BITMAP_LOCK_OFFSET,
 					    OCFS_DLM_EXCLUSIVE_LOCK, 0, 
-					    &lockres, &main_bm_bh, NULL);
+					    &lockres, &main_bm_bh, 
+					    main_bm_inode);
 		if (status < 0) {
 			ocfs_up_sem (&(osb->vol_alloc_lock));
 			if (status != -EINTR)
@@ -3725,7 +3826,8 @@
 		}
 
 		status = ocfs_sync_local_to_main(osb, &(handle->commit_bits),
-						 NULL, main_bm_bh, false);
+						 NULL, main_bm_bh, 
+						 main_bm_inode, false);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
 			goto bail;
@@ -3782,7 +3884,8 @@
 		tmpstat = ocfs_release_lock (osb, 
 					     OCFS_BITMAP_LOCK_OFFSET,
 					     OCFS_DLM_EXCLUSIVE_LOCK, 
-					     0, lockres, main_bm_bh, NULL);
+					     0, lockres, main_bm_bh, 
+					     main_bm_inode);
 		if (tmpstat < 0)
 			LOG_ERROR_STATUS (tmpstat);
 		ocfs_put_lockres (lockres);
@@ -3792,6 +3895,9 @@
 	if (alloc && osb->local_alloc_bh)
 		OCFS_BH_PUT_DATA(osb->local_alloc_bh);
 
+	if (main_bm_inode)
+		iput(main_bm_inode);
+
 	LOG_EXIT_STATUS(status);
 	return(status);
 } /* ocfs_find_space_from_local */
@@ -3853,7 +3959,8 @@
 		status = ocfs_find_contiguous_space_from_bitmap(osb, file_size,
 								cluster_off, 
 								cluster_count, 
-								sysfile, NULL);
+								sysfile, NULL,
+								NULL);
 	if (status < 0)
 		LOG_ERROR_STATUS(status);
 
@@ -3992,7 +4099,8 @@
 	else
 		bh = osb->local_alloc_bh;
 
-	status = ocfs_sync_local_to_main(osb, &f, NULL, NULL, in_recovery);
+	status = ocfs_sync_local_to_main(osb, &f, NULL, NULL, NULL,
+					 in_recovery);
 	if (status < 0)
 		LOG_ERROR_STATUS(status);
 	else if (f)

Modified: trunk/src/dlm.c
===================================================================
--- trunk/src/dlm.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/dlm.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -1097,6 +1097,7 @@
 	
 	OCFS_ASSERT(lock_type != OCFS_DLM_NO_LOCK);
 	OCFS_ASSERT(lock_type != OCFS_DLM_SHARED_LOCK);
+	OCFS_ASSERT(inode);
 
 	if (bh != NULL)
 		b = bh;
@@ -1497,6 +1498,8 @@
 	LOG_ENTRY_ARGS ("(0x%08x, %u.%u, %u, %u, 0x%08x)\n", osb, HI (lock_id),
 			LO (lock_id), lock_type, flags, lockres);
 
+	OCFS_ASSERT(inode);
+
 	flags |= FLAG_RELEASE_LOCK;
 
 again:

Modified: trunk/src/hash.c
===================================================================
--- trunk/src/hash.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/hash.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -1271,7 +1271,7 @@
 
 		if (inum->i_inode) {
 			/* this log_error_args is mainly for debugging */
-			if (atomic_read(&inum->i_inode->i_count) > 2)
+			if (atomic_read(&inum->i_inode->i_count) > 1)
 				LOG_ERROR_ARGS("inode (%lu) with i_count = %u "
 					  "left in system, (voteoff = "
 					  "%u.%u, fileoff = %u.%u)\n", 
@@ -1742,131 +1742,3 @@
 }
 #endif
 
-/* 
- * ocfs_get_inode_from_offset()
- *
- * Not all fields are required, pick your poison:
- *   * fe_bh only -- voteoff and feoff should both be zero then.
- *   * voteoff and feoff -- fe_bh can be NULL (doesn't have to)
- */
-struct inode *ocfs_get_inode_from_offset(ocfs_super *osb, 
-					 __u64 voteoff, __u64 feoff, 
-					 struct buffer_head *fe_bh)
-{
-	struct inode *inode = NULL;
-	struct super_block *sb = osb->sb;
-	ocfs_file_entry *fe;
-	ocfs_find_inode_args args;
-
-	LOG_ENTRY_ARGS("(voteoff = %u.%u, feoff = %u.%u, fe_bh = %p)\n", 
-		       HILO(voteoff), HILO(feoff), fe_bh);
-
-	/* Shortcut: if they ask for the root dirnode, just return
-	 * it. */
-	if (voteoff == osb->vol_layout.root_start_off) {
-		LOG_TRACE_ARGS("Asked for root dirnode (%u.%u)\n",
-			       HILO(feoff));
-
-		inode = osb->sb->s_root->d_inode;
-
-		/* should we iget it or not? i suppose if you're in
-		 * here and you've asked for the root inode you don't
-		 * know what it is and will prolly iput it later... */
-		if (inode) {
-			if (ocfs_inc_icount(inode) < 0)
-				BUG();
-		}
-		goto bail;
-	}
-
-	/* Ok, lets try to be smart here. We need a very specific set
-	 * of arguments to get our inode. Figure these out from the
-	 * available data. */
-	if (fe_bh) {
-		/* best case -- we can figure out what we need from
-		 * the file entry! */
-		fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh);
-		if (!IS_VALID_FILE_ENTRY(fe)) {
-			OCFS_BH_PUT_DATA(fe_bh);
-			LOG_ERROR_STATUS(-EINVAL);
-			goto bail;
-		}
-		feoff = fe->this_sector;
-		/* need voteoff too. */
-		if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
-			voteoff = fe->extents[0].disk_off;
-		else
-			voteoff = fe->this_sector;
-		OCFS_BH_PUT_DATA(fe_bh);
-	} else {
-		if ((voteoff == 0) || (feoff == 0)) {
-			LOG_ERROR_STATUS(-EINVAL);
-			goto bail;
-		}
-	}
-
-	/* This is ugly, but...
-	 * There are several cases where we may not want an inode:
-	 * 1) any time during 1st mount (root_start_off will be 0)
-	 * 2) any system file, EXCEPT the journal as JBD requires one
-	 */
-	if (osb->vol_layout.root_start_off == 0 
-	    || feoff < osb->vol_layout.root_start_off) {
-		/* OHMYGODTHISISTHEUGLIESTIFEVER */
-		if (feoff < (OCFS_JOURNAL_FILE * osb->sect_size 
-			      + osb->vol_layout.root_int_off) 
-		    || 
-		    feoff >= ((OCFS_JOURNAL_FILE + OCFS_MAXIMUM_NODES)
-			       * osb->sect_size 
-			       + osb->vol_layout.root_int_off)) {
-			printk("ocfs2: skipping inode create for %u.%u\n", 
-			       HILO(feoff));
-			goto bail;
-		}
-	}
-
-	inode = ocfs_inode_hash_lookup(osb, voteoff, false);
-	if (!inode) {
-		/* we should put this guy in the hash now... */
-		LOG_TRACE_STR("calling iget4");
-
-		args.offset = feoff;
-		args.fe_bh = fe_bh;
-		args.skip_bind = 0;
-
-		/* 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, voteoff, feoff);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-		inode = ocfs_iget (sb, &args);
-#else
-		inode =
-			iget4 (sb, args.ino,
-			       (find_inode_t) ocfs_find_inode, 
-			       (void *) (&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;
-		}
-	}
-
-bail:
-	if (inode)
-		LOG_TRACE_ARGS("returning inode with number %lu\n", 
-			       inode->i_ino);
-
-	LOG_EXIT_PTR(inode);
-
-	return(inode);
-} /* ocfs_get_inode_from_offset */
-
-

Modified: trunk/src/inc/ocfs.h
===================================================================
--- trunk/src/inc/ocfs.h	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/inc/ocfs.h	2004-04-28 01:37:04 UTC (rev 872)
@@ -1758,6 +1758,10 @@
 #define OCFS_INODE_JOURNAL          0x00000002
 /* set on init_private, cleared on clear_inode */
 #define OCFS_INODE_INITIALIZED      0x00000004
+/* is this a system file? */
+#define OCFS_INODE_SYSFILE          0x00000008
+/* only valid for system files. */
+#define OCFS_INODE_NOFE             0x00000010
 
 #define GET_INODE_CLEAN_SEQ(i)  (atomic_t *)(&(OCFS_I(i)->i_clean_buffer_seq))
 
@@ -2578,12 +2582,18 @@
 
 typedef struct _ocfs_find_inode_args
 {
-	__u64 offset;
+	__u64 voteoff;
+	__u64 feoff;
 	struct buffer_head *fe_bh;
 	int skip_bind;
 	unsigned long ino;
+	__u32 flags;
 }
 ocfs_find_inode_args;
+
+#define OCFS_FIND_INODE_FLAG_SYSFILE              0x00000002
+#define OCFS_FIND_INODE_FLAG_NOFE                 0x00000008
+
 /* timeout structure taken from Ben's aio.c */
 typedef struct _ocfs_timeout {
 	struct timer_list	timer;

Modified: trunk/src/inc/proto.h
===================================================================
--- trunk/src/inc/proto.h	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/inc/proto.h	2004-04-28 01:37:04 UTC (rev 872)
@@ -32,7 +32,7 @@
 int ocfs_free_extents_for_truncate (ocfs_super * osb, ocfs_file_entry * FileEntry, ocfs_journal_handle *handle, struct inode *inode);
 int ocfs_lookup_file_allocation (ocfs_super * osb, __s64 Vbo, __s64 * Lbo, __u32 sectors, u32 *sector_count, struct inode *inode);
 int ocfs_get_leaf_extent (ocfs_super * osb, ocfs_file_entry * FileEntry, __s64 Vbo, struct buffer_head **data_extent_bh, struct inode *inode);
-int ocfs_find_contiguous_space_from_bitmap (ocfs_super * osb, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count, bool sysfile, struct buffer_head *lock_bh);
+int ocfs_find_contiguous_space_from_bitmap (ocfs_super * osb, __u64 file_size, __u64 * cluster_off, __u64 * cluster_count, bool 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);
@@ -91,11 +91,10 @@
 
 int ocfs_find_inode (struct inode *inode, unsigned long ino, void *opaque);
 int ocfs_inode_init_private(struct inode *inode);
-void ocfs_populate_inode (struct inode *inode, ocfs_file_entry *fe, umode_t mode, void *genptr, bool create_ino);
+void ocfs_populate_inode (struct inode *inode, ocfs_file_entry *fe, umode_t mode, bool create_ino);
 void ocfs_read_locked_inode (struct inode *inode, ocfs_find_inode_args *args);
 void ocfs_read_inode2 (struct inode *inode, void *opaque);
 void ocfs_read_inode (struct inode *inode);
-struct inode * ocfs_iget(struct super_block *sb, ocfs_find_inode_args *args);
 void ocfs_put_inode (struct inode *inode);
 void ocfs_clear_inode (struct inode *inode);
 int ocfs_block_symlink (struct inode *inode, const char *symname, int len);
@@ -308,9 +307,8 @@
 		      __u64 oldoff, 
 		      __u64 newoff, 
 		      __u64 new_fe_off);
-struct inode *ocfs_get_inode_from_offset(ocfs_super *osb, 
-					 __u64 voteoff, __u64 feoff, 
-					 struct buffer_head *fe_bh);
+struct inode *ocfs_iget(ocfs_super *osb, __u64 voteoff, __u64 feoff, 
+			struct buffer_head *fe_bh);
 struct inode *ocfs_inode_hash_lookup(ocfs_super *osb, 
 				     __u64 voteoff, 
 				     bool reverse);

Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/inode.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -58,6 +58,10 @@
 int ocfs_kvec_rw(struct file *filp, int rw, kvec_cb_t cb, size_t size, loff_t pos);
 #endif /* AIO_ENABLED */
 
+static void __ocfs_read_inode2(struct inode *inode, 
+			       ocfs_find_inode_args *args);
+static void ocfs_read_inode_nofe(ocfs_super *osb, struct inode *inode, 
+				 __u64 voteoff);
 
 static struct address_space_operations ocfs_aops = {
 	.readpage = ocfs_readpage,
@@ -124,7 +128,159 @@
 	follow_link:    ocfs_follow_link
 };
 
+/* 
+ * ocfs_iget()
+ *
+ * Not all fields are required, pick your poison:
+ *   * fe_bh only -- voteoff and feoff should both be zero then.
+ *   * voteoff and feoff -- fe_bh can be NULL. 
+ *     If AND ONLY IF the inode has no file entry (as in the main bitmap), 
+ *     are you allowed to have feoff = 0.
+ * 
+ *   If you give me both, I'll prefer fe_bh.
+ */
+struct inode *ocfs_iget(ocfs_super *osb, __u64 voteoff, __u64 feoff, 
+			struct buffer_head *fe_bh)
+{
+	struct inode *inode = NULL;
+	struct super_block *sb = osb->sb;
+	ocfs_file_entry *fe;
+	ocfs_find_inode_args args;
+	__u32 flags = 0;
 
+	LOG_ENTRY_ARGS("(voteoff = %u.%u, feoff = %u.%u, fe_bh = %p)\n", 
+		       HILO(voteoff), HILO(feoff), fe_bh);
+
+	/* Shortcut: if they ask for the root dirnode, just return
+	 * it. */
+	if (voteoff == osb->vol_layout.root_start_off) {
+		LOG_TRACE_ARGS("Asked for root dirnode (%u.%u)\n",
+			       HILO(feoff));
+
+		inode = osb->sb->s_root->d_inode;
+
+		/* should we iget it or not? i suppose if you're in
+		 * here and you've asked for the root inode you don't
+		 * know what it is and will prolly iput it later... */
+		if (inode) {
+			if (ocfs_inc_icount(inode) < 0)
+				BUG();
+		}
+		goto bail;
+	}
+
+	/* This shouldn't happen anymore. */
+	if (osb->vol_layout.root_start_off == 0) {
+		LOG_ERROR_ARGS("root_start_off = 0! Skipping inode create for "
+		       "%u.%u, %u.%u\n", HILO(voteoff), HILO(feoff));
+		goto bail;
+	}
+
+	/* Ok, lets try to be smart here. We need a very specific set
+	 * of arguments to get our inode. Figure these out from the
+	 * available data. */
+	if (fe_bh) {
+		/* best case -- we can figure out what we need from
+		 * the file entry! */
+		fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh);
+		if (!IS_VALID_FILE_ENTRY(fe)) {
+			OCFS_BH_PUT_DATA(fe_bh);
+			LOG_ERROR_STATUS(-EINVAL);
+			goto bail;
+		}
+		feoff = fe->this_sector;
+		/* need voteoff too. */
+		if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
+			voteoff = fe->extents[0].disk_off;
+		else
+			voteoff = fe->this_sector;
+		OCFS_BH_PUT_DATA(fe_bh);
+	}
+
+	/* Ok. By now we've either got the offsets passed to us by the
+	 * caller, or we just pulled them off the bh. Lets do some
+	 * sanity checks to make sure they're OK. */
+	if (voteoff == 0) {
+		LOG_ERROR_STATUS(-EINVAL);
+		goto bail;
+	}
+
+	/* feoff = 0 is only valid for root inode and other system files. */
+	if ((feoff == 0) && (voteoff > osb->vol_layout.root_start_off)) {
+		LOG_ERROR_STATUS(-EINVAL);
+		goto bail;
+	}
+
+	/* try to detect whether this is a system file. */
+	if (feoff < osb->vol_layout.root_start_off) {
+		flags |= OCFS_FIND_INODE_FLAG_SYSFILE;
+
+		/* We're not done yet. Some sysfiles (ok, currently
+		 * only the main bitmap sysfile) don't have a file
+		 * entry. Figure out whether we're one of those. */
+		if (voteoff == OCFS_BITMAP_LOCK_OFFSET)
+			flags |= OCFS_FIND_INODE_FLAG_NOFE;
+	}
+
+	inode = ocfs_inode_hash_lookup(osb, voteoff, false);
+	if (!inode) {
+		/* we should put this guy in the hash now... */
+		LOG_TRACE_STR("calling iget4");
+
+		args.feoff = feoff;
+		args.voteoff = voteoff;
+		args.fe_bh = fe_bh;
+		args.skip_bind = 0;
+		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, voteoff, feoff);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+		inode = iget5_locked (sb, args->ino, ocfs_find_actor, 
+				      ocfs_init_locked_inode, args);
+#else
+		inode =
+			iget4 (sb, args.ino,
+			       (find_inode_t) ocfs_find_inode, 
+			       (void *) (&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;
+		}
+	}
+
+bail:
+	if (inode) {
+		LOG_TRACE_ARGS("returning inode with number %lu\n", 
+			       inode->i_ino);
+#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
+		 * afterwards. */
+		if (inode->i_state & I_NEW) {
+			LOG_TRACE_STR("Inode was not in inode cache, reading "
+				      "it.");
+			ocfs_read_locked_inode(inode, args);
+			unlock_new_inode(inode);
+		}
+#endif
+	}
+
+	LOG_EXIT_PTR(inode);
+
+	return(inode);
+} /* ocfs_iget */
+
 /*
  * here's how inodes get read from disk:
  * iget4 -> find_inode -> OCFS_FIND_INODE
@@ -157,7 +313,8 @@
 	if (ino != inode->i_ino)
 		goto bail;
 
-	if (GET_INODE_FEOFF(inode) != args->offset) {
+	if ((GET_INODE_FEOFF(inode) != args->feoff) 
+	    || (GET_INODE_VOTEOFF(inode) != args->feoff)) {
 		LOG_ERROR_STATUS(-EINVAL);
 		goto bail;
 	}
@@ -189,15 +346,10 @@
 		return -ENOMEM;
 
 	i = (ocfs_inode_private *) inode->u.generic_ip;
-
 	memset(i, 0, sizeof(ocfs_inode_private));
 
 	i->flags = 0;
 	atomic_set(&i->i_clean_buffer_seq, 0);
-
-	/* Init old OIN stuff. */
-//	oin->obj_id.type = OCFS_TYPE_OIN;
-//	oin->obj_id.size = sizeof (ocfs_inode);
 	ocfs_init_sem (&(i->main_res));
 	init_MUTEX(&(i->inode_extend_sem));
 	i->open_hndl_cnt = 0;
@@ -217,7 +369,7 @@
  * ocfs_populate_inode()
  *
  */
-void ocfs_populate_inode (struct inode *inode, ocfs_file_entry *fe, umode_t mode, void *genptr, bool create_ino)
+void ocfs_populate_inode (struct inode *inode, ocfs_file_entry *fe, umode_t mode, bool create_ino)
 {
 	struct super_block *sb;
 	ocfs_super *osb;
@@ -314,143 +466,135 @@
  */
 void ocfs_read_locked_inode (struct inode *inode, ocfs_find_inode_args *args)
 {
-	struct super_block *sb;
-	ocfs_super *osb;
-	umode_t mode;
-	__u64 voteoff;
-	ocfs_file_entry *fe = NULL;
-	struct buffer_head *bh = NULL;
-	int status;
+	__ocfs_read_inode2(inode, args);
+	return;
+}				/* ocfs_read_locked_inode */
 
-	LOG_ENTRY_ARGS ("(%p, %p)\n", inode, args);
+#else
 
-	if (inode == NULL || inode->i_sb == NULL) {
-		LOG_ERROR_STR ("bad inode");
-		goto bail;
-	}
-	sb = inode->i_sb;
-	osb = ((ocfs_super *)(sb->s_fs_info));
-	LOG_TRACE_ARGS("osb = %x\n", osb);
-	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
-		LOG_TRACE_ARGS("Populating root inode (i_ino = %lu)\n", inode->i_ino);
-		if (!inode->u.generic_ip && ocfs_inode_init_private(inode)) {
-			/* How can we recover gracefully? */
-			LOG_ERROR_STR("unable to allocate private data for inode");
-			goto bail;
-		}
+/*
+ * ocfs_read_inode2()
+ *
+ * by this point, i_sb, i_dev, i_ino are filled in
+ *
+ */
+void ocfs_read_inode2 (struct inode *inode, void *opaque)
+{
+	__ocfs_read_inode2(inode, (ocfs_find_inode_args *) opaque);
+	return;
+}				/* ocfs_read_inode2 */
 
-		inode->i_mode = S_IFDIR | osb->vol_layout.prot_bits;
-		inode->i_blksize = 512;	/* TODO: fix */
-		inode->i_blkbits = 9;
-		inode->i_blocks = 0;
-		inode->i_mapping->a_ops = &ocfs_aops;
-		inode->i_atime = CURRENT_TIME;
-		inode->i_mtime = CURRENT_TIME;
-		inode->i_ctime = CURRENT_TIME;
-		inode->i_flags |= S_NOATIME;
-		inode->i_op = &ocfs_dir_iops;
-		inode->i_fop = &ocfs_dops;
-		inode->i_uid = osb->vol_layout.uid;
-		inode->i_gid = osb->vol_layout.gid;
-		SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
-		SET_INODE_FEOFF(inode, 0);
+/*
+ * ocfs_read_inode()
+ * Only used in Linux 2.4
+ */
+void ocfs_read_inode (struct inode *inode)
+{
+	make_bad_inode (inode);
+}				/* ocfs_read_inode() */
+#endif
 
-		OCFS_I(inode)->alloc_size = 0ULL;
-		OCFS_I(inode)->inode = inode;
-		OCFS_I(inode)->chng_seq_num = 0ULL;
-		OCFS_I(inode)->oin_flags |= OCFS_OIN_DIRECTORY;
+/* ocfs_read_inode_nofe() 
+ *
+ * This function is ugly. Because we haven't got any file entries to
+ * look at, we have to special case every single offset. 
+ *
+ * Right now, the only inodes this function knows about are:
+ *  - root inode
+ *  - volume bitmap inode 
+ */
+static void ocfs_read_inode_nofe(ocfs_super *osb, struct inode *inode, 
+				 __u64 voteoff)
+{
+	LOG_ENTRY();
 
-		ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
-		goto bail;
+	/* add other offsets to this 'if' as needed. */
+	if (voteoff != OCFS_BITMAP_LOCK_OFFSET 
+	    && voteoff != osb->vol_layout.root_start_off) {
+		printk("ocfs2: yowzah! Asked to create an inode for offset"
+		       "%u.%u, but I haven't yet learned what to do!\n", 
+		       HILO(voteoff));
+
+		BUG();
 	}
 
-	LOG_TRACE_ARGS("Populating non-root inode (i_ino = %lu)\n", inode->i_ino);
-
-	if (!args) {
-		make_bad_inode (inode);
+	if (!inode->u.generic_ip && ocfs_inode_init_private(inode)) {
+		/* How can we recover gracefully? */
+		LOG_ERROR_STR("unable to allocate private data for inode");
 		goto bail;
 	}
 
-	/* Uhoh, they didn't give us a buffer. Read the FE off
-	 * disk. This is safe because the kernel only does one
-	 * read_inode2 for a new inode, and if it doesn't exist yet
-	 * then nobody can be working on it! */
-	if (!args->fe_bh) {
-		status = ocfs_read_bh(osb, args->offset, &bh, 0, NULL);
-		if (status < 0) {
-			LOG_ERROR_STATUS(status);
-			make_bad_inode (inode);
-			goto bail;
-		}
-	} else
-		bh = args->fe_bh;
+	/* Initialize common fields, then do the specific ones below. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+	/* why is this different from 2.4!?!*/
+	inode->i_blksize = 512;
+	inode->i_blkbits = 9;
+#else
+	inode->i_blksize = (__u32) osb->vol_layout.cluster_size;
+	inode->i_attr_flags |= ATTR_FLAG_NOATIME;
+#endif
+	inode->i_mapping->a_ops = &ocfs_aops;
+	inode->i_atime = CURRENT_TIME;
+	inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME;
+	inode->i_flags |= S_NOATIME;
+	inode->i_uid = osb->vol_layout.uid;
+	inode->i_gid = osb->vol_layout.gid;
+	SET_INODE_FEOFF(inode, 0);
 
-	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(bh);
-	
-	mode = fe->prot_bits;
-	switch (fe->attribs) {
-	    case OCFS_ATTRIB_DIRECTORY:
-		    mode |= S_IFDIR;
-		    break;
-	    case OCFS_ATTRIB_CHAR:
-		    inode->i_rdev = MKDEV (fe->dev_major, fe->dev_minor);
-		    mode |= S_IFCHR;
-		    break;
-	    case OCFS_ATTRIB_BLOCK:
-		    inode->i_rdev = MKDEV (fe->dev_major, fe->dev_minor);
-		    mode |= S_IFBLK;
-		    break;
-	    case OCFS_ATTRIB_FIFO:
-		    mode |= S_IFIFO;
-		    break;
-	    case OCFS_ATTRIB_SYMLINK:
-		    mode |= S_IFLNK;
-		    break;
-	    case OCFS_ATTRIB_SOCKET:
-		    mode |= S_IFSOCK;
-		    break;
-	    case OCFS_ATTRIB_REG:
-	    default:
-		    mode |= S_IFREG;
-		    break;
-	}
-	ocfs_populate_inode (inode, fe, mode, NULL, false);
+	OCFS_I(inode)->inode = inode;
+	OCFS_I(inode)->chng_seq_num = 0ULL;
 
-	voteoff = S_ISDIR (mode) ? fe->extents[0].disk_off : fe->this_sector;
-	if (!args->skip_bind)
-		ocfs_inode_hash_bind(osb, voteoff, inode);
+	OCFS_SET_FLAG(OCFS_I(inode)->flags, OCFS_INODE_NOFE);
 
-bail:
-	if (fe)
-		OCFS_BH_PUT_DATA(bh);
+	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
+		inode->i_mode = S_IFDIR | osb->vol_layout.prot_bits;
 
-	if (args && !args->fe_bh && bh)
-		brelse(bh);
+		inode->i_op = &ocfs_dir_iops;
+		inode->i_fop = &ocfs_dops;
+		OCFS_I(inode)->oin_flags |= OCFS_OIN_DIRECTORY;
+		OCFS_I(inode)->alloc_size = 0ULL;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+		inode->i_blocks = 0;
+#else
+		inode->i_blocks = OCFS_DEFAULT_DIR_NODE_SIZE;
+		inode->i_size = OCFS_DEFAULT_DIR_NODE_SIZE;
+#endif
+		SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
+	} else  /* volume bitmap inode */ {
+		inode->i_mode = S_IFREG | osb->vol_layout.prot_bits;
 
-	LOG_EXIT ();
+		/* i_op and f_op should prolly be something a bit more
+		 * appropriate. */
+		inode->i_op = &ocfs_file_iops;
+		inode->i_fop = &ocfs_fops;
+		OCFS_I(inode)->oin_flags = 0;
+		OCFS_I(inode)->alloc_size = ONE_MEGA_BYTE;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+		inode->i_blocks = 0;
+#else
+		inode->i_blocks = ONE_MEGA_BYTE / OCFS_BITMAP_CHUNK;
+		inode->i_size = ONE_MEGA_BYTE;
+#endif
+		SET_INODE_VOTEOFF(inode, OCFS_BITMAP_LOCK_OFFSET);
+	}
+
+bail:
+	LOG_EXIT();
 	return;
-}				/* ocfs_read_locked_inode */
+}
 
-#else
-
-/*
- * ocfs_read_inode2()
- *
- * by this point, i_sb, i_dev, i_ino are filled in
- *
- */
-void ocfs_read_inode2 (struct inode *inode, void *opaque)
+static void __ocfs_read_inode2(struct inode *inode, ocfs_find_inode_args *args)
 {
 	struct super_block *sb;
-	ocfs_find_inode_args *args = NULL;
 	ocfs_super *osb;
 	umode_t mode;
+	__u64 voteoff;
 	ocfs_file_entry *fe = NULL;
-	__u64 voteoff;
 	struct buffer_head *bh = NULL;
 	int status;
 
-	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", inode, opaque);
+	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", inode, args);
 
 	if (inode == NULL || inode->i_sb == NULL) {
 		LOG_ERROR_STR ("bad inode");
@@ -459,53 +603,35 @@
 	sb = inode->i_sb;
 	osb = (ocfs_super *) OCFS_GENERIC_SB_P(sb);
 	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
-		if (!inode->u.generic_ip && ocfs_inode_init_private(inode)) {
-			/* How can we recover gracefully? */
-			LOG_ERROR_STR("unable to allocate private data for inode");
-			goto bail;
-		}
+		ocfs_read_inode_nofe(osb, inode, 
+				     osb->vol_layout.root_start_off);
 
-		inode->i_mode = S_IFDIR | osb->vol_layout.prot_bits;
-		inode->i_blksize = (__u32) osb->vol_layout.cluster_size;
-		inode->i_size = OCFS_DEFAULT_DIR_NODE_SIZE;
-		inode->i_blocks = OCFS_DEFAULT_DIR_NODE_SIZE;
-		inode->i_mapping->a_ops = &ocfs_aops;
-		inode->i_atime = OCFS_CURRENT_TIME;
-		inode->i_attr_flags |= ATTR_FLAG_NOATIME;
-		inode->i_flags |= S_NOATIME;
-		inode->i_mtime = OCFS_CURRENT_TIME;
-		inode->i_ctime = OCFS_CURRENT_TIME;
-		inode->i_attr_flags |= ATTR_FLAG_NOATIME;
-		inode->i_flags |= S_NOATIME;
-		inode->i_op = &ocfs_dir_iops;
-		inode->i_fop = &ocfs_dops;
-		inode->i_uid = osb->vol_layout.uid;
-		inode->i_gid = osb->vol_layout.gid;
-		SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
-		SET_INODE_FEOFF(inode, 0);
+		/* should I set the sysfile flag or not? */
+		OCFS_SET_FLAG(OCFS_I(inode)->flags, OCFS_INODE_SYSFILE);
 
-		OCFS_I(inode)->alloc_size = 0ULL;
-		OCFS_I(inode)->inode = inode;
-		OCFS_I(inode)->chng_seq_num = 0ULL;
-		OCFS_I(inode)->oin_flags |= OCFS_OIN_DIRECTORY;
-
 		ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
 		goto bail;
 	}
 
-	if (opaque == NULL) {
+	if (!args) {
+		LOG_ERROR_STR("bad inode args");
 		make_bad_inode (inode);
 		goto bail;
 	}
 
-	args = (ocfs_find_inode_args *) opaque;
+	voteoff = args->voteoff;
 
+	if (args->flags & OCFS_FIND_INODE_FLAG_NOFE) {
+		ocfs_read_inode_nofe(osb, inode, args->voteoff);
+		goto skip_fe;
+	}
+
 	/* Uhoh, they didn't give us a buffer. Read the FE off
 	 * disk. This is safe because the kernel only does one
 	 * read_inode2 for a new inode, and if it doesn't exist yet
 	 * then nobody can be working on it! */
 	if (!args->fe_bh) {
-		status = ocfs_read_bh(osb, args->offset, &bh, 0, NULL);
+		status = ocfs_read_bh(osb, args->feoff, &bh, 0, NULL);
 		if (status < 0) {
 			LOG_ERROR_STATUS(status);
 			make_bad_inode (inode);
@@ -544,9 +670,17 @@
 		    mode |= S_IFREG;
 		    break;
 	}
-	ocfs_populate_inode (inode, fe, mode, NULL, false);
+	ocfs_populate_inode (inode, fe, mode, false);
 
 	voteoff = S_ISDIR (mode) ? fe->extents[0].disk_off : fe->this_sector;
+
+	if (voteoff != args->voteoff)
+		BUG();
+
+skip_fe:
+	if (args->flags & OCFS_FIND_INODE_FLAG_SYSFILE)
+		OCFS_SET_FLAG(OCFS_I(inode)->flags, OCFS_INODE_SYSFILE);
+
 	if (!args->skip_bind)
 		ocfs_inode_hash_bind(osb, voteoff, inode);
 
@@ -559,18 +693,8 @@
 
 	LOG_EXIT ();
 	return;
-}				/* ocfs_read_inode2 */
+}
 
-/*
- * ocfs_read_inode()
- * Only used in Linux 2.4
- */
-void ocfs_read_inode (struct inode *inode)
-{
-	make_bad_inode (inode);
-}				/* ocfs_read_inode() */
-#endif
-
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 /*
  * here's how inodes get read from disk:
@@ -603,7 +727,8 @@
 		goto bail;
 	args = (ocfs_find_inode_args *) opaque;
 
-	if (GET_INODE_FEOFF(inode) != args->offset) {
+	if ((GET_INODE_FEOFF(inode) != args->feoff) 
+	    || (GET_INODE_VOTEOFF(inode) != args->voteoff)) {
 		LOG_ERROR_STATUS(-EINVAL);
 		goto bail;
 	}
@@ -642,51 +767,6 @@
 	return(ret);
 }
 
-/*
- * ocfs_iget()
- *
- *  expects sb and args to be already filled out.
- *  specifically, need fe->extents[0].disk_off, args->offset
- *  if we're called from ocfs_fill_super, args == NULL
- */
-struct inode * ocfs_iget(struct super_block *sb, ocfs_find_inode_args *args) 
-{
-	struct inode *inode = NULL;
-
-	LOG_ENTRY();
-
-	if (!sb)
-		goto bail;
-
-	/* if args == NULL, we want the root inode */
-	if (!args) {
-		LOG_TRACE_STR("looking for root inode");
-		inode = iget5_locked(sb, OCFS_ROOT_INODE_NUMBER, 
-				     ocfs_find_actor, ocfs_init_locked_inode, 
-				     NULL);
-	} else {
-		LOG_TRACE_STR("looking for non-root inode");
-		/* Need to verify that ocfs_find_inode does the right thing,
-		 * and need to actually write ocfs_init_inode */
-		inode = iget5_locked(sb, args->ino, ocfs_find_actor,
-				     ocfs_init_locked_inode, args);
-	}
-
-	if (!inode)
-		goto bail;
-
-	/* inode was *not* in the inode cache */
-	if (inode->i_state & I_NEW) {
-		LOG_TRACE_STR("Inode was not in inode cache, reading it.");
-		ocfs_read_locked_inode(inode, args);
-		unlock_new_inode(inode);
-	}
-
-bail:
-	LOG_EXIT_PTR(inode);
-	return(inode);
-}
-
 #endif /* 2.6 kernel stuff */
 
 

Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/journal.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -847,7 +847,7 @@
 		  osb->vol_layout.root_int_off;
 
 	/* Ok, look up the inode for our journal */
-	inode = ocfs_get_inode_from_offset(osb, lock_id, lock_id, NULL);
+	inode = ocfs_iget(osb, lock_id, lock_id, NULL);
 	if (inode == NULL) {
 		LOG_ERROR_STR("access error");
 		status = -EACCES;
@@ -1026,7 +1026,7 @@
 	status = ocfs_release_lock (osb, journal->lock_id,
 				    OCFS_DLM_EXCLUSIVE_LOCK,
 				    FLAG_FILE_CREATE, journal->lock_res,
-				    journal->lockbh, NULL);
+				    journal->lockbh, inode);
 	if (status < 0)
 		LOG_ERROR_STATUS (status);
 	
@@ -1416,7 +1416,7 @@
 		+ osb->vol_layout.root_int_off;
 
 	/* Ok, look up the inode for our journal */
-	inode = ocfs_get_inode_from_offset(osb, lock_id, lock_id, NULL);
+	inode = ocfs_iget(osb, lock_id, lock_id, NULL);
 	if (inode == NULL) {
 		LOG_ERROR_STR("access error");
 		status = -EACCES;
@@ -1529,9 +1529,6 @@
 	CLEAR_NODE_IN_RECOVERY(osb, node_num);
 	ocfs_recover_oin_locks(osb, node_num);
 done:
-	if (inode)
-		iput(inode);
-
 	if (recovery_lock)
 		up(&(osb->recovery_lock));
 
@@ -1540,7 +1537,10 @@
 		status = ocfs_release_lock(osb, lock_id, 
 					   OCFS_DLM_EXCLUSIVE_LOCK, 
 					   FLAG_FILE_CREATE|FLAG_FILE_RECOVERY,
-					   lockres, bh, NULL);
+					   lockres, bh, inode);
+	if (inode)
+		iput(inode);
+
 	if (bh)
 		brelse(bh);
 

Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/namei.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -65,15 +65,13 @@
 #endif
 {
 	int status;
-	ocfs_find_inode_args args;
 	ocfs_file_entry *fe = NULL;
 	struct buffer_head *fe_bh = NULL;
-	__u64 parentOffset, fe_off;
+	__u64 parentOffset;
 	struct inode *inode = NULL;
 	struct super_block *sb = dir->i_sb;
 	struct dentry *ret;
 	ocfs_super *osb = (ocfs_super *) OCFS_GENERIC_SB_P(sb);
-	__u64 inode_off;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", dir, dentry,
                         dentry->d_name.len, dentry->d_name.name);
@@ -99,47 +97,13 @@
 		       parentOffset, dentry->d_name.len, dentry->d_name.name);
 		BUG();
 	}
-
-	args.offset = fe->this_sector;
-	args.fe_bh = fe_bh;
-	args.skip_bind = 0;
-	if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
-		inode_off = fe->extents[0].disk_off;
-	else
-		inode_off = fe->this_sector;
-	fe_off = fe->this_sector;
 	OCFS_BH_PUT_DATA(fe_bh);
-	fe = NULL;
 
-	/* first, check if we've already got an inode in the hash. */
-	inode = ocfs_inode_hash_lookup(osb, inode_off, false);
+	inode = ocfs_iget(osb, 0, 0, fe_bh);
 	if (!inode) {
-		/* we should put this guy in the hash now... */
-		LOG_TRACE_STR("calling iget4");
-		/* 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, inode_off, fe_off);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-		inode = ocfs_iget (sb, &args);
-#else
-		inode =
-			iget4 (sb, args.ino,
-			       (find_inode_t) ocfs_find_inode, 
-			       (void *) (&args));
-#endif
-		if (inode == NULL) {
-			LOG_ERROR_STR("access error");
-			ret = ERR_PTR (-EACCES);
-			goto bail;
-		}
-		if (is_bad_inode (inode)) {
-			LOG_ERROR_STR("access error (bad inode)");
-			iput (inode);
-			inode = NULL;
-			ret = ERR_PTR (-EACCES);
-			goto bail;
-		}
+		LOG_ERROR_STR("Could not create inode!");
+		ret = ERR_PTR (-EACCES);
+		goto bail;
 	}
 
 bail_add:
@@ -238,7 +202,7 @@
 
 	parent_off = GET_INODE_VOTEOFF(dir);
 
-	ocfs_populate_inode (inode, fe, mode, NULL, true);
+	ocfs_populate_inode (inode, fe, mode, true);
 	insert_inode_hash (inode);
 	ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
 
@@ -1438,7 +1402,7 @@
 	inode->i_rdev = OCFS_NODEV;
 
 	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(new_fe_bh); /* read */
-	ocfs_populate_inode (inode, fe, S_IFLNK | S_IRWXUGO, NULL, true);
+	ocfs_populate_inode (inode, fe, S_IFLNK | S_IRWXUGO, true);
 	OCFS_BH_PUT_DATA(new_fe_bh);
 	fe = NULL;
 

Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/nm.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -809,7 +809,6 @@
 	__u32 node_num = ctxt->node_num;
 	__u64 lock_id, seq_num, fe_off;
 	int needs_trunc = 0;
-	bool sysfile = false;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", osb, ctxt);
 
@@ -848,7 +847,7 @@
 	if ((flags & (FLAG_FILE_DELETE | FLAG_FILE_RENAME)) && (flags & FLAG_RELEASE_LOCK))
 		inode = NULL;
 	else
-		inode = ocfs_get_inode_from_offset(osb, lock_id, fe_off, NULL);
+		inode = ocfs_iget(osb, lock_id, fe_off, NULL);
 
 	if (inode) {
 		/* we only need i_sem for some of the operations
@@ -857,8 +856,6 @@
 		down(&inode->i_sem);
 		have_i_sem = true;
 	}
-	sysfile = (lock_id <= osb->vol_layout.root_start_off) ||
-		((fe_off != 0) && (fe_off < osb->vol_layout.root_start_off));
 
 	if (disk_vote) {
 		offset = osb->vol_layout.vote_sect_off + (osb->node_num * osb->sect_size);
@@ -894,8 +891,6 @@
 	       (flags & FLAG_ACQUIRE_LOCK ? "ACQUIRE" : "MODIFY"), HILO(lock_id), HILO(fe_off),
 	       vote_type, process_vote_strings[vote_type], disk_vote ? "disk vote" : "net vote" );
 #endif
-	if (!inode && !sysfile)
-		LOG_ERROR_ARGS("No Inode available for non sysfile!\n");
 	/* get_process_vote_action will only allow CHANGE_MASTER, RELEASE_CACHE, and
 	 * ADD_OIN_MAP on a CACHE lock held by this node.  the CHANGE_MASTER/RELEASE_CACHE
 	 * path needs to check the readonly map to see if any nodes need to be updated.  this

Modified: trunk/src/oin.c
===================================================================
--- trunk/src/oin.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/oin.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -265,7 +265,6 @@
 	int status = 0;
 	ocfs_file_entry *fe = NULL;
 	bool local_handle = true;
-	__u32 flags = 0;
 
 	LOG_ENTRY ();
 
@@ -282,8 +281,6 @@
 
 	OCFS_BH_PUT_DATA(fe_bh);
 
-	flags |= OCFS_I(inode)->oin_flags;
-
 	if (inode->i_ino != OCFS_ROOT_INODE_NUMBER) {
 		if (local_handle) {
 			handle = ocfs_start_trans(osb, OCFS_OPEN_CREDITS);
@@ -297,7 +294,8 @@
 		}
 
 		status = ocfs_create_update_lock(osb, GET_INODE_VOTEOFF(inode),
-						 flags, false, inode, handle);
+						 OCFS_I(inode)->oin_flags, 
+						 false, inode, handle);
 		if (status < 0) {
 			if (status != -EINTR)
 				LOG_ERROR_STATUS (status);
@@ -319,7 +317,7 @@
 
 
 
-/* ocfs_create_oin_from_entry()
+/* ocfs_inode_fill_ext_map()
  *
  */
 int ocfs_inode_fill_ext_map(ocfs_super * osb, struct buffer_head * fe_bh, struct inode *inode)
@@ -447,4 +445,4 @@
 
 	LOG_EXIT_STATUS (status);
 	return status;
-}				/* ocfs_create_oin_from_entry */
+}				/* ocfs_inode_fill_ext_map */

Modified: trunk/src/osb.c
===================================================================
--- trunk/src/osb.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/osb.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -393,7 +393,6 @@
 		}
 	}
 
-skip_load:
 	/* 'mounted' flag in publish sector should not be set until
 	 * after we successfully load the journal. */
 	status = ocfs_journal_set_mounted(osb, osb->node_num);

Modified: trunk/src/super.c
===================================================================
--- trunk/src/super.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/super.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -142,6 +142,8 @@
 static int ocfs_statfs (struct super_block *sb, struct statfs *buf);
 #endif
 
+static int ocfs_init_system_inodes(ocfs_super *osb);
+
 static struct super_operations ocfs_sops = {
 	.statfs = ocfs_statfs,
 	.put_inode = ocfs_put_inode,
@@ -178,6 +180,71 @@
 }
 
 /*
+ * ocfs_init_system_inodes()
+ */
+static int ocfs_init_system_inodes(ocfs_super *osb)
+{
+	struct inode *new = NULL;
+	__u64 sys_off = 0;
+	int status = 0;
+
+	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, 0, NULL);
+	if (!new) {
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+	iput(new);
+
+	/* file alloc bitmap */
+	sys_off = osb->vol_layout.root_int_off + 
+		((OCFS_FILE_FILE_ALLOC_BITMAP + osb->node_num) 
+		 * osb->sect_size);
+	new = ocfs_iget(osb, sys_off, sys_off, NULL);
+	if (!new) {
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+	iput(new);
+
+	/* dir alloc bitmap */
+	sys_off = osb->vol_layout.root_int_off + 
+		((OCFS_FILE_DIR_ALLOC_BITMAP + osb->node_num) 
+		 * osb->sect_size);
+	new = ocfs_iget(osb, sys_off, sys_off, NULL);
+	if (!new) {
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+	iput(new);
+
+	/* journal file */
+	sys_off = osb->vol_layout.root_int_off + 
+		((OCFS_JOURNAL_FILE + osb->node_num) * osb->sect_size);
+	new = ocfs_iget(osb, sys_off, sys_off, NULL);
+	if (!new) {
+		status = -EINVAL;
+		LOG_ERROR_STATUS(status);
+		goto bail;
+	}
+	iput(new);
+
+bail:
+	LOG_EXIT_STATUS(status);
+	return(status);
+} /* ocfs_init_system_inodes */
+
+/*
  * __ocfs_read_super()
  *
  */
@@ -240,6 +307,12 @@
 
 	sb->s_root = root;
 
+	status = ocfs_init_system_inodes(osb);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto read_super_error;
+	}
+
 	printk ("ocfs2: Mounting device (%u,%u) on %s (node %d)\n",
 		MAJOR(sb->s_dev), MINOR(sb->s_dev),
 		osb->node_cfg_info[osb->node_num]->node_name, osb->node_num);
@@ -927,9 +1000,11 @@
 	up (&(osb->osb_res));
 
 	/* Initialize the root inode. */
+	/* We need a better way of getting our root inode during startup. */
 	ocfs_inode_hash_insert(osb, osb->vol_layout.root_start_off, 0ULL);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)	
-	inode = ocfs_iget(sb, NULL);
+	inode = iget5_locked(sb, OCFS_ROOT_INODE_NUMBER, 
+			     ocfs_find_actor, ocfs_init_locked_inode, NULL);
 #else
 	inode = iget4(sb, OCFS_ROOT_INODE_NUMBER, 0, NULL);
 #endif
@@ -945,6 +1020,14 @@
 		inode = NULL;
 		goto leave;
 	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+	if (inode->i_state & I_NEW) {
+		ocfs_read_locked_inode(inode, NULL);
+		unlock_new_inode(inode);
+	}
+#endif
+
 	osb->root_inode = inode;
 
 	/* Read the publish sector for this node and cleanup dirent being */

Modified: trunk/src/sysfile.c
===================================================================
--- trunk/src/sysfile.c	2004-04-28 00:11:13 UTC (rev 871)
+++ trunk/src/sysfile.c	2004-04-28 01:37:04 UTC (rev 872)
@@ -312,7 +312,7 @@
 						   FileSize - alloc_size,
 						   &BitmapOffset,
 						   &numClusterAlloc, true, 
-						   NULL);
+						   NULL, NULL);
 		if (status < 0) {
 			LOG_ERROR_STATUS (status);
 			goto leave;



More information about the Ocfs2-commits mailing list