public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Chuck Lever <chuck.lever@oracle.com>
To: trond.myklebust@netapp.com, bfields@citi.umich.edu
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH 10/16] lockd: Support AF_INET6 when hashing addresses in nlm_lookup_host
Date: Mon, 30 Jun 2008 18:59:26 -0400	[thread overview]
Message-ID: <20080630225925.25407.50917.stgit@ellison.1015granger.net> (raw)
In-Reply-To: <20080630225011.25407.61357.stgit-ewv44WTpT0t9HhUboXbp9zCvJB+x5qRC@public.gmane.org>

Adopt an approach similar to the RPC server's auth cache (from Aurelien
Charbon and Brian Haley).

Note the NLM's existing IPv4 address hash function has the same issue
with correctness on little-endian systems as the original IPv4 auth cache
hash function, so I've replaced it with a hash function similar to the new
auth cache hash function.

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

 fs/lockd/host.c |   49 +++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 43 insertions(+), 6 deletions(-)


diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index cd3f663..b10a6fe 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -21,7 +21,6 @@
 
 #define NLMDBG_FACILITY		NLMDBG_HOSTCACHE
 #define NLM_HOST_NRHASH		32
-#define NLM_ADDRHASH(addr)	(ntohl(addr) & (NLM_HOST_NRHASH-1))
 #define NLM_HOST_REBIND		(60 * HZ)
 #define NLM_HOST_EXPIRE		(300 * HZ)
 #define NLM_HOST_COLLECT	(120 * HZ)
@@ -39,6 +38,48 @@ static struct nsm_handle *	nsm_find(const struct sockaddr_in *sin,
 					 const char *hostname,
 					 unsigned int hostname_len);
 
+/*
+ * Hash function must work well on big- and little-endian platforms
+ */
+static unsigned int __nlm_hash32(const __be32 n)
+{
+	unsigned int hash = (__force u32)n ^ ((__force u32)n >> 16);
+	return hash ^ (hash >> 8);
+}
+
+static unsigned int __nlm_hash_addr4(const struct sockaddr *sap)
+{
+	const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
+	return __nlm_hash32(sin->sin_addr.s_addr);
+}
+
+static unsigned int __nlm_hash_addr6(const struct sockaddr *sap)
+{
+	const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
+	const struct in6_addr addr = sin6->sin6_addr;
+	return __nlm_hash32(addr.s6_addr32[0]) ^
+	       __nlm_hash32(addr.s6_addr32[1]) ^
+	       __nlm_hash32(addr.s6_addr32[2]) ^
+	       __nlm_hash32(addr.s6_addr32[3]);
+}
+
+static unsigned int nlm_hash_address(const struct sockaddr *sap)
+{
+	unsigned int hash;
+
+	switch (sap->sa_family) {
+	case AF_INET:
+		hash = __nlm_hash_addr4(sap);
+		break;
+	case AF_INET6:
+		hash = __nlm_hash_addr6(sap);
+		break;
+	default:
+		hash = 0;
+	}
+	return hash & (NLM_HOST_NRHASH - 1);
+}
+
 static void nlm_clear_port(struct sockaddr *sap)
 {
 	struct sockaddr_in *sin = (struct sockaddr_in *)sap;
@@ -90,16 +131,12 @@ static struct nlm_host *nlm_lookup_host(int server,
 	struct hlist_node *pos;
 	struct nlm_host	*host;
 	struct nsm_handle *nsm = NULL;
-	int		hash;
 
 	dprintk("lockd: nlm_lookup_host(proto=%d, vers=%u,"
 			" my role is %s, hostname=%.*s)\n",
 			proto, version, server? "server" : "client",
 			hostname_len, hostname? hostname : "<none>");
 
-	hash = NLM_ADDRHASH(sin->sin_addr.s_addr);
-
-	/* Lock hash table */
 	mutex_lock(&nlm_host_mutex);
 
 	if (time_after_eq(jiffies, next_gc))
@@ -112,7 +149,7 @@ static struct nlm_host *nlm_lookup_host(int server,
 	 * different NLM rpc_clients into one single nlm_host object.
 	 * This would allow us to have one nlm_host per address.
 	 */
-	chain = &nlm_hosts[hash];
+	chain = &nlm_hosts[nlm_hash_address((struct sockaddr *)sin)];
 	hlist_for_each_entry(host, pos, chain, h_hash) {
 		if (!nlm_cmp_addr(nlm_addr(host), (struct sockaddr *)sin))
 			continue;


  parent reply	other threads:[~2008-06-30 23:00 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-30 22:58 [PATCH 00/16] NLM clean-ups for IPv6 support Chuck Lever
     [not found] ` <20080630225011.25407.61357.stgit-ewv44WTpT0t9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
2008-06-30 22:58   ` [PATCH 01/16] lockd: Pass "struct sockaddr *" to new failover-by-IP function Chuck Lever
     [not found]     ` <20080630225813.25407.29856.stgit-ewv44WTpT0t9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
2008-07-15 20:12       ` J. Bruce Fields
2008-07-15 21:26         ` Chuck Lever
2008-06-30 22:58   ` [PATCH 02/16] lockd: address-family independent printable addresses Chuck Lever
     [not found]     ` <20080630225821.25407.58530.stgit-ewv44WTpT0t9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
2008-07-15 20:25       ` J. Bruce Fields
2008-07-15 21:41         ` Chuck Lever
     [not found]           ` <76bd70e30807151441v7a23ce7ev7575a7706ab7a982-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-07-15 21:48             ` J. Bruce Fields
2008-06-30 22:58   ` [PATCH 03/16] lockd: Specify address family for source address Chuck Lever
2008-06-30 22:58   ` [PATCH 04/16] lockd: Add address family-agnostic helper for zeroing the port number Chuck Lever
2008-06-30 22:58   ` [PATCH 05/16] SUNRPC: Make svc_addr's argument a constant Chuck Lever
2008-06-30 22:58   ` [PATCH 06/16] lockd: Use sockaddr_storage + length for h_addr field Chuck Lever
2008-06-30 22:59   ` [PATCH 07/16] lockd: Use sockaddr_storage for h_saddr field Chuck Lever
2008-06-30 22:59   ` [PATCH 08/16] NSM: Use sockaddr_storage for sm_addr field Chuck Lever
2008-06-30 22:59   ` [PATCH 09/16] lockd: Teach nlm_cmp_addr() to support AF_INET6 addresses Chuck Lever
2008-06-30 22:59   ` Chuck Lever [this message]
2008-06-30 22:59   ` [PATCH 11/16] lockd: Combine __nsm_find() and nsm_find() Chuck Lever
2008-06-30 22:59   ` [PATCH 12/16] lockd: Update nsm_find() to support non-AF_INET addresses Chuck Lever
2008-06-30 22:59   ` [PATCH 13/16] lockd: Support non-AF_INET addresses in nlm_lookup_host() Chuck Lever
2008-06-30 22:59   ` [PATCH 14/16] lockd: Adjust nlmclnt_lookup_host() signature to accomodate non-AF_INET Chuck Lever
2008-06-30 23:00   ` [PATCH 15/16] lockd: Adjust nlmsvc_lookup_host() " Chuck Lever
2008-06-30 23:00   ` [PATCH 16/16] lockd: change nlmclnt_grant() to take a "struct sockaddr *" Chuck Lever

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080630225925.25407.50917.stgit@ellison.1015granger.net \
    --to=chuck.lever@oracle.com \
    --cc=bfields@citi.umich.edu \
    --cc=linux-nfs@vger.kernel.org \
    --cc=trond.myklebust@netapp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox