On Fri, Dec 05, 2008 at 07:03:46PM -0500, Chuck Lever wrote: > Introduce a new API to fs/lockd/mon.c that allows nlm_host_rebooted() > to lookup up nsm_handles via the contents of an nlm_reboot struct. > > The new function is equivalent to calling nsm_find() with @create set > to zero, but it takes a struct nlm_reboot instead of separate > arguments. For next time: would prefer this combined with the following patch (on the try-to-introduce-new-code-with-its-users principal), but OK for now; applied.--b. > > Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> > --- > > fs/lockd/mon.c | 64 +++++++++++++++++++++++++++++++++++++++++++ > include/linux/lockd/lockd.h | 1 + > 2 files changed, 65 insertions(+), 0 deletions(-) > > diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c > index e0a799d..65fb904 100644 > --- a/fs/lockd/mon.c > +++ b/fs/lockd/mon.c > @@ -202,6 +202,29 @@ void nsm_unmonitor(const struct nlm_host *host) > } > } > > +static struct nsm_handle *nsm_lookup_hostname(const char *hostname, > + const size_t len) > +{ > + struct nsm_handle *nsm; > + > + list_for_each_entry(nsm, &nsm_handles, sm_link) > + if (strlen(nsm->sm_name) == len && > + memcmp(nsm->sm_name, hostname, len) == 0) > + return nsm; > + return NULL; > +} > + > +static struct nsm_handle *nsm_lookup_priv(const struct nsm_private *priv) > +{ > + struct nsm_handle *nsm; > + > + list_for_each_entry(nsm, &nsm_handles, sm_link) > + if (memcmp(nsm->sm_priv.data, priv->data, > + sizeof(priv->data)) == 0) > + return nsm; > + return NULL; > +} > + > /* > * Construct a unique cookie to match this nsm_handle to this monitored > * host. It is passed to the local rpc.statd via NSMPROC_MON, and > @@ -298,6 +321,47 @@ retry: > } > > /** > + * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle > + * @info: pointer to NLMPROC_SM_NOTIFY arguments > + * > + * Returns a matching nsm_handle if found in the nsm cache; the returned > + * nsm_handle's reference count is bumped and sm_monitored is cleared. > + * Otherwise returns NULL if some error occurred. > + */ > +struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info) > +{ > + struct nsm_handle *cached; > + > + spin_lock(&nsm_lock); > + > + if (nsm_use_hostnames && info->mon != NULL) > + cached = nsm_lookup_hostname(info->mon, info->len); > + else > + cached = nsm_lookup_priv(&info->priv); > + > + if (unlikely(cached == NULL)) { > + spin_unlock(&nsm_lock); > + dprintk("lockd: never saw rebooted peer '%.*s' before\n", > + info->len, info->mon); > + return cached; > + } > + > + atomic_inc(&cached->sm_count); > + spin_unlock(&nsm_lock); > + > + /* > + * During subsequent lock activity, force a fresh > + * notification to be set up for this host. > + */ > + cached->sm_monitored = 0; > + > + dprintk("lockd: host %s (%s) rebooted, cnt %d\n", > + cached->sm_name, cached->sm_addrbuf, > + atomic_read(&cached->sm_count)); > + return cached; > +} > + > +/** > * nsm_release - Release an NSM handle > * @nsm: pointer to handle to be released > * > diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h > index 2a3533e..5e3ad92 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, > const char *hostname, > const size_t hostname_len, > const int create); > +struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info); > void nsm_release(struct nsm_handle *nsm); > > /* > -- 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