diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2011-11-25 09:13:04 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-01-31 18:20:26 -0500 |
commit | 1b340d0118da1d7c60c664f17d7c8fce2bb1cd9d (patch) | |
tree | a66a9626f8fca21bd42d13a3b4270b168e2186fc /fs/nfs/dns_resolve.c | |
parent | 5c1cacb175185ed925d7dc13ac7e0653e7a633cd (diff) |
NFS: DNS resolver cache per network namespace context introduced
This patch implements DNS resolver cache creation and registration for each
alive network namespace context.
This was done by registering NFS per-net operations, responsible for DNS cache
allocation/register and unregister/destructioning instead of initialization and
destruction of static "nfs_dns_resolve" cache detail (this one was removed).
Pointer to network dns resolver cache is stored in new per-net "nfs_net"
structure.
This patch also changes nfs_dns_resolve_name() function prototype (and it's
calls) by adding network pointer parameter, which is used to get proper DNS
resolver cache pointer for do_cache_lookup_wait() call.
Note: empty nfs_dns_resolver_init() and nfs_dns_resolver_destroy() functions
will be used in next patch in the series.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/dns_resolve.c')
-rw-r--r-- | fs/nfs/dns_resolve.c | 96 |
1 files changed, 63 insertions, 33 deletions
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c index 3cbf4b88f827..9aea78ab86ac 100644 --- a/fs/nfs/dns_resolve.c +++ b/fs/nfs/dns_resolve.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <linux/sunrpc/clnt.h> | 11 | #include <linux/sunrpc/clnt.h> |
12 | #include <linux/dns_resolver.h> | 12 | #include <linux/dns_resolver.h> |
13 | 13 | ||
14 | ssize_t nfs_dns_resolve_name(char *name, size_t namelen, | 14 | ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen, |
15 | struct sockaddr *sa, size_t salen) | 15 | struct sockaddr *sa, size_t salen) |
16 | { | 16 | { |
17 | ssize_t ret; | 17 | ssize_t ret; |
@@ -43,12 +43,11 @@ ssize_t nfs_dns_resolve_name(char *name, size_t namelen, | |||
43 | 43 | ||
44 | #include "dns_resolve.h" | 44 | #include "dns_resolve.h" |
45 | #include "cache_lib.h" | 45 | #include "cache_lib.h" |
46 | #include "netns.h" | ||
46 | 47 | ||
47 | #define NFS_DNS_HASHBITS 4 | 48 | #define NFS_DNS_HASHBITS 4 |
48 | #define NFS_DNS_HASHTBL_SIZE (1 << NFS_DNS_HASHBITS) | 49 | #define NFS_DNS_HASHTBL_SIZE (1 << NFS_DNS_HASHBITS) |
49 | 50 | ||
50 | static struct cache_head *nfs_dns_table[NFS_DNS_HASHTBL_SIZE]; | ||
51 | |||
52 | struct nfs_dns_ent { | 51 | struct nfs_dns_ent { |
53 | struct cache_head h; | 52 | struct cache_head h; |
54 | 53 | ||
@@ -259,21 +258,6 @@ out: | |||
259 | return ret; | 258 | return ret; |
260 | } | 259 | } |
261 | 260 | ||
262 | static struct cache_detail nfs_dns_resolve = { | ||
263 | .owner = THIS_MODULE, | ||
264 | .hash_size = NFS_DNS_HASHTBL_SIZE, | ||
265 | .hash_table = nfs_dns_table, | ||
266 | .name = "dns_resolve", | ||
267 | .cache_put = nfs_dns_ent_put, | ||
268 | .cache_upcall = nfs_dns_upcall, | ||
269 | .cache_parse = nfs_dns_parse, | ||
270 | .cache_show = nfs_dns_show, | ||
271 | .match = nfs_dns_match, | ||
272 | .init = nfs_dns_ent_init, | ||
273 | .update = nfs_dns_ent_update, | ||
274 | .alloc = nfs_dns_ent_alloc, | ||
275 | }; | ||
276 | |||
277 | static int do_cache_lookup(struct cache_detail *cd, | 261 | static int do_cache_lookup(struct cache_detail *cd, |
278 | struct nfs_dns_ent *key, | 262 | struct nfs_dns_ent *key, |
279 | struct nfs_dns_ent **item, | 263 | struct nfs_dns_ent **item, |
@@ -336,8 +320,8 @@ out: | |||
336 | return ret; | 320 | return ret; |
337 | } | 321 | } |
338 | 322 | ||
339 | ssize_t nfs_dns_resolve_name(char *name, size_t namelen, | 323 | ssize_t nfs_dns_resolve_name(struct net *net, char *name, |
340 | struct sockaddr *sa, size_t salen) | 324 | size_t namelen, struct sockaddr *sa, size_t salen) |
341 | { | 325 | { |
342 | struct nfs_dns_ent key = { | 326 | struct nfs_dns_ent key = { |
343 | .hostname = name, | 327 | .hostname = name, |
@@ -345,37 +329,83 @@ ssize_t nfs_dns_resolve_name(char *name, size_t namelen, | |||
345 | }; | 329 | }; |
346 | struct nfs_dns_ent *item = NULL; | 330 | struct nfs_dns_ent *item = NULL; |
347 | ssize_t ret; | 331 | ssize_t ret; |
332 | struct nfs_net *nn = net_generic(net, nfs_net_id); | ||
348 | 333 | ||
349 | ret = do_cache_lookup_wait(&nfs_dns_resolve, &key, &item); | 334 | ret = do_cache_lookup_wait(nn->nfs_dns_resolve, &key, &item); |
350 | if (ret == 0) { | 335 | if (ret == 0) { |
351 | if (salen >= item->addrlen) { | 336 | if (salen >= item->addrlen) { |
352 | memcpy(sa, &item->addr, item->addrlen); | 337 | memcpy(sa, &item->addr, item->addrlen); |
353 | ret = item->addrlen; | 338 | ret = item->addrlen; |
354 | } else | 339 | } else |
355 | ret = -EOVERFLOW; | 340 | ret = -EOVERFLOW; |
356 | cache_put(&item->h, &nfs_dns_resolve); | 341 | cache_put(&item->h, nn->nfs_dns_resolve); |
357 | } else if (ret == -ENOENT) | 342 | } else if (ret == -ENOENT) |
358 | ret = -ESRCH; | 343 | ret = -ESRCH; |
359 | return ret; | 344 | return ret; |
360 | } | 345 | } |
361 | 346 | ||
362 | int nfs_dns_resolver_init(void) | 347 | int nfs_dns_resolver_cache_init(struct net *net) |
363 | { | 348 | { |
364 | int err; | 349 | int err = -ENOMEM; |
350 | struct nfs_net *nn = net_generic(net, nfs_net_id); | ||
351 | struct cache_detail *cd; | ||
352 | struct cache_head **tbl; | ||
353 | |||
354 | cd = kzalloc(sizeof(struct cache_detail), GFP_KERNEL); | ||
355 | if (cd == NULL) | ||
356 | goto err_cd; | ||
357 | |||
358 | tbl = kzalloc(NFS_DNS_HASHTBL_SIZE * sizeof(struct cache_head *), | ||
359 | GFP_KERNEL); | ||
360 | if (tbl == NULL) | ||
361 | goto err_tbl; | ||
362 | |||
363 | cd->owner = THIS_MODULE, | ||
364 | cd->hash_size = NFS_DNS_HASHTBL_SIZE, | ||
365 | cd->hash_table = tbl, | ||
366 | cd->name = "dns_resolve", | ||
367 | cd->cache_put = nfs_dns_ent_put, | ||
368 | cd->cache_upcall = nfs_dns_upcall, | ||
369 | cd->cache_parse = nfs_dns_parse, | ||
370 | cd->cache_show = nfs_dns_show, | ||
371 | cd->match = nfs_dns_match, | ||
372 | cd->init = nfs_dns_ent_init, | ||
373 | cd->update = nfs_dns_ent_update, | ||
374 | cd->alloc = nfs_dns_ent_alloc, | ||
375 | |||
376 | nfs_cache_init(cd); | ||
377 | err = nfs_cache_register_net(net, cd); | ||
378 | if (err) | ||
379 | goto err_reg; | ||
380 | nn->nfs_dns_resolve = cd; | ||
381 | return 0; | ||
365 | 382 | ||
366 | nfs_cache_init(&nfs_dns_resolve); | 383 | err_reg: |
367 | err = nfs_cache_register_net(&init_net, &nfs_dns_resolve); | 384 | nfs_cache_destroy(cd); |
368 | if (err) { | 385 | kfree(cd->hash_table); |
369 | nfs_cache_destroy(&nfs_dns_resolve); | 386 | err_tbl: |
370 | return err; | 387 | kfree(cd); |
371 | } | 388 | err_cd: |
389 | return err; | ||
390 | } | ||
391 | |||
392 | void nfs_dns_resolver_cache_destroy(struct net *net) | ||
393 | { | ||
394 | struct nfs_net *nn = net_generic(net, nfs_net_id); | ||
395 | struct cache_detail *cd = nn->nfs_dns_resolve; | ||
396 | |||
397 | nfs_cache_unregister_net(net, cd); | ||
398 | nfs_cache_destroy(cd); | ||
399 | kfree(cd->hash_table); | ||
400 | kfree(cd); | ||
401 | } | ||
402 | |||
403 | int nfs_dns_resolver_init(void) | ||
404 | { | ||
372 | return 0; | 405 | return 0; |
373 | } | 406 | } |
374 | 407 | ||
375 | void nfs_dns_resolver_destroy(void) | 408 | void nfs_dns_resolver_destroy(void) |
376 | { | 409 | { |
377 | nfs_cache_unregister_net(&init_net, &nfs_dns_resolve); | ||
378 | nfs_cache_destroy(&nfs_dns_resolve); | ||
379 | } | 410 | } |
380 | |||
381 | #endif | 411 | #endif |