1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* AFS cell and server record management 3 * 4 * Copyright (C) 2002, 2017 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/slab.h> 9 #include <linux/key.h> 10 #include <linux/ctype.h> 11 #include <linux/dns_resolver.h> 12 #include <linux/sched.h> 13 #include <linux/inet.h> 14 #include <linux/namei.h> 15 #include <keys/rxrpc-type.h> 16 #include "internal.h" 17 18 static unsigned __read_mostly afs_cell_gc_delay = 10; 19 static unsigned __read_mostly afs_cell_min_ttl = 10 * 60; 20 static unsigned __read_mostly afs_cell_max_ttl = 24 * 60 * 60; 21 static atomic_t cell_debug_id; 22 23 static void afs_queue_cell_manager(struct afs_net *); 24 static void afs_manage_cell_work(struct work_struct *); 25 26 static void afs_dec_cells_outstanding(struct afs_net *net) 27 { 28 if (atomic_dec_and_test(&net->cells_outstanding)) 29 wake_up_var(&net->cells_outstanding); 30 } 31 32 /* 33 * Set the cell timer to fire after a given delay, assuming it's not already 34 * set for an earlier time. 35 */ 36 static void afs_set_cell_timer(struct afs_net *net, time64_t delay) 37 { 38 if (net->live) { 39 atomic_inc(&net->cells_outstanding); 40 if (timer_reduce(&net->cells_timer, jiffies + delay * HZ)) 41 afs_dec_cells_outstanding(net); 42 } else { 43 afs_queue_cell_manager(net); 44 } 45 } 46 47 /* 48 * Look up and get an activation reference on a cell record. The caller must 49 * hold net->cells_lock at least read-locked. 50 */ 51 static struct afs_cell *afs_find_cell_locked(struct afs_net *net, 52 const char *name, unsigned int namesz, 53 enum afs_cell_trace reason) 54 { 55 struct afs_cell *cell = NULL; 56 struct rb_node *p; 57 int n; 58 59 _enter("%*.*s", namesz, namesz, name); 60 61 if (name && namesz == 0) 62 return ERR_PTR(-EINVAL); 63 if (namesz > AFS_MAXCELLNAME) 64 return ERR_PTR(-ENAMETOOLONG); 65 66 if (!name) { 67 cell = net->ws_cell; 68 if (!cell) 69 return ERR_PTR(-EDESTADDRREQ); 70 goto found; 71 } 72 73 p = net->cells.rb_node; 74 while (p) { 75 cell = rb_entry(p, struct afs_cell, net_node); 76 77 n = strncasecmp(cell->name, name, 78 min_t(size_t, cell->name_len, namesz)); 79 if (n == 0) 80 n = cell->name_len - namesz; 81 if (n < 0) 82 p = p->rb_left; 83 else if (n > 0) 84 p = p->rb_right; 85 else 86 goto found; 87 } 88 89 return ERR_PTR(-ENOENT); 90 91 found: 92 return afs_use_cell(cell, reason); 93 } 94 95 /* 96 * Look up and get an activation reference on a cell record. 97 */ 98 struct afs_cell *afs_find_cell(struct afs_net *net, 99 const char *name, unsigned int namesz, 100 enum afs_cell_trace reason) 101 { 102 struct afs_cell *cell; 103 104 down_read(&net->cells_lock); 105 cell = afs_find_cell_locked(net, name, namesz, reason); 106 up_read(&net->cells_lock); 107 return cell; 108 } 109 110 /* 111 * Set up a cell record and fill in its name, VL server address list and 112 * allocate an anonymous key 113 */ 114 static struct afs_cell *afs_alloc_cell(struct afs_net *net, 115 const char *name, unsigned int namelen, 116 const char *addresses) 117 { 118 struct afs_vlserver_list *vllist; 119 struct afs_cell *cell; 120 int i, ret; 121 122 ASSERT(name); 123 if (namelen == 0) 124 return ERR_PTR(-EINVAL); 125 if (namelen > AFS_MAXCELLNAME) { 126 _leave(" = -ENAMETOOLONG"); 127 return ERR_PTR(-ENAMETOOLONG); 128 } 129 130 /* Prohibit cell names that contain unprintable chars, '/' and '@' or 131 * that begin with a dot. This also precludes "@cell". 132 */ 133 if (name[0] == '.') 134 return ERR_PTR(-EINVAL); 135 for (i = 0; i < namelen; i++) { 136 char ch = name[i]; 137 if (!isprint(ch) || ch == '/' || ch == '@') 138 return ERR_PTR(-EINVAL); 139 } 140 141 _enter("%*.*s,%s", namelen, namelen, name, addresses); 142 143 cell = kzalloc(sizeof(struct afs_cell), GFP_KERNEL); 144 if (!cell) { 145 _leave(" = -ENOMEM"); 146 return ERR_PTR(-ENOMEM); 147 } 148 149 cell->name = kmalloc(namelen + 1, GFP_KERNEL); 150 if (!cell->name) { 151 kfree(cell); 152 return ERR_PTR(-ENOMEM); 153 } 154 155 cell->net = net; 156 cell->name_len = namelen; 157 for (i = 0; i < namelen; i++) 158 cell->name[i] = tolower(name[i]); 159 cell->name[i] = 0; 160 161 refcount_set(&cell->ref, 1); 162 atomic_set(&cell->active, 0); 163 INIT_WORK(&cell->manager, afs_manage_cell_work); 164 cell->volumes = RB_ROOT; 165 INIT_HLIST_HEAD(&cell->proc_volumes); 166 seqlock_init(&cell->volume_lock); 167 cell->fs_servers = RB_ROOT; 168 seqlock_init(&cell->fs_lock); 169 INIT_LIST_HEAD(&cell->fs_open_mmaps); 170 init_rwsem(&cell->fs_open_mmaps_lock); 171 rwlock_init(&cell->vl_servers_lock); 172 cell->flags = (1 << AFS_CELL_FL_CHECK_ALIAS); 173 174 /* Provide a VL server list, filling it in if we were given a list of 175 * addresses to use. 176 */ 177 if (addresses) { 178 vllist = afs_parse_text_addrs(net, 179 addresses, strlen(addresses), ':', 180 VL_SERVICE, AFS_VL_PORT); 181 if (IS_ERR(vllist)) { 182 ret = PTR_ERR(vllist); 183 goto parse_failed; 184 } 185 186 vllist->source = DNS_RECORD_FROM_CONFIG; 187 vllist->status = DNS_LOOKUP_NOT_DONE; 188 cell->dns_expiry = TIME64_MAX; 189 } else { 190 ret = -ENOMEM; 191 vllist = afs_alloc_vlserver_list(0); 192 if (!vllist) 193 goto error; 194 vllist->source = DNS_RECORD_UNAVAILABLE; 195 vllist->status = DNS_LOOKUP_NOT_DONE; 196 cell->dns_expiry = ktime_get_real_seconds(); 197 } 198 199 rcu_assign_pointer(cell->vl_servers, vllist); 200 201 cell->dns_source = vllist->source; 202 cell->dns_status = vllist->status; 203 smp_store_release(&cell->dns_lookup_count, 1); /* vs source/status */ 204 atomic_inc(&net->cells_outstanding); 205 cell->debug_id = atomic_inc_return(&cell_debug_id); 206 trace_afs_cell(cell->debug_id, 1, 0, afs_cell_trace_alloc); 207 208 _leave(" = %p", cell); 209 return cell; 210 211 parse_failed: 212 if (ret == -EINVAL) 213 printk(KERN_ERR "kAFS: bad VL server IP address\n"); 214 error: 215 kfree(cell->name); 216 kfree(cell); 217 _leave(" = %d", ret); 218 return ERR_PTR(ret); 219 } 220 221 /* 222 * afs_lookup_cell - Look up or create a cell record. 223 * @net: The network namespace 224 * @name: The name of the cell. 225 * @namesz: The strlen of the cell name. 226 * @vllist: A colon/comma separated list of numeric IP addresses or NULL. 227 * @excl: T if an error should be given if the cell name already exists. 228 * 229 * Look up a cell record by name and query the DNS for VL server addresses if 230 * needed. Note that that actual DNS query is punted off to the manager thread 231 * so that this function can return immediately if interrupted whilst allowing 232 * cell records to be shared even if not yet fully constructed. 233 */ 234 struct afs_cell *afs_lookup_cell(struct afs_net *net, 235 const char *name, unsigned int namesz, 236 const char *vllist, bool excl) 237 { 238 struct afs_cell *cell, *candidate, *cursor; 239 struct rb_node *parent, **pp; 240 enum afs_cell_state state; 241 int ret, n; 242 243 _enter("%s,%s", name, vllist); 244 245 if (!excl) { 246 cell = afs_find_cell(net, name, namesz, afs_cell_trace_use_lookup); 247 if (!IS_ERR(cell)) 248 goto wait_for_cell; 249 } 250 251 /* Assume we're probably going to create a cell and preallocate and 252 * mostly set up a candidate record. We can then use this to stash the 253 * name, the net namespace and VL server addresses. 254 * 255 * We also want to do this before we hold any locks as it may involve 256 * upcalling to userspace to make DNS queries. 257 */ 258 candidate = afs_alloc_cell(net, name, namesz, vllist); 259 if (IS_ERR(candidate)) { 260 _leave(" = %ld", PTR_ERR(candidate)); 261 return candidate; 262 } 263 264 /* Find the insertion point and check to see if someone else added a 265 * cell whilst we were allocating. 266 */ 267 down_write(&net->cells_lock); 268 269 pp = &net->cells.rb_node; 270 parent = NULL; 271 while (*pp) { 272 parent = *pp; 273 cursor = rb_entry(parent, struct afs_cell, net_node); 274 275 n = strncasecmp(cursor->name, name, 276 min_t(size_t, cursor->name_len, namesz)); 277 if (n == 0) 278 n = cursor->name_len - namesz; 279 if (n < 0) 280 pp = &(*pp)->rb_left; 281 else if (n > 0) 282 pp = &(*pp)->rb_right; 283 else 284 goto cell_already_exists; 285 } 286 287 cell = candidate; 288 candidate = NULL; 289 atomic_set(&cell->active, 2); 290 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), 2, afs_cell_trace_insert); 291 rb_link_node_rcu(&cell->net_node, parent, pp); 292 rb_insert_color(&cell->net_node, &net->cells); 293 up_write(&net->cells_lock); 294 295 afs_queue_cell(cell, afs_cell_trace_get_queue_new); 296 297 wait_for_cell: 298 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), atomic_read(&cell->active), 299 afs_cell_trace_wait); 300 _debug("wait_for_cell"); 301 wait_var_event(&cell->state, 302 ({ 303 state = smp_load_acquire(&cell->state); /* vs error */ 304 state == AFS_CELL_ACTIVE || state == AFS_CELL_REMOVED; 305 })); 306 307 /* Check the state obtained from the wait check. */ 308 if (state == AFS_CELL_REMOVED) { 309 ret = cell->error; 310 goto error; 311 } 312 313 _leave(" = %p [cell]", cell); 314 return cell; 315 316 cell_already_exists: 317 _debug("cell exists"); 318 cell = cursor; 319 if (excl) { 320 ret = -EEXIST; 321 } else { 322 afs_use_cell(cursor, afs_cell_trace_use_lookup); 323 ret = 0; 324 } 325 up_write(&net->cells_lock); 326 if (candidate) 327 afs_put_cell(candidate, afs_cell_trace_put_candidate); 328 if (ret == 0) 329 goto wait_for_cell; 330 goto error_noput; 331 error: 332 afs_unuse_cell(net, cell, afs_cell_trace_unuse_lookup); 333 error_noput: 334 _leave(" = %d [error]", ret); 335 return ERR_PTR(ret); 336 } 337 338 /* 339 * set the root cell information 340 * - can be called with a module parameter string 341 * - can be called from a write to /proc/fs/afs/rootcell 342 */ 343 int afs_cell_init(struct afs_net *net, const char *rootcell) 344 { 345 struct afs_cell *old_root, *new_root; 346 const char *cp, *vllist; 347 size_t len; 348 349 _enter(""); 350 351 if (!rootcell) { 352 /* module is loaded with no parameters, or built statically. 353 * - in the future we might initialize cell DB here. 354 */ 355 _leave(" = 0 [no root]"); 356 return 0; 357 } 358 359 cp = strchr(rootcell, ':'); 360 if (!cp) { 361 _debug("kAFS: no VL server IP addresses specified"); 362 vllist = NULL; 363 len = strlen(rootcell); 364 } else { 365 vllist = cp + 1; 366 len = cp - rootcell; 367 } 368 369 /* allocate a cell record for the root cell */ 370 new_root = afs_lookup_cell(net, rootcell, len, vllist, false); 371 if (IS_ERR(new_root)) { 372 _leave(" = %ld", PTR_ERR(new_root)); 373 return PTR_ERR(new_root); 374 } 375 376 if (!test_and_set_bit(AFS_CELL_FL_NO_GC, &new_root->flags)) 377 afs_use_cell(new_root, afs_cell_trace_use_pin); 378 379 /* install the new cell */ 380 down_write(&net->cells_lock); 381 afs_see_cell(new_root, afs_cell_trace_see_ws); 382 old_root = net->ws_cell; 383 net->ws_cell = new_root; 384 up_write(&net->cells_lock); 385 386 afs_unuse_cell(net, old_root, afs_cell_trace_unuse_ws); 387 _leave(" = 0"); 388 return 0; 389 } 390 391 /* 392 * Update a cell's VL server address list from the DNS. 393 */ 394 static int afs_update_cell(struct afs_cell *cell) 395 { 396 struct afs_vlserver_list *vllist, *old = NULL, *p; 397 unsigned int min_ttl = READ_ONCE(afs_cell_min_ttl); 398 unsigned int max_ttl = READ_ONCE(afs_cell_max_ttl); 399 time64_t now, expiry = 0; 400 int ret = 0; 401 402 _enter("%s", cell->name); 403 404 vllist = afs_dns_query(cell, &expiry); 405 if (IS_ERR(vllist)) { 406 ret = PTR_ERR(vllist); 407 408 _debug("%s: fail %d", cell->name, ret); 409 if (ret == -ENOMEM) 410 goto out_wake; 411 412 vllist = afs_alloc_vlserver_list(0); 413 if (!vllist) { 414 if (ret >= 0) 415 ret = -ENOMEM; 416 goto out_wake; 417 } 418 419 switch (ret) { 420 case -ENODATA: 421 case -EDESTADDRREQ: 422 vllist->status = DNS_LOOKUP_GOT_NOT_FOUND; 423 break; 424 case -EAGAIN: 425 case -ECONNREFUSED: 426 vllist->status = DNS_LOOKUP_GOT_TEMP_FAILURE; 427 break; 428 default: 429 vllist->status = DNS_LOOKUP_GOT_LOCAL_FAILURE; 430 break; 431 } 432 } 433 434 _debug("%s: got list %d %d", cell->name, vllist->source, vllist->status); 435 cell->dns_status = vllist->status; 436 437 now = ktime_get_real_seconds(); 438 if (min_ttl > max_ttl) 439 max_ttl = min_ttl; 440 if (expiry < now + min_ttl) 441 expiry = now + min_ttl; 442 else if (expiry > now + max_ttl) 443 expiry = now + max_ttl; 444 445 _debug("%s: status %d", cell->name, vllist->status); 446 if (vllist->source == DNS_RECORD_UNAVAILABLE) { 447 switch (vllist->status) { 448 case DNS_LOOKUP_GOT_NOT_FOUND: 449 /* The DNS said that the cell does not exist or there 450 * weren't any addresses to be had. 451 */ 452 cell->dns_expiry = expiry; 453 break; 454 455 case DNS_LOOKUP_BAD: 456 case DNS_LOOKUP_GOT_LOCAL_FAILURE: 457 case DNS_LOOKUP_GOT_TEMP_FAILURE: 458 case DNS_LOOKUP_GOT_NS_FAILURE: 459 default: 460 cell->dns_expiry = now + 10; 461 break; 462 } 463 } else { 464 cell->dns_expiry = expiry; 465 } 466 467 /* Replace the VL server list if the new record has servers or the old 468 * record doesn't. 469 */ 470 write_lock(&cell->vl_servers_lock); 471 p = rcu_dereference_protected(cell->vl_servers, true); 472 if (vllist->nr_servers > 0 || p->nr_servers == 0) { 473 rcu_assign_pointer(cell->vl_servers, vllist); 474 cell->dns_source = vllist->source; 475 old = p; 476 } 477 write_unlock(&cell->vl_servers_lock); 478 afs_put_vlserverlist(cell->net, old); 479 480 out_wake: 481 smp_store_release(&cell->dns_lookup_count, 482 cell->dns_lookup_count + 1); /* vs source/status */ 483 wake_up_var(&cell->dns_lookup_count); 484 _leave(" = %d", ret); 485 return ret; 486 } 487 488 /* 489 * Destroy a cell record 490 */ 491 static void afs_cell_destroy(struct rcu_head *rcu) 492 { 493 struct afs_cell *cell = container_of(rcu, struct afs_cell, rcu); 494 struct afs_net *net = cell->net; 495 int r; 496 497 _enter("%p{%s}", cell, cell->name); 498 499 r = refcount_read(&cell->ref); 500 ASSERTCMP(r, ==, 0); 501 trace_afs_cell(cell->debug_id, r, atomic_read(&cell->active), afs_cell_trace_free); 502 503 afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers)); 504 afs_unuse_cell(net, cell->alias_of, afs_cell_trace_unuse_alias); 505 key_put(cell->anonymous_key); 506 kfree(cell->name); 507 kfree(cell); 508 509 afs_dec_cells_outstanding(net); 510 _leave(" [destroyed]"); 511 } 512 513 /* 514 * Queue the cell manager. 515 */ 516 static void afs_queue_cell_manager(struct afs_net *net) 517 { 518 int outstanding = atomic_inc_return(&net->cells_outstanding); 519 520 _enter("%d", outstanding); 521 522 if (!queue_work(afs_wq, &net->cells_manager)) 523 afs_dec_cells_outstanding(net); 524 } 525 526 /* 527 * Cell management timer. We have an increment on cells_outstanding that we 528 * need to pass along to the work item. 529 */ 530 void afs_cells_timer(struct timer_list *timer) 531 { 532 struct afs_net *net = container_of(timer, struct afs_net, cells_timer); 533 534 _enter(""); 535 if (!queue_work(afs_wq, &net->cells_manager)) 536 afs_dec_cells_outstanding(net); 537 } 538 539 /* 540 * Get a reference on a cell record. 541 */ 542 struct afs_cell *afs_get_cell(struct afs_cell *cell, enum afs_cell_trace reason) 543 { 544 int r; 545 546 __refcount_inc(&cell->ref, &r); 547 trace_afs_cell(cell->debug_id, r + 1, atomic_read(&cell->active), reason); 548 return cell; 549 } 550 551 /* 552 * Drop a reference on a cell record. 553 */ 554 void afs_put_cell(struct afs_cell *cell, enum afs_cell_trace reason) 555 { 556 if (cell) { 557 unsigned int debug_id = cell->debug_id; 558 unsigned int a; 559 bool zero; 560 int r; 561 562 a = atomic_read(&cell->active); 563 zero = __refcount_dec_and_test(&cell->ref, &r); 564 trace_afs_cell(debug_id, r - 1, a, reason); 565 if (zero) { 566 a = atomic_read(&cell->active); 567 WARN(a != 0, "Cell active count %u > 0\n", a); 568 call_rcu(&cell->rcu, afs_cell_destroy); 569 } 570 } 571 } 572 573 /* 574 * Note a cell becoming more active. 575 */ 576 struct afs_cell *afs_use_cell(struct afs_cell *cell, enum afs_cell_trace reason) 577 { 578 int r, a; 579 580 r = refcount_read(&cell->ref); 581 WARN_ON(r == 0); 582 a = atomic_inc_return(&cell->active); 583 trace_afs_cell(cell->debug_id, r, a, reason); 584 return cell; 585 } 586 587 /* 588 * Record a cell becoming less active. When the active counter reaches 1, it 589 * is scheduled for destruction, but may get reactivated. 590 */ 591 void afs_unuse_cell(struct afs_net *net, struct afs_cell *cell, enum afs_cell_trace reason) 592 { 593 unsigned int debug_id; 594 time64_t now, expire_delay; 595 int r, a; 596 597 if (!cell) 598 return; 599 600 _enter("%s", cell->name); 601 602 now = ktime_get_real_seconds(); 603 cell->last_inactive = now; 604 expire_delay = 0; 605 if (cell->vl_servers->nr_servers) 606 expire_delay = afs_cell_gc_delay; 607 608 debug_id = cell->debug_id; 609 r = refcount_read(&cell->ref); 610 a = atomic_dec_return(&cell->active); 611 trace_afs_cell(debug_id, r, a, reason); 612 WARN_ON(a == 0); 613 if (a == 1) 614 /* 'cell' may now be garbage collected. */ 615 afs_set_cell_timer(net, expire_delay); 616 } 617 618 /* 619 * Note that a cell has been seen. 620 */ 621 void afs_see_cell(struct afs_cell *cell, enum afs_cell_trace reason) 622 { 623 int r, a; 624 625 r = refcount_read(&cell->ref); 626 a = atomic_read(&cell->active); 627 trace_afs_cell(cell->debug_id, r, a, reason); 628 } 629 630 /* 631 * Queue a cell for management, giving the workqueue a ref to hold. 632 */ 633 void afs_queue_cell(struct afs_cell *cell, enum afs_cell_trace reason) 634 { 635 afs_get_cell(cell, reason); 636 if (!queue_work(afs_wq, &cell->manager)) 637 afs_put_cell(cell, afs_cell_trace_put_queue_fail); 638 } 639 640 /* 641 * Allocate a key to use as a placeholder for anonymous user security. 642 */ 643 static int afs_alloc_anon_key(struct afs_cell *cell) 644 { 645 struct key *key; 646 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp; 647 648 /* Create a key to represent an anonymous user. */ 649 memcpy(keyname, "afs@", 4); 650 dp = keyname + 4; 651 cp = cell->name; 652 do { 653 *dp++ = tolower(*cp); 654 } while (*cp++); 655 656 key = rxrpc_get_null_key(keyname); 657 if (IS_ERR(key)) 658 return PTR_ERR(key); 659 660 cell->anonymous_key = key; 661 662 _debug("anon key %p{%x}", 663 cell->anonymous_key, key_serial(cell->anonymous_key)); 664 return 0; 665 } 666 667 /* 668 * Activate a cell. 669 */ 670 static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell) 671 { 672 struct hlist_node **p; 673 struct afs_cell *pcell; 674 int ret; 675 676 if (!cell->anonymous_key) { 677 ret = afs_alloc_anon_key(cell); 678 if (ret < 0) 679 return ret; 680 } 681 682 ret = afs_proc_cell_setup(cell); 683 if (ret < 0) 684 return ret; 685 686 mutex_lock(&net->proc_cells_lock); 687 for (p = &net->proc_cells.first; *p; p = &(*p)->next) { 688 pcell = hlist_entry(*p, struct afs_cell, proc_link); 689 if (strcmp(cell->name, pcell->name) < 0) 690 break; 691 } 692 693 cell->proc_link.pprev = p; 694 cell->proc_link.next = *p; 695 rcu_assign_pointer(*p, &cell->proc_link.next); 696 if (cell->proc_link.next) 697 cell->proc_link.next->pprev = &cell->proc_link.next; 698 699 afs_dynroot_mkdir(net, cell); 700 mutex_unlock(&net->proc_cells_lock); 701 return 0; 702 } 703 704 /* 705 * Deactivate a cell. 706 */ 707 static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell) 708 { 709 _enter("%s", cell->name); 710 711 afs_proc_cell_remove(cell); 712 713 mutex_lock(&net->proc_cells_lock); 714 hlist_del_rcu(&cell->proc_link); 715 afs_dynroot_rmdir(net, cell); 716 mutex_unlock(&net->proc_cells_lock); 717 718 _leave(""); 719 } 720 721 /* 722 * Manage a cell record, initialising and destroying it, maintaining its DNS 723 * records. 724 */ 725 static void afs_manage_cell(struct afs_cell *cell) 726 { 727 struct afs_net *net = cell->net; 728 int ret, active; 729 730 _enter("%s", cell->name); 731 732 again: 733 _debug("state %u", cell->state); 734 switch (cell->state) { 735 case AFS_CELL_INACTIVE: 736 case AFS_CELL_FAILED: 737 down_write(&net->cells_lock); 738 active = 1; 739 if (atomic_try_cmpxchg_relaxed(&cell->active, &active, 0)) { 740 rb_erase(&cell->net_node, &net->cells); 741 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), 0, 742 afs_cell_trace_unuse_delete); 743 smp_store_release(&cell->state, AFS_CELL_REMOVED); 744 } 745 up_write(&net->cells_lock); 746 if (cell->state == AFS_CELL_REMOVED) { 747 wake_up_var(&cell->state); 748 goto final_destruction; 749 } 750 if (cell->state == AFS_CELL_FAILED) 751 goto done; 752 smp_store_release(&cell->state, AFS_CELL_UNSET); 753 wake_up_var(&cell->state); 754 goto again; 755 756 case AFS_CELL_UNSET: 757 smp_store_release(&cell->state, AFS_CELL_ACTIVATING); 758 wake_up_var(&cell->state); 759 goto again; 760 761 case AFS_CELL_ACTIVATING: 762 ret = afs_activate_cell(net, cell); 763 if (ret < 0) 764 goto activation_failed; 765 766 smp_store_release(&cell->state, AFS_CELL_ACTIVE); 767 wake_up_var(&cell->state); 768 goto again; 769 770 case AFS_CELL_ACTIVE: 771 if (atomic_read(&cell->active) > 1) { 772 if (test_and_clear_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags)) { 773 ret = afs_update_cell(cell); 774 if (ret < 0) 775 cell->error = ret; 776 } 777 goto done; 778 } 779 smp_store_release(&cell->state, AFS_CELL_DEACTIVATING); 780 wake_up_var(&cell->state); 781 goto again; 782 783 case AFS_CELL_DEACTIVATING: 784 if (atomic_read(&cell->active) > 1) 785 goto reverse_deactivation; 786 afs_deactivate_cell(net, cell); 787 smp_store_release(&cell->state, AFS_CELL_INACTIVE); 788 wake_up_var(&cell->state); 789 goto again; 790 791 case AFS_CELL_REMOVED: 792 goto done; 793 794 default: 795 break; 796 } 797 _debug("bad state %u", cell->state); 798 BUG(); /* Unhandled state */ 799 800 activation_failed: 801 cell->error = ret; 802 afs_deactivate_cell(net, cell); 803 804 smp_store_release(&cell->state, AFS_CELL_FAILED); /* vs error */ 805 wake_up_var(&cell->state); 806 goto again; 807 808 reverse_deactivation: 809 smp_store_release(&cell->state, AFS_CELL_ACTIVE); 810 wake_up_var(&cell->state); 811 _leave(" [deact->act]"); 812 return; 813 814 done: 815 _leave(" [done %u]", cell->state); 816 return; 817 818 final_destruction: 819 /* The root volume is pinning the cell */ 820 afs_put_volume(cell->net, cell->root_volume, afs_volume_trace_put_cell_root); 821 cell->root_volume = NULL; 822 afs_put_cell(cell, afs_cell_trace_put_destroy); 823 } 824 825 static void afs_manage_cell_work(struct work_struct *work) 826 { 827 struct afs_cell *cell = container_of(work, struct afs_cell, manager); 828 829 afs_manage_cell(cell); 830 afs_put_cell(cell, afs_cell_trace_put_queue_work); 831 } 832 833 /* 834 * Manage the records of cells known to a network namespace. This includes 835 * updating the DNS records and garbage collecting unused cells that were 836 * automatically added. 837 * 838 * Note that constructed cell records may only be removed from net->cells by 839 * this work item, so it is safe for this work item to stash a cursor pointing 840 * into the tree and then return to caller (provided it skips cells that are 841 * still under construction). 842 * 843 * Note also that we were given an increment on net->cells_outstanding by 844 * whoever queued us that we need to deal with before returning. 845 */ 846 void afs_manage_cells(struct work_struct *work) 847 { 848 struct afs_net *net = container_of(work, struct afs_net, cells_manager); 849 struct rb_node *cursor; 850 time64_t now = ktime_get_real_seconds(), next_manage = TIME64_MAX; 851 bool purging = !net->live; 852 853 _enter(""); 854 855 /* Trawl the cell database looking for cells that have expired from 856 * lack of use and cells whose DNS results have expired and dispatch 857 * their managers. 858 */ 859 down_read(&net->cells_lock); 860 861 for (cursor = rb_first(&net->cells); cursor; cursor = rb_next(cursor)) { 862 struct afs_cell *cell = 863 rb_entry(cursor, struct afs_cell, net_node); 864 unsigned active; 865 bool sched_cell = false; 866 867 active = atomic_read(&cell->active); 868 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), 869 active, afs_cell_trace_manage); 870 871 ASSERTCMP(active, >=, 1); 872 873 if (purging) { 874 if (test_and_clear_bit(AFS_CELL_FL_NO_GC, &cell->flags)) { 875 active = atomic_dec_return(&cell->active); 876 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), 877 active, afs_cell_trace_unuse_pin); 878 } 879 } 880 881 if (active == 1) { 882 struct afs_vlserver_list *vllist; 883 time64_t expire_at = cell->last_inactive; 884 885 read_lock(&cell->vl_servers_lock); 886 vllist = rcu_dereference_protected( 887 cell->vl_servers, 888 lockdep_is_held(&cell->vl_servers_lock)); 889 if (vllist->nr_servers > 0) 890 expire_at += afs_cell_gc_delay; 891 read_unlock(&cell->vl_servers_lock); 892 if (purging || expire_at <= now) 893 sched_cell = true; 894 else if (expire_at < next_manage) 895 next_manage = expire_at; 896 } 897 898 if (!purging) { 899 if (test_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags)) 900 sched_cell = true; 901 } 902 903 if (sched_cell) 904 afs_queue_cell(cell, afs_cell_trace_get_queue_manage); 905 } 906 907 up_read(&net->cells_lock); 908 909 /* Update the timer on the way out. We have to pass an increment on 910 * cells_outstanding in the namespace that we are in to the timer or 911 * the work scheduler. 912 */ 913 if (!purging && next_manage < TIME64_MAX) { 914 now = ktime_get_real_seconds(); 915 916 if (next_manage - now <= 0) { 917 if (queue_work(afs_wq, &net->cells_manager)) 918 atomic_inc(&net->cells_outstanding); 919 } else { 920 afs_set_cell_timer(net, next_manage - now); 921 } 922 } 923 924 afs_dec_cells_outstanding(net); 925 _leave(" [%d]", atomic_read(&net->cells_outstanding)); 926 } 927 928 /* 929 * Purge in-memory cell database. 930 */ 931 void afs_cell_purge(struct afs_net *net) 932 { 933 struct afs_cell *ws; 934 935 _enter(""); 936 937 down_write(&net->cells_lock); 938 ws = net->ws_cell; 939 net->ws_cell = NULL; 940 up_write(&net->cells_lock); 941 afs_unuse_cell(net, ws, afs_cell_trace_unuse_ws); 942 943 _debug("del timer"); 944 if (del_timer_sync(&net->cells_timer)) 945 atomic_dec(&net->cells_outstanding); 946 947 _debug("kick mgr"); 948 afs_queue_cell_manager(net); 949 950 _debug("wait"); 951 wait_var_event(&net->cells_outstanding, 952 !atomic_read(&net->cells_outstanding)); 953 _leave(""); 954 } 955