summaryrefslogtreecommitdiffstats
path: root/fs/lockd
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2018-01-23 19:39:04 -0500
committerTrond Myklebust <trondmy@gmail.com>2018-01-24 17:33:57 -0500
commit535cb8f3193f2976f39371810dcad64ae2650771 (patch)
treedd7ece1d3b2cf6b5475e4e9120d43bced6d46224 /fs/lockd
parent8f39fce84a6765b62cbc30fd9c3fdaa5bdf46ded (diff)
downloadlinux-535cb8f3193f2976f39371810dcad64ae2650771.tar.gz
linux-535cb8f3193f2976f39371810dcad64ae2650771.tar.bz2
linux-535cb8f3193f2976f39371810dcad64ae2650771.zip
lockd: Fix server refcounting
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>
Diffstat (limited to 'fs/lockd')
-rw-r--r--fs/lockd/host.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 7d6ab72bbe65..d35cd6be0675 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -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) {