All of lore.kernel.org
 help / color / mirror / Atom feed
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
>
>
>

  reply	other threads:[~2022-04-01 19:11 UTC|newest]

Thread overview: 29+ 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-15 14:47           ` dai.ngo
2022-04-15 14:56             ` dai.ngo
2022-04-15 15:19               ` Bruce Fields
2022-04-15 15:36                 ` dai.ngo
2022-04-15 19:53                 ` 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.