aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/cell.c
diff options
context:
space:
mode:
authorWang Lei <wang840925@gmail.com>2010-08-04 10:16:38 -0400
committerSteve French <sfrench@us.ibm.com>2010-08-05 13:17:51 -0400
commit07567a5509327bcbf2c867286eb1524447c9b954 (patch)
tree35e73b223c2def7ca130b6a58aef8e93aa2bd72a /fs/afs/cell.c
parent1a4240f4764ac78adbf4b0ebb49b3bd8c72ffa11 (diff)
DNS: Make AFS go to the DNS for AFSDB records for unknown cells
Add DNS query support for AFS so that it can get the IP addresses of Volume Location servers from the DNS using an AFSDB record. This requires userspace support. /etc/request-key.conf must be configured to invoke a helper for dns_resolver type keys with a subtype of "afsdb:" in the description. 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.c40
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;
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));