diff options
author | Fred Isaman <iisaman@netapp.com> | 2010-10-20 00:17:59 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-10-24 18:07:10 -0400 |
commit | 02c35fca7cf4ea2dfdc6db279e230cacbbf4b870 (patch) | |
tree | 7449a8a3fb119d862f6c163c05cf43d58443c377 /fs/nfs/pnfs.c | |
parent | 85e174ba6b786ad336eb2df105b4f66d0932e70a (diff) |
NFSv4.1: pnfs: full mount/umount infrastructure
Allow a module implementing a layout type to register, and
have its mount/umount routines called for filesystems that
the server declares support it.
Signed-off-by: Fred Isaman <iisaman@netapp.com>
Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Bian Naimeng <biannm@cn.fujitsu.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r-- | fs/nfs/pnfs.c | 88 |
1 files changed, 86 insertions, 2 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index b483026e82aa..cf795625610e 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -32,16 +32,51 @@ | |||
32 | 32 | ||
33 | #define NFSDBG_FACILITY NFSDBG_PNFS | 33 | #define NFSDBG_FACILITY NFSDBG_PNFS |
34 | 34 | ||
35 | /* STUB that returns the equivalent of "no module found" */ | 35 | /* Locking: |
36 | * | ||
37 | * pnfs_spinlock: | ||
38 | * protects pnfs_modules_tbl. | ||
39 | */ | ||
40 | static DEFINE_SPINLOCK(pnfs_spinlock); | ||
41 | |||
42 | /* | ||
43 | * pnfs_modules_tbl holds all pnfs modules | ||
44 | */ | ||
45 | static LIST_HEAD(pnfs_modules_tbl); | ||
46 | |||
47 | /* Return the registered pnfs layout driver module matching given id */ | ||
48 | static struct pnfs_layoutdriver_type * | ||
49 | find_pnfs_driver_locked(u32 id) | ||
50 | { | ||
51 | struct pnfs_layoutdriver_type *local; | ||
52 | |||
53 | list_for_each_entry(local, &pnfs_modules_tbl, pnfs_tblid) | ||
54 | if (local->id == id) | ||
55 | goto out; | ||
56 | local = NULL; | ||
57 | out: | ||
58 | dprintk("%s: Searching for id %u, found %p\n", __func__, id, local); | ||
59 | return local; | ||
60 | } | ||
61 | |||
36 | static struct pnfs_layoutdriver_type * | 62 | static struct pnfs_layoutdriver_type * |
37 | find_pnfs_driver(u32 id) | 63 | find_pnfs_driver(u32 id) |
38 | { | 64 | { |
39 | return NULL; | 65 | struct pnfs_layoutdriver_type *local; |
66 | |||
67 | spin_lock(&pnfs_spinlock); | ||
68 | local = find_pnfs_driver_locked(id); | ||
69 | spin_unlock(&pnfs_spinlock); | ||
70 | return local; | ||
40 | } | 71 | } |
41 | 72 | ||
42 | void | 73 | void |
43 | unset_pnfs_layoutdriver(struct nfs_server *nfss) | 74 | unset_pnfs_layoutdriver(struct nfs_server *nfss) |
44 | { | 75 | { |
76 | if (nfss->pnfs_curr_ld) { | ||
77 | nfss->pnfs_curr_ld->uninitialize_mountpoint(nfss); | ||
78 | module_put(nfss->pnfs_curr_ld->owner); | ||
79 | } | ||
45 | nfss->pnfs_curr_ld = NULL; | 80 | nfss->pnfs_curr_ld = NULL; |
46 | } | 81 | } |
47 | 82 | ||
@@ -74,7 +109,18 @@ set_pnfs_layoutdriver(struct nfs_server *server, u32 id) | |||
74 | goto out_no_driver; | 109 | goto out_no_driver; |
75 | } | 110 | } |
76 | } | 111 | } |
112 | if (!try_module_get(ld_type->owner)) { | ||
113 | dprintk("%s: Could not grab reference on module\n", __func__); | ||
114 | goto out_no_driver; | ||
115 | } | ||
77 | server->pnfs_curr_ld = ld_type; | 116 | server->pnfs_curr_ld = ld_type; |
117 | if (ld_type->initialize_mountpoint(server)) { | ||
118 | printk(KERN_ERR | ||
119 | "%s: Error initializing mount point for layout driver %u.\n", | ||
120 | __func__, id); | ||
121 | module_put(ld_type->owner); | ||
122 | goto out_no_driver; | ||
123 | } | ||
78 | dprintk("%s: pNFS module for %u set\n", __func__, id); | 124 | dprintk("%s: pNFS module for %u set\n", __func__, id); |
79 | return; | 125 | return; |
80 | 126 | ||
@@ -82,3 +128,41 @@ out_no_driver: | |||
82 | dprintk("%s: Using NFSv4 I/O\n", __func__); | 128 | dprintk("%s: Using NFSv4 I/O\n", __func__); |
83 | server->pnfs_curr_ld = NULL; | 129 | server->pnfs_curr_ld = NULL; |
84 | } | 130 | } |
131 | |||
132 | int | ||
133 | pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *ld_type) | ||
134 | { | ||
135 | int status = -EINVAL; | ||
136 | struct pnfs_layoutdriver_type *tmp; | ||
137 | |||
138 | if (ld_type->id == 0) { | ||
139 | printk(KERN_ERR "%s id 0 is reserved\n", __func__); | ||
140 | return status; | ||
141 | } | ||
142 | |||
143 | spin_lock(&pnfs_spinlock); | ||
144 | tmp = find_pnfs_driver_locked(ld_type->id); | ||
145 | if (!tmp) { | ||
146 | list_add(&ld_type->pnfs_tblid, &pnfs_modules_tbl); | ||
147 | status = 0; | ||
148 | dprintk("%s Registering id:%u name:%s\n", __func__, ld_type->id, | ||
149 | ld_type->name); | ||
150 | } else { | ||
151 | printk(KERN_ERR "%s Module with id %d already loaded!\n", | ||
152 | __func__, ld_type->id); | ||
153 | } | ||
154 | spin_unlock(&pnfs_spinlock); | ||
155 | |||
156 | return status; | ||
157 | } | ||
158 | EXPORT_SYMBOL_GPL(pnfs_register_layoutdriver); | ||
159 | |||
160 | void | ||
161 | pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *ld_type) | ||
162 | { | ||
163 | dprintk("%s Deregistering id:%u\n", __func__, ld_type->id); | ||
164 | spin_lock(&pnfs_spinlock); | ||
165 | list_del(&ld_type->pnfs_tblid); | ||
166 | spin_unlock(&pnfs_spinlock); | ||
167 | } | ||
168 | EXPORT_SYMBOL_GPL(pnfs_unregister_layoutdriver); | ||