From d107131f78bc66e97738c406b7cc8f5597514604 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Fri, 26 Aug 2011 13:21:27 -0400 Subject: [PATCH] lock: fix for upcall.status on cancel_lock() cancel_lock() can't rely on checking upcall.status, because a handle_lock() success could be overwritten by upcall_marshall() or failure to allocate the upcall reply buffer. added new flag lock_upcall_args.acquired for this purpose Signed-off-by: Casey Bodley --- daemon/lock.c | 6 +++++- daemon/upcall.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/daemon/lock.c b/daemon/lock.c index d1e7b11..1ff0339 100644 --- a/daemon/lock.c +++ b/daemon/lock.c @@ -229,6 +229,7 @@ static int handle_lock(nfs41_upcall *upcall) if (open_lock_delegate(state, lock)) { dprintf(LKLVL, "delegated lock { %llu, %llu }\n", lock->offset, lock->length); + args->acquired = TRUE; /* for cancel_lock() */ goto out; } @@ -253,6 +254,7 @@ static int handle_lock(nfs41_upcall *upcall) /* save lock state with the open */ open_lock_add(state, &stateid, lock); + args->acquired = TRUE; /* for cancel_lock() */ out: return status; @@ -271,7 +273,9 @@ static void cancel_lock(IN nfs41_upcall *upcall) dprintf(1, "--> cancel_lock()\n"); - if (upcall->status) + /* can't do 'if (upcall->status)' here, because a handle_lock() success + * could be overwritten by upcall_marshall() or allocation failure */ + if (!args->acquired) goto out; input.offset = args->offset; diff --git a/daemon/upcall.h b/daemon/upcall.h index d2e53e2..443c1cd 100644 --- a/daemon/upcall.h +++ b/daemon/upcall.h @@ -74,6 +74,7 @@ typedef struct __lock_upcall_args { uint64_t length; BOOLEAN exclusive; BOOLEAN blocking; + BOOLEAN acquired; } lock_upcall_args; typedef struct __unlock_upcall_args {