aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/cell.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/cell.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/cell.c')
-rw-r--r--fs/afs/cell.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index d0765883430e..0d5eeadf6121 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -31,21 +31,20 @@ static struct afs_cell *afs_cell_root;
31 * allocate a cell record and fill in its name, VL server address list and 31 * allocate a cell record and fill in its name, VL server address list and
32 * allocate an anonymous key 32 * allocate an anonymous key
33 */ 33 */
34static struct afs_cell *afs_cell_alloc(const char *name, char *vllist) 34static struct afs_cell *afs_cell_alloc(const char *name, unsigned namelen,
35 char *vllist)
35{ 36{
36 struct afs_cell *cell; 37 struct afs_cell *cell;
37 struct key *key; 38 struct key *key;
38 size_t namelen;
39 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next; 39 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next;
40 char *dvllist = NULL, *_vllist = NULL; 40 char *dvllist = NULL, *_vllist = NULL;
41 char delimiter = ':'; 41 char delimiter = ':';
42 int ret; 42 int ret;
43 43
44 _enter("%s,%s", name, vllist); 44 _enter("%*.*s,%s", namelen, namelen, name ?: "", vllist);
45 45
46 BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */ 46 BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */
47 47
48 namelen = strlen(name);
49 if (namelen > AFS_MAXCELLNAME) { 48 if (namelen > AFS_MAXCELLNAME) {
50 _leave(" = -ENAMETOOLONG"); 49 _leave(" = -ENAMETOOLONG");
51 return ERR_PTR(-ENAMETOOLONG); 50 return ERR_PTR(-ENAMETOOLONG);
@@ -142,26 +141,29 @@ error:
142} 141}
143 142
144/* 143/*
145 * create a cell record 144 * afs_cell_crate() - create a cell record
146 * - "name" is the name of the cell 145 * @name: is the name of the cell.
147 * - "vllist" is a colon separated list of IP addresses in "a.b.c.d" format 146 * @namsesz: is the strlen of the cell name.
147 * @vllist: is a colon separated list of IP addresses in "a.b.c.d" format.
148 * @retref: is T to return the cell reference when the cell exists.
148 */ 149 */
149struct afs_cell *afs_cell_create(const char *name, char *vllist) 150struct afs_cell *afs_cell_create(const char *name, unsigned namesz,
151 char *vllist, bool retref)
150{ 152{
151 struct afs_cell *cell; 153 struct afs_cell *cell;
152 int ret; 154 int ret;
153 155
154 _enter("%s,%s", name, vllist); 156 _enter("%*.*s,%s", namesz, namesz, name ?: "", vllist);
155 157
156 down_write(&afs_cells_sem); 158 down_write(&afs_cells_sem);
157 read_lock(&afs_cells_lock); 159 read_lock(&afs_cells_lock);
158 list_for_each_entry(cell, &afs_cells, link) { 160 list_for_each_entry(cell, &afs_cells, link) {
159 if (strcasecmp(cell->name, name) == 0) 161 if (strncasecmp(cell->name, name, namesz) == 0)
160 goto duplicate_name; 162 goto duplicate_name;
161 } 163 }
162 read_unlock(&afs_cells_lock); 164 read_unlock(&afs_cells_lock);
163 165
164 cell = afs_cell_alloc(name, vllist); 166 cell = afs_cell_alloc(name, namesz, vllist);
165 if (IS_ERR(cell)) { 167 if (IS_ERR(cell)) {
166 _leave(" = %ld", PTR_ERR(cell)); 168 _leave(" = %ld", PTR_ERR(cell));
167 up_write(&afs_cells_sem); 169 up_write(&afs_cells_sem);
@@ -201,8 +203,18 @@ error:
201 return ERR_PTR(ret); 203 return ERR_PTR(ret);
202 204
203duplicate_name: 205duplicate_name:
206 if (retref && !IS_ERR(cell))
207 afs_get_cell(cell);
208
204 read_unlock(&afs_cells_lock); 209 read_unlock(&afs_cells_lock);
205 up_write(&afs_cells_sem); 210 up_write(&afs_cells_sem);
211
212 if (retref) {
213 _leave(" = %p", cell);
214 return cell;
215 }
216
217 _leave(" = -EEXIST");
206 return ERR_PTR(-EEXIST); 218 return ERR_PTR(-EEXIST);
207} 219}
208 220
@@ -233,7 +245,7 @@ int afs_cell_init(char *rootcell)
233 *cp++ = 0; 245 *cp++ = 0;
234 246
235 /* allocate a cell record for the root cell */ 247 /* allocate a cell record for the root cell */
236 new_root = afs_cell_create(rootcell, cp); 248 new_root = afs_cell_create(rootcell, strlen(rootcell), cp, false);
237 if (IS_ERR(new_root)) { 249 if (IS_ERR(new_root)) {
238 _leave(" = %ld", PTR_ERR(new_root)); 250 _leave(" = %ld", PTR_ERR(new_root));
239 return PTR_ERR(new_root); 251 return PTR_ERR(new_root);
@@ -253,11 +265,12 @@ int afs_cell_init(char *rootcell)
253/* 265/*
254 * lookup a cell record 266 * lookup a cell record
255 */ 267 */
256struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz) 268struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz,
269 bool dns_cell)
257{ 270{
258 struct afs_cell *cell; 271 struct afs_cell *cell;
259 272
260 _enter("\"%*.*s\",", namesz, namesz, name ? name : ""); 273 _enter("\"%*.*s\",", namesz, namesz, name ?: "");
261 274
262 down_read(&afs_cells_sem); 275 down_read(&afs_cells_sem);
263 read_lock(&afs_cells_lock); 276 read_lock(&afs_cells_lock);
@@ -271,6 +284,8 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz)
271 } 284 }
272 } 285 }
273 cell = ERR_PTR(-ENOENT); 286 cell = ERR_PTR(-ENOENT);
287 if (dns_cell)
288 goto create_cell;
274 found: 289 found:
275 ; 290 ;
276 } else { 291 } else {
@@ -293,6 +308,15 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz)
293 up_read(&afs_cells_sem); 308 up_read(&afs_cells_sem);
294 _leave(" = %p", cell); 309 _leave(" = %p", cell);
295 return cell; 310 return cell;
311
312create_cell:
313 read_unlock(&afs_cells_lock);
314 up_read(&afs_cells_sem);
315
316 cell = afs_cell_create(name, namesz, NULL, true);
317
318 _leave(" = %p", cell);
319 return cell;
296} 320}
297 321
298#if 0 322#if 0