[Ocfs2-commits] mfasheh commits r2482 - trunk/fs/ocfs2

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Jul 28 16:23:05 CDT 2005


Author: mfasheh
Signed-off-by: jlbec
Signed-off-by: zab
Date: 2005-07-28 16:23:00 -0500 (Thu, 28 Jul 2005)
New Revision: 2482

Modified:
   trunk/fs/ocfs2/dlmglue.c
   trunk/fs/ocfs2/dlmglue.h
   trunk/fs/ocfs2/inode.c
   trunk/fs/ocfs2/inode.h
   trunk/fs/ocfs2/ocfs2.h
   trunk/fs/ocfs2/vote.c
   trunk/fs/ocfs2/vote.h
Log:
* Queue up lockres for downconvert always now. The previous implementation  
  which tried to take an inode reference via igrab was causing problems during
  delete_inode.

* Similarly the vote thread wasn't always able to get to the inode if it was 
  in ocfs2_delete_inode to mark it deleted. Fix this by always setting the
  deleted flag.

Signed-off-by: jlbec
Signed-off-by: zab



Modified: trunk/fs/ocfs2/dlmglue.c
===================================================================
--- trunk/fs/ocfs2/dlmglue.c	2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/dlmglue.c	2005-07-28 21:23:00 UTC (rev 2482)
@@ -54,7 +54,6 @@
 
 #include "buffer_head_io.h"
 
-
 static void ocfs2_inode_ast_func(void *opaque);
 static void ocfs2_inode_bast_func(void *opaque,
 				  int level);
@@ -172,8 +171,6 @@
 static int ocfs2_generic_handle_bast(struct ocfs2_lock_res *lockres, int level);
 static void ocfs2_schedule_blocked_lock(ocfs2_super *osb,
 					struct ocfs2_lock_res *lockres);
-static void ocfs2_schedule_blocked_inode_lock(struct inode *inode,
-					      struct ocfs2_lock_res *lockres);
 static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
 						int convert);
 #define ocfs2_log_dlm_error(_func, _stat, _lockres) do {	\
@@ -559,8 +556,7 @@
 	lksb = &(lockres->l_lksb);
 	if (lksb->status != DLM_NORMAL) {
 		mlog(ML_ERROR, "ocfs2_inode_ast_func: lksb status value of %u "
-			       "on inode %"MLFu64"\n",
-		     lksb->status,
+		     "on inode %"MLFu64"\n", lksb->status,
 		     OCFS2_I(inode)->ip_blkno);
 		spin_unlock(&lockres->l_lock);
 		mlog_exit_void();
@@ -651,12 +647,11 @@
 
 	needs_downconvert = ocfs2_generic_handle_bast(lockres, level);
 	if (needs_downconvert)
-		ocfs2_schedule_blocked_inode_lock(inode, lockres);
+		ocfs2_schedule_blocked_lock(osb, lockres);
 
 	spin_unlock(&lockres->l_lock);
 
 	ocfs2_kick_vote_thread(osb);
-	/* TODO: Is a wake_up call here really necessary? */
 	wake_up(&lockres->l_event);
 
 	mlog_exit_void();
@@ -916,6 +911,33 @@
 	complete(&sc->sc_complete);
 }
 
+static int ocfs2_wait_for_status_completion(struct ocfs2_status_completion *sc)
+{
+	wait_for_completion(&sc->sc_complete);
+	/* Re-arm the completion in case we want to wait on it again */
+	INIT_COMPLETION(sc->sc_complete);
+	return sc->sc_status;
+}
+
+static void ocfs2_init_fcb(struct ocfs2_lockres_flag_callback *fcb,
+			   ocfs2_lock_callback cb,
+			   unsigned long cb_data,
+			   int stack_allocated)
+{
+	fcb->fc_cb = cb;
+	fcb->fc_data = cb_data;
+	fcb->fc_free_once_called = !stack_allocated;
+	INIT_LIST_HEAD(&fcb->fc_lockres_item);
+}
+
+/* Init a stack allocated FCB and an ocfs2_status_completion together. */
+static void ocfs2_init_completion_fcb(struct ocfs2_lockres_flag_callback *fcb,
+				      struct ocfs2_status_completion *sc)
+{
+	init_completion(&sc->sc_complete);
+	ocfs2_init_fcb(fcb, ocfs2_status_completion_cb, (unsigned long) sc, 1);
+}
+
 static int ocfs2_cluster_lock(ocfs2_super *osb,
 			      struct ocfs2_lock_res *lockres,
 			      int level,
@@ -938,10 +960,9 @@
 			ret = -ENOMEM;
 			goto out;
 		}
-		fcb->fc_cb = cb;
-		fcb->fc_data = cb_data;
-		fcb->fc_free_once_called = 1;
 
+		ocfs2_init_fcb(fcb, cb, cb_data, 0);
+
 		/* A callback passed in means we'll assume async
 		 * behavior - no waiting on dlm operations will be
 		 * done here and the allocated fcb will call the
@@ -953,15 +974,9 @@
 		 * stack allocated fcb for this. The status completion
 		 * helpers defined above come in handy here. */
 		fcb = &sync_fcb;
-
-		init_completion(&sc.sc_complete);
-		fcb->fc_cb = ocfs2_status_completion_cb;
-		fcb->fc_data = (unsigned long)≻
-		fcb->fc_free_once_called = 0;
+		ocfs2_init_completion_fcb(fcb, &sc);
 	}
 
-	INIT_LIST_HEAD(&fcb->fc_lockres_item);
-
 again:
 	if (catch_signals && signal_pending(current)) {
 		ret = -ERESTARTSYS;
@@ -970,6 +985,10 @@
 
 	spin_lock(&lockres->l_lock);
 
+	mlog_bug_on_msg(lockres->l_flags & OCFS2_LOCK_FREEING,
+			"Cluster lock called on freeing lockres %s! flags 0x%lx\n",
+			lockres->l_name, lockres->l_flags);
+
 	/* We only compare against the currently granted level
 	 * here. If the lock is blocked waiting on a downconvert,
 	 * we'll get caught below. */
@@ -1063,12 +1082,10 @@
 	 * to complete. We must be careful to re-initialize the
 	 * completion before looping back. */
 	if (ret == -EIOCBRETRY && sync) {
-		wait_for_completion(&sc.sc_complete);
-		ret = sc.sc_status;
-		if (ret == 0) {
-			INIT_COMPLETION(sc.sc_complete);
+		ret = ocfs2_wait_for_status_completion(&sc);
+		if (ret == 0)
 			goto again;
-		}
+		mlog_errno(ret);
 	}
 
 	/* Only free the async fcb on error. */
@@ -1853,7 +1870,8 @@
 	 * hurt anything anyway */
 	if (status == DLM_CANCELGRANT &&
 	    lockres->l_unlock_action == OCFS2_UNLOCK_CANCEL_CONVERT) {
-		mlog(0, "Ok, got cancelgrant for %s\n", lockres->l_name);
+		mlog(0, "Got cancelgrant for %s\n", lockres->l_name);
+
 		/* We don't clear the busy flag in this case as it
 		 * should have been cleared by the ast which the dlm
 		 * has called. */
@@ -1870,6 +1888,7 @@
 
 	switch(lockres->l_unlock_action) {
 	case OCFS2_UNLOCK_CANCEL_CONVERT:
+		mlog(0, "Cancel convert success for %s\n", lockres->l_name);
 		lockres->l_action = OCFS2_AST_INVALID;
 		break;
 	case OCFS2_UNLOCK_DROP_LOCK:
@@ -1958,6 +1977,10 @@
 
 	spin_lock(&lockres->l_lock);
 
+	mlog_bug_on_msg(!(lockres->l_flags & OCFS2_LOCK_FREEING),
+			"lockres %s, flags 0x%lx\n",
+			lockres->l_name, lockres->l_flags);
+
 	while (lockres->l_flags & OCFS2_LOCK_BUSY) {
 		mlog(0, "waiting on busy lock \"%s\": flags = %lx, action = "
 		     "%u, unlock_action = %u\n",
@@ -1982,16 +2005,51 @@
 	return  __ocfs2_drop_lock(osb, lockres);
 }
 
+/* Mark the lockres as being dropped. It will no longer be
+ * queued if blocking, but we still may have to wait on it
+ * being dequeued from the vote thread before we can consider
+ * it safe to drop. 
+ *
+ * You can *not* attempt to call cluster_lock on this lockres anymore. */
+void ocfs2_mark_lockres_freeing(struct ocfs2_lock_res *lockres)
+{
+	int status;
+	struct ocfs2_status_completion sc;
+	struct ocfs2_lockres_flag_callback fcb;
+
+	ocfs2_init_completion_fcb(&fcb, &sc);
+
+	spin_lock(&lockres->l_lock);
+	lockres->l_flags |= OCFS2_LOCK_FREEING;
+	while (lockres->l_flags & OCFS2_LOCK_QUEUED) {
+		lockres_add_flag_callback(lockres, &fcb, OCFS2_LOCK_QUEUED, 0);
+		spin_unlock(&lockres->l_lock);
+
+		mlog(0, "Waiting on lockres %s\n", lockres->l_name);
+
+		status = ocfs2_wait_for_status_completion(&sc);
+		if (status)
+			mlog_errno(status);
+
+		spin_lock(&lockres->l_lock);
+	}
+	spin_unlock(&lockres->l_lock);
+}
+
 static void ocfs2_drop_osb_locks(ocfs2_super *osb)
 {
 	int status;
 
 	mlog_entry_void();
 
+	ocfs2_mark_lockres_freeing(&osb->osb_super_lockres);
+
 	status = ocfs2_drop_lock(osb, &osb->osb_super_lockres, NULL);
 	if (status < 0)
 		mlog_errno(status);
 
+	ocfs2_mark_lockres_freeing(&osb->osb_rename_lockres);
+
 	status = ocfs2_drop_lock(osb, &osb->osb_rename_lockres, NULL);
 	if (status < 0)
 		mlog_errno(status);
@@ -2020,6 +2078,9 @@
 
 	mlog_entry_void();
 
+	/* No need to call ocfs2_mark_lockres_freeing here -
+	 * ocfs2_clear_inode has done it for us. */
+
 	err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
 			      &OCFS2_I(inode)->ip_data_lockres,
 			      NULL);
@@ -2108,6 +2169,10 @@
 	/* set things up for the unlockast to know to just
 	 * clear out the ast_action and unset busy, etc. */
 	lockres->l_unlock_action = OCFS2_UNLOCK_CANCEL_CONVERT;
+
+	mlog_bug_on_msg(!(lockres->l_flags & OCFS2_LOCK_BUSY),
+			"lock %s, invalid flags: 0x%lx\n",
+			lockres->l_name, lockres->l_flags);
 	spin_unlock(&lockres->l_lock);
 
 	ret = 0;
@@ -2138,6 +2203,8 @@
 		 * then just drop the spinlock and allow the caller to
 		 * requeue this lock. */
 		spin_unlock(&lockres->l_lock);
+
+		mlog(0, "Lockres %s, skip convert\n", lockres->l_name);
 		return 0;
 	}
 
@@ -2370,16 +2437,6 @@
 	mlog(0, "inode %"MLFu64", requeue = %d\n",
 	     OCFS2_I(inode)->ip_blkno, *requeue);
 
-	/* because of inode ref counting, we never want to propagate
-	 * up requeue requests for inode locks. Instead we do it
-	 * ourselves here, and lose the extra ref we got from queueing
-	 * when we came in. */
-	if (*requeue)
-		ocfs2_schedule_blocked_inode_lock(inode, lockres);
-
-	iput(inode);
-	*requeue = 0;
-
 	mlog_exit(status);
 	return status;
 }
@@ -2403,14 +2460,6 @@
 	mlog(0, "inode %"MLFu64", requeue = %d\n",
 	     OCFS2_I(inode)->ip_blkno, *requeue);
 
-	/* if you're confused by this, see the comment in
-	 * ocfs2_unblock_data */
-	if (*requeue)
-		ocfs2_schedule_blocked_inode_lock(inode, lockres);
-
-	iput(inode);
-	*requeue = 0;
-
 	mlog_exit(status);
 	return status;
 }
@@ -2446,6 +2495,10 @@
 	int status;
 	int requeue = 0;
 
+	/* Our reference to the lockres in this function can be
+	 * considered valid until we remove the OCFS2_LOCK_QUEUED
+	 * flag. */
+
 	mlog_entry_void();
 
 	BUG_ON(!lockres);
@@ -2454,15 +2507,30 @@
 
 	mlog(0, "lockres %s blocked.\n", lockres->l_name);
 
+	/* Detect whether a lock has been marked as going away while
+	 * the vote thread was processing other things. A lock can
+	 * still be marked with OCFS2_LOCK_FREEING after this check,
+	 * but short circuiting here will still save us some
+	 * performance. */
+	spin_lock(&lockres->l_lock);
+	if (lockres->l_flags & OCFS2_LOCK_FREEING)
+		goto unqueue;
+	spin_unlock(&lockres->l_lock);
+
 	status = lockres->l_ops->unblock(lockres, &requeue);
 	if (status < 0)
 		mlog_errno(status);
 
-	if (requeue)
+	spin_lock(&lockres->l_lock);
+unqueue:
+	if (lockres->l_flags & OCFS2_LOCK_FREEING || !requeue) {
+		lockres_clear_flags(lockres, OCFS2_LOCK_QUEUED);
+	} else
 		ocfs2_schedule_blocked_lock(osb, lockres);
 
 	mlog(0, "lockres %s, requeue = %s.\n", lockres->l_name,
 	     requeue ? "yes" : "no");
+	spin_unlock(&lockres->l_lock);
 
 	mlog_exit_void();
 }
@@ -2472,6 +2540,19 @@
 {
 	mlog_entry_void();
 
+	assert_spin_locked(&lockres->l_lock);
+
+	if (lockres->l_flags & OCFS2_LOCK_FREEING) {
+		/* Do not schedule a lock for downconvert when it's on
+		 * the way to destruction - any nodes wanting access
+		 * to the resource will get it soon. */
+		mlog(0, "Lockres %s won't be scheduled: flags 0x%lx\n",
+		     lockres->l_name, lockres->l_flags);
+		return;
+	}
+
+	lockres_or_flags(lockres, OCFS2_LOCK_QUEUED);
+
 	spin_lock(&osb->vote_task_lock);
 	if (list_empty(&lockres->l_blocked_list)) {
 		list_add_tail(&lockres->l_blocked_list,
@@ -2483,23 +2564,6 @@
 	mlog_exit_void();
 }
 
-/* needed for inodes as we have to take a reference on them.. */
-static void ocfs2_schedule_blocked_inode_lock(struct inode *inode,
-					      struct ocfs2_lock_res *lockres)
-{
-	mlog_entry_void();
-
-	if (!igrab(inode)) {
-		mlog(0, "Inode %"MLFu64" asked to be scheduled during "
-		     "clear_inode!\n", OCFS2_I(inode)->ip_blkno);
-		return;
-	}
-
-	ocfs2_schedule_blocked_lock(OCFS2_SB(inode->i_sb), lockres);
-
-	mlog_exit_void();
-}
-
 void ocfs2_meta_lvb_set_trunc_clusters(struct inode *inode,
 				       unsigned int trunc_clusters)
 {

Modified: trunk/fs/ocfs2/dlmglue.h
===================================================================
--- trunk/fs/ocfs2/dlmglue.h	2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/dlmglue.h	2005-07-28 21:23:00 UTC (rev 2482)
@@ -113,6 +113,8 @@
 			int ex);
 int ocfs2_rename_lock(ocfs2_super *osb);
 void ocfs2_rename_unlock(ocfs2_super *osb);
+void ocfs2_mark_lockres_freeing(struct ocfs2_lock_res *lockres);
+
 /* for the vote thread */
 void ocfs2_process_blocked_lock(ocfs2_super *osb,
 				struct ocfs2_lock_res *lockres);

Modified: trunk/fs/ocfs2/inode.c
===================================================================
--- trunk/fs/ocfs2/inode.c	2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/inode.c	2005-07-28 21:23:00 UTC (rev 2482)
@@ -54,6 +54,7 @@
 #include "buffer_head_io.h"
 
 #define OCFS2_FI_FLAG_NOWAIT	0x1
+#define OCFS2_FI_FLAG_DELETE	0x2
 struct ocfs2_find_inode_args
 {
 	u64		fi_blkno;
@@ -69,17 +70,20 @@
 				    struct inode *inode,
 				    struct buffer_head *fe_bh);
 
-struct inode *ocfs2_ilookup(ocfs2_super *osb, u64 blkno)
+struct inode *ocfs2_ilookup_for_vote(ocfs2_super *osb,
+				     u64 blkno,
+				     int delete_vote)
 {
 	struct ocfs2_find_inode_args args;
 
-	/* ocfs2_ilookup should *only* be called from the vote thread,
-	 * unless modified to conditionally set
-	 * OCFS2_FI_FLAG_NOWAIT */
+	/* ocfs2_ilookup_for_vote should *only* be called from the
+	 * vote thread */
 	BUG_ON(current != osb->vote_task);
 
 	args.fi_blkno = blkno;
 	args.fi_flags = OCFS2_FI_FLAG_NOWAIT;
+	if (delete_vote)
+		args.fi_flags |= OCFS2_FI_FLAG_DELETE;
 	args.fi_ino = ino_from_blkno(osb->sb, blkno);
 	return ilookup5(osb->sb, args.fi_ino, ocfs2_find_actor, &args);
 }
@@ -147,6 +151,7 @@
 static int ocfs2_find_actor(struct inode *inode, void *opaque)
 {
 	struct ocfs2_find_inode_args *args = NULL;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
 	int ret = 0;
 
 	mlog_entry("(0x%p, %lu, 0x%p)\n", inode, inode->i_ino, opaque);
@@ -155,20 +160,30 @@
 
 	mlog_bug_on_msg(!inode, "No inode in find actor!\n");
 
-	if (OCFS2_I(inode)->ip_blkno != args->fi_blkno)
+	if (oi->ip_blkno != args->fi_blkno)
 		goto bail;
 
-	/* OCFS2_FI_FLAG_NOWAIT is *only* set from ocfs2_ilookup which
-	 * won't create an inode for one that isn't
-	 * found. ocfs2_ilookup is called from the vote thread which
-	 * doesn't want to get an inode which is in the process of
-	 * going away - otherwise the call to __wait_on_freeing_inode
-	 * in find_inode_fast will cause it to deadlock on an inode
-	 * which may be waiting on a vote (or lock release) in
-	 * delete_inode */
+	/* OCFS2_FI_FLAG_NOWAIT is *only* set from
+	 * ocfs2_ilookup_for_vote which won't create an inode for one
+	 * that isn't found. The vote thread which doesn't want to get
+	 * an inode which is in the process of going away - otherwise
+	 * the call to __wait_on_freeing_inode in find_inode_fast will
+	 * cause it to deadlock on an inode which may be waiting on a
+	 * vote (or lock release) in delete_inode */
 	if ((args->fi_flags & OCFS2_FI_FLAG_NOWAIT) &&
-	    (inode->i_state & (I_FREEING|I_CLEAR)))
+	    (inode->i_state & (I_FREEING|I_CLEAR))) {
+		/* As stated above, we're not going to return an
+		 * inode.  In the case of a delete vote, the voting
+		 * code is going to signal the other node to go
+		 * ahead. Mark that state here, so this freeing inode
+		 * has the state when it gets to delete_inode. */
+		if (args->fi_flags & OCFS2_FI_FLAG_DELETE) {
+			spin_lock(&oi->ip_lock);
+			ocfs2_mark_inode_remotely_deleted(inode);
+			spin_unlock(&oi->ip_lock);
+		}
 		goto bail;
+	}
 
 	ret = 1;
 bail:
@@ -676,9 +691,9 @@
 		/* for lack of a better error? */
 		status = -EEXIST;
 		mlog(ML_ERROR,
-		     "Inode %"MLFu64" (on-disk %"MLFu64") not orphaned!\n",
-		     OCFS2_I(inode)->ip_blkno,
-		     di->i_blkno);
+		     "Inode %"MLFu64" (on-disk %"MLFu64") not orphaned! "
+		     "Disk flags  0x%x, inode flags 0x%x\n",
+		     oi->ip_blkno, di->i_blkno, di->i_flags, oi->ip_flags);
 		goto bail;
 	}
 
@@ -841,6 +856,11 @@
 	mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,
 			"Inode=%lu\n", inode->i_ino);
 
+	/* Do these before all the other work so that we don't bounce
+	 * the vote thread while waiting to destroy the locks. */
+	ocfs2_mark_lockres_freeing(&oi->ip_meta_lockres);
+	ocfs2_mark_lockres_freeing(&oi->ip_data_lockres);
+
 	/* We very well may get a clear_inode before all an inodes
 	 * metadata has hit disk. Of course, we can't drop any cluster
 	 * locks until the journal has finished with it. The only

Modified: trunk/fs/ocfs2/inode.h
===================================================================
--- trunk/fs/ocfs2/inode.h	2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/inode.h	2005-07-28 21:23:00 UTC (rev 2482)
@@ -122,7 +122,9 @@
 void ocfs2_delete_inode(struct inode *inode);
 void ocfs2_drop_inode(struct inode *inode);
 struct inode *ocfs2_iget(ocfs2_super *osb, u64 feoff);
-struct inode *ocfs2_ilookup(ocfs2_super *osb, u64 feoff);
+struct inode *ocfs2_ilookup_for_vote(ocfs2_super *osb,
+				     u64 blkno,
+				     int delete_vote);
 int ocfs2_inode_init_private(struct inode *inode);
 int ocfs2_inode_revalidate(struct dentry *dentry);
 int ocfs2_populate_inode(struct inode *inode, ocfs2_dinode *fe,

Modified: trunk/fs/ocfs2/ocfs2.h
===================================================================
--- trunk/fs/ocfs2/ocfs2.h	2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/ocfs2.h	2005-07-28 21:23:00 UTC (rev 2482)
@@ -84,7 +84,6 @@
 	OCFS2_UNLOCK_DROP_LOCK,
 };
 
-
 /* ocfs2_lock_res->l_flags flags. */
 #define OCFS2_LOCK_ATTACHED      (0x00000001) /* have we initialized
 					       * the lvb */
@@ -97,6 +96,12 @@
 #define OCFS2_LOCK_REFRESHING    (0x00000020)
 #define OCFS2_LOCK_INITIALIZED   (0x00000040) /* track initialization
 					       * for shutdown paths */
+#define OCFS2_LOCK_FREEING       (0x00000080) /* help dlmglue track
+					       * when to skip queueing
+					       * a lock because it's
+					       * about to be
+					       * dropped. */
+#define OCFS2_LOCK_QUEUED        (0x00000100) /* queued for downconvert */
 
 struct ocfs2_lock_res_ops;
 

Modified: trunk/fs/ocfs2/vote.c
===================================================================
--- trunk/fs/ocfs2/vote.c	2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/vote.c	2005-07-28 21:23:00 UTC (rev 2482)
@@ -156,6 +156,19 @@
 	ocfs2_node_map_set_bit(osb, &osb->umount_map, node_num);
 }
 
+void ocfs2_mark_inode_remotely_deleted(struct inode *inode)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+	assert_spin_locked(&oi->ip_lock);
+	/* We set the SKIP_DELETE flag on the inode so we don't try to
+	 * delete it in delete_inode ourselves, thus avoiding
+	 * unecessary lock pinging. If the other node failed to wipe
+	 * the inode as a result of a crash, then recovery will pick
+	 * up the slack. */
+	oi->ip_flags |= OCFS2_INODE_DELETED|OCFS2_INODE_SKIP_DELETE;
+}
+
 static int ocfs2_process_delete_request(struct inode *inode,
 					int *orphaned_slot)
 {
@@ -234,23 +247,15 @@
 	}
 
 	/* Mark the inode as being wiped from disk. */
-	OCFS2_I(inode)->ip_flags |= OCFS2_INODE_DELETED;
-
-	/* If we get here, then we're voting 'yes', so commit the
-	 * delete on our side. */
-	response = OCFS2_RESPONSE_OK;
-
-	/* We set the SKIP_DELETE flag on the inode so we don't try to
-	 * delete it in delete_inode ourselves, thus avoiding
-	 * unecessary lock pinging. If the other node failed to wipe
-	 * the inode as a result of a crash, then recovery will pick
-	 * up the slack. */
-	OCFS2_I(inode)->ip_flags |=  OCFS2_INODE_SKIP_DELETE;
+	ocfs2_mark_inode_remotely_deleted(inode);
 	spin_unlock(&OCFS2_I(inode)->ip_lock);
 
 	/* Not sure this is necessary anymore. */
 	d_prune_aliases(inode);
 
+	/* If we get here, then we're voting 'yes', so commit the
+	 * delete on our side. */
+	response = OCFS2_RESPONSE_OK;
 done:
 	return response;
 }
@@ -413,7 +418,8 @@
 		goto respond;
 
 	/* If we get here, then the request is against an inode. */
-	inode = ocfs2_ilookup(osb, blkno);
+	inode = ocfs2_ilookup_for_vote(osb, blkno,
+				       request == OCFS2_VOTE_REQ_DELETE);
 
 	/* Not finding the inode is perfectly valid - it means we're
 	 * not interested in what the other node is about to do to it

Modified: trunk/fs/ocfs2/vote.h
===================================================================
--- trunk/fs/ocfs2/vote.h	2005-07-28 18:39:03 UTC (rev 2481)
+++ trunk/fs/ocfs2/vote.h	2005-07-28 21:23:00 UTC (rev 2482)
@@ -49,6 +49,8 @@
 int ocfs2_register_net_handlers(ocfs2_super *osb);
 void ocfs2_unregister_net_handlers(ocfs2_super *osb);
 
+void ocfs2_mark_inode_remotely_deleted(struct inode *inode);
+
 void ocfs2_remove_node_from_vote_queues(ocfs2_super *osb,
 					int node_num);
 #endif



More information about the Ocfs2-commits mailing list