All of lore.kernel.org
 help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@fieldses.org>
To: Jeff Layton <jlayton@primarydata.com>
Cc: linux-nfs@vger.kernel.org, hch@infradead.org
Subject: Re: [PATCH 37/37] nfsd: add some comments to the nfsd4 object definitions
Date: Tue, 5 Aug 2014 11:36:28 -0400	[thread overview]
Message-ID: <20140805153628.GP23341@fieldses.org> (raw)
In-Reply-To: <1406723258-8512-38-git-send-email-jlayton@primarydata.com>

Thanks for the documentation!  A couple comments:

On Wed, Jul 30, 2014 at 08:27:38AM -0400, Jeff Layton wrote:
> Add some comments that describe what each of these objects is, and how
> they related to one another.
> 
> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
> ---
>  fs/nfsd/netns.h |  8 +++++
>  fs/nfsd/state.h | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 92 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
> index 3831ef6e5c75..46680da55cd7 100644
> --- a/fs/nfsd/netns.h
> +++ b/fs/nfsd/netns.h
> @@ -34,6 +34,14 @@
>  struct cld_net;
>  struct nfsd4_client_tracking_ops;
>  
> +/*
> + * Represents a nfsd "container". With respect to nfsv4 state tracking, the
> + * fields of interest are the *_id_hashtbls and the *_name_tree. These track
> + * the nfs4_client objects by either short or long form clientid.
> + *
> + * Each nfsd_net runs a nfs4_laundromat workqueue job every lease period to

It's a little more complicated than that suggests--maybe replace "every
lease period" by "when necessary"?

> + * clean up expired clients and delegations within the container.
> + */
>  struct nfsd_net {
>  	struct cld_net *cld_net;
>  
> diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
> index a363f6bb621e..52ccd07d92ed 100644
> --- a/fs/nfsd/state.h
> +++ b/fs/nfsd/state.h
> @@ -72,6 +72,11 @@ struct nfsd4_callback {
>  	bool cb_done;
>  };
>  
> +/*
> + * A core object that represents a "common" stateid. These are generally
> + * embedded within the different (more specific) stateid objects and contain
> + * fields that are of general use to any stateid.
> + */
>  struct nfs4_stid {
>  	atomic_t sc_count;
>  #define NFS4_OPEN_STID 1
> @@ -89,6 +94,18 @@ struct nfs4_stid {
>  	void (*sc_free)(struct nfs4_stid *);
>  };
>  
> +/*
> + * Represents a delegation stateid. The nfs4_client holds references to these
> + * and they are put when it is being destroyed or when the delegation is
> + * returned by the client.

This might be worth another sentence or two.  I believe the references
are:

	- 1 reference as long as a delegation is still in force (taken
	  when it's alloc'd, put when it's returned or revoked)
	- 1 reference as long as a recall rpc is in progress (taken when
	  the lease is broken, put when the rpc exits.
	- 1 more ephemeral reference for each nfsd thread currently
	  doing something with that delegation without holding
	  cl_lock?

(By the way, I wonder if that list_for_each_entry() at the end of
nfsd4_process_cb_update actually does anything: hasn't
nfsd4_cb_recall_release() already run and removed any delegation from
the cl_callbacks list?  I may just be forgetting how this works.)

--b.

> + * If the server attempts to recall a delegation and the client doesn't do so
> + * before a timeout, the server may also revoke the delegation. In that case,
> + * the object will either be destroyed (v4.0) or moved to a per-client list of
> + * revoked delegations (v4.1+).
> + *
> + * This object is a superset of the nfs4_stid.
> + */
>  struct nfs4_delegation {
>  	struct nfs4_stid	dl_stid; /* must be first field */
>  	struct list_head	dl_perfile;
> @@ -195,6 +212,11 @@ struct nfsd4_conn {
>  	unsigned char cn_flags;
>  };
>  
> +/*
> + * Representation of a v4.1+ session. These are refcounted in a similar fashion
> + * to the nfs4_client. References are only taken when the server is actively
> + * working on the object (primarily during the processing of compounds).
> + */
>  struct nfsd4_session {
>  	atomic_t		se_ref;
>  	struct list_head	se_hash;	/* hash by sessionid */
> @@ -224,13 +246,30 @@ struct nfsd4_sessionid {
>  
>  /*
>   * struct nfs4_client - one per client.  Clientids live here.
> - * 	o Each nfs4_client is hashed by clientid.
>   *
> - * 	o Each nfs4_clients is also hashed by name 
> - * 	  (the opaque quantity initially sent by the client to identify itself).
> + * The initial object created by an NFS client using SETCLIENTID (for NFSv4.0)
> + * or EXCHANGE_ID (for NFSv4.1+). These objects are refcounted and timestamped.
> + * Each nfsd_net_ns object contains a set of these and they are tracked via
> + * short and long form clientid. They are hashed and searched for under the
> + * per-nfsd_net client_lock spinlock.
> + *
> + * References to it are only held during the processing of compounds, and in
> + * certain other operations. In their "resting state" they have a refcount of
> + * 0. If they are not renewed within a lease period, they become eligible for
> + * destruction by the laundromat.
> + *
> + * These objects can also be destroyed prematurely by the fault injection code,
> + * or if the client sends certain forms of SETCLIENTID or EXCHANGE_ID updates.
> + * Care is taken *not* to do this however when the objects have an elevated
> + * refcount.
> + *
> + * o Each nfs4_client is hashed by clientid
> + *
> + * o Each nfs4_clients is also hashed by name (the opaque quantity initially
> + *   sent by the client to identify itself).
>   * 	  
> - *	o cl_perclient list is used to ensure no dangling stateowner references
> - *	  when we expire the nfs4_client
> + * o cl_perclient list is used to ensure no dangling stateowner references
> + *   when we expire the nfs4_client
>   */
>  struct nfs4_client {
>  	struct list_head	cl_idhash; 	/* hash by cl_clientid.id */
> @@ -340,6 +379,12 @@ struct nfs4_stateowner_operations {
>  	void (*so_free)(struct nfs4_stateowner *);
>  };
>  
> +/*
> + * A core object that represents either an open or lock owner. The object and
> + * lock owner objects have one of these embedded within them. Refcounts and
> + * other fields common to both owner types are contained within these
> + * structures.
> + */
>  struct nfs4_stateowner {
>  	struct list_head			so_strhash;
>  	struct list_head			so_stateids;
> @@ -354,6 +399,12 @@ struct nfs4_stateowner {
>  	bool					so_is_open_owner;
>  };
>  
> +/*
> + * When a file is opened, the client provides an open state owner opaque string
> + * that indicates the "owner" of that open. These objects are refcounted.
> + * References to it are held by each open state associated with it. This object
> + * is a superset of the nfs4_stateowner struct.
> + */
>  struct nfs4_openowner {
>  	struct nfs4_stateowner	oo_owner; /* must be first field */
>  	struct list_head        oo_perclient;
> @@ -371,6 +422,12 @@ struct nfs4_openowner {
>  	unsigned char		oo_flags;
>  };
>  
> +/*
> + * Represents a generic "lockowner". Similar to an openowner. References to it
> + * are held by the lock stateids that are created on its behalf. This object is
> + * a superset of the nfs4_stateowner struct (or would be if it needed any extra
> + * fields).
> + */
>  struct nfs4_lockowner {
>  	struct nfs4_stateowner	lo_owner; /* must be first element */
>  };
> @@ -385,7 +442,14 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so)
>  	return container_of(so, struct nfs4_lockowner, lo_owner);
>  }
>  
> -/* nfs4_file: a file opened by some number of (open) nfs4_stateowners. */
> +/*
> + * nfs4_file: a file opened by some number of (open) nfs4_stateowners.
> + *
> + * These objects are global. nfsd only keeps one instance of a nfs4_file per
> + * inode (though it may keep multiple file descriptors open per inode). These
> + * are tracked in the file_hashtbl which is protected by the state_lock
> + * spinlock.
> + */
>  struct nfs4_file {
>  	atomic_t		fi_ref;
>  	spinlock_t		fi_lock;
> @@ -410,7 +474,20 @@ struct nfs4_file {
>  	bool			fi_had_conflict;
>  };
>  
> -/* "ol" stands for "Open or Lock".  Better suggestions welcome. */
> +/*
> + * A generic struct representing either a open or lock stateid. The nfs4_client
> + * holds a reference to each of these objects, and they in turn hold a
> + * reference to their respective stateowners. The client's reference is
> + * released in response to a close or unlock (depending on whether it's an open
> + * or lock stateid) or when the client is being destroyed.
> + *
> + * In the case of v4.0 open stateids, these objects are preserved for a little
> + * while after close in order to handle CLOSE replays. Those are eventually
> + * reclaimed via a LRU scheme by the laundromat.
> + *
> + * This object is a superset of the nfs4_stid. "ol" stands for "Open or Lock".
> + * Better suggestions welcome.
> + */
>  struct nfs4_ol_stateid {
>  	struct nfs4_stid    st_stid; /* must be first field */
>  	struct list_head              st_perfile;
> -- 
> 1.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2014-08-05 15:36 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-30 12:27 [PATCH 00/37] nfsd: remaining client_mutex removal patches Jeff Layton
2014-07-30 12:27 ` [PATCH 01/37] nfsd: Ensure struct nfs4_client is unhashed before we try to destroy it Jeff Layton
2014-07-30 12:27 ` [PATCH 02/37] nfsd: Ensure that the laundromat unhashes the client before releasing locks Jeff Layton
2014-07-30 12:27 ` [PATCH 03/37] nfsd: Don't require client_lock in free_client Jeff Layton
2014-07-30 12:27 ` [PATCH 04/37] nfsd: Move create_client() call outside the lock Jeff Layton
2014-07-30 12:27 ` [PATCH 05/37] nfsd: Protect unconfirmed client creation using client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 06/37] nfsd: Protect session creation and client confirm " Jeff Layton
2014-07-30 12:27 ` [PATCH 07/37] nfsd: Protect nfsd4_destroy_clientid " Jeff Layton
2014-07-30 12:27 ` [PATCH 08/37] nfsd: Ensure lookup_clientid() takes client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 09/37] nfsd: Add lockdep assertions to document the nfs4_client/session locking Jeff Layton
2014-08-04 21:18   ` J. Bruce Fields
2014-07-30 12:27 ` [PATCH 10/37] nfsd: protect the close_lru list and oo_last_closed_stid with client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 11/37] nfsd: move unhash_client_locked call into mark_client_expired_locked Jeff Layton
2014-07-30 12:27 ` [PATCH 12/37] nfsd: don't destroy client if mark_client_expired_locked fails Jeff Layton
2014-07-30 12:27 ` [PATCH 13/37] nfsd: don't destroy clients that are busy Jeff Layton
2014-07-30 12:27 ` [PATCH 14/37] nfsd: protect clid and verifier generation with client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 15/37] nfsd: abstract out the get and set routines into the fault injection ops Jeff Layton
2014-07-30 12:27 ` [PATCH 16/37] nfsd: add a forget_clients "get" routine with proper locking Jeff Layton
2014-07-30 12:27 ` [PATCH 17/37] nfsd: add a forget_client set_clnt routine Jeff Layton
2014-07-30 12:27 ` [PATCH 18/37] nfsd: add nfsd_inject_forget_clients Jeff Layton
2014-07-30 12:27 ` [PATCH 19/37] nfsd: add a list_head arg to nfsd_foreach_client_lock Jeff Layton
2014-07-30 12:27 ` [PATCH 20/37] nfsd: add more granular locking to forget_locks fault injector Jeff Layton
2014-07-30 12:27 ` [PATCH 21/37] nfsd: add more granular locking to forget_openowners " Jeff Layton
2014-07-30 12:27 ` [PATCH 22/37] nfsd: add more granular locking to *_delegations fault injectors Jeff Layton
2014-07-30 12:27 ` [PATCH 23/37] nfsd: remove old fault injection infrastructure Jeff Layton
2014-07-30 12:27 ` [PATCH 24/37] nfsd: Remove nfs4_lock_state(): nfs4_preprocess_stateid_op() Jeff Layton
2014-07-30 12:27 ` [PATCH 25/37] nfsd: Remove nfs4_lock_state(): nfsd4_test_stateid/nfsd4_free_stateid Jeff Layton
2014-07-30 12:27 ` [PATCH 26/37] nfsd: Remove nfs4_lock_state(): nfsd4_release_lockowner Jeff Layton
2014-07-30 12:27 ` [PATCH 27/37] nfsd: Remove nfs4_lock_state(): nfsd4_lock/locku/lockt() Jeff Layton
2014-07-30 12:27 ` [PATCH 28/37] nfsd: Remove nfs4_lock_state(): nfsd4_open_downgrade + nfsd4_close Jeff Layton
2014-07-30 12:27 ` [PATCH 29/37] nfsd: Remove nfs4_lock_state(): nfsd4_delegreturn() Jeff Layton
2014-07-30 12:27 ` [PATCH 30/37] nfsd: Remove nfs4_lock_state(): nfsd4_open and nfsd4_open_confirm Jeff Layton
2014-07-30 12:27 ` [PATCH 31/37] nfsd: Remove nfs4_lock_state(): exchange_id, create/destroy_session() Jeff Layton
2014-07-30 12:27 ` [PATCH 32/37] nfsd: Remove nfs4_lock_state(): setclientid, setclientid_confirm, renew Jeff Layton
2014-07-30 12:27 ` [PATCH 33/37] nfsd: Remove nfs4_lock_state(): reclaim_complete() Jeff Layton
2014-07-30 12:27 ` [PATCH 34/37] nfsd: remove nfs4_lock_state: nfs4_laundromat Jeff Layton
2014-07-30 12:27 ` [PATCH 35/37] nfsd: remove nfs4_lock_state: nfs4_state_shutdown_net Jeff Layton
2014-07-30 12:27 ` [PATCH 36/37] nfsd: remove the client_mutex and the nfs4_lock/unlock_state wrappers Jeff Layton
2014-08-01 11:20   ` Jeff Layton
2014-08-05 19:08     ` J. Bruce Fields
2014-07-30 12:27 ` [PATCH 37/37] nfsd: add some comments to the nfsd4 object definitions Jeff Layton
2014-08-05 15:36   ` J. Bruce Fields [this message]
2014-08-05 17:01     ` Jeff Layton
2014-08-05 18:56       ` J. Bruce Fields
2014-08-05 19:13   ` [PATCH v2] " Jeff Layton
2014-08-05 20:29     ` J. Bruce Fields
2014-08-01 20:48 ` [PATCH 00/37] nfsd: remaining client_mutex removal patches 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=20140805153628.GP23341@fieldses.org \
    --to=bfields@fieldses.org \
    --cc=hch@infradead.org \
    --cc=jlayton@primarydata.com \
    --cc=linux-nfs@vger.kernel.org \
    /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.