aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2011-11-25 09:13:12 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-01-31 18:20:26 -0500
commit9df69c81b469780b64f9b26bb87c048613fdeddf (patch)
tree76dc666bf8b8b18c2e3b628159d6a85e5cffa62b
parent1b340d0118da1d7c60c664f17d7c8fce2bb1cd9d (diff)
NFS: DNS resolver PipeFS notifier introduced
This patch subscribes DNS resolver caches to RPC pipefs notifications. Notifier is registering on NFS module load. This notifier callback is responsible for creation/destruction of PipeFS DNS resolver cache directory. Note that no locking required in notifier callback because PipeFS superblock pointer is passed as an argument from it's creation or destruction routine and thus we can be sure about it's validity. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/cache_lib.c4
-rw-r--r--fs/nfs/cache_lib.h4
-rw-r--r--fs/nfs/dns_resolve.c38
3 files changed, 43 insertions, 3 deletions
diff --git a/fs/nfs/cache_lib.c b/fs/nfs/cache_lib.c
index 5dd017bbb7a2..5905a31211e5 100644
--- a/fs/nfs/cache_lib.c
+++ b/fs/nfs/cache_lib.c
@@ -112,7 +112,7 @@ int nfs_cache_wait_for_upcall(struct nfs_cache_defer_req *dreq)
112 return 0; 112 return 0;
113} 113}
114 114
115static int nfs_cache_register_sb(struct super_block *sb, struct cache_detail *cd) 115int nfs_cache_register_sb(struct super_block *sb, struct cache_detail *cd)
116{ 116{
117 int ret; 117 int ret;
118 struct dentry *dir; 118 struct dentry *dir;
@@ -147,7 +147,7 @@ err:
147 return ret; 147 return ret;
148} 148}
149 149
150static void nfs_cache_unregister_sb(struct super_block *sb, struct cache_detail *cd) 150void nfs_cache_unregister_sb(struct super_block *sb, struct cache_detail *cd)
151{ 151{
152 if (cd->u.pipefs.dir) 152 if (cd->u.pipefs.dir)
153 sunrpc_cache_unregister_pipefs(cd); 153 sunrpc_cache_unregister_pipefs(cd);
diff --git a/fs/nfs/cache_lib.h b/fs/nfs/cache_lib.h
index e0a6cc4b01b9..317db95e37f8 100644
--- a/fs/nfs/cache_lib.h
+++ b/fs/nfs/cache_lib.h
@@ -27,3 +27,7 @@ extern void nfs_cache_init(struct cache_detail *cd);
27extern void nfs_cache_destroy(struct cache_detail *cd); 27extern void nfs_cache_destroy(struct cache_detail *cd);
28extern int nfs_cache_register_net(struct net *net, struct cache_detail *cd); 28extern int nfs_cache_register_net(struct net *net, struct cache_detail *cd);
29extern void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd); 29extern void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd);
30extern int nfs_cache_register_sb(struct super_block *sb,
31 struct cache_detail *cd);
32extern void nfs_cache_unregister_sb(struct super_block *sb,
33 struct cache_detail *cd);
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index 9aea78ab86ac..200eb67c95d9 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -40,6 +40,7 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
40#include <linux/sunrpc/clnt.h> 40#include <linux/sunrpc/clnt.h>
41#include <linux/sunrpc/cache.h> 41#include <linux/sunrpc/cache.h>
42#include <linux/sunrpc/svcauth.h> 42#include <linux/sunrpc/svcauth.h>
43#include <linux/sunrpc/rpc_pipe_fs.h>
43 44
44#include "dns_resolve.h" 45#include "dns_resolve.h"
45#include "cache_lib.h" 46#include "cache_lib.h"
@@ -400,12 +401,47 @@ void nfs_dns_resolver_cache_destroy(struct net *net)
400 kfree(cd); 401 kfree(cd);
401} 402}
402 403
404static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
405 void *ptr)
406{
407 struct super_block *sb = ptr;
408 struct net *net = sb->s_fs_info;
409 struct nfs_net *nn = net_generic(net, nfs_net_id);
410 struct cache_detail *cd = nn->nfs_dns_resolve;
411 int ret = 0;
412
413 if (cd == NULL)
414 return 0;
415
416 if (!try_module_get(THIS_MODULE))
417 return 0;
418
419 switch (event) {
420 case RPC_PIPEFS_MOUNT:
421 ret = nfs_cache_register_sb(sb, cd);
422 break;
423 case RPC_PIPEFS_UMOUNT:
424 nfs_cache_unregister_sb(sb, cd);
425 break;
426 default:
427 ret = -ENOTSUPP;
428 break;
429 }
430 module_put(THIS_MODULE);
431 return ret;
432}
433
434static struct notifier_block nfs_dns_resolver_block = {
435 .notifier_call = rpc_pipefs_event,
436};
437
403int nfs_dns_resolver_init(void) 438int nfs_dns_resolver_init(void)
404{ 439{
405 return 0; 440 return rpc_pipefs_notifier_register(&nfs_dns_resolver_block);
406} 441}
407 442
408void nfs_dns_resolver_destroy(void) 443void nfs_dns_resolver_destroy(void)
409{ 444{
445 rpc_pipefs_notifier_unregister(&nfs_dns_resolver_block);
410} 446}
411#endif 447#endif