linux/fs/nfs/delegation.c
<<
>>
Prefs
   1/*
   2 * linux/fs/nfs/delegation.c
   3 *
   4 * Copyright (C) 2004 Trond Myklebust
   5 *
   6 * NFS file delegation management
   7 *
   8 */
   9#include <linux/completion.h>
  10#include <linux/kthread.h>
  11#include <linux/module.h>
  12#include <linux/sched.h>
  13#include <linux/slab.h>
  14#include <linux/spinlock.h>
  15
  16#include <linux/nfs4.h>
  17#include <linux/nfs_fs.h>
  18#include <linux/nfs_xdr.h>
  19
  20#include "nfs4_fs.h"
  21#include "delegation.h"
  22#include "internal.h"
  23#include "nfs4trace.h"
  24
  25static void nfs_free_delegation(struct nfs_delegation *delegation)
  26{
  27        if (delegation->cred) {
  28                put_rpccred(delegation->cred);
  29                delegation->cred = NULL;
  30        }
  31        kfree_rcu(delegation, rcu);
  32}
  33
  34/**
  35 * nfs_mark_delegation_referenced - set delegation's REFERENCED flag
  36 * @delegation: delegation to process
  37 *
  38 */
  39void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
  40{
  41        set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
  42}
  43
  44static bool
  45nfs4_is_valid_delegation(const struct nfs_delegation *delegation,
  46                fmode_t flags)
  47{
  48        if (delegation != NULL && (delegation->type & flags) == flags &&
  49            !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
  50            !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
  51                return true;
  52        return false;
  53}
  54
  55static int
  56nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark)
  57{
  58        struct nfs_delegation *delegation;
  59        int ret = 0;
  60
  61        flags &= FMODE_READ|FMODE_WRITE;
  62        rcu_read_lock();
  63        delegation = rcu_dereference(NFS_I(inode)->delegation);
  64        if (nfs4_is_valid_delegation(delegation, flags)) {
  65                if (mark)
  66                        nfs_mark_delegation_referenced(delegation);
  67                ret = 1;
  68        }
  69        rcu_read_unlock();
  70        return ret;
  71}
  72/**
  73 * nfs_have_delegation - check if inode has a delegation, mark it
  74 * NFS_DELEGATION_REFERENCED if there is one.
  75 * @inode: inode to check
  76 * @flags: delegation types to check for
  77 *
  78 * Returns one if inode has the indicated delegation, otherwise zero.
  79 */
  80int nfs4_have_delegation(struct inode *inode, fmode_t flags)
  81{
  82        return nfs4_do_check_delegation(inode, flags, true);
  83}
  84
  85/*
  86 * nfs4_check_delegation - check if inode has a delegation, do not mark
  87 * NFS_DELEGATION_REFERENCED if it has one.
  88 */
  89int nfs4_check_delegation(struct inode *inode, fmode_t flags)
  90{
  91        return nfs4_do_check_delegation(inode, flags, false);
  92}
  93
  94static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
  95{
  96        struct inode *inode = state->inode;
  97        struct file_lock *fl;
  98        struct file_lock_context *flctx = inode->i_flctx;
  99        struct list_head *list;
 100        int status = 0;
 101
 102        if (flctx == NULL)
 103                goto out;
 104
 105        list = &flctx->flc_posix;
 106        spin_lock(&flctx->flc_lock);
 107restart:
 108        list_for_each_entry(fl, list, fl_list) {
 109                if (nfs_file_open_context(fl->fl_file) != ctx)
 110                        continue;
 111                spin_unlock(&flctx->flc_lock);
 112                status = nfs4_lock_delegation_recall(fl, state, stateid);
 113                if (status < 0)
 114                        goto out;
 115                spin_lock(&flctx->flc_lock);
 116        }
 117        if (list == &flctx->flc_posix) {
 118                list = &flctx->flc_flock;
 119                goto restart;
 120        }
 121        spin_unlock(&flctx->flc_lock);
 122out:
 123        return status;
 124}
 125
 126static int nfs_delegation_claim_opens(struct inode *inode,
 127                const nfs4_stateid *stateid, fmode_t type)
 128{
 129        struct nfs_inode *nfsi = NFS_I(inode);
 130        struct nfs_open_context *ctx;
 131        struct nfs4_state_owner *sp;
 132        struct nfs4_state *state;
 133        unsigned int seq;
 134        int err;
 135
 136again:
 137        spin_lock(&inode->i_lock);
 138        list_for_each_entry(ctx, &nfsi->open_files, list) {
 139                state = ctx->state;
 140                if (state == NULL)
 141                        continue;
 142                if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
 143                        continue;
 144                if (!nfs4_valid_open_stateid(state))
 145                        continue;
 146                if (!nfs4_stateid_match(&state->stateid, stateid))
 147                        continue;
 148                get_nfs_open_context(ctx);
 149                spin_unlock(&inode->i_lock);
 150                sp = state->owner;
 151                /* Block nfs4_proc_unlck */
 152                mutex_lock(&sp->so_delegreturn_mutex);
 153                seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
 154                err = nfs4_open_delegation_recall(ctx, state, stateid, type);
 155                if (!err)
 156                        err = nfs_delegation_claim_locks(ctx, state, stateid);
 157                if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
 158                        err = -EAGAIN;
 159                mutex_unlock(&sp->so_delegreturn_mutex);
 160                put_nfs_open_context(ctx);
 161                if (err != 0)
 162                        return err;
 163                goto again;
 164        }
 165        spin_unlock(&inode->i_lock);
 166        return 0;
 167}
 168
 169/**
 170 * nfs_inode_reclaim_delegation - process a delegation reclaim request
 171 * @inode: inode to process
 172 * @cred: credential to use for request
 173 * @res: new delegation state from server
 174 *
 175 */
 176void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
 177                                  struct nfs_openres *res)
 178{
 179        struct nfs_delegation *delegation;
 180        struct rpc_cred *oldcred = NULL;
 181
 182        rcu_read_lock();
 183        delegation = rcu_dereference(NFS_I(inode)->delegation);
 184        if (delegation != NULL) {
 185                spin_lock(&delegation->lock);
 186                if (delegation->inode != NULL) {
 187                        nfs4_stateid_copy(&delegation->stateid, &res->delegation);
 188                        delegation->type = res->delegation_type;
 189                        delegation->pagemod_limit = res->pagemod_limit;
 190                        oldcred = delegation->cred;
 191                        delegation->cred = get_rpccred(cred);
 192                        clear_bit(NFS_DELEGATION_NEED_RECLAIM,
 193                                  &delegation->flags);
 194                        spin_unlock(&delegation->lock);
 195                        rcu_read_unlock();
 196                        put_rpccred(oldcred);
 197                        trace_nfs4_reclaim_delegation(inode, res->delegation_type);
 198                        return;
 199                }
 200                /* We appear to have raced with a delegation return. */
 201                spin_unlock(&delegation->lock);
 202        }
 203        rcu_read_unlock();
 204        nfs_inode_set_delegation(inode, cred, res);
 205}
 206
 207static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
 208{
 209        int res = 0;
 210
 211        if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
 212                res = nfs4_proc_delegreturn(inode,
 213                                delegation->cred,
 214                                &delegation->stateid,
 215                                issync);
 216        nfs_free_delegation(delegation);
 217        return res;
 218}
 219
 220static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation)
 221{
 222        struct inode *inode = NULL;
 223
 224        spin_lock(&delegation->lock);
 225        if (delegation->inode != NULL)
 226                inode = igrab(delegation->inode);
 227        spin_unlock(&delegation->lock);
 228        return inode;
 229}
 230
 231static struct nfs_delegation *
 232nfs_start_delegation_return_locked(struct nfs_inode *nfsi)
 233{
 234        struct nfs_delegation *ret = NULL;
 235        struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation);
 236
 237        if (delegation == NULL)
 238                goto out;
 239        spin_lock(&delegation->lock);
 240        if (!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
 241                ret = delegation;
 242        spin_unlock(&delegation->lock);
 243out:
 244        return ret;
 245}
 246
 247static struct nfs_delegation *
 248nfs_start_delegation_return(struct nfs_inode *nfsi)
 249{
 250        struct nfs_delegation *delegation;
 251
 252        rcu_read_lock();
 253        delegation = nfs_start_delegation_return_locked(nfsi);
 254        rcu_read_unlock();
 255        return delegation;
 256}
 257
 258static void
 259nfs_abort_delegation_return(struct nfs_delegation *delegation,
 260                struct nfs_client *clp)
 261{
 262
 263        spin_lock(&delegation->lock);
 264        clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
 265        set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
 266        spin_unlock(&delegation->lock);
 267        set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
 268}
 269
 270static struct nfs_delegation *
 271nfs_detach_delegation_locked(struct nfs_inode *nfsi,
 272                struct nfs_delegation *delegation,
 273                struct nfs_client *clp)
 274{
 275        struct nfs_delegation *deleg_cur =
 276                rcu_dereference_protected(nfsi->delegation,
 277                                lockdep_is_held(&clp->cl_lock));
 278
 279        if (deleg_cur == NULL || delegation != deleg_cur)
 280                return NULL;
 281
 282        spin_lock(&delegation->lock);
 283        set_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
 284        list_del_rcu(&delegation->super_list);
 285        delegation->inode = NULL;
 286        rcu_assign_pointer(nfsi->delegation, NULL);
 287        spin_unlock(&delegation->lock);
 288        return delegation;
 289}
 290
 291static struct nfs_delegation *nfs_detach_delegation(struct nfs_inode *nfsi,
 292                struct nfs_delegation *delegation,
 293                struct nfs_server *server)
 294{
 295        struct nfs_client *clp = server->nfs_client;
 296
 297        spin_lock(&clp->cl_lock);
 298        delegation = nfs_detach_delegation_locked(nfsi, delegation, clp);
 299        spin_unlock(&clp->cl_lock);
 300        return delegation;
 301}
 302
 303static struct nfs_delegation *
 304nfs_inode_detach_delegation(struct inode *inode)
 305{
 306        struct nfs_inode *nfsi = NFS_I(inode);
 307        struct nfs_server *server = NFS_SERVER(inode);
 308        struct nfs_delegation *delegation;
 309
 310        delegation = nfs_start_delegation_return(nfsi);
 311        if (delegation == NULL)
 312                return NULL;
 313        return nfs_detach_delegation(nfsi, delegation, server);
 314}
 315
 316static void
 317nfs_update_inplace_delegation(struct nfs_delegation *delegation,
 318                const struct nfs_delegation *update)
 319{
 320        if (nfs4_stateid_is_newer(&update->stateid, &delegation->stateid)) {
 321                delegation->stateid.seqid = update->stateid.seqid;
 322                smp_wmb();
 323                delegation->type = update->type;
 324        }
 325}
 326
 327/**
 328 * nfs_inode_set_delegation - set up a delegation on an inode
 329 * @inode: inode to which delegation applies
 330 * @cred: cred to use for subsequent delegation processing
 331 * @res: new delegation state from server
 332 *
 333 * Returns zero on success, or a negative errno value.
 334 */
 335int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
 336{
 337        struct nfs_server *server = NFS_SERVER(inode);
 338        struct nfs_client *clp = server->nfs_client;
 339        struct nfs_inode *nfsi = NFS_I(inode);
 340        struct nfs_delegation *delegation, *old_delegation;
 341        struct nfs_delegation *freeme = NULL;
 342        int status = 0;
 343
 344        delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
 345        if (delegation == NULL)
 346                return -ENOMEM;
 347        nfs4_stateid_copy(&delegation->stateid, &res->delegation);
 348        delegation->type = res->delegation_type;
 349        delegation->pagemod_limit = res->pagemod_limit;
 350        delegation->change_attr = inode->i_version;
 351        delegation->cred = get_rpccred(cred);
 352        delegation->inode = inode;
 353        delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
 354        spin_lock_init(&delegation->lock);
 355
 356        spin_lock(&clp->cl_lock);
 357        old_delegation = rcu_dereference_protected(nfsi->delegation,
 358                                        lockdep_is_held(&clp->cl_lock));
 359        if (old_delegation != NULL) {
 360                /* Is this an update of the existing delegation? */
 361                if (nfs4_stateid_match_other(&old_delegation->stateid,
 362                                        &delegation->stateid)) {
 363                        nfs_update_inplace_delegation(old_delegation,
 364                                        delegation);
 365                        goto out;
 366                }
 367                /*
 368                 * Deal with broken servers that hand out two
 369                 * delegations for the same file.
 370                 * Allow for upgrades to a WRITE delegation, but
 371                 * nothing else.
 372                 */
 373                dfprintk(FILE, "%s: server %s handed out "
 374                                "a duplicate delegation!\n",
 375                                __func__, clp->cl_hostname);
 376                if (delegation->type == old_delegation->type ||
 377                    !(delegation->type & FMODE_WRITE)) {
 378                        freeme = delegation;
 379                        delegation = NULL;
 380                        goto out;
 381                }
 382                if (test_and_set_bit(NFS_DELEGATION_RETURNING,
 383                                        &old_delegation->flags))
 384                        goto out;
 385                freeme = nfs_detach_delegation_locked(nfsi,
 386                                old_delegation, clp);
 387                if (freeme == NULL)
 388                        goto out;
 389        }
 390        list_add_tail_rcu(&delegation->super_list, &server->delegations);
 391        rcu_assign_pointer(nfsi->delegation, delegation);
 392        delegation = NULL;
 393
 394        /* Ensure we revalidate the attributes and page cache! */
 395        spin_lock(&inode->i_lock);
 396        nfsi->cache_validity |= NFS_INO_REVAL_FORCED;
 397        spin_unlock(&inode->i_lock);
 398        trace_nfs4_set_delegation(inode, res->delegation_type);
 399
 400out:
 401        spin_unlock(&clp->cl_lock);
 402        if (delegation != NULL)
 403                nfs_free_delegation(delegation);
 404        if (freeme != NULL)
 405                nfs_do_return_delegation(inode, freeme, 0);
 406        return status;
 407}
 408
 409/*
 410 * Basic procedure for returning a delegation to the server
 411 */
 412static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation *delegation, int issync)
 413{
 414        struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
 415        struct nfs_inode *nfsi = NFS_I(inode);
 416        int err = 0;
 417
 418        if (delegation == NULL)
 419                return 0;
 420        do {
 421                if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
 422                        break;
 423                err = nfs_delegation_claim_opens(inode, &delegation->stateid,
 424                                delegation->type);
 425                if (!issync || err != -EAGAIN)
 426                        break;
 427                /*
 428                 * Guard against state recovery
 429                 */
 430                err = nfs4_wait_clnt_recover(clp);
 431        } while (err == 0);
 432
 433        if (err) {
 434                nfs_abort_delegation_return(delegation, clp);
 435                goto out;
 436        }
 437        if (!nfs_detach_delegation(nfsi, delegation, NFS_SERVER(inode)))
 438                goto out;
 439
 440        err = nfs_do_return_delegation(inode, delegation, issync);
 441out:
 442        return err;
 443}
 444
 445static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
 446{
 447        bool ret = false;
 448
 449        if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
 450                goto out;
 451        if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
 452                ret = true;
 453        if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) {
 454                struct inode *inode;
 455
 456                spin_lock(&delegation->lock);
 457                inode = delegation->inode;
 458                if (inode && list_empty(&NFS_I(inode)->open_files))
 459                        ret = true;
 460                spin_unlock(&delegation->lock);
 461        }
 462out:
 463        return ret;
 464}
 465
 466/**
 467 * nfs_client_return_marked_delegations - return previously marked delegations
 468 * @clp: nfs_client to process
 469 *
 470 * Note that this function is designed to be called by the state
 471 * manager thread. For this reason, it cannot flush the dirty data,
 472 * since that could deadlock in case of a state recovery error.
 473 *
 474 * Returns zero on success, or a negative errno value.
 475 */
 476int nfs_client_return_marked_delegations(struct nfs_client *clp)
 477{
 478        struct nfs_delegation *delegation;
 479        struct nfs_server *server;
 480        struct inode *inode;
 481        int err = 0;
 482
 483restart:
 484        rcu_read_lock();
 485        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
 486                list_for_each_entry_rcu(delegation, &server->delegations,
 487                                                                super_list) {
 488                        if (!nfs_delegation_need_return(delegation))
 489                                continue;
 490                        if (!nfs_sb_active(server->super))
 491                                continue;
 492                        inode = nfs_delegation_grab_inode(delegation);
 493                        if (inode == NULL) {
 494                                rcu_read_unlock();
 495                                nfs_sb_deactive(server->super);
 496                                goto restart;
 497                        }
 498                        delegation = nfs_start_delegation_return_locked(NFS_I(inode));
 499                        rcu_read_unlock();
 500
 501                        err = nfs_end_delegation_return(inode, delegation, 0);
 502                        iput(inode);
 503                        nfs_sb_deactive(server->super);
 504                        if (!err)
 505                                goto restart;
 506                        set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
 507                        return err;
 508                }
 509        }
 510        rcu_read_unlock();
 511        return 0;
 512}
 513
 514/**
 515 * nfs_inode_return_delegation_noreclaim - return delegation, don't reclaim opens
 516 * @inode: inode to process
 517 *
 518 * Does not protect against delegation reclaims, therefore really only safe
 519 * to be called from nfs4_clear_inode().
 520 */
 521void nfs_inode_return_delegation_noreclaim(struct inode *inode)
 522{
 523        struct nfs_delegation *delegation;
 524
 525        delegation = nfs_inode_detach_delegation(inode);
 526        if (delegation != NULL)
 527                nfs_do_return_delegation(inode, delegation, 1);
 528}
 529
 530/**
 531 * nfs_inode_return_delegation - synchronously return a delegation
 532 * @inode: inode to process
 533 *
 534 * This routine will always flush any dirty data to disk on the
 535 * assumption that if we need to return the delegation, then
 536 * we should stop caching.
 537 *
 538 * Returns zero on success, or a negative errno value.
 539 */
 540int nfs4_inode_return_delegation(struct inode *inode)
 541{
 542        struct nfs_inode *nfsi = NFS_I(inode);
 543        struct nfs_delegation *delegation;
 544        int err = 0;
 545
 546        nfs_wb_all(inode);
 547        delegation = nfs_start_delegation_return(nfsi);
 548        if (delegation != NULL)
 549                err = nfs_end_delegation_return(inode, delegation, 1);
 550        return err;
 551}
 552
 553static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
 554                struct nfs_delegation *delegation)
 555{
 556        set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
 557        set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
 558}
 559
 560static void nfs_mark_return_delegation(struct nfs_server *server,
 561                struct nfs_delegation *delegation)
 562{
 563        set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
 564        set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
 565}
 566
 567static bool nfs_server_mark_return_all_delegations(struct nfs_server *server)
 568{
 569        struct nfs_delegation *delegation;
 570        bool ret = false;
 571
 572        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
 573                nfs_mark_return_delegation(server, delegation);
 574                ret = true;
 575        }
 576        return ret;
 577}
 578
 579static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
 580{
 581        struct nfs_server *server;
 582
 583        rcu_read_lock();
 584        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
 585                nfs_server_mark_return_all_delegations(server);
 586        rcu_read_unlock();
 587}
 588
 589static void nfs_delegation_run_state_manager(struct nfs_client *clp)
 590{
 591        if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
 592                nfs4_schedule_state_manager(clp);
 593}
 594
 595/**
 596 * nfs_expire_all_delegations
 597 * @clp: client to process
 598 *
 599 */
 600void nfs_expire_all_delegations(struct nfs_client *clp)
 601{
 602        nfs_client_mark_return_all_delegations(clp);
 603        nfs_delegation_run_state_manager(clp);
 604}
 605
 606/**
 607 * nfs_super_return_all_delegations - return delegations for one superblock
 608 * @sb: sb to process
 609 *
 610 */
 611void nfs_server_return_all_delegations(struct nfs_server *server)
 612{
 613        struct nfs_client *clp = server->nfs_client;
 614        bool need_wait;
 615
 616        if (clp == NULL)
 617                return;
 618
 619        rcu_read_lock();
 620        need_wait = nfs_server_mark_return_all_delegations(server);
 621        rcu_read_unlock();
 622
 623        if (need_wait) {
 624                nfs4_schedule_state_manager(clp);
 625                nfs4_wait_clnt_recover(clp);
 626        }
 627}
 628
 629static void nfs_mark_return_unused_delegation_types(struct nfs_server *server,
 630                                                 fmode_t flags)
 631{
 632        struct nfs_delegation *delegation;
 633
 634        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
 635                if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
 636                        continue;
 637                if (delegation->type & flags)
 638                        nfs_mark_return_if_closed_delegation(server, delegation);
 639        }
 640}
 641
 642static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *clp,
 643                                                        fmode_t flags)
 644{
 645        struct nfs_server *server;
 646
 647        rcu_read_lock();
 648        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
 649                nfs_mark_return_unused_delegation_types(server, flags);
 650        rcu_read_unlock();
 651}
 652
 653static void nfs_mark_delegation_revoked(struct nfs_server *server,
 654                struct nfs_delegation *delegation)
 655{
 656        set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
 657        delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
 658        nfs_mark_return_delegation(server, delegation);
 659}
 660
 661static bool nfs_revoke_delegation(struct inode *inode,
 662                const nfs4_stateid *stateid)
 663{
 664        struct nfs_delegation *delegation;
 665        nfs4_stateid tmp;
 666        bool ret = false;
 667
 668        rcu_read_lock();
 669        delegation = rcu_dereference(NFS_I(inode)->delegation);
 670        if (delegation == NULL)
 671                goto out;
 672        if (stateid == NULL) {
 673                nfs4_stateid_copy(&tmp, &delegation->stateid);
 674                stateid = &tmp;
 675        } else if (!nfs4_stateid_match(stateid, &delegation->stateid))
 676                goto out;
 677        nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
 678        ret = true;
 679out:
 680        rcu_read_unlock();
 681        if (ret)
 682                nfs_inode_find_state_and_recover(inode, stateid);
 683        return ret;
 684}
 685
 686void nfs_remove_bad_delegation(struct inode *inode,
 687                const nfs4_stateid *stateid)
 688{
 689        struct nfs_delegation *delegation;
 690
 691        if (!nfs_revoke_delegation(inode, stateid))
 692                return;
 693        delegation = nfs_inode_detach_delegation(inode);
 694        if (delegation)
 695                nfs_free_delegation(delegation);
 696}
 697EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);
 698
 699/**
 700 * nfs_expire_unused_delegation_types
 701 * @clp: client to process
 702 * @flags: delegation types to expire
 703 *
 704 */
 705void nfs_expire_unused_delegation_types(struct nfs_client *clp, fmode_t flags)
 706{
 707        nfs_client_mark_return_unused_delegation_types(clp, flags);
 708        nfs_delegation_run_state_manager(clp);
 709}
 710
 711static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server)
 712{
 713        struct nfs_delegation *delegation;
 714
 715        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
 716                if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
 717                        continue;
 718                nfs_mark_return_if_closed_delegation(server, delegation);
 719        }
 720}
 721
 722/**
 723 * nfs_expire_unreferenced_delegations - Eliminate unused delegations
 724 * @clp: nfs_client to process
 725 *
 726 */
 727void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
 728{
 729        struct nfs_server *server;
 730
 731        rcu_read_lock();
 732        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
 733                nfs_mark_return_unreferenced_delegations(server);
 734        rcu_read_unlock();
 735
 736        nfs_delegation_run_state_manager(clp);
 737}
 738
 739/**
 740 * nfs_async_inode_return_delegation - asynchronously return a delegation
 741 * @inode: inode to process
 742 * @stateid: state ID information
 743 *
 744 * Returns zero on success, or a negative errno value.
 745 */
 746int nfs_async_inode_return_delegation(struct inode *inode,
 747                                      const nfs4_stateid *stateid)
 748{
 749        struct nfs_server *server = NFS_SERVER(inode);
 750        struct nfs_client *clp = server->nfs_client;
 751        struct nfs_delegation *delegation;
 752
 753        rcu_read_lock();
 754        delegation = rcu_dereference(NFS_I(inode)->delegation);
 755        if (delegation == NULL)
 756                goto out_enoent;
 757        if (stateid != NULL &&
 758            !clp->cl_mvops->match_stateid(&delegation->stateid, stateid))
 759                goto out_enoent;
 760        nfs_mark_return_delegation(server, delegation);
 761        rcu_read_unlock();
 762
 763        nfs_delegation_run_state_manager(clp);
 764        return 0;
 765out_enoent:
 766        rcu_read_unlock();
 767        return -ENOENT;
 768}
 769
 770static struct inode *
 771nfs_delegation_find_inode_server(struct nfs_server *server,
 772                                 const struct nfs_fh *fhandle)
 773{
 774        struct nfs_delegation *delegation;
 775        struct inode *res = NULL;
 776
 777        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
 778                spin_lock(&delegation->lock);
 779                if (delegation->inode != NULL &&
 780                    nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
 781                        res = igrab(delegation->inode);
 782                }
 783                spin_unlock(&delegation->lock);
 784                if (res != NULL)
 785                        break;
 786        }
 787        return res;
 788}
 789
 790/**
 791 * nfs_delegation_find_inode - retrieve the inode associated with a delegation
 792 * @clp: client state handle
 793 * @fhandle: filehandle from a delegation recall
 794 *
 795 * Returns pointer to inode matching "fhandle," or NULL if a matching inode
 796 * cannot be found.
 797 */
 798struct inode *nfs_delegation_find_inode(struct nfs_client *clp,
 799                                        const struct nfs_fh *fhandle)
 800{
 801        struct nfs_server *server;
 802        struct inode *res = NULL;
 803
 804        rcu_read_lock();
 805        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
 806                res = nfs_delegation_find_inode_server(server, fhandle);
 807                if (res != NULL)
 808                        break;
 809        }
 810        rcu_read_unlock();
 811        return res;
 812}
 813
 814static void nfs_delegation_mark_reclaim_server(struct nfs_server *server)
 815{
 816        struct nfs_delegation *delegation;
 817
 818        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
 819                /*
 820                 * If the delegation may have been admin revoked, then we
 821                 * cannot reclaim it.
 822                 */
 823                if (test_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags))
 824                        continue;
 825                set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
 826        }
 827}
 828
 829/**
 830 * nfs_delegation_mark_reclaim - mark all delegations as needing to be reclaimed
 831 * @clp: nfs_client to process
 832 *
 833 */
 834void nfs_delegation_mark_reclaim(struct nfs_client *clp)
 835{
 836        struct nfs_server *server;
 837
 838        rcu_read_lock();
 839        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
 840                nfs_delegation_mark_reclaim_server(server);
 841        rcu_read_unlock();
 842}
 843
 844/**
 845 * nfs_delegation_reap_unclaimed - reap unclaimed delegations after reboot recovery is done
 846 * @clp: nfs_client to process
 847 *
 848 */
 849void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
 850{
 851        struct nfs_delegation *delegation;
 852        struct nfs_server *server;
 853        struct inode *inode;
 854
 855restart:
 856        rcu_read_lock();
 857        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
 858                list_for_each_entry_rcu(delegation, &server->delegations,
 859                                                                super_list) {
 860                        if (test_bit(NFS_DELEGATION_RETURNING,
 861                                                &delegation->flags))
 862                                continue;
 863                        if (test_bit(NFS_DELEGATION_NEED_RECLAIM,
 864                                                &delegation->flags) == 0)
 865                                continue;
 866                        if (!nfs_sb_active(server->super))
 867                                continue;
 868                        inode = nfs_delegation_grab_inode(delegation);
 869                        if (inode == NULL) {
 870                                rcu_read_unlock();
 871                                nfs_sb_deactive(server->super);
 872                                goto restart;
 873                        }
 874                        delegation = nfs_start_delegation_return_locked(NFS_I(inode));
 875                        rcu_read_unlock();
 876                        if (delegation != NULL) {
 877                                delegation = nfs_detach_delegation(NFS_I(inode),
 878                                        delegation, server);
 879                                if (delegation != NULL)
 880                                        nfs_free_delegation(delegation);
 881                        }
 882                        iput(inode);
 883                        nfs_sb_deactive(server->super);
 884                        goto restart;
 885                }
 886        }
 887        rcu_read_unlock();
 888}
 889
 890static inline bool nfs4_server_rebooted(const struct nfs_client *clp)
 891{
 892        return (clp->cl_state & (BIT(NFS4CLNT_CHECK_LEASE) |
 893                                BIT(NFS4CLNT_LEASE_EXPIRED) |
 894                                BIT(NFS4CLNT_SESSION_RESET))) != 0;
 895}
 896
 897static void nfs_mark_test_expired_delegation(struct nfs_server *server,
 898            struct nfs_delegation *delegation)
 899{
 900        if (delegation->stateid.type == NFS4_INVALID_STATEID_TYPE)
 901                return;
 902        clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
 903        set_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
 904        set_bit(NFS4CLNT_DELEGATION_EXPIRED, &server->nfs_client->cl_state);
 905}
 906
 907static void nfs_inode_mark_test_expired_delegation(struct nfs_server *server,
 908                struct inode *inode)
 909{
 910        struct nfs_delegation *delegation;
 911
 912        rcu_read_lock();
 913        delegation = rcu_dereference(NFS_I(inode)->delegation);
 914        if (delegation)
 915                nfs_mark_test_expired_delegation(server, delegation);
 916        rcu_read_unlock();
 917
 918}
 919
 920static void nfs_delegation_mark_test_expired_server(struct nfs_server *server)
 921{
 922        struct nfs_delegation *delegation;
 923
 924        list_for_each_entry_rcu(delegation, &server->delegations, super_list)
 925                nfs_mark_test_expired_delegation(server, delegation);
 926}
 927
 928/**
 929 * nfs_mark_test_expired_all_delegations - mark all delegations for testing
 930 * @clp: nfs_client to process
 931 *
 932 * Iterates through all the delegations associated with this server and
 933 * marks them as needing to be checked for validity.
 934 */
 935void nfs_mark_test_expired_all_delegations(struct nfs_client *clp)
 936{
 937        struct nfs_server *server;
 938
 939        rcu_read_lock();
 940        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
 941                nfs_delegation_mark_test_expired_server(server);
 942        rcu_read_unlock();
 943}
 944
 945/**
 946 * nfs_reap_expired_delegations - reap expired delegations
 947 * @clp: nfs_client to process
 948 *
 949 * Iterates through all the delegations associated with this server and
 950 * checks if they have may have been revoked. This function is usually
 951 * expected to be called in cases where the server may have lost its
 952 * lease.
 953 */
 954void nfs_reap_expired_delegations(struct nfs_client *clp)
 955{
 956        const struct nfs4_minor_version_ops *ops = clp->cl_mvops;
 957        struct nfs_delegation *delegation;
 958        struct nfs_server *server;
 959        struct inode *inode;
 960        struct rpc_cred *cred;
 961        nfs4_stateid stateid;
 962
 963restart:
 964        rcu_read_lock();
 965        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
 966                list_for_each_entry_rcu(delegation, &server->delegations,
 967                                                                super_list) {
 968                        if (test_bit(NFS_DELEGATION_RETURNING,
 969                                                &delegation->flags))
 970                                continue;
 971                        if (test_bit(NFS_DELEGATION_TEST_EXPIRED,
 972                                                &delegation->flags) == 0)
 973                                continue;
 974                        if (!nfs_sb_active(server->super))
 975                                continue;
 976                        inode = nfs_delegation_grab_inode(delegation);
 977                        if (inode == NULL) {
 978                                rcu_read_unlock();
 979                                nfs_sb_deactive(server->super);
 980                                goto restart;
 981                        }
 982                        cred = get_rpccred_rcu(delegation->cred);
 983                        nfs4_stateid_copy(&stateid, &delegation->stateid);
 984                        clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
 985                        rcu_read_unlock();
 986                        if (cred != NULL &&
 987                            ops->test_and_free_expired(server, &stateid, cred) < 0) {
 988                                nfs_revoke_delegation(inode, &stateid);
 989                                nfs_inode_find_state_and_recover(inode, &stateid);
 990                        }
 991                        put_rpccred(cred);
 992                        if (nfs4_server_rebooted(clp)) {
 993                                nfs_inode_mark_test_expired_delegation(server,inode);
 994                                iput(inode);
 995                                nfs_sb_deactive(server->super);
 996                                return;
 997                        }
 998                        iput(inode);
 999                        nfs_sb_deactive(server->super);
1000                        goto restart;
1001                }
1002        }
1003        rcu_read_unlock();
1004}
1005
1006void nfs_inode_find_delegation_state_and_recover(struct inode *inode,
1007                const nfs4_stateid *stateid)
1008{
1009        struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
1010        struct nfs_delegation *delegation;
1011        bool found = false;
1012
1013        rcu_read_lock();
1014        delegation = rcu_dereference(NFS_I(inode)->delegation);
1015        if (delegation &&
1016            nfs4_stateid_match_other(&delegation->stateid, stateid)) {
1017                nfs_mark_test_expired_delegation(NFS_SERVER(inode), delegation);
1018                found = true;
1019        }
1020        rcu_read_unlock();
1021        if (found)
1022                nfs4_schedule_state_manager(clp);
1023}
1024
1025/**
1026 * nfs_delegations_present - check for existence of delegations
1027 * @clp: client state handle
1028 *
1029 * Returns one if there are any nfs_delegation structures attached
1030 * to this nfs_client.
1031 */
1032int nfs_delegations_present(struct nfs_client *clp)
1033{
1034        struct nfs_server *server;
1035        int ret = 0;
1036
1037        rcu_read_lock();
1038        list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1039                if (!list_empty(&server->delegations)) {
1040                        ret = 1;
1041                        break;
1042                }
1043        rcu_read_unlock();
1044        return ret;
1045}
1046
1047/**
1048 * nfs4_copy_delegation_stateid - Copy inode's state ID information
1049 * @inode: inode to check
1050 * @flags: delegation type requirement
1051 * @dst: stateid data structure to fill in
1052 * @cred: optional argument to retrieve credential
1053 *
1054 * Returns "true" and fills in "dst->data" * if inode had a delegation,
1055 * otherwise "false" is returned.
1056 */
1057bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags,
1058                nfs4_stateid *dst, struct rpc_cred **cred)
1059{
1060        struct nfs_inode *nfsi = NFS_I(inode);
1061        struct nfs_delegation *delegation;
1062        bool ret;
1063
1064        flags &= FMODE_READ|FMODE_WRITE;
1065        rcu_read_lock();
1066        delegation = rcu_dereference(nfsi->delegation);
1067        ret = nfs4_is_valid_delegation(delegation, flags);
1068        if (ret) {
1069                nfs4_stateid_copy(dst, &delegation->stateid);
1070                nfs_mark_delegation_referenced(delegation);
1071                if (cred)
1072                        *cred = get_rpccred(delegation->cred);
1073        }
1074        rcu_read_unlock();
1075        return ret;
1076}
1077
1078/**
1079 * nfs4_delegation_flush_on_close - Check if we must flush file on close
1080 * @inode: inode to check
1081 *
1082 * This function checks the number of outstanding writes to the file
1083 * against the delegation 'space_limit' field to see if
1084 * the spec requires us to flush the file on close.
1085 */
1086bool nfs4_delegation_flush_on_close(const struct inode *inode)
1087{
1088        struct nfs_inode *nfsi = NFS_I(inode);
1089        struct nfs_delegation *delegation;
1090        bool ret = true;
1091
1092        rcu_read_lock();
1093        delegation = rcu_dereference(nfsi->delegation);
1094        if (delegation == NULL || !(delegation->type & FMODE_WRITE))
1095                goto out;
1096        if (nfsi->nrequests < delegation->pagemod_limit)
1097                ret = false;
1098out:
1099        rcu_read_unlock();
1100        return ret;
1101}
1102