All of lore.kernel.org
 help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@fieldses.org>
To: Dai Ngo <dai.ngo@oracle.com>
Cc: chuck.lever@oracle.com, jlayton@redhat.com,
	viro@zeniv.linux.org.uk, linux-nfs@vger.kernel.org,
	linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH RFC v24 6/7] NFSD: add support for lock conflict to courteous server
Date: Mon, 2 May 2022 12:00:58 -0400	[thread overview]
Message-ID: <20220502160058.GF30550@fieldses.org> (raw)
In-Reply-To: <1651426696-15509-7-git-send-email-dai.ngo@oracle.com>

On Sun, May 01, 2022 at 10:38:15AM -0700, Dai Ngo wrote:
> This patch allows expired client with lock state to be in COURTESY
> state. Lock conflict with COURTESY client is resolved by the fs/lock
> code using the lm_lock_expirable and lm_expire_lock callback in the
> struct lock_manager_operations.
> 
> If conflict client is in COURTESY state, set it to EXPIRABLE and
> schedule the laundromat to run immediately to expire the client. The
> callback lm_expire_lock waits for the laundromat to flush its work
> queue before returning to caller.

Reviewed-by: J. Bruce Fields <bfields@fieldses.org>

(These searches over hash tables that we're adding in a few places are
inefficient, but I'm assuming it won't matter.  And I don't have a
better idea off the top of my head.  So I'm fine with just doing this
instead of optimizing prematurely.)

--b.

> 
> Signed-off-by: Dai Ngo <dai.ngo@oracle.com>
> ---
>  fs/nfsd/nfs4state.c | 70 +++++++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 54 insertions(+), 16 deletions(-)
> 
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index f369142da79f..4ab7dda44f38 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -5715,39 +5715,51 @@ static void nfsd4_ssc_expire_umount(struct nfsd_net *nn)
>  }
>  #endif
>  
> +/* Check if any lock belonging to this lockowner has any blockers */
>  static bool
> -nfs4_has_any_locks(struct nfs4_client *clp)
> +nfs4_lockowner_has_blockers(struct nfs4_lockowner *lo)
> +{
> +	struct file_lock_context *ctx;
> +	struct nfs4_ol_stateid *stp;
> +	struct nfs4_file *nf;
> +
> +	list_for_each_entry(stp, &lo->lo_owner.so_stateids, st_perstateowner) {
> +		nf = stp->st_stid.sc_file;
> +		ctx = nf->fi_inode->i_flctx;
> +		if (!ctx)
> +			continue;
> +		if (locks_owner_has_blockers(ctx, lo))
> +			return true;
> +	}
> +	return false;
> +}
> +
> +static bool
> +nfs4_anylock_blockers(struct nfs4_client *clp)
>  {
>  	int i;
>  	struct nfs4_stateowner *so;
> +	struct nfs4_lockowner *lo;
>  
> +	if (atomic_read(&clp->cl_delegs_in_recall))
> +		return true;
>  	spin_lock(&clp->cl_lock);
>  	for (i = 0; i < OWNER_HASH_SIZE; i++) {
>  		list_for_each_entry(so, &clp->cl_ownerstr_hashtbl[i],
>  				so_strhash) {
>  			if (so->so_is_open_owner)
>  				continue;
> -			spin_unlock(&clp->cl_lock);
> -			return true;
> +			lo = lockowner(so);
> +			if (nfs4_lockowner_has_blockers(lo)) {
> +				spin_unlock(&clp->cl_lock);
> +				return true;
> +			}
>  		}
>  	}
>  	spin_unlock(&clp->cl_lock);
>  	return false;
>  }
>  
> -/*
> - * place holder for now, no check for lock blockers yet
> - */
> -static bool
> -nfs4_anylock_blockers(struct nfs4_client *clp)
> -{
> -	if (atomic_read(&clp->cl_delegs_in_recall) ||
> -			!list_empty(&clp->async_copies) ||
> -			nfs4_has_any_locks(clp))
> -		return true;
> -	return false;
> -}
> -
>  static void
>  nfs4_get_client_reaplist(struct nfsd_net *nn, struct list_head *reaplist,
>  				struct laundry_time *lt)
> @@ -6712,6 +6724,29 @@ nfsd4_lm_put_owner(fl_owner_t owner)
>  		nfs4_put_stateowner(&lo->lo_owner);
>  }
>  
> +/* return pointer to struct nfs4_client if client is expirable */
> +static bool
> +nfsd4_lm_lock_expirable(struct file_lock *cfl)
> +{
> +	struct nfs4_lockowner *lo = (struct nfs4_lockowner *)cfl->fl_owner;
> +	struct nfs4_client *clp = lo->lo_owner.so_client;
> +	struct nfsd_net *nn;
> +
> +	if (try_to_expire_client(clp)) {
> +		nn = net_generic(clp->net, nfsd_net_id);
> +		mod_delayed_work(laundry_wq, &nn->laundromat_work, 0);
> +		return true;
> +	}
> +	return false;
> +}
> +
> +/* schedule laundromat to run immediately and wait for it to complete */
> +static void
> +nfsd4_lm_expire_lock(void)
> +{
> +	flush_workqueue(laundry_wq);
> +}
> +
>  static void
>  nfsd4_lm_notify(struct file_lock *fl)
>  {
> @@ -6738,9 +6773,12 @@ nfsd4_lm_notify(struct file_lock *fl)
>  }
>  
>  static const struct lock_manager_operations nfsd_posix_mng_ops  = {
> +	.lm_mod_owner = THIS_MODULE,
>  	.lm_notify = nfsd4_lm_notify,
>  	.lm_get_owner = nfsd4_lm_get_owner,
>  	.lm_put_owner = nfsd4_lm_put_owner,
> +	.lm_lock_expirable = nfsd4_lm_lock_expirable,
> +	.lm_expire_lock = nfsd4_lm_expire_lock,
>  };
>  
>  static inline void
> -- 
> 2.9.5

  reply	other threads:[~2022-05-02 16:01 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-01 17:38 [PATCH RFC v24 0/7] NFSD: Initial implementation of NFSv4 Courteous Server Dai Ngo
2022-05-01 17:38 ` [PATCH RFC v24 1/7] NFSD: add courteous server support for thread with only delegation Dai Ngo
2022-05-02 15:23   ` J. Bruce Fields
2022-05-01 17:38 ` [PATCH RFC v24 2/7] NFSD: add support for share reservation conflict to courteous server Dai Ngo
2022-05-02 15:31   ` J. Bruce Fields
2022-05-01 17:38 ` [PATCH RFC v24 3/7] NFSD: move create/destroy of laundry_wq to init_nfsd and exit_nfsd Dai Ngo
2022-05-02 15:35   ` J. Bruce Fields
2022-05-01 17:38 ` [PATCH RFC v24 4/7] fs/lock: add helper locks_owner_has_blockers to check for blockers Dai Ngo
2022-05-02 15:43   ` J. Bruce Fields
2022-05-01 17:38 ` [PATCH RFC v24 5/7] fs/lock: add 2 callbacks to lock_manager_operations to resolve conflict Dai Ngo
2022-05-02 15:53   ` J. Bruce Fields
2022-05-01 17:38 ` [PATCH RFC v24 6/7] NFSD: add support for lock conflict to courteous server Dai Ngo
2022-05-02 16:00   ` J. Bruce Fields [this message]
2022-05-01 17:38 ` [PATCH RFC v24 7/7] NFSD: Show state of courtesy client in client info Dai Ngo
2022-05-02 16:06   ` J. Bruce Fields
2022-05-02 16:07 ` [PATCH RFC v24 0/7] NFSD: Initial implementation of NFSv4 Courteous Server J. Bruce Fields

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=20220502160058.GF30550@fieldses.org \
    --to=bfields@fieldses.org \
    --cc=chuck.lever@oracle.com \
    --cc=dai.ngo@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.