aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlaf Kirch <okir@suse.de>2006-10-04 02:16:01 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 07:55:17 -0700
commitabd1f50094cad9dff6d68ada98b495549f52fc30 (patch)
treedd738067aa90af1cb4613a7c711ee426ff5f8ae9
parent350fce8dbf43f7d441b77366851c9ce3cd28d6dc (diff)
[PATCH] knfsd: lockd: optionally use hostnames for identifying peers
This patch adds the nsm_use_hostnames sysctl and module param. If set, lockd will use the client's name (as given in the NLM arguments) to find the NSM handle. This makes recovery work when the NFS peer is multi-homed, and the reboot notification arrives from a different IP than the original lock calls. Signed-off-by: Olaf Kirch <okir@suse.de> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/lockd/host.c6
-rw-r--r--fs/lockd/mon.c12
-rw-r--r--fs/lockd/svc.c10
-rw-r--r--include/linux/lockd/lockd.h1
-rw-r--r--include/linux/lockd/sm_inter.h2
5 files changed, 27 insertions, 4 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 1bf384307d1..a1423c66df0 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -462,7 +462,11 @@ __nsm_find(const struct sockaddr_in *sin,
list_for_each(pos, &nsm_handles) {
nsm = list_entry(pos, struct nsm_handle, sm_link);
- if (!nlm_cmp_addr(&nsm->sm_addr, sin))
+ if (hostname && nsm_use_hostnames) {
+ if (strlen(nsm->sm_name) != hostname_len
+ || memcmp(nsm->sm_name, hostname, hostname_len))
+ continue;
+ } else if (!nlm_cmp_addr(&nsm->sm_addr, sin))
continue;
atomic_inc(&nsm->sm_count);
goto out;
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 626b6c116a6..709cf7c8054 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -47,6 +47,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
}
memset(&args, 0, sizeof(args));
+ args.mon_name = nsm->sm_name;
args.addr = nsm->sm_addr.sin_addr.s_addr;
args.prog = NLM_PROGRAM;
args.vers = 3;
@@ -150,7 +151,7 @@ nsm_create(void)
static u32 *
xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
{
- char buffer[20];
+ char buffer[20], *name;
/*
* Use the dotted-quad IP address of the remote host as
@@ -158,8 +159,13 @@ xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
* hostname first for whatever remote hostname it receives,
* so this works alright.
*/
- sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
- if (!(p = xdr_encode_string(p, buffer))
+ if (nsm_use_hostnames) {
+ name = argp->mon_name;
+ } else {
+ sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
+ name = buffer;
+ }
+ if (!(p = xdr_encode_string(p, name))
|| !(p = xdr_encode_string(p, utsname()->nodename)))
return ERR_PTR(-EIO);
*p++ = htonl(argp->prog);
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 3cc369e5693..a3b7602cd38 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -61,6 +61,7 @@ static DECLARE_WAIT_QUEUE_HEAD(lockd_exit);
static unsigned long nlm_grace_period;
static unsigned long nlm_timeout = LOCKD_DFLT_TIMEO;
static int nlm_udpport, nlm_tcpport;
+int nsm_use_hostnames = 0;
/*
* Constants needed for the sysctl interface.
@@ -395,6 +396,14 @@ static ctl_table nlm_sysctls[] = {
.extra1 = (int *) &nlm_port_min,
.extra2 = (int *) &nlm_port_max,
},
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "nsm_use_hostnames",
+ .data = &nsm_use_hostnames,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
{ .ctl_name = 0 }
};
@@ -483,6 +492,7 @@ module_param_call(nlm_udpport, param_set_port, param_get_int,
&nlm_udpport, 0644);
module_param_call(nlm_tcpport, param_set_port, param_get_int,
&nlm_tcpport, 0644);
+module_param(nsm_use_hostnames, bool, 0644);
/*
* Initialising and terminating the module.
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 1fcf936d75b..7be7aeaeee5 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -142,6 +142,7 @@ extern struct svc_procedure nlmsvc_procedures4[];
#endif
extern int nlmsvc_grace_period;
extern unsigned long nlmsvc_timeout;
+extern int nsm_use_hostnames;
/*
* Lockd client functions
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index d93b074668c..daef509bb9b 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -28,6 +28,8 @@ struct nsm_args {
u32 prog; /* RPC callback info */
u32 vers;
u32 proc;
+
+ char * mon_name;
};
/*