NFS: Fix stateid used for NFS v4 closes

After 566fcec60 the client uses the "current stateid" from the
nfs4_state structure to close a file.  This could potentially contain a
delegation stateid, which is disallowed by the protocol and causes
servers to return NFS4ERR_BAD_STATEID.  This patch restores the
(correct) behavior of sending the open stateid to close a file.

Reported-by: Olga Kornievskaia <kolga@netapp.com>
Fixes: 566fcec60 (NFSv4: Fix an atomicity problem in CLOSE)
Signed-off-by: Anna Schumaker <Anna.Schumaker@netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
Anna Schumaker 2015-03-02 16:46:09 -05:00 committed by Trond Myklebust
parent 7c0af9ffb7
commit 369d6b7f00

View File

@ -2655,7 +2655,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
case -NFS4ERR_BAD_STATEID: case -NFS4ERR_BAD_STATEID:
case -NFS4ERR_EXPIRED: case -NFS4ERR_EXPIRED:
if (!nfs4_stateid_match(&calldata->arg.stateid, if (!nfs4_stateid_match(&calldata->arg.stateid,
&state->stateid)) { &state->open_stateid)) {
rpc_restart_call_prepare(task); rpc_restart_call_prepare(task);
goto out_release; goto out_release;
} }
@ -2691,7 +2691,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags); is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags);
is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags); is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags);
is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags); is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags);
nfs4_stateid_copy(&calldata->arg.stateid, &state->stateid); nfs4_stateid_copy(&calldata->arg.stateid, &state->open_stateid);
/* Calculate the change in open mode */ /* Calculate the change in open mode */
calldata->arg.fmode = 0; calldata->arg.fmode = 0;
if (state->n_rdwr == 0) { if (state->n_rdwr == 0) {