linux/fs/afs/server.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* AFS server record management
   3 *
   4 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 */
   7
   8#include <linux/sched.h>
   9#include <linux/slab.h>
  10#include "afs_fs.h"
  11#include "internal.h"
  12#include "protocol_yfs.h"
  13
  14static unsigned afs_server_gc_delay = 10;       /* Server record timeout in seconds */
  15static atomic_t afs_server_debug_id;
  16
  17static struct afs_server *afs_maybe_use_server(struct afs_server *,
  18                                               enum afs_server_trace);
  19static void __afs_put_server(struct afs_net *, struct afs_server *);
  20
  21/*
  22 * Find a server by one of its addresses.
  23 */
  24struct afs_server *afs_find_server(struct afs_net *net,
  25                                   const struct sockaddr_rxrpc *srx)
  26{
  27        const struct afs_addr_list *alist;
  28        struct afs_server *server = NULL;
  29        unsigned int i;
  30        int seq = 0, diff;
  31
  32        rcu_read_lock();
  33
  34        do {
  35                if (server)
  36                        afs_unuse_server_notime(net, server, afs_server_trace_put_find_rsq);
  37                server = NULL;
  38                read_seqbegin_or_lock(&net->fs_addr_lock, &seq);
  39
  40                if (srx->transport.family == AF_INET6) {
  41                        const struct sockaddr_in6 *a = &srx->transport.sin6, *b;
  42                        hlist_for_each_entry_rcu(server, &net->fs_addresses6, addr6_link) {
  43                                alist = rcu_dereference(server->addresses);
  44                                for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) {
  45                                        b = &alist->addrs[i].transport.sin6;
  46                                        diff = ((u16 __force)a->sin6_port -
  47                                                (u16 __force)b->sin6_port);
  48                                        if (diff == 0)
  49                                                diff = memcmp(&a->sin6_addr,
  50                                                              &b->sin6_addr,
  51                                                              sizeof(struct in6_addr));
  52                                        if (diff == 0)
  53                                                goto found;
  54                                }
  55                        }
  56                } else {
  57                        const struct sockaddr_in *a = &srx->transport.sin, *b;
  58                        hlist_for_each_entry_rcu(server, &net->fs_addresses4, addr4_link) {
  59                                alist = rcu_dereference(server->addresses);
  60                                for (i = 0; i < alist->nr_ipv4; i++) {
  61                                        b = &alist->addrs[i].transport.sin;
  62                                        diff = ((u16 __force)a->sin_port -
  63                                                (u16 __force)b->sin_port);
  64                                        if (diff == 0)
  65                                                diff = ((u32 __force)a->sin_addr.s_addr -
  66                                                        (u32 __force)b->sin_addr.s_addr);
  67                                        if (diff == 0)
  68                                                goto found;
  69                                }
  70                        }
  71                }
  72
  73                server = NULL;
  74                continue;
  75        found:
  76                server = afs_maybe_use_server(server, afs_server_trace_get_by_addr);
  77
  78        } while (need_seqretry(&net->fs_addr_lock, seq));
  79
  80        done_seqretry(&net->fs_addr_lock, seq);
  81
  82        rcu_read_unlock();
  83        return server;
  84}
  85
  86/*
  87 * Look up a server by its UUID and mark it active.
  88 */
  89struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uuid)
  90{
  91        struct afs_server *server = NULL;
  92        struct rb_node *p;
  93        int diff, seq = 0;
  94
  95        _enter("%pU", uuid);
  96
  97        do {
  98                /* Unfortunately, rbtree walking doesn't give reliable results
  99                 * under just the RCU read lock, so we have to check for
 100                 * changes.
 101                 */
 102                if (server)
 103                        afs_unuse_server(net, server, afs_server_trace_put_uuid_rsq);
 104                server = NULL;
 105
 106                read_seqbegin_or_lock(&net->fs_lock, &seq);
 107
 108                p = net->fs_servers.rb_node;
 109                while (p) {
 110                        server = rb_entry(p, struct afs_server, uuid_rb);
 111
 112                        diff = memcmp(uuid, &server->uuid, sizeof(*uuid));
 113                        if (diff < 0) {
 114                                p = p->rb_left;
 115                        } else if (diff > 0) {
 116                                p = p->rb_right;
 117                        } else {
 118                                afs_use_server(server, afs_server_trace_get_by_uuid);
 119                                break;
 120                        }
 121
 122                        server = NULL;
 123                }
 124        } while (need_seqretry(&net->fs_lock, seq));
 125
 126        done_seqretry(&net->fs_lock, seq);
 127
 128        _leave(" = %p", server);
 129        return server;
 130}
 131
 132/*
 133 * Install a server record in the namespace tree.  If there's a clash, we stick
 134 * it into a list anchored on whichever afs_server struct is actually in the
 135 * tree.
 136 */
 137static struct afs_server *afs_install_server(struct afs_cell *cell,
 138                                             struct afs_server *candidate)
 139{
 140        const struct afs_addr_list *alist;
 141        struct afs_server *server, *next;
 142        struct afs_net *net = cell->net;
 143        struct rb_node **pp, *p;
 144        int diff;
 145
 146        _enter("%p", candidate);
 147
 148        write_seqlock(&net->fs_lock);
 149
 150        /* Firstly install the server in the UUID lookup tree */
 151        pp = &net->fs_servers.rb_node;
 152        p = NULL;
 153        while (*pp) {
 154                p = *pp;
 155                _debug("- consider %p", p);
 156                server = rb_entry(p, struct afs_server, uuid_rb);
 157                diff = memcmp(&candidate->uuid, &server->uuid, sizeof(uuid_t));
 158                if (diff < 0) {
 159                        pp = &(*pp)->rb_left;
 160                } else if (diff > 0) {
 161                        pp = &(*pp)->rb_right;
 162                } else {
 163                        if (server->cell == cell)
 164                                goto exists;
 165
 166                        /* We have the same UUID representing servers in
 167                         * different cells.  Append the new server to the list.
 168                         */
 169                        for (;;) {
 170                                next = rcu_dereference_protected(
 171                                        server->uuid_next,
 172                                        lockdep_is_held(&net->fs_lock.lock));
 173                                if (!next)
 174                                        break;
 175                                server = next;
 176                        }
 177                        rcu_assign_pointer(server->uuid_next, candidate);
 178                        candidate->uuid_prev = server;
 179                        server = candidate;
 180                        goto added_dup;
 181                }
 182        }
 183
 184        server = candidate;
 185        rb_link_node(&server->uuid_rb, p, pp);
 186        rb_insert_color(&server->uuid_rb, &net->fs_servers);
 187        hlist_add_head_rcu(&server->proc_link, &net->fs_proc);
 188
 189added_dup:
 190        write_seqlock(&net->fs_addr_lock);
 191        alist = rcu_dereference_protected(server->addresses,
 192                                          lockdep_is_held(&net->fs_addr_lock.lock));
 193
 194        /* Secondly, if the server has any IPv4 and/or IPv6 addresses, install
 195         * it in the IPv4 and/or IPv6 reverse-map lists.
 196         *
 197         * TODO: For speed we want to use something other than a flat list
 198         * here; even sorting the list in terms of lowest address would help a
 199         * bit, but anything we might want to do gets messy and memory
 200         * intensive.
 201         */
 202        if (alist->nr_ipv4 > 0)
 203                hlist_add_head_rcu(&server->addr4_link, &net->fs_addresses4);
 204        if (alist->nr_addrs > alist->nr_ipv4)
 205                hlist_add_head_rcu(&server->addr6_link, &net->fs_addresses6);
 206
 207        write_sequnlock(&net->fs_addr_lock);
 208
 209exists:
 210        afs_get_server(server, afs_server_trace_get_install);
 211        write_sequnlock(&net->fs_lock);
 212        return server;
 213}
 214
 215/*
 216 * Allocate a new server record and mark it active.
 217 */
 218static struct afs_server *afs_alloc_server(struct afs_cell *cell,
 219                                           const uuid_t *uuid,
 220                                           struct afs_addr_list *alist)
 221{
 222        struct afs_server *server;
 223        struct afs_net *net = cell->net;
 224
 225        _enter("");
 226
 227        server = kzalloc(sizeof(struct afs_server), GFP_KERNEL);
 228        if (!server)
 229                goto enomem;
 230
 231        atomic_set(&server->ref, 1);
 232        atomic_set(&server->active, 1);
 233        server->debug_id = atomic_inc_return(&afs_server_debug_id);
 234        RCU_INIT_POINTER(server->addresses, alist);
 235        server->addr_version = alist->version;
 236        server->uuid = *uuid;
 237        rwlock_init(&server->fs_lock);
 238        INIT_WORK(&server->initcb_work, afs_server_init_callback_work);
 239        init_waitqueue_head(&server->probe_wq);
 240        INIT_LIST_HEAD(&server->probe_link);
 241        spin_lock_init(&server->probe_lock);
 242        server->cell = cell;
 243        server->rtt = UINT_MAX;
 244
 245        afs_inc_servers_outstanding(net);
 246        trace_afs_server(server, 1, 1, afs_server_trace_alloc);
 247        _leave(" = %p", server);
 248        return server;
 249
 250enomem:
 251        _leave(" = NULL [nomem]");
 252        return NULL;
 253}
 254
 255/*
 256 * Look up an address record for a server
 257 */
 258static struct afs_addr_list *afs_vl_lookup_addrs(struct afs_cell *cell,
 259                                                 struct key *key, const uuid_t *uuid)
 260{
 261        struct afs_vl_cursor vc;
 262        struct afs_addr_list *alist = NULL;
 263        int ret;
 264
 265        ret = -ERESTARTSYS;
 266        if (afs_begin_vlserver_operation(&vc, cell, key)) {
 267                while (afs_select_vlserver(&vc)) {
 268                        if (test_bit(AFS_VLSERVER_FL_IS_YFS, &vc.server->flags))
 269                                alist = afs_yfsvl_get_endpoints(&vc, uuid);
 270                        else
 271                                alist = afs_vl_get_addrs_u(&vc, uuid);
 272                }
 273
 274                ret = afs_end_vlserver_operation(&vc);
 275        }
 276
 277        return ret < 0 ? ERR_PTR(ret) : alist;
 278}
 279
 280/*
 281 * Get or create a fileserver record.
 282 */
 283struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,
 284                                     const uuid_t *uuid, u32 addr_version)
 285{
 286        struct afs_addr_list *alist;
 287        struct afs_server *server, *candidate;
 288
 289        _enter("%p,%pU", cell->net, uuid);
 290
 291        server = afs_find_server_by_uuid(cell->net, uuid);
 292        if (server) {
 293                if (server->addr_version != addr_version)
 294                        set_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
 295                return server;
 296        }
 297
 298        alist = afs_vl_lookup_addrs(cell, key, uuid);
 299        if (IS_ERR(alist))
 300                return ERR_CAST(alist);
 301
 302        candidate = afs_alloc_server(cell, uuid, alist);
 303        if (!candidate) {
 304                afs_put_addrlist(alist);
 305                return ERR_PTR(-ENOMEM);
 306        }
 307
 308        server = afs_install_server(cell, candidate);
 309        if (server != candidate) {
 310                afs_put_addrlist(alist);
 311                kfree(candidate);
 312        } else {
 313                /* Immediately dispatch an asynchronous probe to each interface
 314                 * on the fileserver.  This will make sure the repeat-probing
 315                 * service is started.
 316                 */
 317                afs_fs_probe_fileserver(cell->net, server, key, true);
 318        }
 319
 320        return server;
 321}
 322
 323/*
 324 * Set the server timer to fire after a given delay, assuming it's not already
 325 * set for an earlier time.
 326 */
 327static void afs_set_server_timer(struct afs_net *net, time64_t delay)
 328{
 329        if (net->live) {
 330                afs_inc_servers_outstanding(net);
 331                if (timer_reduce(&net->fs_timer, jiffies + delay * HZ))
 332                        afs_dec_servers_outstanding(net);
 333        }
 334}
 335
 336/*
 337 * Server management timer.  We have an increment on fs_outstanding that we
 338 * need to pass along to the work item.
 339 */
 340void afs_servers_timer(struct timer_list *timer)
 341{
 342        struct afs_net *net = container_of(timer, struct afs_net, fs_timer);
 343
 344        _enter("");
 345        if (!queue_work(afs_wq, &net->fs_manager))
 346                afs_dec_servers_outstanding(net);
 347}
 348
 349/*
 350 * Get a reference on a server object.
 351 */
 352struct afs_server *afs_get_server(struct afs_server *server,
 353                                  enum afs_server_trace reason)
 354{
 355        unsigned int u = atomic_inc_return(&server->ref);
 356
 357        trace_afs_server(server, u, atomic_read(&server->active), reason);
 358        return server;
 359}
 360
 361/*
 362 * Try to get a reference on a server object.
 363 */
 364static struct afs_server *afs_maybe_use_server(struct afs_server *server,
 365                                               enum afs_server_trace reason)
 366{
 367        unsigned int r = atomic_fetch_add_unless(&server->ref, 1, 0);
 368        unsigned int a;
 369
 370        if (r == 0)
 371                return NULL;
 372
 373        a = atomic_inc_return(&server->active);
 374        trace_afs_server(server, r, a, reason);
 375        return server;
 376}
 377
 378/*
 379 * Get an active count on a server object.
 380 */
 381struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_trace reason)
 382{
 383        unsigned int r = atomic_inc_return(&server->ref);
 384        unsigned int a = atomic_inc_return(&server->active);
 385
 386        trace_afs_server(server, r, a, reason);
 387        return server;
 388}
 389
 390/*
 391 * Release a reference on a server record.
 392 */
 393void afs_put_server(struct afs_net *net, struct afs_server *server,
 394                    enum afs_server_trace reason)
 395{
 396        unsigned int usage;
 397
 398        if (!server)
 399                return;
 400
 401        usage = atomic_dec_return(&server->ref);
 402        trace_afs_server(server, usage, atomic_read(&server->active), reason);
 403        if (unlikely(usage == 0))
 404                __afs_put_server(net, server);
 405}
 406
 407/*
 408 * Drop an active count on a server object without updating the last-unused
 409 * time.
 410 */
 411void afs_unuse_server_notime(struct afs_net *net, struct afs_server *server,
 412                             enum afs_server_trace reason)
 413{
 414        if (server) {
 415                unsigned int active = atomic_dec_return(&server->active);
 416
 417                if (active == 0)
 418                        afs_set_server_timer(net, afs_server_gc_delay);
 419                afs_put_server(net, server, reason);
 420        }
 421}
 422
 423/*
 424 * Drop an active count on a server object.
 425 */
 426void afs_unuse_server(struct afs_net *net, struct afs_server *server,
 427                      enum afs_server_trace reason)
 428{
 429        if (server) {
 430                server->unuse_time = ktime_get_real_seconds();
 431                afs_unuse_server_notime(net, server, reason);
 432        }
 433}
 434
 435static void afs_server_rcu(struct rcu_head *rcu)
 436{
 437        struct afs_server *server = container_of(rcu, struct afs_server, rcu);
 438
 439        trace_afs_server(server, atomic_read(&server->ref),
 440                         atomic_read(&server->active), afs_server_trace_free);
 441        afs_put_addrlist(rcu_access_pointer(server->addresses));
 442        kfree(server);
 443}
 444
 445static void __afs_put_server(struct afs_net *net, struct afs_server *server)
 446{
 447        call_rcu(&server->rcu, afs_server_rcu);
 448        afs_dec_servers_outstanding(net);
 449}
 450
 451static void afs_give_up_callbacks(struct afs_net *net, struct afs_server *server)
 452{
 453        struct afs_addr_list *alist = rcu_access_pointer(server->addresses);
 454        struct afs_addr_cursor ac = {
 455                .alist  = alist,
 456                .index  = alist->preferred,
 457                .error  = 0,
 458        };
 459
 460        afs_fs_give_up_all_callbacks(net, server, &ac, NULL);
 461}
 462
 463/*
 464 * destroy a dead server
 465 */
 466static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
 467{
 468        if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))
 469                afs_give_up_callbacks(net, server);
 470
 471        flush_work(&server->initcb_work);
 472        afs_put_server(net, server, afs_server_trace_destroy);
 473}
 474
 475/*
 476 * Garbage collect any expired servers.
 477 */
 478static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)
 479{
 480        struct afs_server *server, *next, *prev;
 481        int active;
 482
 483        while ((server = gc_list)) {
 484                gc_list = server->gc_next;
 485
 486                write_seqlock(&net->fs_lock);
 487
 488                active = atomic_read(&server->active);
 489                if (active == 0) {
 490                        trace_afs_server(server, atomic_read(&server->ref),
 491                                         active, afs_server_trace_gc);
 492                        next = rcu_dereference_protected(
 493                                server->uuid_next, lockdep_is_held(&net->fs_lock.lock));
 494                        prev = server->uuid_prev;
 495                        if (!prev) {
 496                                /* The one at the front is in the tree */
 497                                if (!next) {
 498                                        rb_erase(&server->uuid_rb, &net->fs_servers);
 499                                } else {
 500                                        rb_replace_node_rcu(&server->uuid_rb,
 501                                                            &next->uuid_rb,
 502                                                            &net->fs_servers);
 503                                        next->uuid_prev = NULL;
 504                                }
 505                        } else {
 506                                /* This server is not at the front */
 507                                rcu_assign_pointer(prev->uuid_next, next);
 508                                if (next)
 509                                        next->uuid_prev = prev;
 510                        }
 511
 512                        list_del(&server->probe_link);
 513                        hlist_del_rcu(&server->proc_link);
 514                        if (!hlist_unhashed(&server->addr4_link))
 515                                hlist_del_rcu(&server->addr4_link);
 516                        if (!hlist_unhashed(&server->addr6_link))
 517                                hlist_del_rcu(&server->addr6_link);
 518                }
 519                write_sequnlock(&net->fs_lock);
 520
 521                if (active == 0)
 522                        afs_destroy_server(net, server);
 523        }
 524}
 525
 526/*
 527 * Manage the records of servers known to be within a network namespace.  This
 528 * includes garbage collecting unused servers.
 529 *
 530 * Note also that we were given an increment on net->servers_outstanding by
 531 * whoever queued us that we need to deal with before returning.
 532 */
 533void afs_manage_servers(struct work_struct *work)
 534{
 535        struct afs_net *net = container_of(work, struct afs_net, fs_manager);
 536        struct afs_server *gc_list = NULL;
 537        struct rb_node *cursor;
 538        time64_t now = ktime_get_real_seconds(), next_manage = TIME64_MAX;
 539        bool purging = !net->live;
 540
 541        _enter("");
 542
 543        /* Trawl the server list looking for servers that have expired from
 544         * lack of use.
 545         */
 546        read_seqlock_excl(&net->fs_lock);
 547
 548        for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) {
 549                struct afs_server *server =
 550                        rb_entry(cursor, struct afs_server, uuid_rb);
 551                int active = atomic_read(&server->active);
 552
 553                _debug("manage %pU %u", &server->uuid, active);
 554
 555                if (purging) {
 556                        trace_afs_server(server, atomic_read(&server->ref),
 557                                         active, afs_server_trace_purging);
 558                        if (active != 0)
 559                                pr_notice("Can't purge s=%08x\n", server->debug_id);
 560                }
 561
 562                if (active == 0) {
 563                        time64_t expire_at = server->unuse_time;
 564
 565                        if (!test_bit(AFS_SERVER_FL_VL_FAIL, &server->flags) &&
 566                            !test_bit(AFS_SERVER_FL_NOT_FOUND, &server->flags))
 567                                expire_at += afs_server_gc_delay;
 568                        if (purging || expire_at <= now) {
 569                                server->gc_next = gc_list;
 570                                gc_list = server;
 571                        } else if (expire_at < next_manage) {
 572                                next_manage = expire_at;
 573                        }
 574                }
 575        }
 576
 577        read_sequnlock_excl(&net->fs_lock);
 578
 579        /* Update the timer on the way out.  We have to pass an increment on
 580         * servers_outstanding in the namespace that we are in to the timer or
 581         * the work scheduler.
 582         */
 583        if (!purging && next_manage < TIME64_MAX) {
 584                now = ktime_get_real_seconds();
 585
 586                if (next_manage - now <= 0) {
 587                        if (queue_work(afs_wq, &net->fs_manager))
 588                                afs_inc_servers_outstanding(net);
 589                } else {
 590                        afs_set_server_timer(net, next_manage - now);
 591                }
 592        }
 593
 594        afs_gc_servers(net, gc_list);
 595
 596        afs_dec_servers_outstanding(net);
 597        _leave(" [%d]", atomic_read(&net->servers_outstanding));
 598}
 599
 600static void afs_queue_server_manager(struct afs_net *net)
 601{
 602        afs_inc_servers_outstanding(net);
 603        if (!queue_work(afs_wq, &net->fs_manager))
 604                afs_dec_servers_outstanding(net);
 605}
 606
 607/*
 608 * Purge list of servers.
 609 */
 610void afs_purge_servers(struct afs_net *net)
 611{
 612        _enter("");
 613
 614        if (del_timer_sync(&net->fs_timer))
 615                afs_dec_servers_outstanding(net);
 616
 617        afs_queue_server_manager(net);
 618
 619        _debug("wait");
 620        atomic_dec(&net->servers_outstanding);
 621        wait_var_event(&net->servers_outstanding,
 622                       !atomic_read(&net->servers_outstanding));
 623        _leave("");
 624}
 625
 626/*
 627 * Get an update for a server's address list.
 628 */
 629static noinline bool afs_update_server_record(struct afs_operation *op,
 630                                              struct afs_server *server)
 631{
 632        struct afs_addr_list *alist, *discard;
 633
 634        _enter("");
 635
 636        trace_afs_server(server, atomic_read(&server->ref), atomic_read(&server->active),
 637                         afs_server_trace_update);
 638
 639        alist = afs_vl_lookup_addrs(op->volume->cell, op->key, &server->uuid);
 640        if (IS_ERR(alist)) {
 641                if ((PTR_ERR(alist) == -ERESTARTSYS ||
 642                     PTR_ERR(alist) == -EINTR) &&
 643                    (op->flags & AFS_OPERATION_UNINTR) &&
 644                    server->addresses) {
 645                        _leave(" = t [intr]");
 646                        return true;
 647                }
 648                op->error = PTR_ERR(alist);
 649                _leave(" = f [%d]", op->error);
 650                return false;
 651        }
 652
 653        discard = alist;
 654        if (server->addr_version != alist->version) {
 655                write_lock(&server->fs_lock);
 656                discard = rcu_dereference_protected(server->addresses,
 657                                                    lockdep_is_held(&server->fs_lock));
 658                rcu_assign_pointer(server->addresses, alist);
 659                server->addr_version = alist->version;
 660                write_unlock(&server->fs_lock);
 661        }
 662
 663        afs_put_addrlist(discard);
 664        _leave(" = t");
 665        return true;
 666}
 667
 668/*
 669 * See if a server's address list needs updating.
 670 */
 671bool afs_check_server_record(struct afs_operation *op, struct afs_server *server)
 672{
 673        bool success;
 674        int ret, retries = 0;
 675
 676        _enter("");
 677
 678        ASSERT(server);
 679
 680retry:
 681        if (test_bit(AFS_SERVER_FL_UPDATING, &server->flags))
 682                goto wait;
 683        if (test_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags))
 684                goto update;
 685        _leave(" = t [good]");
 686        return true;
 687
 688update:
 689        if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) {
 690                clear_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
 691                success = afs_update_server_record(op, server);
 692                clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags);
 693                wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING);
 694                _leave(" = %d", success);
 695                return success;
 696        }
 697
 698wait:
 699        ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
 700                          (op->flags & AFS_OPERATION_UNINTR) ?
 701                          TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
 702        if (ret == -ERESTARTSYS) {
 703                op->error = ret;
 704                _leave(" = f [intr]");
 705                return false;
 706        }
 707
 708        retries++;
 709        if (retries == 4) {
 710                _leave(" = f [stale]");
 711                ret = -ESTALE;
 712                return false;
 713        }
 714        goto retry;
 715}
 716