Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3420a8c4 authored by Chuck Lever's avatar Chuck Lever Committed by J. Bruce Fields
Browse files

NSM: Add nsm_lookup() function



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.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 576df463
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
@@ -201,6 +201,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
@@ -297,6 +320,47 @@ struct nsm_handle *nsm_find(const struct sockaddr *sap, const size_t salen,
	return nsm;
}

/**
 * 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
+1 −0
Original line number Diff line number Diff line
@@ -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);

/*