Re: [PATCH 07/27] NSM: Move nsm_find() to fs/lockd/mon.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Dec 05, 2008 at 07:02:45PM -0500, Chuck Lever wrote:
> The nsm_find() function sets up fresh nsm_handle entries.  This is
> where we will store the "priv" cookie used to lookup nsm_handles during
> reboot recovery.  The cookie will be constructed when nsm_find()
> creates a new nsm_handle.
> 
> As much as possible, I would like to keep everything that handles a
> "priv" cookie in fs/lockd/mon.c so that all the smarts are in one
> source file.  That organization should make it pretty simple to see how
> all this works.
> 
> To me, it makes more sense than the current arrangement to keep
> nsm_find() with nsm_monitor() and nsm_unmonitor().
> 
> So, start reorganizing by moving nsm_find() into fs/lockd/mon.c.  The
> nsm_release() function comes along too, since it shares the nsm_lock
> global variable.

OK, haven't thought that organization through myself, but it sounds
sensible, so I'll trust your judgement; applied.--b.

> 
> Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
> ---
> 
>  fs/lockd/host.c             |  129 -----------------------------------------
>  fs/lockd/mon.c              |  134 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/lockd/lockd.h |    6 ++
>  3 files changed, 140 insertions(+), 129 deletions(-)
> 
> diff --git a/fs/lockd/host.c b/fs/lockd/host.c
> index 316241a..dbdeaa8 100644
> --- a/fs/lockd/host.c
> +++ b/fs/lockd/host.c
> @@ -32,12 +32,6 @@ static int			nrhosts;
>  static DEFINE_MUTEX(nlm_host_mutex);
>  
>  static void			nlm_gc_hosts(void);
> -static struct nsm_handle	*nsm_find(const struct sockaddr *sap,
> -						const size_t salen,
> -						const char *hostname,
> -						const size_t hostname_len,
> -						const int create);
> -static void			nsm_release(struct nsm_handle *nsm);
>  
>  struct nlm_lookup_host_info {
>  	const int		server;		/* search for server|client */
> @@ -106,44 +100,6 @@ static void nlm_clear_port(struct sockaddr *sap)
>  	}
>  }
>  
> -static void nlm_display_ipv4_address(const struct sockaddr *sap, char *buf,
> -				     const size_t len)
> -{
> -	const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
> -	snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
> -}
> -
> -static void nlm_display_ipv6_address(const struct sockaddr *sap, char *buf,
> -				     const size_t len)
> -{
> -	const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
> -
> -	if (ipv6_addr_v4mapped(&sin6->sin6_addr))
> -		snprintf(buf, len, NIPQUAD_FMT,
> -				NIPQUAD(sin6->sin6_addr.s6_addr32[3]));
> -	else if (sin6->sin6_scope_id != 0)
> -		snprintf(buf, len, NIP6_FMT "%%%u", NIP6(sin6->sin6_addr),
> -				sin6->sin6_scope_id);
> -	else
> -		snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr));
> -}
> -
> -static void nlm_display_address(const struct sockaddr *sap,
> -				char *buf, const size_t len)
> -{
> -	switch (sap->sa_family) {
> -	case AF_INET:
> -		nlm_display_ipv4_address(sap, buf, len);
> -		break;
> -	case AF_INET6:
> -		nlm_display_ipv6_address(sap, buf, len);
> -		break;
> -	default:
> -		snprintf(buf, len, "unsupported address family");
> -		break;
> -	}
> -}
> -
>  /*
>   * Common host lookup routine for server & client
>   */
> @@ -636,88 +592,3 @@ nlm_gc_hosts(void)
>  
>  	next_gc = jiffies + NLM_HOST_COLLECT;
>  }
> -
> -
> -/*
> - * Manage NSM handles
> - */
> -static LIST_HEAD(nsm_handles);
> -static DEFINE_SPINLOCK(nsm_lock);
> -
> -static struct nsm_handle *nsm_find(const struct sockaddr *sap,
> -				   const size_t salen,
> -				   const char *hostname,
> -				   const size_t hostname_len,
> -				   const int create)
> -{
> -	struct nsm_handle *nsm = NULL;
> -	struct nsm_handle *pos;
> -
> -	if (!sap)
> -		return NULL;
> -
> -	if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
> -		if (printk_ratelimit()) {
> -			printk(KERN_WARNING "Invalid hostname \"%.*s\" "
> -					    "in NFS lock request\n",
> -				(int)hostname_len, hostname);
> -		}
> -		return NULL;
> -	}
> -
> -retry:
> -	spin_lock(&nsm_lock);
> -	list_for_each_entry(pos, &nsm_handles, sm_link) {
> -
> -		if (hostname && nsm_use_hostnames) {
> -			if (strlen(pos->sm_name) != hostname_len
> -			 || memcmp(pos->sm_name, hostname, hostname_len))
> -				continue;
> -		} else if (!nlm_cmp_addr(nsm_addr(pos), sap))
> -			continue;
> -		atomic_inc(&pos->sm_count);
> -		kfree(nsm);
> -		nsm = pos;
> -		goto found;
> -	}
> -	if (nsm) {
> -		list_add(&nsm->sm_link, &nsm_handles);
> -		goto found;
> -	}
> -	spin_unlock(&nsm_lock);
> -
> -	if (!create)
> -		return NULL;
> -
> -	nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
> -	if (nsm == NULL)
> -		return NULL;
> -
> -	memcpy(nsm_addr(nsm), sap, salen);
> -	nsm->sm_addrlen = salen;
> -	nsm->sm_name = (char *) (nsm + 1);
> -	memcpy(nsm->sm_name, hostname, hostname_len);
> -	nsm->sm_name[hostname_len] = '\0';
> -	nlm_display_address((struct sockaddr *)&nsm->sm_addr,
> -				nsm->sm_addrbuf, sizeof(nsm->sm_addrbuf));
> -	atomic_set(&nsm->sm_count, 1);
> -	goto retry;
> -
> -found:
> -	spin_unlock(&nsm_lock);
> -	return nsm;
> -}
> -
> -/*
> - * Release an NSM handle
> - */
> -static void nsm_release(struct nsm_handle *nsm)
> -{
> -	if (!nsm)
> -		return;
> -	if (atomic_dec_and_lock(&nsm->sm_count, &nsm_lock)) {
> -		list_del(&nsm->sm_link);
> -		spin_unlock(&nsm_lock);
> -		kfree(nsm);
> -	}
> -}
> diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
> index 81e1cc1..d5bd847 100644
> --- a/fs/lockd/mon.c
> +++ b/fs/lockd/mon.c
> @@ -47,12 +47,52 @@ struct nsm_res {
>  static struct rpc_clnt *	nsm_create(void);
>  
>  static struct rpc_program	nsm_program;
> +static				LIST_HEAD(nsm_handles);
> +static				DEFINE_SPINLOCK(nsm_lock);
>  
>  /*
>   * Local NSM state
>   */
>  int				nsm_local_state;
>  
> +static void nsm_display_ipv4_address(const struct sockaddr *sap, char *buf,
> +				     const size_t len)
> +{
> +	const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
> +	snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
> +}
> +
> +static void nsm_display_ipv6_address(const struct sockaddr *sap, char *buf,
> +				     const size_t len)
> +{
> +	const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
> +
> +	if (ipv6_addr_v4mapped(&sin6->sin6_addr))
> +		snprintf(buf, len, NIPQUAD_FMT,
> +				NIPQUAD(sin6->sin6_addr.s6_addr32[3]));
> +	else if (sin6->sin6_scope_id != 0)
> +		snprintf(buf, len, NIP6_FMT "%%%u", NIP6(sin6->sin6_addr),
> +				sin6->sin6_scope_id);
> +	else
> +		snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr));
> +}
> +
> +static void nsm_display_address(const struct sockaddr *sap,
> +				char *buf, const size_t len)
> +{
> +	switch (sap->sa_family) {
> +	case AF_INET:
> +		nsm_display_ipv4_address(sap, buf, len);
> +		break;
> +	case AF_INET6:
> +		nsm_display_ipv6_address(sap, buf, len);
> +		break;
> +	default:
> +		snprintf(buf, len, "unsupported address family");
> +		break;
> +	}
> +}
> +
>  /*
>   * Common procedure for NSMPROC_MON/NSMPROC_UNMON calls
>   */
> @@ -162,6 +202,100 @@ void nsm_unmonitor(const struct nlm_host *host)
>  	}
>  }
>  
> +/**
> + * nsm_find - Find or create a cached nsm_handle
> + * @sap: pointer to socket address of handle to find
> + * @salen: length of socket address
> + * @hostname: pointer to C string containing hostname to find
> + * @hostname_len: length of C string
> + * @create: one means create new handle if not found in cache
> + *
> + * Behavior is modulated by the global nsm_use_hostnames variable
> + * and by the @create argument.
> + *
> + * Returns a cached nsm_handle after bumping its ref count, or if
> + * @create is set, returns a fresh nsm_handle if a handle that
> + * matches @sap and/or @hostname cannot be found in the handle cache.
> + * Returns NULL if an error occurs.
> + */
> +struct nsm_handle *nsm_find(const struct sockaddr *sap, const size_t salen,
> +			    const char *hostname, const size_t hostname_len,
> +			    const int create)
> +{
> +	struct nsm_handle *nsm = NULL;
> +	struct nsm_handle *pos;
> +
> +	if (!sap)
> +		return NULL;
> +
> +	if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
> +		if (printk_ratelimit()) {
> +			printk(KERN_WARNING "Invalid hostname \"%.*s\" "
> +					    "in NFS lock request\n",
> +				(int)hostname_len, hostname);
> +		}
> +		return NULL;
> +	}
> +
> +retry:
> +	spin_lock(&nsm_lock);
> +	list_for_each_entry(pos, &nsm_handles, sm_link) {
> +
> +		if (hostname && nsm_use_hostnames) {
> +			if (strlen(pos->sm_name) != hostname_len
> +			 || memcmp(pos->sm_name, hostname, hostname_len))
> +				continue;
> +		} else if (!nlm_cmp_addr(nsm_addr(pos), sap))
> +			continue;
> +		atomic_inc(&pos->sm_count);
> +		kfree(nsm);
> +		nsm = pos;
> +		goto found;
> +	}
> +	if (nsm) {
> +		list_add(&nsm->sm_link, &nsm_handles);
> +		goto found;
> +	}
> +	spin_unlock(&nsm_lock);
> +
> +	if (!create)
> +		return NULL;
> +
> +	nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
> +	if (nsm == NULL)
> +		return NULL;
> +
> +	memcpy(nsm_addr(nsm), sap, salen);
> +	nsm->sm_addrlen = salen;
> +	nsm->sm_name = (char *) (nsm + 1);
> +	memcpy(nsm->sm_name, hostname, hostname_len);
> +	nsm->sm_name[hostname_len] = '\0';
> +	nsm_display_address((struct sockaddr *)&nsm->sm_addr,
> +				nsm->sm_addrbuf, sizeof(nsm->sm_addrbuf));
> +	atomic_set(&nsm->sm_count, 1);
> +	goto retry;
> +
> +found:
> +	spin_unlock(&nsm_lock);
> +	return nsm;
> +}
> +
> +/**
> + * nsm_release - Release an NSM handle
> + * @nsm: pointer to handle to be released
> + *
> + */
> +void nsm_release(struct nsm_handle *nsm)
> +{
> +	if (!nsm)
> +		return;
> +	if (atomic_dec_and_lock(&nsm->sm_count, &nsm_lock)) {
> +		list_del(&nsm->sm_link);
> +		spin_unlock(&nsm_lock);
> +		kfree(nsm);
> +	}
> +}
> +
>  /*
>   * Create NSM client for the local host
>   */
> diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
> index 38344bf..8d71536 100644
> --- a/include/linux/lockd/lockd.h
> +++ b/include/linux/lockd/lockd.h
> @@ -247,6 +247,12 @@ extern void	  nlm_host_rebooted(const struct sockaddr_in *, const char *,
>  int		  nsm_monitor(const struct nlm_host *host);
>  void		  nsm_unmonitor(const struct nlm_host *host);
>  
> +struct nsm_handle *nsm_find(const struct sockaddr *sap, const size_t salen,
> +					const char *hostname,
> +					const size_t hostname_len,
> +					const int create);
> +void		  nsm_release(struct nsm_handle *nsm);
> +
>  /*
>   * This is used in garbage collection and resource reclaim
>   * A return value != 0 means destroy the lock/block/share
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux