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 <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2011-08-26 13:21:27 -04:00 committed by unknown
parent d08d3774fd
commit d107131f78
2 changed files with 6 additions and 1 deletions

View file

@ -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;

View file

@ -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 {