deleg: return delegation before conflicting operations
new function nfs41_delegation_return() for synchronous delegation return. uses a condition variable to wait if another thread is already returning the delegation if nfs41_delegate_open() would conflict with a delegation, return it before sending the OPEN return the delegation before sending LINK, RENAME, REMOVE, and SETATTR all of this functionality is dependent on the preprocessor define DELEGATION_RETURN_ON_CONFLICT (on by default). if not defined, nfs41_delegation_return() is a noop Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
38259e0017
commit
bc6471d981
6 changed files with 179 additions and 19 deletions
|
|
@ -133,7 +133,7 @@ void nfs41_open_stateid_arg(
|
|||
if (state->delegation.state) {
|
||||
nfs41_delegation_state *deleg = state->delegation.state;
|
||||
AcquireSRWLockShared(&deleg->lock);
|
||||
if (!deleg->state.recalled) {
|
||||
if (deleg->status == DELEGATION_GRANTED) {
|
||||
arg->type = STATEID_DELEG_FILE;
|
||||
memcpy(&arg->stateid, &deleg->state.stateid, sizeof(stateid4));
|
||||
}
|
||||
|
|
@ -668,6 +668,9 @@ static void cancel_open(IN nfs41_upcall *upcall)
|
|||
|
||||
} else if (args->created) {
|
||||
const nfs41_component *name = &state->file.name;
|
||||
/* break any delegations and truncate before REMOVE */
|
||||
nfs41_delegation_return(state->session, &state->file,
|
||||
OPEN_DELEGATE_WRITE, TRUE);
|
||||
status = nfs41_remove(state->session, &state->parent, name);
|
||||
if (status)
|
||||
dprintf(1, "cancel_open: nfs41_remove() failed with %s\n",
|
||||
|
|
@ -722,6 +725,10 @@ static int handle_close(nfs41_upcall *upcall)
|
|||
create_silly_rename(&state->path, &state->file.fh, name);
|
||||
}
|
||||
|
||||
/* break any delegations and truncate before REMOVE */
|
||||
nfs41_delegation_return(state->session, &state->file,
|
||||
OPEN_DELEGATE_WRITE, TRUE);
|
||||
|
||||
dprintf(1, "calling nfs41_remove for %s\n", name->name);
|
||||
rm_status = nfs41_remove(state->session, &state->parent, name);
|
||||
if (rm_status) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue