diff options
author | Sunil Mushran <sunil.mushran@oracle.com> | 2007-03-22 20:01:07 -0400 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-03-26 19:50:52 -0400 |
commit | 78062cb2e54ffe0df811dce5e68b54da9b8c9025 (patch) | |
tree | d360f3440fbe3489ef1c467f0b4b8ef196516ec2 | |
parent | e0f2e3a06be513352cb4955313ed7e55909acd84 (diff) |
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>
-rw-r--r-- | fs/ocfs2/dlm/dlmdomain.c | 6 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmthread.c | 10 |
2 files changed, 6 insertions, 10 deletions
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 6087c4749fee..dbbac184c261 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -138,8 +138,10 @@ static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm); | |||
138 | 138 | ||
139 | void __dlm_unhash_lockres(struct dlm_lock_resource *lockres) | 139 | void __dlm_unhash_lockres(struct dlm_lock_resource *lockres) |
140 | { | 140 | { |
141 | hlist_del_init(&lockres->hash_node); | 141 | if (!hlist_unhashed(&lockres->hash_node)) { |
142 | dlm_lockres_put(lockres); | 142 | hlist_del_init(&lockres->hash_node); |
143 | dlm_lockres_put(lockres); | ||
144 | } | ||
143 | } | 145 | } |
144 | 146 | ||
145 | void __dlm_insert_lockres(struct dlm_ctxt *dlm, | 147 | void __dlm_insert_lockres(struct dlm_ctxt *dlm, |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 6421a8fae1de..2b264c6ba039 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
@@ -256,20 +256,14 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm, | |||
256 | break; | 256 | break; |
257 | } | 257 | } |
258 | 258 | ||
259 | mlog(0, "removing lockres %.*s:%p from purgelist\n", | 259 | dlm_lockres_get(lockres); |
260 | lockres->lockname.len, lockres->lockname.name, lockres); | ||
261 | list_del_init(&lockres->purge); | ||
262 | dlm_lockres_put(lockres); | ||
263 | dlm->purge_count--; | ||
264 | 260 | ||
265 | /* This may drop and reacquire the dlm spinlock if it | 261 | /* This may drop and reacquire the dlm spinlock if it |
266 | * has to do migration. */ | 262 | * has to do migration. */ |
267 | mlog(0, "calling dlm_purge_lockres!\n"); | ||
268 | dlm_lockres_get(lockres); | ||
269 | if (dlm_purge_lockres(dlm, lockres)) | 263 | if (dlm_purge_lockres(dlm, lockres)) |
270 | BUG(); | 264 | BUG(); |
265 | |||
271 | dlm_lockres_put(lockres); | 266 | dlm_lockres_put(lockres); |
272 | mlog(0, "DONE calling dlm_purge_lockres!\n"); | ||
273 | 267 | ||
274 | /* Avoid adding any scheduling latencies */ | 268 | /* Avoid adding any scheduling latencies */ |
275 | cond_resched_lock(&dlm->spinlock); | 269 | cond_resched_lock(&dlm->spinlock); |