aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlaf Kirch <okir@suse.de>2006-10-04 05:16:01 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:17 -0400
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 1bf384307d15..a1423c66df04 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -462,7 +462,11 @@ __nsm_find(const struct sockaddr_in *sin,
462 list_for_each(pos, &nsm_handles) { 462 list_for_each(pos, &nsm_handles) {
463 nsm = list_entry(pos, struct nsm_handle, sm_link); 463 nsm = list_entry(pos, struct nsm_handle, sm_link);
464 464
465 if (!nlm_cmp_addr(&nsm->sm_addr, sin)) 465 if (hostname && nsm_use_hostnames) {
466 if (strlen(nsm->sm_name) != hostname_len
467 || memcmp(nsm->sm_name, hostname, hostname_len))
468 continue;
469 } else if (!nlm_cmp_addr(&nsm->sm_addr, sin))
466 continue; 470 continue;
467 atomic_inc(&nsm->sm_count); 471 atomic_inc(&nsm->sm_count);
468 goto out; 472 goto out;
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 626b6c116a6d..709cf7c80545 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)
47 } 47 }
48 48
49 memset(&args, 0, sizeof(args)); 49 memset(&args, 0, sizeof(args));
50 args.mon_name = nsm->sm_name;
50 args.addr = nsm->sm_addr.sin_addr.s_addr; 51 args.addr = nsm->sm_addr.sin_addr.s_addr;
51 args.prog = NLM_PROGRAM; 52 args.prog = NLM_PROGRAM;
52 args.vers = 3; 53 args.vers = 3;
@@ -150,7 +151,7 @@ nsm_create(void)
150static u32 * 151static u32 *
151xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp) 152xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
152{ 153{
153 char buffer[20]; 154 char buffer[20], *name;
154 155
155 /* 156 /*
156 * Use the dotted-quad IP address of the remote host as 157 * 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)
158 * hostname first for whatever remote hostname it receives, 159 * hostname first for whatever remote hostname it receives,
159 * so this works alright. 160 * so this works alright.
160 */ 161 */
161 sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr)); 162 if (nsm_use_hostnames) {
162 if (!(p = xdr_encode_string(p, buffer)) 163 name = argp->mon_name;
164 } else {
165 sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
166 name = buffer;
167 }
168 if (!(p = xdr_encode_string(p, name))
163 || !(p = xdr_encode_string(p, utsname()->nodename))) 169 || !(p = xdr_encode_string(p, utsname()->nodename)))
164 return ERR_PTR(-EIO); 170 return ERR_PTR(-EIO);
165 *p++ = htonl(argp->prog); 171 *p++ = htonl(argp->prog);
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 3cc369e5693f..a3b7602cd383 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -61,6 +61,7 @@ static DECLARE_WAIT_QUEUE_HEAD(lockd_exit);
61static unsigned long nlm_grace_period; 61static unsigned long nlm_grace_period;
62static unsigned long nlm_timeout = LOCKD_DFLT_TIMEO; 62static unsigned long nlm_timeout = LOCKD_DFLT_TIMEO;
63static int nlm_udpport, nlm_tcpport; 63static int nlm_udpport, nlm_tcpport;
64int nsm_use_hostnames = 0;
64 65
65/* 66/*
66 * Constants needed for the sysctl interface. 67 * Constants needed for the sysctl interface.
@@ -395,6 +396,14 @@ static ctl_table nlm_sysctls[] = {
395 .extra1 = (int *) &nlm_port_min, 396 .extra1 = (int *) &nlm_port_min,
396 .extra2 = (int *) &nlm_port_max, 397 .extra2 = (int *) &nlm_port_max,
397 }, 398 },
399 {
400 .ctl_name = CTL_UNNUMBERED,
401 .procname = "nsm_use_hostnames",
402 .data = &nsm_use_hostnames,
403 .maxlen = sizeof(int),
404 .mode = 0644,
405 .proc_handler = &proc_dointvec,
406 },
398 { .ctl_name = 0 } 407 { .ctl_name = 0 }
399}; 408};
400 409
@@ -483,6 +492,7 @@ module_param_call(nlm_udpport, param_set_port, param_get_int,
483 &nlm_udpport, 0644); 492 &nlm_udpport, 0644);
484module_param_call(nlm_tcpport, param_set_port, param_get_int, 493module_param_call(nlm_tcpport, param_set_port, param_get_int,
485 &nlm_tcpport, 0644); 494 &nlm_tcpport, 0644);
495module_param(nsm_use_hostnames, bool, 0644);
486 496
487/* 497/*
488 * Initialising and terminating the module. 498 * Initialising and terminating the module.
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 1fcf936d75b9..7be7aeaeee58 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -142,6 +142,7 @@ extern struct svc_procedure nlmsvc_procedures4[];
142#endif 142#endif
143extern int nlmsvc_grace_period; 143extern int nlmsvc_grace_period;
144extern unsigned long nlmsvc_timeout; 144extern unsigned long nlmsvc_timeout;
145extern int nsm_use_hostnames;
145 146
146/* 147/*
147 * Lockd client functions 148 * Lockd client functions
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index d93b074668ce..daef509bb9b3 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -28,6 +28,8 @@ struct nsm_args {
28 u32 prog; /* RPC callback info */ 28 u32 prog; /* RPC callback info */
29 u32 vers; 29 u32 vers;
30 u32 proc; 30 u32 proc;
31
32 char * mon_name;
31}; 33};
32 34
33/* 35/*