ocfs2-devel.oss.oracle.com archive mirror
 help / color / mirror / Atom feed
From: Sunil Mushran <sunil.mushran@oracle.com>
To: ocfs2-devel@oss.oracle.com
Subject: [Ocfs2-devel] [PATCH 14/18] ocfs2/dlm: Add missing dlm_lockres_put()s in migration path
Date: Tue Mar 11 16:32:19 2008	[thread overview]
Message-ID: <1205278329-11111-15-git-send-email-sunil.mushran@oracle.com> (raw)
In-Reply-To: <1205278329-11111-1-git-send-email-sunil.mushran@oracle.com>

Mainline commit 52987e2ab456c1a828046494aac53819b1454341
Author: Sunil Mushran <sunil.mushran@oracle.com>
Date: Sat, 1 Mar 2008 14:04:21 -0800

During migration, the recovery master node may be asked to master a lockres
it may not know about. In that case, it would not only have to create a
lockres and add it to the hash, but also remember to to do the _put_
corresponding to the kref_init in dlm_init_lockres(), as soon as the migration
is completed. Yes, we don't wait for the dlm_purge_lockres() to do that
matching put. Note the ref added for it being in the hash protects the lockres
from being freed prematurely.

This patch adds that missing put, as described above, to plug a memleak.

Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
---
 fs/ocfs2/dlm/dlmcommon.h   |    1 +
 fs/ocfs2/dlm/dlmrecovery.c |   40 ++++++++++++++++++++++++++++++++++------
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index b90ee17..57c0a08 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -176,6 +176,7 @@ struct dlm_mig_lockres_priv
 {
 	struct dlm_lock_resource *lockres;
 	u8 real_master;
+	u8 extra_ref;
 };
 
 struct dlm_assert_master_priv
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index 4a0e7aa..7843ec1 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -1327,6 +1327,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
 		(struct dlm_migratable_lockres *)msg->buf;
 	int ret = 0;
 	u8 real_master;
+	u8 extra_refs = 0;
 	char *buf = NULL;
 	struct dlm_work_item *item = NULL;
 	struct dlm_lock_resource *res = NULL;
@@ -1404,16 +1405,28 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
 		__dlm_insert_lockres(dlm, res);
 		spin_unlock(&dlm->spinlock);
 
+		/* Add an extra ref for this lock-less lockres lest the
+		 * dlm_thread purges it before we get the chance to add
+		 * locks to it */
+		dlm_lockres_get(res);
+
+		/* There are three refs that need to be put.
+		 * 1. Taken above.
+		 * 2. kref_init in dlm_new_lockres()->dlm_init_lockres().
+		 * 3. dlm_lookup_lockres()
+		 * The first one is handled at the end of this function. The
+		 * other two are handled in the worker thread after locks have
+		 * been attached. Yes, we don't wait for purge time to match
+		 * kref_init. The lockres will still have atleast one ref
+		 * added because it is in the hash __dlm_insert_lockres() */
+		extra_refs++;
+
 		/* now that the new lockres is inserted,
 		 * make it usable by other processes */
 		spin_lock(&res->spinlock);
 		res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
 		spin_unlock(&res->spinlock);
 		wake_up(&res->wq);
-
-		/* add an extra ref for just-allocated lockres 
-		 * otherwise the lockres will be purged immediately */
-		dlm_lockres_get(res);
 	}
 
 	/* at this point we have allocated everything we need,
@@ -1443,12 +1456,17 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
 	dlm_init_work_item(dlm, item, dlm_mig_lockres_worker, buf);
 	item->u.ml.lockres = res; /* already have a ref */
 	item->u.ml.real_master = real_master;
+	item->u.ml.extra_ref = extra_refs;
 	spin_lock(&dlm->work_lock);
 	list_add_tail(&item->list, &dlm->work_list);
 	spin_unlock(&dlm->work_lock);
 	queue_work(dlm->dlm_worker, &dlm->dispatched_work);
 
 leave:
+	/* One extra ref taken needs to be put here */
+	if (extra_refs)
+		dlm_lockres_put(res);
+
 	dlm_put(dlm);
 	if (ret < 0) {
 		if (buf)
@@ -1464,17 +1482,19 @@ leave:
 
 static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data)
 {
-	struct dlm_ctxt *dlm = data;
+	struct dlm_ctxt *dlm;
 	struct dlm_migratable_lockres *mres;
 	int ret = 0;
 	struct dlm_lock_resource *res;
 	u8 real_master;
+	u8 extra_ref;
 
 	dlm = item->dlm;
 	mres = (struct dlm_migratable_lockres *)data;
 
 	res = item->u.ml.lockres;
 	real_master = item->u.ml.real_master;
+	extra_ref = item->u.ml.extra_ref;
 
 	if (real_master == DLM_LOCK_RES_OWNER_UNKNOWN) {
 		/* this case is super-rare. only occurs if
@@ -1517,6 +1537,12 @@ again:
 	}
 
 leave:
+	/* See comment in dlm_mig_lockres_handler() */
+	if (res) {
+		if (extra_ref)
+			dlm_lockres_put(res);
+		dlm_lockres_put(res);
+	}
 	kfree(data);
 	mlog_exit(ret);
 }
@@ -1644,7 +1670,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data,
 				/* retry!? */
 				BUG();
 			}
-		}
+		} else /* put.. incase we are not the master */
+			dlm_lockres_put(res);
 		spin_unlock(&res->spinlock);
 	}
 	spin_unlock(&dlm->spinlock);
@@ -1921,6 +1948,7 @@ void dlm_move_lockres_to_recovery_list(struct dlm_ctxt *dlm,
 		     "Recovering res %s:%.*s, is already on recovery list!\n",
 		     dlm->name, res->lockname.len, res->lockname.name);
 		list_del_init(&res->recovering);
+		dlm_lockres_put(res);
 	}
 	/* We need to hold a reference while on the recovery list */
 	dlm_lockres_get(res);
-- 
1.5.3.4

  parent reply	other threads:[~2008-03-11 16:32 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-11 16:32 [Ocfs2-devel] Backports to OCFS2 1.4 Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 07/18] ocfs2: make dlm_do_assert_master() static Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 08/18] ocfs2: Correct use of ! and & in aops.c Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 01/18] ocfs2: Add helper task_pid_nr Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 05/18] ocfs2: possible cleanups Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 04/18] ocfs2: Fix writeout in ocfs2_data_convert_worker() Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 06/18] ocfs2: make ocfs2_downconvert_thread() static Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 02/18] ocfs2: Spelling fixes Sunil Mushran
2008-03-11 16:32 ` Sunil Mushran [this message]
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 11/18] ocfs2: Fix endian bug in o2dlm protocol negotiation Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 15/18] ocfs2/dlm: Add missing dlm_lockres_put()s Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 16/18] ocfs2/dlm: Print message showing the recovery master Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 12/18] ocfs2: Fix an endian bug in online resize Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 03/18] ocfs2: Negotiate locking protocol versions Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 09/18] ocfs2/dlm: fix printk warning Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 10/18] ocfs2: Use dlm_print_one_lock_resource for lock resource print Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 17/18] ocfs2/dlm: dlm_thread should not sleep while holding the dlm_spinlock Sunil Mushran
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 18/18] ocfs2: Fix NULL pointer dereferences in o2net Sunil Mushran
2008-03-16 21:10   ` [Ocfs2-devel] how to use run_lvb_torture.py ? Coly Li
2008-03-17  5:09     ` Marcos E. Matsunaga
2008-03-11 16:32 ` [Ocfs2-devel] [PATCH 13/18] ocfs2/dlm: Add missing dlm_lock_put()s Sunil Mushran

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1205278329-11111-15-git-send-email-sunil.mushran@oracle.com \
    --to=sunil.mushran@oracle.com \
    --cc=ocfs2-devel@oss.oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).