aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/afs/Kconfig1
-rw-r--r--fs/afs/cell.c40
2 files changed, 31 insertions, 10 deletions
diff --git a/fs/afs/Kconfig b/fs/afs/Kconfig
index 5c4e61d3c772..8f975f25b486 100644
--- a/fs/afs/Kconfig
+++ b/fs/afs/Kconfig
@@ -2,6 +2,7 @@ config AFS_FS
2 tristate "Andrew File System support (AFS) (EXPERIMENTAL)" 2 tristate "Andrew File System support (AFS) (EXPERIMENTAL)"
3 depends on INET && EXPERIMENTAL 3 depends on INET && EXPERIMENTAL
4 select AF_RXRPC 4 select AF_RXRPC
5 select DNS_RESOLVER
5 help 6 help
6 If you say Y here, you will get an experimental Andrew File System 7 If you say Y here, you will get an experimental Andrew File System
7 driver. It currently only supports unsecured read-only AFS access. 8 driver. It currently only supports unsecured read-only AFS access.
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index e19c13f059ed..ffea35c63879 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -13,6 +13,7 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/key.h> 14#include <linux/key.h>
15#include <linux/ctype.h> 15#include <linux/ctype.h>
16#include <linux/dns_resolver.h>
16#include <linux/sched.h> 17#include <linux/sched.h>
17#include <keys/rxrpc-type.h> 18#include <keys/rxrpc-type.h>
18#include "internal.h" 19#include "internal.h"
@@ -36,6 +37,8 @@ static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
36 struct key *key; 37 struct key *key;
37 size_t namelen; 38 size_t namelen;
38 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;
41 char delimiter = ':';
39 int ret; 42 int ret;
40 43
41 _enter("%s,%s", name, vllist); 44 _enter("%s,%s", name, vllist);
@@ -43,8 +46,10 @@ static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
43 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 */
44 47
45 namelen = strlen(name); 48 namelen = strlen(name);
46 if (namelen > AFS_MAXCELLNAME) 49 if (namelen > AFS_MAXCELLNAME) {
50 _leave(" = -ENAMETOOLONG");
47 return ERR_PTR(-ENAMETOOLONG); 51 return ERR_PTR(-ENAMETOOLONG);
52 }
48 53
49 /* allocate and initialise a cell record */ 54 /* allocate and initialise a cell record */
50 cell = kzalloc(sizeof(struct afs_cell) + namelen + 1, GFP_KERNEL); 55 cell = kzalloc(sizeof(struct afs_cell) + namelen + 1, GFP_KERNEL);
@@ -64,15 +69,31 @@ static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
64 INIT_LIST_HEAD(&cell->vl_list); 69 INIT_LIST_HEAD(&cell->vl_list);
65 spin_lock_init(&cell->vl_lock); 70 spin_lock_init(&cell->vl_lock);
66 71
72 /* if the ip address is invalid, try dns query */
73 if (!vllist || strlen(vllist) < 7) {
74 ret = dns_query("afsdb", name, namelen, "ipv4", &dvllist, NULL);
75 if (ret < 0) {
76 _leave(" = %d", ret);
77 return ERR_PTR(ret);
78 }
79 _vllist = dvllist;
80
81 /* change the delimiter for user-space reply */
82 delimiter = ',';
83
84 } else {
85 _vllist = vllist;
86 }
87
67 /* fill in the VL server list from the rest of the string */ 88 /* fill in the VL server list from the rest of the string */
68 do { 89 do {
69 unsigned a, b, c, d; 90 unsigned a, b, c, d;
70 91
71 next = strchr(vllist, ':'); 92 next = strchr(_vllist, delimiter);
72 if (next) 93 if (next)
73 *next++ = 0; 94 *next++ = 0;
74 95
75 if (sscanf(vllist, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) 96 if (sscanf(_vllist, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
76 goto bad_address; 97 goto bad_address;
77 98
78 if (a > 255 || b > 255 || c > 255 || d > 255) 99 if (a > 255 || b > 255 || c > 255 || d > 255)
@@ -81,7 +102,7 @@ static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
81 cell->vl_addrs[cell->vl_naddrs++].s_addr = 102 cell->vl_addrs[cell->vl_naddrs++].s_addr =
82 htonl((a << 24) | (b << 16) | (c << 8) | d); 103 htonl((a << 24) | (b << 16) | (c << 8) | d);
83 104
84 } while (cell->vl_naddrs < AFS_CELL_MAX_ADDRS && (vllist = next)); 105 } while (cell->vl_naddrs < AFS_CELL_MAX_ADDRS && (_vllist = next));
85 106
86 /* create a key to represent an anonymous user */ 107 /* create a key to represent an anonymous user */
87 memcpy(keyname, "afs@", 4); 108 memcpy(keyname, "afs@", 4);
@@ -110,6 +131,7 @@ bad_address:
110 ret = -EINVAL; 131 ret = -EINVAL;
111error: 132error:
112 key_put(cell->anonymous_key); 133 key_put(cell->anonymous_key);
134 kfree(dvllist);
113 kfree(cell); 135 kfree(cell);
114 _leave(" = %d", ret); 136 _leave(" = %d", ret);
115 return ERR_PTR(ret); 137 return ERR_PTR(ret);
@@ -201,14 +223,12 @@ int afs_cell_init(char *rootcell)
201 } 223 }
202 224
203 cp = strchr(rootcell, ':'); 225 cp = strchr(rootcell, ':');
204 if (!cp) { 226 if (!cp)
205 printk(KERN_ERR "kAFS: no VL server IP addresses specified\n"); 227 _debug("kAFS: no VL server IP addresses specified");
206 _leave(" = -EINVAL"); 228 else
207 return -EINVAL; 229 *cp++ = 0;
208 }
209 230
210 /* allocate a cell record for the root cell */ 231 /* allocate a cell record for the root cell */
211 *cp++ = 0;
212 new_root = afs_cell_create(rootcell, cp); 232 new_root = afs_cell_create(rootcell, cp);
213 if (IS_ERR(new_root)) { 233 if (IS_ERR(new_root)) {
214 _leave(" = %ld", PTR_ERR(new_root)); 234 _leave(" = %ld", PTR_ERR(new_root));