aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/super.c
diff options
context:
space:
mode:
authorwanglei <wang840925@gmail.com>2010-08-11 04:38:04 -0400
committerSteve French <sfrench@us.ibm.com>2010-08-11 13:11:29 -0400
commitbec5eb6141308a30a73682330cb045a40e442b8c (patch)
treeae514575d62e65a07d6089746fbd880f816ee382 /fs/afs/super.c
parent4a2d789267e00b5a1175ecd2ddefcc78b83fbf09 (diff)
AFS: Implement an autocell mount capability [ver #2]
Implement the ability for the root directory of a mounted AFS filesystem to accept lookups of arbitrary directory names, to interpet the names as the names of cells, to look the cell names up in the DNS for AFSDB records and to mount the root.cell volume of the nominated cell on the pseudo-directory created by lookup. This facility is requested by passing: -o autocell to the mountpoint for which this is desired, usually the /afs mount. To use this facility, a DNS upcall program is required for AFSDB records. This can be obtained from: http://people.redhat.com/~dhowells/afs/dns.afsdb.c It should be compiled with -lresolv and -lkeyutils and installed as, say: /usr/sbin/dns.afsdb Then the following line needs to be added to /sbin/request-key.conf: create dns_resolver afsdb:* * /usr/sbin/dns.afsdb %k This can be tested by mounting AFS, say: insmod dns_resolver.ko insmod af-rxrpc.ko insmod kafs.ko rootcell=grand.central.org mount -t afs "#grand.central.org:root.cell." /afs -o autocell and doing: ls /afs/grand.central.org/ which should show: archive/ cvs/ doc/ local/ project/ service/ software/ user/ www/ if it works. Signed-off-by: Wang Lei <wang840925@gmail.com> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/afs/super.c')
-rw-r--r--fs/afs/super.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 9cf80f02da1..77e1e5a6115 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/mount.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/smp_lock.h> 22#include <linux/smp_lock.h>
@@ -48,6 +49,7 @@ struct file_system_type afs_fs_type = {
48static const struct super_operations afs_super_ops = { 49static const struct super_operations afs_super_ops = {
49 .statfs = afs_statfs, 50 .statfs = afs_statfs,
50 .alloc_inode = afs_alloc_inode, 51 .alloc_inode = afs_alloc_inode,
52 .drop_inode = afs_drop_inode,
51 .destroy_inode = afs_destroy_inode, 53 .destroy_inode = afs_destroy_inode,
52 .evict_inode = afs_evict_inode, 54 .evict_inode = afs_evict_inode,
53 .put_super = afs_put_super, 55 .put_super = afs_put_super,
@@ -62,12 +64,14 @@ enum {
62 afs_opt_cell, 64 afs_opt_cell,
63 afs_opt_rwpath, 65 afs_opt_rwpath,
64 afs_opt_vol, 66 afs_opt_vol,
67 afs_opt_autocell,
65}; 68};
66 69
67static const match_table_t afs_options_list = { 70static const match_table_t afs_options_list = {
68 { afs_opt_cell, "cell=%s" }, 71 { afs_opt_cell, "cell=%s" },
69 { afs_opt_rwpath, "rwpath" }, 72 { afs_opt_rwpath, "rwpath" },
70 { afs_opt_vol, "vol=%s" }, 73 { afs_opt_vol, "vol=%s" },
74 { afs_opt_autocell, "autocell" },
71 { afs_no_opt, NULL }, 75 { afs_no_opt, NULL },
72}; 76};
73 77
@@ -151,7 +155,8 @@ static int afs_parse_options(struct afs_mount_params *params,
151 switch (token) { 155 switch (token) {
152 case afs_opt_cell: 156 case afs_opt_cell:
153 cell = afs_cell_lookup(args[0].from, 157 cell = afs_cell_lookup(args[0].from,
154 args[0].to - args[0].from); 158 args[0].to - args[0].from,
159 false);
155 if (IS_ERR(cell)) 160 if (IS_ERR(cell))
156 return PTR_ERR(cell); 161 return PTR_ERR(cell);
157 afs_put_cell(params->cell); 162 afs_put_cell(params->cell);
@@ -166,6 +171,10 @@ static int afs_parse_options(struct afs_mount_params *params,
166 *devname = args[0].from; 171 *devname = args[0].from;
167 break; 172 break;
168 173
174 case afs_opt_autocell:
175 params->autocell = 1;
176 break;
177
169 default: 178 default:
170 printk(KERN_ERR "kAFS:" 179 printk(KERN_ERR "kAFS:"
171 " Unknown or invalid mount option: '%s'\n", p); 180 " Unknown or invalid mount option: '%s'\n", p);
@@ -252,10 +261,10 @@ static int afs_parse_device_name(struct afs_mount_params *params,
252 261
253 /* lookup the cell record */ 262 /* lookup the cell record */
254 if (cellname || !params->cell) { 263 if (cellname || !params->cell) {
255 cell = afs_cell_lookup(cellname, cellnamesz); 264 cell = afs_cell_lookup(cellname, cellnamesz, true);
256 if (IS_ERR(cell)) { 265 if (IS_ERR(cell)) {
257 printk(KERN_ERR "kAFS: unable to lookup cell '%s'\n", 266 printk(KERN_ERR "kAFS: unable to lookup cell '%*.*s'\n",
258 cellname ?: ""); 267 cellnamesz, cellnamesz, cellname ?: "");
259 return PTR_ERR(cell); 268 return PTR_ERR(cell);
260 } 269 }
261 afs_put_cell(params->cell); 270 afs_put_cell(params->cell);
@@ -321,6 +330,9 @@ static int afs_fill_super(struct super_block *sb, void *data)
321 if (IS_ERR(inode)) 330 if (IS_ERR(inode))
322 goto error_inode; 331 goto error_inode;
323 332
333 if (params->autocell)
334 set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags);
335
324 ret = -ENOMEM; 336 ret = -ENOMEM;
325 root = d_alloc_root(inode); 337 root = d_alloc_root(inode);
326 if (!root) 338 if (!root)