Commit 631fc9ea authored by J. Bruce Fields's avatar J. Bruce Fields

nfsd4: allow removing clients not holding state

RFC 5661 actually says we should allow an exchange_id to remove a
matching client, even if the exchange_id comes from a different
principal, *if* the victim client lacks any state.
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 136e658d
...@@ -1508,6 +1508,19 @@ nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid) ...@@ -1508,6 +1508,19 @@ nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid)
clid->flags = new->cl_exchange_flags; clid->flags = new->cl_exchange_flags;
} }
static bool client_has_state(struct nfs4_client *clp)
{
/*
* Note clp->cl_openowners check isn't quite right: there's no
* need to count owners without stateid's.
*
* Also note we should probably be using this in 4.0 case too.
*/
return list_empty(&clp->cl_openowners)
&& list_empty(&clp->cl_delegations)
&& list_empty(&clp->cl_sessions);
}
__be32 __be32
nfsd4_exchange_id(struct svc_rqst *rqstp, nfsd4_exchange_id(struct svc_rqst *rqstp,
struct nfsd4_compound_state *cstate, struct nfsd4_compound_state *cstate,
...@@ -1576,15 +1589,19 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, ...@@ -1576,15 +1589,19 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
goto out_copy; goto out_copy;
} }
if (!creds_match) { /* case 3 */ if (!creds_match) { /* case 3 */
if (client_has_state(conf)) {
status = nfserr_clid_inuse; status = nfserr_clid_inuse;
goto out; goto out;
} }
goto expire_client;
}
if (verfs_match) { /* case 2 */ if (verfs_match) { /* case 2 */
exid->flags |= EXCHGID4_FLAG_CONFIRMED_R; exid->flags |= EXCHGID4_FLAG_CONFIRMED_R;
new = conf; new = conf;
goto out_copy; goto out_copy;
} }
/* case 5, client reboot */ /* case 5, client reboot */
expire_client:
expire_client(conf); expire_client(conf);
goto out_new; goto out_new;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment