diff options
Diffstat (limited to 'fs/afs/cell.c')
| -rw-r--r-- | fs/afs/cell.c | 40 |
1 files changed, 30 insertions, 10 deletions
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; |
| 111 | error: | 132 | error: |
| 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)); |
