mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
NSM: Move nsm_find() to fs/lockd/mon.c
The nsm_find() function sets up fresh nsm_handle entries. This is where we will store the "priv" cookie used to lookup nsm_handles during reboot recovery. The cookie will be constructed when nsm_find() creates a new nsm_handle. As much as possible, I would like to keep everything that handles a "priv" cookie in fs/lockd/mon.c so that all the smarts are in one source file. That organization should make it pretty simple to see how all this works. To me, it makes more sense than the current arrangement to keep nsm_find() with nsm_monitor() and nsm_unmonitor(). So, start reorganizing by moving nsm_find() into fs/lockd/mon.c. The nsm_release() function comes along too, since it shares the nsm_lock global variable. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
parent
03eb1dcbb7
commit
67c6d107a6
3 changed files with 139 additions and 128 deletions
128
fs/lockd/host.c
128
fs/lockd/host.c
|
@ -32,12 +32,6 @@ static int nrhosts;
|
|||
static DEFINE_MUTEX(nlm_host_mutex);
|
||||
|
||||
static void nlm_gc_hosts(void);
|
||||
static struct nsm_handle *nsm_find(const struct sockaddr *sap,
|
||||
const size_t salen,
|
||||
const char *hostname,
|
||||
const size_t hostname_len,
|
||||
const int create);
|
||||
static void nsm_release(struct nsm_handle *nsm);
|
||||
|
||||
struct nlm_lookup_host_info {
|
||||
const int server; /* search for server|client */
|
||||
|
@ -106,43 +100,6 @@ static void nlm_clear_port(struct sockaddr *sap)
|
|||
}
|
||||
}
|
||||
|
||||
static void nlm_display_ipv4_address(const struct sockaddr *sap, char *buf,
|
||||
const size_t len)
|
||||
{
|
||||
const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
|
||||
snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
|
||||
}
|
||||
|
||||
static void nlm_display_ipv6_address(const struct sockaddr *sap, char *buf,
|
||||
const size_t len)
|
||||
{
|
||||
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
|
||||
|
||||
if (ipv6_addr_v4mapped(&sin6->sin6_addr))
|
||||
snprintf(buf, len, "%pI4", &sin6->sin6_addr.s6_addr32[3]);
|
||||
else if (sin6->sin6_scope_id != 0)
|
||||
snprintf(buf, len, "%pI6%%%u", &sin6->sin6_addr,
|
||||
sin6->sin6_scope_id);
|
||||
else
|
||||
snprintf(buf, len, "%pI6", &sin6->sin6_addr);
|
||||
}
|
||||
|
||||
static void nlm_display_address(const struct sockaddr *sap,
|
||||
char *buf, const size_t len)
|
||||
{
|
||||
switch (sap->sa_family) {
|
||||
case AF_INET:
|
||||
nlm_display_ipv4_address(sap, buf, len);
|
||||
break;
|
||||
case AF_INET6:
|
||||
nlm_display_ipv6_address(sap, buf, len);
|
||||
break;
|
||||
default:
|
||||
snprintf(buf, len, "unsupported address family");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Common host lookup routine for server & client
|
||||
*/
|
||||
|
@ -635,88 +592,3 @@ nlm_gc_hosts(void)
|
|||
|
||||
next_gc = jiffies + NLM_HOST_COLLECT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Manage NSM handles
|
||||
*/
|
||||
static LIST_HEAD(nsm_handles);
|
||||
static DEFINE_SPINLOCK(nsm_lock);
|
||||
|
||||
static 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 = NULL;
|
||||
struct nsm_handle *pos;
|
||||
|
||||
if (!sap)
|
||||
return NULL;
|
||||
|
||||
if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
|
||||
if (printk_ratelimit()) {
|
||||
printk(KERN_WARNING "Invalid hostname \"%.*s\" "
|
||||
"in NFS lock request\n",
|
||||
(int)hostname_len, hostname);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retry:
|
||||
spin_lock(&nsm_lock);
|
||||
list_for_each_entry(pos, &nsm_handles, sm_link) {
|
||||
|
||||
if (hostname && nsm_use_hostnames) {
|
||||
if (strlen(pos->sm_name) != hostname_len
|
||||
|| memcmp(pos->sm_name, hostname, hostname_len))
|
||||
continue;
|
||||
} else if (!nlm_cmp_addr(nsm_addr(pos), sap))
|
||||
continue;
|
||||
atomic_inc(&pos->sm_count);
|
||||
kfree(nsm);
|
||||
nsm = pos;
|
||||
goto found;
|
||||
}
|
||||
if (nsm) {
|
||||
list_add(&nsm->sm_link, &nsm_handles);
|
||||
goto found;
|
||||
}
|
||||
spin_unlock(&nsm_lock);
|
||||
|
||||
if (!create)
|
||||
return NULL;
|
||||
|
||||
nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
|
||||
if (nsm == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy(nsm_addr(nsm), sap, salen);
|
||||
nsm->sm_addrlen = salen;
|
||||
nsm->sm_name = (char *) (nsm + 1);
|
||||
memcpy(nsm->sm_name, hostname, hostname_len);
|
||||
nsm->sm_name[hostname_len] = '\0';
|
||||
nlm_display_address((struct sockaddr *)&nsm->sm_addr,
|
||||
nsm->sm_addrbuf, sizeof(nsm->sm_addrbuf));
|
||||
atomic_set(&nsm->sm_count, 1);
|
||||
goto retry;
|
||||
|
||||
found:
|
||||
spin_unlock(&nsm_lock);
|
||||
return nsm;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release an NSM handle
|
||||
*/
|
||||
static void nsm_release(struct nsm_handle *nsm)
|
||||
{
|
||||
if (!nsm)
|
||||
return;
|
||||
if (atomic_dec_and_lock(&nsm->sm_count, &nsm_lock)) {
|
||||
list_del(&nsm->sm_link);
|
||||
spin_unlock(&nsm_lock);
|
||||
kfree(nsm);
|
||||
}
|
||||
}
|
||||
|
|
133
fs/lockd/mon.c
133
fs/lockd/mon.c
|
@ -47,12 +47,51 @@ struct nsm_res {
|
|||
static struct rpc_clnt * nsm_create(void);
|
||||
|
||||
static struct rpc_program nsm_program;
|
||||
static LIST_HEAD(nsm_handles);
|
||||
static DEFINE_SPINLOCK(nsm_lock);
|
||||
|
||||
/*
|
||||
* Local NSM state
|
||||
*/
|
||||
int nsm_local_state;
|
||||
|
||||
static void nsm_display_ipv4_address(const struct sockaddr *sap, char *buf,
|
||||
const size_t len)
|
||||
{
|
||||
const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
|
||||
snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
|
||||
}
|
||||
|
||||
static void nsm_display_ipv6_address(const struct sockaddr *sap, char *buf,
|
||||
const size_t len)
|
||||
{
|
||||
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
|
||||
|
||||
if (ipv6_addr_v4mapped(&sin6->sin6_addr))
|
||||
snprintf(buf, len, "%pI4", &sin6->sin6_addr.s6_addr32[3]);
|
||||
else if (sin6->sin6_scope_id != 0)
|
||||
snprintf(buf, len, "%pI6%%%u", &sin6->sin6_addr,
|
||||
sin6->sin6_scope_id);
|
||||
else
|
||||
snprintf(buf, len, "%pI6", &sin6->sin6_addr);
|
||||
}
|
||||
|
||||
static void nsm_display_address(const struct sockaddr *sap,
|
||||
char *buf, const size_t len)
|
||||
{
|
||||
switch (sap->sa_family) {
|
||||
case AF_INET:
|
||||
nsm_display_ipv4_address(sap, buf, len);
|
||||
break;
|
||||
case AF_INET6:
|
||||
nsm_display_ipv6_address(sap, buf, len);
|
||||
break;
|
||||
default:
|
||||
snprintf(buf, len, "unsupported address family");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Common procedure for NSMPROC_MON/NSMPROC_UNMON calls
|
||||
*/
|
||||
|
@ -162,6 +201,100 @@ void nsm_unmonitor(const struct nlm_host *host)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nsm_find - Find or create a cached nsm_handle
|
||||
* @sap: pointer to socket address of handle to find
|
||||
* @salen: length of socket address
|
||||
* @hostname: pointer to C string containing hostname to find
|
||||
* @hostname_len: length of C string
|
||||
* @create: one means create new handle if not found in cache
|
||||
*
|
||||
* Behavior is modulated by the global nsm_use_hostnames variable
|
||||
* and by the @create argument.
|
||||
*
|
||||
* Returns a cached nsm_handle after bumping its ref count, or if
|
||||
* @create is set, returns a fresh nsm_handle if a handle that
|
||||
* matches @sap and/or @hostname cannot be found in the handle cache.
|
||||
* Returns NULL if an error occurs.
|
||||
*/
|
||||
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 = NULL;
|
||||
struct nsm_handle *pos;
|
||||
|
||||
if (!sap)
|
||||
return NULL;
|
||||
|
||||
if (hostname && memchr(hostname, '/', hostname_len) != NULL) {
|
||||
if (printk_ratelimit()) {
|
||||
printk(KERN_WARNING "Invalid hostname \"%.*s\" "
|
||||
"in NFS lock request\n",
|
||||
(int)hostname_len, hostname);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retry:
|
||||
spin_lock(&nsm_lock);
|
||||
list_for_each_entry(pos, &nsm_handles, sm_link) {
|
||||
|
||||
if (hostname && nsm_use_hostnames) {
|
||||
if (strlen(pos->sm_name) != hostname_len
|
||||
|| memcmp(pos->sm_name, hostname, hostname_len))
|
||||
continue;
|
||||
} else if (!nlm_cmp_addr(nsm_addr(pos), sap))
|
||||
continue;
|
||||
atomic_inc(&pos->sm_count);
|
||||
kfree(nsm);
|
||||
nsm = pos;
|
||||
goto found;
|
||||
}
|
||||
if (nsm) {
|
||||
list_add(&nsm->sm_link, &nsm_handles);
|
||||
goto found;
|
||||
}
|
||||
spin_unlock(&nsm_lock);
|
||||
|
||||
if (!create)
|
||||
return NULL;
|
||||
|
||||
nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL);
|
||||
if (nsm == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy(nsm_addr(nsm), sap, salen);
|
||||
nsm->sm_addrlen = salen;
|
||||
nsm->sm_name = (char *) (nsm + 1);
|
||||
memcpy(nsm->sm_name, hostname, hostname_len);
|
||||
nsm->sm_name[hostname_len] = '\0';
|
||||
nsm_display_address((struct sockaddr *)&nsm->sm_addr,
|
||||
nsm->sm_addrbuf, sizeof(nsm->sm_addrbuf));
|
||||
atomic_set(&nsm->sm_count, 1);
|
||||
goto retry;
|
||||
|
||||
found:
|
||||
spin_unlock(&nsm_lock);
|
||||
return nsm;
|
||||
}
|
||||
|
||||
/**
|
||||
* nsm_release - Release an NSM handle
|
||||
* @nsm: pointer to handle to be released
|
||||
*
|
||||
*/
|
||||
void nsm_release(struct nsm_handle *nsm)
|
||||
{
|
||||
if (!nsm)
|
||||
return;
|
||||
if (atomic_dec_and_lock(&nsm->sm_count, &nsm_lock)) {
|
||||
list_del(&nsm->sm_link);
|
||||
spin_unlock(&nsm_lock);
|
||||
kfree(nsm);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create NSM client for the local host
|
||||
*/
|
||||
|
|
|
@ -247,6 +247,12 @@ extern void nlm_host_rebooted(const struct sockaddr_in *, const char *,
|
|||
int nsm_monitor(const struct nlm_host *host);
|
||||
void nsm_unmonitor(const struct nlm_host *host);
|
||||
|
||||
struct nsm_handle *nsm_find(const struct sockaddr *sap, const size_t salen,
|
||||
const char *hostname,
|
||||
const size_t hostname_len,
|
||||
const int create);
|
||||
void nsm_release(struct nsm_handle *nsm);
|
||||
|
||||
/*
|
||||
* This is used in garbage collection and resource reclaim
|
||||
* A return value != 0 means destroy the lock/block/share
|
||||
|
|
Loading…
Reference in a new issue