diff options
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/clntlock.c | 51 | ||||
-rw-r--r-- | fs/lockd/mon.c | 8 | ||||
-rw-r--r-- | fs/lockd/svc.c | 42 |
3 files changed, 29 insertions, 72 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index aedc47a264c1..1f3b0fc0d351 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -139,55 +139,6 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) | |||
139 | return 0; | 139 | return 0; |
140 | } | 140 | } |
141 | 141 | ||
142 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
143 | static const struct in6_addr *nlmclnt_map_v4addr(const struct sockaddr *sap, | ||
144 | struct in6_addr *addr_mapped) | ||
145 | { | ||
146 | const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; | ||
147 | |||
148 | switch (sap->sa_family) { | ||
149 | case AF_INET6: | ||
150 | return &((const struct sockaddr_in6 *)sap)->sin6_addr; | ||
151 | case AF_INET: | ||
152 | ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, addr_mapped); | ||
153 | return addr_mapped; | ||
154 | } | ||
155 | |||
156 | return NULL; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * If lockd is using a PF_INET6 listener, all incoming requests appear | ||
161 | * to come from AF_INET6 remotes. The address of AF_INET remotes are | ||
162 | * mapped to AF_INET6 automatically by the network layer. In case the | ||
163 | * user passed an AF_INET server address at mount time, ensure both | ||
164 | * addresses are AF_INET6 before comparing them. | ||
165 | */ | ||
166 | static int nlmclnt_cmp_addr(const struct nlm_host *host, | ||
167 | const struct sockaddr *sap) | ||
168 | { | ||
169 | const struct in6_addr *addr1; | ||
170 | const struct in6_addr *addr2; | ||
171 | struct in6_addr addr1_mapped; | ||
172 | struct in6_addr addr2_mapped; | ||
173 | |||
174 | addr1 = nlmclnt_map_v4addr(nlm_addr(host), &addr1_mapped); | ||
175 | if (likely(addr1 != NULL)) { | ||
176 | addr2 = nlmclnt_map_v4addr(sap, &addr2_mapped); | ||
177 | if (likely(addr2 != NULL)) | ||
178 | return ipv6_addr_equal(addr1, addr2); | ||
179 | } | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | #else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ | ||
184 | static int nlmclnt_cmp_addr(const struct nlm_host *host, | ||
185 | const struct sockaddr *sap) | ||
186 | { | ||
187 | return nlm_cmp_addr(nlm_addr(host), sap); | ||
188 | } | ||
189 | #endif /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ | ||
190 | |||
191 | /* | 142 | /* |
192 | * The server lockd has called us back to tell us the lock was granted | 143 | * The server lockd has called us back to tell us the lock was granted |
193 | */ | 144 | */ |
@@ -215,7 +166,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) | |||
215 | */ | 166 | */ |
216 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) | 167 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) |
217 | continue; | 168 | continue; |
218 | if (!nlmclnt_cmp_addr(block->b_host, addr)) | 169 | if (!nlm_cmp_addr(nlm_addr(block->b_host), addr)) |
219 | continue; | 170 | continue; |
220 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) | 171 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) |
221 | continue; | 172 | continue; |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 5e2c4d5ac827..6d5d4a4169e5 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/sunrpc/svc.h> | 16 | #include <linux/sunrpc/svc.h> |
17 | #include <linux/lockd/lockd.h> | 17 | #include <linux/lockd/lockd.h> |
18 | 18 | ||
19 | #include <asm/unaligned.h> | ||
20 | |||
19 | #define NLMDBG_FACILITY NLMDBG_MONITOR | 21 | #define NLMDBG_FACILITY NLMDBG_MONITOR |
20 | #define NSM_PROGRAM 100024 | 22 | #define NSM_PROGRAM 100024 |
21 | #define NSM_VERSION 1 | 23 | #define NSM_VERSION 1 |
@@ -274,10 +276,12 @@ static void nsm_init_private(struct nsm_handle *nsm) | |||
274 | { | 276 | { |
275 | u64 *p = (u64 *)&nsm->sm_priv.data; | 277 | u64 *p = (u64 *)&nsm->sm_priv.data; |
276 | struct timespec ts; | 278 | struct timespec ts; |
279 | s64 ns; | ||
277 | 280 | ||
278 | ktime_get_ts(&ts); | 281 | ktime_get_ts(&ts); |
279 | *p++ = timespec_to_ns(&ts); | 282 | ns = timespec_to_ns(&ts); |
280 | *p = (unsigned long)nsm; | 283 | put_unaligned(ns, p); |
284 | put_unaligned((unsigned long)nsm, p + 1); | ||
281 | } | 285 | } |
282 | 286 | ||
283 | static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap, | 287 | static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap, |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 64f1c31b5853..abf83881f68a 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -53,17 +53,6 @@ static struct svc_rqst *nlmsvc_rqst; | |||
53 | unsigned long nlmsvc_timeout; | 53 | unsigned long nlmsvc_timeout; |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * If the kernel has IPv6 support available, always listen for | ||
57 | * both AF_INET and AF_INET6 requests. | ||
58 | */ | ||
59 | #if (defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) && \ | ||
60 | defined(CONFIG_SUNRPC_REGISTER_V4) | ||
61 | static const sa_family_t nlmsvc_family = AF_INET6; | ||
62 | #else /* (CONFIG_IPV6 || CONFIG_IPV6_MODULE) && CONFIG_SUNRPC_REGISTER_V4 */ | ||
63 | static const sa_family_t nlmsvc_family = AF_INET; | ||
64 | #endif /* (CONFIG_IPV6 || CONFIG_IPV6_MODULE) && CONFIG_SUNRPC_REGISTER_V4 */ | ||
65 | |||
66 | /* | ||
67 | * These can be set at insmod time (useful for NFS as root filesystem), | 56 | * These can be set at insmod time (useful for NFS as root filesystem), |
68 | * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003 | 57 | * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003 |
69 | */ | 58 | */ |
@@ -204,19 +193,30 @@ lockd(void *vrqstp) | |||
204 | return 0; | 193 | return 0; |
205 | } | 194 | } |
206 | 195 | ||
207 | static int create_lockd_listener(struct svc_serv *serv, char *name, | 196 | static int create_lockd_listener(struct svc_serv *serv, const char *name, |
208 | unsigned short port) | 197 | const int family, const unsigned short port) |
209 | { | 198 | { |
210 | struct svc_xprt *xprt; | 199 | struct svc_xprt *xprt; |
211 | 200 | ||
212 | xprt = svc_find_xprt(serv, name, 0, 0); | 201 | xprt = svc_find_xprt(serv, name, family, 0); |
213 | if (xprt == NULL) | 202 | if (xprt == NULL) |
214 | return svc_create_xprt(serv, name, port, SVC_SOCK_DEFAULTS); | 203 | return svc_create_xprt(serv, name, family, port, |
215 | 204 | SVC_SOCK_DEFAULTS); | |
216 | svc_xprt_put(xprt); | 205 | svc_xprt_put(xprt); |
217 | return 0; | 206 | return 0; |
218 | } | 207 | } |
219 | 208 | ||
209 | static int create_lockd_family(struct svc_serv *serv, const int family) | ||
210 | { | ||
211 | int err; | ||
212 | |||
213 | err = create_lockd_listener(serv, "udp", family, nlm_udpport); | ||
214 | if (err < 0) | ||
215 | return err; | ||
216 | |||
217 | return create_lockd_listener(serv, "tcp", family, nlm_tcpport); | ||
218 | } | ||
219 | |||
220 | /* | 220 | /* |
221 | * Ensure there are active UDP and TCP listeners for lockd. | 221 | * Ensure there are active UDP and TCP listeners for lockd. |
222 | * | 222 | * |
@@ -232,13 +232,15 @@ static int make_socks(struct svc_serv *serv) | |||
232 | static int warned; | 232 | static int warned; |
233 | int err; | 233 | int err; |
234 | 234 | ||
235 | err = create_lockd_listener(serv, "udp", nlm_udpport); | 235 | err = create_lockd_family(serv, PF_INET); |
236 | if (err < 0) | 236 | if (err < 0) |
237 | goto out_err; | 237 | goto out_err; |
238 | 238 | ||
239 | err = create_lockd_listener(serv, "tcp", nlm_tcpport); | 239 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
240 | if (err < 0) | 240 | err = create_lockd_family(serv, PF_INET6); |
241 | if (err < 0 && err != -EAFNOSUPPORT) | ||
241 | goto out_err; | 242 | goto out_err; |
243 | #endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */ | ||
242 | 244 | ||
243 | warned = 0; | 245 | warned = 0; |
244 | return 0; | 246 | return 0; |
@@ -274,7 +276,7 @@ int lockd_up(void) | |||
274 | "lockd_up: no pid, %d users??\n", nlmsvc_users); | 276 | "lockd_up: no pid, %d users??\n", nlmsvc_users); |
275 | 277 | ||
276 | error = -ENOMEM; | 278 | error = -ENOMEM; |
277 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, nlmsvc_family, NULL); | 279 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); |
278 | if (!serv) { | 280 | if (!serv) { |
279 | printk(KERN_WARNING "lockd_up: create service failed\n"); | 281 | printk(KERN_WARNING "lockd_up: create service failed\n"); |
280 | goto out; | 282 | goto out; |