From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Teigland Date: Mon, 23 May 2011 13:59:03 -0400 Subject: [Cluster-devel] dlm_controld: clear waiting plocks for closed files Message-ID: <20110523175903.GA25353@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit The new CLOSE flag is set in unlock operations that are generated by the vfs removing locks that were not unlocked by the process, when the process closes the file or exits. The kernel does not take a reply for these unlock-close operations. plock requests can now be interrupted in the kernel when the process is killed. So the unlock-close also needs to clear any waiting plocks that were abandoned by the killed process. The corresponding kernel patch: https://lkml.org/lkml/2011/5/23/237 Signed-off-by: David Teigland --- group/dlm_controld/plock.c | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) diff --git a/group/dlm_controld/plock.c b/group/dlm_controld/plock.c index f27001f..6d5dea8 100644 --- a/group/dlm_controld/plock.c +++ b/group/dlm_controld/plock.c @@ -631,6 +631,27 @@ static int unlock_internal(struct lockspace *ls, struct resource *r, return rv; } +static void clear_waiters(struct lockspace *ls, struct resource *r, + struct dlm_plock_info *in) +{ + struct lock_waiter *w, *safe; + + list_for_each_entry_safe(w, safe, &r->waiters, list) { + if (w->info.nodeid != in->nodeid || w->info.owner != in->owner) + continue; + + list_del(&w->list); + + log_plock_error(ls, "clear waiter %llx %llx-%llx %d/%u/%llx", + (unsigned long long)in->number, + (unsigned long long)in->start, + (unsigned long long)in->end, + in->nodeid, in->pid, + (unsigned long long)in->owner); + free(w); + } +} + static int add_waiter(struct lockspace *ls, struct resource *r, struct dlm_plock_info *in) @@ -716,9 +737,16 @@ static void do_unlock(struct lockspace *ls, struct dlm_plock_info *in, rv = unlock_internal(ls, r, in); + if (in->flags & DLM_PLOCK_FL_CLOSE) { + clear_waiters(ls, r, in); + /* no replies for unlock-close ops */ + goto skip_result; + } + if (in->nodeid == our_nodeid) write_result(ls, in, rv); + skip_result: do_waiters(ls, r); put_resource(r); } -- 1.7.1.1