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_waitqueue_head(&server->probe_wq);
 239        INIT_LIST_HEAD(&server->probe_link);
 240        spin_lock_init(&server->probe_lock);
 241        server->cell = cell;
 242        server->rtt = UINT_MAX;
 243
 244        afs_inc_servers_outstanding(net);
 245        trace_afs_server(server, 1, 1, afs_server_trace_alloc);
 246        _leave(" = %p", server);
 247        return server;
 248
 249enomem:
 250        _leave(" = NULL [nomem]");
 251        return NULL;
 252}
 253
 254/*
 255 * Look up an address record for a server
 256 */
 257static struct afs_addr_list *afs_vl_lookup_addrs(struct afs_cell *cell,
 258                                                 struct key *key, const uuid_t *uuid)
 259{
 260        struct afs_vl_cursor vc;
 261        struct afs_addr_list *alist = NULL;
 262        int ret;
 263
 264        ret = -ERESTARTSYS;
 265        if (afs_begin_vlserver_operation(&vc, cell, key)) {
 266                while (afs_select_vlserver(&vc)) {
 267                        if (test_bit(AFS_VLSERVER_FL_IS_YFS, &vc.server->flags))
 268                                alist = afs_yfsvl_get_endpoints(&vc, uuid);
 269                        else
 270                                alist = afs_vl_get_addrs_u(&vc, uuid);
 271                }
 272
 273                ret = afs_end_vlserver_operation(&vc);
 274        }
 275
 276        return ret < 0 ? ERR_PTR(ret) : alist;
 277}
 278
 279/*
 280 * Get or create a fileserver record.
 281 */
 282struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,
 283                                     const uuid_t *uuid, u32 addr_version)
 284{
 285        struct afs_addr_list *alist;
 286        struct afs_server *server, *candidate;
 287
 288        _enter("%p,%pU", cell->net, uuid);
 289
 290        server = afs_find_server_by_uuid(cell->net, uuid);
 291        if (server) {
 292                if (server->addr_version != addr_version)
 293                        set_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
 294                return server;
 295        }
 296
 297        alist = afs_vl_lookup_addrs(cell, key, uuid);
 298        if (IS_ERR(alist))
 299                return ERR_CAST(alist);
 300
 301        candidate = afs_alloc_server(cell, uuid, alist);
 302        if (!candidate) {
 303                afs_put_addrlist(alist);
 304                return ERR_PTR(-ENOMEM);
 305        }
 306
 307        server = afs_install_server(cell, candidate);
 308        if (server != candidate) {
 309                afs_put_addrlist(alist);
 310                kfree(candidate);
 311        } else {
 312                /* Immediately dispatch an asynchronous probe to each interface
 313                 * on the fileserver.  This will make sure the repeat-probing
 314                 * service is started.
 315                 */
 316                afs_fs_probe_fileserver(cell->net, server, key, true);
 317        }
 318
 319        return server;
 320}
 321
 322/*
 323 * Set the server timer to fire after a given delay, assuming it's not already
 324 * set for an earlier time.
 325 */
 326static void afs_set_server_timer(struct afs_net *net, time64_t delay)
 327{
 328        if (net->live) {
 329                afs_inc_servers_outstanding(net);
 330                if (timer_reduce(&net->fs_timer, jiffies + delay * HZ))
 331                        afs_dec_servers_outstanding(net);
 332        }
 333}
 334
 335/*
 336 * Server management timer.  We have an increment on fs_outstanding that we
 337 * need to pass along to the work item.
 338 */
 339void afs_servers_timer(struct timer_list *timer)
 340{
 341        struct afs_net *net = container_of(timer, struct afs_net, fs_timer);
 342
 343        _enter("");
 344        if (!queue_work(afs_wq, &net->fs_manager))
 345                afs_dec_servers_outstanding(net);
 346}
 347
 348/*
 349 * Get a reference on a server object.
 350 */
 351struct afs_server *afs_get_server(struct afs_server *server,
 352                                  enum afs_server_trace reason)
 353{
 354        unsigned int u = atomic_inc_return(&server->ref);
 355
 356        trace_afs_server(server, u, atomic_read(&server->active), reason);
 357        return server;
 358}
 359
 360/*
 361 * Try to get a reference on a server object.
 362 */
 363static struct afs_server *afs_maybe_use_server(struct afs_server *server,
 364                                               enum afs_server_trace reason)
 365{
 366        unsigned int r = atomic_fetch_add_unless(&server->ref, 1, 0);
 367        unsigned int a;
 368
 369        if (r == 0)
 370                return NULL;
 371
 372        a = atomic_inc_return(&server->active);
 373        trace_afs_server(server, r, a, reason);
 374        return server;
 375}
 376
 377/*
 378 * Get an active count on a server object.
 379 */
 380struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_trace reason)
 381{
 382        unsigned int r = atomic_inc_return(&server->ref);
 383        unsigned int a = atomic_inc_return(&server->active);
 384
 385        trace_afs_server(server, r, a, reason);
 386        return server;
 387}
 388
 389/*
 390 * Release a reference on a server record.
 391 */
 392void afs_put_server(struct afs_net *net, struct afs_server *server,
 393                    enum afs_server_trace reason)
 394{
 395        unsigned int usage;
 396
 397        if (!server)
 398                return;
 399
 400        usage = atomic_dec_return(&server->ref);
 401        trace_afs_server(server, usage, atomic_read(&server->active), reason);
 402        if (unlikely(usage == 0))
 403                __afs_put_server(net, server);
 404}
 405
 406/*
 407 * Drop an active count on a server object without updating the last-unused
 408 * time.
 409 */
 410void afs_unuse_server_notime(struct afs_net *net, struct afs_server *server,
 411                             enum afs_server_trace reason)
 412{
 413        if (server) {
 414                unsigned int active = atomic_dec_return(&server->active);
 415
 416                if (active == 0)
 417                        afs_set_server_timer(net, afs_server_gc_delay);
 418                afs_put_server(net, server, reason);
 419        }
 420}
 421
 422/*
 423 * Drop an active count on a server object.
 424 */
 425void afs_unuse_server(struct afs_net *net, struct afs_server *server,
 426                      enum afs_server_trace reason)
 427{
 428        if (server) {
 429                server->unuse_time = ktime_get_real_seconds();
 430                afs_unuse_server_notime(net, server, reason);
 431        }
 432}
 433
 434static void afs_server_rcu(struct rcu_head *rcu)
 435{
 436        struct afs_server *server = container_of(rcu, struct afs_server, rcu);
 437
 438        trace_afs_server(server, atomic_read(&server->ref),
 439                         atomic_read(&server->active), afs_server_trace_free);
 440        afs_put_addrlist(rcu_access_pointer(server->addresses));
 441        kfree(server);
 442}
 443
 444static void __afs_put_server(struct afs_net *net, struct afs_server *server)
 445{
 446        call_rcu(&server->rcu, afs_server_rcu);
 447        afs_dec_servers_outstanding(net);
 448}
 449
 450static void afs_give_up_callbacks(struct afs_net *net, struct afs_server *server)
 451{
 452        struct afs_addr_list *alist = rcu_access_pointer(server->addresses);
 453        struct afs_addr_cursor ac = {
 454                .alist  = alist,
 455                .index  = alist->preferred,
 456                .error  = 0,
 457        };
 458
 459        afs_fs_give_up_all_callbacks(net, server, &ac, NULL);
 460}
 461
 462/*
 463 * destroy a dead server
 464 */
 465static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
 466{
 467        if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))
 468                afs_give_up_callbacks(net, server);
 469
 470        afs_put_server(net, server, afs_server_trace_destroy);
 471}
 472
 473/*
 474 * Garbage collect any expired servers.
 475 */
 476static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)
 477{
 478        struct afs_server *server, *next, *prev;
 479        int active;
 480
 481        while ((server = gc_list)) {
 482                gc_list = server->gc_next;
 483
 484                write_seqlock(&net->fs_lock);
 485
 486                active = atomic_read(&server->active);
 487                if (active == 0) {
 488                        trace_afs_server(server, atomic_read(&server->ref),
 489                                         active, afs_server_trace_gc);
 490                        next = rcu_dereference_protected(
 491                                server->uuid_next, lockdep_is_held(&net->fs_lock.lock));
 492                        prev = server->uuid_prev;
 493                        if (!prev) {
 494                                /* The one at the front is in the tree */
 495                                if (!next) {
 496                                        rb_erase(&server->uuid_rb, &net->fs_servers);
 497                                } else {
 498                                        rb_replace_node_rcu(&server->uuid_rb,
 499                                                            &next->uuid_rb,
 500                                                            &net->fs_servers);
 501                                        next->uuid_prev = NULL;
 502                                }
 503                        } else {
 504                                /* This server is not at the front */
 505                                rcu_assign_pointer(prev->uuid_next, next);
 506                                if (next)
 507                                        next->uuid_prev = prev;
 508                        }
 509
 510                        list_del(&server->probe_link);
 511                        hlist_del_rcu(&server->proc_link);
 512                        if (!hlist_unhashed(&server->addr4_link))
 513                                hlist_del_rcu(&server->addr4_link);
 514                        if (!hlist_unhashed(&server->addr6_link))
 515                                hlist_del_rcu(&server->addr6_link);
 516                }
 517                write_sequnlock(&net->fs_lock);
 518
 519                if (active == 0)
 520                        afs_destroy_server(net, server);
 521        }
 522}
 523
 524/*
 525 * Manage the records of servers known to be within a network namespace.  This
 526 * includes garbage collecting unused servers.
 527 *
 528 * Note also that we were given an increment on net->servers_outstanding by
 529 * whoever queued us that we need to deal with before returning.
 530 */
 531void afs_manage_servers(struct work_struct *work)
 532{
 533        struct afs_net *net = container_of(work, struct afs_net, fs_manager);
 534        struct afs_server *gc_list = NULL;
 535        struct rb_node *cursor;
 536        time64_t now = ktime_get_real_seconds(), next_manage = TIME64_MAX;
 537        bool purging = !net->live;
 538
 539        _enter("");
 540
 541        /* Trawl the server list looking for servers that have expired from
 542         * lack of use.
 543         */
 544        read_seqlock_excl(&net->fs_lock);
 545
 546        for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) {
 547                struct afs_server *server =
 548                        rb_entry(cursor, struct afs_server, uuid_rb);
 549                int active = atomic_read(&server->active);
 550
 551                _debug("manage %pU %u", &server->uuid, active);
 552
 553                if (purging) {
 554                        trace_afs_server(server, atomic_read(&server->ref),
 555                                         active, afs_server_trace_purging);
 556                        if (active != 0)
 557                                pr_notice("Can't purge s=%08x\n", server->debug_id);
 558                }
 559
 560                if (active == 0) {
 561                        time64_t expire_at = server->unuse_time;
 562
 563                        if (!test_bit(AFS_SERVER_FL_VL_FAIL, &server->flags) &&
 564                            !test_bit(AFS_SERVER_FL_NOT_FOUND, &server->flags))
 565                                expire_at += afs_server_gc_delay;
 566                        if (purging || expire_at <= now) {
 567                                server->gc_next = gc_list;
 568                                gc_list = server;
 569                        } else if (expire_at < next_manage) {
 570                                next_manage = expire_at;
 571                        }
 572                }
 573        }
 574
 575        read_sequnlock_excl(&net->fs_lock);
 576
 577        /* Update the timer on the way out.  We have to pass an increment on
 578         * servers_outstanding in the namespace that we are in to the timer or
 579         * the work scheduler.
 580         */
 581        if (!purging && next_manage < TIME64_MAX) {
 582                now = ktime_get_real_seconds();
 583
 584                if (next_manage - now <= 0) {
 585                        if (queue_work(afs_wq, &net->fs_manager))
 586                                afs_inc_servers_outstanding(net);
 587                } else {
 588                        afs_set_server_timer(net, next_manage - now);
 589                }
 590        }
 591
 592        afs_gc_servers(net, gc_list);
 593
 594        afs_dec_servers_outstanding(net);
 595        _leave(" [%d]", atomic_read(&net->servers_outstanding));
 596}
 597
 598static void afs_queue_server_manager(struct afs_net *net)
 599{
 600        afs_inc_servers_outstanding(net);
 601        if (!queue_work(afs_wq, &net->fs_manager))
 602                afs_dec_servers_outstanding(net);
 603}
 604
 605/*
 606 * Purge list of servers.
 607 */
 608void afs_purge_servers(struct afs_net *net)
 609{
 610        _enter("");
 611
 612        if (del_timer_sync(&net->fs_timer))
 613                afs_dec_servers_outstanding(net);
 614
 615        afs_queue_server_manager(net);
 616
 617        _debug("wait");
 618        atomic_dec(&net->servers_outstanding);
 619        wait_var_event(&net->servers_outstanding,
 620                       !atomic_read(&net->servers_outstanding));
 621        _leave("");
 622}
 623
 624/*
 625 * Get an update for a server's address list.
 626 */
 627static noinline bool afs_update_server_record(struct afs_operation *op,
 628                                              struct afs_server *server)
 629{
 630        struct afs_addr_list *alist, *discard;
 631
 632        _enter("");
 633
 634        trace_afs_server(server, atomic_read(&server->ref), atomic_read(&server->active),
 635                         afs_server_trace_update);
 636
 637        alist = afs_vl_lookup_addrs(op->volume->cell, op->key, &server->uuid);
 638        if (IS_ERR(alist)) {
 639                if ((PTR_ERR(alist) == -ERESTARTSYS ||
 640                     PTR_ERR(alist) == -EINTR) &&
 641                    (op->flags & AFS_OPERATION_UNINTR) &&
 642                    server->addresses) {
 643                        _leave(" = t [intr]");
 644                        return true;
 645                }
 646                op->error = PTR_ERR(alist);
 647                _leave(" = f [%d]", op->error);
 648                return false;
 649        }
 650
 651        discard = alist;
 652        if (server->addr_version != alist->version) {
 653                write_lock(&server->fs_lock);
 654                discard = rcu_dereference_protected(server->addresses,
 655                                                    lockdep_is_held(&server->fs_lock));
 656                rcu_assign_pointer(server->addresses, alist);
 657                server->addr_version = alist->version;
 658                write_unlock(&server->fs_lock);
 659        }
 660
 661        afs_put_addrlist(discard);
 662        _leave(" = t");
 663        return true;
 664}
 665
 666/*
 667 * See if a server's address list needs updating.
 668 */
 669bool afs_check_server_record(struct afs_operation *op, struct afs_server *server)
 670{
 671        bool success;
 672        int ret, retries = 0;
 673
 674        _enter("");
 675
 676        ASSERT(server);
 677
 678retry:
 679        if (test_bit(AFS_SERVER_FL_UPDATING, &server->flags))
 680                goto wait;
 681        if (test_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags))
 682                goto update;
 683        _leave(" = t [good]");
 684        return true;
 685
 686update:
 687        if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) {
 688                clear_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
 689                success = afs_update_server_record(op, server);
 690                clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags);
 691                wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING);
 692                _leave(" = %d", success);
 693                return success;
 694        }
 695
 696wait:
 697        ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
 698                          (op->flags & AFS_OPERATION_UNINTR) ?
 699                          TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
 700        if (ret == -ERESTARTSYS) {
 701                op->error = ret;
 702                _leave(" = f [intr]");
 703                return false;
 704        }
 705
 706        retries++;
 707        if (retries == 4) {
 708                _leave(" = f [stale]");
 709                ret = -ESTALE;
 710                return false;
 711        }
 712        goto retry;
 713}
 714