NFSv4: deal with v4.0 servers that request confirmation on reclaim-type opens
Subsystems (2)
cover NFSv4: deal with v4.0 servers that request confirmation on reclaim-type opens
A Red Hat customer started having problems with open reclaims after a kernel upgrade. It turns out that the customer's NFS server is setting the OPEN4_RESULT_CONFIRM in response to an OPEN(CLAIM_PREVIOUS), which is not permitted by RFC 7530.
The client used to be able to handle that because nfs4_open_prepare() used to copy the filehandle from the OPEN args to the OPEN results when doing an open by filehandle. That copy was removed by commit 4e2fcac77390 "nfsv4: Use correct inode in _nfs4_opendata_to_nfs4_state()".
It looks to me like adding the copy back in would not affect the behavior of the nfs4_opendata_get_inode() helper that was added in 4e2fcac77390 (it uses the filehandle to look up the inode when doing an open by name)... so this patch adds the copy back in and also adds a warning in the event that the client does receive OPEN4_RESULT_CONFIRM in response to an OPEN(CLAIM_PREVIOUS).
Scott Mayhew (1):
NFSv4: deal with v4.0 servers that request confirmation on
reclaim-type opens
fs/nfs/nfs4proc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
Signature · 1 line
2.17.1
PATCH 1/1 NFSv4: deal with v4.0 servers that request confirmation on reclaim-type opens
There are some NFS v4.0 servers that request confirmation on reclaim-type opens even though it is disallowed by RFC 7530.
The Linux NFS client used to cope with those okay due to
1) nfs4_opendata_alloc() setting the filehandle in the args for the OPEN_CONFIRM to point to the filehandle in the OPEN results, and
2) nfs4_open_prepare() copying the filehandle from the OPEN args to the OPEN results when doing an open by filehandle
The latter part was removed by commit 4e2fcac77390 ("nfsv4: Use correct inode in _nfs4_opendata_to_nfs4_state()")... and since there's no GETFH in the OPEN compound when doing a reclaim-type open, if one of these servers does request confirmation we wind up sending a zero filehandle in the PUTFH of the OPEN_CONFIRM compound and the OPEN_CONFIRM fails with NFS4ERR_BADHANDLE, causing the reclaim to fail.
Add the copying of the filehandle back to nfs4_open_prepare() and log a warning in the event that the client does get a reply to OPEN(CLAIM_PREVIOUS) that has NFS4_OPEN_RESULT_CONFIRM set.
--- fs/nfs/nfs4proc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/nfs/nfs4proc.c +8 -1
@@ -2323,6 +2323,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)/* Fall through */ case NFS4_OPEN_CLAIM_FH : task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR ]; +nfs_copy_fh (&data->o_res.fh, data->o_arg.fh); } data->timestamp = jiffies; if (nfs4_setup_sequence(data->o_arg.server->nfs_client,
@@ -2470,8 +2471,14 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data)nfs_fattr_map_and_free_names (NFS_SERVER (dir), &data->f_attr); -if (o_res->rflags &NFS4_OPEN_RESULT_CONFIRM ) +if (o_res->rflags &NFS4_OPEN_RESULT_CONFIRM ) { +if (data->o_arg.claim ==NFS4_OPEN_CLAIM_PREVIOUS ) +pr_err_ratelimited ("NFS: Broken NFSv4 server %s is " +"requesting open confirmation for " +"OPEN(CLAIM_PREVIOUS)\n" , +NFS_SERVER (dir)->nfs_client->cl_hostname); status =_nfs4_proc_open_confirm (data); + }return status; }
Signature · 1 line
2.17.1
Quoted 58 lines · Scott Mayhew
There are some NFS v4.0 servers that request confirmation on reclaim-type opens even though it is disallowed by RFC 7530.
The Linux NFS client used to cope with those okay due to
1)nfs4_opendata_alloc()setting the filehandle in the args for theOPEN_CONFIRMto point to the filehandle in the OPEN results, and
2)nfs4_open_prepare()copying the filehandle from the OPEN args to the
OPEN results when doing an open by filehandleThe latter part was removed by commit
4e2fcac77390("nfsv4: Use correct
inode in_nfs4_opendata_to_nfs4_state()")... and since there's no GETFH
in the OPEN compound when doing a reclaim-type open, if one of these servers does request confirmation we wind up sending a zero filehandle
in the PUTFH of theOPEN_CONFIRMcompound and theOPEN_CONFIRMfails withNFS4ERR_BADHANDLE, causing the reclaim to fail.Add the copying of the filehandle back to
nfs4_open_prepare()and log a warning in the event that the client does get a reply toOPEN(CLAIM_PREVIOUS)that hasNFS4_OPEN_RESULT_CONFIRMset.Signed-off-by Scott Mayhew <[email protected]>--- fs/nfs/nfs4proc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)fs/nfs/nfs4proc.c +1
-0@@ -2323,6 +2323,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)/* Fall through */ case NFS4_OPEN_CLAIM_FH : task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR ]; +nfs_copy_fh (&data->o_res.fh, data->o_arg.fh); }fs/nfs/nfs4proc.c +3
-1data->timestamp = jiffies; if (nfs4_setup_sequence(data->o_arg.server->nfs_client,@@ -2470,8 +2471,14 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data) nfs_fattr_map_and_free_names(NFS_SERVER(dir), &data->f_attr); -if (o_res->rflags &NFS4_OPEN_RESULT_CONFIRM ) +if (o_res->rflags &NFS4_OPEN_RESULT_CONFIRM ) { +if (data->o_arg.claim ==NFS4_OPEN_CLAIM_PREVIOUS ) + pr_err_ratelimited("NFS: Broken NFSv4 server %sis "
fs/nfs/nfs4proc.c +1
-0+ "requesting open confirmationfor "
fs/nfs/nfs4proc.c +2
-0+"OPEN(CLAIM_PREVIOUS)\n" , + NFS_SERVER(dir)->nfs_client-Quoted 1 line
cl_hostname);
fs/nfs/nfs4proc.c static int _nfs4_recover_proc_open(struct nfs4_opendata *data) · line 2484
Quoted 5 lines
fs/nfs/nfs4proc.c +1
-0status =_nfs4_proc_open_confirm (data); + }return status; }
If the spec says that the server is broken, then we don't change the client. We already have one ugly hack like this, but that is no excuse for adding a second.
Signature · 3 lines
Trond Myklebust Linux NFS client maintainer, Hammerspace [email protected]