]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
lockd: Fix server refcounting
authorTrond Myklebust <trondmy@gmail.com>
Wed, 24 Jan 2018 00:39:04 +0000 (19:39 -0500)
committerTrond Myklebust <trondmy@gmail.com>
Wed, 24 Jan 2018 22:33:57 +0000 (17:33 -0500)
The server shouldn't actually delete the struct nlm_host until it hits
the garbage collector. In order to make that work correctly with the
refcount API, we can bump the refcount by one, and then use
refcount_dec_if_one() in the garbage collector.

Signed-off-by: Trond Myklebust <trondmy@gmail.com>
Acked-by: J. Bruce Fields <bfields@fieldses.org>
fs/lockd/host.c

index 7d6ab72bbe65c6b12eb2b742492282d08b4dd49a..d35cd6be067592acd7f2bc8ca50f0dd869e817e5 100644 (file)
@@ -388,6 +388,8 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
        ln->nrhosts++;
        nrhosts++;
 
+       refcount_inc(&host->h_count);
+
        dprintk("lockd: %s created host %s (%s)\n",
                __func__, host->h_name, host->h_addrbuf);
 
@@ -662,8 +664,7 @@ nlm_gc_hosts(struct net *net)
        for_each_host_safe(host, next, chain, nlm_server_hosts) {
                if (net && host->net != net)
                        continue;
-               if (refcount_read(&host->h_count) || host->h_inuse
-                || time_before(jiffies, host->h_expires)) {
+               if (host->h_inuse || time_before(jiffies, host->h_expires)) {
                        dprintk("nlm_gc_hosts skipping %s "
                                "(cnt %d use %d exp %ld net %x)\n",
                                host->h_name, refcount_read(&host->h_count),
@@ -671,7 +672,8 @@ nlm_gc_hosts(struct net *net)
                                host->net->ns.inum);
                        continue;
                }
-               nlm_destroy_host_locked(host);
+               if (refcount_dec_if_one(&host->h_count))
+                       nlm_destroy_host_locked(host);
        }
 
        if (net) {