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