]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ocfs2/dlm: remove potential deadlock -V3
authorWengang Wang <wen.gang.wang@oracle.com>
Fri, 30 Jul 2010 15:18:00 +0000 (23:18 +0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 26 Aug 2010 23:41:38 +0000 (16:41 -0700)
commit b11f1f1ab73fd358b1b734a9427744802202ba68 upstream.

When we need to take both dlm_domain_lock and dlm->spinlock, we should take
them in order of: dlm_domain_lock then dlm->spinlock.

There is pathes disobey this order. That is calling dlm_lockres_put() with
dlm->spinlock held in dlm_run_purge_list. dlm_lockres_put() calls dlm_put() at
the ref and dlm_put() locks on dlm_domain_lock.

Fix:
Don't grab/put the dlm when the initialising/releasing lockres.
That grab is not required because we don't call dlm_unregister_domain()
based on refcount.

Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/ocfs2/dlm/dlmmaster.c

index 8c54014cbddc383510a6cfc79508c3e595660eda..ef1ac9ab4ee1a8504da627d037b63a74c5d20302 100644 (file)
@@ -511,8 +511,6 @@ static void dlm_lockres_release(struct kref *kref)
 
        atomic_dec(&dlm->res_cur_count);
 
-       dlm_put(dlm);
-
        if (!hlist_unhashed(&res->hash_node) ||
            !list_empty(&res->granted) ||
            !list_empty(&res->converting) ||
@@ -585,8 +583,6 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
        res->migration_pending = 0;
        res->inflight_locks = 0;
 
-       /* put in dlm_lockres_release */
-       dlm_grab(dlm);
        res->dlm = dlm;
 
        kref_init(&res->refs);