NSM: Release nsmhandle in nlm_destroy_host
authorChuck Lever <chuck.lever@oracle.com>
Thu, 4 Dec 2008 19:21:31 +0000 (14:21 -0500)
committerJ. Bruce Fields <bfields@citi.umich.edu>
Tue, 6 Jan 2009 16:53:52 +0000 (11:53 -0500)
The nsm_handle's reference count is bumped in nlm_lookup_host().  It
should be decremented in nlm_destroy_host() to make it easier to see
the balance of these two operations.

Move the nsm_release() call to fs/lockd/host.c.

The h_nsmhandle pointer is set in nlm_lookup_host(), and never cleared.
The nlm_destroy_host() function is never called for the same nlm_host
twice, so h_nsmhandle won't ever be NULL when nsm_unmonitor() is
called.

All references to the nlm_host are gone before it is freed.  We can
skip making h_nsmhandle NULL just before the nlm_host is deallocated.

It's also likely we can remove the h_nsmhandle NULL check in
nlmsvc_is_client() as well, but we can do that later when rearchitect-
ing the nlm_host cache.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
fs/lockd/host.c
fs/lockd/mon.c
include/linux/lockd/lockd.h

index 780918a..1d523c1 100644 (file)
@@ -37,6 +37,7 @@ static struct nsm_handle      *nsm_find(const struct sockaddr *sap,
                                                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 */
@@ -263,10 +264,8 @@ nlm_destroy_host(struct nlm_host *host)
        BUG_ON(!list_empty(&host->h_lockowners));
        BUG_ON(atomic_read(&host->h_count));
 
-       /*
-        * Release NSM handle and unmonitor host.
-        */
        nsm_unmonitor(host);
+       nsm_release(host->h_nsmhandle);
 
        clnt = host->h_rpcclnt;
        if (clnt != NULL)
@@ -711,8 +710,7 @@ found:
 /*
  * Release an NSM handle
  */
-void
-nsm_release(struct nsm_handle *nsm)
+static void nsm_release(struct nsm_handle *nsm)
 {
        if (!nsm)
                return;
index aaaa08e..15fab22 100644 (file)
@@ -117,10 +117,6 @@ nsm_unmonitor(struct nlm_host *host)
        struct nsm_res  res;
        int             status = 0;
 
-       if (nsm == NULL)
-               return 0;
-       host->h_nsmhandle = NULL;
-
        if (atomic_read(&nsm->sm_count) == 1
         && nsm->sm_monitored && !nsm->sm_sticky) {
                dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
@@ -132,7 +128,6 @@ nsm_unmonitor(struct nlm_host *host)
                else
                        nsm->sm_monitored = 0;
        }
-       nsm_release(nsm);
        return status;
 }
 
index f15a4f5..30a6a9c 100644 (file)
@@ -240,7 +240,6 @@ 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