1 /* AFS cell and server record management 2 * 3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/slab.h> 14 #include <linux/key.h> 15 #include <linux/ctype.h> 16 #include <linux/dns_resolver.h> 17 #include <linux/sched.h> 18 #include <keys/rxrpc-type.h> 19 #include "internal.h" 20 21 DECLARE_RWSEM(afs_proc_cells_sem); 22 LIST_HEAD(afs_proc_cells); 23 24 static LIST_HEAD(afs_cells); 25 static DEFINE_RWLOCK(afs_cells_lock); 26 static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */ 27 static DECLARE_WAIT_QUEUE_HEAD(afs_cells_freeable_wq); 28 static struct afs_cell *afs_cell_root; 29 30 /* 31 * allocate a cell record and fill in its name, VL server address list and 32 * allocate an anonymous key 33 */ 34 static struct afs_cell *afs_cell_alloc(const char *name, unsigned namelen, 35 char *vllist) 36 { 37 struct afs_cell *cell; 38 struct key *key; 39 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next; 40 char *dvllist = NULL, *_vllist = NULL; 41 char delimiter = ':'; 42 int ret; 43 44 _enter("%*.*s,%s", namelen, namelen, name ?: "", vllist); 45 46 BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */ 47 48 if (namelen > AFS_MAXCELLNAME) { 49 _leave(" = -ENAMETOOLONG"); 50 return ERR_PTR(-ENAMETOOLONG); 51 } 52 53 /* allocate and initialise a cell record */ 54 cell = kzalloc(sizeof(struct afs_cell) + namelen + 1, GFP_KERNEL); 55 if (!cell) { 56 _leave(" = -ENOMEM"); 57 return ERR_PTR(-ENOMEM); 58 } 59 60 memcpy(cell->name, name, namelen); 61 cell->name[namelen] = 0; 62 63 atomic_set(&cell->usage, 1); 64 INIT_LIST_HEAD(&cell->link); 65 rwlock_init(&cell->servers_lock); 66 INIT_LIST_HEAD(&cell->servers); 67 init_rwsem(&cell->vl_sem); 68 INIT_LIST_HEAD(&cell->vl_list); 69 spin_lock_init(&cell->vl_lock); 70 71 /* if the ip address is invalid, try dns query */ 72 if (!vllist || strlen(vllist) < 7) { 73 ret = dns_query("afsdb", name, namelen, "ipv4", &dvllist, NULL); 74 if (ret < 0) { 75 if (ret == -ENODATA || ret == -EAGAIN || ret == -ENOKEY) 76 /* translate these errors into something 77 * userspace might understand */ 78 ret = -EDESTADDRREQ; 79 _leave(" = %d", ret); 80 return ERR_PTR(ret); 81 } 82 _vllist = dvllist; 83 84 /* change the delimiter for user-space reply */ 85 delimiter = ','; 86 87 } else { 88 _vllist = vllist; 89 } 90 91 /* fill in the VL server list from the rest of the string */ 92 do { 93 unsigned a, b, c, d; 94 95 next = strchr(_vllist, delimiter); 96 if (next) 97 *next++ = 0; 98 99 if (sscanf(_vllist, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) 100 goto bad_address; 101 102 if (a > 255 || b > 255 || c > 255 || d > 255) 103 goto bad_address; 104 105 cell->vl_addrs[cell->vl_naddrs++].s_addr = 106 htonl((a << 24) | (b << 16) | (c << 8) | d); 107 108 } while (cell->vl_naddrs < AFS_CELL_MAX_ADDRS && (_vllist = next)); 109 110 /* create a key to represent an anonymous user */ 111 memcpy(keyname, "afs@", 4); 112 dp = keyname + 4; 113 cp = cell->name; 114 do { 115 *dp++ = toupper(*cp); 116 } while (*cp++); 117 118 key = rxrpc_get_null_key(keyname); 119 if (IS_ERR(key)) { 120 _debug("no key"); 121 ret = PTR_ERR(key); 122 goto error; 123 } 124 cell->anonymous_key = key; 125 126 _debug("anon key %p{%x}", 127 cell->anonymous_key, key_serial(cell->anonymous_key)); 128 129 _leave(" = %p", cell); 130 return cell; 131 132 bad_address: 133 printk(KERN_ERR "kAFS: bad VL server IP address\n"); 134 ret = -EINVAL; 135 error: 136 key_put(cell->anonymous_key); 137 kfree(dvllist); 138 kfree(cell); 139 _leave(" = %d", ret); 140 return ERR_PTR(ret); 141 } 142 143 /* 144 * afs_cell_crate() - create a cell record 145 * @name: is the name of the cell. 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. 149 */ 150 struct afs_cell *afs_cell_create(const char *name, unsigned namesz, 151 char *vllist, bool retref) 152 { 153 struct afs_cell *cell; 154 int ret; 155 156 _enter("%*.*s,%s", namesz, namesz, name ?: "", vllist); 157 158 down_write(&afs_cells_sem); 159 read_lock(&afs_cells_lock); 160 list_for_each_entry(cell, &afs_cells, link) { 161 if (strncasecmp(cell->name, name, namesz) == 0) 162 goto duplicate_name; 163 } 164 read_unlock(&afs_cells_lock); 165 166 cell = afs_cell_alloc(name, namesz, vllist); 167 if (IS_ERR(cell)) { 168 _leave(" = %ld", PTR_ERR(cell)); 169 up_write(&afs_cells_sem); 170 return cell; 171 } 172 173 /* add a proc directory for this cell */ 174 ret = afs_proc_cell_setup(cell); 175 if (ret < 0) 176 goto error; 177 178 #ifdef CONFIG_AFS_FSCACHE 179 /* put it up for caching (this never returns an error) */ 180 cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index, 181 &afs_cell_cache_index_def, 182 cell, true); 183 #endif 184 185 /* add to the cell lists */ 186 write_lock(&afs_cells_lock); 187 list_add_tail(&cell->link, &afs_cells); 188 write_unlock(&afs_cells_lock); 189 190 down_write(&afs_proc_cells_sem); 191 list_add_tail(&cell->proc_link, &afs_proc_cells); 192 up_write(&afs_proc_cells_sem); 193 up_write(&afs_cells_sem); 194 195 _leave(" = %p", cell); 196 return cell; 197 198 error: 199 up_write(&afs_cells_sem); 200 key_put(cell->anonymous_key); 201 kfree(cell); 202 _leave(" = %d", ret); 203 return ERR_PTR(ret); 204 205 duplicate_name: 206 if (retref && !IS_ERR(cell)) 207 afs_get_cell(cell); 208 209 read_unlock(&afs_cells_lock); 210 up_write(&afs_cells_sem); 211 212 if (retref) { 213 _leave(" = %p", cell); 214 return cell; 215 } 216 217 _leave(" = -EEXIST"); 218 return ERR_PTR(-EEXIST); 219 } 220 221 /* 222 * set the root cell information 223 * - can be called with a module parameter string 224 * - can be called from a write to /proc/fs/afs/rootcell 225 */ 226 int afs_cell_init(char *rootcell) 227 { 228 struct afs_cell *old_root, *new_root; 229 char *cp; 230 231 _enter(""); 232 233 if (!rootcell) { 234 /* module is loaded with no parameters, or built statically. 235 * - in the future we might initialize cell DB here. 236 */ 237 _leave(" = 0 [no root]"); 238 return 0; 239 } 240 241 cp = strchr(rootcell, ':'); 242 if (!cp) 243 _debug("kAFS: no VL server IP addresses specified"); 244 else 245 *cp++ = 0; 246 247 /* allocate a cell record for the root cell */ 248 new_root = afs_cell_create(rootcell, strlen(rootcell), cp, false); 249 if (IS_ERR(new_root)) { 250 _leave(" = %ld", PTR_ERR(new_root)); 251 return PTR_ERR(new_root); 252 } 253 254 /* install the new cell */ 255 write_lock(&afs_cells_lock); 256 old_root = afs_cell_root; 257 afs_cell_root = new_root; 258 write_unlock(&afs_cells_lock); 259 afs_put_cell(old_root); 260 261 _leave(" = 0"); 262 return 0; 263 } 264 265 /* 266 * lookup a cell record 267 */ 268 struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz, 269 bool dns_cell) 270 { 271 struct afs_cell *cell; 272 273 _enter("\"%*.*s\",", namesz, namesz, name ?: ""); 274 275 down_read(&afs_cells_sem); 276 read_lock(&afs_cells_lock); 277 278 if (name) { 279 /* if the cell was named, look for it in the cell record list */ 280 list_for_each_entry(cell, &afs_cells, link) { 281 if (strncmp(cell->name, name, namesz) == 0) { 282 afs_get_cell(cell); 283 goto found; 284 } 285 } 286 cell = ERR_PTR(-ENOENT); 287 if (dns_cell) 288 goto create_cell; 289 found: 290 ; 291 } else { 292 cell = afs_cell_root; 293 if (!cell) { 294 /* this should not happen unless user tries to mount 295 * when root cell is not set. Return an impossibly 296 * bizarre errno to alert the user. Things like 297 * ENOENT might be "more appropriate" but they happen 298 * for other reasons. 299 */ 300 cell = ERR_PTR(-EDESTADDRREQ); 301 } else { 302 afs_get_cell(cell); 303 } 304 305 } 306 307 read_unlock(&afs_cells_lock); 308 up_read(&afs_cells_sem); 309 _leave(" = %p", cell); 310 return cell; 311 312 create_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; 320 } 321 322 #if 0 323 /* 324 * try and get a cell record 325 */ 326 struct afs_cell *afs_get_cell_maybe(struct afs_cell *cell) 327 { 328 write_lock(&afs_cells_lock); 329 330 if (cell && !list_empty(&cell->link)) 331 afs_get_cell(cell); 332 else 333 cell = NULL; 334 335 write_unlock(&afs_cells_lock); 336 return cell; 337 } 338 #endif /* 0 */ 339 340 /* 341 * destroy a cell record 342 */ 343 void afs_put_cell(struct afs_cell *cell) 344 { 345 if (!cell) 346 return; 347 348 _enter("%p{%d,%s}", cell, atomic_read(&cell->usage), cell->name); 349 350 ASSERTCMP(atomic_read(&cell->usage), >, 0); 351 352 /* to prevent a race, the decrement and the dequeue must be effectively 353 * atomic */ 354 write_lock(&afs_cells_lock); 355 356 if (likely(!atomic_dec_and_test(&cell->usage))) { 357 write_unlock(&afs_cells_lock); 358 _leave(""); 359 return; 360 } 361 362 ASSERT(list_empty(&cell->servers)); 363 ASSERT(list_empty(&cell->vl_list)); 364 365 write_unlock(&afs_cells_lock); 366 367 wake_up(&afs_cells_freeable_wq); 368 369 _leave(" [unused]"); 370 } 371 372 /* 373 * destroy a cell record 374 * - must be called with the afs_cells_sem write-locked 375 * - cell->link should have been broken by the caller 376 */ 377 static void afs_cell_destroy(struct afs_cell *cell) 378 { 379 _enter("%p{%d,%s}", cell, atomic_read(&cell->usage), cell->name); 380 381 ASSERTCMP(atomic_read(&cell->usage), >=, 0); 382 ASSERT(list_empty(&cell->link)); 383 384 /* wait for everyone to stop using the cell */ 385 if (atomic_read(&cell->usage) > 0) { 386 DECLARE_WAITQUEUE(myself, current); 387 388 _debug("wait for cell %s", cell->name); 389 set_current_state(TASK_UNINTERRUPTIBLE); 390 add_wait_queue(&afs_cells_freeable_wq, &myself); 391 392 while (atomic_read(&cell->usage) > 0) { 393 schedule(); 394 set_current_state(TASK_UNINTERRUPTIBLE); 395 } 396 397 remove_wait_queue(&afs_cells_freeable_wq, &myself); 398 set_current_state(TASK_RUNNING); 399 } 400 401 _debug("cell dead"); 402 ASSERTCMP(atomic_read(&cell->usage), ==, 0); 403 ASSERT(list_empty(&cell->servers)); 404 ASSERT(list_empty(&cell->vl_list)); 405 406 afs_proc_cell_remove(cell); 407 408 down_write(&afs_proc_cells_sem); 409 list_del_init(&cell->proc_link); 410 up_write(&afs_proc_cells_sem); 411 412 #ifdef CONFIG_AFS_FSCACHE 413 fscache_relinquish_cookie(cell->cache, 0); 414 #endif 415 key_put(cell->anonymous_key); 416 kfree(cell); 417 418 _leave(" [destroyed]"); 419 } 420 421 /* 422 * purge in-memory cell database on module unload or afs_init() failure 423 * - the timeout daemon is stopped before calling this 424 */ 425 void afs_cell_purge(void) 426 { 427 struct afs_cell *cell; 428 429 _enter(""); 430 431 afs_put_cell(afs_cell_root); 432 433 down_write(&afs_cells_sem); 434 435 while (!list_empty(&afs_cells)) { 436 cell = NULL; 437 438 /* remove the next cell from the front of the list */ 439 write_lock(&afs_cells_lock); 440 441 if (!list_empty(&afs_cells)) { 442 cell = list_entry(afs_cells.next, 443 struct afs_cell, link); 444 list_del_init(&cell->link); 445 } 446 447 write_unlock(&afs_cells_lock); 448 449 if (cell) { 450 _debug("PURGING CELL %s (%d)", 451 cell->name, atomic_read(&cell->usage)); 452 453 /* now the cell should be left with no references */ 454 afs_cell_destroy(cell); 455 } 456 } 457 458 up_write(&afs_cells_sem); 459 _leave(""); 460 } 461