[PATCH 14/14] NSM: Use same helpers in nsm_get_handle() and nsm_lookup_rebooted()

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

 



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@xxxxxxxxxx>
---

 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;
 }
 
 /**

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

  Powered by Linux