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

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Fri Apr 16 18:38:57 CDT 2004


Author: mfasheh
Date: 2004-04-16 17:38:55 -0500 (Fri, 16 Apr 2004)
New Revision: 847

Modified:
   trunk/src/alloc.c
   trunk/src/dcache.c
   trunk/src/dlm.c
   trunk/src/extmap.c
   trunk/src/file.c
   trunk/src/hash.c
   trunk/src/inc/journal.h
   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/super.c
   trunk/src/sysfile.c
Log:
* Merge my nooin branch from r831 to r846 back into trunk



Modified: trunk/src/alloc.c
===================================================================
--- trunk/src/alloc.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/alloc.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -1159,7 +1159,7 @@
  * ocfs_allocate_extent()
  *
  */
-int ocfs_allocate_extent (ocfs_super * osb, ocfs_inode * oin, struct buffer_head *fe_bh, ocfs_journal_handle *handle, __u64 actualDiskOffset, __u64 actualLength, struct inode *inode)
+int ocfs_allocate_extent (ocfs_super * osb, struct buffer_head *fe_bh, ocfs_journal_handle *handle, __u64 actualDiskOffset, __u64 actualLength, struct inode *inode)
 {
 	int status = 0;
 	bool IncreaseTreeDepth = false;
@@ -1169,9 +1169,13 @@
 	bool UpdateParent = false;
 	__u64 newExtentOff, up_ptr;
 	ocfs_file_entry * FileEntry = NULL;
+	ocfs_inode *oin = NULL;
 
 	LOG_ENTRY_ARGS("(actualDiskOffset=%u.%u, actualLength=%u.%u)\n", actualDiskOffset, actualLength);
 
+	if (inode)
+		oin = GET_INODE_OIN(inode);
+
 	FileEntry = (ocfs_file_entry *)OCFS_BH_GET_DATA_WRITE(fe_bh);  /* write */
 	OCFS_ASSERT (FileEntry);
 
@@ -2459,7 +2463,7 @@
  * decoded and updated in the extent map.
  *
  */
-int ocfs_lookup_file_allocation (ocfs_super * osb, ocfs_inode * oin, __s64 Vbo, __s64 * Lbo, __u32 sectors, u32 *sector_count, struct inode *inode)
+int ocfs_lookup_file_allocation (ocfs_super * osb, __s64 Vbo, __s64 * Lbo, __u32 sectors, u32 *sector_count, struct inode *inode)
 {
 	int status = -EFAIL;
 	ocfs_file_entry *fe = NULL;
@@ -2471,13 +2475,15 @@
 	__s64 localVbo;
 	__u64 cnt;
 	__u32 NumIndex;
+	ocfs_inode *oin = NULL;
 
 	LOG_ENTRY ();
 
 	OCFS_ASSERT (osb);
-	OCFS_ASSERT (oin);
+	OCFS_ASSERT (inode);
+	oin = GET_INODE_OIN(inode);
 
-	if (oin->journal_inode || Vbo < oin->alloc_size) {
+	if (INODE_JOURNAL(inode) || Vbo < oin->alloc_size) {
 		if (ocfs_lookup_extent_map_entry (osb, &(oin->map), 
 			   Vbo, Lbo, &cnt, &NumIndex) && cnt >= sectors) {
 			status = 0;
@@ -2485,8 +2491,6 @@
 		}
 	}
 
-	OCFS_ASSERT (inode);
-
 	remainingLength = sectors;
 	localVbo = Vbo;
 	    		
@@ -2507,7 +2511,7 @@
 		goto finally;
 	}
 
-	if (!oin->journal_inode && Vbo >= (__s64) fe->alloc_size) {
+	if (!INODE_JOURNAL(inode) && Vbo >= (__s64) fe->alloc_size) {
 		LOG_ERROR_ARGS ("vbo=%u.%u, fe->alloc_sz=%u.%u oin->alloc_size=%u.%u", 
 				HILO (Vbo), HILO (fe->alloc_size),
 				HILO (oin->alloc_size));
@@ -3115,7 +3119,7 @@
 		ocfs_journal_add_lock(handle, lockId, 
 				      OCFS_DLM_EXCLUSIVE_LOCK, 
 				      FLAG_FILE_CREATE, 
-				      pLockResource, bh);
+				      pLockResource, bh, NULL);
 		tmpstat = 0;
 	} else 	if (bLockAcquired) {
 		tmpstat =

Modified: trunk/src/dcache.c
===================================================================
--- trunk/src/dcache.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/dcache.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -97,8 +97,8 @@
                 /* hit the disk */
                 /* TODO: optimize */
 		ocfs_down_sem (&(oin->main_res), true);
-		oin->needs_verification = true;
-		tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
+		OCFS_I(inode)->needs_verification = true;
+		tmpstat = ocfs_verify_update_inode(osb, inode, &needs_trunc);
 		if (tmpstat < 0)
 			LOG_ERROR_STATUS (tmpstat);
 		ocfs_up_sem (&(oin->main_res));

Modified: trunk/src/dlm.c
===================================================================
--- trunk/src/dlm.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/dlm.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -35,47 +35,26 @@
 
 int new_lock_function(ocfs_super * osb, __u32 requested_lock, __u32 flags, ocfs_lock_res * lockres, struct buffer_head *bh, bool *disk_vote, struct inode *inode);
 
-static inline int ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres);
+static inline int ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode);
 
-static int ocfs_insert_cache_link (ocfs_super * osb, ocfs_lock_res * lockres);
-static int ocfs_send_dlm_request_msg (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, __u64 vote_map);
+static int ocfs_send_dlm_request_msg (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, __u64 vote_map, struct inode *inode);
 static int ocfs_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num, struct inode *inode);
 static int ocfs_wait_for_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u32 time_to_wait, __u64 lock_seq_num, ocfs_lock_res * lockres);
 static int ocfs_reset_voting (ocfs_super * osb);
 static int ocfs_wait_for_lock_release (ocfs_super * osb, __u64 offset, __u32 time_to_wait, ocfs_lock_res * lockres, __u32 lock_type, struct inode *inode);
 static int ocfs_get_vote_on_disk (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 * got_vote_map, __u64 vote_map, __u64 lock_seq_num, __u64 * oin_open_map);
 static int ocfs_break_cache_lock (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode);
-static int ocfs_disk_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num);
-int ocfs_update_disk_lock (ocfs_super * osb, ocfs_lock_res * lockres, __u32 flags, struct buffer_head **bh, struct inode *inode);
-static int ocfs_update_master_on_open (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode);
+static int ocfs_disk_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num, __u64 feoff);
+int ocfs_update_disk_lock (ocfs_super * osb, ocfs_lock_res * lockres, __u32 flags, struct buffer_head **bh, struct inode *inode, ocfs_journal_handle *handle);
+static int ocfs_update_master_on_open (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode, ocfs_journal_handle *handle);
 int ocfs_disk_release_lock (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, struct buffer_head *bh, struct inode *inode);
 static int ocfs_zap_child_buffers_func(struct dentry *dentry, void *data);
 
 /*
- * ocfs_insert_cache_link()
- *
- */
-static int ocfs_insert_cache_link (ocfs_super * osb, ocfs_lock_res * lockres)
-{
-	int status = 0;
-
-	LOG_ENTRY ();
-
-	lockres->in_cache_list = true;
-
-	list_add_tail (&(lockres->cache_list), &(osb->cache_lock_list));
-
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_insert_cache_link */
-
-
-
-/*
  * ocfs_disk_request_vote()
  *
  */
-static int ocfs_disk_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num)
+static int ocfs_disk_request_vote (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, __u64 vote_map, __u64 * lock_seq_num, __u64 feoff)
 {
 	int status = 0;
 	__u64 offset = 0;
@@ -161,8 +140,13 @@
 	pubsect->vote_map = vote_map;
 	pubsect->vote_type = flags;
 	pubsect->dir_ent = lock_id;
+	pubsect->fe_off = feoff;
 
 	OCFS_BH_PUT_DATA(bhs[osb->node_num]);
+#ifdef VERBOSE_LOCKING_TRACE
+	printk("ocfs_disk_request_vote: lockid = %u.%u, "
+	       "fe_off=%u.%u\n", HILO(lock_id), HILO(feoff));
+#endif
 	pub_off = osb->vol_layout.publ_sect_off + (osb->node_num * osb->sect_size);
 
 	status = ocfs_write_bh (osb, bhs[osb->node_num], 0, NULL);
@@ -695,7 +679,8 @@
 	LOG_ENTRY ();
 
 	status = ocfs_disk_request_vote (osb, lock_id, lock_type, flags,
-					 vote_map, lock_seq_num);
+					 vote_map, lock_seq_num, 
+					 inode ? GET_INODE_FEOFF(inode) : 0);
 
 	LOG_EXIT_STATUS (status);
 	return status;
@@ -729,7 +714,7 @@
  * ocfs_send_dlm_request_msg()
  *
  */
-static int ocfs_send_dlm_request_msg (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, __u64 vote_map)
+static int ocfs_send_dlm_request_msg (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, __u64 vote_map, struct inode *inode)
 {
 	int status = 0;
 	ocfs_dlm_msg *dlm_msg = NULL;
@@ -766,7 +751,15 @@
 	req->lock_id = lock_id;
 	req->flags = flags;
 	req->lock_seq_num = lockres->last_upd_seq_num;
+	if (inode)
+		req->fe_off = GET_INODE_FEOFF(inode);
+	else
+		req->fe_off = 0;
+#ifdef VERBOSE_LOCKING_TRACE
+	printk("ocfs_send_dlm_request_msg: inode=%p, lockid = %u.%u, "
+	       "fe_off=%u.%u\n", inode, HILO(lock_id), HILO(req->fe_off));
 
+#endif
 	ocfs_send_bcast (osb, vote_map, dlm_msg);
 	status = ocfs_wait (lockres->voted_event,
 			    atomic_read (&lockres->voted_event_woken), 
@@ -798,6 +791,9 @@
 	unsigned long jif = 0;
 	int status = 0;
 	int cnt = 0;
+#ifdef VERBOSE_LOCKING_TRACE
+	bool printed = false;
+#endif
 
 	LOG_ENTRY_ARGS ("(0x%08x, %d)\n", lockres, timeout);
 
@@ -812,6 +808,12 @@
 		if (lockres->in_use) {
 			if (lockres->thread_id != mypid) {
 				spin_unlock (&lockres->lock_mutex);
+#ifdef VERBOSE_LOCKING_TRACE
+				if (!printed) {
+					printk("ocfs2: waiting on lockres %u.%u, mypid = %u, thread_id = %u\n", HILO(lockres->sector_num), ocfs_getpid(), lockres->thread_id);
+					printed = true;
+				}
+#endif
 				if (jif && jif < jiffies) {
 					LOG_TRACE_ARGS ("lockpid=%d, newpid=%d,"
 						" timedout\n",
@@ -876,7 +878,7 @@
  * ocfs_update_disk_lock()
  *
  */
-int ocfs_update_disk_lock (ocfs_super * osb, ocfs_lock_res * lockres, __u32 flags, struct buffer_head **bh, struct inode *inode)
+int ocfs_update_disk_lock (ocfs_super * osb, ocfs_lock_res * lockres, __u32 flags, struct buffer_head **bh, struct inode *inode, ocfs_journal_handle *handle)
 {
 	int status = 0;
 	__u64 offset = 0;
@@ -891,6 +893,15 @@
 		LOG_ERROR_STATUS (status);
 		goto finally;
 	}
+
+	if (handle) {
+		status = ocfs_journal_access(handle, *bh, OCFS_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			LOG_ERROR_STATUS (status);
+			goto finally;
+		}
+	}
+
 	fe = (ocfs_file_entry *)OCFS_BH_GET_DATA_READ(*bh); /* read */
 
 	if (flags & DLOCK_FLAG_MASTER && 
@@ -936,7 +947,16 @@
 	OCFS_BH_PUT_DATA(*bh);
 
 	if (changed) {
-		status = ocfs_write_bh (osb, *bh, 0, inode);
+		if (handle) {
+			status = ocfs_journal_dirty(handle, *bh);
+			lockres->lock_holders++;
+#warning I hope these lock flags are alright.
+			ocfs_get_lockres(lockres);
+			ocfs_journal_add_lock(handle, lockres->sector_num, 
+					      lockres->lock_type, 0, lockres, 
+					      *bh, inode);
+		} else
+			status = ocfs_write_bh (osb, *bh, 0, inode);
 		if (status < 0) 
 			LOG_ERROR_STATUS (status);
 	}
@@ -950,7 +970,7 @@
  * ocfs_update_master_on_open()
  *
  */
-int ocfs_update_master_on_open (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode)
+int ocfs_update_master_on_open (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode, ocfs_journal_handle *handle)
 {
 	int status = -EAGAIN;
 	bool disk_vote = false;
@@ -977,7 +997,8 @@
 
 			lockres->oin_openmap |= (1 << osb->node_num);
 			status = ocfs_update_disk_lock (osb, lockres,
-						DLOCK_FLAG_OPEN_MAP, &bh, inode);
+						DLOCK_FLAG_OPEN_MAP, &bh, 
+						inode, handle);
 			if (bh)
 				brelse(bh);
 
@@ -1031,7 +1052,6 @@
 	lockres->oin_openmap = 0;
 	lockres->sector_num = lock_id;
 	lockres->in_use = 0;
-	lockres->oin = NULL;
 	lockres->lock_state = 0;
 	lockres->vote_state = 0;
 	lockres->in_cache_list = false;
@@ -1066,16 +1086,19 @@
  * ocfs_create_update_lock()
  *
  */
-int ocfs_create_update_lock (ocfs_super * osb, ocfs_inode * oin, __u64 lock_id, __u32 flags, bool new_file, struct inode *inode)
+int ocfs_create_update_lock (ocfs_super * osb, __u64 lock_id, __u32 flags, bool new_file, struct inode *inode, ocfs_journal_handle *handle)
 {
 	int status = 0;
 	ocfs_lock_res *lockres = NULL;
 	ocfs_lock_res *tmp_lockres = NULL;
 	bool is_dir = false;
+	ocfs_inode *oin = NULL;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, %u.%u, %u)\n", osb, oin,
 			HI (lock_id), LO (lock_id), flags);
 
+	oin = GET_INODE_OIN(inode);
+
 	is_dir = (flags & OCFS_OIN_DIRECTORY) ? true : false;
 
 	/* Check the lock state on the disk / in our resource map */
@@ -1087,17 +1110,6 @@
 		}
 
 		ocfs_acquire_lockres (lockres);
-		if (lockres->oin) {
-			if (lockres->oin->obj_id.type != OCFS_TYPE_OIN) {
-				ocfs_release_lockres (lockres);
-				LOG_ERROR_STATUS (status = -EFAIL);
-				goto bail;
-			} else {
-				ocfs_put_lockres (lockres->oin->lock_res);
-				lockres->oin->lock_res = NULL;
-			}
-		}
-		lockres->oin = oin;
 		oin->oin_flags |= flags;
 		ocfs_get_lockres (lockres);
 		oin->lock_res = lockres;
@@ -1154,20 +1166,11 @@
 				}
 				goto bail;
 			}
-		} else {
-			if (flags & OCFS_OIN_CACHE_UPDATE) {
-				status = ocfs_insert_cache_link (osb, lockres);
-				if (status < 0) {
-					LOG_ERROR_STR ("Lock up volume");
-					goto bail;
-				}
-			}
 		}
 	}
 
 	ocfs_acquire_lockres (lockres);
 
-	lockres->oin = oin;
 	oin->oin_flags |= flags;
 	if (oin->lock_res != lockres) {
 		ocfs_put_lockres (oin->lock_res);
@@ -1185,7 +1188,7 @@
 		/* Send a message to master so that he can send the oin update to */
 		/* this node also. If u are the master then update File_entry */
 		/* and set the bit that this node has a open */
-		status = ocfs_update_master_on_open (osb, lockres, inode);
+		status = ocfs_update_master_on_open (osb, lockres, inode, handle);
 		if (status < 0) {
 			ocfs_release_lockres (lockres);
 			if (status != -EINTR)
@@ -1350,7 +1353,7 @@
 	if (lockres->readonly_node != osb->node_num)
 		lockres->readonly_node = OCFS_INVALID_NODE_NUM; // clear any owner
 
-	status = ocfs_wait_for_readonly_drop(osb, lockres);
+	status = ocfs_wait_for_readonly_drop(osb, lockres, inode);
 	if (status < 0) {
 		if (status == -ETIMEDOUT)
 			goto again;
@@ -1528,7 +1531,7 @@
 		if (comm_voting && !disk_vote) {
 			LOG_TRACE_STR ("Network vote");
 			status = ocfs_send_dlm_request_msg (osb, lock_id, lock_type,
-								flags, lockres, votemap);
+								flags, lockres, votemap, inode);
 			if (status >= 0) {
 				status = lockres->vote_status;
 				if (status >= 0) {
@@ -1748,7 +1751,7 @@
 			status = ocfs_send_dlm_request_msg (osb, lockres->sector_num,
 							lockres->lock_type, 
 							FLAG_ACQUIRE_LOCK|FLAG_FILE_RELEASE_CACHE,
-							lockres, votemap);
+							lockres, votemap, inode);
 			if (status >= 0) {
 				status = lockres->vote_status;
 				if (status >= 0) {
@@ -1872,7 +1875,7 @@
 
 
 /* TODO: merge down into new lock function */
-int ocfs_send_readonly_drop_message(ocfs_super *osb, ocfs_lock_res *lockres, __u64 vote_map)
+int ocfs_send_readonly_drop_message(ocfs_super *osb, ocfs_lock_res *lockres, __u64 vote_map, struct inode *inode)
 {
 	int status = 0, tmpstat;
 	__u64 lock_id = lockres->sector_num, lockseqnum = 0;
@@ -1882,7 +1885,7 @@
 
 	if (comm_voting) {
 		status = ocfs_send_dlm_request_msg (osb, lock_id, OCFS_DLM_ENABLE_CACHE_LOCK,
-						    FLAG_DROP_READONLY, lockres, vote_map);
+						    FLAG_DROP_READONLY, lockres, vote_map, inode);
 		if (status >= 0) {
 			status = lockres->vote_status;
 			goto bail;
@@ -2009,7 +2012,7 @@
 	/* net voting */
 	if (comm_voting && !*disk_vote) {
 		LOG_TRACE_STR ("Network vote");
-		status = ocfs_send_dlm_request_msg (osb, lock_id, lock_type, flags, lockres, vote_map);
+		status = ocfs_send_dlm_request_msg (osb, lock_id, lock_type, flags, lockres, vote_map, inode);
 		if (status >= 0) {
 			status = lockres->vote_status;
 			if (status >= 0)
@@ -2068,7 +2071,7 @@
 
 	/* update the disk lock */
 	if (need_lock_write) {
-		status = ocfs_update_disk_lock (osb, lockres, lock_write_flags, &bh, inode);
+		status = ocfs_update_disk_lock (osb, lockres, lock_write_flags, &bh, inode, NULL);
 		if (status < 0)
 			LOG_ERROR_STATUS (status);
 	}
@@ -2095,17 +2098,17 @@
 	return status;
 }
 
-static int _ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres);
+static int _ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode);
 
-static inline int ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres)
+static inline int ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode)
 {
 	if (lockres->readonly_map == 0ULL)
 		return 0;
-	return _ocfs_wait_for_readonly_drop(osb, lockres);
+	return _ocfs_wait_for_readonly_drop(osb, lockres, inode);
 }
 	
 #define READONLY_DROP_TRIES 5
-static int _ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres)
+static int _ocfs_wait_for_readonly_drop(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode)
 {
 	int tries = 0;
 	int status = 0;
@@ -2120,7 +2123,7 @@
 		OCFS_ASSERT(lockres->readonly_node == osb->node_num);
 		if (!lockres->readonly_dropping) {
 			ocfs_get_lockres(lockres);
-			status = ocfs_drop_readonly_cache_lock(osb, lockres);
+			status = ocfs_drop_readonly_cache_lock(osb, lockres, inode);
 			if (status < 0) {
 				LOG_ERROR_STATUS (status);
 				ocfs_release_lockres (lockres);

Modified: trunk/src/extmap.c
===================================================================
--- trunk/src/extmap.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/extmap.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -439,7 +439,7 @@
  * ocfs_delete_all_extent_maps()
  *
  */
-void ocfs_delete_all_extent_maps (ocfs_inode * oin)
+void ocfs_delete_all_extent_maps (ocfs_super *osb, ocfs_inode * oin)
 {
 	__u32 RunsInExtentMap = 0, ExtentMapIndex, ByteCount = 0;
 	__s64 Vbo;
@@ -452,9 +452,9 @@
 	for (ExtentMapIndex = 0; ExtentMapIndex < RunsInExtentMap;
 	     ExtentMapIndex++) {
 		if (ocfs_get_next_extent_map_entry
-		    (oin->osb, &oin->map, ExtentMapIndex, &Vbo, &Lbo,
+		    (osb, &oin->map, ExtentMapIndex, &Vbo, &Lbo,
 		     &ByteCount)) {
-			ocfs_remove_extent_map_entry (oin->osb, &oin->map, Vbo,
+			ocfs_remove_extent_map_entry (osb, &oin->map, Vbo,
 						  ByteCount);
 		}
 	}

Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/file.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -96,7 +96,6 @@
 	ocfs_inode *oin = NULL;
 	bool bAcquiredOIN = false;
 	bool bClearInUse = false;
-	bool new_oin = false;
 	struct buffer_head *fe_bh = NULL;
 	__u64 parent_off;
 	ocfs_sem *oin_sem = NULL;
@@ -121,98 +120,60 @@
 	/* kch - for an open request we are already given the 
 	* inode, and therefore we are given the oin too */
 	down(&inode->i_sem);
-	oin = NULL;
-	if (inode_data_is_oin (inode))
-		oin = GET_INODE_OIN(inode);
-	status = -EFAIL;
+	oin = GET_INODE_OIN(inode);
+	oin_sem = &(oin->main_res);
+	ocfs_down_sem (oin_sem, true);
+	bAcquiredOIN = true;
 
-	if (oin != NULL) {
-		if (!(oin->oin_flags & OCFS_OIN_IN_TEARDOWN) &&
-			!(oin->oin_flags & OCFS_OIN_DELETE_ON_CLOSE)) {
-				OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_IN_USE);
-				status = 0;
-		}
-		if (status < 0) {
-			if (oin->oin_flags & OCFS_OIN_IN_TEARDOWN)
-				LOG_ERROR_ARGS ("oin (%p) in teardown", oin);
-			else
-				LOG_ERROR_ARGS ("oin (%p) deleted", oin);
-		}
+	/* If the in use flag is set, forget about it. This will go
+	 * eventually. */
+	if (!(oin->oin_flags & OCFS_OIN_IN_TEARDOWN) &&
+	    !(oin->oin_flags & OCFS_OIN_DELETE_ON_CLOSE)) {
+		OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_IN_USE);
+		bClearInUse = true;
 	} else {
-		/* now it IS possible to have an inode but no OIN attached yet
-		 * must be loaded now to open file */
-		status = -ENOENT;
+		if (oin->oin_flags & OCFS_OIN_IN_TEARDOWN)
+			LOG_ERROR_ARGS ("oin (%p) in teardown", oin);
+		else
+			LOG_ERROR_ARGS ("oin (%p) deleted", oin);
+		up(&inode->i_sem);
+		goto leave;
 	}
-	up(&inode->i_sem);
 
-	if (status < 0) {
-		if (status != -ENOENT && status != -EINTR) {
-			LOG_ERROR_STATUS (status);
+	/* 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, 
+				      OCFS_BH_CACHED, inode);
+		if (status < 0) {
+			up(&inode->i_sem);
+			LOG_ERROR_STATUS(status);
 			goto leave;
 		}
 
-		/*  Look on the disk now ... */
-		down(&parent->i_sem);
-		status = ocfs_find_files_on_disk (osb, parent_off, &(dentry->d_name),
-					  &fe_bh, NULL, parent, true);
-		up(&parent->i_sem);
-
-		if (status >= 0) {
-			oin = NULL;
-			ocfs_down_sem (&(osb->osb_res), true);
-			status = ocfs_create_oin_from_entry (osb, fe_bh, &oin, parent_off, inode);
-			if (status < 0)
-				LOG_ERROR_STATUS(status);
-			new_oin = true;
-			ocfs_up_sem (&(osb->osb_res));
+		status = ocfs_inode_open(osb, fe_bh, NULL, inode);
+		if (status < 0) {
+			up(&inode->i_sem);
+			LOG_ERROR_STATUS(status);
+			if (status != -EINTR) {
+				LOG_ERROR_ARGS("Open request made for nonexistent "
+					       "file! ('%*s')", 
+					       file->f_dentry->d_name.len, 
+					       file->f_dentry->d_name.name);
+				status = -ENOENT;
+			}
+			goto leave;
 		}
-	}
+		bClearInUse = true;
 
-	if (status < 0) {	/* not found on disk or in mem */
-		if (status != -EINTR) {
-			LOG_ERROR_ARGS("Open request made for nonexistent "
-				       "file! ('%*s')", 
-				       file->f_dentry->d_name.len, 
-				       file->f_dentry->d_name.name);
-			status = -ENOENT;
+		status = ocfs_inode_fill_ext_map (osb, fe_bh, inode);
+		if (status < 0) {
+			up(&inode->i_sem);
+			LOG_ERROR_STATUS(status);
+			goto leave;
 		}
-		goto leave;
 	}
-
-	bClearInUse = true;
- 
-	/* check if another process doing an open */
-	/* concurrently has just set the oin */
-	down(&inode->i_sem);
-	if (new_oin) {
-		if (inode_data_is_oin (inode)) {
-			// delete the oin we just made 
-			if (oin->inode) {
-				iput(oin->inode);
-				oin->inode = NULL;
-			}
-			oin->lock_res = NULL;
-			ocfs_release_oin(oin, true);
-			// and use the correct one
-			oin = GET_INODE_OIN(inode);
-		} else {
-			if (ocfs_inc_icount(inode) < 0)
-				BUG();
-			oin->inode = inode;
-			SET_INODE_OIN (inode, oin);
-		}
-	}
- 
-	/* we should now have a single oin regardless */
-	/* of how many concurrent openers at this point */
-	/* so take the oin->main_res so we won't need the i_sem */
 	up(&inode->i_sem);
- 
-	oin_sem = &(oin->main_res);
-	if (!bAcquiredOIN) {
-		ocfs_down_sem (oin_sem, true);
-		bAcquiredOIN = true;
-	}
+	/* yes, hold onto main_res. */
 
 	if (oin->oin_flags & OCFS_OIN_DELETE_ON_CLOSE) {
 		LOG_TRACE_STR ("oin has DELETE_ON_CLOSE set, returning DELETE_PENDING");
@@ -220,9 +181,8 @@
 		goto leave;
 	}
 
-	/* only call ocfs_verify_update_oin if there's a good inode */
-	if (oin->inode == inode && OIN_NEEDS_VERIFICATION(oin)) {
-		status = ocfs_verify_update_oin (osb, oin, &truncate_pages);
+	if (OCFS_I(inode)->needs_verification) {
+		status = ocfs_verify_update_inode (osb, inode, &truncate_pages);
 		if (status < 0) {
 			/*  disable VOLUME TODO */
 			LOG_ERROR_STATUS (status);
@@ -230,12 +190,13 @@
 		}
 	}
 
-	if (oin->open_hndl_cnt > 0) {
+	if (OCFS_I(inode)->open_hndl_cnt > 0) {
 		/*  The OIN is currently in use by some thread. */
 		/*  We must check whether the requested access/share access */
 		/*  conflicts with the existing open operations. */
 
-		LOG_TRACE_ARGS ("oin->open_hndl_cnt > 0! : %u\n", oin->open_hndl_cnt);
+		LOG_TRACE_ARGS ("oin->open_hndl_cnt > 0! : %u\n", 
+				OCFS_I(inode)->open_hndl_cnt);
 		if (!(mode & O_DIRECT)) {
 			if ((oin->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO) && !(mode & O_RDONLY)) {
 				status = -EACCES;
@@ -266,7 +227,7 @@
 		}
 	}
 
-	oin->open_hndl_cnt++;
+	OCFS_I(inode)->open_hndl_cnt++;
 
 	/* We should clear the in use now as we are safe from the case */
 	/* where the voting thread can vote and we have an open in */
@@ -326,6 +287,9 @@
 		ret = 0;
 	}
 
+	if (ret < 0)
+		ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
+
 	LOG_TRACE_ARGS
 	    ("exiting file_open: file=%p dentry=%p inode=%p oin=%p kiovec=%d\n",
 	     file, file->f_dentry, file->f_dentry->d_inode, 
@@ -375,68 +339,49 @@
 			        ocfs_safefree (ofile->curr_dir_buf);
 			        ofile->curr_dir_buf = NULL;
 		        }
-		        ocfs_release_ofile (ofile);
+			ocfs_release_ofile (ofile);
                 }
                 goto bail;
         }
 
-        /* file */
-	if (inode_data_is_oin(inode))
-		oin = GET_INODE_OIN(inode);
+	oin = GET_INODE_OIN(inode);
 
-	if (oin == NULL)
-		goto bail;
-	  
-	if (oin->obj_id.type != OCFS_TYPE_OIN ||
-	    oin->obj_id.size != sizeof (ocfs_inode) ||
-	    oin->main_res.magic != OCFS_SEM_MAGIC) {
-		int i;
-		
-		LOG_ERROR_ARGS("oin appears to have been freed!  oin=%p, inode->oin=%p\n",
-			       oin, GET_INODE_OIN(inode));
-		for (i=0; i<sizeof (ocfs_inode); i++) {
-			printk("%03x ", ((char *)oin)[i]);
-		}
-		printk("\n");
-		goto bail;
-	}
-		
-
         ocfs_down_sem (&(oin->main_res), true);
-        oin->open_hndl_cnt--;
-	if (!oin->open_hndl_cnt) 
+        OCFS_I(inode)->open_hndl_cnt--;
+	if (!OCFS_I(inode)->open_hndl_cnt) 
 		last_close = true;
 
         if (oin->oin_flags & OCFS_OIN_ROOT_DIRECTORY) {
                 ocfs_up_sem (&(oin->main_res));
                 goto bail;
         }
-                
+
         LOG_TRACE_ARGS ("openhandles: %d / osbfiles: %d / refcount: %d\n",
-                         oin->open_hndl_cnt, osb->file_open_cnt,
+                        OCFS_I(inode)->open_hndl_cnt, osb->file_open_cnt,
                         atomic_read(&dentry->d_count)); 
-               
-        /* FIXME: in all the other places I run thru all the dentries */
-        /* for the inode, but here I just check this one becuz I'm lz */
-        /* no hard links yet so who cares */
-        if (!atomic_read(&dentry->d_count)) { 
-		if (oin->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO) {
+
+	if (last_close) {
+		ocfs_extent_map_destroy (&oin->map);
+		ocfs_extent_map_init (&oin->map);
+
+		if (oin->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO)
 			OCFS_CLEAR_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
+
+		if (oin->oin_flags & OCFS_OIN_NEEDS_DELETION ||
+		    oin->oin_flags & OCFS_OIN_IN_USE) {
+			ocfs_up_sem (&(oin->main_res));
+			LOG_ERROR_STR("Not deleting lockrse on a last close! eek!");
+			goto bail;
 		}
-                if (oin->oin_flags & OCFS_OIN_NEEDS_DELETION ||
-                    oin->oin_flags & OCFS_OIN_IN_USE) {
-                        ocfs_up_sem (&(oin->main_res));
-                        goto bail;
-                }
-		
-                ocfs_up_sem (&(oin->main_res));
-                ocfs_release_oin (oin, true);
-		ocfs_sync_inode(inode);
-        } else {
-                ocfs_up_sem (&(oin->main_res));
-                ocfs_release_cached_oin (osb, oin);
-		ocfs_sync_inode(inode);
-        }
+		if (!oin->lock_res)
+			LOG_ERROR_STR("My oin has no lockres!");
+		else {
+			ocfs_put_lockres(oin->lock_res);
+			oin->lock_res = NULL;
+		}
+	}
+	ocfs_up_sem (&(oin->main_res));
+	ocfs_sync_inode(inode);
 
 	if (last_close) {
 		if (inode->i_data.nrpages)
@@ -444,6 +389,8 @@
 	}
 
 bail:
+//	ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
+
 	LOG_EXIT_LONG (0);
 	return 0;
 }				/* ocfs_file_release */
@@ -597,8 +544,9 @@
 		if (status < 0) {
 			ocfs_abort_trans(handle);
 		} else {
-			ocfs_journal_add_lock(handle, lockId, locktype, lockFlags, 
-					      pLockResource, bh);
+			ocfs_journal_add_lock(handle, lockId, locktype, 
+					      lockFlags, pLockResource, bh, 
+					      inode);
 			bAcquiredLock = false;
 
 			ocfs_commit_trans(handle);
@@ -656,7 +604,7 @@
 		goto bail;
 	}
 	oin = GET_INODE_OIN(inode);
-	osb = (ocfs_super *) oin->osb;
+	osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
 
 	lockres = oin->lock_res;
 	if (lockres == NULL) {
@@ -666,13 +614,6 @@
 
 	ocfs_get_lockres (lockres);
 
-	if ((lockres->master_node_num != osb->node_num) ||
-	    (lockres->lock_type != OCFS_DLM_ENABLE_CACHE_LOCK)) {
-		oin->cache_enabled = false;
-	} else {
-		oin->cache_enabled = true;
-	}
-
 	if (osb->osb_flags & OCFS_OSB_FLAGS_SHUTDOWN) {
 		LOG_TRACE_STR ("Volume has already started shutdown");
 		ret = -EIO;
@@ -696,8 +637,8 @@
 	if (!(filp->f_flags & O_DIRECT)) {
 		/* FIXME: is the down_sem supposed to be here?! */
 		LOG_TRACE_ARGS ("non O_DIRECT write, fileopencount=%d\n",
-				oin->open_hndl_cnt);
-		if (oin->open_hndl_cnt > 1) {
+				OCFS_I(inode)->open_hndl_cnt);
+		if (OCFS_I(inode)->open_hndl_cnt > 1) {
 			if (oin->oin_flags & OCFS_OIN_OPEN_FOR_WRITE) {
 				LOG_TRACE_STR
 				    ("uh oh! someone else is doing non O_DIRECT writes!\n");
@@ -712,15 +653,15 @@
 		}
 	}
 
-	if (OIN_NEEDS_VERIFICATION (oin)) {
+	if (OCFS_I(inode)->needs_verification) {
 		LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
 		ocfs_down_sem (&(oin->main_res), true);
-		status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
+		status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
 		ocfs_up_sem (&(oin->main_res));
 		if (needs_trunc)
 			ocfs_truncate_inode_pages(inode, 0);
 		if (status < 0) {
-			LOG_TRACE_STR ("ocfs_verify_update_oin failed");
+			LOG_TRACE_STR ("ocfs_verify_update_inode failed");
 			LOG_TRACE_STR ("TODO: disable volume");
 			ret = -EIO;
 			goto bail;
@@ -756,7 +697,7 @@
 		     HI (oin->alloc_size), LO (oin->alloc_size), HI (newsize),
 		     LO (newsize));
 
-		status = ocfs_extend_file (osb, oin->parent_dirnode_off, oin, newsize, GET_INODE_FEOFF(inode), NULL, inode, NULL);
+		status = ocfs_extend_file (osb, newsize, GET_INODE_FEOFF(inode), NULL, inode, NULL);
 		if (status < 0) {
 			if (status != -EINTR && status != -ENOSPC) {
 				LOG_ERROR_STATUS (status);
@@ -796,17 +737,8 @@
 		OCFS_CLEAR_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_WRITE);
 	}
 
-#if 0
-        if (inode && oin && !oin->cache_enabled && !(filp->f_flags & O_DIRECT)) {
-                fsync_inode_buffers(inode);
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
-		fsync_inode_data_buffers(inode);
-#endif
-        }
-#endif
-
 	ocfs_put_lockres (lockres);
-	
+
 	if (ret < 0)
 		ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
 
@@ -837,7 +769,7 @@
 		goto bail;
 	}
 	oin = GET_INODE_OIN(inode);
-	osb = (ocfs_super *) oin->osb;
+	osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
 
 	if (filp->f_flags & O_DIRECT) {
 		/* anything special for o_direct? */
@@ -849,14 +781,14 @@
 		}
 	}
 
-	if (OIN_NEEDS_VERIFICATION (oin)) {
+	if (OCFS_I(inode)->needs_verification) {
 		ocfs_down_sem (&(oin->main_res), true);
-		status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
+		status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
 		ocfs_up_sem (&(oin->main_res));
 		if (needs_trunc)
 			ocfs_truncate_inode_pages(inode, 0);
 		if (status < 0) {
-			LOG_TRACE_STR ("ocfs_verify_update_oin failed");
+			LOG_TRACE_STR ("ocfs_verify_update_inode failed");
 			LOG_TRACE_STR ("TODO: disable volume");
 			ret = -EIO;
 			goto bail;
@@ -1081,7 +1013,7 @@
 /* ocfs_extend_file()
  *
  */
-int ocfs_extend_file (ocfs_super * osb, __u64 parent_off, ocfs_inode * oin, __u64 file_size, __u64 file_off, ocfs_journal_handle *passed_handle, struct inode *inode, struct iattr *attr)
+int ocfs_extend_file (ocfs_super * osb, __u64 file_size, __u64 file_off, ocfs_journal_handle *passed_handle, struct inode *inode, struct iattr *attr)
 {
 	int status = 0;
 	int tmpstat;
@@ -1102,9 +1034,15 @@
 	struct buffer_head *bh = NULL;
 	int flags = 0;
 	ocfs_journal_handle *handle = NULL;
+	ocfs_inode *oin = NULL;
 
 	LOG_ENTRY ();
 
+	if (!inode)
+		BUG();
+
+	oin = GET_INODE_OIN(inode);
+
 	if (file_size == 0)
 		goto leave;
 
@@ -1238,7 +1176,7 @@
 
 		/* note: ok if oin is null here, not used in
 		 * ocfs_allocate_extent */
-		status = ocfs_allocate_extent (osb, oin, bh, handle,
+		status = ocfs_allocate_extent (osb, bh, handle,
 					actualDiskOffset, actualLength, inode);
 		if (status < 0) {
 			OCFS_BH_PUT_DATA(bh);
@@ -1298,9 +1236,9 @@
 				if (bFileLockAcquired)
 					lockFlags |= FLAG_FILE_UPDATE_OIN;
 
-				ocfs_journal_add_lock(handle, lockId, locktype, 
+				ocfs_journal_add_lock(handle, lockId, locktype,
 						      lockFlags, pLockResource,
-						      bh);
+						      bh, inode);
 				bAcquiredLock = false;
 
 				ocfs_commit_trans(handle);
@@ -1397,30 +1335,28 @@
 	}
 
 	if (attr->ia_valid & ATTR_SIZE) {
-		if (oin != NULL) {
-			ocfs_down_sem (&(oin->main_res), true);
-			if (OIN_NEEDS_VERIFICATION (oin)) {
-				LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
-				status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
-				if (status < 0) {
-					LOG_ERROR_STATUS (status);
-					LOG_TRACE_STR ("TODO: disable volume");
-					ocfs_up_sem (&(oin->main_res));
-					error = -EIO;
-					goto bail;
-				}
+		ocfs_down_sem (&(oin->main_res), true);
+		if (OCFS_I(inode)->needs_verification) {
+			LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
+			status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
+			if (status < 0) {
+				LOG_ERROR_STATUS (status);
+				LOG_TRACE_STR ("TODO: disable volume");
+				ocfs_up_sem (&(oin->main_res));
+				error = -EIO;
+				goto bail;
 			}
-			ocfs_up_sem (&(oin->main_res));
-			if (needs_trunc)
-				ocfs_truncate_inode_pages(inode, 0);
 		}
+		ocfs_up_sem (&(oin->main_res));
+		if (needs_trunc)
+			ocfs_truncate_inode_pages(inode, 0);
 
                 if (inode->i_size > newsize)
 			status = ocfs_truncate_file(osb, fileOff, newsize, 
 						    oin, inode);
 		else {
-			status = ocfs_extend_file(osb, parentOff, oin, newsize,
-						  fileOff, NULL, inode, attr);
+			status = ocfs_extend_file(osb, newsize, fileOff, NULL, 
+						  inode, attr);
 			extended = true;
 		}
 		if (status < 0) {
@@ -1433,7 +1369,7 @@
 		if (oin != NULL) {
 			ocfs_down_sem (&(oin->main_res), true);
                         if (inode->i_size > newsize) {
-                            ocfs_delete_all_extent_maps(oin);
+                            ocfs_delete_all_extent_maps(osb, oin);
                         }
 			inode->i_size = newsize;
 			inode->i_blocks = (newsize + sb->s_blocksize) >> sb->s_blocksize_bits;
@@ -1522,6 +1458,7 @@
 	struct inode *inode;
 	struct super_block *sb = dentry->d_inode->i_sb;
 	int status, needs_trunc = 0;
+	ocfs_super *osb;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", dentry, attr,
                         dentry->d_name.len, dentry->d_name.name);
@@ -1529,19 +1466,20 @@
 	inode = dentry->d_inode;
 	if (inode == NULL || !inode_data_is_oin (inode))
 		goto bail;
+
+	osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
 	oin = GET_INODE_OIN(inode);
 	if (oin == ((ocfs_super *)(OCFS_GENERIC_SB_P(sb)))->oin_root_dir)
 		goto bail;
-	if (oin != NULL) {
-		ocfs_down_sem (&(oin->main_res), true);
-		status = ocfs_verify_update_oin (oin->osb, oin, &needs_trunc);
-		ocfs_up_sem (&(oin->main_res));
-		if (needs_trunc)
-			ocfs_truncate_inode_pages(inode, 0);
-		if (status < 0)
-			LOG_ERROR_STATUS (status);
-	}
 
+	ocfs_down_sem (&(oin->main_res), true);
+	status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
+	ocfs_up_sem (&(oin->main_res));
+	if (needs_trunc)
+		ocfs_truncate_inode_pages(inode, 0);
+	if (status < 0)
+		LOG_ERROR_STATUS (status);
+
 bail:
 	LOG_EXIT_LONG (0);
 	return 0;

Modified: trunk/src/hash.c
===================================================================
--- trunk/src/hash.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/hash.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -1526,7 +1526,7 @@
 	inum = __ocfs_inode_hash_lookup(h, voteoff);
 
 	if (!inum) {
-		printk("ocfs2: lost inum, offset =%u.%u, inode->i_ino= %lu\n",
+		printk("ocfs2: lost inum, offset = %u.%u, inode->i_ino= %lu\n",
 		       HILO(voteoff), inode->i_ino);
 
 		BUG();
@@ -1615,6 +1615,12 @@
 
 	spin_unlock(&h->lock);
 
+	if (!inum->i_inode)
+		LOG_ERROR_ARGS("deleting inum in unbound state! (state = %d, "
+			       "voteoff = %u.%u, feoff = %u.%u, i_ino = %u\n",
+			       inum->i_state, HILO(inum->i_voteoff),
+			       HILO(inum->i_feoff), inum->i_ino);
+
 	if (inum->i_inode)
 		iput(inum->i_inode);
 
@@ -1708,45 +1714,27 @@
 /* 
  * ocfs_get_inode_from_offset()
  *
- * If you call this on an offset, you MUST make sure that it won't be
- * deleted out from underneath us.
+ * 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 offset, 
+					 __u64 voteoff, __u64 feoff, 
 					 struct buffer_head *fe_bh)
 {
 	struct inode *inode = NULL;
 	struct super_block *sb = osb->sb;
-	__u64 fe_off;
 	ocfs_file_entry *fe;
 	ocfs_find_inode_args args;
 
-	LOG_ENTRY_ARGS("(offset = %u.%u)\n", HILO(offset));
+	LOG_ENTRY_ARGS("(voteoff = %u.%u, feoff = %u.%u, fe_bh = %p)\n", 
+		       HILO(voteoff), HILO(feoff), fe_bh);
 
-	/* 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 
-	    || offset < osb->vol_layout.root_start_off) {
-		/* OHMYGODTHISISTHEUGLIESTIFEVER */
-		if (offset < (JOURNAL_FILE_BASE_ID * osb->sect_size 
-			      + osb->vol_layout.root_int_off) 
-		    || 
-		    offset >= ((JOURNAL_FILE_BASE_ID + OCFS_MAXIMUM_NODES)
-			       * osb->sect_size 
-			       + osb->vol_layout.root_int_off)) {
-			printk("ocfs2: skipping inode create for %u.%u\n", 
-			       HILO(offset));
-			goto bail;
-		}
-	}
-
-	/* if they ask for the root dirnode, just return it. */
-	if (offset == osb->vol_layout.root_start_off) {
+	/* 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(offset));
+			       HILO(feoff));
 
 		inode = osb->sb->s_root->d_inode;
 
@@ -1760,29 +1748,65 @@
 		goto bail;
 	}
 
-	/* if it's a directory, we want the parent fe off so get it here. */
-	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh);
-	if (!IS_VALID_FILE_ENTRY(fe)) {
+	/* 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);
-		LOG_ERROR_STATUS(-EINVAL);
-		goto bail;
+	} else {
+		if ((voteoff == 0) || (feoff == 0)) {
+			LOG_ERROR_STATUS(-EINVAL);
+			goto bail;
+		}
 	}
-	fe_off = fe->this_sector;
-	OCFS_BH_PUT_DATA(fe_bh);
 
-	inode = ocfs_inode_hash_lookup(osb, offset, false);
+	/* 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 < (JOURNAL_FILE_BASE_ID * osb->sect_size 
+			      + osb->vol_layout.root_int_off) 
+		    || 
+		    feoff >= ((JOURNAL_FILE_BASE_ID + 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 = fe_off;
+		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, offset, fe_off);
+		args.ino = ocfs_inode_hash_insert(osb, voteoff, feoff);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 		inode = ocfs_iget (sb, &args);
 #else
@@ -1804,7 +1828,6 @@
 		}
 	}
 
-
 bail:
 	if (inode)
 		LOG_TRACE_ARGS("returning inode with number %lu\n", 

Modified: trunk/src/inc/journal.h
===================================================================
--- trunk/src/inc/journal.h	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/inc/journal.h	2004-04-16 22:38:55 UTC (rev 847)
@@ -99,6 +99,7 @@
 	__u32 flags;
 	struct _ocfs_lock_res * res;
 	struct buffer_head *bh;
+	struct inode *inode;
 	struct list_head lock_list;
 };
 
@@ -330,7 +331,8 @@
 void                 ocfs_journal_add_lock(ocfs_journal_handle *handle, 
 					   __u64 id,  __u32 type, __u32 flags, 
 					   struct _ocfs_lock_res *res, 
-					   struct buffer_head *bh);
+					   struct buffer_head *bh, 
+					   struct inode *inode);
 
 /*  
  *  Trans Lock:
@@ -393,4 +395,8 @@
 	 			   + OCFS_MAX_FILE_ENTRY_EXTENTS              \
 				   + OCFS_JOURNAL_FUZZ_CREDITS + \
 				   OCFS_DEFAULT_DIR_NODE_SECTS)
+
+/* On very rare open operations (it's a first open and we're not in
+ * the open map), we have to change the file entry. */
+#define OCFS_OPEN_CREDITS 1
 #endif /* _OCFSJOURNAL_H_ */

Modified: trunk/src/inc/ocfs.h
===================================================================
--- trunk/src/inc/ocfs.h	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/inc/ocfs.h	2004-04-16 22:38:55 UTC (rev 847)
@@ -229,62 +229,6 @@
 #define ocfs_getpid()               getpid()
 #endif
 
-struct _ocfs_inode;
-
-/* OCFS2 Inode Private Data
- *
- * feoff/voteoff can change during rename. Luckily, rename takes a ton
- * of locks and does several checks, so you're safe reading these values
- * if any of the following is true:
- *  1) you have i_sem
- *  2) you have oin->main_res
- *  3) oin->open_hndl_cnt > 0 
- */
-typedef struct _ocfs_inode_private
-{
-	struct _ocfs_inode *oin;
-	__u64            voteoff;
-	__u64            feoff;
-	atomic_t         i_clean_buffer_seq;
-	__u8             deleted; /* this can be a generic flags field later */
-} ocfs_inode_private;
-
-#define GET_INODE_CLEAN_SEQ(i)  (atomic_t *)(&(OCFS_GENERIC_IP(i)->i_clean_buffer_seq))
-
-#define OCFS_GENERIC_IP(i)        ((ocfs_inode_private *)(i->u.generic_ip))
-
-#define inode_data_is_oin(i)      (OCFS_GENERIC_IP(i)->oin != NULL)
-
-#define INODE_DELETED(i) (OCFS_GENERIC_IP(i)->deleted)
-#define SET_INODE_DELETED(i) OCFS_GENERIC_IP(i)->deleted = 1
-#define CLEAR_INODE_DELETED(i) OCFS_GENERIC_IP(i)->deleted = 0
-
-#define SET_INODE_VOTEOFF(i,o)						      \
-do {									      \
-	OCFS_GENERIC_IP(i)->voteoff = o;				      \
-} while (0)
-
-#define GET_INODE_VOTEOFF(i) OCFS_GENERIC_IP(i)->voteoff
-
-#define SET_INODE_FEOFF(i,o)						      \
-do {									      \
-	OCFS_GENERIC_IP(i)->feoff = o;					      \
-} while (0)
-
-#define GET_INODE_FEOFF(i) OCFS_GENERIC_IP(i)->feoff
-
-#define CLEAR_INODE_OIN(i)						      \
-do {									      \
-	GET_INODE_OIN(i)= (void *)NULL;					      \
-} while (0)
-
-#define SET_INODE_OIN(i,o)						      \
-do {									      \
-	GET_INODE_OIN(i)= (void *)o;					      \
-} while (0)
-
-#define GET_INODE_OIN(i) ((OCFS_GENERIC_IP(i)->oin))
-
 #define FIRST_FILE_ENTRY(dir)   ((char *) ((char *)dir)+OCFS_SECTOR_SIZE)
 #define FILEENT(dir,idx)        (ocfs_file_entry *) ( ((char *)dir) + \
                                 ((dir->index[idx]+1) * OCFS_SECTOR_SIZE))
@@ -603,9 +547,6 @@
 #ifndef  _OCFSDEF_H_
 #define  _OCFSDEF_H_
 
-#define  OIN_NEEDS_VERIFICATION(a)	((a)->needs_verification)
-#define  OIN_UPDATED(a)			((a)->needs_verification = false)
-
 #define  IS_VALID_DIR_NODE(ptr)                                       \
                  (!strncmp((ptr)->signature, OCFS_DIR_NODE_SIGNATURE, \
                            strlen(OCFS_DIR_NODE_SIGNATURE)))
@@ -998,6 +939,7 @@
 	} while (0)
 #endif
 
+#if 0
 /* oin macros - currently the release is handled separately */
 #ifdef OCFS_MEM_DBG
 #define ocfs_allocate_oin()  ((ocfs_inode *)({ \
@@ -1020,8 +962,8 @@
         } \
 	oin; })) 
 #endif
+#endif
 
-
 #define hashsize(n)             ((__u32)1<<(n))
 #define hashmask(n)             (hashsize(n)-1)
 
@@ -1801,7 +1743,6 @@
 	bool cache_lock_held;
 	__u32 lock_state;
 	__u32 vote_state;		/* Is the lockres being voted on over ipcdlm */
-	ocfs_inode *oin;
 	spinlock_t lock_mutex;
 	wait_queue_head_t voted_event;
 	atomic_t voted_event_woken;
@@ -1820,25 +1761,80 @@
 
 struct _ocfs_inode
 {
-	ocfs_obj_id obj_id;
-	struct inode *inode;
-	struct _ocfs_super *osb;	/* ocfs_inode belongs to this volume */
-	struct list_head recovery_list;
 	ocfs_sem main_res;
 	struct semaphore extend_sem;
 	__u32 num_extends;
 	ocfs_lock_res *lock_res;
 	ocfs_extent_map map;
 	__s64 alloc_size;
-	__u64 chng_seq_num;
-	__u64 parent_dirnode_off;	/* from the start of vol */
-	__u32 open_hndl_cnt;
 	__u32 oin_flags;
-	bool needs_verification;
-	bool cache_enabled;
-	bool journal_inode;    /* is this the journal oin? */
 };
 
+/* OCFS2 Inode Private Data
+ *
+ * feoff/voteoff can change during rename. Luckily, rename takes a ton
+ * of locks and does several checks, so you're safe reading these values
+ * if any of the following is true:
+ *  1) you have i_sem
+ *  2) you have oin->main_res
+ *  3) oin->open_hndl_cnt > 0 
+ */
+typedef struct _ocfs_inode_private
+{
+	/* always valid, just a simple back pointer. */
+	struct inode *inode;
+
+	/* protected by main_res */
+	ocfs_inode       oin;
+	__u32            open_hndl_cnt;
+	bool             needs_verification;
+	struct list_head recovery_list;
+	__u64            chng_seq_num;
+
+	__u64            voteoff;
+	__u64            feoff;
+	atomic_t         i_clean_buffer_seq;
+	__u32            flags; /* see below */
+} ocfs_inode_private;
+
+/* has this inode been deleted, either from this node or from another node. */
+#define OCFS_INODE_DELETED          0x00000001
+/* is this the journal inode? */
+#define OCFS_INODE_JOURNAL          0x00000002
+
+#define GET_INODE_CLEAN_SEQ(i)  (atomic_t *)(&(OCFS_GENERIC_IP(i)->i_clean_buffer_seq))
+
+#define OCFS_GENERIC_IP(i)        ((ocfs_inode_private *)(i->u.generic_ip))
+#define OCFS_I(i) OCFS_GENERIC_IP(i)
+
+#define INODE_DELETED(i) (OCFS_GENERIC_IP(i)->flags & OCFS_INODE_DELETED)
+#define SET_INODE_DELETED(i) (OCFS_GENERIC_IP(i)->flags |= OCFS_INODE_DELETED)
+#define CLEAR_INODE_DELETED(i) (OCFS_GENERIC_IP(i)->flags &= (~OCFS_INODE_DELETED))
+
+#define INODE_JOURNAL(i) (OCFS_GENERIC_IP(i)->flags & OCFS_INODE_JOURNAL)
+#define SET_INODE_JOURNAL(i) (OCFS_GENERIC_IP(i)->flags |= OCFS_INODE_JOURNAL)
+#define CLEAR_INODE_JOURNAL(i) (OCFS_GENERIC_IP(i)->flags &= (~OCFS_INODE_JOURNAL))
+
+#define SET_INODE_VOTEOFF(i,o)						      \
+do {									      \
+	OCFS_GENERIC_IP(i)->voteoff = o;				      \
+} while (0)
+
+#define GET_INODE_VOTEOFF(i) OCFS_GENERIC_IP(i)->voteoff
+
+#define SET_INODE_FEOFF(i,o)						      \
+do {									      \
+	OCFS_GENERIC_IP(i)->feoff = o;					      \
+} while (0)
+
+#define GET_INODE_FEOFF(i) OCFS_GENERIC_IP(i)->feoff
+
+/* callers of these next three functions should be fixed as we always
+ * have oin now. */
+#define inode_data_is_oin(i)      (1)
+
+#define GET_INODE_OIN(i) (&(OCFS_GENERIC_IP(i)->oin))
+
 typedef enum _ocfs_vol_state
 {
 	VOLUME_DISABLED,
@@ -1964,6 +1960,7 @@
 	HASHTABLE root_sect_node;	/* lockres->sector_num hash */
 	struct list_head cache_lock_list;
 	struct super_block *sb;
+	struct inode *root_inode;
 	ocfs_inode *oin_root_dir;	/* ptr to the root dir ocfs_inode */
 	ocfs_vol_layout vol_layout;
 	ocfs_vol_node_map vol_node_map;
@@ -2143,6 +2140,7 @@
 	/* last seq num used in comm voting */
 	__u64 comm_seq_num;		// NUMBER RANGE(0,ULONG_LONG_MAX)
 	bool mounted;                   /* used for journaling */
+	__u64 fe_off;                   /* needed to create inodes. */
 }
 OCFS_GCC_ATTR_PACKALGN
 ocfs_publish;				// END CLASS
@@ -2317,6 +2315,7 @@
 	__u32 flags;
 	__u64 lock_seq_num;
 	__u8 open_handle;
+	__u64 fe_off;
 } 
 OCFS_GCC_ATTR_PACKALGN
 ocfs_dlm_msg_hdr;

Modified: trunk/src/inc/proto.h
===================================================================
--- trunk/src/inc/proto.h	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/inc/proto.h	2004-04-16 22:38:55 UTC (rev 847)
@@ -27,10 +27,10 @@
 #ifndef _PROTO_H_
 #define _PROTO_H_
 
-int ocfs_allocate_extent (ocfs_super * osb, ocfs_inode * oin, struct buffer_head *fe_bh, ocfs_journal_handle *handle,__u64 actualDiskOffset, __u64 actualLength, struct inode *inode);
+int ocfs_allocate_extent (ocfs_super * osb, struct buffer_head *fe_bh, ocfs_journal_handle *handle,__u64 actualDiskOffset, __u64 actualLength, struct inode *inode);
 int ocfs_kill_this_tree(ocfs_super *osb, struct buffer_head *extent_grp_bh, ocfs_journal_handle *handle, struct inode *inode);
 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, ocfs_inode * oin, __s64 Vbo, __s64 * Lbo, __u32 sectors, u32 *sector_count, 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_alloc_node_block (ocfs_super * osb, __u64 FileSize, __u64 * DiskOffset, __u64 * file_off, __u32 NodeNum, __u32 Type, ocfs_journal_handle *handle);
@@ -44,20 +44,20 @@
 int ocfs_acquire_lockres_ex (ocfs_lock_res * lockres, __u32 timeout);
 void ocfs_release_lockres (ocfs_lock_res * lockres);
 void ocfs_init_lockres (ocfs_super * osb, ocfs_lock_res * lockres, __u64 lock_id);
-int ocfs_create_update_lock (ocfs_super * osb, ocfs_inode * oin, __u64 lock_id, __u32 flags, bool new_file, struct inode *inode);
+int ocfs_create_update_lock (ocfs_super * osb, __u64 lock_id, __u32 flags, bool new_file, struct inode *inode, ocfs_journal_handle *handle);
 int ocfs_acquire_lock (ocfs_super * osb, __u64 lock_id, __u32 lock_type,
 		   __u32 flags, ocfs_lock_res ** lr, struct buffer_head **bh, struct inode *inode);
 int ocfs_release_lock (ocfs_super * osb, __u64 lock_id, __u32 lock_type, __u32 flags, ocfs_lock_res * lockres, struct buffer_head *bh, struct inode *inode);
 int ocfs_init_dlm (void);
 void ocfs_process_one_vote_reply(ocfs_super *osb, ocfs_vote_reply_ctxt *ctxt, __u32 node_num);
 int ocfs_break_cache_lock_zap_buffers(ocfs_super * osb, struct inode * inode);
-int ocfs_send_readonly_drop_message(ocfs_super *osb, ocfs_lock_res *lockres, __u64 vote_map);
+int ocfs_send_readonly_drop_message(ocfs_super *osb, ocfs_lock_res *lockres, __u64 vote_map, struct inode *inode);
 
 int ocfs_extend_system_file (ocfs_super * osb, __u32 FileId, __u64 FileSize, struct buffer_head *fe_bh, ocfs_journal_handle *handle, bool zero);
 
 void ocfs_extent_map_init (ocfs_extent_map * map);
 void ocfs_extent_map_destroy (ocfs_extent_map * map);
-void ocfs_delete_all_extent_maps (ocfs_inode * oin);
+void ocfs_delete_all_extent_maps (ocfs_super * osb, ocfs_inode * oin);
 void ocfs_remove_extent_map_entry (ocfs_super * osb, ocfs_extent_map * Map, __s64 Vbo, __u32 ByteCount);
 bool ocfs_get_next_extent_map_entry (ocfs_super * osb, ocfs_extent_map * Map, __u32 RunIndex, __s64 * Vbo, __s64 * Lbo, __u32 * SectorCount);
 bool ocfs_lookup_extent_map_entry (ocfs_super * osb, ocfs_extent_map * Map, __s64 Vbo, __s64 * Lbo, __u64 * SectorCount, __u32 * Index);
@@ -76,7 +76,7 @@
 int ocfs_sync_file (struct file *file, struct dentry *dentry, int datasync);
 ssize_t ocfs_file_write (struct file *filp, const char *buf, size_t count, loff_t * ppos);
 ssize_t ocfs_file_read (struct file *filp, char *buf, size_t count, loff_t * ppos);
-int ocfs_extend_file (ocfs_super * osb, __u64 parent_off, ocfs_inode * oin, __u64 file_size, __u64 file_off, ocfs_journal_handle *passed_handle, struct inode *inode, struct iattr *attr);
+int ocfs_extend_file (ocfs_super * osb, __u64 file_size, __u64 file_off, ocfs_journal_handle *passed_handle, struct inode *inode, struct iattr *attr);
 int ocfs_setattr (struct dentry *dentry, struct iattr *attr);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 int ocfs_getattr (struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
@@ -85,6 +85,7 @@
 #endif
 
 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_read_locked_inode (struct inode *inode, ocfs_find_inode_args *args);
 void ocfs_read_inode2 (struct inode *inode, void *opaque);
@@ -172,15 +173,12 @@
 void ocfs_linux_dbg_free (const void *Buffer);
 
 
-int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin, int *needs_trunc);
-int ocfs_create_oin_from_entry (ocfs_super * osb, struct buffer_head * fe_bh, ocfs_inode ** new_oin, __u64 parent_dir_off, struct inode *inode);
-int ocfs_initialize_oin (ocfs_inode * oin, ocfs_super * osb, __u32 flags, __u64 file_off, __u64 lock_id, bool new_file, struct inode *inode);
-int ocfs_create_new_oin (ocfs_inode ** Returnedoin, __u64 alloc_size, ocfs_super * osb);
+int ocfs_verify_update_inode (ocfs_super * osb, struct inode * inode, int *needs_trunc);
+int ocfs_inode_fill_ext_map(ocfs_super * osb, struct buffer_head * fe_bh, struct inode *inode);
+int ocfs_inode_open(ocfs_super *osb, struct buffer_head *fe_bh, 
+		    ocfs_journal_handle *handle, struct inode *inode);
 int ocfs_create_root_oin (ocfs_super * osb, struct inode *root);
-void ocfs_release_oin (ocfs_inode * oin, bool FreeMemory);
-void ocfs_release_cached_oin (ocfs_super * osb, ocfs_inode * oin);
 
-
 int ocfs_initialize_osb (ocfs_super * osb, ocfs_vol_disk_hdr * vdh, ocfs_vol_label * vol_label, __u32 sect_size);
 int ocfs_verify_volume (ocfs_vol_disk_hdr * vdh);
 int ocfs_check_volume (ocfs_super * osb);
@@ -205,7 +203,7 @@
 int ocfs_recv_udp_msg (ocfs_recv_ctxt * recv_ctxt);
 int ocfs_send_dismount_msg (ocfs_super * osb, __u64 vote_map);
 int ocfs_send_vote_reply (ocfs_super * osb, ocfs_dlm_msg * dlm_msg, __u32 vote_status, bool inode_open);
-int ocfs_drop_readonly_cache_lock(ocfs_super *osb, ocfs_lock_res *lockres);
+int ocfs_drop_readonly_cache_lock(ocfs_super *osb, ocfs_lock_res *lockres, struct inode *inode);
 
 
 void ocfs_initialize_bitmap (ocfs_alloc_bm * bitmap, __u32 validbits, __u32 allocbits);
@@ -308,7 +306,8 @@
 		      __u64 oldoff, 
 		      __u64 newoff, 
 		      __u64 new_fe_off);
-struct inode *ocfs_get_inode_from_offset(ocfs_super *osb, __u64 offset, 
+struct inode *ocfs_get_inode_from_offset(ocfs_super *osb, 
+					 __u64 voteoff, __u64 feoff, 
 					 struct buffer_head *fe_bh);
 struct inode *ocfs_inode_hash_lookup(ocfs_super *osb, 
 				     __u64 voteoff, 

Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/inode.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -28,6 +28,7 @@
 
 #define OCFS_DEBUG_CONTEXT    OCFS_DEBUG_CONTEXT_INODE
 
+extern struct semaphore recovery_list_sem;
 
 static int ocfs_readpage (struct file *file, struct page *page);
 static int ocfs_prepare_write (struct file *file, struct page *page, unsigned from, unsigned to);
@@ -133,8 +134,6 @@
 
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
 
-#define REPOPULATE_INODE 1
-
 /*
  * ocfs_find_inode()
  *
@@ -143,81 +142,26 @@
 int ocfs_find_inode (struct inode *inode, unsigned long ino, void *opaque)
 {
 	ocfs_find_inode_args *args = NULL;
-	ocfs_inode *oin;
 	int ret = 0;
-	__u64 fileOff;
-	mode_t mode;
 	ocfs_file_entry *fe = NULL;
 
 	LOG_ENTRY_ARGS ("(0x%08x, %u, 0x%08x)\n", inode, ino, opaque);
-
+	
+	/* We have unique inode numbers so these are just sanity
+	 * checks at this point. */
 	if (opaque == NULL || inode == NULL)
 		goto bail;
+
 	args = (ocfs_find_inode_args *) opaque;
 
-	if (ino != inode->i_ino) {
+	if (ino != inode->i_ino)
 		goto bail;
-	}
 
-	if (!ocfs_linux_get_inode_offset (inode, &fileOff, NULL)) {
-		LOG_TRACE_STR ("error getting inode offset");
+	if (GET_INODE_FEOFF(inode) != args->offset) {
+		LOG_ERROR_STATUS(-EINVAL);
 		goto bail;
 	}
 
-	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(args->fe_bh); /* read */
-	if (S_ISDIR (inode->i_mode)) {
-		LOG_TRACE_STR ("find_inode -> S_ISDIR");
-		if (fe->extents[0].disk_off != fileOff) {
-			LOG_TRACE_ARGS
-		    	("DIR : inode number same but full offset does not match: %u.%u != %u.%u\n",
-		     	fe->extents[0].disk_off, fileOff);
-			goto bail;
-		}
-	} else if (args->offset != fileOff) {
-		LOG_TRACE_ARGS
-	    	("FILE : inode number same but full offset does not match: %u.%u != %u.%u\n",
-	     	args->offset, fileOff);
-		goto bail;
-	}
-	
-#ifdef REPOPULATE_INODE
-	/* not sure if this is appropriate, but we have the most 
- 	* current file entry so why not use it? */
-	mode = fe->prot_bits;
-
-	switch (fe->attribs) {
-    	case OCFS_ATTRIB_DIRECTORY:
-	    	mode |= S_IFDIR;
-	    	break;
-    	case OCFS_ATTRIB_CHAR:
-	    	mode |= S_IFCHR;
-	    	inode->i_rdev = MKDEV (fe->dev_major, fe->dev_minor);
-	    	break;
-    	case OCFS_ATTRIB_BLOCK:
-	    	mode |= S_IFBLK;
-	    	inode->i_rdev = MKDEV (fe->dev_major, fe->dev_minor);
-	    	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;
-	}
-	oin = NULL;		/* set it back to our current OIN if we have one */
-	if (inode_data_is_oin (inode))
-		oin = GET_INODE_OIN(inode);
-
-	ocfs_populate_inode (inode, fe, mode, oin, false);
-#endif /* REPOPULATE_INODE */
-
 	ret = 1;
 bail:
 	if (fe)
@@ -227,7 +171,50 @@
 }				/* ocfs_find_inode */
 #endif /* LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) */
 
+/*
+ * ocfs_inode_init_private()
+ *
+ */
+int ocfs_inode_init_private(struct inode *inode)
+{
+	ocfs_inode_private *i = NULL;
+	struct _ocfs_inode *oin;
 
+	if (!inode)
+		BUG();
+
+	inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, 
+					       GFP_NOFS);
+
+	if (!inode->u.generic_ip)
+		return -ENOMEM;
+
+	i = (ocfs_inode_private *) inode->u.generic_ip;
+	oin = &i->oin;
+
+	memset(i, 0, sizeof(ocfs_inode_private));
+
+	i->flags = 0;
+	atomic_set(&i->i_clean_buffer_seq, 0);
+
+	/* Init OIN (or old OIN) stuff. */
+//	oin->obj_id.type = OCFS_TYPE_OIN;
+//	oin->obj_id.size = sizeof (ocfs_inode);
+	ocfs_init_sem (&(oin->main_res));
+	init_MUTEX(&(oin->extend_sem));
+	OCFS_SET_FLAG (oin->oin_flags, OCFS_INITIALIZED_MAIN_RESOURCE);
+	i->open_hndl_cnt = 0;
+	ocfs_extent_map_init (&oin->map);
+	INIT_LIST_HEAD(&i->recovery_list);
+
+	/* These should be set in read_inode2. */
+	oin->alloc_size = 0ULL;
+	i->voteoff = 0ULL;
+	i->feoff = 0ULL;
+
+	return 0;
+} /* ocfs_inode_init_private */
+
 /*
  * ocfs_populate_inode()
  *
@@ -238,6 +225,7 @@
 	ocfs_super *osb;
 	__u64 offset, fe_off;
 	unsigned long uniq_ino;
+	ocfs_inode *oin = NULL;
 
 	LOG_ENTRY_ARGS ("(0x%08x, %u, size:%u)\n", inode, mode, fe->file_size);
 
@@ -251,12 +239,10 @@
 		BUG();
 	}
 
-	if (!inode->u.generic_ip)
-		inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache,
-						       GFP_NOFS);
-	if (!inode->u.generic_ip) {
+	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");
+		LOG_ERROR_STR("unable to allocate private data for "
+			      "inode");
 		goto bail;
 	}
 	
@@ -274,14 +260,17 @@
 	OCFS_SET_INODE_TIME(inode, i_atime, fe->modify_time);
 	OCFS_SET_INODE_TIME(inode, i_mtime, fe->modify_time);
 	OCFS_SET_INODE_TIME(inode, i_ctime, fe->create_time);
-	if (genptr)
-		SET_INODE_OIN(inode, genptr);
-	else
-		CLEAR_INODE_OIN(inode);
 
 	SET_INODE_VOTEOFF(inode, offset);
 	SET_INODE_FEOFF(inode, fe_off);
 
+	oin = GET_INODE_OIN(inode);
+	oin->alloc_size = fe->alloc_size;
+	OCFS_I(inode)->inode = inode;
+	OCFS_I(inode)->chng_seq_num = DISK_LOCK_SEQNUM (fe);
+	if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
+		oin->oin_flags |= OCFS_OIN_DIRECTORY;
+
 	if (create_ino) {
 		uniq_ino = ocfs_inode_hash_insert(osb, offset, fe_off);
 		inode->i_ino = uniq_ino;
@@ -335,6 +324,8 @@
 	umode_t mode;
 	__u64 voteoff;
 	ocfs_file_entry *fe = NULL;
+	ocfs_inode *oin = NULL;
+	struct buffer_head *bh = NULL;
 
 	LOG_ENTRY_ARGS ("(%p, %p)\n", inode, args);
 
@@ -347,8 +338,7 @@
 	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);
-		inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
-		if (!inode->u.generic_ip) {
+		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;
@@ -367,20 +357,41 @@
 		inode->i_fop = &ocfs_dops;
 		inode->i_uid = osb->vol_layout.uid;
 		inode->i_gid = osb->vol_layout.gid;
-		SET_INODE_OIN (inode, osb->oin_root_dir);
 		SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
 		SET_INODE_FEOFF(inode, 0);
+
+		oin = GET_INODE_OIN(inode);
+		oin->alloc_size = 0ULL;
+		OCFS_I(inode)->inode = inode;
+		OCFS_I(inode)->chng_seq_num = 0ULL;
+		oin->oin_flags |= OCFS_OIN_DIRECTORY | OCFS_OIN_ROOT_DIRECTORY;
+
 		ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
 		goto bail;
 	}
 
 	LOG_TRACE_ARGS("Populating non-root inode (i_ino = %lu)\n", inode->i_ino);
-	if (args)
-		fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(args->fe_bh);
-	if (!fe) {
+
+	if (!args) {
 		make_bad_inode (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;
+
+	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(bh);
 	
 	newoin = NULL;
 
@@ -412,14 +423,18 @@
 		    break;
 	}
 	ocfs_populate_inode (inode, fe, mode, newoin, false);
+
 	voteoff = S_ISDIR (mode) ? fe->extents[0].disk_off : fe->this_sector;
 	if (!args->skip_bind)
 		ocfs_inode_hash_bind(osb, voteoff, inode);
 
 bail:
 	if (fe)
-		OCFS_BH_PUT_DATA(args->fe_bh);
+		OCFS_BH_PUT_DATA(bh);
 
+	if (args && !args->fe_bh && bh)
+		brelse(bh);
+
 	LOG_EXIT ();
 	return;
 }				/* ocfs_read_locked_inode */
@@ -437,10 +452,12 @@
 	struct super_block *sb;
 	ocfs_find_inode_args *args = NULL;
 	ocfs_super *osb;
-	ocfs_inode *newoin;
+	ocfs_inode *oin = NULL;
 	umode_t mode;
 	ocfs_file_entry *fe = NULL;
 	__u64 voteoff;
+	struct buffer_head *bh = NULL;
+	int status;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", inode, opaque);
 
@@ -451,8 +468,7 @@
 	sb = inode->i_sb;
 	osb = (ocfs_super *) OCFS_GENERIC_SB_P(sb);
 	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
-		inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
-		if (!inode->u.generic_ip) {
+		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;
@@ -474,9 +490,15 @@
 		inode->i_fop = &ocfs_dops;
 		inode->i_uid = osb->vol_layout.uid;
 		inode->i_gid = osb->vol_layout.gid;
-		SET_INODE_OIN (inode, osb->oin_root_dir);
 		SET_INODE_VOTEOFF(inode, osb->vol_layout.root_start_off);
 		SET_INODE_FEOFF(inode, 0);
+
+		oin = GET_INODE_OIN(inode);
+		oin->alloc_size = 0ULL;
+		OCFS_I(inode)->inode = inode;
+		OCFS_I(inode)->chng_seq_num = 0ULL;
+		oin->oin_flags |= OCFS_OIN_DIRECTORY | OCFS_OIN_ROOT_DIRECTORY;
+
 		ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
 		goto bail;
 	}
@@ -487,12 +509,23 @@
 	}
 
 	args = (ocfs_find_inode_args *) opaque;
-	newoin = NULL;
-	if (args->fe_bh == NULL)
-		BUG();
 
-	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(args->fe_bh); /* read */
+	/* 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;
 
+	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(bh); /* read */
+
 	mode = fe->prot_bits;
 
 	switch (fe->attribs) {
@@ -521,7 +554,7 @@
 		    mode |= S_IFREG;
 		    break;
 	}
-	ocfs_populate_inode (inode, fe, mode, newoin, false);
+	ocfs_populate_inode (inode, fe, mode, NULL, false);
 
 	voteoff = S_ISDIR (mode) ? fe->extents[0].disk_off : fe->this_sector;
 	if (!args->skip_bind)
@@ -529,7 +562,11 @@
 
 bail:
 	if (fe)
-		OCFS_BH_PUT_DATA(args->fe_bh);
+		OCFS_BH_PUT_DATA(bh);
+
+	if (args && !args->fe_bh && bh)
+		brelse(bh);
+
 	LOG_EXIT ();
 	return;
 }				/* ocfs_read_inode2 */
@@ -576,27 +613,11 @@
 		goto bail;
 	args = (ocfs_find_inode_args *) opaque;
 
-	if (!ocfs_linux_get_inode_offset (inode, &fileOff, NULL)) {
-		LOG_TRACE_STR ("could not get inode offset");
+	if (GET_INODE_FEOFF(inode) != args->offset) {
+		LOG_ERROR_STATUS(-EINVAL);
 		goto bail;
 	}
 
-	if (S_ISDIR (inode->i_mode)) {
-		LOG_TRACE_STR ("find_actor -> S_ISDIR\n");
-		fe = OCFS_BH_GET_DATA_READ(args->fe_bh); /* read */
-		if (fe->extents[0].disk_off != fileOff) {
-			LOG_TRACE_ARGS
-		    	("DIR : inode number same but full offset does not match: %u.%u != %u.%u\n",
-		     	fe->extents[0].disk_off, fileOff);
-			goto bail;
-		}
-	} else if (args->offset != fileOff) {
-		LOG_TRACE_ARGS
-	    	("FILE : inode number same but full offset does not match: %u.%u != %u.%u\n",
-	     	args->offset, fileOff);
-		goto bail;
-	}
-
 	ret = 1;
 bail:
 	if (fe)
@@ -695,17 +716,6 @@
 	if (inode_data_is_oin(inode))
 		oin = GET_INODE_OIN(inode);
 
-	/* can we destroy the oin? Uhm, shouldn't this be a test
-	 * against a count of '3'? */
-	if (oin && (atomic_read (&inode->i_count) == 2) && 
-	    (inode->i_ino != OCFS_ROOT_INODE_NUMBER)) {
-		ocfs_extent_map_destroy (&oin->map);
-		ocfs_extent_map_init (&oin->map);
-		ocfs_release_cached_oin (osb, oin);
-		ocfs_release_oin (oin, true);
-		oin = NULL;
-	} 
-
 	/* 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. */
@@ -752,6 +762,12 @@
 	if (!inode)
 		goto bail;
 
+	LOG_TRACE_ARGS("Clearing inode %u (voteoff: %u.%u, "
+		       "feoff: %u.%u)\n", inode->i_ino, 
+		       HILO(GET_INODE_VOTEOFF(inode)), 
+		       HILO(GET_INODE_FEOFF(inode)));
+
+	/* we should not really be using osb in this context. */
 	osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
 
 	if (!ocfs_linux_get_inode_offset(inode, &offset, NULL)) {
@@ -762,42 +778,63 @@
 
 	/* offset == 0 if this inode is newly created and hasn't been
 	 * filled in yet. */
-	if (offset == 0)
+	if (offset == 0) {
+		LOG_ERROR_STR("uhm, feoff = 0!");
 		goto bail;
+	}
 
-	if (inode_data_is_oin (inode)) {
-		LOG_TRACE_STR ("inode with oin : clear inode");
+	oin = GET_INODE_OIN(inode);
 
-		oin = GET_INODE_OIN(inode);
-		if (oin != osb->oin_root_dir)
-			BUG();
-		
+	if (inode->i_ino == OCFS_ROOT_INODE_NUMBER) {
 		LOG_TRACE_STR("this is the root inode, doing cleanup now!");
 		ocfs_sync_blockdev(inode->i_sb);
 		LOG_TRACE_STR ("syncing past root inode");
 		LOG_TRACE_STR ("calling dismount");
 		ocfs_dismount_volume (inode->i_sb);
+		goto bail;
+	}
+
+	OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_IN_TEARDOWN);
+
+	lockres = oin->lock_res;
+	if (lockres) {
+		ocfs_acquire_lockres (lockres);
+		ocfs_release_lockres (lockres);
+		oin->lock_res = NULL;
+		ocfs_put_lockres (lockres);
+		lockres = NULL;
+	}
+
+	ocfs_extent_map_destroy (&oin->map);
+	ocfs_extent_map_init (&oin->map);
+
+	down(&recovery_list_sem);
+	list_del(&OCFS_I(inode)->recovery_list);
+	up(&recovery_list_sem);
+
+	ocfs_del_sem (&(oin->main_res));
+	OCFS_CLEAR_FLAG (oin->oin_flags, OCFS_INITIALIZED_MAIN_RESOURCE);
+
+	/* clean out the oin ... why?! */
+	memset(oin, 0, sizeof(ocfs_inode));
+
+	if (!ocfs_lookup_sector_node (osb, offset, &lockres)) {
+		if (lockres) {
+			ocfs_remove_sector_node (osb, lockres);
+			ocfs_put_lockres(lockres);
+		} else
+			LOG_TRACE_STR ("lockres in hash is null");
 	} else {
-		if (!ocfs_lookup_sector_node (osb, offset, &lockres)) {
-			if (lockres) {
-				if (lockres->oin) {
-					ocfs_put_lockres (lockres->oin->lock_res);
-					lockres->oin->lock_res = NULL;
-					lockres->oin = NULL;
-				}
-				ocfs_remove_sector_node (osb, lockres);
-				ocfs_put_lockres(lockres);
-			} else
-				LOG_TRACE_STR ("lockres in hash is null");
-		} else {
-			LOG_TRACE_STR("hashtable has already been destroyed.");
-		}
+		LOG_TRACE_STR("hashtable has already been destroyed.");
 	}
 
-	if (inode->u.generic_ip)
+bail:
+	if (inode && inode->u.generic_ip) {
 		kmem_cache_free(OcfsGlobalCtxt.inode_cache, 
 				inode->u.generic_ip);
-bail:
+		inode->u.generic_ip = NULL;
+	}
+
 	LOG_EXIT ();
 	return;
 }				/* ocfs_clear_inode */
@@ -895,7 +932,9 @@
 		if (unlock)
 			ocfs_up_sem (&(oin->main_res));
 
-		status = ocfs_extend_file (osb, oin->parent_dirnode_off, oin, newsize, GET_INODE_FEOFF(inode), NULL, inode, NULL);
+		status = ocfs_extend_file (osb, newsize, 
+					   GET_INODE_FEOFF(inode), NULL, 
+					   inode, NULL);
 
 		if (unlock)
 			ocfs_down_sem (&(oin->main_res), true);
@@ -1011,10 +1050,10 @@
 		goto bail;
 	}
 	
-	osb = (ocfs_super *) oin->osb;
+	osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
 	vbo = (__s64) iblock << inode->i_sb->s_blocksize_bits;
 
-	if (!oin->journal_inode && vbo >= oin->alloc_size) {
+	if (!INODE_JOURNAL(inode) && vbo >= oin->alloc_size) {
 		LOG_TRACE_STR("Extending allocation");
 		err = ocfs_extend_allocation(osb, oin, vbo+512, false, inode);
 		if (err < 0) {
@@ -1030,8 +1069,7 @@
 
 	len = 1;
 	down(&oin->extend_sem);
-	err = ocfs_lookup_file_allocation(osb, oin, vbo, &lbo, len, NULL, 
-					  inode);
+	err = ocfs_lookup_file_allocation(osb, vbo, &lbo, len, NULL, inode);
 	up(&oin->extend_sem);
 	if (err < 0) {
 		LOG_ERROR_ARGS ("vbo=%u.%u lbo=%u.%u len=%u", HILO(vbo),
@@ -1088,7 +1126,7 @@
 
 	oin = GET_INODE_OIN(inode);
 
-	if (!(oin->journal_inode)) {
+	if (!INODE_JOURNAL(inode)) {
 		LOG_ERROR_STR("bmap is only for journal inodes!");
 		err = -EINVAL;
 		LOG_ERROR_STATUS(err);
@@ -1111,8 +1149,7 @@
 
 	vbo = (__s64) block << inode->i_sb->s_blocksize_bits;
 	len = 1;
-	err = ocfs_lookup_file_allocation(osb, oin, vbo, &lbo, len, 
-					  NULL, inode);
+	err = ocfs_lookup_file_allocation(osb, vbo, &lbo, len, NULL, inode);
 	if (err < 0) {
 		LOG_ERROR_ARGS ("vbo=%u.%u lbo=%u.%u len=%u", HILO(vbo),
 				HILO(lbo), len);
@@ -1149,11 +1186,11 @@
 	}
 
 	oin = GET_INODE_OIN(inode);
-	osb = (ocfs_super *) oin->osb;
+	osb = (ocfs_super *) OCFS_GENERIC_SB_P(inode->i_sb);
 
 	vbo = (__s64) iblock << inode->i_sb->s_blocksize_bits;
 	len = 1;
-	err = ocfs_lookup_file_allocation (osb, oin, vbo, &lbo, len, NULL, inode);
+	err = ocfs_lookup_file_allocation (osb, vbo, &lbo, len, NULL, inode);
 	if (err < 0) {
 		LOG_ERROR_STATUS (err);
 		err = -1;
@@ -1270,13 +1307,13 @@
 	osb = (ocfs_super *) inode->i_sb->s_fs_info;
 	blocksize_bits = inode->i_sb->s_blocksize_bits;
 	/* make sure we're up to date... */
-	if (OIN_NEEDS_VERIFICATION (oin)) {
+	if (OCFS_I(inode)->needs_verification) {
 		LOG_TRACE_STR ("ocfs_direct_IO_get_blocks: verify oin.");
-		status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
+		status = ocfs_verify_update_inode (osb, inode, &needs_trunc);
 		if (needs_trunc) 
 			ocfs_truncate_inode_pages(inode, 0);
 		if (status < 0) {
-			LOG_TRACE_STR ("ocfs_verify_update_oin failed");
+			LOG_TRACE_STR ("ocfs_verify_update_inode failed");
 			ret = -EIO;
 			goto bail;
 		}
@@ -1305,7 +1342,8 @@
 	/* This figure out the size of the next contiguous block, and
 	 * our logical offset */	
 	/* TODO: Try our damndest to give sizes in multiples of PAGE_SIZE */
-	status = ocfs_lookup_file_allocation(osb, oin, vbo, &lbo, max_blocks, &new_size, inode);
+	status = ocfs_lookup_file_allocation(osb, vbo, &lbo, max_blocks, 
+					     &new_size, inode);
 
 	/* Do whatever we need to the buffer_head */
 	if (set_new) {

Modified: trunk/src/journal.c
===================================================================
--- trunk/src/journal.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/journal.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -237,7 +237,8 @@
 
 		tmpstat = ocfs_release_lock(osb, lock->id, lock->type, 
 					    lock->flags, lock->res, 
-					    (abort ? NULL : lock->bh), NULL);
+					    (abort ? NULL : lock->bh), 
+					    lock->inode);
 		if (tmpstat < 0) {
 			LOG_ERROR_ARGS("Could not release lock %u.%u\n", 
 				       HILO(lock->id));
@@ -247,7 +248,8 @@
 		ocfs_put_lockres(lock->res);
 		if (lock->bh != NULL)
 			brelse(lock->bh);
-
+		if (lock->inode)
+			iput(lock->inode);
 		list_del(&(lock->lock_list));
 		handle->num_locks--;
 		ocfs_free(lock);
@@ -769,7 +771,7 @@
  * other transactions anyway... */
 void ocfs_journal_add_lock(ocfs_journal_handle *handle, __u64 id,  __u32 type, 
 			   __u32 flags, struct _ocfs_lock_res *res, 
-			   struct buffer_head *bh) 
+			   struct buffer_head *bh, struct inode *inode) 
 {
 	ocfs_journal_lock *lock;
 
@@ -789,9 +791,13 @@
 	lock->flags = flags;
 	lock->res   = res;
 	lock->bh    = bh;
+	lock->inode = inode;
 
 	if (bh)
 		get_bh(bh);
+	
+	if (inode)
+		atomic_inc(&inode->i_count);
 
 	spin_lock(&handle->list_lock);
 	list_add_tail(&(lock->lock_list), &(handle->locks));
@@ -858,7 +864,6 @@
 	int status = -1;
 	struct inode *inode = NULL; /* the journal inode */
 	journal_t * k_journal = NULL;
-	ocfs_find_inode_args args;
 	ocfs_file_entry *fe = NULL;
 	ocfs_lock_res *lock_res = NULL;
 	__u32 cleanup_file_id = 0;
@@ -878,14 +883,29 @@
 	INIT_LIST_HEAD(&(osb->journal.commited));
 	init_MUTEX(&(osb->journal.commit_sem));
 
-	/* get the cleanup file fe and lock */
 	cleanup_file_id = (__u32) (JOURNAL_FILE_BASE_ID + osb->node_num);
 	lock_id = ((JOURNAL_FILE_BASE_ID + osb->node_num) * osb->sect_size) +
 		  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);
+	if (inode == NULL) {
+		LOG_ERROR_STR("access error");
+		status = -EACCES;
+		goto done;
+	}
+	if (is_bad_inode (inode)) {
+		LOG_ERROR_STR("access error (bad inode)");
+		iput (inode);
+		inode = NULL;
+		status = -EACCES;
+		goto done;
+	}
+	SET_INODE_JOURNAL(inode);
+
 	/* TODO: Use another type of lock. */
 	status = ocfs_acquire_lock (osb, lock_id, OCFS_DLM_EXCLUSIVE_LOCK,
-				    FLAG_FILE_CREATE, &lock_res, &bh, NULL);
+				    FLAG_FILE_CREATE, &lock_res, &bh, inode);
 	if (status < 0) {
 		if (status != -EINTR)
 			LOG_ERROR_STR("Could not get lock on journal!");
@@ -914,35 +934,22 @@
 
 	/* gonna need this later */
 	alloc_size = fe->alloc_size;
-
-	/* Ok, look up the inode for our journal */
-	args.offset = fe->this_sector;
-	args.fe_bh = bh;
-	args.skip_bind = 0;
 	LOG_TRACE_ARGS("fe->this_sector = %u.%u\n", HI(fe->this_sector), 
 		       LO(fe->this_sector));
+	inode->i_size = fe->file_size;
 	OCFS_BH_PUT_DATA(bh);
 	fe = NULL;
-	inode = ocfs_get_inode_from_offset(osb, args.offset, bh);
-	if (inode == NULL) {
-		LOG_ERROR_STR("access error");
-		status = -EACCES;
+
+	/* we just changed this but extend_system_file doesn't know
+	 * about oins, so we update alloc_size ourselves. */
+	oin = GET_INODE_OIN(inode);
+	oin->alloc_size = alloc_size;
+	status = ocfs_create_update_lock(osb, lock_id, 0, false, inode, NULL);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
 		goto done;
 	}
-	if (is_bad_inode (inode)) {
-		LOG_ERROR_STR("access error (bad inode)");
-		iput (inode);
-		inode = NULL;
-		status = -EACCES;
-		goto done;
-	}
-	LOG_TRACE_ARGS("inode->i_size = %u\n", inode->i_size);
-
-	status = ocfs_create_new_oin(&oin, alloc_size, osb);
-	status = ocfs_initialize_oin(oin, osb, 0, lock_id, lock_id, false, NULL);
-	oin->journal_inode = true;
-	oin->open_hndl_cnt++;
-	SET_INODE_OIN(inode, oin);
+	OCFS_I(inode)->open_hndl_cnt++;
 	LOG_TRACE_ARGS("oin->alloc_size = %u.%u\n", HI(oin->alloc_size), 
 		       LO(oin->alloc_size));
 
@@ -979,8 +986,8 @@
 				OCFS_BH_PUT_DATA(bh);
 			brelse(bh);
 		}
-		if (oin)
-			oin->open_hndl_cnt--;
+		if (inode)
+			OCFS_I(inode)->open_hndl_cnt--;
 	}
 	LOG_EXIT_STATUS(status);
 	return(status);
@@ -1049,9 +1056,7 @@
 	/* release the oin here. Isn't this racy? */
 	if (inode_data_is_oin(inode)) {
 		oin = GET_INODE_OIN(inode);
-		CLEAR_INODE_OIN(inode);
-		oin->open_hndl_cnt--;
-		ocfs_release_oin(oin, true);
+		OCFS_I(inode)->open_hndl_cnt--;
 	}
 
 	/* unlock our journal */
@@ -1333,7 +1338,7 @@
 
 	LOG_TRACE_ARGS("Force reading %u blocks\n", totalblks);
 
-	status = ocfs_lookup_file_allocation(osb, oin, vbo, &lbo, size, NULL, 
+	status = ocfs_lookup_file_allocation(osb, vbo, &lbo, size, NULL, 
 					     inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
@@ -1467,7 +1472,6 @@
 	ocfs_inode *oin = NULL;
 	struct inode *inode = NULL;
 	journal_t *k_journal = NULL;
-	ocfs_find_inode_args args;
 	struct buffer_head *bh = NULL;
 	ocfs_journal * journal = NULL;
 	bool recovery_lock = false;
@@ -1499,6 +1503,22 @@
 	lock_id = ((JOURNAL_FILE_BASE_ID + node_num) * osb->sect_size) 
 		+ 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);
+	if (inode == NULL) {
+		LOG_ERROR_STR("access error");
+		status = -EACCES;
+		goto done;
+	}
+	if (is_bad_inode (inode)) {
+		LOG_ERROR_STR("access error (bad inode)");
+		iput (inode);
+		inode = NULL;
+		status = -EACCES;
+		goto done;
+	}
+	SET_INODE_JOURNAL(inode);
+
 	/* Should not ever be called to recover ourselves -- in that
 	 * case we should've called ocfs_journal_load instead. */
 	if (osb->node_num == node_num)
@@ -1507,7 +1527,7 @@
 	status = ocfs_acquire_lock (osb, lock_id, 
 				    OCFS_DLM_EXCLUSIVE_LOCK,
 				    FLAG_FILE_CREATE|FLAG_FILE_RECOVERY, 
-				    &lock_res, &bh, NULL);
+				    &lock_res, &bh, inode);
 	if (status < 0) {
 		LOG_TRACE_ARGS("status returned from acquire_lock=%d\n", 
 			       status);
@@ -1548,40 +1568,19 @@
 	OCFS_BH_PUT_DATA(config_bh);
 
 	fe = (ocfs_file_entry *)OCFS_BH_GET_DATA_READ(bh); /* read */
-
 	/* gonna need this later */
 	alloc_size = fe->alloc_size;
-
-	/* Ok, look up the inode for our journal */
-	args.offset = fe->this_sector;
-	args.fe_bh = bh;
-	args.skip_bind = 0;
 	OCFS_BH_PUT_DATA(bh);
+
 	fe = NULL;
-	inode = ocfs_get_inode_from_offset(osb, args.offset, bh);
-	if (inode == NULL) {
-		LOG_ERROR_STR("access error");
-		status = -EACCES;
-		goto done;
-	}
-	if (is_bad_inode (inode)) {
-		LOG_ERROR_STR("access error (bad inode)");
-		iput (inode);
-		inode = NULL;
-		status = -EACCES;
-		goto done;
-	}
-	LOG_TRACE_ARGS("inode->i_size = %u\n", inode->i_size);
 
-	status = ocfs_create_new_oin(&oin, alloc_size, osb);
+	oin = GET_INODE_OIN(inode);
+	oin->alloc_size = alloc_size;
+	status = ocfs_create_update_lock(osb, lock_id, 0, false, inode, NULL);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto done;
 	}
-	status = ocfs_initialize_oin(oin, osb, 0, lock_id, lock_id, false, 
-				     NULL);
-	oin->journal_inode = true;
-	SET_INODE_OIN(inode, oin);
 
 	status = ocfs_force_read_journal(osb, inode->i_size, oin, inode);
 	if (status < 0) {
@@ -1639,14 +1638,7 @@
 	CLEAR_NODE_IN_RECOVERY(osb, node_num);
 	ocfs_recover_oin_locks(osb, node_num);
 done:
-	/* close the journal file */
 	if (inode)
-		CLEAR_INODE_OIN(inode);
-
-	if (oin)
-		ocfs_release_oin(oin, true);
-	
-	if (inode)
 		iput(inode);
 
 	if (recovery_lock)

Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/namei.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -196,8 +196,7 @@
 		goto leave;
 	}
 
-	inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
-	if (!inode->u.generic_ip) {
+	if (ocfs_inode_init_private(inode)) {
 		LOG_ERROR_STATUS(status = -ENOMEM);
 		goto leave;
 	}
@@ -232,7 +231,8 @@
 	/* Ok, we got the lock -- we'd better add it to our transaction */
 	ocfs_journal_add_lock(handle, parent_off, 
 			      OCFS_DLM_ENABLE_CACHE_LOCK, 
-			      FLAG_FILE_CREATE | FLAG_DIR, lock_res, lock_bh);
+			      FLAG_FILE_CREATE | FLAG_DIR, lock_res, lock_bh, 
+			      dir);
 
 	/* do the real work now. */
 	status = ocfs_mknod_locked(osb, dir, dentry, mode, dev, lock_bh, 
@@ -243,24 +243,12 @@
 		goto leave;
 	}
 
-	status = ocfs_create_new_oin (&oin, 0ULL, osb);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto leave;
-	}
-
 	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(new_fe_bh); /* read */
 
 	file_off = fe->this_sector;
 	dirnode_off = fe->extents[0].disk_off;
-	oinflags = OCFS_OIN_CACHE_UPDATE | (S_ISDIR (mode) ?  OCFS_OIN_DIRECTORY : 0);
+	oinflags = (S_ISDIR (mode) ?  OCFS_OIN_DIRECTORY : 0);
 
-	OCFS_BH_PUT_DATA(new_fe_bh);
-	fe = NULL;
-
-	status = ocfs_initialize_oin (oin, osb, oinflags, file_off, 
-			     S_ISDIR (mode) ?  dirnode_off : file_off, true, inode);
-
 	if (!ocfs_linux_get_inode_offset (dir, &parent_off, &ParentOin)) {
 		LOG_ERROR_STATUS (status = -ENOENT);
 		goto leave;
@@ -269,8 +257,24 @@
 	if (ParentOin)
 		OCFS_CLEAR_FLAG (ParentOin->oin_flags, OCFS_OIN_IN_USE);
 
+	ocfs_populate_inode (inode, fe, mode, NULL, true);
+	insert_inode_hash (inode);
+	ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
+
+	handle->new_file_lockid = fe->this_sector;
+	OCFS_BH_PUT_DATA(new_fe_bh);
+	fe = NULL;
+
+	oin = GET_INODE_OIN(inode);
+	status = ocfs_create_update_lock(osb, GET_INODE_VOTEOFF(inode), 
+					 oinflags, true, inode, handle);
+	if (status < 0)
+		LOG_ERROR_STATUS(status);
+
 	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(new_fe_bh); /* read */
 
+        /*  Insert the OFile on the OIN list */
+	OCFS_I(inode)->chng_seq_num = DISK_LOCK_SEQNUM (fe);
 	if (oin->lock_res != NULL) {
 		ocfs_lock_res *lockres = oin->lock_res;
 		ocfs_acquire_lockres(lockres);
@@ -285,28 +289,15 @@
 		}
 		ocfs_release_lockres(lockres);
 	}
-	
-        /*  Insert the OFile on the OIN list */
-	oin->chng_seq_num = DISK_LOCK_SEQNUM (fe);
-	oin->parent_dirnode_off = parent_off;
-
-	LOG_TRACE_ARGS("ocfs_mknod: new_fe_bh: this_sector = %u.%u, "
-		       "extents[0].disk_off = %u.%u\n",
-		       HILO(fe->this_sector), HILO(fe->extents[0].disk_off));
-
-	if (ocfs_inc_icount(inode) < 0)
-		BUG();
-	oin->inode = inode;
-
-	ocfs_populate_inode (inode, fe, mode, oin, true);
-	insert_inode_hash (inode);
-	ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
-	d_instantiate (dentry, inode);
-
-	handle->new_file_lockid = fe->this_sector;
 	OCFS_BH_PUT_DATA(new_fe_bh);
 	fe = NULL;
 
+	LOG_TRACE_ARGS("ocfs2: Created inode %u (voteoff: %u.%u, "
+		       "feoff: %u.%u)\n", inode->i_ino, 
+		       HILO(GET_INODE_VOTEOFF(inode)), 
+		       HILO(GET_INODE_FEOFF(inode)));
+
+	d_instantiate (dentry, inode);
 	ocfs_commit_trans(handle);
 
 	status = 0;
@@ -588,15 +579,6 @@
 	__u64 parentOff, fileOff;
 	bool do_release = false;
 	struct inode *parentInode = dentry->d_parent->d_inode;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-	/* 
-	 * On a 2.6 kernel sys_unlink will increment the inode 
-	 * count before calling the filesystem unlink function
-	 */
-	int max_cnt = 3; /* one for this process, inode hash, and sys_unlink */
-#else
-	int max_cnt = 2; /* one for this process and one for inode hash */
-#endif
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", dir, dentry,
                         dentry->d_name.len, dentry->d_name.name);
@@ -614,15 +596,10 @@
 
 	status = -EBUSY;
 
-	if (oin && oin->inode)
-		max_cnt++;
-
-	if (atomic_read (&inode->i_count) > max_cnt || atomic_read (&dentry->d_count) > 2) {
-		LOG_TRACE_ARGS ("i_count > %d or d_count > 2\n", max_cnt);
-	} else if (!ocfs_empty(dentry)) {
+	if (!ocfs_empty(dentry)) {
 		LOG_TRACE_STR ("dentry is not empty, cannot delete");
-	} else if (oin && oin->open_hndl_cnt > 0) {
-		LOG_TRACE_ARGS ("Cannot remove an open file (open_hndl_cnt = %u, fileOff = %u.%u, d_count=%u)\n", oin->open_hndl_cnt, HILO(fileOff), atomic_read(&dentry->d_count));
+	} else if (OCFS_I(inode)->open_hndl_cnt > 0) {
+		LOG_TRACE_ARGS ("Cannot remove an open file (open_hndl_cnt = %u, fileOff = %u.%u, d_count=%u)\n", OCFS_I(inode)->open_hndl_cnt, HILO(fileOff), atomic_read(&dentry->d_count));
 	} else if (oin && oin->oin_flags & OCFS_OIN_ROOT_DIRECTORY) {
 		LOG_TRACE_STR ("Cannot delete the root directory");
 		status = -EPERM;
@@ -637,7 +614,7 @@
 		if (oin) {
 			spin_lock(&oin_num_ext_lock);
 			if (oin->num_extends) {
-				LOG_TRACE_ARGS ("Cannot remove a file with = "
+				LOG_ERROR_ARGS ("Cannot remove a file with = "
 						"%u, pending extends (fileOff "
 						"= %u.%u)\n", oin->num_extends,
 						HILO(fileOff));
@@ -669,17 +646,12 @@
 			}
 			goto bail;
 		} 
-		
-		if (oin)
-			ocfs_release_cached_oin (osb, oin);
 	}
 
 	if (do_release)
 	{
-		if (oin)
-			ocfs_release_oin (oin, true);
-		else {
-                	if (fileOff != -1) {
+		if (!oin) {
+			if (fileOff != -1) {
                         	tmpstat = ocfs_lookup_sector_node (osb, fileOff, &lockres);
                         	if (tmpstat >= 0 && lockres) {
                                 	ocfs_remove_sector_node (osb, lockres);
@@ -798,8 +770,9 @@
 	} else if (handle) {
 		if (id2_locked)
 			ocfs_journal_add_lock(handle, id2, type2, flags2, 
-					      *res2, *bh2);
-		ocfs_journal_add_lock(handle, id1, type1, flags1, *res1, *bh1);
+					      *res2, *bh2, inode2);
+		ocfs_journal_add_lock(handle, id1, type1, flags1, *res1, *bh1, 
+				      inode1);
 	}
 
 	LOG_EXIT_STATUS(status);
@@ -935,7 +908,6 @@
 	__u32 newfe_flags = 0;
 	__u32 newfe_lockid = 0;
 	int needs_trunc = 0;
-	int max_cnt = 2;
 
 	LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, 0x%08x, 0x%08x, from='%*s' to='%*s')\n",
 			old_dir, old_dentry, new_dir, new_dentry,
@@ -966,13 +938,7 @@
 			BUG();
 	}
 
-	if (oldOIN && oldOIN->inode)
-		max_cnt++;
-
-	if (atomic_read (&old_inode->i_count) > max_cnt) {
-		status = -EBUSY;
-		goto bail;
-	} else if (atomic_read (&old_dentry->d_count) > 2) {
+	if (atomic_read (&old_dentry->d_count) > 2) {
 		shrink_dcache_parent (old_dentry);
 		if (atomic_read (&old_dentry->d_count) > 2) {
 			status = -EBUSY;
@@ -988,7 +954,7 @@
 	}
 
 	if (oldOIN) {
-		if (oldOIN->open_hndl_cnt != 0) {
+		if (OCFS_I(old_dentry->d_inode)->open_hndl_cnt != 0) {
 			status = -EBUSY;
 			goto bail;
 		}
@@ -1010,7 +976,7 @@
 			/* OIN exists and it's not marked for deletion! */
 			ocfs_down_sem (&(newOIN->main_res), true);
 			OCFS_SET_FLAG (newOIN->oin_flags, OCFS_OIN_IN_USE);
-			status = ocfs_verify_update_oin (osb, newOIN, &needs_trunc);
+			status = ocfs_verify_update_inode (osb, new_dentry->d_inode, &needs_trunc);
 			ocfs_up_sem (&(newOIN->main_res));
 			delete_target_oin = true;
 			if (needs_trunc)
@@ -1258,18 +1224,8 @@
 				LOG_ERROR_STATUS(status);
 		}
 
-		if (oldOIN) {
-			ocfs_release_cached_oin (osb, oldOIN);
-			ocfs_release_oin (oldOIN, true);
-			if (new_dentry->d_inode)
+		if (oldOIN && new_dentry->d_inode)
 				fsync_inode_buffers(old_dentry->d_inode);
-		}
-
-		/* delete the targets oin here as we've just blown it away! */
-		if (kill_newfe && newOIN && delete_target_oin) {
-			ocfs_release_cached_oin (osb, newOIN);
-			ocfs_release_oin (newOIN, true);
-		}
 	}
 
 	old_inode->i_nlink++;
@@ -1366,8 +1322,7 @@
 		goto bail;
 	}
 
-	inode->u.generic_ip = kmem_cache_alloc(OcfsGlobalCtxt.inode_cache, GFP_NOFS);
-	if (!inode->u.generic_ip) {
+	if (ocfs_inode_init_private(inode)) {
 		LOG_ERROR_STATUS(status = -ENOMEM);
 		goto bail;
 	}
@@ -1421,7 +1376,7 @@
 	OCFS_BH_PUT_DATA(new_fe_bh);
 	fe = NULL;
 
-	status = ocfs_extend_file (osb, parent_off, NULL, newsize, file_off, handle, inode, NULL);
+	status = ocfs_extend_file (osb, newsize, file_off, handle, inode, NULL);
 	if (status < 0) {
 		if (status != -ENOSPC && status != -EINTR) {
 			LOG_ERROR_ARGS ("Failed to extend file to %u.%u", HILO (newsize));
@@ -1430,20 +1385,8 @@
 		}
 		goto abort_trans;
 	}
-
-	status = ocfs_create_oin_from_entry(osb, new_fe_bh, &oin, 
-					    parent_off, NULL);
-	if (status < 0) {
-		LOG_ERROR_STATUS(status);
-		goto abort_trans;
-	}
-
 	inode->i_rdev = OCFS_NODEV;
 
-	if (ocfs_inc_icount(inode) < 0)
-		BUG();
-	oin->inode = inode;
-
 	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(new_fe_bh); /* read */
 	ocfs_populate_inode (inode, fe, S_IFLNK | S_IRWXUGO, oin, true);
 	OCFS_BH_PUT_DATA(new_fe_bh);
@@ -1451,6 +1394,19 @@
 
 	inode->i_size = newsize;
 	inode->i_blocks = (newsize + sb->s_blocksize) >> sb->s_blocksize_bits;
+
+	status = ocfs_inode_open(osb, new_fe_bh, handle, inode);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto abort_trans;
+	}
+
+	status = ocfs_inode_fill_ext_map(osb, new_fe_bh, inode);
+	if (status < 0) {
+		LOG_ERROR_STATUS(status);
+		goto abort_trans;
+	}
+
 	insert_inode_hash (inode);
 	ocfs_inode_hash_bind(osb, GET_INODE_VOTEOFF(inode), inode);
 	d_instantiate (dentry, inode);
@@ -1484,6 +1440,7 @@
 	if (status < 0)
 		ocfs_bh_sem_hash_cleanup_pid(ocfs_getpid());
 
+
 	LOG_EXIT_STATUS (status);
 	return status;
 }				/* ocfs_symlink */
@@ -1864,8 +1821,11 @@
 
 	if (inode && status == 0 && !(flags & FLAG_DEL_INODE)) {
 		SET_INODE_DELETED(inode);
-		LOG_TRACE_ARGS("removing inode %lu, voteoff = %u.%u\n",
-		       inode->i_ino, HILO(GET_INODE_VOTEOFF(inode)));
+//		printk("ocfs2: removing inode (%p, %p) %lu, voteoff = %u.%u, "
+//		       "feoff = %u.%u\n", inode, inode->u.generic_ip,
+//		       inode->i_ino, 
+//			       HILO(GET_INODE_VOTEOFF(inode)), 
+//			       HILO(GET_INODE_FEOFF(inode)));
 		ocfs_inode_hash_remove(&osb->inode_hash, 
 				       GET_INODE_VOTEOFF(inode));
 	}

Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/nm.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -31,8 +31,9 @@
 
 /* for lack of a better name... protects oin->num_extends. */
 spinlock_t oin_num_ext_lock = SPIN_LOCK_UNLOCKED;
+struct semaphore recovery_list_sem;
 
-static inline int get_process_vote_action(ocfs_super * osb, ocfs_lock_res *lockres, __u32 node_num, __u32 flags, int status, bool *master_alive, ocfs_inode **oin);
+static inline int get_process_vote_action(ocfs_super * osb, ocfs_lock_res *lockres, __u32 node_num, __u32 flags, int status, bool *master_alive, ocfs_inode **oin, struct inode *inode);
 static int ocfs_disk_update_resource (ocfs_super * osb, ocfs_lock_res * lock_res, struct buffer_head **bh, __u32 timeout, struct inode *inode);
 static int ocfs_search_commited(ocfs_super *osb, ocfs_lock_res *lockres);
 static int ocfs_schedule_process_vote(ocfs_super *osb, struct buffer_head *bh, int vote_node);
@@ -43,6 +44,7 @@
 {
 	ocfs_super *osb;
 	ocfs_lock_res *lockres;
+	struct inode *inode;
 } ocfs_ro_cache_drop_ctxt;
 
 
@@ -658,7 +660,7 @@
 }				/* ocfs_find_update_res */
 
 static inline int get_process_vote_action(ocfs_super * osb, ocfs_lock_res *lockres, __u32 node_num, 
-					  __u32 flags, int status, bool *master_alive, ocfs_inode **oin)
+					  __u32 flags, int status, bool *master_alive, ocfs_inode **oin, struct inode *inode)
 {
 	int vote_type = INVALID_REQUEST;
 	bool my_node_wins = false;
@@ -668,6 +670,9 @@
 		       HILO(lockid), node_num, flags);
 
 	*oin = NULL;
+	if (inode)
+		*oin = GET_INODE_OIN(inode);
+
 	*master_alive = true;
 	if (status < 0) {
 		if (status == -ETIMEDOUT) {
@@ -680,8 +685,6 @@
 			 lockres->master_node_num, OCFS_MAXIMUM_NODES);
 		my_node_wins = lockres->vote_state & LOCK_STATE_IN_VOTING &&
 			node_num < osb->node_num;
-		if (lockres->oin)
-			*oin = lockres->oin;
 	}
 
 	if (flags & FLAG_DROP_READONLY) {
@@ -802,8 +805,9 @@
 	ocfs_publish *publish = (disk_vote ? ctxt->u.publish : NULL);
 	ocfs_dlm_msg *dlm_msg = (comm_vote ? ctxt->u.dlm_msg : NULL);
 	__u32 node_num = ctxt->node_num;
-	__u64 lock_id, seq_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);
 
@@ -822,17 +826,38 @@
 		flags = publish->vote_type;
 		lock_id = publish->dir_ent;
 		seq_num = publish->publ_seq_num;
+		fe_off = publish->fe_off;
 	} else {
 		ocfs_dlm_req_master *req_master = (ocfs_dlm_req_master *)dlm_msg->msg_buf;
 		flags = req_master->flags;
 		lock_id = req_master->lock_id;
 		seq_num = req_master->lock_seq_num;
+		fe_off = req_master->fe_off;
 	}
 	lockflags = (lock_id >= osb->vol_layout.bitmap_off ? OCFS_BH_CACHED : 0);
 	
 	LOG_TRACE_ARGS ("node=%u, id=%u.%u, seq=%u.%u\n", node_num,
 			HILO (lock_id), HILO (seq_num));
 
+	/* delete / rename is slightly different -- we don't want to
+	 * look up the inode in the release case -- it should already
+	 * be gone. Eventually what we'll really want to do is get it
+	 * via the old offsets and set the new ones. */
+	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);
+
+	if (inode) {
+		/* we only need i_sem for some of the operations
+		 * below, but due to lock ordering, we want to take it
+		 * before we acquire_lockres. */
+		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);
 		status = ocfs_read_bh(osb, offset, &vote_bh, 0, NULL);
@@ -842,15 +867,6 @@
 		}
 	}
 
-	inode = ocfs_inode_hash_lookup(osb, lock_id, false);
-	if (inode) {
-		/* we only need i_sem for some of the operations
-		 * below, but due to lock ordering, we want to take it
-		 * before we acquire_lockres. */
-		down(&inode->i_sem);
-		have_i_sem = true;
-	}
-
 	status = ocfs_find_update_res (osb, lock_id, &lockres, NULL, NULL,
 					(OCFS_NM_HEARTBEAT_TIME/2), inode);
 	if (status < 0) {
@@ -868,14 +884,16 @@
 	}
 
 	vote_type = get_process_vote_action(osb, lockres, node_num, flags, 
-					    status, &master_alive, &oin);
+					    status, &master_alive, &oin, inode);
 
 #ifdef VERBOSE_PROCESS_VOTE
-	printk("(%u) ocfs_process_vote: %s request for lockid: %u.%u, action: (%u) %s, type: %s\n", ocfs_getpid(),
+	printk("(%u) ocfs_process_vote: %s request for lockid: %u.%u, fe_off: %u.%u, action: (%u) %s, type: %s\n", ocfs_getpid(),
 	       flags & FLAG_RELEASE_LOCK ? "RELEASE" : 
-	       (flags & FLAG_ACQUIRE_LOCK ? "ACQUIRE" : "MODIFY"), lock_id,
+	       (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
@@ -937,8 +955,8 @@
 		case UPDATE_OIN_INODE:
 			LOG_TRACE_STR("UPDATE_OIN_INODE");
 			ocfs_down_sem (&(oin->main_res), true);
-			oin->needs_verification = true;
-			tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
+			OCFS_I(inode)->needs_verification = true;
+			tmpstat = ocfs_verify_update_inode(osb, inode, &needs_trunc);
 			if (tmpstat < 0)
 				LOG_ERROR_STATUS (tmpstat);
 			ocfs_up_sem (&(oin->main_res));
@@ -953,7 +971,6 @@
 		
 		case DELETE_RENAME:
 			LOG_TRACE_STR("DELETE_RENAME");
-			oin = lockres->oin;
 
 			/* all cases except open_hndl_cnt > 0 will vote YES */
 			vote_response = FLAG_VOTE_NODE;
@@ -961,8 +978,8 @@
 			if (oin) {
 				oin_sem = &(oin->main_res);
 				ocfs_down_sem (oin_sem, true);
-				oin->needs_verification = true;
-				tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
+				OCFS_I(inode)->needs_verification = true;
+				tmpstat = ocfs_verify_update_inode(osb, inode, &needs_trunc);
 				if (tmpstat < 0)
 					LOG_ERROR_STATUS (tmpstat);
 		
@@ -977,10 +994,7 @@
 					ocfs_down_sem (oin_sem, true);
 				}
 
-				/* make sure that lockres->oin has not changed */
-				oin = lockres->oin;
-
-				if (oin && oin->open_hndl_cnt > 0) {
+				if (OCFS_I(inode)->open_hndl_cnt > 0) {
 					/* the NO vote for delete/rename */
 					vote_response = FLAG_VOTE_OIN_ALREADY_INUSE;
 				} else if (oin) {
@@ -1138,7 +1152,7 @@
 					status = 0;
 					if (!lockres->readonly_dropping) {
 						ocfs_get_lockres(lockres);
-						if (ocfs_drop_readonly_cache_lock(osb, lockres) < 0) {
+						if (ocfs_drop_readonly_cache_lock(osb, lockres, inode) < 0) {
 							LOG_ERROR_STATUS(status = -ENOMEM);
 							ocfs_put_lockres(lockres);
 						}
@@ -1315,17 +1329,12 @@
 	if (flags & (FLAG_FILE_EXTEND|FLAG_FILE_TRUNCATE) && 
 	    ((flags & FLAG_ACQUIRE_LOCK && vote_response==FLAG_VOTE_NODE) ||
 	    (flags & FLAG_RELEASE_LOCK))) {
-		oin = NULL;
-		if (lockres && lockres->oin)
-			oin = lockres->oin;
-		
+
 		LOG_TRACE_ARGS("responding YES to %s %s request, oin=%p, node=%u\n", flags & FLAG_FILE_EXTEND ?
 				      "extend" : "truncate", flags & FLAG_RELEASE_LOCK ? 
 				      "release" : "acquire", oin, node_num);
 
 		if (oin && (flags & FLAG_ACQUIRE_LOCK)) {
-			ocfs_down_sem (&(osb->osb_res), true);
-
 			spin_lock(&oin_num_ext_lock);
 
 			if (oin->num_extends < 0)
@@ -1336,7 +1345,6 @@
 				spin_unlock(&oin_num_ext_lock);
 			} else {
 				spin_unlock(&oin_num_ext_lock);
-				ocfs_up_sem (&(osb->osb_res));
 
 				/* take the extend_sem on behalf of
 				 * this other node. It won't be
@@ -1347,15 +1355,15 @@
 				 * inode. */
 				down(&oin->extend_sem);
 
-				ocfs_down_sem (&(osb->osb_res), true);
+				down(&recovery_list_sem);
 				spin_lock(&oin_num_ext_lock);
 				oin->num_extends++;
-				list_add_tail(&oin->recovery_list, &osb->lock_recovery_lists[node_num]);
+				list_add_tail(&OCFS_I(inode)->recovery_list, &osb->lock_recovery_lists[node_num]);
 				spin_unlock(&oin_num_ext_lock);
+				up(&recovery_list_sem);
 			}
-			ocfs_up_sem (&(osb->osb_res));
 		} else if (oin && (flags & FLAG_RELEASE_LOCK)) {
-			ocfs_down_sem (&(osb->osb_res), true);
+			down(&recovery_list_sem);
 			spin_lock(&oin_num_ext_lock);
 			oin->num_extends--;
 			
@@ -1363,13 +1371,13 @@
 				BUG();
 			
 			if (!oin->num_extends) {
-				list_del(&oin->recovery_list);
+				list_del(&OCFS_I(inode)->recovery_list);
 
 				up(&oin->extend_sem);
 			}
 			spin_unlock(&oin_num_ext_lock);
 
-			ocfs_up_sem (&(osb->osb_res));
+			up(&recovery_list_sem);
 		}
 	}
 
@@ -1461,22 +1469,23 @@
 {
 	struct list_head *iter, *temp;
 	ocfs_inode *oin;
-	
+	struct inode *inode;
+	ocfs_inode_private *i;
+
 	LOG_ENTRY_ARGS("(node_num = %u)\n", node_num);
 
-	ocfs_down_sem (&(osb->osb_res), true);
+	down(&recovery_list_sem);
 	list_for_each_safe (iter, temp, &osb->lock_recovery_lists[node_num]) {
-		oin = list_entry (iter, ocfs_inode, recovery_list);
-		if (oin->obj_id.type != OCFS_TYPE_OIN) {
-			LOG_ERROR_ARGS("node %u recovery: invalid oin!\n", node_num);
-			continue;
-		}
+		i = list_entry (iter, ocfs_inode_private, recovery_list);
 
+		inode = i->inode;
+		oin = GET_INODE_OIN(inode);
 		spin_lock(&oin_num_ext_lock);
 		
 		if (oin->num_extends) {
 			oin->num_extends = 0;
-			list_del(&oin->recovery_list);
+			list_del(&OCFS_I(inode)->recovery_list);
+			INIT_LIST_HEAD(&OCFS_I(inode)->recovery_list);
 			up(&oin->extend_sem);
 		} else
 			LOG_ERROR_STR("oin is in recovery list, but has zero extend counter value!");
@@ -1484,12 +1493,13 @@
 		spin_unlock(&oin_num_ext_lock);
 	}
 
-	ocfs_up_sem (&(osb->osb_res));
+	up (&recovery_list_sem);
 
 	LOG_EXIT();
 }
 
-int ocfs_drop_readonly_cache_lock(ocfs_super *osb, ocfs_lock_res *lockres)
+int ocfs_drop_readonly_cache_lock(ocfs_super *osb, ocfs_lock_res *lockres, 
+				  struct inode *inode)
 {
 	ocfs_ro_cache_drop_ctxt *arg;
 	arg = kmalloc(sizeof(ocfs_ro_cache_drop_ctxt), GFP_KERNEL);
@@ -1498,6 +1508,9 @@
 
 	arg->osb = osb;
 	arg->lockres = lockres;
+	arg->inode = inode;
+	if (inode)
+		atomic_inc(&inode->i_count);
 
 	kernel_thread(_ocfs_drop_readonly_cache_lock, (void *) arg,
 		      CLONE_VM | CLONE_FS | CLONE_FILES);
@@ -1509,6 +1522,7 @@
 	ocfs_ro_cache_drop_ctxt *ctxt = (ocfs_ro_cache_drop_ctxt *)arg;
 	ocfs_super *osb = ctxt->osb;
 	ocfs_lock_res *lockres = ctxt->lockres;
+	struct inode *inode = ctxt->inode;
 	__u64 map;
 	int status = 0;
 
@@ -1548,7 +1562,8 @@
 		/* cannot hold lockres while waiting for vote */
 		ocfs_release_lockres(lockres);
 
-		status = ocfs_send_readonly_drop_message(osb, lockres, map);
+		status = ocfs_send_readonly_drop_message(osb, lockres, map, 
+							 inode);
 		if (status >= 0) {
 			ocfs_acquire_lockres(lockres);
 			break;
@@ -1571,6 +1586,8 @@
 leave:
 	ocfs_release_lockres(lockres);
 	ocfs_put_lockres(lockres);
+	if (inode)
+		iput(inode);
 	kfree(arg);
 	return status;
 }

Modified: trunk/src/oin.c
===================================================================
--- trunk/src/oin.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/oin.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -31,43 +31,36 @@
 extern spinlock_t oin_num_ext_lock;
 
 /*
- * ocfs_verify_update_oin()
- *
- * This function searches the cached oin list for a volume for a given
- * filename. We currently cache all the oin's. We should hash this list.
- *
+ * ocfs_verify_update_inode()
  */ 
-int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin, int *needs_trunc)
+int ocfs_verify_update_inode (ocfs_super * osb, struct inode * inode, int *needs_trunc)
 {
 	int status = 0;
 	struct buffer_head *fe_bh = NULL;
 	ocfs_file_entry *fe = NULL;
 	ocfs_lock_res *pLockRes;
-	struct inode *inode = NULL;
         struct list_head *iter;
         struct list_head *temp_iter;
         int disk_len;
 	__u64 offset;
 	ocfs_disk_lock dlock;   /* ???: is this too much on the stack? */
+	ocfs_inode *oin = NULL;
 
 	/* We are setting the oin Updated flag in the end. */
 	LOG_ENTRY ();
 
-	OCFS_ASSERT (oin);
+	OCFS_ASSERT (inode);
 
-	if (!oin->inode) {
-		printk(KERN_ERR "ocfs2: oin has no inode!\n");
-		BUG();
-	}
+	oin = GET_INODE_OIN(inode);
 
 	*needs_trunc = 0;
 
 	/* This read of feoff from the inode depends on all callers to
 	 * make sure that unlink or rename can't be change it while we're
 	 * in here! */
-	offset = GET_INODE_FEOFF(oin->inode);
+	offset = GET_INODE_FEOFF(inode);
 
-	status = ocfs_read_bh(osb, offset, &fe_bh, OCFS_BH_COND_CACHED, oin->inode);
+	status = ocfs_read_bh(osb, offset, &fe_bh, OCFS_BH_COND_CACHED, inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
 		goto leave;
@@ -93,13 +86,6 @@
 		}
 
                 disk_len = strlen(fe->filename);
-		inode = oin->inode;
-		if (inode == NULL) {
-			LOG_ERROR_STR ("oin has no matching inode!!!!");
-			OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_INVALID);
-			status = -ENOENT;
-			goto leave;
-		}
 
                 status = -ENOENT;
                 list_for_each_safe (iter, temp_iter, &(inode->i_dentry)) {
@@ -119,7 +105,7 @@
 
 		if ((oin->alloc_size != (__s64) fe->alloc_size) ||
 		    (inode->i_size != (__s64) fe->file_size) ||
-		    (oin->chng_seq_num != DISK_LOCK_SEQNUM (fe)) ||
+		    (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) {
 
@@ -132,7 +118,7 @@
 			    ("Allocsize, filesize or seq no did not match");
 			oin->alloc_size = fe->alloc_size;
 			inode->i_size = fe->file_size;
-			oin->chng_seq_num = DISK_LOCK_SEQNUM (fe);
+			OCFS_I(inode)->chng_seq_num = DISK_LOCK_SEQNUM (fe);
 
 			inode->i_blocks = (inode->i_size + 512) >> 9;
 			inode->i_uid = fe->uid;
@@ -145,7 +131,7 @@
 			if (!S_ISDIR (inode->i_mode) &&
 			    (oin->alloc_size != (__s64) fe->alloc_size ||
 			     inode->i_size != (__s64) fe->file_size ||
-			     oin->chng_seq_num != DISK_LOCK_SEQNUM (fe))) {
+			     OCFS_I(inode)->chng_seq_num != DISK_LOCK_SEQNUM (fe))) {
 				*needs_trunc = 1;
 			}
 
@@ -257,7 +243,7 @@
 
 leave:
 	if (status == 0)
-		OIN_UPDATED (oin);
+		OCFS_I(inode)->needs_verification = false;
 
 	if (fe_bh) {
 		if (fe)
@@ -267,17 +253,84 @@
 
 	LOG_EXIT_STATUS (status);
 	return status;
-}				/* ocfs_verify_update_oin */
+}				/* ocfs_verify_update_inode */
 
+/* you should be holding i_sem and main_res in this function. 
+ *
+ * Put a lockres on the oin and if needed add ourselves to the open
+ * map. Only call this on 1st open of a file. Marks the oin as "in use"
+ */
+int ocfs_inode_open(ocfs_super *osb, struct buffer_head *fe_bh, 
+		    ocfs_journal_handle *handle, struct inode *inode)
+{
+	int status = 0;
+	ocfs_inode *oin;
+	ocfs_file_entry *fe = NULL;
+	bool local_handle = true;
+	__u32 flags = OCFS_OIN_IN_USE;
 
+	LOG_ENTRY ();
+
+	if (handle)
+		local_handle = false;
+
+	oin = GET_INODE_OIN(inode);
+
+	fe = (ocfs_file_entry *) OCFS_BH_GET_DATA_READ(fe_bh); /* read */
+
+	/* why do we update these here? */
+	oin->alloc_size = fe->alloc_size;
+	OCFS_I(inode)->chng_seq_num = DISK_LOCK_SEQNUM (fe);
+	if (fe->this_sector == 0)
+		LOG_ERROR_STR ("this_sector=0");
+
+	OCFS_BH_PUT_DATA(fe_bh);
+
+	flags |= oin->oin_flags;
+
+	if (!(flags & OCFS_OIN_ROOT_DIRECTORY)) {
+		if (local_handle) {
+			handle = ocfs_start_trans(osb, OCFS_OPEN_CREDITS);
+			if (!handle) {
+				LOG_ERROR_STATUS(status = -ENOMEM);
+				goto leave;
+			}
+			/* we want this to be a really fast transaction. */
+			ocfs_handle_set_sync(handle, false);
+			ocfs_handle_set_checkpoint(handle, false);
+		}
+
+		status = ocfs_create_update_lock(osb, GET_INODE_VOTEOFF(inode),
+						 flags, false, inode, handle);
+		if (status < 0) {
+			if (status != -EINTR)
+				LOG_ERROR_STATUS (status);
+			goto leave;
+		}
+	}
+	oin->oin_flags |= OCFS_OIN_IN_USE;
+
+leave:
+	if (local_handle && handle) {
+		if (status < 0)
+			ocfs_abort_trans(handle);
+		else
+			ocfs_commit_trans(handle);
+	}
+
+	LOG_EXIT_STATUS (status);
+	return status;
+}
+
+
+
 /* ocfs_create_oin_from_entry()
  *
  */
-int ocfs_create_oin_from_entry (ocfs_super * osb, struct buffer_head * fe_bh, ocfs_inode ** new_oin, __u64 parent_dir_off, struct inode *inode)
+int ocfs_inode_fill_ext_map(ocfs_super * osb, struct buffer_head * fe_bh, struct inode *inode)
 {
 	int status = 0;
 	ocfs_inode *oin;
-	__u64 lockId;
 	int j;
 	__s64 tempVbo;
 	__s64 tempLbo;
@@ -291,7 +344,7 @@
 
 	LOG_ENTRY ();
 
-	*new_oin = NULL;
+	oin = GET_INODE_OIN(inode);
 
 	/* get a copy of fe, used readonly in this path and */
 	/* ocfs_create_new_oin will deadlock if fe_bh is locked */
@@ -303,134 +356,92 @@
 	tmp = OCFS_BH_GET_DATA_READ(fe_bh); /* read */
 	memcpy(fe, tmp, sizeof(ocfs_file_entry));
 	OCFS_BH_PUT_DATA(fe_bh);
+	tempoff = fe->this_sector;
 
-	/* We have a new file on disk , so create an oin for the file */
-	status = ocfs_create_new_oin (&oin, fe->alloc_size, osb);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
+	/* we don't want to do the extent map stuff for a directory. */
+	if (fe->attribs & OCFS_ATTRIB_DIRECTORY)
 		goto leave;
-	}
 
-	oin->parent_dirnode_off = parent_dir_off;
-	oin->chng_seq_num = DISK_LOCK_SEQNUM (fe);
-
-	if (fe->this_sector == 0)
-		LOG_ERROR_STR ("this_sector=0");
-
-	tempoff = fe->this_sector;
-
-	/* The oins gets Linked into the osb in this function */
-
-	if (fe->attribs & OCFS_ATTRIB_DIRECTORY) {
-		lockId = fe->extents[0].disk_off;
-
-		status = ocfs_initialize_oin (oin, osb,
-				OCFS_OIN_DIRECTORY | OCFS_OIN_IN_USE, 
-				tempoff, lockId, false, inode);
-		if (status < 0) {
-			if (status != -EINTR)
-				LOG_ERROR_STATUS (status);
-			goto leave;
+	if (fe->local_ext) {
+		for (j = 0; j < fe->next_free_ext; j++) {
+			tempVbo = fe->extents[j].file_off;
+			tempLbo = fe->extents[j].disk_off;
+			tempSize = fe->extents[j].num_bytes;
+			
+			/* Add the Extent to extent map */
+			bRet = ocfs_add_extent_map_entry (osb, 
+							  &oin->map,
+							  tempVbo, 
+							  tempLbo, 
+							  tempSize);
+			if (!bRet) {
+				LOG_ERROR_STATUS (status = -ENOMEM);
+				goto leave;
+			}
 		}
 	} else {
-		__u32 flags = OCFS_OIN_IN_USE;
-
-		if((DISK_LOCK_FILE_LOCK(fe) == OCFS_DLM_ENABLE_CACHE_LOCK)  
-			&& (DISK_LOCK_CURRENT_MASTER(fe) == osb->node_num)) 
-			flags |= OCFS_OIN_CACHE_UPDATE;
-		status = ocfs_initialize_oin (oin, osb, flags, 
-					    tempoff, tempoff, false, inode);
+		__u64 next_data_ext;
+		
+		/* Extents are branched and we are no longer using */
+		/* Local Extents for this File Entry. */
+		
+		status = ocfs_get_leaf_extent (osb, fe, 0, &extent_bh, inode);
 		if (status < 0) {
-			if (status != -EINTR)
-				LOG_ERROR_STATUS (status);
+			LOG_ERROR_STATUS (status);
 			goto leave;
 		}
-
-		if (fe->local_ext) {
-			for (j = 0; j < fe->next_free_ext; j++) {
-				tempVbo = fe->extents[j].file_off;
-				tempLbo = fe->extents[j].disk_off;
-				tempSize = fe->extents[j].num_bytes;
-
+		
+		while (1) {
+			extent = (ocfs_extent_group *) OCFS_BH_GET_DATA_READ(extent_bh); /* read */
+			
+			if (!IS_VALID_EXTENT_DATA (extent)) {
+				LOG_ERROR_STATUS(status = -EFAIL);
+				goto leave;
+			}
+			
+			for (j = 0; j < extent->next_free_ext; j++) {
+				tempVbo = extent->extents[j].file_off;
+				tempLbo = extent->extents[j].disk_off;
+				tempSize = extent->extents[j].num_bytes;
+				
 				/* Add the Extent to extent map */
-				bRet = ocfs_add_extent_map_entry (osb, 
-								  &oin->map,
-								  tempVbo, 
-								  tempLbo, 
-								  tempSize);
+				bRet =
+					ocfs_add_extent_map_entry (osb,
+								   &oin->map,
+								   tempVbo,
+								   tempLbo,
+								   tempSize);
 				if (!bRet) {
-					LOG_ERROR_STATUS (status = -ENOMEM);
+					LOG_ERROR_STATUS (status =
+							  -ENOMEM);
 					goto leave;
 				}
 			}
-		} else {
-			__u64 next_data_ext;
-
-			/* Extents are branched and we are no longer using */
-			/* Local Extents for this File Entry. */
-
-			status = ocfs_get_leaf_extent (osb, fe, 0, &extent_bh, inode);
-			if (status < 0) {
-				LOG_ERROR_STATUS (status);
-				goto leave;
-			}
-
-			while (1) {
-				extent = (ocfs_extent_group *) OCFS_BH_GET_DATA_READ(extent_bh); /* read */
-
-				if (!IS_VALID_EXTENT_DATA (extent)) {
-					LOG_ERROR_STATUS(status = -EFAIL);
+			
+			if (extent->next_data_ext > 0) {
+				if (!extent->next_data_ext) {
+					LOG_ERROR_STATUS (status = -EFAIL);
 					goto leave;
 				}
+				next_data_ext = extent->next_data_ext;
+				OCFS_BH_PUT_DATA(extent_bh);
+				extent = NULL;
+				extent_bh = NULL;
 
-				for (j = 0; j < extent->next_free_ext; j++) {
-					tempVbo = extent->extents[j].file_off;
-					tempLbo = extent->extents[j].disk_off;
-					tempSize = extent->extents[j].num_bytes;
-
-					/* Add the Extent to extent map */
-					bRet =
-					    ocfs_add_extent_map_entry (osb,
-								   &oin->map,
-								   tempVbo,
-								   tempLbo,
-								   tempSize);
-					if (!bRet) {
-						LOG_ERROR_STATUS (status =
-								  -ENOMEM);
-						goto leave;
-					}
-				}
-
-				if (extent->next_data_ext > 0) {
-					if (!extent->next_data_ext) {
-						LOG_ERROR_STATUS (status = -EFAIL);
-						goto leave;
-					}
-					next_data_ext = extent->next_data_ext;
-					OCFS_BH_PUT_DATA(extent_bh);
-					extent = NULL;
-					extent_bh = NULL;
-
-					status = ocfs_read_bh(osb, 
+				status = ocfs_read_bh(osb, 
 						      next_data_ext, 
 						      &extent_bh, 
 						      OCFS_BH_COND_CACHED, inode);
-					if (status < 0) {
-						LOG_ERROR_STATUS (status);
-						goto leave;
-					}
-				} else
-					break;
-			}
+				if (status < 0) {
+					LOG_ERROR_STATUS (status);
+					goto leave;
+				}
+			} else
+				break;
 		}
 	}
 
-	*new_oin = oin;
 leave:
-	if (!*new_oin && oin)
-		ocfs_release_oin (oin, true);
-
 	/* this fe was a copy */
 	if (fe)
 		ocfs_release_file_entry (fe);
@@ -445,79 +456,6 @@
 	return status;
 }				/* ocfs_create_oin_from_entry */
 
-
-/*
- * ocfs_initialize_oin()
- *
- * Initialize a oin structure and file object. This function is called
- * whenever a file is recognized for the first time.
- */
-int ocfs_initialize_oin (ocfs_inode * oin, ocfs_super * osb, __u32 flags, __u64 file_off, __u64 lock_id, bool new_file, struct inode *inode)
-{
-	int status = 0;
-
-	LOG_ENTRY ();
-
-	if (!(flags & OCFS_OIN_ROOT_DIRECTORY)) {
-		status = ocfs_create_update_lock (osb, oin, lock_id, flags, new_file, inode);
-		if (status < 0) {
-			/* This can be okay as the other node can tell us the 
-			 * file was deleted. */
-			goto leave;
-		}
-	}
-
-	oin->osb = osb;
-	oin->oin_flags |= flags;
-	oin->open_hndl_cnt = 0;
-	oin->journal_inode = false;
-	ocfs_extent_map_init (&oin->map);
-
-leave:
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_initialize_oin */
-
-/*
- * ocfs_create_new_oin()
- *
- * Create a new oin.
- */
-int ocfs_create_new_oin (ocfs_inode ** Returnedoin, __u64 alloc_size, ocfs_super * osb)
-{
-	int status = 0;
-	ocfs_inode *oin = NULL;
-
-	LOG_ENTRY_ARGS("(alloc_size = %u.%u)\n", HILO(alloc_size));
-
-	OCFS_ASSERT (osb);
-
-	oin = ocfs_allocate_oin ();
-	*Returnedoin = oin;
-
-	if (oin == NULL) {
-		LOG_ERROR_STATUS (status = -ENOMEM);
-		goto finally;
-	}
-
-	ocfs_init_sem (&(oin->main_res));
-	init_MUTEX(&(oin->extend_sem));
-	OCFS_SET_FLAG (oin->oin_flags, OCFS_INITIALIZED_MAIN_RESOURCE);
-
-	/*  Initialize the alloc size value here, file size will come
-	 *  later in i_size */
-	oin->alloc_size = alloc_size;
-
-	/* Insert the pointer to osb in the oin and also Initialize
-	 * the OFile list  */
-	oin->osb = osb;
-
-finally:
-
-	LOG_EXIT_STATUS (status);
-	return status;
-}				/* ocfs_create_new_oin */
-
 /* ocfs_create_root_oin()
  *
  */
@@ -525,7 +463,6 @@
 {
 	int status = 0;
 	int tmpstat;
-	ocfs_inode *oin = NULL;
 	ocfs_vol_disk_hdr *volDiskHdr = NULL;
 	struct buffer_head *hdr_bh = NULL;
 	ocfs_lock_res *LockResource = NULL;
@@ -589,36 +526,7 @@
 		/*  if it fails, Release the memory for the OFile we allocated above */
 	}
 
-	/* Create the root directory oin. This is done either here or in */
-	/* FindNewoin's if it fails, Release the memory for the OFile we */
-	/* allocated above */
-	status = ocfs_create_new_oin (&oin, 0ULL, osb);
-	if (status < 0) {
-		LOG_ERROR_STATUS (status);
-		goto finally;
-	}
-
-	/*  This is for root . */
-	status = ocfs_initialize_oin (oin, osb,
-			   OCFS_OIN_DIRECTORY | OCFS_OIN_ROOT_DIRECTORY,
-			   0, osb->vol_layout.root_start_off, true, root);
-	if (status < 0) {
-		if (status != -EINTR)
-			LOG_ERROR_STATUS (status);
-		goto finally;
-	}
-
-	/* put the offset/inode number in the inode cache thingy. */
-	ocfs_inode_hash_insert(osb, osb->vol_layout.root_start_off, 0ULL);
-	// oin->Parentoin = NULL; /*  Root has no parent */
-
-	/*  Set the Rootdirectories root Dir Node */
-
-	osb->oin_root_dir = oin;
-
 finally:
-	if (status < 0 && oin)
-		ocfs_release_oin (oin, true);
 
 	if (hdr_bh) {
 		lock_buffer(hdr_bh);
@@ -631,190 +539,3 @@
 	LOG_EXIT_STATUS (status);
 	return status;
 }				/* ocfs_create_root_oin */
-
-/*
- * ocfs_release_oin()
- *
- */
-void ocfs_release_oin (ocfs_inode * oin, bool FreeMemory)
-{
-	ocfs_lock_res *lockres = NULL;
-	ocfs_super *osb = NULL;
-	struct inode *inode;
-
-	LOG_ENTRY_ARGS ("oin = %p, free = %s\n", oin, FreeMemory? "yes" : "no");
-
-	if (!oin || !oin->osb)
-		goto bail;
-
-	osb = oin->osb;
-	lockres = oin->lock_res;
-
-	if (lockres != NULL) {
-		ocfs_get_lockres (lockres);
-		ocfs_acquire_lockres (lockres);
-		if (lockres->oin == oin)
-			lockres->oin = NULL;
-		ocfs_release_lockres (lockres);
-	}
-
-	ocfs_down_sem (&(osb->osb_res), true);
-	spin_lock(&oin_num_ext_lock);
-	if (oin->num_extends)
-		list_del(&oin->recovery_list);
-	spin_unlock(&oin_num_ext_lock);
-	ocfs_up_sem (&(osb->osb_res));
-
-	inode = (struct inode *) oin->inode;
-
-	if (inode) {
-		CLEAR_INODE_OIN(inode);
-		LOG_TRACE_ARGS ("inode oin cleared / flags: %d / offset: %u.%u\n",
-			inode->i_flags, GET_INODE_FEOFF(inode));
-	}
-
-	ocfs_extent_map_destroy (&oin->map);
-
-	/*  Delete the ocfs_sem objects */
-	if (oin->oin_flags & OCFS_INITIALIZED_MAIN_RESOURCE) {
-		ocfs_del_sem (&(oin->main_res));
-		OCFS_CLEAR_FLAG (oin->oin_flags, OCFS_INITIALIZED_MAIN_RESOURCE);
-	}
-
-	if (FreeMemory) {
-		if (oin->inode) {
-			/* we don't do an iput to avoid recursive
-			 * calls to ocfs_put_inode */
-			atomic_dec(&oin->inode->i_count);
-			oin->inode = NULL;
-		}
-		/* clean out the oin ... why?! */
-		memset(oin, 0, sizeof(ocfs_inode));
-#ifdef OCFS_MEM_DBG
-		ocfs_dbg_slab_free (OcfsGlobalCtxt.oin_cache, oin);
-#else
-		kmem_cache_free (OcfsGlobalCtxt.oin_cache, oin);
-#endif
-		oin = NULL;
-		ocfs_put_lockres (lockres);
-	}
-	ocfs_put_lockres (lockres);
-bail:
-	LOG_EXIT ();
-	return;
-}				/* ocfs_release_oin */
-
-/*
- * ocfs_release_cached_oin()
- *
- */
-void ocfs_release_cached_oin (ocfs_super * osb, ocfs_inode * oin)
-{
-	bool bAcquiredOIN = false;
-	ocfs_lock_res *lockResource = NULL;
-	ocfs_lock_res *val=NULL;
-	struct dentry *dentry;
-	struct list_head *iter;
-	struct list_head *temp_iter;
-	struct inode *inode;
-	int refcount = 0;
-	int status = 0;
-	__u64 feoff = 0;
-
-	LOG_ENTRY_ARGS ("(oin = 0x%08x)\n", oin);
-
-	if (oin == NULL)
-		goto bail;
-
-	/*
-	 * If the OCFS_OSB_FLAGS_BEING_DISMOUNTED flag has
-	 * already been set, then the lockres hash has already
-	 * been cleaned out which means that we have a lock_res
-	 * pointer that points to free memory.
-	 */
-	if (osb->osb_flags & OCFS_OSB_FLAGS_BEING_DISMOUNTED) {
-		oin->lock_res = NULL;
-		goto bail;
-	}
-
-	ocfs_down_sem (&(oin->main_res), true);
-	bAcquiredOIN = true;
-        inode = oin->inode;
-        
-        if (inode) {
-                list_for_each_safe (iter, temp_iter, &(inode->i_dentry)) {
-                        dentry = list_entry (iter, struct dentry, d_alias);
-                        refcount += atomic_read(&dentry->d_count);
-                }
-		feoff = GET_INODE_FEOFF(inode);
-        }
-
-
-        if (refcount != 0 || oin->open_hndl_cnt != 0 || 
-            oin->oin_flags & OCFS_OIN_IN_USE) {
-		if (bAcquiredOIN) {
-			ocfs_up_sem (&(oin->main_res));
-			bAcquiredOIN = false;
-		}
-		goto bail;
-	} else {
-		OCFS_SET_FLAG (oin->oin_flags, OCFS_OIN_IN_TEARDOWN);
-
-		if (bAcquiredOIN) {
-			ocfs_up_sem (&(oin->main_res));
-			bAcquiredOIN = false;
-		}
-
-		lockResource = (ocfs_lock_res *) oin->lock_res;
-		if (lockResource == NULL) {
-			LOG_ERROR_ARGS("lockres=null, feoff = %u.%u\n", 
-				       HILO(feoff));
-
-			goto bail;
-		}
-
-		if (lockResource->signature != 0x55AA) {
-			LOG_ERROR_STR("Invalid lock resource");
-			goto bail;
-		}
-		ocfs_get_lockres (lockResource);
-
-		if (lockResource->sector_num == 0 || lockResource->oin != oin) {
-			LOG_ERROR_STR ("id=0 or oin invalid");
-			goto bail;
-		}
-
-		lockResource->oin = NULL;
-		if (lockResource->in_cache_list) {
-			list_del (& (lockResource->cache_list));
-			lockResource->in_cache_list = false;
-		}
-
-		status = ocfs_lookup_sector_node (osb, lockResource->sector_num, &val);
-		if (status >= 0) {
-			if (val == lockResource)
-				ocfs_remove_sector_node (osb, val);
-			else
-				LOG_ERROR_ARGS("(lres=0x%08x) != (val=0x%08x)",
-					       lockResource, val);
-			ocfs_put_lockres (val);
-		} else {
-			if (status == -EFAIL) {
-				ocfs_put_lockres (oin->lock_res);
-				oin->lock_res = NULL;
-				LOG_TRACE_ARGS ("hashtable already destroyed\n");
-				goto bail;
-			}
-			LOG_ERROR_ARGS("lres=0x%08x is not in the hash!",
-				       lockResource);
-		}
-		ocfs_put_lockres (oin->lock_res);
-		oin->lock_res = NULL;
-	}
-
-bail:
-	ocfs_put_lockres (lockResource);
-	LOG_EXIT ();
-	return;
-}				/* ocfs_release_cached_oin */
-

Modified: trunk/src/super.c
===================================================================
--- trunk/src/super.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/super.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -124,6 +124,8 @@
 MODULE_PARM_DESC(comm_voting, "Enable/Disable network dlm");
 #endif /* Linux 2.4 stuff */
 
+extern struct semaphore recovery_list_sem;
+
 static int ocfs_parse_options (char *options, __u32 * uid, __u32 * gid, bool * reclaim_id);
 static int __init ocfs_driver_entry (void);
 static void __exit ocfs_driver_exit (void);
@@ -220,11 +222,7 @@
 		goto read_super_error;
 	}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)	
-	inode = ocfs_iget(sb, NULL);
-#else
-	inode = iget4(sb, OCFS_ROOT_INODE_NUMBER, 0, NULL);
-#endif
+	inode = osb->root_inode;
 	if (!inode) {
 		status = -EIO;
 		LOG_ERROR_STATUS (status);
@@ -451,6 +449,7 @@
 	OcfsGlobalCtxt.comm_seq_num = 0;
 	spin_unlock (&OcfsGlobalCtxt.comm_seq_lock);
 	
+	init_MUTEX (&recovery_list_sem);
 	/* Initialize the proc interface */
 	ocfs_proc_init ();
 
@@ -740,20 +739,6 @@
 }
 #endif
 
-static void ocfs_inode_init_once(void *p, kmem_cache_t *cachep, 
-				 unsigned long flags)
-{
-        ocfs_inode_private *i = (ocfs_inode_private *) p;
-
-	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-	    SLAB_CTOR_CONSTRUCTOR) {
-		i->oin = NULL;
-		i->voteoff = 0;
-		i->feoff = 0;
-		atomic_set(&i->i_clean_buffer_seq, 0);
-         }	
-}
-
 /*
  * ocfs_initialize_mem_lists()
  *
@@ -762,7 +747,7 @@
 {
 	OcfsGlobalCtxt.inode_cache = kmem_cache_create("ocfs2_inode",
 		 sizeof(ocfs_inode_private), 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
-		 ocfs_inode_init_once, NULL);
+		 NULL, NULL);
 
 	OcfsGlobalCtxt.oin_cache = kmem_cache_create ("ocfs2_oin",
 		sizeof (ocfs_inode) + OCFS_POINTER_SIZE, 0, SLAB_NO_REAP | SLAB_HWCACHE_ALIGN,
@@ -826,6 +811,7 @@
 	ocfs_vol_label *vol_label = NULL;
 	int child_pid, i;
 	struct buffer_head *bhs[] = { NULL, NULL };
+	struct inode *inode = NULL;
 
 	LOG_ENTRY ();
 
@@ -1014,6 +1000,28 @@
 		goto leave;
 	}
 
+	/* Initialize the root inode. */
+	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);
+#else
+	inode = iget4(sb, OCFS_ROOT_INODE_NUMBER, 0, NULL);
+#endif
+	if (!inode) {
+		status = -EIO;
+		LOG_ERROR_STATUS (status);
+		goto leave;
+	}
+	if  (is_bad_inode(inode)) {
+		status = -EIO;
+		LOG_ERROR_STATUS (status);
+		iput(inode);
+		inode = NULL;
+		goto leave;
+	}
+	osb->root_inode = inode;
+	osb->oin_root_dir = GET_INODE_OIN(inode);
+
 	/* Read the publish sector for this node and cleanup dirent being */
 	/* modified when we crashed. */
 	LOG_TRACE_STR ("ocfs_check_volume...");
@@ -1118,7 +1126,6 @@
 		LOG_ERROR_STR("Could not set mounted flag!");
 
 	ocfs_sync_blockdev(sb);
-	ocfs_release_oin (rootoin, true);
 
 	/* Destroy the Hash table */
 	ocfs_hash_destroy (&(osb->root_sect_node), lockres_hash_free_func);

Modified: trunk/src/sysfile.c
===================================================================
--- trunk/src/sysfile.c	2004-04-16 21:49:58 UTC (rev 846)
+++ trunk/src/sysfile.c	2004-04-16 22:38:55 UTC (rev 847)
@@ -537,7 +537,7 @@
 		actualLength =
 		    (__u64) (numClusterAlloc * osb->vol_layout.cluster_size);
 
-		status = ocfs_allocate_extent (osb, NULL, fe_bh, handle,  
+		status = ocfs_allocate_extent (osb, fe_bh, handle,  
 					       actualDiskOffset, actualLength, NULL);
 		if (status < 0) {
 			LOG_ERROR_STATUS (status);



More information about the Ocfs2-commits mailing list