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