Linux NFS development
 help / color / mirror / Atom feed
* [PATCH 00/14] RFC: IPv6 support for kernel NSM
@ 2008-10-24 18:09 Chuck Lever
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  0 siblings, 1 reply; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:09 UTC (permalink / raw)
  To: linux-nfs

I'm interested in some comments on the following proposal for supporting
IPv6 in the kernel's NSM implementation.

The first three patches simply add support for using an IPv6 address for
the mon_name argument when nsm_use_hostnames is not set.  Nothing too
complex there.  It re-uses the address display functions in
fs/lockd/host.c to generate the address string.

The middle eight patches replace the contents of the "priv" argument to
the SM_MON upcall and the NLM_SM_NOTIFY downcall.  We use a 32-bit raw
IPv4 address today, so we have to replace it with something else to
support IPv6 properly.  I propose using an arbitrary unique cookie for
each nsm_handle.

This is a little more extensive than a simple change here, as I
decided to re-organize this code a little bit to make it simpler to
understand and modify.  The idea is to move as many NSM-related data
structures and functions into fs/lockd/mon.c.  The creation and
interpretation of the cookies should happen in just this one place,
and not be spread around in fs/lockd/host.c and in lockd's XDR layer.
It should be easier to understand and relate the various pieces now.

The last three patches are clean-ups that result from this
reorganization.

This patch set builds, but has not been tested.  Constructive comments
and review are welcome.

---

Chuck Lever (14):
      NSM: Use same helpers in nsm_get_handle() and nsm_lookup_rebooted()
      NLM: Remove "create" argument from nsm_find()
      NSM: Remove include/linux/lockd/sm_inter.h
      NSM: Replace IP address as our nlm_reboot lookup key
      NSM: Add nsm_lookup() function
      NLM: Decode "priv" argument of NLM_SM_NOTIFY as an opaque
      NLM: Change nlm_host_rebooted() to take a single nlm_reboot argument
      NSM: Generate "priv" argument when nsm_handle is created
      NSM: Move NSM program and procedure numbers to fs/lockd/mon.c
      NSM: Move NSM-related XDR data structures to lockd's xdr.h
      NSM: Move NSM-related function and variable declarations to lockd.h
      NSM: Support IPv6 version of mon_name
      NSM: Move nsm_find() to fs/lockd/mon.c
      NLM: Beef up NLM address display function


 fs/lockd/clntproc.c            |    1 
 fs/lockd/host.c                |  173 +++++++----------------
 fs/lockd/mon.c                 |  298 ++++++++++++++++++++++++++++++++--------
 fs/lockd/svc.c                 |    1 
 fs/lockd/svc4proc.c            |   13 --
 fs/lockd/svcproc.c             |   13 --
 fs/lockd/svcsubs.c             |    1 
 fs/lockd/xdr.c                 |    5 -
 fs/lockd/xdr4.c                |    5 -
 include/linux/lockd/lockd.h    |   31 +++-
 include/linux/lockd/sm_inter.h |   48 ------
 include/linux/lockd/xdr.h      |   15 +-
 12 files changed, 335 insertions(+), 269 deletions(-)
 delete mode 100644 include/linux/lockd/sm_inter.h

-- 
Chuck Lever

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 01/14] NLM: Beef up NLM address display function
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2008-10-24 18:09   ` Chuck Lever
       [not found]     ` <20081024180954.23810.34150.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2008-10-24 18:10   ` [PATCH 02/14] NSM: Move nsm_find() to fs/lockd/mon.c Chuck Lever
                     ` (12 subsequent siblings)
  13 siblings, 1 reply; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:09 UTC (permalink / raw)
  To: linux-nfs

Add support for IPv6 addresses with a scope ID, and enable calls from
outside of fs/lockd/host.c

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/host.c             |   51 ++++++++++++++++++++++++++++++++-----------
 include/linux/lockd/lockd.h |   13 ++++++++---
 2 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 9fd8889..c7516ae 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -104,29 +104,54 @@ static void nlm_clear_port(struct sockaddr *sap)
 	}
 }
 
-static void nlm_display_address(const struct sockaddr *sap,
-				char *buf, const size_t len)
+static int 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));
+
+	return 0;
+}
+
+static int 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));
+
+	return 0;
+}
+
+/**
+ * nlm_display_address - Convert sockaddr to presentation format
+ * @sap: pointer to socket address
+ * @buf: pointer to buffer to fill in
+ * @len: length of buffer
+ *
+ */
+int nlm_display_address(const struct sockaddr *sap, char *buf,
+			const size_t len)
+{
 	switch (sap->sa_family) {
 	case AF_UNSPEC:
-		snprintf(buf, len, "unspecified");
-		break;
+		snprintf(buf, len, "unspecified address");
+		return -EAFNOSUPPORT;
 	case AF_INET:
-		snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
-		break;
+		return nlm_display_ipv4_address(sap, buf, len);
 	case AF_INET6:
-		if (ipv6_addr_v4mapped(&sin6->sin6_addr))
-			snprintf(buf, len, NIPQUAD_FMT,
-				 NIPQUAD(sin6->sin6_addr.s6_addr32[3]));
-		else
-			snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr));
-		break;
+		return nlm_display_ipv6_address(sap, buf, len);
 	default:
 		snprintf(buf, len, "unsupported address family");
-		break;
+		return -EAFNOSUPPORT;
 	}
 }
 
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index b56d5aa..4e713f9 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -36,6 +36,11 @@
 #define LOCKD_DFLT_TIMEO	10
 
 /*
+ * Size of presentation format address buffer
+ */
+#define LOCKD_ADDRBUF		55
+
+/*
  * Lockd host handle (used both by the client and server personality).
  */
 struct nlm_host {
@@ -65,8 +70,8 @@ struct nlm_host {
 	struct list_head	h_reclaim;	/* Locks in RECLAIM state */
 	struct nsm_handle *	h_nsmhandle;	/* NSM status handle */
 
-	char			h_addrbuf[48],	/* address eyecatchers */
-				h_srcaddrbuf[48];
+	char			h_addrbuf[LOCKD_ADDRBUF],
+				h_srcaddrbuf[LOCKD_ADDRBUF];
 };
 
 struct nsm_handle {
@@ -77,7 +82,7 @@ struct nsm_handle {
 	size_t			sm_addrlen;
 	unsigned int		sm_monitored : 1,
 				sm_sticky : 1;	/* don't unmonitor */
-	char			sm_addrbuf[48];	/* address eyecatcher */
+	char			sm_addrbuf[LOCKD_ADDRBUF];
 };
 
 /*
@@ -224,6 +229,8 @@ struct nlm_host  *nlmclnt_lookup_host(const struct sockaddr *sap,
 struct nlm_host  *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
 					const char *hostname,
 					const size_t hostname_len);
+int		  nlm_display_address(const struct sockaddr *sap,
+					char *buf, const size_t len);
 struct rpc_clnt * nlm_bind_host(struct nlm_host *);
 void		  nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 02/14] NSM: Move nsm_find() to fs/lockd/mon.c
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2008-10-24 18:09   ` [PATCH 01/14] NLM: Beef up NLM address display function Chuck Lever
@ 2008-10-24 18:10   ` Chuck Lever
  2008-10-24 18:10   ` [PATCH 03/14] NSM: Support IPv6 version of mon_name Chuck Lever
                     ` (11 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:10 UTC (permalink / raw)
  To: linux-nfs

Start coalescing NSM-related functions into fs/lockd/mon.c by moving
the nsm_find() function (and associated static variables) into
fs/lockd/mon.c.

One minor change to nsm_release() -- it doesn't currently look
possible to call it with a NULL argument, so I'm removing that check.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/host.c             |   91 -------------------------------------------
 fs/lockd/mon.c              |   88 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/lockd/lockd.h |    9 ++++
 3 files changed, 96 insertions(+), 92 deletions(-)

diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index c7516ae..0fb0910 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -32,11 +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);
 
 struct nlm_lookup_host_info {
 	const int		server;		/* search for server|client */
@@ -645,89 +640,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
- */
-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 4e7e958..a5c6ec4 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -29,6 +29,9 @@ static struct rpc_program	nsm_program;
  */
 int				nsm_local_state;
 
+static				LIST_HEAD(nsm_handles);
+static				DEFINE_SPINLOCK(nsm_lock);
+
 /*
  * Common procedure for SM_MON/SM_UNMON calls
  */
@@ -69,6 +72,91 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 	return status;
 }
 
+/**
+ * nsm_find - Find a cached nsm_handle by name or address
+ * @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
+ *
+ */
+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;
+}
+
+/**
+ * nsm_release - Release an NSM handle
+ * @nsm: pointer to handle to be released
+ *
+ */
+void nsm_release(struct nsm_handle *nsm)
+{
+	if (atomic_dec_and_lock(&nsm->sm_count, &nsm_lock)) {
+		list_del(&nsm->sm_link);
+		spin_unlock(&nsm_lock);
+		kfree(nsm);
+	}
+}
+
 /*
  * Set up monitoring of a remote host
  */
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 4e713f9..a45be5d 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -238,8 +238,15 @@ void		  nlm_release_host(struct nlm_host *);
 void		  nlm_shutdown_hosts(void);
 extern void	  nlm_host_rebooted(const struct sockaddr_in *, const char *,
 					unsigned int, u32);
-void		  nsm_release(struct nsm_handle *);
 
+/*
+ * Host monitoring
+ */
+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


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 03/14] NSM: Support IPv6 version of mon_name
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2008-10-24 18:09   ` [PATCH 01/14] NLM: Beef up NLM address display function Chuck Lever
  2008-10-24 18:10   ` [PATCH 02/14] NSM: Move nsm_find() to fs/lockd/mon.c Chuck Lever
@ 2008-10-24 18:10   ` Chuck Lever
       [not found]     ` <20081024181009.23810.56793.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2008-10-24 18:10   ` [PATCH 04/14] NSM: Move NSM-related function and variable declarations to lockd.h Chuck Lever
                     ` (10 subsequent siblings)
  13 siblings, 1 reply; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:10 UTC (permalink / raw)
  To: linux-nfs

When the "nsm_use_hostnames" sysctl is set to zero, the kernel's NSM
provides a presentation format IP address in the mon_name argument of
SM_MON upcalls.  This is part of the private interface between Linux's
rpc.statd and the kernel's lockd implementation.  Linux's rpc.statd
can then resolve this address with DNS as a sanity check.

To support IPv6 addresses for the mon_name argument, just point the
XDR encoder to the nsm_handle's eye-catcher, which already contains a
presentation format address string.

Finally, provide some debugging message clean up.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/mon.c |   43 +++++++++++++++----------------------------
 1 files changed, 15 insertions(+), 28 deletions(-)

diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index a5c6ec4..1c058b1 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -18,8 +18,6 @@
 
 #define NLMDBG_FACILITY		NLMDBG_MONITOR
 
-#define XDR_ADDRBUF_LEN		(20)
-
 static struct rpc_clnt *	nsm_create(void);
 
 static struct rpc_program	nsm_program;
@@ -40,7 +38,14 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 {
 	struct rpc_clnt	*clnt;
 	int		status;
-	struct nsm_args	args;
+	struct nsm_args	args = {
+		.addr		= nsm_addr_in(nsm)->sin_addr.s_addr,
+		.prog		= NLM_PROGRAM,
+		.vers		= 3,
+		.proc		= NLMPROC_NSM_NOTIFY,
+		.mon_name	= nsm_use_hostnames ?
+					nsm->sm_name : nsm->sm_addrbuf,
+	};
 	struct rpc_message msg = {
 		.rpc_argp	= &args,
 		.rpc_resp	= res,
@@ -49,24 +54,21 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 	clnt = nsm_create();
 	if (IS_ERR(clnt)) {
 		status = PTR_ERR(clnt);
+		dprintk("lockd: failed to create nsm transport, "
+				"status=%d\n", status);
 		goto out;
 	}
 
-	memset(&args, 0, sizeof(args));
-	args.mon_name = nsm->sm_name;
-	args.addr = nsm_addr_in(nsm)->sin_addr.s_addr;
-	args.prog = NLM_PROGRAM;
-	args.vers = 3;
-	args.proc = NLMPROC_NSM_NOTIFY;
 	memset(res, 0, sizeof(*res));
 
 	msg.rpc_proc = &clnt->cl_procinfo[proc];
 	status = rpc_call_sync(clnt, &msg, 0);
 	if (status < 0)
-		printk(KERN_DEBUG "nsm_mon_unmon: rpc failed, status=%d\n",
-			status);
-	else
+		dprintk("lockd: nsm rpc failed, status=%d\n", status);
+	else {
 		status = 0;
+		dprintk("lockd: monitoring '%s'\n", args.mon_name);
+	}
 	rpc_shutdown_client(clnt);
  out:
 	return status;
@@ -253,25 +255,10 @@ static __be32 *xdr_encode_nsm_string(__be32 *p, char *string)
 
 /*
  * "mon_name" specifies the host to be monitored.
- *
- * Linux uses a text version of the IP address of the remote
- * host as the host identifier (the "mon_name" argument).
- *
- * Linux statd always looks up the canonical hostname first for
- * whatever remote hostname it receives, so this works alright.
  */
 static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp)
 {
-	char	buffer[XDR_ADDRBUF_LEN + 1];
-	char	*name = argp->mon_name;
-
-	if (!nsm_use_hostnames) {
-		snprintf(buffer, XDR_ADDRBUF_LEN,
-			 NIPQUAD_FMT, NIPQUAD(argp->addr));
-		name = buffer;
-	}
-
-	return xdr_encode_nsm_string(p, name);
+	return xdr_encode_nsm_string(p, argp->mon_name);
 }
 
 /*


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 04/14] NSM: Move NSM-related function and variable declarations to lockd.h
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (2 preceding siblings ...)
  2008-10-24 18:10   ` [PATCH 03/14] NSM: Support IPv6 version of mon_name Chuck Lever
@ 2008-10-24 18:10   ` Chuck Lever
       [not found]     ` <20081024181016.23810.69413.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2008-10-24 18:10   ` [PATCH 05/14] NSM: Move NSM-related XDR data structures to lockd's xdr.h Chuck Lever
                     ` (9 subsequent siblings)
  13 siblings, 1 reply; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:10 UTC (permalink / raw)
  To: linux-nfs

Clean up: Keep the NSM function declarations together with the
declarations already in lockd.h, and modernize the documenting
comments.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/mon.c                 |   18 ++++++++++--------
 include/linux/lockd/lockd.h    |    4 ++++
 include/linux/lockd/sm_inter.h |    4 ----
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 1c058b1..d48ae14 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -159,11 +159,12 @@ void nsm_release(struct nsm_handle *nsm)
 	}
 }
 
-/*
- * Set up monitoring of a remote host
+/**
+ * nsm_monitor - Set up monitoring of a remote host
+ * @host: pointer to nlm_host representing remote peer to monitor
+ *
  */
-int
-nsm_monitor(struct nlm_host *host)
+int nsm_monitor(struct nlm_host *host)
 {
 	struct nsm_handle *nsm = host->h_nsmhandle;
 	struct nsm_res	res;
@@ -184,11 +185,12 @@ nsm_monitor(struct nlm_host *host)
 	return status;
 }
 
-/*
- * Cease to monitor remote host
+/**
+ * nsm_unmonitor - Cease to monitor remote host
+ * @host: pointer to nlm_host representing remote peer to stop monitoring
+ *
  */
-int
-nsm_unmonitor(struct nlm_host *host)
+int nsm_unmonitor(struct nlm_host *host)
 {
 	struct nsm_handle *nsm = host->h_nsmhandle;
 	struct nsm_res	res;
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index a45be5d..6dc1043 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -200,7 +200,9 @@ extern struct svc_procedure	nlmsvc_procedures4[];
 #endif
 extern int			nlmsvc_grace_period;
 extern unsigned long		nlmsvc_timeout;
+
 extern int			nsm_use_hostnames;
+extern int			nsm_local_state;
 
 /*
  * Lockd client functions
@@ -247,6 +249,8 @@ struct nsm_handle *nsm_find(const struct sockaddr *sap, const size_t salen,
 					const size_t hostname_len,
 					const int create);
 void		  nsm_release(struct nsm_handle *nsm);
+int		  nsm_monitor(struct nlm_host *host);
+int		  nsm_unmonitor(struct nlm_host *host);
 
 /*
  * This is used in garbage collection and resource reclaim
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index 5a5448b..f75d3ea 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -41,8 +41,4 @@ struct nsm_res {
 	u32		state;
 };
 
-int		nsm_monitor(struct nlm_host *);
-int		nsm_unmonitor(struct nlm_host *);
-extern int	nsm_local_state;
-
 #endif /* LINUX_LOCKD_SM_INTER_H */


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 05/14] NSM: Move NSM-related XDR data structures to lockd's xdr.h
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (3 preceding siblings ...)
  2008-10-24 18:10   ` [PATCH 04/14] NSM: Move NSM-related function and variable declarations to lockd.h Chuck Lever
@ 2008-10-24 18:10   ` Chuck Lever
  2008-10-24 18:10   ` [PATCH 06/14] NSM: Move NSM program and procedure numbers to fs/lockd/mon.c Chuck Lever
                     ` (8 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:10 UTC (permalink / raw)
  To: linux-nfs

Clean up: NSM's XDR data structures are used only in fs/lockd/mon.c,
so move them out of the public header sm_inter.h.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/mon.c                 |   14 ++++++++++++++
 include/linux/lockd/sm_inter.h |   20 --------------------
 2 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index d48ae14..db650cf 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -22,6 +22,20 @@ static struct rpc_clnt *	nsm_create(void);
 
 static struct rpc_program	nsm_program;
 
+struct nsm_args {
+	__be32			addr;		/* remote address */
+	u32			prog;		/* RPC callback info */
+	u32			vers;
+	u32			proc;
+
+	char			*mon_name;
+};
+
+struct nsm_res {
+	u32			status;
+	u32			state;
+};
+
 /*
  * Local NSM state
  */
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index f75d3ea..29f0206 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -21,24 +21,4 @@
 #define SM_MAXSTRLEN	1024
 #define SM_PRIV_SIZE	16
 
-/*
- * Arguments for all calls to statd
- */
-struct nsm_args {
-	__be32		addr;		/* remote address */
-	u32		prog;		/* RPC callback info */
-	u32		vers;
-	u32		proc;
-
-	char *		mon_name;
-};
-
-/*
- * Result returned by statd
- */
-struct nsm_res {
-	u32		status;
-	u32		state;
-};
-
 #endif /* LINUX_LOCKD_SM_INTER_H */


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 06/14] NSM: Move NSM program and procedure numbers to fs/lockd/mon.c
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (4 preceding siblings ...)
  2008-10-24 18:10   ` [PATCH 05/14] NSM: Move NSM-related XDR data structures to lockd's xdr.h Chuck Lever
@ 2008-10-24 18:10   ` Chuck Lever
  2008-10-24 18:10   ` [PATCH 07/14] NSM: Generate "priv" argument when nsm_handle is created Chuck Lever
                     ` (7 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:10 UTC (permalink / raw)
  To: linux-nfs

Clean up: Move the RPC program and procedure numbers for NSM into the
one source file that needs them: fs/lockd/mon.c.

And, as with NLM, NFS, and rpcbind calls, use NSMPROC_FOO instead of
SM_FOO for NSM procedure numbers.

Finally, make a couple of comments more precise: what is referred to
here as SM_NOTIFY is really an NLM (lockd) call, not NSMPROC_NOTIFY.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/mon.c                 |   37 +++++++++++++++++++++++++------------
 include/linux/lockd/sm_inter.h |    9 ---------
 2 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index db650cf..6f3a54e 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -18,6 +18,19 @@
 
 #define NLMDBG_FACILITY		NLMDBG_MONITOR
 
+#define NSM_PROGRAM		(100024)
+#define NSM_VERSION		(1)
+
+enum {
+	NSMPROC_NULL,
+	NSMPROC_STAT,
+	NSMPROC_MON,
+	NSMPROC_UNMON,
+	NSMPROC_UNMON_ALL,
+	NSMPROC_SIMU_CRASH,
+	NSMPROC_NOTIFY,
+};
+
 static struct rpc_clnt *	nsm_create(void);
 
 static struct rpc_program	nsm_program;
@@ -190,7 +203,7 @@ int nsm_monitor(struct nlm_host *host)
 	if (nsm->sm_monitored)
 		return 0;
 
-	status = nsm_mon_unmon(nsm, SM_MON, &res);
+	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res);
 
 	if (status < 0 || res.status != 0)
 		printk(KERN_NOTICE "lockd: cannot monitor %s\n", host->h_name);
@@ -218,7 +231,7 @@ int nsm_unmonitor(struct nlm_host *host)
 	 && nsm->sm_monitored && !nsm->sm_sticky) {
 		dprintk("lockd: nsm_unmonitor(%s)\n", host->h_name);
 
-		status = nsm_mon_unmon(nsm, SM_UNMON, &res);
+		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res);
 		if (status < 0)
 			printk(KERN_NOTICE "lockd: cannot unmonitor %s\n",
 					host->h_name);
@@ -246,7 +259,7 @@ nsm_create(void)
 		.addrsize	= sizeof(sin),
 		.servername	= "localhost",
 		.program	= &nsm_program,
-		.version	= SM_VERSION,
+		.version	= NSM_VERSION,
 		.authflavor	= RPC_AUTH_NULL,
 	};
 
@@ -280,7 +293,7 @@ static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp)
 /*
  * The "my_id" argument specifies the hostname and RPC procedure
  * to be called when the status manager receives notification
- * (via the SM_NOTIFY call) that the state of host "mon_name"
+ * (via the NLM_SM_NOTIFY call) that the state of host "mon_name"
  * has changed.
  */
 static __be32 *xdr_encode_my_id(__be32 *p, struct nsm_args *argp)
@@ -312,7 +325,7 @@ static __be32 *xdr_encode_mon_id(__be32 *p, struct nsm_args *argp)
 /*
  * The "priv" argument may contain private information required
  * by the SM_MON call. This information will be supplied in the
- * SM_NOTIFY call.
+ * NLM_SM_NOTIFY call.
  *
  * Linux provides the raw IP address of the monitored host,
  * left in network byte order.
@@ -379,22 +392,22 @@ xdr_decode_stat(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp)
 #define SM_unmonres_sz	1
 
 static struct rpc_procinfo	nsm_procedures[] = {
-[SM_MON] = {
-		.p_proc		= SM_MON,
+[NSMPROC_MON] = {
+		.p_proc		= NSMPROC_MON,
 		.p_encode	= (kxdrproc_t) xdr_encode_mon,
 		.p_decode	= (kxdrproc_t) xdr_decode_stat_res,
 		.p_arglen	= SM_mon_sz,
 		.p_replen	= SM_monres_sz,
-		.p_statidx	= SM_MON,
+		.p_statidx	= NSMPROC_MON,
 		.p_name		= "MONITOR",
 	},
-[SM_UNMON] = {
-		.p_proc		= SM_UNMON,
+[NSMPROC_UNMON] = {
+		.p_proc		= NSMPROC_UNMON,
 		.p_encode	= (kxdrproc_t) xdr_encode_unmon,
 		.p_decode	= (kxdrproc_t) xdr_decode_stat,
 		.p_arglen	= SM_mon_id_sz,
 		.p_replen	= SM_unmonres_sz,
-		.p_statidx	= SM_UNMON,
+		.p_statidx	= NSMPROC_UNMON,
 		.p_name		= "UNMONITOR",
 	},
 };
@@ -413,7 +426,7 @@ static struct rpc_stat		nsm_stats;
 
 static struct rpc_program	nsm_program = {
 		.name		= "statd",
-		.number		= SM_PROGRAM,
+		.number		= NSM_PROGRAM,
 		.nrvers		= ARRAY_SIZE(nsm_version),
 		.version	= nsm_version,
 		.stats		= &nsm_stats
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index 29f0206..da72872 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -9,15 +9,6 @@
 #ifndef LINUX_LOCKD_SM_INTER_H
 #define LINUX_LOCKD_SM_INTER_H
 
-#define SM_PROGRAM	100024
-#define SM_VERSION	1
-#define SM_STAT		1
-#define SM_MON		2
-#define SM_UNMON	3
-#define SM_UNMON_ALL	4
-#define SM_SIMU_CRASH	5
-#define SM_NOTIFY	6
-
 #define SM_MAXSTRLEN	1024
 #define SM_PRIV_SIZE	16
 


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 07/14] NSM: Generate "priv" argument when nsm_handle is created
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (5 preceding siblings ...)
  2008-10-24 18:10   ` [PATCH 06/14] NSM: Move NSM program and procedure numbers to fs/lockd/mon.c Chuck Lever
@ 2008-10-24 18:10   ` Chuck Lever
  2008-10-24 18:10   ` [PATCH 08/14] NLM: Change nlm_host_rebooted() to take a single nlm_reboot argument Chuck Lever
                     ` (6 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:10 UTC (permalink / raw)
  To: linux-nfs

Construct the "priv" cookie when the nsm_handle is created, and pass
that to SM_MON's XDR encoder, instead of creating the "priv" cookie
in the encoder at call time.

This patch should not cause a behavioral change: the contents of the
cookie remain the same for the time being.

Collect NSM XDR data type definitions in the same header as NLM XDR
data type definitions, since lockd uses NSM XDR data types too.  The
nlm_reboot data structure, for example, is used in both lockd and in
the NSM implementation.  The new definition of nsm_private is placed
in xdr.h, and the definition of SM_PRIV_SIZE is placed next to it.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/mon.c                 |   29 ++++++++++++++++++-----------
 include/linux/lockd/lockd.h    |    1 +
 include/linux/lockd/sm_inter.h |    1 -
 include/linux/lockd/xdr.h      |    6 ++++++
 4 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 6f3a54e..a4d2b9e 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -36,7 +36,7 @@ static struct rpc_clnt *	nsm_create(void);
 static struct rpc_program	nsm_program;
 
 struct nsm_args {
-	__be32			addr;		/* remote address */
+	struct nsm_private	*priv;
 	u32			prog;		/* RPC callback info */
 	u32			vers;
 	u32			proc;
@@ -66,7 +66,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 	struct rpc_clnt	*clnt;
 	int		status;
 	struct nsm_args	args = {
-		.addr		= nsm_addr_in(nsm)->sin_addr.s_addr,
+		.priv		= &nsm->sm_priv,
 		.prog		= NLM_PROGRAM,
 		.vers		= 3,
 		.proc		= NLMPROC_NSM_NOTIFY,
@@ -101,6 +101,20 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 	return status;
 }
 
+/*
+ * Construct a unique cookie to identify this nsm_handle.  It is
+ * passed to our statd via SM_MON, and returned via NLM_SM_NOTIFY,
+ * in the "priv" field of these requests.
+ *
+ * Linux provides the raw IP address of the monitored host,
+ * left in network byte order.
+ */
+static void nsm_init_private(struct nsm_handle *nsm)
+{
+	__be32 *p = (__be32 *)&nsm->sm_priv.data;
+	*p = nsm_addr_in(nsm)->sin_addr.s_addr;
+}
+
 /**
  * nsm_find - Find a cached nsm_handle by name or address
  * @sap: pointer to socket address of handle to find
@@ -162,6 +176,7 @@ retry:
 	nsm->sm_name = (char *) (nsm + 1);
 	memcpy(nsm->sm_name, hostname, hostname_len);
 	nsm->sm_name[hostname_len] = '\0';
+	nsm_init_private(nsm);
 	nlm_display_address((struct sockaddr *)&nsm->sm_addr,
 				nsm->sm_addrbuf, sizeof(nsm->sm_addrbuf));
 	atomic_set(&nsm->sm_count, 1);
@@ -326,18 +341,10 @@ static __be32 *xdr_encode_mon_id(__be32 *p, struct nsm_args *argp)
  * The "priv" argument may contain private information required
  * by the SM_MON call. This information will be supplied in the
  * NLM_SM_NOTIFY call.
- *
- * Linux provides the raw IP address of the monitored host,
- * left in network byte order.
  */
 static __be32 *xdr_encode_priv(__be32 *p, struct nsm_args *argp)
 {
-	*p++ = argp->addr;
-	*p++ = 0;
-	*p++ = 0;
-	*p++ = 0;
-
-	return p;
+	return xdr_encode_opaque(p, argp->priv->data, sizeof(argp->priv->data));
 }
 
 static int
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 6dc1043..20a56e9 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -82,6 +82,7 @@ struct nsm_handle {
 	size_t			sm_addrlen;
 	unsigned int		sm_monitored : 1,
 				sm_sticky : 1;	/* don't unmonitor */
+	struct nsm_private	sm_priv;
 	char			sm_addrbuf[LOCKD_ADDRBUF];
 };
 
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index da72872..7f22d6f 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -10,6 +10,5 @@
 #define LINUX_LOCKD_SM_INTER_H
 
 #define SM_MAXSTRLEN	1024
-#define SM_PRIV_SIZE	16
 
 #endif /* LINUX_LOCKD_SM_INTER_H */
diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h
index d6b3a80..6b51992 100644
--- a/include/linux/lockd/xdr.h
+++ b/include/linux/lockd/xdr.h
@@ -13,6 +13,12 @@
 #include <linux/nfs.h>
 #include <linux/sunrpc/xdr.h>
 
+#define SM_PRIV_SIZE		16
+
+struct nsm_private {
+	unsigned char		data[SM_PRIV_SIZE];
+};
+
 struct svc_rqst;
 
 #define NLM_MAXCOOKIELEN    	32


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 08/14] NLM: Change nlm_host_rebooted() to take a single nlm_reboot argument
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (6 preceding siblings ...)
  2008-10-24 18:10   ` [PATCH 07/14] NSM: Generate "priv" argument when nsm_handle is created Chuck Lever
@ 2008-10-24 18:10   ` Chuck Lever
  2008-10-24 18:10   ` [PATCH 09/14] NLM: Decode "priv" argument of NLM_SM_NOTIFY as an opaque Chuck Lever
                     ` (5 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:10 UTC (permalink / raw)
  To: linux-nfs

Pass the nlm_reboot data structure directly from the NLM_SM_NOTIFY
XDR decoder to nlm_host_rebooted().  This eliminates some packing and
unpacking of the NLM_SM_NOTIFY results, and prepares for passing
NLM_SM_NOTIFY's "priv" argument directly to nsm_find().

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/host.c             |   31 +++++++++++++++++--------------
 fs/lockd/svc4proc.c         |   11 +----------
 fs/lockd/svcproc.c          |   11 +----------
 include/linux/lockd/lockd.h |    3 +--
 4 files changed, 20 insertions(+), 36 deletions(-)

diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 0fb0910..91e26be 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -492,31 +492,34 @@ void nlm_release_host(struct nlm_host *host)
 	}
 }
 
-/*
- * We were notified that the host indicated by address &sin
- * has rebooted.
- * Release all resources held by that peer.
+/**
+ * nlm_host_rebooted - Release all resources held by rebooted host
+ * @info: pointer to decoded results of NLM_SM_NOTIFY call
+ *
+ * We were notified that the specified host has rebooted.  Release
+ * all resources held by that peer.
  */
-void nlm_host_rebooted(const struct sockaddr_in *sin,
-				const char *hostname,
-				unsigned int hostname_len,
-				u32 new_state)
+void nlm_host_rebooted(struct nlm_reboot *info)
 {
+	const struct sockaddr_in sin = {
+		.sin_family		= AF_INET,
+		.sin_addr.s_addr	= info->addr,
+	};
 	struct hlist_head *chain;
 	struct hlist_node *pos;
 	struct nsm_handle *nsm;
 	struct nlm_host	*host;
 
-	nsm = nsm_find((struct sockaddr *)sin, sizeof(*sin),
-			hostname, hostname_len, 0);
+	nsm = nsm_find((struct sockaddr *)&sin, sizeof(sin),
+			info->mon, info->len, 0);
 	if (nsm == NULL) {
 		dprintk("lockd: never saw rebooted peer '%.*s' before\n",
-				hostname_len, hostname);
+				info->len, info->mon);
 		return;
 	}
 
 	dprintk("lockd: nlm_host_rebooted(%.*s, %s)\n",
-			hostname_len, hostname, nsm->sm_addrbuf);
+			info->len, info->mon, nsm->sm_addrbuf);
 
 	/* When reclaiming locks on this peer, make sure that
 	 * we set up a new notification */
@@ -531,8 +534,8 @@ again:	mutex_lock(&nlm_host_mutex);
 	for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) {
 		hlist_for_each_entry(host, pos, chain, h_hash) {
 			if (host->h_nsmhandle == nsm
-			 && host->h_nsmstate != new_state) {
-				host->h_nsmstate = new_state;
+			 && host->h_nsmstate != info->state) {
+				host->h_nsmstate = info->state;
 				host->h_state++;
 
 				nlm_get_host(host);
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 4dfdcbc..bb79a53 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -419,8 +419,6 @@ static __be32
 nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 					      void	        *resp)
 {
-	struct sockaddr_in	saddr;
-
 	dprintk("lockd: SM_NOTIFY     called\n");
 
 	if (!nlm_privileged_requester(rqstp)) {
@@ -430,14 +428,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 		return rpc_system_err;
 	}
 
-	/* Obtain the host pointer for this NFS server and try to
-	 * reclaim all locks we hold on this server.
-	 */
-	memset(&saddr, 0, sizeof(saddr));
-	saddr.sin_family = AF_INET;
-	saddr.sin_addr.s_addr = argp->addr;
-	nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state);
-
+	nlm_host_rebooted(argp);
 	return rpc_success;
 }
 
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 3ca89e2..e44310c 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -451,8 +451,6 @@ static __be32
 nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 					      void	        *resp)
 {
-	struct sockaddr_in	saddr;
-
 	dprintk("lockd: SM_NOTIFY     called\n");
 
 	if (!nlm_privileged_requester(rqstp)) {
@@ -462,14 +460,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 		return rpc_system_err;
 	}
 
-	/* Obtain the host pointer for this NFS server and try to
-	 * reclaim all locks we hold on this server.
-	 */
-	memset(&saddr, 0, sizeof(saddr));
-	saddr.sin_family = AF_INET;
-	saddr.sin_addr.s_addr = argp->addr;
-	nlm_host_rebooted(&saddr, argp->mon, argp->len, argp->state);
-
+	nlm_host_rebooted(argp);
 	return rpc_success;
 }
 
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 20a56e9..d271169 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -239,8 +239,7 @@ void		  nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);
 void		  nlm_release_host(struct nlm_host *);
 void		  nlm_shutdown_hosts(void);
-extern void	  nlm_host_rebooted(const struct sockaddr_in *, const char *,
-					unsigned int, u32);
+void		  nlm_host_rebooted(struct nlm_reboot *);
 
 /*
  * Host monitoring


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 09/14] NLM: Decode "priv" argument of NLM_SM_NOTIFY as an opaque
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (7 preceding siblings ...)
  2008-10-24 18:10   ` [PATCH 08/14] NLM: Change nlm_host_rebooted() to take a single nlm_reboot argument Chuck Lever
@ 2008-10-24 18:10   ` Chuck Lever
  2008-10-24 18:11   ` [PATCH 10/14] NSM: Add nsm_lookup() function Chuck Lever
                     ` (4 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:10 UTC (permalink / raw)
  To: linux-nfs

The NLM XDR decoders for the NLM_SM_NOTIFY procedure should treat
their "priv" argument truly as an opaque, as defined by the protocol,
and let the upper layers figure out what is in it.

This will make it easier to modify the contents and interpretation of
the "priv" argument, but for now NLM and NSM should behave exactly as
they did before.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/host.c           |    3 ++-
 fs/lockd/xdr.c            |    4 ++--
 fs/lockd/xdr4.c           |    4 ++--
 include/linux/lockd/xdr.h |    8 ++++----
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 91e26be..4949eb3 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -501,9 +501,10 @@ void nlm_release_host(struct nlm_host *host)
  */
 void nlm_host_rebooted(struct nlm_reboot *info)
 {
+	__be32 *p = (__be32 *)&info->priv.data;
 	const struct sockaddr_in sin = {
 		.sin_family		= AF_INET,
-		.sin_addr.s_addr	= info->addr,
+		.sin_addr.s_addr	= *p,
 	};
 	struct hlist_head *chain;
 	struct hlist_node *pos;
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index 1f22629..4cc7d01 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -349,8 +349,8 @@ nlmsvc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp)
 	if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN)))
 		return 0;
 	argp->state = ntohl(*p++);
-	/* Preserve the address in network byte order */
-	argp->addr = *p++;
+	memcpy(&argp->priv.data, p, sizeof(argp->priv.data));
+	p += XDR_QUADLEN(SM_PRIV_SIZE);
 	return xdr_argsize_check(rqstp, p);
 }
 
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index 50c493a..61d1714 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -356,8 +356,8 @@ nlm4svc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp
 	if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN)))
 		return 0;
 	argp->state = ntohl(*p++);
-	/* Preserve the address in network byte order */
-	argp->addr  = *p++;
+	memcpy(&argp->priv.data, p, sizeof(argp->priv.data));
+	p += XDR_QUADLEN(SM_PRIV_SIZE);
 	return xdr_argsize_check(rqstp, p);
 }
 
diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h
index 6b51992..6338866 100644
--- a/include/linux/lockd/xdr.h
+++ b/include/linux/lockd/xdr.h
@@ -83,10 +83,10 @@ struct nlm_res {
  * statd callback when client has rebooted
  */
 struct nlm_reboot {
-	char *		mon;
-	unsigned int	len;
-	u32		state;
-	__be32		addr;
+	char			*mon;
+	unsigned int		len;
+	u32			state;
+	struct nsm_private	priv;
 };
 
 /*


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 10/14] NSM: Add nsm_lookup() function
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (8 preceding siblings ...)
  2008-10-24 18:10   ` [PATCH 09/14] NLM: Decode "priv" argument of NLM_SM_NOTIFY as an opaque Chuck Lever
@ 2008-10-24 18:11   ` Chuck Lever
  2008-10-24 18:11   ` [PATCH 11/14] NSM: Replace IP address as our nlm_reboot lookup key Chuck Lever
                     ` (3 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:11 UTC (permalink / raw)
  To: linux-nfs

Introduce a new function to fs/lockd/mon.c that allows nlm_host_rebooted()
to lookup up nsm_handles by their "priv".

This should not introduce a behavioral change, but finishes the job of
collecting all logic in fs/lockd/mon.c that cares what's inside an
nsm_private structure.

This will make it easier to modify the contents and interpretation of
the "priv" argument, but for now NLM and NSM should behave exactly as
they did before.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/host.c             |    8 +------
 fs/lockd/mon.c              |   48 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/lockd/lockd.h |    1 +
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 4949eb3..1ecec4f 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -501,18 +501,12 @@ void nlm_release_host(struct nlm_host *host)
  */
 void nlm_host_rebooted(struct nlm_reboot *info)
 {
-	__be32 *p = (__be32 *)&info->priv.data;
-	const struct sockaddr_in sin = {
-		.sin_family		= AF_INET,
-		.sin_addr.s_addr	= *p,
-	};
 	struct hlist_head *chain;
 	struct hlist_node *pos;
 	struct nsm_handle *nsm;
 	struct nlm_host	*host;
 
-	nsm = nsm_find((struct sockaddr *)&sin, sizeof(sin),
-			info->mon, info->len, 0);
+	nsm = nsm_reboot_lookup(info);
 	if (nsm == NULL) {
 		dprintk("lockd: never saw rebooted peer '%.*s' before\n",
 				info->len, info->mon);
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index a4d2b9e..c38ef20 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -101,6 +101,29 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 	return status;
 }
 
+static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv)
+{
+	struct nsm_handle *nsm;
+
+	list_for_each_entry(nsm, &nsm_handles, sm_link)
+		if (memcmp(nsm->sm_priv.data, priv->data,
+					sizeof(priv->data)) == 0)
+			return nsm;
+	return NULL;
+}
+
+static struct nsm_handle *nsm_lookup_hostname(const char *hostname,
+					      const size_t len)
+{
+	struct nsm_handle *nsm;
+
+	list_for_each_entry(nsm, &nsm_handles, sm_link)
+		if (strlen(nsm->sm_name) == len &&
+		    memcmp(nsm->sm_name, hostname, len) == 0)
+			return nsm;
+	return NULL;
+}
+
 /*
  * Construct a unique cookie to identify this nsm_handle.  It is
  * passed to our statd via SM_MON, and returned via NLM_SM_NOTIFY,
@@ -188,6 +211,31 @@ found:
 }
 
 /**
+ * nsm_reboot_lookup - match NLM_SM_NOTIFY arguments to an nsm_handle
+ * @info: pointer to NLM_SM_NOTIFY arguments
+ *
+ * Returns a matching nsm_handle if found in the nsm cache; otherwise
+ * returns NULL;
+ */
+struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
+{
+	struct nsm_handle *cached;
+
+	spin_lock(&nsm_lock);
+
+	if (nsm_use_hostnames && info->mon)
+		cached = nsm_lookup_hostname(info->mon, info->len);
+	else
+		cached = nsm_lookup_priv(&info->priv);
+	if (cached)
+		atomic_inc(&cached->sm_count);
+
+	spin_unlock(&nsm_lock);
+
+	return cached;
+}
+
+/**
  * nsm_release - Release an NSM handle
  * @nsm: pointer to handle to be released
  *
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index d271169..46f5cee 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -251,6 +251,7 @@ struct nsm_handle *nsm_find(const struct sockaddr *sap, const size_t salen,
 void		  nsm_release(struct nsm_handle *nsm);
 int		  nsm_monitor(struct nlm_host *host);
 int		  nsm_unmonitor(struct nlm_host *host);
+struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info);
 
 /*
  * This is used in garbage collection and resource reclaim


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 11/14] NSM: Replace IP address as our nlm_reboot lookup key
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (9 preceding siblings ...)
  2008-10-24 18:11   ` [PATCH 10/14] NSM: Add nsm_lookup() function Chuck Lever
@ 2008-10-24 18:11   ` Chuck Lever
  2008-10-24 18:11   ` [PATCH 12/14] NSM: Remove include/linux/lockd/sm_inter.h Chuck Lever
                     ` (2 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:11 UTC (permalink / raw)
  To: linux-nfs

NLM provides file locking services for NFS files.  Part of this
service includes a second protocol, known as NSM, which monitors host
reboots.  NLM uses this service to determine when to release locks or
enter a grace period after a client or server reboots.

The NLM service (lockd in the Linux kernel) contacts its local NSM
service (rpc.statd in Linux user space) via a special protocol to
request a callback when a particular remote peer reboots.  To identify
the remote peer, the NLM service constructs a cookie that it passes in
the request.  The NSM service passes that cookie back to the NLM
service when it is notified that the given remote peer has indeed
rebooted.

Currently on Linux, the cookie is the raw 32-bit IPv4 address of the
remote peer.  To support IPv6 addresses, which are larger, we could
use all 16 bytes of the cookie to represent a full IPv6 address,
although we still can't represent an IPv6 address with a scope ID in
just 16 bytes.

Instead, to avoid the need for future changes to support additional
address types, we'll use a manufactured value for the cookie, and use
that to find the corresponding nsm_handle struct in the kernel during
the notification callback.

This should provide complete support in the kernel's NSM
implementation for IPv6 hosts.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/mon.c |   20 ++++++++++++++++----
 1 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index c38ef20..9fbeca2 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -129,13 +129,25 @@ static struct nsm_handle *nsm_lookup_hostname(const char *hostname,
  * passed to our statd via SM_MON, and returned via NLM_SM_NOTIFY,
  * in the "priv" field of these requests.
  *
- * Linux provides the raw IP address of the monitored host,
- * left in network byte order.
+ * These cookies do not have to last across reboots, but they must
+ * be unique for each nsm_handle.  Uniqueness is guaranteed by
+ * using the memory address of the handle data structure.
+ * 
+ * The cookies are exposed only to local user space via loopback.
+ * They do not appear on the physical network.  If we want greater
+ * security, we could add more bits (say, by appending jiffies)
+ * then perform a one-way hash on the address.
+ *
+ * For safety, the cookie returned via NLM_SM_NOTIFY is treated as
+ * an opaque -- the address is not used directly to find its
+ * associated handle.  This also means it would be simple to change
+ * the cookie generator again at some later point without having to
+ * mess with the nsm_handle lookup code.
  */
 static void nsm_init_private(struct nsm_handle *nsm)
 {
-	__be32 *p = (__be32 *)&nsm->sm_priv.data;
-	*p = nsm_addr_in(nsm)->sin_addr.s_addr;
+	__be64 *p = (__be64 *)&nsm->sm_priv.data;
+	*p = (unsigned long)nsm;
 }
 
 /**


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 12/14] NSM: Remove include/linux/lockd/sm_inter.h
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (10 preceding siblings ...)
  2008-10-24 18:11   ` [PATCH 11/14] NSM: Replace IP address as our nlm_reboot lookup key Chuck Lever
@ 2008-10-24 18:11   ` Chuck Lever
  2008-10-24 18:11   ` [PATCH 13/14] NLM: Remove "create" argument from nsm_find() Chuck Lever
  2008-10-24 18:11   ` [PATCH 14/14] NSM: Use same helpers in nsm_get_handle() and nsm_lookup_rebooted() Chuck Lever
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:11 UTC (permalink / raw)
  To: linux-nfs

Clean up: The include/linux/lockd/sm_inter.h header has a single item in it
now.  Move that item to include/linux/lockd/xdr.h, and remove sm_inter.h.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/clntproc.c            |    1 -
 fs/lockd/host.c                |    1 -
 fs/lockd/mon.c                 |    2 --
 fs/lockd/svc.c                 |    1 -
 fs/lockd/svc4proc.c            |    2 --
 fs/lockd/svcproc.c             |    2 --
 fs/lockd/svcsubs.c             |    1 -
 fs/lockd/xdr.c                 |    1 -
 fs/lockd/xdr4.c                |    1 -
 include/linux/lockd/sm_inter.h |   14 --------------
 include/linux/lockd/xdr.h      |    1 +
 11 files changed, 1 insertions(+), 26 deletions(-)
 delete mode 100644 include/linux/lockd/sm_inter.h

diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 31668b6..366099b 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -16,7 +16,6 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/lockd.h>
-#include <linux/lockd/sm_inter.h>
 
 #define NLMDBG_FACILITY		NLMDBG_CLIENT
 #define NLMCLNT_GRACE_WAIT	(5*HZ)
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 1ecec4f..181cb26 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -15,7 +15,6 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/lockd.h>
-#include <linux/lockd/sm_inter.h>
 #include <linux/mutex.h>
 
 #include <net/ipv6.h>
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 9fbeca2..78bc36c 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -13,8 +13,6 @@
 #include <linux/sunrpc/xprtsock.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/lockd.h>
-#include <linux/lockd/sm_inter.h>
-
 
 #define NLMDBG_FACILITY		NLMDBG_MONITOR
 
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index c631a83..50de426 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -35,7 +35,6 @@
 #include <linux/sunrpc/svcsock.h>
 #include <net/ip.h>
 #include <linux/lockd/lockd.h>
-#include <linux/lockd/sm_inter.h>
 #include <linux/nfs.h>
 
 #define NLMDBG_FACILITY		NLMDBG_SVC
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index bb79a53..1725037 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -16,8 +16,6 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
-#include <linux/lockd/sm_inter.h>
-
 
 #define NLMDBG_FACILITY		NLMDBG_CLIENT
 
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index e44310c..3688e55 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -16,8 +16,6 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
-#include <linux/lockd/sm_inter.h>
-
 
 #define NLMDBG_FACILITY		NLMDBG_CLIENT
 
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index 34c2766..9e4d6aa 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -17,7 +17,6 @@
 #include <linux/nfsd/export.h>
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
-#include <linux/lockd/sm_inter.h>
 #include <linux/module.h>
 #include <linux/mount.h>
 
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index 4cc7d01..0336f2b 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -16,7 +16,6 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/stats.h>
 #include <linux/lockd/lockd.h>
-#include <linux/lockd/sm_inter.h>
 
 #define NLMDBG_FACILITY		NLMDBG_XDR
 
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index 61d1714..e1d5286 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -17,7 +17,6 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/stats.h>
 #include <linux/lockd/lockd.h>
-#include <linux/lockd/sm_inter.h>
 
 #define NLMDBG_FACILITY		NLMDBG_XDR
 
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
deleted file mode 100644
index 7f22d6f..0000000
--- a/include/linux/lockd/sm_inter.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * linux/include/linux/lockd/sm_inter.h
- *
- * Declarations for the kernel statd client.
- *
- * Copyright (C) 1996, Olaf Kirch <okir-pn4DOG8n3UYbFoVRYvo4fw@public.gmane.org>
- */
-
-#ifndef LINUX_LOCKD_SM_INTER_H
-#define LINUX_LOCKD_SM_INTER_H
-
-#define SM_MAXSTRLEN	1024
-
-#endif /* LINUX_LOCKD_SM_INTER_H */
diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h
index 6338866..7dc5b6c 100644
--- a/include/linux/lockd/xdr.h
+++ b/include/linux/lockd/xdr.h
@@ -13,6 +13,7 @@
 #include <linux/nfs.h>
 #include <linux/sunrpc/xdr.h>
 
+#define SM_MAXSTRLEN		1024
 #define SM_PRIV_SIZE		16
 
 struct nsm_private {


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 13/14] NLM: Remove "create" argument from nsm_find()
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (11 preceding siblings ...)
  2008-10-24 18:11   ` [PATCH 12/14] NSM: Remove include/linux/lockd/sm_inter.h Chuck Lever
@ 2008-10-24 18:11   ` Chuck Lever
       [not found]     ` <20081024181123.23810.65076.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2008-10-24 18:11   ` [PATCH 14/14] NSM: Use same helpers in nsm_get_handle() and nsm_lookup_rebooted() Chuck Lever
  13 siblings, 1 reply; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:11 UTC (permalink / raw)
  To: linux-nfs

Clean up: nsm_find() now has only one caller who always sets the
"create" argument, so it is no longer needed.  Since nsm_find() now
has a more specific function, pick a more appropriate name for it.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/host.c             |    4 ++--
 fs/lockd/mon.c              |   12 ++++--------
 include/linux/lockd/lockd.h |    6 +++---
 3 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 181cb26..db66bfb 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -207,8 +207,8 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
 		atomic_inc(&nsm->sm_count);
 	else {
 		host = NULL;
-		nsm = nsm_find(ni->sap, ni->salen,
-				ni->hostname, ni->hostname_len, 1);
+		nsm = nsm_get_handle(ni->sap, ni->salen,
+					ni->hostname, ni->hostname_len);
 		if (!nsm) {
 			dprintk("lockd: nlm_lookup_host failed; "
 				"no nsm handle\n");
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 78bc36c..d564b6f 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -149,17 +149,16 @@ static void nsm_init_private(struct nsm_handle *nsm)
 }
 
 /**
- * nsm_find - Find a cached nsm_handle by name or address
+ * nsm_get_handle - Find a cached nsm_handle by name or address
  * @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
  *
  */
-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_get_handle(const struct sockaddr *sap,
+				  const size_t salen, const char *hostname,
+				  const size_t hostname_len)
 {
 	struct nsm_handle *nsm = NULL;
 	struct nsm_handle *pos;
@@ -197,9 +196,6 @@ retry:
 	}
 	spin_unlock(&nsm_lock);
 
-	if (!create)
-		return NULL;
-
 	nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
 	if (nsm == NULL)
 		return NULL;
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 46f5cee..052078c 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -244,10 +244,10 @@ void		  nlm_host_rebooted(struct nlm_reboot *);
 /*
  * Host monitoring
  */
-struct nsm_handle *nsm_find(const struct sockaddr *sap, const size_t salen,
+struct nsm_handle *nsm_get_handle(const struct sockaddr *sap,
+					const size_t salen,
 					const char *hostname,
-					const size_t hostname_len,
-					const int create);
+					const size_t hostname_len);
 void		  nsm_release(struct nsm_handle *nsm);
 int		  nsm_monitor(struct nlm_host *host);
 int		  nsm_unmonitor(struct nlm_host *host);


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 14/14] NSM: Use same helpers in nsm_get_handle() and nsm_lookup_rebooted()
       [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (12 preceding siblings ...)
  2008-10-24 18:11   ` [PATCH 13/14] NLM: Remove "create" argument from nsm_find() Chuck Lever
@ 2008-10-24 18:11   ` Chuck Lever
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-24 18:11 UTC (permalink / raw)
  To: linux-nfs

One last clean up: refactor the nsm_get_handle() function so it uses
the same lookup helpers as the newly added nsm_reboot_lookup()
function.

This also makes it easier if some day we want to use a more
sophisticated lookup algorithm than a linked list search for finding
nsm_handles.  It's likely that we would use a different data structure
for each of the different lookups (hostname, priv, or IP address) and
now these are already split into different functions.

There is an additional micro-optimization here.  This change moves the
"hostname & nsm_use_hostnames" test out of the list_for_each_entry()
clause in nsm_get_handle(), since it is loop-invariant.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/mon.c |   97 +++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 58 insertions(+), 39 deletions(-)

diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index d564b6f..3180efc 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -122,6 +122,16 @@ static struct nsm_handle *nsm_lookup_hostname(const char *hostname,
 	return NULL;
 }
 
+static struct nsm_handle *nsm_lookup_addr(const struct sockaddr *sap)
+{
+	struct nsm_handle *nsm;
+
+	list_for_each_entry(nsm, &nsm_handles, sm_link)
+		if (nlm_cmp_addr(nsm_addr(nsm), sap))
+			return nsm;
+	return NULL;
+}
+
 /*
  * Construct a unique cookie to identify this nsm_handle.  It is
  * passed to our statd via SM_MON, and returned via NLM_SM_NOTIFY,
@@ -148,6 +158,30 @@ static void nsm_init_private(struct nsm_handle *nsm)
 	*p = (unsigned long)nsm;
 }
 
+static struct nsm_handle *nsm_init_handle(const struct sockaddr *sap,
+					  const size_t salen,
+					  const char *hostname,
+					  const size_t hostname_len)
+{
+	struct nsm_handle *nsm;
+
+	nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
+	if (nsm) {
+		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_init_private(nsm);
+		nlm_display_address((struct sockaddr *)&nsm->sm_addr,
+					nsm->sm_addrbuf,
+					sizeof(nsm->sm_addrbuf));
+		atomic_set(&nsm->sm_count, 1);
+	}
+
+	return nsm;
+}
+
 /**
  * nsm_get_handle - Find a cached nsm_handle by name or address
  * @sap: pointer to socket address of handle to find
@@ -160,8 +194,7 @@ struct nsm_handle *nsm_get_handle(const struct sockaddr *sap,
 				  const size_t salen, const char *hostname,
 				  const size_t hostname_len)
 {
-	struct nsm_handle *nsm = NULL;
-	struct nsm_handle *pos;
+	struct nsm_handle *new, *cached;
 
 	if (!sap)
 		return NULL;
@@ -175,45 +208,31 @@ struct nsm_handle *nsm_get_handle(const struct sockaddr *sap,
 		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);
+	new = NULL;
+	do {
+		spin_lock(&nsm_lock);
 
-	nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
-	if (nsm == NULL)
-		return NULL;
+		if (nsm_use_hostnames && hostname)
+			cached = nsm_lookup_hostname(hostname, hostname_len);
+		else
+			cached = nsm_lookup_addr(sap);
+		if (cached) {
+			atomic_inc(&cached->sm_count);
+			spin_unlock(&nsm_lock);
+			kfree(new);
+			return cached;
+		} else if (new) {
+			list_add(&new->sm_link, &nsm_handles);
+			spin_unlock(&nsm_lock);
+			return new;
+		}
 
-	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_init_private(nsm);
-	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;
+		spin_unlock(&nsm_lock);
+
+		new = nsm_init_handle(sap, salen, hostname, hostname_len);
+	} while (new);
+
+	return NULL;
 }
 
 /**


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 01/14] NLM: Beef up NLM address display function
       [not found]     ` <20081024180954.23810.34150.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2008-10-29 19:25       ` J. Bruce Fields
  2008-10-29 20:05         ` Chuck Lever
  0 siblings, 1 reply; 21+ messages in thread
From: J. Bruce Fields @ 2008-10-29 19:25 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

On Fri, Oct 24, 2008 at 02:09:54PM -0400, Chuck Lever wrote:
> Add support for IPv6 addresses with a scope ID,

I remain a bit confused about scope ID's.  If you tell me they're
needed, I'll believe you.

> and enable calls from outside of fs/lockd/host.c

Some day of course it'd be nice to collect all the basic "display an
ipv6 address" code together in one place!

> diff --git a/fs/lockd/host.c b/fs/lockd/host.c
> index 9fd8889..c7516ae 100644
> --- a/fs/lockd/host.c
> +++ b/fs/lockd/host.c
> @@ -104,29 +104,54 @@ static void nlm_clear_port(struct sockaddr *sap)
>  	}
>  }
>  
> -static void nlm_display_address(const struct sockaddr *sap,
...
> +int nlm_display_address(const struct sockaddr *sap, char *buf,

The return value is never used, even after your other patches.  Do you
have any plans to use it?

--b.

> +			const size_t len)
> +{
>  	switch (sap->sa_family) {
>  	case AF_UNSPEC:
> -		snprintf(buf, len, "unspecified");
> -		break;
> +		snprintf(buf, len, "unspecified address");
> +		return -EAFNOSUPPORT;
>  	case AF_INET:
> -		snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
> -		break;
> +		return nlm_display_ipv4_address(sap, buf, len);
>  	case AF_INET6:
> -		if (ipv6_addr_v4mapped(&sin6->sin6_addr))
> -			snprintf(buf, len, NIPQUAD_FMT,
> -				 NIPQUAD(sin6->sin6_addr.s6_addr32[3]));
> -		else
> -			snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr));
> -		break;
> +		return nlm_display_ipv6_address(sap, buf, len);
>  	default:
>  		snprintf(buf, len, "unsupported address family");
> -		break;
> +		return -EAFNOSUPPORT;
>  	}
>  }

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 03/14] NSM: Support IPv6 version of mon_name
       [not found]     ` <20081024181009.23810.56793.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2008-10-29 20:00       ` J. Bruce Fields
  2008-10-29 20:22         ` Chuck Lever
  0 siblings, 1 reply; 21+ messages in thread
From: J. Bruce Fields @ 2008-10-29 20:00 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

On Fri, Oct 24, 2008 at 02:10:09PM -0400, Chuck Lever wrote:
> When the "nsm_use_hostnames" sysctl is set to zero, the kernel's NSM
> provides a presentation format IP address in the mon_name argument of
> SM_MON upcalls.  This is part of the private interface between Linux's
> rpc.statd and the kernel's lockd implementation.  Linux's rpc.statd
> can then resolve this address with DNS as a sanity check.

Have you checked how rpc.statd actually uses this field?

--b.

> 
> To support IPv6 addresses for the mon_name argument, just point the
> XDR encoder to the nsm_handle's eye-catcher, which already contains a
> presentation format address string.
> 
> Finally, provide some debugging message clean up.
> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> 
>  fs/lockd/mon.c |   43 +++++++++++++++----------------------------
>  1 files changed, 15 insertions(+), 28 deletions(-)
> 
> diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
> index a5c6ec4..1c058b1 100644
> --- a/fs/lockd/mon.c
> +++ b/fs/lockd/mon.c
> @@ -18,8 +18,6 @@
>  
>  #define NLMDBG_FACILITY		NLMDBG_MONITOR
>  
> -#define XDR_ADDRBUF_LEN		(20)
> -
>  static struct rpc_clnt *	nsm_create(void);
>  
>  static struct rpc_program	nsm_program;
> @@ -40,7 +38,14 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
>  {
>  	struct rpc_clnt	*clnt;
>  	int		status;
> -	struct nsm_args	args;
> +	struct nsm_args	args = {
> +		.addr		= nsm_addr_in(nsm)->sin_addr.s_addr,
> +		.prog		= NLM_PROGRAM,
> +		.vers		= 3,
> +		.proc		= NLMPROC_NSM_NOTIFY,
> +		.mon_name	= nsm_use_hostnames ?
> +					nsm->sm_name : nsm->sm_addrbuf,
> +	};
>  	struct rpc_message msg = {
>  		.rpc_argp	= &args,
>  		.rpc_resp	= res,
> @@ -49,24 +54,21 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
>  	clnt = nsm_create();
>  	if (IS_ERR(clnt)) {
>  		status = PTR_ERR(clnt);
> +		dprintk("lockd: failed to create nsm transport, "
> +				"status=%d\n", status);
>  		goto out;
>  	}
>  
> -	memset(&args, 0, sizeof(args));
> -	args.mon_name = nsm->sm_name;
> -	args.addr = nsm_addr_in(nsm)->sin_addr.s_addr;
> -	args.prog = NLM_PROGRAM;
> -	args.vers = 3;
> -	args.proc = NLMPROC_NSM_NOTIFY;
>  	memset(res, 0, sizeof(*res));
>  
>  	msg.rpc_proc = &clnt->cl_procinfo[proc];
>  	status = rpc_call_sync(clnt, &msg, 0);
>  	if (status < 0)
> -		printk(KERN_DEBUG "nsm_mon_unmon: rpc failed, status=%d\n",
> -			status);
> -	else
> +		dprintk("lockd: nsm rpc failed, status=%d\n", status);
> +	else {
>  		status = 0;
> +		dprintk("lockd: monitoring '%s'\n", args.mon_name);
> +	}
>  	rpc_shutdown_client(clnt);
>   out:
>  	return status;
> @@ -253,25 +255,10 @@ static __be32 *xdr_encode_nsm_string(__be32 *p, char *string)
>  
>  /*
>   * "mon_name" specifies the host to be monitored.
> - *
> - * Linux uses a text version of the IP address of the remote
> - * host as the host identifier (the "mon_name" argument).
> - *
> - * Linux statd always looks up the canonical hostname first for
> - * whatever remote hostname it receives, so this works alright.
>   */
>  static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp)
>  {
> -	char	buffer[XDR_ADDRBUF_LEN + 1];
> -	char	*name = argp->mon_name;
> -
> -	if (!nsm_use_hostnames) {
> -		snprintf(buffer, XDR_ADDRBUF_LEN,
> -			 NIPQUAD_FMT, NIPQUAD(argp->addr));
> -		name = buffer;
> -	}
> -
> -	return xdr_encode_nsm_string(p, name);
> +	return xdr_encode_nsm_string(p, argp->mon_name);
>  }
>  
>  /*
> 
> --
> 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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 04/14] NSM: Move NSM-related function and variable declarations to lockd.h
       [not found]     ` <20081024181016.23810.69413.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2008-10-29 20:02       ` J. Bruce Fields
  0 siblings, 0 replies; 21+ messages in thread
From: J. Bruce Fields @ 2008-10-29 20:02 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

On Fri, Oct 24, 2008 at 02:10:17PM -0400, Chuck Lever wrote:
> Clean up: Keep the NSM function declarations together with the
> declarations already in lockd.h, and modernize the documenting
> comments.

Do the kerneldoc comments actually currently get processed?  (E.g. does
'make htmldocs' do anything with them?)  If not, should we fix that?  If
so, do they produce anything useful?

--b.

> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> 
>  fs/lockd/mon.c                 |   18 ++++++++++--------
>  include/linux/lockd/lockd.h    |    4 ++++
>  include/linux/lockd/sm_inter.h |    4 ----
>  3 files changed, 14 insertions(+), 12 deletions(-)
> 
> diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
> index 1c058b1..d48ae14 100644
> --- a/fs/lockd/mon.c
> +++ b/fs/lockd/mon.c
> @@ -159,11 +159,12 @@ void nsm_release(struct nsm_handle *nsm)
>  	}
>  }
>  
> -/*
> - * Set up monitoring of a remote host
> +/**
> + * nsm_monitor - Set up monitoring of a remote host
> + * @host: pointer to nlm_host representing remote peer to monitor
> + *
>   */
> -int
> -nsm_monitor(struct nlm_host *host)
> +int nsm_monitor(struct nlm_host *host)
>  {
>  	struct nsm_handle *nsm = host->h_nsmhandle;
>  	struct nsm_res	res;
> @@ -184,11 +185,12 @@ nsm_monitor(struct nlm_host *host)
>  	return status;
>  }
>  
> -/*
> - * Cease to monitor remote host
> +/**
> + * nsm_unmonitor - Cease to monitor remote host
> + * @host: pointer to nlm_host representing remote peer to stop monitoring
> + *
>   */
> -int
> -nsm_unmonitor(struct nlm_host *host)
> +int nsm_unmonitor(struct nlm_host *host)
>  {
>  	struct nsm_handle *nsm = host->h_nsmhandle;
>  	struct nsm_res	res;
> diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
> index a45be5d..6dc1043 100644
> --- a/include/linux/lockd/lockd.h
> +++ b/include/linux/lockd/lockd.h
> @@ -200,7 +200,9 @@ extern struct svc_procedure	nlmsvc_procedures4[];
>  #endif
>  extern int			nlmsvc_grace_period;
>  extern unsigned long		nlmsvc_timeout;
> +
>  extern int			nsm_use_hostnames;
> +extern int			nsm_local_state;
>  
>  /*
>   * Lockd client functions
> @@ -247,6 +249,8 @@ struct nsm_handle *nsm_find(const struct sockaddr *sap, const size_t salen,
>  					const size_t hostname_len,
>  					const int create);
>  void		  nsm_release(struct nsm_handle *nsm);
> +int		  nsm_monitor(struct nlm_host *host);
> +int		  nsm_unmonitor(struct nlm_host *host);
>  
>  /*
>   * This is used in garbage collection and resource reclaim
> diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
> index 5a5448b..f75d3ea 100644
> --- a/include/linux/lockd/sm_inter.h
> +++ b/include/linux/lockd/sm_inter.h
> @@ -41,8 +41,4 @@ struct nsm_res {
>  	u32		state;
>  };
>  
> -int		nsm_monitor(struct nlm_host *);
> -int		nsm_unmonitor(struct nlm_host *);
> -extern int	nsm_local_state;
> -
>  #endif /* LINUX_LOCKD_SM_INTER_H */
> 
> --
> 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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 01/14] NLM: Beef up NLM address display function
  2008-10-29 19:25       ` J. Bruce Fields
@ 2008-10-29 20:05         ` Chuck Lever
  0 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-29 20:05 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-nfs

On Oct 29, 2008, at 3:25 PM, J. Bruce Fields wrote:
> On Fri, Oct 24, 2008 at 02:09:54PM -0400, Chuck Lever wrote:
>> Add support for IPv6 addresses with a scope ID,
>
> I remain a bit confused about scope ID's.  If you tell me they're
> needed, I'll believe you.

In this case we need to be able to send an IPv6 address to user space  
(in addition to the original use for this code, which was just to  
print debugging information).

To support locking and NSM with link-local addresses (which need an  
interface ID to work) we need to have scope ID support here.

>> and enable calls from outside of fs/lockd/host.c
>
> Some day of course it'd be nice to collect all the basic "display an
> ipv6 address" code together in one place!

There's a storm brewing on netdev to put address printing support into  
the kernel's implementation of vsnprintf (in preference to NIPQUAD and  
NIP6), so this may all go away at some point soon.

>> diff --git a/fs/lockd/host.c b/fs/lockd/host.c
>> index 9fd8889..c7516ae 100644
>> --- a/fs/lockd/host.c
>> +++ b/fs/lockd/host.c
>> @@ -104,29 +104,54 @@ static void nlm_clear_port(struct sockaddr  
>> *sap)
>> 	}
>> }
>>
>> -static void nlm_display_address(const struct sockaddr *sap,
> ...
>> +int nlm_display_address(const struct sockaddr *sap, char *buf,
>
> The return value is never used, even after your other patches.  Do you
> have any plans to use it?

I thought it was used in the NSM code.  I'll review that before  
submitting these again.

> --b.
>
>> +			const size_t len)
>> +{
>> 	switch (sap->sa_family) {
>> 	case AF_UNSPEC:
>> -		snprintf(buf, len, "unspecified");
>> -		break;
>> +		snprintf(buf, len, "unspecified address");
>> +		return -EAFNOSUPPORT;
>> 	case AF_INET:
>> -		snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
>> -		break;
>> +		return nlm_display_ipv4_address(sap, buf, len);
>> 	case AF_INET6:
>> -		if (ipv6_addr_v4mapped(&sin6->sin6_addr))
>> -			snprintf(buf, len, NIPQUAD_FMT,
>> -				 NIPQUAD(sin6->sin6_addr.s6_addr32[3]));
>> -		else
>> -			snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr));
>> -		break;
>> +		return nlm_display_ipv6_address(sap, buf, len);
>> 	default:
>> 		snprintf(buf, len, "unsupported address family");
>> -		break;
>> +		return -EAFNOSUPPORT;
>> 	}
>> }

--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 03/14] NSM: Support IPv6 version of mon_name
  2008-10-29 20:00       ` J. Bruce Fields
@ 2008-10-29 20:22         ` Chuck Lever
  0 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2008-10-29 20:22 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-nfs


On Oct 29, 2008, at 4:00 PM, J. Bruce Fields wrote:

> On Fri, Oct 24, 2008 at 02:10:09PM -0400, Chuck Lever wrote:
>> When the "nsm_use_hostnames" sysctl is set to zero, the kernel's NSM
>> provides a presentation format IP address in the mon_name argument of
>> SM_MON upcalls.  This is part of the private interface between  
>> Linux's
>> rpc.statd and the kernel's lockd implementation.  Linux's rpc.statd
>> can then resolve this address with DNS as a sanity check.
>
> Have you checked how rpc.statd actually uses this field?

The main piece is here:

   utils/statd/monitor.c:sm_mon_1_svc()

This function receives the incoming SM_MON RPC and attempts to sanity  
check the contents of the mon_name argument by performing a DNS lookup.

It appears to use a second DNS lookup to normalize all incoming names  
so that subsequent hostname matches (ie when handling an SM_NOTIFY  
request) have a better change of succeeding.

> --b.
>
>>
>> To support IPv6 addresses for the mon_name argument, just point the
>> XDR encoder to the nsm_handle's eye-catcher, which already contains a
>> presentation format address string.
>>
>> Finally, provide some debugging message clean up.
>>
>> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
>> ---
>>
>> fs/lockd/mon.c |   43 +++++++++++++++----------------------------
>> 1 files changed, 15 insertions(+), 28 deletions(-)
>>
>> diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
>> index a5c6ec4..1c058b1 100644
>> --- a/fs/lockd/mon.c
>> +++ b/fs/lockd/mon.c
>> @@ -18,8 +18,6 @@
>>
>> #define NLMDBG_FACILITY		NLMDBG_MONITOR
>>
>> -#define XDR_ADDRBUF_LEN		(20)
>> -
>> static struct rpc_clnt *	nsm_create(void);
>>
>> static struct rpc_program	nsm_program;
>> @@ -40,7 +38,14 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc,  
>> struct nsm_res *res)
>> {
>> 	struct rpc_clnt	*clnt;
>> 	int		status;
>> -	struct nsm_args	args;
>> +	struct nsm_args	args = {
>> +		.addr		= nsm_addr_in(nsm)->sin_addr.s_addr,
>> +		.prog		= NLM_PROGRAM,
>> +		.vers		= 3,
>> +		.proc		= NLMPROC_NSM_NOTIFY,
>> +		.mon_name	= nsm_use_hostnames ?
>> +					nsm->sm_name : nsm->sm_addrbuf,
>> +	};
>> 	struct rpc_message msg = {
>> 		.rpc_argp	= &args,
>> 		.rpc_resp	= res,
>> @@ -49,24 +54,21 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc,  
>> struct nsm_res *res)
>> 	clnt = nsm_create();
>> 	if (IS_ERR(clnt)) {
>> 		status = PTR_ERR(clnt);
>> +		dprintk("lockd: failed to create nsm transport, "
>> +				"status=%d\n", status);
>> 		goto out;
>> 	}
>>
>> -	memset(&args, 0, sizeof(args));
>> -	args.mon_name = nsm->sm_name;
>> -	args.addr = nsm_addr_in(nsm)->sin_addr.s_addr;
>> -	args.prog = NLM_PROGRAM;
>> -	args.vers = 3;
>> -	args.proc = NLMPROC_NSM_NOTIFY;
>> 	memset(res, 0, sizeof(*res));
>>
>> 	msg.rpc_proc = &clnt->cl_procinfo[proc];
>> 	status = rpc_call_sync(clnt, &msg, 0);
>> 	if (status < 0)
>> -		printk(KERN_DEBUG "nsm_mon_unmon: rpc failed, status=%d\n",
>> -			status);
>> -	else
>> +		dprintk("lockd: nsm rpc failed, status=%d\n", status);
>> +	else {
>> 		status = 0;
>> +		dprintk("lockd: monitoring '%s'\n", args.mon_name);
>> +	}
>> 	rpc_shutdown_client(clnt);
>>  out:
>> 	return status;
>> @@ -253,25 +255,10 @@ static __be32 *xdr_encode_nsm_string(__be32  
>> *p, char *string)
>>
>> /*
>>  * "mon_name" specifies the host to be monitored.
>> - *
>> - * Linux uses a text version of the IP address of the remote
>> - * host as the host identifier (the "mon_name" argument).
>> - *
>> - * Linux statd always looks up the canonical hostname first for
>> - * whatever remote hostname it receives, so this works alright.
>>  */
>> static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp)
>> {
>> -	char	buffer[XDR_ADDRBUF_LEN + 1];
>> -	char	*name = argp->mon_name;
>> -
>> -	if (!nsm_use_hostnames) {
>> -		snprintf(buffer, XDR_ADDRBUF_LEN,
>> -			 NIPQUAD_FMT, NIPQUAD(argp->addr));
>> -		name = buffer;
>> -	}
>> -
>> -	return xdr_encode_nsm_string(p, name);
>> +	return xdr_encode_nsm_string(p, argp->mon_name);
>> }
>>
>> /*
>>
>> --
>> 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

--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 13/14] NLM: Remove "create" argument from nsm_find()
       [not found]     ` <20081024181123.23810.65076.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2008-10-29 20:48       ` J. Bruce Fields
  0 siblings, 0 replies; 21+ messages in thread
From: J. Bruce Fields @ 2008-10-29 20:48 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

On Fri, Oct 24, 2008 at 02:11:23PM -0400, Chuck Lever wrote:
> Clean up: nsm_find() now has only one caller who always sets the

Clearer to say: "now only has one caller, and that caller always
sets...".

> "create" argument, so it is no longer needed.  Since nsm_find() now
> has a more specific function, pick a more appropriate name for it.
...
> -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_get_handle(const struct sockaddr *sap,
> +				  const size_t salen, const char *hostname,
> +				  const size_t hostname_len)
>  {

Maybe "nsm_create_handle" would be even clearer?  (It doesn't just
increment a reference counter.)

--b.

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2008-10-29 20:48 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-24 18:09 [PATCH 00/14] RFC: IPv6 support for kernel NSM Chuck Lever
     [not found] ` <20081024180150.23810.9718.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-10-24 18:09   ` [PATCH 01/14] NLM: Beef up NLM address display function Chuck Lever
     [not found]     ` <20081024180954.23810.34150.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-10-29 19:25       ` J. Bruce Fields
2008-10-29 20:05         ` Chuck Lever
2008-10-24 18:10   ` [PATCH 02/14] NSM: Move nsm_find() to fs/lockd/mon.c Chuck Lever
2008-10-24 18:10   ` [PATCH 03/14] NSM: Support IPv6 version of mon_name Chuck Lever
     [not found]     ` <20081024181009.23810.56793.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-10-29 20:00       ` J. Bruce Fields
2008-10-29 20:22         ` Chuck Lever
2008-10-24 18:10   ` [PATCH 04/14] NSM: Move NSM-related function and variable declarations to lockd.h Chuck Lever
     [not found]     ` <20081024181016.23810.69413.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-10-29 20:02       ` J. Bruce Fields
2008-10-24 18:10   ` [PATCH 05/14] NSM: Move NSM-related XDR data structures to lockd's xdr.h Chuck Lever
2008-10-24 18:10   ` [PATCH 06/14] NSM: Move NSM program and procedure numbers to fs/lockd/mon.c Chuck Lever
2008-10-24 18:10   ` [PATCH 07/14] NSM: Generate "priv" argument when nsm_handle is created Chuck Lever
2008-10-24 18:10   ` [PATCH 08/14] NLM: Change nlm_host_rebooted() to take a single nlm_reboot argument Chuck Lever
2008-10-24 18:10   ` [PATCH 09/14] NLM: Decode "priv" argument of NLM_SM_NOTIFY as an opaque Chuck Lever
2008-10-24 18:11   ` [PATCH 10/14] NSM: Add nsm_lookup() function Chuck Lever
2008-10-24 18:11   ` [PATCH 11/14] NSM: Replace IP address as our nlm_reboot lookup key Chuck Lever
2008-10-24 18:11   ` [PATCH 12/14] NSM: Remove include/linux/lockd/sm_inter.h Chuck Lever
2008-10-24 18:11   ` [PATCH 13/14] NLM: Remove "create" argument from nsm_find() Chuck Lever
     [not found]     ` <20081024181123.23810.65076.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-10-29 20:48       ` J. Bruce Fields
2008-10-24 18:11   ` [PATCH 14/14] NSM: Use same helpers in nsm_get_handle() and nsm_lookup_rebooted() Chuck Lever

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox