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