Эх сурвалжийг харах

ocfs2_dlm: Fix lockres ref counting bug

During umount, the umount thread migrates the lockres' and the dlm_thread
frees the empty lockres'. Due to a race, the reference counting on the
lockres goes awry leading to extra puts.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Sunil Mushran 18 жил өмнө
parent
commit
78062cb2e5

+ 4 - 2
fs/ocfs2/dlm/dlmdomain.c

@@ -138,8 +138,10 @@ static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm);
 
 void __dlm_unhash_lockres(struct dlm_lock_resource *lockres)
 {
-	hlist_del_init(&lockres->hash_node);
-	dlm_lockres_put(lockres);
+	if (!hlist_unhashed(&lockres->hash_node)) {
+		hlist_del_init(&lockres->hash_node);
+		dlm_lockres_put(lockres);
+	}
 }
 
 void __dlm_insert_lockres(struct dlm_ctxt *dlm,

+ 2 - 8
fs/ocfs2/dlm/dlmthread.c

@@ -256,20 +256,14 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm,
 			break;
 		}
 
-		mlog(0, "removing lockres %.*s:%p from purgelist\n",
-		     lockres->lockname.len, lockres->lockname.name, lockres);
-		list_del_init(&lockres->purge);
-		dlm_lockres_put(lockres);
-		dlm->purge_count--;
+		dlm_lockres_get(lockres);
 
 		/* This may drop and reacquire the dlm spinlock if it
 		 * has to do migration. */
-		mlog(0, "calling dlm_purge_lockres!\n");
-		dlm_lockres_get(lockres);
 		if (dlm_purge_lockres(dlm, lockres))
 			BUG();
+
 		dlm_lockres_put(lockres);
-		mlog(0, "DONE calling dlm_purge_lockres!\n");
 
 		/* Avoid adding any scheduling latencies */
 		cond_resched_lock(&dlm->spinlock);