* [PATCH 0/5] recent patches conflict with Harvey's printf formatters
@ 2008-12-29 22:20 Chuck Lever
[not found] ` <20081229221603.28005.42498.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
0 siblings, 1 reply; 7+ messages in thread
From: Chuck Lever @ 2008-12-29 22:20 UTC (permalink / raw)
To: bfields; +Cc: linux-nfs
Hi Bruce-
I pulled from Linus's tree today, and found that Harvey's IP address print
formatters have already been merged. I had conflicts with some of the NSM
IPv6 patches I've already sent you that use the old NIP macros.
Here are the conflicting patches, updated to use Harvey's new formatters.
You may have already done some of this work to merge your NFSD tree into
linux-next, but I did update at least one patch description.
I have already updated the NFSD patches that are still pending, so you'll
get those changes when I resend that series.
---
Chuck Lever (5):
NSM: Move nsm_find() to fs/lockd/mon.c
NSM: Support IPv6 version of mon_name
NLM: Add helper to handle IPv4 addresses
NLM: Support IPv6 scope IDs in nlm_display_address()
NLM: Remove AF_UNSPEC arm in nlm_display_address()
fs/lockd/clntproc.c | 6 -
fs/lockd/host.c | 121 ------------
fs/lockd/mon.c | 411 +++++++++++++++++++++++++++++-----------
include/linux/lockd/lockd.h | 25 ++
include/linux/lockd/sm_inter.h | 31 ---
5 files changed, 322 insertions(+), 272 deletions(-)
--
Chuck Lever <chuck.lever@oracle.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/5] NLM: Remove AF_UNSPEC arm in nlm_display_address()
[not found] ` <20081229221603.28005.42498.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2008-12-29 22:20 ` Chuck Lever
2008-12-29 22:20 ` [PATCH 2/5] NLM: Support IPv6 scope IDs " Chuck Lever
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2008-12-29 22:20 UTC (permalink / raw)
To: bfields; +Cc: linux-nfs
AF_UNSPEC support is no longer needed in nlm_display_address() now
that a presentation address is no longer generated for the h_srcaddr
field.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/lockd/host.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 33bf67a..beb5da8 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -112,9 +112,6 @@ static void nlm_display_address(const struct sockaddr *sap,
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
switch (sap->sa_family) {
- case AF_UNSPEC:
- snprintf(buf, len, "unspecified");
- break;
case AF_INET:
snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
break;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/5] NLM: Support IPv6 scope IDs in nlm_display_address()
[not found] ` <20081229221603.28005.42498.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-12-29 22:20 ` [PATCH 1/5] NLM: Remove AF_UNSPEC arm in nlm_display_address() Chuck Lever
@ 2008-12-29 22:20 ` Chuck Lever
2008-12-29 22:20 ` [PATCH 3/5] NLM: Add helper to handle IPv4 addresses Chuck Lever
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2008-12-29 22:20 UTC (permalink / raw)
To: bfields; +Cc: linux-nfs
Scope ID support is needed since the kernel's NSM implementation is
about to use these displayed addresses as a mon_name in some cases.
When nsm_use_hostnames is zero, without scope ID support NSM will fail
to handle peers that contact us via a link-local address. Link-local
addresses do not work without an interface ID, which is stored in the
sockaddr's sin6_scope_id field.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/lockd/host.c | 21 +++++++++++++++------
include/linux/lockd/lockd.h | 10 +++++++++-
2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index beb5da8..012e49a 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -105,22 +105,31 @@ static void nlm_clear_port(struct sockaddr *sap)
}
}
+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, "%pI4", &sin6->sin6_addr.s6_addr32[3]);
+ else if (sin6->sin6_scope_id != 0)
+ snprintf(buf, len, "%pI6%%%u", &sin6->sin6_addr,
+ sin6->sin6_scope_id);
+ else
+ snprintf(buf, len, "%pI6", &sin6->sin6_addr);
+}
+
static void nlm_display_address(const struct sockaddr *sap,
char *buf, const size_t len)
{
const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
- const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
switch (sap->sa_family) {
case AF_INET:
snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
break;
case AF_INET6:
- if (ipv6_addr_v4mapped(&sin6->sin6_addr))
- snprintf(buf, len, "%pI4",
- &sin6->sin6_addr.s6_addr32[3]);
- else
- snprintf(buf, len, "%pI6", &sin6->sin6_addr);
+ nlm_display_ipv6_address(sap, buf, len);
break;
default:
snprintf(buf, len, "unsupported address family");
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index dae22cb..80a0a2c 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -68,6 +68,14 @@ struct nlm_host {
char *h_addrbuf; /* address eyecatcher */
};
+/*
+ * The largest string sm_addrbuf should hold is a full-size IPv6 address
+ * (no "::" anywhere) with a scope ID. The buffer size is computed to
+ * hold eight groups of colon-separated four-hex-digit numbers, a
+ * percent sign, a scope id (at most 32 bits, in decimal), and NUL.
+ */
+#define NSM_ADDRBUF ((8 * 4 + 7) + (1 + 10) + 1)
+
struct nsm_handle {
struct list_head sm_link;
atomic_t sm_count;
@@ -76,7 +84,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[NSM_ADDRBUF];
};
/*
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/5] NLM: Add helper to handle IPv4 addresses
[not found] ` <20081229221603.28005.42498.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-12-29 22:20 ` [PATCH 1/5] NLM: Remove AF_UNSPEC arm in nlm_display_address() Chuck Lever
2008-12-29 22:20 ` [PATCH 2/5] NLM: Support IPv6 scope IDs " Chuck Lever
@ 2008-12-29 22:20 ` Chuck Lever
2008-12-29 22:20 ` [PATCH 4/5] NSM: Support IPv6 version of mon_name Chuck Lever
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2008-12-29 22:20 UTC (permalink / raw)
To: bfields; +Cc: linux-nfs
Clean up: introduce a helper function to generate IPv4 addresses using
the same style as the IPv6 helper function we just added.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/lockd/host.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 012e49a..780918a 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -105,6 +105,13 @@ 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, "%pI4", &sin->sin_addr.s_addr);
+}
+
static void nlm_display_ipv6_address(const struct sockaddr *sap, char *buf,
const size_t len)
{
@@ -122,11 +129,9 @@ static void nlm_display_ipv6_address(const struct sockaddr *sap, char *buf,
static void nlm_display_address(const struct sockaddr *sap,
char *buf, const size_t len)
{
- const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
-
switch (sap->sa_family) {
case AF_INET:
- snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
+ nlm_display_ipv4_address(sap, buf, len);
break;
case AF_INET6:
nlm_display_ipv6_address(sap, buf, len);
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/5] NSM: Support IPv6 version of mon_name
[not found] ` <20081229221603.28005.42498.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (2 preceding siblings ...)
2008-12-29 22:20 ` [PATCH 3/5] NLM: Add helper to handle IPv4 addresses Chuck Lever
@ 2008-12-29 22:20 ` Chuck Lever
2008-12-29 22:20 ` [PATCH 5/5] NSM: Move nsm_find() to fs/lockd/mon.c Chuck Lever
2008-12-31 1:43 ` [PATCH 0/5] recent patches conflict with Harvey's printf formatters J. Bruce Fields
5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2008-12-29 22:20 UTC (permalink / raw)
To: bfields; +Cc: linux-nfs
The "mon_name" argument of the NSMPROC_MON and NSMPROC_UNMON upcalls
is a string that contains the hostname or IP address of the remote peer
to be notified when this host has rebooted. The sm-notify command uses
this identifier to contact the peer when we reboot, so it must be
either a well-qualified DNS hostname or a presentation format IP
address string.
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.
Otherwise, the "caller_name" argument from NLM requests is used,
which is usually just the DNS hostname of the peer.
To support IPv6 addresses for the mon_name argument, we use the
nsm_handle's address eye-catcher, which already contains an appropriate
presentation format address string. Using the eye-catcher string
obviates the need to use a large buffer on the stack to form the
presentation address string for the upcall.
This patch also addresses a subtle bug.
An NSMPROC_MON request and the subsequent NSMPROC_UNMON request for the
same peer are required to use the same value for the "mon_name"
argument. Otherwise, rpc.statd's NSMPROC_UNMON processing cannot
locate the database entry for that peer and remove it.
If the setting of nsm_use_hostnames is changed between the time the
kernel sends an NSMPROC_MON request and the time it sends the
NSMPROC_UNMON request for the same peer, the "mon_name" argument for
these two requests may not be the same. This is because the value of
"mon_name" is currently chosen at the moment the call is made based on
the setting of nsm_use_hostnames
To ensure both requests pass identical contents in the "mon_name"
argument, we now select which string to use for the argument in the
nsm_monitor() function. A pointer to this string is saved in the
nsm_handle so it can be used for a subsequent NSMPROC_UNMON upcall.
NB: There are other potential problems, such as how nlm_host_rebooted()
might behave if nsm_use_hostnames were changed while hosts are still
being monitored. This patch does not attempt to address those
problems.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/lockd/mon.c | 27 ++++++++-------------------
include/linux/lockd/lockd.h | 1 +
2 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 497dfea..a606fbb 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;
@@ -42,7 +40,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
.prog = NLM_PROGRAM,
.vers = 3,
.proc = NLMPROC_NSM_NOTIFY,
- .mon_name = nsm->sm_name,
+ .mon_name = nsm->sm_mon_name,
};
struct rpc_message msg = {
.rpc_argp = &args,
@@ -87,6 +85,12 @@ nsm_monitor(struct nlm_host *host)
if (nsm->sm_monitored)
return 0;
+ /*
+ * Choose whether to record the caller_name or IP address of
+ * this peer in the local rpc.statd's database.
+ */
+ nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
+
status = nsm_mon_unmon(nsm, SM_MON, &res);
if (status < 0 || res.status != 0)
@@ -167,25 +171,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,
- "%pI4", &argp->addr);
- name = buffer;
- }
-
- return xdr_encode_nsm_string(p, name);
+ return xdr_encode_nsm_string(p, argp->mon_name);
}
/*
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 54dbb45..d3c7247 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -79,6 +79,7 @@ struct nlm_host {
struct nsm_handle {
struct list_head sm_link;
atomic_t sm_count;
+ char *sm_mon_name;
char *sm_name;
struct sockaddr_storage sm_addr;
size_t sm_addrlen;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/5] NSM: Move nsm_find() to fs/lockd/mon.c
[not found] ` <20081229221603.28005.42498.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (3 preceding siblings ...)
2008-12-29 22:20 ` [PATCH 4/5] NSM: Support IPv6 version of mon_name Chuck Lever
@ 2008-12-29 22:20 ` Chuck Lever
2008-12-31 1:43 ` [PATCH 0/5] recent patches conflict with Harvey's printf formatters J. Bruce Fields
5 siblings, 0 replies; 7+ messages in thread
From: Chuck Lever @ 2008-12-29 22:20 UTC (permalink / raw)
To: bfields; +Cc: linux-nfs
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.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/lockd/host.c | 128 -----------------------------------------
fs/lockd/mon.c | 133 +++++++++++++++++++++++++++++++++++++++++++
include/linux/lockd/lockd.h | 6 ++
3 files changed, 139 insertions(+), 128 deletions(-)
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 1d523c1..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,43 +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, "%pI4", &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, "%pI4", &sin6->sin6_addr.s6_addr32[3]);
- else if (sin6->sin6_scope_id != 0)
- snprintf(buf, len, "%pI6%%%u", &sin6->sin6_addr,
- sin6->sin6_scope_id);
- else
- snprintf(buf, len, "%pI6", &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
*/
@@ -635,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..8e68e79 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -47,12 +47,51 @@ 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, "%pI4", &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, "%pI4", &sin6->sin6_addr.s6_addr32[3]);
+ else if (sin6->sin6_scope_id != 0)
+ snprintf(buf, len, "%pI6%%%u", &sin6->sin6_addr,
+ sin6->sin6_scope_id);
+ else
+ snprintf(buf, len, "%pI6", &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 +201,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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 0/5] recent patches conflict with Harvey's printf formatters
[not found] ` <20081229221603.28005.42498.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (4 preceding siblings ...)
2008-12-29 22:20 ` [PATCH 5/5] NSM: Move nsm_find() to fs/lockd/mon.c Chuck Lever
@ 2008-12-31 1:43 ` J. Bruce Fields
5 siblings, 0 replies; 7+ messages in thread
From: J. Bruce Fields @ 2008-12-31 1:43 UTC (permalink / raw)
To: Chuck Lever; +Cc: linux-nfs
On Mon, Dec 29, 2008 at 05:20:07PM -0500, Chuck Lever wrote:
> Hi Bruce-
>
> I pulled from Linus's tree today, and found that Harvey's IP address print
> formatters have already been merged. I had conflicts with some of the NSM
> IPv6 patches I've already sent you that use the old NIP macros.
>
> Here are the conflicting patches, updated to use Harvey's new formatters.
> You may have already done some of this work to merge your NFSD tree into
> linux-next, but I did update at least one patch description.
Thanks, done. (I rebased my for-2.6.29 branch onto latest linus tip,
merged by hand, then did a diff-of-diffs between my results and yours,
which just caught the one commit message edit.) The result is at
git://linux-nfs.org/~bfields/linux.git for-2.6.29
I expect I'll be more completely back at work Jan. 1 or 2nd, look
through my mailbox for any more stragglers at that point, then send
Linus a pull message by early next week.
--b.
>
> I have already updated the NFSD patches that are still pending, so you'll
> get those changes when I resend that series.
>
> ---
>
> Chuck Lever (5):
> NSM: Move nsm_find() to fs/lockd/mon.c
> NSM: Support IPv6 version of mon_name
> NLM: Add helper to handle IPv4 addresses
> NLM: Support IPv6 scope IDs in nlm_display_address()
> NLM: Remove AF_UNSPEC arm in nlm_display_address()
>
>
> fs/lockd/clntproc.c | 6 -
> fs/lockd/host.c | 121 ------------
> fs/lockd/mon.c | 411 +++++++++++++++++++++++++++++-----------
> include/linux/lockd/lockd.h | 25 ++
> include/linux/lockd/sm_inter.h | 31 ---
> 5 files changed, 322 insertions(+), 272 deletions(-)
>
> --
> Chuck Lever <chuck.lever@oracle.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-12-31 1:43 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-29 22:20 [PATCH 0/5] recent patches conflict with Harvey's printf formatters Chuck Lever
[not found] ` <20081229221603.28005.42498.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2008-12-29 22:20 ` [PATCH 1/5] NLM: Remove AF_UNSPEC arm in nlm_display_address() Chuck Lever
2008-12-29 22:20 ` [PATCH 2/5] NLM: Support IPv6 scope IDs " Chuck Lever
2008-12-29 22:20 ` [PATCH 3/5] NLM: Add helper to handle IPv4 addresses Chuck Lever
2008-12-29 22:20 ` [PATCH 4/5] NSM: Support IPv6 version of mon_name Chuck Lever
2008-12-29 22:20 ` [PATCH 5/5] NSM: Move nsm_find() to fs/lockd/mon.c Chuck Lever
2008-12-31 1:43 ` [PATCH 0/5] recent patches conflict with Harvey's printf formatters J. Bruce Fields
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox