mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-28 20:02:17 +00:00
NFSv4: Fix the return value of nfs4_select_rw_stateid
In commit 5521abfdcf
(NFSv4: Resend the READ/WRITE RPC call
if a stateid change causes an error), we overloaded the return value of
nfs4_select_rw_stateid() to cause it to return -EWOULDBLOCK if an RPC
call is outstanding that would cause the NFSv4 lock or open stateid
to change.
That is all redundant when we actually copy the stateid used in the
read/write RPC call that failed, and check that against the current
stateid. It is doubly so, when we consider that in the NFSv4.1 case,
we also set the stateid's seqid to the special value '0', which means
'match the current valid stateid'.
Reported-by: Andy Adamson <andros@netapp.com>
Link: http://lkml.kernel.org/r/1393954269-3974-1-git-send-email-andros@netapp.com
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
e1253be0ec
commit
927864cd92
1 changed files with 3 additions and 11 deletions
|
@ -974,9 +974,6 @@ static int nfs4_copy_lock_stateid(nfs4_stateid *dst,
|
||||||
else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) {
|
else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) {
|
||||||
nfs4_stateid_copy(dst, &lsp->ls_stateid);
|
nfs4_stateid_copy(dst, &lsp->ls_stateid);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
smp_rmb();
|
|
||||||
if (!list_empty(&lsp->ls_seqid.list))
|
|
||||||
ret = -EWOULDBLOCK;
|
|
||||||
}
|
}
|
||||||
spin_unlock(&state->state_lock);
|
spin_unlock(&state->state_lock);
|
||||||
nfs4_put_lock_state(lsp);
|
nfs4_put_lock_state(lsp);
|
||||||
|
@ -984,10 +981,9 @@ static int nfs4_copy_lock_stateid(nfs4_stateid *dst,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
|
static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
|
||||||
{
|
{
|
||||||
const nfs4_stateid *src;
|
const nfs4_stateid *src;
|
||||||
int ret;
|
|
||||||
int seq;
|
int seq;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -996,12 +992,7 @@ static int nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
|
||||||
if (test_bit(NFS_OPEN_STATE, &state->flags))
|
if (test_bit(NFS_OPEN_STATE, &state->flags))
|
||||||
src = &state->open_stateid;
|
src = &state->open_stateid;
|
||||||
nfs4_stateid_copy(dst, src);
|
nfs4_stateid_copy(dst, src);
|
||||||
ret = 0;
|
|
||||||
smp_rmb();
|
|
||||||
if (!list_empty(&state->owner->so_seqid.list))
|
|
||||||
ret = -EWOULDBLOCK;
|
|
||||||
} while (read_seqretry(&state->seqlock, seq));
|
} while (read_seqretry(&state->seqlock, seq));
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1026,7 +1017,8 @@ int nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state,
|
||||||
* choose to use.
|
* choose to use.
|
||||||
*/
|
*/
|
||||||
goto out;
|
goto out;
|
||||||
ret = nfs4_copy_open_stateid(dst, state);
|
nfs4_copy_open_stateid(dst, state);
|
||||||
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
if (nfs_server_capable(state->inode, NFS_CAP_STATEID_NFSV41))
|
if (nfs_server_capable(state->inode, NFS_CAP_STATEID_NFSV41))
|
||||||
dst->seqid = 0;
|
dst->seqid = 0;
|
||||||
|
|
Loading…
Reference in a new issue