aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/mon.c64
-rw-r--r--include/linux/lockd/lockd.h1
2 files changed, 65 insertions, 0 deletions
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 4424b0a5a51f..e46903995c99 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -201,6 +201,29 @@ void nsm_unmonitor(const struct nlm_host *host)
201 } 201 }
202} 202}
203 203
204static struct nsm_handle *nsm_lookup_hostname(const char *hostname,
205 const size_t len)
206{
207 struct nsm_handle *nsm;
208
209 list_for_each_entry(nsm, &nsm_handles, sm_link)
210 if (strlen(nsm->sm_name) == len &&
211 memcmp(nsm->sm_name, hostname, len) == 0)
212 return nsm;
213 return NULL;
214}
215
216static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv)
217{
218 struct nsm_handle *nsm;
219
220 list_for_each_entry(nsm, &nsm_handles, sm_link)
221 if (memcmp(nsm->sm_priv.data, priv->data,
222 sizeof(priv->data)) == 0)
223 return nsm;
224 return NULL;
225}
226
204/* 227/*
205 * Construct a unique cookie to match this nsm_handle to this monitored 228 * Construct a unique cookie to match this nsm_handle to this monitored
206 * host. It is passed to the local rpc.statd via NSMPROC_MON, and 229 * host. It is passed to the local rpc.statd via NSMPROC_MON, and
@@ -298,6 +321,47 @@ found:
298} 321}
299 322
300/** 323/**
324 * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle
325 * @info: pointer to NLMPROC_SM_NOTIFY arguments
326 *
327 * Returns a matching nsm_handle if found in the nsm cache; the returned
328 * nsm_handle's reference count is bumped and sm_monitored is cleared.
329 * Otherwise returns NULL if some error occurred.
330 */
331struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
332{
333 struct nsm_handle *cached;
334
335 spin_lock(&nsm_lock);
336
337 if (nsm_use_hostnames && info->mon != NULL)
338 cached = nsm_lookup_hostname(info->mon, info->len);
339 else
340 cached = nsm_lookup_priv(&info->priv);
341
342 if (unlikely(cached == NULL)) {
343 spin_unlock(&nsm_lock);
344 dprintk("lockd: never saw rebooted peer '%.*s' before\n",
345 info->len, info->mon);
346 return cached;
347 }
348
349 atomic_inc(&cached->sm_count);
350 spin_unlock(&nsm_lock);
351
352 /*
353 * During subsequent lock activity, force a fresh
354 * notification to be set up for this host.
355 */
356 cached->sm_monitored = 0;
357
358 dprintk("lockd: host %s (%s) rebooted, cnt %d\n",
359 cached->sm_name, cached->sm_addrbuf,
360 atomic_read(&cached->sm_count));
361 return cached;
362}
363
364/**
301 * nsm_release - Release an NSM handle 365 * nsm_release - Release an NSM handle
302 * @nsm: pointer to handle to be released 366 * @nsm: pointer to handle to be released
303 * 367 *
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 2a3533ea38dd..5e3ad926de89 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -251,6 +251,7 @@ struct nsm_handle *nsm_find(const struct sockaddr *sap, const size_t salen,
251 const char *hostname, 251 const char *hostname,
252 const size_t hostname_len, 252 const size_t hostname_len,
253 const int create); 253 const int create);
254struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info);
254void nsm_release(struct nsm_handle *nsm); 255void nsm_release(struct nsm_handle *nsm);
255 256
256/* 257/*