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;
  21static atomic_t cell_debug_id;
  22
  23static void afs_queue_cell_manager(struct afs_net *);
  24static void afs_manage_cell_work(struct work_struct *);
  25
  26static 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 */
  36static 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 */
  51static 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
  91found:
  92        return afs_use_cell(cell, reason);
  93}
  94
  95/*
  96 * Look up and get an activation reference on a cell record.
  97 */
  98struct 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 */
 114static 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        atomic_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
 211parse_failed:
 212        if (ret == -EINVAL)
 213                printk(KERN_ERR "kAFS: bad VL server IP address\n");
 214error:
 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 */
 234struct 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, atomic_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
 297wait_for_cell:
 298        trace_afs_cell(cell->debug_id, atomic_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
 316cell_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;
 331error:
 332        afs_unuse_cell(net, cell, afs_cell_trace_unuse_lookup);
 333error_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 */
 343int 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 */
 394static 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                ret = -ENOMEM;
 413                vllist = afs_alloc_vlserver_list(0);
 414                if (!vllist)
 415                        goto out_wake;
 416
 417                switch (ret) {
 418                case -ENODATA:
 419                case -EDESTADDRREQ:
 420                        vllist->status = DNS_LOOKUP_GOT_NOT_FOUND;
 421                        break;
 422                case -EAGAIN:
 423                case -ECONNREFUSED:
 424                        vllist->status = DNS_LOOKUP_GOT_TEMP_FAILURE;
 425                        break;
 426                default:
 427                        vllist->status = DNS_LOOKUP_GOT_LOCAL_FAILURE;
 428                        break;
 429                }
 430        }
 431
 432        _debug("%s: got list %d %d", cell->name, vllist->source, vllist->status);
 433        cell->dns_status = vllist->status;
 434
 435        now = ktime_get_real_seconds();
 436        if (min_ttl > max_ttl)
 437                max_ttl = min_ttl;
 438        if (expiry < now + min_ttl)
 439                expiry = now + min_ttl;
 440        else if (expiry > now + max_ttl)
 441                expiry = now + max_ttl;
 442
 443        _debug("%s: status %d", cell->name, vllist->status);
 444        if (vllist->source == DNS_RECORD_UNAVAILABLE) {
 445                switch (vllist->status) {
 446                case DNS_LOOKUP_GOT_NOT_FOUND:
 447                        /* The DNS said that the cell does not exist or there
 448                         * weren't any addresses to be had.
 449                         */
 450                        cell->dns_expiry = expiry;
 451                        break;
 452
 453                case DNS_LOOKUP_BAD:
 454                case DNS_LOOKUP_GOT_LOCAL_FAILURE:
 455                case DNS_LOOKUP_GOT_TEMP_FAILURE:
 456                case DNS_LOOKUP_GOT_NS_FAILURE:
 457                default:
 458                        cell->dns_expiry = now + 10;
 459                        break;
 460                }
 461        } else {
 462                cell->dns_expiry = expiry;
 463        }
 464
 465        /* Replace the VL server list if the new record has servers or the old
 466         * record doesn't.
 467         */
 468        write_lock(&cell->vl_servers_lock);
 469        p = rcu_dereference_protected(cell->vl_servers, true);
 470        if (vllist->nr_servers > 0 || p->nr_servers == 0) {
 471                rcu_assign_pointer(cell->vl_servers, vllist);
 472                cell->dns_source = vllist->source;
 473                old = p;
 474        }
 475        write_unlock(&cell->vl_servers_lock);
 476        afs_put_vlserverlist(cell->net, old);
 477
 478out_wake:
 479        smp_store_release(&cell->dns_lookup_count,
 480                          cell->dns_lookup_count + 1); /* vs source/status */
 481        wake_up_var(&cell->dns_lookup_count);
 482        _leave(" = %d", ret);
 483        return ret;
 484}
 485
 486/*
 487 * Destroy a cell record
 488 */
 489static void afs_cell_destroy(struct rcu_head *rcu)
 490{
 491        struct afs_cell *cell = container_of(rcu, struct afs_cell, rcu);
 492        struct afs_net *net = cell->net;
 493        int u;
 494
 495        _enter("%p{%s}", cell, cell->name);
 496
 497        u = atomic_read(&cell->ref);
 498        ASSERTCMP(u, ==, 0);
 499        trace_afs_cell(cell->debug_id, u, atomic_read(&cell->active), afs_cell_trace_free);
 500
 501        afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers));
 502        afs_unuse_cell(net, cell->alias_of, afs_cell_trace_unuse_alias);
 503        key_put(cell->anonymous_key);
 504        kfree(cell->name);
 505        kfree(cell);
 506
 507        afs_dec_cells_outstanding(net);
 508        _leave(" [destroyed]");
 509}
 510
 511/*
 512 * Queue the cell manager.
 513 */
 514static void afs_queue_cell_manager(struct afs_net *net)
 515{
 516        int outstanding = atomic_inc_return(&net->cells_outstanding);
 517
 518        _enter("%d", outstanding);
 519
 520        if (!queue_work(afs_wq, &net->cells_manager))
 521                afs_dec_cells_outstanding(net);
 522}
 523
 524/*
 525 * Cell management timer.  We have an increment on cells_outstanding that we
 526 * need to pass along to the work item.
 527 */
 528void afs_cells_timer(struct timer_list *timer)
 529{
 530        struct afs_net *net = container_of(timer, struct afs_net, cells_timer);
 531
 532        _enter("");
 533        if (!queue_work(afs_wq, &net->cells_manager))
 534                afs_dec_cells_outstanding(net);
 535}
 536
 537/*
 538 * Get a reference on a cell record.
 539 */
 540struct afs_cell *afs_get_cell(struct afs_cell *cell, enum afs_cell_trace reason)
 541{
 542        int u;
 543
 544        if (atomic_read(&cell->ref) <= 0)
 545                BUG();
 546
 547        u = atomic_inc_return(&cell->ref);
 548        trace_afs_cell(cell->debug_id, u, atomic_read(&cell->active), reason);
 549        return cell;
 550}
 551
 552/*
 553 * Drop a reference on a cell record.
 554 */
 555void afs_put_cell(struct afs_cell *cell, enum afs_cell_trace reason)
 556{
 557        if (cell) {
 558                unsigned int debug_id = cell->debug_id;
 559                unsigned int u, a;
 560
 561                a = atomic_read(&cell->active);
 562                u = atomic_dec_return(&cell->ref);
 563                trace_afs_cell(debug_id, u, a, reason);
 564                if (u == 0) {
 565                        a = atomic_read(&cell->active);
 566                        WARN(a != 0, "Cell active count %u > 0\n", a);
 567                        call_rcu(&cell->rcu, afs_cell_destroy);
 568                }
 569        }
 570}
 571
 572/*
 573 * Note a cell becoming more active.
 574 */
 575struct afs_cell *afs_use_cell(struct afs_cell *cell, enum afs_cell_trace reason)
 576{
 577        int u, a;
 578
 579        if (atomic_read(&cell->ref) <= 0)
 580                BUG();
 581
 582        u = atomic_read(&cell->ref);
 583        a = atomic_inc_return(&cell->active);
 584        trace_afs_cell(cell->debug_id, u, a, reason);
 585        return cell;
 586}
 587
 588/*
 589 * Record a cell becoming less active.  When the active counter reaches 1, it
 590 * is scheduled for destruction, but may get reactivated.
 591 */
 592void afs_unuse_cell(struct afs_net *net, struct afs_cell *cell, enum afs_cell_trace reason)
 593{
 594        unsigned int debug_id;
 595        time64_t now, expire_delay;
 596        int u, a;
 597
 598        if (!cell)
 599                return;
 600
 601        _enter("%s", cell->name);
 602
 603        now = ktime_get_real_seconds();
 604        cell->last_inactive = now;
 605        expire_delay = 0;
 606        if (cell->vl_servers->nr_servers)
 607                expire_delay = afs_cell_gc_delay;
 608
 609        debug_id = cell->debug_id;
 610        u = atomic_read(&cell->ref);
 611        a = atomic_dec_return(&cell->active);
 612        trace_afs_cell(debug_id, u, a, reason);
 613        WARN_ON(a == 0);
 614        if (a == 1)
 615                /* 'cell' may now be garbage collected. */
 616                afs_set_cell_timer(net, expire_delay);
 617}
 618
 619/*
 620 * Note that a cell has been seen.
 621 */
 622void afs_see_cell(struct afs_cell *cell, enum afs_cell_trace reason)
 623{
 624        int u, a;
 625
 626        u = atomic_read(&cell->ref);
 627        a = atomic_read(&cell->active);
 628        trace_afs_cell(cell->debug_id, u, a, reason);
 629}
 630
 631/*
 632 * Queue a cell for management, giving the workqueue a ref to hold.
 633 */
 634void afs_queue_cell(struct afs_cell *cell, enum afs_cell_trace reason)
 635{
 636        afs_get_cell(cell, reason);
 637        if (!queue_work(afs_wq, &cell->manager))
 638                afs_put_cell(cell, afs_cell_trace_put_queue_fail);
 639}
 640
 641/*
 642 * Allocate a key to use as a placeholder for anonymous user security.
 643 */
 644static int afs_alloc_anon_key(struct afs_cell *cell)
 645{
 646        struct key *key;
 647        char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp;
 648
 649        /* Create a key to represent an anonymous user. */
 650        memcpy(keyname, "afs@", 4);
 651        dp = keyname + 4;
 652        cp = cell->name;
 653        do {
 654                *dp++ = tolower(*cp);
 655        } while (*cp++);
 656
 657        key = rxrpc_get_null_key(keyname);
 658        if (IS_ERR(key))
 659                return PTR_ERR(key);
 660
 661        cell->anonymous_key = key;
 662
 663        _debug("anon key %p{%x}",
 664               cell->anonymous_key, key_serial(cell->anonymous_key));
 665        return 0;
 666}
 667
 668/*
 669 * Activate a cell.
 670 */
 671static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
 672{
 673        struct hlist_node **p;
 674        struct afs_cell *pcell;
 675        int ret;
 676
 677        if (!cell->anonymous_key) {
 678                ret = afs_alloc_anon_key(cell);
 679                if (ret < 0)
 680                        return ret;
 681        }
 682
 683#ifdef CONFIG_AFS_FSCACHE
 684        cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
 685                                             &afs_cell_cache_index_def,
 686                                             cell->name, strlen(cell->name),
 687                                             NULL, 0,
 688                                             cell, 0, true);
 689#endif
 690        ret = afs_proc_cell_setup(cell);
 691        if (ret < 0)
 692                return ret;
 693
 694        mutex_lock(&net->proc_cells_lock);
 695        for (p = &net->proc_cells.first; *p; p = &(*p)->next) {
 696                pcell = hlist_entry(*p, struct afs_cell, proc_link);
 697                if (strcmp(cell->name, pcell->name) < 0)
 698                        break;
 699        }
 700
 701        cell->proc_link.pprev = p;
 702        cell->proc_link.next = *p;
 703        rcu_assign_pointer(*p, &cell->proc_link.next);
 704        if (cell->proc_link.next)
 705                cell->proc_link.next->pprev = &cell->proc_link.next;
 706
 707        afs_dynroot_mkdir(net, cell);
 708        mutex_unlock(&net->proc_cells_lock);
 709        return 0;
 710}
 711
 712/*
 713 * Deactivate a cell.
 714 */
 715static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
 716{
 717        _enter("%s", cell->name);
 718
 719        afs_proc_cell_remove(cell);
 720
 721        mutex_lock(&net->proc_cells_lock);
 722        hlist_del_rcu(&cell->proc_link);
 723        afs_dynroot_rmdir(net, cell);
 724        mutex_unlock(&net->proc_cells_lock);
 725
 726#ifdef CONFIG_AFS_FSCACHE
 727        fscache_relinquish_cookie(cell->cache, NULL, false);
 728        cell->cache = NULL;
 729#endif
 730
 731        _leave("");
 732}
 733
 734/*
 735 * Manage a cell record, initialising and destroying it, maintaining its DNS
 736 * records.
 737 */
 738static void afs_manage_cell(struct afs_cell *cell)
 739{
 740        struct afs_net *net = cell->net;
 741        int ret, active;
 742
 743        _enter("%s", cell->name);
 744
 745again:
 746        _debug("state %u", cell->state);
 747        switch (cell->state) {
 748        case AFS_CELL_INACTIVE:
 749        case AFS_CELL_FAILED:
 750                down_write(&net->cells_lock);
 751                active = 1;
 752                if (atomic_try_cmpxchg_relaxed(&cell->active, &active, 0)) {
 753                        rb_erase(&cell->net_node, &net->cells);
 754                        trace_afs_cell(cell->debug_id, atomic_read(&cell->ref), 0,
 755                                       afs_cell_trace_unuse_delete);
 756                        smp_store_release(&cell->state, AFS_CELL_REMOVED);
 757                }
 758                up_write(&net->cells_lock);
 759                if (cell->state == AFS_CELL_REMOVED) {
 760                        wake_up_var(&cell->state);
 761                        goto final_destruction;
 762                }
 763                if (cell->state == AFS_CELL_FAILED)
 764                        goto done;
 765                smp_store_release(&cell->state, AFS_CELL_UNSET);
 766                wake_up_var(&cell->state);
 767                goto again;
 768
 769        case AFS_CELL_UNSET:
 770                smp_store_release(&cell->state, AFS_CELL_ACTIVATING);
 771                wake_up_var(&cell->state);
 772                goto again;
 773
 774        case AFS_CELL_ACTIVATING:
 775                ret = afs_activate_cell(net, cell);
 776                if (ret < 0)
 777                        goto activation_failed;
 778
 779                smp_store_release(&cell->state, AFS_CELL_ACTIVE);
 780                wake_up_var(&cell->state);
 781                goto again;
 782
 783        case AFS_CELL_ACTIVE:
 784                if (atomic_read(&cell->active) > 1) {
 785                        if (test_and_clear_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags)) {
 786                                ret = afs_update_cell(cell);
 787                                if (ret < 0)
 788                                        cell->error = ret;
 789                        }
 790                        goto done;
 791                }
 792                smp_store_release(&cell->state, AFS_CELL_DEACTIVATING);
 793                wake_up_var(&cell->state);
 794                goto again;
 795
 796        case AFS_CELL_DEACTIVATING:
 797                if (atomic_read(&cell->active) > 1)
 798                        goto reverse_deactivation;
 799                afs_deactivate_cell(net, cell);
 800                smp_store_release(&cell->state, AFS_CELL_INACTIVE);
 801                wake_up_var(&cell->state);
 802                goto again;
 803
 804        case AFS_CELL_REMOVED:
 805                goto done;
 806
 807        default:
 808                break;
 809        }
 810        _debug("bad state %u", cell->state);
 811        BUG(); /* Unhandled state */
 812
 813activation_failed:
 814        cell->error = ret;
 815        afs_deactivate_cell(net, cell);
 816
 817        smp_store_release(&cell->state, AFS_CELL_FAILED); /* vs error */
 818        wake_up_var(&cell->state);
 819        goto again;
 820
 821reverse_deactivation:
 822        smp_store_release(&cell->state, AFS_CELL_ACTIVE);
 823        wake_up_var(&cell->state);
 824        _leave(" [deact->act]");
 825        return;
 826
 827done:
 828        _leave(" [done %u]", cell->state);
 829        return;
 830
 831final_destruction:
 832        /* The root volume is pinning the cell */
 833        afs_put_volume(cell->net, cell->root_volume, afs_volume_trace_put_cell_root);
 834        cell->root_volume = NULL;
 835        afs_put_cell(cell, afs_cell_trace_put_destroy);
 836}
 837
 838static void afs_manage_cell_work(struct work_struct *work)
 839{
 840        struct afs_cell *cell = container_of(work, struct afs_cell, manager);
 841
 842        afs_manage_cell(cell);
 843        afs_put_cell(cell, afs_cell_trace_put_queue_work);
 844}
 845
 846/*
 847 * Manage the records of cells known to a network namespace.  This includes
 848 * updating the DNS records and garbage collecting unused cells that were
 849 * automatically added.
 850 *
 851 * Note that constructed cell records may only be removed from net->cells by
 852 * this work item, so it is safe for this work item to stash a cursor pointing
 853 * into the tree and then return to caller (provided it skips cells that are
 854 * still under construction).
 855 *
 856 * Note also that we were given an increment on net->cells_outstanding by
 857 * whoever queued us that we need to deal with before returning.
 858 */
 859void afs_manage_cells(struct work_struct *work)
 860{
 861        struct afs_net *net = container_of(work, struct afs_net, cells_manager);
 862        struct rb_node *cursor;
 863        time64_t now = ktime_get_real_seconds(), next_manage = TIME64_MAX;
 864        bool purging = !net->live;
 865
 866        _enter("");
 867
 868        /* Trawl the cell database looking for cells that have expired from
 869         * lack of use and cells whose DNS results have expired and dispatch
 870         * their managers.
 871         */
 872        down_read(&net->cells_lock);
 873
 874        for (cursor = rb_first(&net->cells); cursor; cursor = rb_next(cursor)) {
 875                struct afs_cell *cell =
 876                        rb_entry(cursor, struct afs_cell, net_node);
 877                unsigned active;
 878                bool sched_cell = false;
 879
 880                active = atomic_read(&cell->active);
 881                trace_afs_cell(cell->debug_id, atomic_read(&cell->ref),
 882                               active, afs_cell_trace_manage);
 883
 884                ASSERTCMP(active, >=, 1);
 885
 886                if (purging) {
 887                        if (test_and_clear_bit(AFS_CELL_FL_NO_GC, &cell->flags)) {
 888                                active = atomic_dec_return(&cell->active);
 889                                trace_afs_cell(cell->debug_id, atomic_read(&cell->ref),
 890                                               active, afs_cell_trace_unuse_pin);
 891                        }
 892                }
 893
 894                if (active == 1) {
 895                        struct afs_vlserver_list *vllist;
 896                        time64_t expire_at = cell->last_inactive;
 897
 898                        read_lock(&cell->vl_servers_lock);
 899                        vllist = rcu_dereference_protected(
 900                                cell->vl_servers,
 901                                lockdep_is_held(&cell->vl_servers_lock));
 902                        if (vllist->nr_servers > 0)
 903                                expire_at += afs_cell_gc_delay;
 904                        read_unlock(&cell->vl_servers_lock);
 905                        if (purging || expire_at <= now)
 906                                sched_cell = true;
 907                        else if (expire_at < next_manage)
 908                                next_manage = expire_at;
 909                }
 910
 911                if (!purging) {
 912                        if (test_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags))
 913                                sched_cell = true;
 914                }
 915
 916                if (sched_cell)
 917                        afs_queue_cell(cell, afs_cell_trace_get_queue_manage);
 918        }
 919
 920        up_read(&net->cells_lock);
 921
 922        /* Update the timer on the way out.  We have to pass an increment on
 923         * cells_outstanding in the namespace that we are in to the timer or
 924         * the work scheduler.
 925         */
 926        if (!purging && next_manage < TIME64_MAX) {
 927                now = ktime_get_real_seconds();
 928
 929                if (next_manage - now <= 0) {
 930                        if (queue_work(afs_wq, &net->cells_manager))
 931                                atomic_inc(&net->cells_outstanding);
 932                } else {
 933                        afs_set_cell_timer(net, next_manage - now);
 934                }
 935        }
 936
 937        afs_dec_cells_outstanding(net);
 938        _leave(" [%d]", atomic_read(&net->cells_outstanding));
 939}
 940
 941/*
 942 * Purge in-memory cell database.
 943 */
 944void afs_cell_purge(struct afs_net *net)
 945{
 946        struct afs_cell *ws;
 947
 948        _enter("");
 949
 950        down_write(&net->cells_lock);
 951        ws = net->ws_cell;
 952        net->ws_cell = NULL;
 953        up_write(&net->cells_lock);
 954        afs_unuse_cell(net, ws, afs_cell_trace_unuse_ws);
 955
 956        _debug("del timer");
 957        if (del_timer_sync(&net->cells_timer))
 958                atomic_dec(&net->cells_outstanding);
 959
 960        _debug("kick mgr");
 961        afs_queue_cell_manager(net);
 962
 963        _debug("wait");
 964        wait_var_event(&net->cells_outstanding,
 965                       !atomic_read(&net->cells_outstanding));
 966        _leave("");
 967}
 968