[Ocfs2-commits] mfasheh commits r843 - in branches/nooin/src: . inc

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Apr 6 14:59:15 CDT 2004


Author: mfasheh
Date: 2004-04-06 13:59:13 -0500 (Tue, 06 Apr 2004)
New Revision: 843

Modified:
   branches/nooin/src/alloc.c
   branches/nooin/src/dlm.c
   branches/nooin/src/file.c
   branches/nooin/src/hash.c
   branches/nooin/src/inc/journal.h
   branches/nooin/src/inc/ocfs.h
   branches/nooin/src/inc/proto.h
   branches/nooin/src/inode.c
   branches/nooin/src/journal.c
   branches/nooin/src/namei.c
   branches/nooin/src/nm.c
Log:
This is a big one. Basically rework things so that we can get at inode
anywhere we want in a race free manner - including process_vote
(probably the most important one). Now that we have this, we can
simply hang ocfs_inode off the ocfs_inode_private args and do away
with allocation / deallocation of oin. Slowly, fields can be moved
back to inode after this. Also, this is a major step in the direction
of being able to use i_sem for locking operations, even outside of the
kernels normal context (as in process_vote, etc.)

* Pass the inode down through our locking functions all the way now to
  the very bottom -- ocfs_disk_request_vote and
  ocfs_send_dlm_request_msg.

* Alter the voting message type slightly by adding an fe_off field
  which holds the file entry offset when applicable.

* Rework ocfs_get_inode_from_offset to optionally take voteoff and
  feoff instead of the buffer head, which we don't always have now. This
  function is much more robust now and can work from just about any
  context, including ocfs_process_vote.

* Pass inode through the journals add_lock functions, this way they
  can be passed to ocfs_release_lock even after an operation has
  completed.

* Take out useless code in find_inode (was used waaay back when our
  i_ino wasn't yet unique). More importantly, this code relied on the
  buffer_head existing, which got in the way.

* In read_inode2, read the block off disk if the buffer_head is not
  passed in. This allows callers of iget4 like
  ocfs_get_inode_from_offset to count on the kernel locking to prevent
  races with reading that sector, as read_inode2 will only be called if:
	1) the inode doesn't already exist (and therefore nobody can
	   be doing anything to that sector yet)
	2) only one read_inode2 call will be made, even if multiple
	   people attempt to iget the same inode at the same time.

* With the above tasks complete, we can now reliably lookup/create
  inodes in process_vote. Instead of the call to ocfs_inode_hash_lookup,
  which may or may not give us the inode (it can be created later even
  while we're still processing that vote), we will *always* be able to
  get an inode for a lock request unless one should not exist yet (in
  the case of certain system files for instance). Do not underestimate
  the importance of this. No really, this is important.

* Remove the i_count checks in delete/rename paths as they are not
  necessary and more importantly get in the way now.

* Create the journal inode earlier in ocfs_journal_init and
  ocfs_recover_vol so that they can be passed to acquire_lock.

* Put debugging printks in the acquire_lock and process_vote checks as
  some of this stuff is new.

* Add a sanity check to ocfs_inode_hash_remove

* Port the "trunk" patch to fix the bug in ocfs_rename where the wrong
  inode was being passed to acquire_lock.



Modified: branches/nooin/src/alloc.c
===================================================================
--- branches/nooin/src/alloc.c	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/alloc.c	2004-04-06 18:59:13 UTC (rev 843)
@@ -3114,7 +3114,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: branches/nooin/src/dlm.c
===================================================================
--- branches/nooin/src/dlm.c	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/dlm.c	2004-04-06 18:59:13 UTC (rev 843)
@@ -35,17 +35,17 @@
 
 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);
+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);
 static int ocfs_update_master_on_open (ocfs_super * osb, ocfs_lock_res * lockres, struct inode *inode);
 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);
@@ -75,7 +75,7 @@
  * 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 +161,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 +700,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 +735,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 +772,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), 
@@ -1350,7 +1364,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 +1542,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 +1762,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 +1886,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 +1896,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 +2023,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)
@@ -2095,17 +2109,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 +2134,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: branches/nooin/src/file.c
===================================================================
--- branches/nooin/src/file.c	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/file.c	2004-04-06 18:59:13 UTC (rev 843)
@@ -597,8 +597,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);
@@ -1282,9 +1283,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);

Modified: branches/nooin/src/hash.c
===================================================================
--- branches/nooin/src/hash.c	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/hash.c	2004-04-06 18:59:13 UTC (rev 843)
@@ -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: branches/nooin/src/inc/journal.h
===================================================================
--- branches/nooin/src/inc/journal.h	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/inc/journal.h	2004-04-06 18:59:13 UTC (rev 843)
@@ -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:

Modified: branches/nooin/src/inc/ocfs.h
===================================================================
--- branches/nooin/src/inc/ocfs.h	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/inc/ocfs.h	2004-04-06 18:59:13 UTC (rev 843)
@@ -2150,6 +2150,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
@@ -2324,6 +2325,7 @@
 	__u32 flags;
 	__u64 lock_seq_num;
 	__u8 open_handle;
+	__u64 fe_off;
 } 
 OCFS_GCC_ATTR_PACKALGN
 ocfs_dlm_msg_hdr;

Modified: branches/nooin/src/inc/proto.h
===================================================================
--- branches/nooin/src/inc/proto.h	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/inc/proto.h	2004-04-06 18:59:13 UTC (rev 843)
@@ -51,7 +51,7 @@
 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);
 
@@ -205,7 +205,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 +308,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: branches/nooin/src/inode.c
===================================================================
--- branches/nooin/src/inode.c	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/inode.c	2004-04-06 18:59:13 UTC (rev 843)
@@ -133,8 +133,6 @@
 
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
 
-#define REPOPULATE_INODE 1
-
 /*
  * ocfs_find_inode()
  *
@@ -143,81 +141,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)
@@ -443,6 +386,8 @@
 	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);
 
@@ -492,11 +437,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) {
@@ -533,7 +490,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 */

Modified: branches/nooin/src/journal.c
===================================================================
--- branches/nooin/src/journal.c	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/journal.c	2004-04-06 18:59:13 UTC (rev 843)
@@ -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,16 @@
 
 	/* 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;
-		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->open_hndl_cnt++;
 	SET_INODE_OIN(inode, oin);
-	SET_INODE_JOURNAL(inode);
 	LOG_TRACE_ARGS("oin->alloc_size = %u.%u\n", HI(oin->alloc_size), 
 		       LO(oin->alloc_size));
 
@@ -1467,7 +1468,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 +1499,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 +1523,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,30 +1564,11 @@
 	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);
 	if (status < 0) {
@@ -1581,7 +1578,6 @@
 	status = ocfs_initialize_oin(oin, osb, 0, lock_id, lock_id, false, 
 				     NULL);
 	SET_INODE_OIN(inode, oin);
-	SET_INODE_JOURNAL(inode);
 
 	status = ocfs_force_read_journal(osb, inode->i_size, oin, inode);
 	if (status < 0) {

Modified: branches/nooin/src/namei.c
===================================================================
--- branches/nooin/src/namei.c	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/namei.c	2004-04-06 18:59:13 UTC (rev 843)
@@ -232,7 +232,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, 
@@ -617,9 +618,11 @@
 	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)) {
+// removed this check as technically i don't even think it's legal.
+//	if (atomic_read (&inode->i_count) > max_cnt || atomic_read (&dentry->d_count) > 2) {
+//		LOG_ERROR_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));
@@ -637,7 +640,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));
@@ -798,8 +801,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);
@@ -969,10 +973,11 @@
 	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_inode->i_count) > max_cnt) {
+//		status = -EBUSY;
+//		goto bail;
+//	} else 
+	if (atomic_read (&old_dentry->d_count) > 2) {
 		shrink_dcache_parent (old_dentry);
 		if (atomic_read (&old_dentry->d_count) > 2) {
 			status = -EBUSY;
@@ -1067,7 +1072,7 @@
 		oldfe_flags |= FLAG_FILE_RENAME;
 
 	status = ocfs_acquire_lock(osb, oldfe_lockid, OCFS_DLM_EXCLUSIVE_LOCK,
-				   oldfe_flags, &oldfe_lock, NULL, old_dir);
+				   oldfe_flags, &oldfe_lock, NULL, old_inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto finally;
@@ -1289,23 +1294,23 @@
 	}
 
 bail:
-	if (new_inode)
-		iput(new_inode);
-
 	if (oldfe_lock) {
 		ocfs_release_lock(osb, oldfe_lockid, 
 				  OCFS_DLM_EXCLUSIVE_LOCK, 
-				  oldfe_flags, oldfe_lock, NULL, old_dir);
+				  oldfe_flags, oldfe_lock, NULL, old_inode);
 		ocfs_put_lockres(oldfe_lock);
 	}
 
 	if (newfe_lock) {
 		ocfs_release_lock(osb, newfe_lockid, 
 				  OCFS_DLM_EXCLUSIVE_LOCK, 
-				  newfe_flags, newfe_lock, NULL, new_dir);
+				  newfe_flags, newfe_lock, NULL, new_inode);
 		ocfs_put_lockres(newfe_lock);
 	}
 
+	if (new_inode)
+		iput(new_inode);
+
 	if (tmpfe)
 		ocfs_release_file_entry (tmpfe);
 	if (oldfe_bh) {

Modified: branches/nooin/src/nm.c
===================================================================
--- branches/nooin/src/nm.c	2004-04-05 23:11:42 UTC (rev 842)
+++ branches/nooin/src/nm.c	2004-04-06 18:59:13 UTC (rev 843)
@@ -43,6 +43,7 @@
 {
 	ocfs_super *osb;
 	ocfs_lock_res *lockres;
+	struct inode *inode;
 } ocfs_ro_cache_drop_ctxt;
 
 
@@ -783,8 +784,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);
 
@@ -803,17 +805,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);
@@ -823,15 +846,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) {
@@ -852,11 +866,13 @@
 					    status, &master_alive, &oin);
 
 #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
@@ -1119,7 +1135,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);
 						}
@@ -1470,7 +1486,8 @@
 	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);
@@ -1479,6 +1496,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);
@@ -1490,6 +1510,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;
 
@@ -1529,7 +1550,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;
@@ -1552,6 +1574,8 @@
 leave:
 	ocfs_release_lockres(lockres);
 	ocfs_put_lockres(lockres);
+	if (inode)
+		iput(inode);
 	kfree(arg);
 	return status;
 }



More information about the Ocfs2-commits mailing list