NFSv4: When returning a delegation, don't reclaim an incompatible open mode.
Subsystems (2)
PATCH 1/1 NFSv4: When returning a delegation, don't reclaim an incompatible open mode.
It is possible to have an active open with one mode, and a delegation for the same file with a different mode.
In particular, a WR_ONLY open and an RD_ONLY delegation. This happens if a WR_ONLY open is followed by a RD_ONLY open which provides a delegation, but is then close.
When returning the delegation, we currently try to claim opens for every open type (n_rdwr, n_rdonly, n_wronly). As there is no harm in claiming an open for a mode that we already have, this is often simplest.
However if the delegation only provides a subset of the modes that we currently have open, this will produce an error from the server.
So when claiming open modes prior to returning a delegation, skip the open request if the mode is not covered by the delegation - the open_stateid must already cover that mode, so there is nothing to do.
fs/nfs/nfs4proc.c +7 -0
@@ -1553,6 +1553,13 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, fmode_t fmodstruct nfs4_state *newstate;int ret; +if ((opendata->o_arg.claim ==NFS4_OPEN_CLAIM_DELEGATE_CUR || + opendata->o_arg.claim ==NFS4_OPEN_CLAIM_DELEG_CUR_FH ) && + (opendata->o_arg.u.delegation_type & fmode) != fmode) +/* This mode can't have been delegated, so we must have +* a valid open_stateid to cover it - not need to reclaim. +*/ +return 0 ; opendata->o_arg.open_flags =0 ; opendata->o_arg.fmode = fmode; opendata->o_arg.share_access = nfs4_map_atomic_open_share(