linux/fs/nfs/delegation.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * linux/fs/nfs/delegation.c
   4 *
   5 * Copyright (C) 2004 Trond Myklebust
   6 *
   7 * NFS file delegation management
   8 *
   9 */
  10#include <linux/completion.h>
  11#include <linux/kthread.h>
  12#include <linux/module.h>
  13#include <linux/sched.h>
  14#include <linux/slab.h>
  15#include <linux/spinlock.h>
  16#include <linux/iversion.h>
  17
  18#include <linux/nfs4.h>
  19#include <linux/nfs_fs.h>
  20#include <linux/nfs_xdr.h>
  21
  22#include "nfs4_fs.h"
  23#include "nfs4session.h"
  24#include "delegation.h"
  25#include "internal.h"
  26#include "nfs4trace.h"
  27
  28#define NFS_DEFAULT_DELEGATION_WATERMARK (5000U)
  29
  30static atomic_long_t nfs_active_delegations;
  31static unsigned nfs_delegation_watermark = NFS_DEFAULT_DELEGATION_WATERMARK;
  32
  33static void __nfs_free_delegation(struct nfs_delegation *delegation)
  34{
  35        put_cred(delegation->cred);
  36        delegation->cred = NULL;
  37        kfree_rcu(delegation, rcu);
  38}
  39
  40static void nfs_mark_delegation_revoked(struct nfs_delegation *delegation)
  41{
  42        if (!test_and_set_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
  43                delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
  44                atomic_long_dec(&nfs_active_delegations);
  45                if (!test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
  46                        nfs_clear_verifier_delegated(delegation->inode);
  47        }
  48}
  49
  50static struct nfs_delegation *nfs_get_delegation(struct nfs_delegation *delegation)
  51{
  52        refcount_inc(&delegation->refcount);
  53        return delegation;
  54}
  55
  56static void nfs_put_delegation(struct nfs_delegation *delegation)
  57{
  58        if (refcount_dec_and_test(&delegation->refcount))
  59                __nfs_free_delegation(delegation);
  60}
  61
  62static void nfs_free_delegation(struct nfs_delegation *delegation)
  63{
  64        nfs_mark_delegation_revoked(delegation);
  65        nfs_put_delegation(delegation);
  66}
  67
  68/**
  69 * nfs_mark_delegation_referenced - set delegation's REFERENCED flag
  70 * @delegation: delegation to process
  71 *
  72 */
  73void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
  74{
  75        set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
  76}
  77
  78static bool
  79nfs4_is_valid_delegation(const struct nfs_delegation *delegation,
  80                fmode_t flags)
  81{
  82        if (delegation != NULL && (delegation->type & flags) == flags &&
  83            !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
  84            !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
  85                return true;
  86        return false;
  87}
  88
  89struct nfs_delegation *nfs4_get_valid_delegation(const struct inode *inode)
  90{
  91        struct nfs_delegation *delegation;
  92
  93        delegation = rcu_dereference(NFS_I(inode)->delegation);
  94        if (nfs4_is_valid_delegation(delegation, 0))
  95                return delegation;
  96        return NULL;
  97}
  98
  99static int
 100nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark)
 101{
 102        struct nfs_delegation *delegation;
 103        int ret = 0;
 104
 105        flags &= FMODE_READ|FMODE_WRITE;
 106        rcu_read_lock();
 107        delegation = rcu_dereference(NFS_I(inode)->delegation);
 108        if (nfs4_is_valid_delegation(delegation, flags)) {
 109                if (mark)
 110                        nfs_mark_delegation_referenced(delegation);
 111                ret = 1;
 112        }
 113        rcu_read_unlock();
 114        return ret;
 115}
 116/**
 117 * nfs_have_delegation - check if inode has a delegation, mark it
 118 * NFS_DELEGATION_REFERENCED if there is one.
 119 * @inode: inode to check
 120 * @flags: delegation types to check for
 121 *
 122 * Returns one if inode has the indicated delegation, otherwise zero.
 123 */
 124int nfs4_have_delegation(struct inode *inode, fmode_t flags)
 125{
 126        return nfs4_do_check_delegation(inode, flags, true);
 127}
 128
 129/*
 130 * nfs4_check_delegation - check if inode has a delegation, do not mark
 131 * NFS_DELEGATION_REFERENCED if it has one.
 132 */
 133int nfs4_check_delegation(struct inode *inode, fmode_t flags)
 134{
 135        return nfs4_do_check_delegation(inode, flags, false);
 136}
 137
 138static int nfs_delegation_claim_locks(struct nfs4_state *state, const nfs4_stateid *stateid)
 139{
 140        struct inode *inode = state->inode;
 141        struct file_lock *fl;
 142        struct file_lock_context *flctx = inode->i_flctx;
 143        struct list_head *list;
 144        int status = 0;
 145
 146        if (flctx == NULL)
 147                goto out;
 148
 149        list = &flctx->flc_posix;
 150        spin_lock(&flctx->flc_lock);
 151restart:
 152        list_for_each_entry(fl, list, fl_list) {
 153                if (nfs_file_open_context(fl->fl_file)->state != state)
 154                        continue;
 155                spin_unlock(&flctx->flc_lock);
 156                status = nfs4_lock_delegation_recall(fl, state, stateid);
 157                if (status < 0)
 158                        goto out;
 159                spin_lock(&flctx->flc_lock);
 160        }
 161        if (list == &flctx->flc_posix) {
 162                list = &flctx->flc_flock;
 163                goto restart;
 164        }
 165        spin_unlock(&flctx->flc_lock);
 166out:
 167        return status;
 168}
 169
 170static int nfs_delegation_claim_opens(struct inode *inode,
 171                const nfs4_stateid *stateid, fmode_t type)
 172{
 173        struct nfs_inode *nfsi = NFS_I(inode);
 174        struct nfs_open_context *ctx;
 175        struct nfs4_state_owner *sp;
 176        struct nfs4_state *state;
 177        unsigned int seq;
 178        int err;
 179
 180again:
 181        rcu_read_lock();
 182        list_for_each_entry_rcu(ctx, &nfsi->open_files, list) {
 183                state = ctx->state;
 184                if (state == NULL)
 185                        continue;
 186                if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
 187                        continue;
 188                if (!nfs4_valid_open_stateid(state))
 189                        continue;
 190                if (!nfs4_stateid_match(&state->stateid, stateid))
 191                        continue;
 192                if (!get_nfs_open_context(ctx))
 193                        continue;
 194                rcu_read_unlock();
 195                sp = state->owner;
 196                /* Block nfs4_proc_unlck */
 197                mutex_lock(&sp->so_delegreturn_mutex);
 198                seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
 199                err = nfs4_open_delegation_recall(ctx, state, stateid);
 200                if (!err)
 201                        err = nfs_delegation_claim_locks(state, stateid);
 202                if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
 203                        err = -EAGAIN;
 204                mutex_unlock(&sp->so_delegreturn_mutex);
 205                put_nfs_open_context(ctx);
 206                if (err != 0)
 207                        return err;
 208                goto again;
 209        }
 210        rcu_read_unlock();
 211        return 0;
 212}
 213
 214/**
 215 * nfs_inode_reclaim_delegation - process a delegation reclaim request
 216 * @inode: inode to process
 217 * @cred: credential to use for request
 218 * @type: delegation type
 219 * @stateid: delegation stateid
 220 * @pagemod_limit: write delegation "space_limit"
 221 *
 222 */
 223void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
 224                                  fmode_t type,
 225                                  const nfs4_stateid *stateid,
 226                                  unsigned long pagemod_limit)
 227{
 228        struct nfs_delegation *delegation;
 229        const struct cred *oldcred = NULL;
 230
 231        rcu_read_lock();
 232        delegation = rcu_dereference(NFS_I(inode)->delegation);
 233        if (delegation != NULL) {
 234                spin_lock(&delegation->lock);
 235                if (nfs4_is_valid_delegation(delegation, 0)) {
 236                        nfs4_stateid_copy(&delegation->stateid, stateid);
 237                        delegation->type = type;
 238                        delegation->pagemod_limit = pagemod_limit;
 239                        oldcred = delegation->cred;
 240                        delegation->cred = get_cred(cred);
 241                        clear_bit(NFS_DELEGATION_NEED_RECLAIM,
 242                                  &delegation->flags);
 243                        spin_unlock(&delegation->lock);
 244                        rcu_read_unlock();
 245                        put_cred(oldcred);
 246                        trace_nfs4_reclaim_delegation(inode, type);
 247                        return;
 248                }
 249                /* We appear to have raced with a delegation return. */
 250                spin_unlock(&delegation->lock);
 251        }
 252        rcu_read_unlock();
 253        nfs_inode_set_delegation(inode, cred, type, stateid, pagemod_limit);
 254}
 255
 256static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
 257{
 258        const struct cred *cred;
 259        int res = 0;
 260
 261        if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
 262                spin_lock(&delegation->lock);
 263                cred = get_cred(delegation->cred);
 264                spin_unlock(&delegation->lock);
 265                res = nfs4_proc_delegreturn(inode, cred,
 266                                &delegation->stateid,
 267                                issync);
 268                put_cred(cred);
 269        }
 270        return res;
 271}
 272
 273static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation)
 274{
 275        struct inode *inode = NULL;
 276
 277        spin_lock(&delegation->lock);
 278        if (delegation->inode != NULL)
 279                inode = igrab(delegation->inode);
 280        if (!inode)
 281                set_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags);
 282        spin_unlock(&delegation->lock);
 283        return inode;
 284}
 285
 286static struct nfs_delegation *
 287nfs_start_delegation_return_locked(struct nfs_inode *nfsi)
 288{
 289        struct nfs_delegation *ret = NULL;
 290        struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation);
 291
 292        if (delegation == NULL)
 293                goto out;
 294        spin_lock(&delegation->lock);
 295        if (!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
 296                /* Refcount matched in nfs_end_delegation_return() */
 297                ret = nfs_get_delegation(delegation);
 298        }
 299        spin_unlock(&delegation->lock);
 300        if (ret)
 301                nfs_clear_verifier_delegated(&nfsi->vfs_inode);
 302out:
 303        return ret;
 304}
 305
 306static struct nfs_delegation *
 307nfs_start_delegation_return(struct nfs_inode *nfsi)
 308{
 309        struct nfs_delegation *delegation;
 310
 311        rcu_read_lock();
 312        delegation = nfs_start_delegation_return_locked(nfsi);
 313        rcu_read_unlock();
 314        return delegation;
 315}
 316
 317static void
 318nfs_abort_delegation_return(struct nfs_delegation *delegation,
 319                struct nfs_client *clp)
 320{
 321
 322        spin_lock(&delegation->lock);
 323        clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
 324        set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
 325        spin_unlock(&delegation->lock);
 326        set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
 327}
 328
 329static struct nfs_delegation *
 330nfs_detach_delegation_locked(struct nfs_inode *nfsi,
 331                struct nfs_delegation *delegation,
 332                struct nfs_client *clp)
 333{
 334        struct nfs_delegation *deleg_cur =
 335                rcu_dereference_protected(nfsi->delegation,
 336                                lockdep_is_held(&clp->cl_lock));
 337
 338        if (deleg_cur == NULL || delegation != deleg_cur)
 339                return NULL;
 340
 341        spin_lock(&delegation->lock);
 342        if (!delegation->inode) {
 343                spin_unlock(&delegation->lock);
 344                return NULL;
 345        }
 346        list_del_rcu(&delegation->super_list);
 347        delegation->inode = NULL;
 348        rcu_assign_pointer(nfsi->delegation, NULL);
 349        spin_unlock(&delegation->lock);
 350        return delegation;
 351}
 352
 353static struct nfs_delegation *nfs_detach_delegation(struct nfs_inode *nfsi,
 354                struct nfs_delegation *delegation,
 355                struct nfs_server *server)
 356{
 357        struct nfs_client *clp = server->nfs_client;
 358
 359        spin_lock(&clp->cl_lock);
 360        delegation = nfs_detach_delegation_locked(nfsi, delegation, clp);
 361        spin_unlock(&clp->cl_lock);
 362        return delegation;
 363}
 364
 365static struct nfs_delegation *
 366nfs_inode_detach_delegation(struct inode *inode)
 367{
 368        struct nfs_inode *nfsi = NFS_I(inode);
 369        struct nfs_server *server = NFS_SERVER(inode);
 370        struct nfs_delegation *delegation;
 371
 372        rcu_read_lock();
 373        delegation = rcu_dereference(nfsi->delegation);
 374        if (delegation != NULL)
 375                delegation = nfs_detach_delegation(nfsi, delegation, server);
 376        rcu_read_unlock();
 377        return delegation;
 378}
 379
 380static void
 381nfs_update_delegation_cred(struct nfs_delegation *delegation,
 382                const struct cred *cred)
 383{
 384        const struct cred *old;
 385
 386        if (cred_fscmp(delegation->cred, cred) != 0) {
 387                old = xchg(&delegation->cred, get_cred(cred));
 388                put_cred(old);
 389        }
 390}
 391
 392static void
 393nfs_update_inplace_delegation(struct nfs_delegation *delegation,
 394                const struct nfs_delegation *update)
 395{
 396        if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) {
 397                delegation->stateid.seqid = update->stateid.seqid;
 398                smp_wmb();
 399                delegation->type = update->type;
 400                delegation->pagemod_limit = update->pagemod_limit;
 401                if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
 402                        delegation->change_attr = update->change_attr;
 403                        nfs_update_delegation_cred(delegation, update->cred);
 404                        /* smp_mb__before_atomic() is implicit due to xchg() */
 405                        clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
 406                        atomic_long_inc(&nfs_active_delegations);
 407                }
 408        }
 409}
 410
 411/**
 412 * nfs_inode_set_delegation - set up a delegation on an inode
 413 * @inode: inode to which delegation applies
 414 * @cred: cred to use for subsequent delegation processing
 415 * @type: delegation type
 416 * @stateid: delegation stateid
 417 * @pagemod_limit: write delegation "space_limit"
 418 *
 419 * Returns zero on success, or a negative errno value.
 420 */
 421int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
 422                                  fmode_t type,
 423                                  const nfs4_stateid *stateid,
 424                                  unsigned long pagemod_limit)
 425{
 426        struct nfs_server *server = NFS_SERVER(inode);
 427        struct nfs_client *clp = server->nfs_client;
 428        struct nfs_inode *nfsi = NFS_I(inode);
 429        struct nfs_delegation *delegation, *old_delegation;
 430        struct nfs_delegation *freeme = NULL;
 431        int status = 0;
 432
 433        delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
 434        if (delegation == NULL)
 435                return -ENOMEM;
 436        nfs4_stateid_copy(&delegation->stateid, stateid);
 437        refcount_set(&delegation->refcount, 1);
 438        delegation->type = type;
 439        delegation->pagemod_limit = pagemod_limit;
 440        delegation->change_attr = inode_peek_iversion_raw(inode);
 441        delegation->cred = get_cred(cred);
 442        delegation->inode = inode;
 443        delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
 444        spin_lock_init(&delegation->lock);
 445
 446        spin_lock(&clp->cl_lock);
 447        old_delegation = rcu_dereference_protected(nfsi->delegation,
 448                                        lockdep_is_held(&clp->cl_lock));
 449        if (old_delegation == NULL)
 450                goto add_new;
 451        /* Is this an update of the existing delegation? */
 452        if (nfs4_stateid_match_other(&old_delegation->stateid,
 453                                &delegation->stateid)) {
 454                spin_lock(&old_delegation->lock);
 455                nfs_update_inplace_delegation(old_delegation,
 456                                delegation);
 457                spin_unlock(&old_delegation->lock);
 458                goto out;
 459        }
 460        if (!test_bit(NFS_DELEGATION_REVOKED, &old_delegation->flags)) {
 461                /*
 462                 * Deal with broken servers that hand out two
 463                 * delegations for the same file.
 464                 * Allow for upgrades to a WRITE delegation, but
 465                 * nothing else.
 466                 */
 467                dfprintk(FILE, "%s: server %s handed out "
 468                                "a duplicate delegation!\n",
 469                                __func__, clp->cl_hostname);
 470                if (delegation->type == old_delegation->type ||
 471                    !(delegation->type & FMODE_WRITE)) {
 472                        freeme = delegation;
 473                        delegation = NULL;
 474                        goto out;
 475                }
 476                if (test_and_set_bit(NFS_DELEGATION_RETURNING,
 477                                        &old_delegation->flags))
 478                        goto out;
 479        }
 480        freeme = nfs_detach_delegation_locked(nfsi, old_delegation, clp);
 481        if (freeme == NULL)
 482                goto out;
 483add_new:
 484        list_add_tail_rcu(&delegation->super_list, &server->delegations);
 485        rcu_assign_pointer(nfsi->delegation, delegation);
 486        delegation = NULL;
 487
 488        atomic_long_inc(&nfs_active_delegations);
 489
 490        trace_nfs4_set_delegation(inode, type);
 491
 492        spin_lock(&inode->i_lock);
 493        if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME))
 494                NFS_I(inode)->cache_validity |= NFS_INO_REVAL_FORCED;
 495        spin_unlock(&inode->i_lock);
 496out:
 497        spin_unlock(&clp->cl_lock);
 498        if (delegation != NULL)
 499                __nfs_free_delegation(delegation);
 500        if (freeme != NULL) {
 501                nfs_do_return_delegation(inode, freeme, 0);
 502                nfs_free_delegation(freeme);
 503        }
 504        return status;
 505}
 506
 507/*
 508 * Basic procedure for returning a delegation to the server
 509 */
 510static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation *delegation, int issync)
 511{
 512        struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
 513        int err = 0;
 514
 515        if (delegation == NULL)
 516                return 0;
 517        do {
 518                if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
 519                        break;
 520                err = nfs_delegation_claim_opens(inode, &delegation->stateid,
 521                                delegation->type);
 522                if (!issync || err != -EAGAIN)
 523                        break;
 524                /*
 525                 * Guard against state recovery
 526                 */
 527                err = nfs4_wait_clnt_recover(clp);
 528        } while (err == 0);
 529
 530        if (err) {
 531                nfs_abort_delegation_return(delegation, clp);
 532                goto out;
 533        }
 534
 535        err = nfs_do_return_delegation(inode, delegation, issync);
 536out:
 537        /* Refcount matched in nfs_start_delegation_return_locked() */
 538        nfs_put_delegation(delegation);
 539        return err;
 540}
 541
 542static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
 543{
 544        bool ret = false;
 545
 546        if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
 547                ret = true;
 548        else if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) {
 549                struct inode *inode;
 550
 551                spin_lock(&delegation->lock);
 552                inode = delegation->inode;
 553                if (inode && list_empty(&NFS_I(inode)->open_files))
 554                        ret = true;
 555                spin_unlock(&delegation->lock);
 556        }
 557        if (ret)
 558                clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
 559        if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags) ||
 560            test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
 561                ret = false;
 562
 563        return ret;
 564}
 565
 566static int nfs_server_return_marked_delegations(struct nfs_server *server,
 567                void __always_unused *data)
 568{
 569        struct nfs_delegation *delegation;
 570        struct nfs_delegation *prev;
 571        struct inode *inode;
 572        struct inode *place_holder = NULL;
 573        struct nfs_delegation *place_holder_deleg = NULL;
 574        int err = 0;
 575
 576restart:
 577        /*
 578         * To avoid quadratic looping we hold a reference
 579         * to an inode place_holder.  Each time we restart, we
 580         * list delegation in the server from the delegations
 581         * of that inode.
 582         * prev is an RCU-protected pointer to a delegation which
 583         * wasn't marked for return and might be a good choice for
 584         * the next place_holder.
 585         */
 586        prev = NULL;
 587        delegation = NULL;
 588        rcu_read_lock();
 589        if (place_holder)
 590                delegation = rcu_dereference(NFS_I(place_holder)->delegation);
 591        if (!delegation || delegation != place_holder_deleg)
 592                delegation = list_entry_rcu(server->delegations.next,
 593                                            struct nfs_delegation, super_list);
 594        list_for_each_entry_from_rcu(delegation, &server->delegations, super_list) {
 595                struct inode *to_put = NULL;
 596
 597                if (test_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags))
 598                        continue;
 599                if (!nfs_delegation_need_return(delegation)) {
 600                        if (nfs4_is_valid_delegation(delegation, 0))
 601                                prev = delegation;
 602                        continue;
 603                }
 604
 605                if (prev) {
 606                        struct inode *tmp = nfs_delegation_grab_inode(prev);
 607                        if (tmp) {
 608                                to_put = place_holder;
 609                                place_holder = tmp;
 610                                place_holder_deleg = prev;
 611                        }
 612                }
 613
 614                inode = nfs_delegation_grab_inode(delegation);
 615                if (inode == NULL) {
 616                        rcu_read_unlock();
 617                        iput(to_put);
 618                        goto restart;
 619                }
 620                delegation = nfs_start_delegation_return_locked(NFS_I(inode));
 621                rcu_read_unlock();
 622
 623                iput(to_put);
 624
 625                err = nfs_end_delegation_return(inode, delegation, 0);
 626                iput(inode);
 627                cond_resched();
 628                if (!err)
 629                        goto restart;
 630                set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
 631                goto out;
 632        }
 633        rcu_read_unlock();
 634out:
 635        iput(place_holder);
 636        return err;
 637}
 638
 639/**
 640 * nfs_client_return_marked_delegations - return previously marked delegations
 641 * @clp: nfs_client to process
 642 *
 643 * Note that this function is designed to be called by the state
 644 * manager thread. For this reason, it cannot flush the dirty data,
 645 * since that could deadlock in case of a state recovery error.
 646 *
 647 * Returns zero on success, or a negative errno value.
 648 */
 649int nfs_client_return_marked_delegations(struct nfs_client *clp)
 650{
 651        return nfs_client_for_each_server(clp,
 652                        nfs_server_return_marked_delegations, NULL);
 653}
 654
 655/**
 656 * nfs_inode_evict_delegation - return delegation, don't reclaim opens
 657 * @inode: inode to process
 658 *
 659 * Does not protect against delegation reclaims, therefore really only safe
 660 * to be called from nfs4_clear_inode(). Guaranteed to always free
 661 * the delegation structure.
 662 */
 663void nfs_inode_evict_delegation(struct inode *inode)
 664{
 665        struct nfs_delegation *delegation;
 666
 667        delegation = nfs_inode_detach_delegation(inode);
 668        if (delegation != NULL) {
 669                set_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
 670                set_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags);
 671                nfs_do_return_delegation(inode, delegation, 1);
 672                nfs_free_delegation(delegation);
 673        }
 674}
 675
 676/**
 677 * nfs_inode_return_delegation - synchronously return a delegation
 678 * @inode: inode to process
 679 *
 680 * This routine will always flush any dirty data to disk on the
 681 * assumption that if we need to return the delegation, then
 682 * we should stop caching.
 683 *
 684 * Returns zero on success, or a negative errno value.
 685 */
 686int nfs4_inode_return_delegation(struct inode *inode)
 687{
 688        struct nfs_inode *nfsi = NFS_I(inode);
 689        struct nfs_delegation *delegation;
 690        int err = 0;
 691
 692        nfs_wb_all(inode);
 693        delegation = nfs_start_delegation_return(nfsi);
 694        if (delegation != NULL)
 695                err = nfs_end_delegation_return(inode, delegation, 1);
 696        return err;
 697}
 698
 699/**
 700 * nfs_inode_return_delegation_on_close - asynchronously return a delegation
 701 * @inode: inode to process
 702 *
 703 * This routine is called on file close in order to determine if the
 704 * inode delegation needs to be returned immediately.
 705 */
 706void nfs4_inode_return_delegation_on_close(struct inode *inode)
 707{
 708        struct nfs_delegation *delegation;
 709        struct nfs_delegation *ret = NULL;
 710
 711        if (!inode)
 712                return;
 713        rcu_read_lock();
 714        delegation = nfs4_get_valid_delegation(inode);
 715        if (!delegation)
 716                goto out;
 717        if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) ||
 718            atomic_long_read(&nfs_active_delegations) >= nfs_delegation_watermark) {
 719                spin_lock(&delegation->lock);
 720                if (delegation->inode &&
 721                    list_empty(&NFS_I(inode)->open_files) &&
 722                    !test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
 723                        clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
 724                        /* Refcount matched in nfs_end_delegation_return() */
 725                        ret = nfs_get_delegation(delegation);
 726                }
 727                spin_unlock(&delegation->lock);
 728                if (ret)
 729                        nfs_clear_verifier_delegated(inode);
 730        }
 731out:
 732        rcu_read_unlock();
 733        nfs_end_delegation_return(inode, ret, 0);
 734}
 735
 736/**
 737 * nfs4_inode_make_writeable
 738 * @inode: pointer to inode
 739 *
 740 * Make the inode writeable by returning the delegation if necessary
 741 *
 742 * Returns zero on success, or a negative errno value.
 743 */
 744int nfs4_inode_make_writeable(struct inode *inode)
 745{
 746        struct nfs_delegation *delegation;
 747
 748        rcu_read_lock();
 749        delegation = nfs4_get_valid_delegation(inode);
 750        if (delegation == NULL ||
 751            (nfs4_has_session(NFS_SERVER(inode)->nfs_client) &&
 752             (delegation->type & FMODE_WRITE))) {
 753                rcu_read_unlock();
 754                return 0;
 755        }
 756        rcu_read_unlock();
 757        return nfs4_inode_return_delegation(inode);
 758}
 759
 760static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
 761                struct nfs_delegation *delegation)
 762{
 763        set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
 764        set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
 765}
 766
 767static void nfs_mark_return_delegation(struct nfs_server *server,
 768                struct nfs_delegation *delegation)
 769{
 770        set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
 771        set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
 772}
 773
 774static bool nfs_server_mark_return_all_delegations(struct nfs_server *server)
 775{
 776        struct nfs_delegation *delegation;
 777        bool ret = false;
 778
 779        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
 780                nfs_mark_return_delegation(server, delegation);
 781                ret = true;
 782        }
 783        return ret;
 784}
 785
 786static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
 787{
 788        struct nfs_server *server;
 789
 790        rcu_read_lock();
 791        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
 792                nfs_server_mark_return_all_delegations(server);
 793        rcu_read_unlock();
 794}
 795
 796static void nfs_delegation_run_state_manager(struct nfs_client *clp)
 797{
 798        if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
 799                nfs4_schedule_state_manager(clp);
 800}
 801
 802/**
 803 * nfs_expire_all_delegations
 804 * @clp: client to process
 805 *
 806 */
 807void nfs_expire_all_delegations(struct nfs_client *clp)
 808{
 809        nfs_client_mark_return_all_delegations(clp);
 810        nfs_delegation_run_state_manager(clp);
 811}
 812
 813/**
 814 * nfs_super_return_all_delegations - return delegations for one superblock
 815 * @server: pointer to nfs_server to process
 816 *
 817 */
 818void nfs_server_return_all_delegations(struct nfs_server *server)
 819{
 820        struct nfs_client *clp = server->nfs_client;
 821        bool need_wait;
 822
 823        if (clp == NULL)
 824                return;
 825
 826        rcu_read_lock();
 827        need_wait = nfs_server_mark_return_all_delegations(server);
 828        rcu_read_unlock();
 829
 830        if (need_wait) {
 831                nfs4_schedule_state_manager(clp);
 832                nfs4_wait_clnt_recover(clp);
 833        }
 834}
 835
 836static void nfs_mark_return_unused_delegation_types(struct nfs_server *server,
 837                                                 fmode_t flags)
 838{
 839        struct nfs_delegation *delegation;
 840
 841        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
 842                if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
 843                        continue;
 844                if (delegation->type & flags)
 845                        nfs_mark_return_if_closed_delegation(server, delegation);
 846        }
 847}
 848
 849static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *clp,
 850                                                        fmode_t flags)
 851{
 852        struct nfs_server *server;
 853
 854        rcu_read_lock();
 855        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
 856                nfs_mark_return_unused_delegation_types(server, flags);
 857        rcu_read_unlock();
 858}
 859
 860static void nfs_revoke_delegation(struct inode *inode,
 861                const nfs4_stateid *stateid)
 862{
 863        struct nfs_delegation *delegation;
 864        nfs4_stateid tmp;
 865        bool ret = false;
 866
 867        rcu_read_lock();
 868        delegation = rcu_dereference(NFS_I(inode)->delegation);
 869        if (delegation == NULL)
 870                goto out;
 871        if (stateid == NULL) {
 872                nfs4_stateid_copy(&tmp, &delegation->stateid);
 873                stateid = &tmp;
 874        } else {
 875                if (!nfs4_stateid_match_other(stateid, &delegation->stateid))
 876                        goto out;
 877                spin_lock(&delegation->lock);
 878                if (stateid->seqid) {
 879                        if (nfs4_stateid_is_newer(&delegation->stateid, stateid)) {
 880                                spin_unlock(&delegation->lock);
 881                                goto out;
 882                        }
 883                        delegation->stateid.seqid = stateid->seqid;
 884                }
 885                spin_unlock(&delegation->lock);
 886        }
 887        nfs_mark_delegation_revoked(delegation);
 888        ret = true;
 889out:
 890        rcu_read_unlock();
 891        if (ret)
 892                nfs_inode_find_state_and_recover(inode, stateid);
 893}
 894
 895void nfs_remove_bad_delegation(struct inode *inode,
 896                const nfs4_stateid *stateid)
 897{
 898        nfs_revoke_delegation(inode, stateid);
 899}
 900EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);
 901
 902void nfs_delegation_mark_returned(struct inode *inode,
 903                const nfs4_stateid *stateid)
 904{
 905        struct nfs_delegation *delegation;
 906
 907        if (!inode)
 908                return;
 909
 910        rcu_read_lock();
 911        delegation = rcu_dereference(NFS_I(inode)->delegation);
 912        if (!delegation)
 913                goto out_rcu_unlock;
 914
 915        spin_lock(&delegation->lock);
 916        if (!nfs4_stateid_match_other(stateid, &delegation->stateid))
 917                goto out_spin_unlock;
 918        if (stateid->seqid) {
 919                /* If delegation->stateid is newer, dont mark as returned */
 920                if (nfs4_stateid_is_newer(&delegation->stateid, stateid))
 921                        goto out_clear_returning;
 922                if (delegation->stateid.seqid != stateid->seqid)
 923                        delegation->stateid.seqid = stateid->seqid;
 924        }
 925
 926        nfs_mark_delegation_revoked(delegation);
 927
 928out_clear_returning:
 929        clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
 930out_spin_unlock:
 931        spin_unlock(&delegation->lock);
 932out_rcu_unlock:
 933        rcu_read_unlock();
 934
 935        nfs_inode_find_state_and_recover(inode, stateid);
 936}
 937
 938/**
 939 * nfs_expire_unused_delegation_types
 940 * @clp: client to process
 941 * @flags: delegation types to expire
 942 *
 943 */
 944void nfs_expire_unused_delegation_types(struct nfs_client *clp, fmode_t flags)
 945{
 946        nfs_client_mark_return_unused_delegation_types(clp, flags);
 947        nfs_delegation_run_state_manager(clp);
 948}
 949
 950static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server)
 951{
 952        struct nfs_delegation *delegation;
 953
 954        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
 955                if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
 956                        continue;
 957                nfs_mark_return_if_closed_delegation(server, delegation);
 958        }
 959}
 960
 961/**
 962 * nfs_expire_unreferenced_delegations - Eliminate unused delegations
 963 * @clp: nfs_client to process
 964 *
 965 */
 966void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
 967{
 968        struct nfs_server *server;
 969
 970        rcu_read_lock();
 971        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
 972                nfs_mark_return_unreferenced_delegations(server);
 973        rcu_read_unlock();
 974
 975        nfs_delegation_run_state_manager(clp);
 976}
 977
 978/**
 979 * nfs_async_inode_return_delegation - asynchronously return a delegation
 980 * @inode: inode to process
 981 * @stateid: state ID information
 982 *
 983 * Returns zero on success, or a negative errno value.
 984 */
 985int nfs_async_inode_return_delegation(struct inode *inode,
 986                                      const nfs4_stateid *stateid)
 987{
 988        struct nfs_server *server = NFS_SERVER(inode);
 989        struct nfs_client *clp = server->nfs_client;
 990        struct nfs_delegation *delegation;
 991
 992        rcu_read_lock();
 993        delegation = nfs4_get_valid_delegation(inode);
 994        if (delegation == NULL)
 995                goto out_enoent;
 996        if (stateid != NULL &&
 997            !clp->cl_mvops->match_stateid(&delegation->stateid, stateid))
 998                goto out_enoent;
 999        nfs_mark_return_delegation(server, delegation);
1000        rcu_read_unlock();
1001
1002        nfs_delegation_run_state_manager(clp);
1003        return 0;
1004out_enoent:
1005        rcu_read_unlock();
1006        return -ENOENT;
1007}
1008
1009static struct inode *
1010nfs_delegation_find_inode_server(struct nfs_server *server,
1011                                 const struct nfs_fh *fhandle)
1012{
1013        struct nfs_delegation *delegation;
1014        struct inode *freeme, *res = NULL;
1015
1016        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
1017                spin_lock(&delegation->lock);
1018                if (delegation->inode != NULL &&
1019                    !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
1020                    nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
1021                        freeme = igrab(delegation->inode);
1022                        if (freeme && nfs_sb_active(freeme->i_sb))
1023                                res = freeme;
1024                        spin_unlock(&delegation->lock);
1025                        if (res != NULL)
1026                                return res;
1027                        if (freeme) {
1028                                rcu_read_unlock();
1029                                iput(freeme);
1030                                rcu_read_lock();
1031                        }
1032                        return ERR_PTR(-EAGAIN);
1033                }
1034                spin_unlock(&delegation->lock);
1035        }
1036        return ERR_PTR(-ENOENT);
1037}
1038
1039/**
1040 * nfs_delegation_find_inode - retrieve the inode associated with a delegation
1041 * @clp: client state handle
1042 * @fhandle: filehandle from a delegation recall
1043 *
1044 * Returns pointer to inode matching "fhandle," or NULL if a matching inode
1045 * cannot be found.
1046 */
1047struct inode *nfs_delegation_find_inode(struct nfs_client *clp,
1048                                        const struct nfs_fh *fhandle)
1049{
1050        struct nfs_server *server;
1051        struct inode *res;
1052
1053        rcu_read_lock();
1054        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
1055                res = nfs_delegation_find_inode_server(server, fhandle);
1056                if (res != ERR_PTR(-ENOENT)) {
1057                        rcu_read_unlock();
1058                        return res;
1059                }
1060        }
1061        rcu_read_unlock();
1062        return ERR_PTR(-ENOENT);
1063}
1064
1065static void nfs_delegation_mark_reclaim_server(struct nfs_server *server)
1066{
1067        struct nfs_delegation *delegation;
1068
1069        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
1070                /*
1071                 * If the delegation may have been admin revoked, then we
1072                 * cannot reclaim it.
1073                 */
1074                if (test_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags))
1075                        continue;
1076                set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
1077        }
1078}
1079
1080/**
1081 * nfs_delegation_mark_reclaim - mark all delegations as needing to be reclaimed
1082 * @clp: nfs_client to process
1083 *
1084 */
1085void nfs_delegation_mark_reclaim(struct nfs_client *clp)
1086{
1087        struct nfs_server *server;
1088
1089        rcu_read_lock();
1090        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1091                nfs_delegation_mark_reclaim_server(server);
1092        rcu_read_unlock();
1093}
1094
1095static int nfs_server_reap_unclaimed_delegations(struct nfs_server *server,
1096                void __always_unused *data)
1097{
1098        struct nfs_delegation *delegation;
1099        struct inode *inode;
1100restart:
1101        rcu_read_lock();
1102restart_locked:
1103        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
1104                if (test_bit(NFS_DELEGATION_INODE_FREEING,
1105                                        &delegation->flags) ||
1106                    test_bit(NFS_DELEGATION_RETURNING,
1107                                        &delegation->flags) ||
1108                    test_bit(NFS_DELEGATION_NEED_RECLAIM,
1109                                        &delegation->flags) == 0)
1110                        continue;
1111                inode = nfs_delegation_grab_inode(delegation);
1112                if (inode == NULL)
1113                        goto restart_locked;
1114                delegation = nfs_start_delegation_return_locked(NFS_I(inode));
1115                rcu_read_unlock();
1116                if (delegation != NULL) {
1117                        if (nfs_detach_delegation(NFS_I(inode), delegation,
1118                                                server) != NULL)
1119                                nfs_free_delegation(delegation);
1120                        /* Match nfs_start_delegation_return_locked */
1121                        nfs_put_delegation(delegation);
1122                }
1123                iput(inode);
1124                cond_resched();
1125                goto restart;
1126        }
1127        rcu_read_unlock();
1128        return 0;
1129}
1130
1131/**
1132 * nfs_delegation_reap_unclaimed - reap unclaimed delegations after reboot recovery is done
1133 * @clp: nfs_client to process
1134 *
1135 */
1136void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
1137{
1138        nfs_client_for_each_server(clp, nfs_server_reap_unclaimed_delegations,
1139                        NULL);
1140}
1141
1142static inline bool nfs4_server_rebooted(const struct nfs_client *clp)
1143{
1144        return (clp->cl_state & (BIT(NFS4CLNT_CHECK_LEASE) |
1145                                BIT(NFS4CLNT_LEASE_EXPIRED) |
1146                                BIT(NFS4CLNT_SESSION_RESET))) != 0;
1147}
1148
1149static void nfs_mark_test_expired_delegation(struct nfs_server *server,
1150            struct nfs_delegation *delegation)
1151{
1152        if (delegation->stateid.type == NFS4_INVALID_STATEID_TYPE)
1153                return;
1154        clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
1155        set_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
1156        set_bit(NFS4CLNT_DELEGATION_EXPIRED, &server->nfs_client->cl_state);
1157}
1158
1159static void nfs_inode_mark_test_expired_delegation(struct nfs_server *server,
1160                struct inode *inode)
1161{
1162        struct nfs_delegation *delegation;
1163
1164        rcu_read_lock();
1165        delegation = rcu_dereference(NFS_I(inode)->delegation);
1166        if (delegation)
1167                nfs_mark_test_expired_delegation(server, delegation);
1168        rcu_read_unlock();
1169
1170}
1171
1172static void nfs_delegation_mark_test_expired_server(struct nfs_server *server)
1173{
1174        struct nfs_delegation *delegation;
1175
1176        list_for_each_entry_rcu(delegation, &server->delegations, super_list)
1177                nfs_mark_test_expired_delegation(server, delegation);
1178}
1179
1180/**
1181 * nfs_mark_test_expired_all_delegations - mark all delegations for testing
1182 * @clp: nfs_client to process
1183 *
1184 * Iterates through all the delegations associated with this server and
1185 * marks them as needing to be checked for validity.
1186 */
1187void nfs_mark_test_expired_all_delegations(struct nfs_client *clp)
1188{
1189        struct nfs_server *server;
1190
1191        rcu_read_lock();
1192        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1193                nfs_delegation_mark_test_expired_server(server);
1194        rcu_read_unlock();
1195}
1196
1197/**
1198 * nfs_test_expired_all_delegations - test all delegations for a client
1199 * @clp: nfs_client to process
1200 *
1201 * Helper for handling "recallable state revoked" status from server.
1202 */
1203void nfs_test_expired_all_delegations(struct nfs_client *clp)
1204{
1205        nfs_mark_test_expired_all_delegations(clp);
1206        nfs4_schedule_state_manager(clp);
1207}
1208
1209static void
1210nfs_delegation_test_free_expired(struct inode *inode,
1211                nfs4_stateid *stateid,
1212                const struct cred *cred)
1213{
1214        struct nfs_server *server = NFS_SERVER(inode);
1215        const struct nfs4_minor_version_ops *ops = server->nfs_client->cl_mvops;
1216        int status;
1217
1218        if (!cred)
1219                return;
1220        status = ops->test_and_free_expired(server, stateid, cred);
1221        if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID)
1222                nfs_remove_bad_delegation(inode, stateid);
1223}
1224
1225static int nfs_server_reap_expired_delegations(struct nfs_server *server,
1226                void __always_unused *data)
1227{
1228        struct nfs_delegation *delegation;
1229        struct inode *inode;
1230        const struct cred *cred;
1231        nfs4_stateid stateid;
1232restart:
1233        rcu_read_lock();
1234restart_locked:
1235        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
1236                if (test_bit(NFS_DELEGATION_INODE_FREEING,
1237                                        &delegation->flags) ||
1238                    test_bit(NFS_DELEGATION_RETURNING,
1239                                        &delegation->flags) ||
1240                    test_bit(NFS_DELEGATION_TEST_EXPIRED,
1241                                        &delegation->flags) == 0)
1242                        continue;
1243                inode = nfs_delegation_grab_inode(delegation);
1244                if (inode == NULL)
1245                        goto restart_locked;
1246                spin_lock(&delegation->lock);
1247                cred = get_cred_rcu(delegation->cred);
1248                nfs4_stateid_copy(&stateid, &delegation->stateid);
1249                spin_unlock(&delegation->lock);
1250                clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
1251                rcu_read_unlock();
1252                nfs_delegation_test_free_expired(inode, &stateid, cred);
1253                put_cred(cred);
1254                if (!nfs4_server_rebooted(server->nfs_client)) {
1255                        iput(inode);
1256                        cond_resched();
1257                        goto restart;
1258                }
1259                nfs_inode_mark_test_expired_delegation(server,inode);
1260                iput(inode);
1261                return -EAGAIN;
1262        }
1263        rcu_read_unlock();
1264        return 0;
1265}
1266
1267/**
1268 * nfs_reap_expired_delegations - reap expired delegations
1269 * @clp: nfs_client to process
1270 *
1271 * Iterates through all the delegations associated with this server and
1272 * checks if they have may have been revoked. This function is usually
1273 * expected to be called in cases where the server may have lost its
1274 * lease.
1275 */
1276void nfs_reap_expired_delegations(struct nfs_client *clp)
1277{
1278        nfs_client_for_each_server(clp, nfs_server_reap_expired_delegations,
1279                        NULL);
1280}
1281
1282void nfs_inode_find_delegation_state_and_recover(struct inode *inode,
1283                const nfs4_stateid *stateid)
1284{
1285        struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
1286        struct nfs_delegation *delegation;
1287        bool found = false;
1288
1289        rcu_read_lock();
1290        delegation = rcu_dereference(NFS_I(inode)->delegation);
1291        if (delegation &&
1292            nfs4_stateid_match_or_older(&delegation->stateid, stateid) &&
1293            !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
1294                nfs_mark_test_expired_delegation(NFS_SERVER(inode), delegation);
1295                found = true;
1296        }
1297        rcu_read_unlock();
1298        if (found)
1299                nfs4_schedule_state_manager(clp);
1300}
1301
1302/**
1303 * nfs_delegations_present - check for existence of delegations
1304 * @clp: client state handle
1305 *
1306 * Returns one if there are any nfs_delegation structures attached
1307 * to this nfs_client.
1308 */
1309int nfs_delegations_present(struct nfs_client *clp)
1310{
1311        struct nfs_server *server;
1312        int ret = 0;
1313
1314        rcu_read_lock();
1315        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1316                if (!list_empty(&server->delegations)) {
1317                        ret = 1;
1318                        break;
1319                }
1320        rcu_read_unlock();
1321        return ret;
1322}
1323
1324/**
1325 * nfs4_refresh_delegation_stateid - Update delegation stateid seqid
1326 * @dst: stateid to refresh
1327 * @inode: inode to check
1328 *
1329 * Returns "true" and updates "dst->seqid" * if inode had a delegation
1330 * that matches our delegation stateid. Otherwise "false" is returned.
1331 */
1332bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
1333{
1334        struct nfs_delegation *delegation;
1335        bool ret = false;
1336        if (!inode)
1337                goto out;
1338
1339        rcu_read_lock();
1340        delegation = rcu_dereference(NFS_I(inode)->delegation);
1341        if (delegation != NULL &&
1342            nfs4_stateid_match_other(dst, &delegation->stateid) &&
1343            nfs4_stateid_is_newer(&delegation->stateid, dst) &&
1344            !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
1345                dst->seqid = delegation->stateid.seqid;
1346                ret = true;
1347        }
1348        rcu_read_unlock();
1349out:
1350        return ret;
1351}
1352
1353/**
1354 * nfs4_copy_delegation_stateid - Copy inode's state ID information
1355 * @inode: inode to check
1356 * @flags: delegation type requirement
1357 * @dst: stateid data structure to fill in
1358 * @cred: optional argument to retrieve credential
1359 *
1360 * Returns "true" and fills in "dst->data" * if inode had a delegation,
1361 * otherwise "false" is returned.
1362 */
1363bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags,
1364                nfs4_stateid *dst, const struct cred **cred)
1365{
1366        struct nfs_inode *nfsi = NFS_I(inode);
1367        struct nfs_delegation *delegation;
1368        bool ret = false;
1369
1370        flags &= FMODE_READ|FMODE_WRITE;
1371        rcu_read_lock();
1372        delegation = rcu_dereference(nfsi->delegation);
1373        if (!delegation)
1374                goto out;
1375        spin_lock(&delegation->lock);
1376        ret = nfs4_is_valid_delegation(delegation, flags);
1377        if (ret) {
1378                nfs4_stateid_copy(dst, &delegation->stateid);
1379                nfs_mark_delegation_referenced(delegation);
1380                if (cred)
1381                        *cred = get_cred(delegation->cred);
1382        }
1383        spin_unlock(&delegation->lock);
1384out:
1385        rcu_read_unlock();
1386        return ret;
1387}
1388
1389/**
1390 * nfs4_delegation_flush_on_close - Check if we must flush file on close
1391 * @inode: inode to check
1392 *
1393 * This function checks the number of outstanding writes to the file
1394 * against the delegation 'space_limit' field to see if
1395 * the spec requires us to flush the file on close.
1396 */
1397bool nfs4_delegation_flush_on_close(const struct inode *inode)
1398{
1399        struct nfs_inode *nfsi = NFS_I(inode);
1400        struct nfs_delegation *delegation;
1401        bool ret = true;
1402
1403        rcu_read_lock();
1404        delegation = rcu_dereference(nfsi->delegation);
1405        if (delegation == NULL || !(delegation->type & FMODE_WRITE))
1406                goto out;
1407        if (atomic_long_read(&nfsi->nrequests) < delegation->pagemod_limit)
1408                ret = false;
1409out:
1410        rcu_read_unlock();
1411        return ret;
1412}
1413
1414module_param_named(delegation_watermark, nfs_delegation_watermark, uint, 0644);
1415