From: dai.ngo@oracle.com
To: Chuck Lever III <chuck.lever@oracle.com>,
Bruce Fields <bfields@fieldses.org>
Cc: Jeff Layton <jlayton@redhat.com>,
Al Viro <viro@zeniv.linux.org.uk>,
Linux NFS Mailing List <linux-nfs@vger.kernel.org>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>
Subject: Re: [PATCH RFC v19 06/11] NFSD: Update find_clp_in_name_tree() to handle courtesy client
Date: Fri, 1 Apr 2022 12:11:34 -0700 [thread overview]
Message-ID: <8dc762fc-dac8-b323-d0bc-4dbeada8c279@oracle.com> (raw)
In-Reply-To: <52CA1DBC-A0E2-4C1C-96DF-3E6114CDDFFD@oracle.com>
On 4/1/22 8:57 AM, Chuck Lever III wrote:
>
>> On Apr 1, 2022, at 11:21 AM, J. Bruce Fields <bfields@fieldses.org> wrote:
>>
>> On Thu, Mar 31, 2022 at 09:02:04AM -0700, Dai Ngo wrote:
>>> Update find_clp_in_name_tree to check and expire courtesy client.
>>>
>>> Update find_confirmed_client_by_name to discard the courtesy
>>> client by setting CLIENT_EXPIRED.
>>>
>>> Update nfsd4_setclientid to expire client with CLIENT_EXPIRED
>>> state to prevent multiple confirmed clients with the same name
>>> on the conf_name_tree.
>>>
>>> Signed-off-by: Dai Ngo <dai.ngo@oracle.com>
>>> ---
>>> fs/nfsd/nfs4state.c | 27 ++++++++++++++++++++++++---
>>> fs/nfsd/state.h | 22 ++++++++++++++++++++++
>>> 2 files changed, 46 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
>>> index fe8969ba94b3..eadce5d19473 100644
>>> --- a/fs/nfsd/nfs4state.c
>>> +++ b/fs/nfsd/nfs4state.c
>>> @@ -2893,8 +2893,11 @@ find_clp_in_name_tree(struct xdr_netobj *name, struct rb_root *root)
>>> node = node->rb_left;
>>> else if (cmp < 0)
>>> node = node->rb_right;
>>> - else
>>> + else {
>>> + if (nfsd4_courtesy_clnt_expired(clp))
>>> + return NULL;
>>> return clp;
>>> + }
>>> }
>>> return NULL;
>>> }
>>> @@ -2973,8 +2976,15 @@ static bool clp_used_exchangeid(struct nfs4_client *clp)
>>> static struct nfs4_client *
>>> find_confirmed_client_by_name(struct xdr_netobj *name, struct nfsd_net *nn)
>>> {
>>> + struct nfs4_client *clp;
>>> +
>>> lockdep_assert_held(&nn->client_lock);
>>> - return find_clp_in_name_tree(name, &nn->conf_name_tree);
>>> + clp = find_clp_in_name_tree(name, &nn->conf_name_tree);
>>> + if (clp && clp->cl_cs_client_state == NFSD4_CLIENT_RECONNECTED) {
>>> + nfsd4_discard_courtesy_clnt(clp);
>>> + clp = NULL;
>>> + }
>>> + return clp;
>>> }
>>>
>> ....
>>> +static inline void
>>> +nfsd4_discard_courtesy_clnt(struct nfs4_client *clp)
>>> +{
>>> + spin_lock(&clp->cl_cs_lock);
>>> + clp->cl_cs_client_state = NFSD4_CLIENT_EXPIRED;
>>> + spin_unlock(&clp->cl_cs_lock);
>>> +}
>> This is a red flag to me.... What guarantees that the condition we just
>> checked (cl_cs_client_state == NFSD4_CLIENT_RECONNECTED) is still true
>> here? Why couldn't another thread have raced in and called
>> reactivate_courtesy_client?
>>
>> Should we be holding cl_cs_lock across both the cl_cs_client_state and
>> the assignment?
> Holding cl_cs_lock while checking cl_cs_client_state and then
> updating it sounds OK to me.
Thanks Bruce and Chuck!
I replaced nfsd4_discard_courtesy_clnt with nfsd4_discard_reconnect_clnt
which checks and sets the cl_cs_client_state under the cl_cs_lock:
static inline bool
nfsd4_discard_reconnect_clnt(struct nfs4_client *clp)
{
bool ret = false;
spin_lock(&clp->cl_cs_lock);
if (clp->cl_cs_client_state == NFSD4_CLIENT_RECONNECTED) {
clp->cl_cs_client_state = NFSD4_CLIENT_EXPIRED;
ret = true;
}
spin_unlock(&clp->cl_cs_lock);
return ret;
}
>
>
>> Or should reactivate_courtesy_client be taking the
>> client_lock?
>>
>> I'm still not clear on the need for the CLIENT_RECONNECTED state.
>>
>> I think analysis would be a bit simpler if the only states were ACTIVE,
>> COURTESY, and EXPIRED, the only transitions possible were
>>
>> ACTIVE->COURTESY->{EXPIRED or ACTIVE}
>>
>> and the same lock ensured that those were the only possible transitions.
> Yes, that would be easier, but I don't think it's realistic. There
> are lock ordering issues between nn->client_lock and the locks on
> the individual files and state that make it onerous.
>
>
>> (And to be honest I'd still prefer the original approach where we expire
>> clients from the posix locking code and then retry. It handles an
>> additional case (the one where reboot happens after a long network
>> partition), and I don't think it requires adding these new client
>> states....)
> The locking of the earlier approach was unworkable.
>
> But, I'm happy to consider that again if you can come up with a way
> of handling it properly and simply.
I will wait for feedback from Bruce before sending v20 with the
above change.
-Dai
>
>
> --
> Chuck Lever
>
>
>
next prev parent reply other threads:[~2022-04-01 19:11 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-31 16:01 [PATCH RFC v19 0/11] NFSD: Initial implementation of NFSv4 Courteous Server Dai Ngo
2022-03-31 16:01 ` [PATCH RFC v19 01/11] fs/lock: add helper locks_owner_has_blockers to check for blockers Dai Ngo
2022-03-31 16:17 ` Chuck Lever III
2022-03-31 16:29 ` dai.ngo
2022-03-31 16:02 ` [PATCH RFC v19 02/11] NFSD: Add courtesy client state, macro and spinlock to support courteous server Dai Ngo
2022-03-31 16:02 ` [PATCH RFC v19 03/11] NFSD: Add lm_lock_expired call out Dai Ngo
2022-03-31 16:02 ` [PATCH RFC v19 04/11] NFSD: Update nfsd_breaker_owns_lease() to handle courtesy clients Dai Ngo
2022-03-31 16:02 ` [PATCH RFC v19 05/11] NFSD: Update nfs4_get_vfs_file() to handle courtesy client Dai Ngo
2022-03-31 16:02 ` [PATCH RFC v19 06/11] NFSD: Update find_clp_in_name_tree() " Dai Ngo
2022-04-01 15:21 ` J. Bruce Fields
2022-04-01 15:57 ` Chuck Lever III
2022-04-01 19:11 ` dai.ngo [this message]
2022-04-13 12:55 ` Bruce Fields
2022-04-13 18:28 ` dai.ngo
2022-04-13 18:42 ` Bruce Fields
2022-04-17 19:07 ` Bruce Fields
2022-04-18 1:18 ` dai.ngo
2022-03-31 16:02 ` [PATCH RFC v19 07/11] NFSD: Update find_in_sessionid_hashtbl() " Dai Ngo
2022-03-31 16:02 ` [PATCH RFC v19 08/11] NFSD: Update find_client_in_id_table() " Dai Ngo
2022-03-31 16:02 ` [PATCH RFC v19 09/11] NFSD: Refactor nfsd4_laundromat() Dai Ngo
2022-03-31 16:02 ` [PATCH RFC v19 10/11] NFSD: Update laundromat to handle courtesy clients Dai Ngo
2022-03-31 16:02 ` [PATCH RFC v19 11/11] NFSD: Show state of courtesy clients in client info Dai Ngo
2022-04-02 10:35 ` [PATCH RFC v19 0/11] NFSD: Initial implementation of NFSv4 Courteous Server Jeff Layton
2022-04-02 15:10 ` Chuck Lever III
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8dc762fc-dac8-b323-d0bc-4dbeada8c279@oracle.com \
--to=dai.ngo@oracle.com \
--cc=bfields@fieldses.org \
--cc=chuck.lever@oracle.com \
--cc=jlayton@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).