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