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:
parent
d08d3774fd
commit
d107131f78
2 changed files with 6 additions and 1 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue