linux/fs/nfs/nfs4state.c
<<
>>
Prefs
   1/*
   2 *  fs/nfs/nfs4state.c
   3 *
   4 *  Client-side XDR for NFSv4.
   5 *
   6 *  Copyright (c) 2002 The Regents of the University of Michigan.
   7 *  All rights reserved.
   8 *
   9 *  Kendrick Smith <kmsmith@umich.edu>
  10 *
  11 *  Redistribution and use in source and binary forms, with or without
  12 *  modification, are permitted provided that the following conditions
  13 *  are met:
  14 *
  15 *  1. Redistributions of source code must retain the above copyright
  16 *     notice, this list of conditions and the following disclaimer.
  17 *  2. Redistributions in binary form must reproduce the above copyright
  18 *     notice, this list of conditions and the following disclaimer in the
  19 *     documentation and/or other materials provided with the distribution.
  20 *  3. Neither the name of the University nor the names of its
  21 *     contributors may be used to endorse or promote products derived
  22 *     from this software without specific prior written permission.
  23 *
  24 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  25 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  26 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  31 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  32 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  33 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  34 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35 *
  36 * Implementation of the NFSv4 state model.  For the time being,
  37 * this is minimal, but will be made much more complex in a
  38 * subsequent patch.
  39 */
  40
  41#include <linux/kernel.h>
  42#include <linux/slab.h>
  43#include <linux/smp_lock.h>
  44#include <linux/nfs_fs.h>
  45#include <linux/nfs_idmap.h>
  46#include <linux/kthread.h>
  47#include <linux/module.h>
  48#include <linux/random.h>
  49#include <linux/workqueue.h>
  50#include <linux/bitops.h>
  51
  52#include "nfs4_fs.h"
  53#include "callback.h"
  54#include "delegation.h"
  55#include "internal.h"
  56
  57#define OPENOWNER_POOL_SIZE     8
  58
  59const nfs4_stateid zero_stateid;
  60
  61static LIST_HEAD(nfs4_clientid_list);
  62
  63int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
  64{
  65        unsigned short port;
  66        int status;
  67
  68        port = nfs_callback_tcpport;
  69        if (clp->cl_addr.ss_family == AF_INET6)
  70                port = nfs_callback_tcpport6;
  71
  72        status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred);
  73        if (status == 0)
  74                status = nfs4_proc_setclientid_confirm(clp, cred);
  75        if (status == 0)
  76                nfs4_schedule_state_renewal(clp);
  77        return status;
  78}
  79
  80struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
  81{
  82        struct rpc_cred *cred = NULL;
  83
  84        if (clp->cl_machine_cred != NULL)
  85                cred = get_rpccred(clp->cl_machine_cred);
  86        return cred;
  87}
  88
  89static void nfs4_clear_machine_cred(struct nfs_client *clp)
  90{
  91        struct rpc_cred *cred;
  92
  93        spin_lock(&clp->cl_lock);
  94        cred = clp->cl_machine_cred;
  95        clp->cl_machine_cred = NULL;
  96        spin_unlock(&clp->cl_lock);
  97        if (cred != NULL)
  98                put_rpccred(cred);
  99}
 100
 101struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
 102{
 103        struct nfs4_state_owner *sp;
 104        struct rb_node *pos;
 105        struct rpc_cred *cred = NULL;
 106
 107        for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
 108                sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
 109                if (list_empty(&sp->so_states))
 110                        continue;
 111                cred = get_rpccred(sp->so_cred);
 112                break;
 113        }
 114        return cred;
 115}
 116
 117#if defined(CONFIG_NFS_V4_1)
 118
 119struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
 120{
 121        struct rpc_cred *cred;
 122
 123        spin_lock(&clp->cl_lock);
 124        cred = nfs4_get_machine_cred_locked(clp);
 125        spin_unlock(&clp->cl_lock);
 126        return cred;
 127}
 128
 129#endif /* CONFIG_NFS_V4_1 */
 130
 131struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
 132{
 133        struct nfs4_state_owner *sp;
 134        struct rb_node *pos;
 135        struct rpc_cred *cred;
 136
 137        spin_lock(&clp->cl_lock);
 138        cred = nfs4_get_machine_cred_locked(clp);
 139        if (cred != NULL)
 140                goto out;
 141        pos = rb_first(&clp->cl_state_owners);
 142        if (pos != NULL) {
 143                sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
 144                cred = get_rpccred(sp->so_cred);
 145        }
 146out:
 147        spin_unlock(&clp->cl_lock);
 148        return cred;
 149}
 150
 151static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new,
 152                __u64 minval, int maxbits)
 153{
 154        struct rb_node **p, *parent;
 155        struct nfs_unique_id *pos;
 156        __u64 mask = ~0ULL;
 157
 158        if (maxbits < 64)
 159                mask = (1ULL << maxbits) - 1ULL;
 160
 161        /* Ensure distribution is more or less flat */
 162        get_random_bytes(&new->id, sizeof(new->id));
 163        new->id &= mask;
 164        if (new->id < minval)
 165                new->id += minval;
 166retry:
 167        p = &root->rb_node;
 168        parent = NULL;
 169
 170        while (*p != NULL) {
 171                parent = *p;
 172                pos = rb_entry(parent, struct nfs_unique_id, rb_node);
 173
 174                if (new->id < pos->id)
 175                        p = &(*p)->rb_left;
 176                else if (new->id > pos->id)
 177                        p = &(*p)->rb_right;
 178                else
 179                        goto id_exists;
 180        }
 181        rb_link_node(&new->rb_node, parent, p);
 182        rb_insert_color(&new->rb_node, root);
 183        return;
 184id_exists:
 185        for (;;) {
 186                new->id++;
 187                if (new->id < minval || (new->id & mask) != new->id) {
 188                        new->id = minval;
 189                        break;
 190                }
 191                parent = rb_next(parent);
 192                if (parent == NULL)
 193                        break;
 194                pos = rb_entry(parent, struct nfs_unique_id, rb_node);
 195                if (new->id < pos->id)
 196                        break;
 197        }
 198        goto retry;
 199}
 200
 201static void nfs_free_unique_id(struct rb_root *root, struct nfs_unique_id *id)
 202{
 203        rb_erase(&id->rb_node, root);
 204}
 205
 206static struct nfs4_state_owner *
 207nfs4_find_state_owner(struct nfs_server *server, struct rpc_cred *cred)
 208{
 209        struct nfs_client *clp = server->nfs_client;
 210        struct rb_node **p = &clp->cl_state_owners.rb_node,
 211                       *parent = NULL;
 212        struct nfs4_state_owner *sp, *res = NULL;
 213
 214        while (*p != NULL) {
 215                parent = *p;
 216                sp = rb_entry(parent, struct nfs4_state_owner, so_client_node);
 217
 218                if (server < sp->so_server) {
 219                        p = &parent->rb_left;
 220                        continue;
 221                }
 222                if (server > sp->so_server) {
 223                        p = &parent->rb_right;
 224                        continue;
 225                }
 226                if (cred < sp->so_cred)
 227                        p = &parent->rb_left;
 228                else if (cred > sp->so_cred)
 229                        p = &parent->rb_right;
 230                else {
 231                        atomic_inc(&sp->so_count);
 232                        res = sp;
 233                        break;
 234                }
 235        }
 236        return res;
 237}
 238
 239static struct nfs4_state_owner *
 240nfs4_insert_state_owner(struct nfs_client *clp, struct nfs4_state_owner *new)
 241{
 242        struct rb_node **p = &clp->cl_state_owners.rb_node,
 243                       *parent = NULL;
 244        struct nfs4_state_owner *sp;
 245
 246        while (*p != NULL) {
 247                parent = *p;
 248                sp = rb_entry(parent, struct nfs4_state_owner, so_client_node);
 249
 250                if (new->so_server < sp->so_server) {
 251                        p = &parent->rb_left;
 252                        continue;
 253                }
 254                if (new->so_server > sp->so_server) {
 255                        p = &parent->rb_right;
 256                        continue;
 257                }
 258                if (new->so_cred < sp->so_cred)
 259                        p = &parent->rb_left;
 260                else if (new->so_cred > sp->so_cred)
 261                        p = &parent->rb_right;
 262                else {
 263                        atomic_inc(&sp->so_count);
 264                        return sp;
 265                }
 266        }
 267        nfs_alloc_unique_id(&clp->cl_openowner_id, &new->so_owner_id, 1, 64);
 268        rb_link_node(&new->so_client_node, parent, p);
 269        rb_insert_color(&new->so_client_node, &clp->cl_state_owners);
 270        return new;
 271}
 272
 273static void
 274nfs4_remove_state_owner(struct nfs_client *clp, struct nfs4_state_owner *sp)
 275{
 276        if (!RB_EMPTY_NODE(&sp->so_client_node))
 277                rb_erase(&sp->so_client_node, &clp->cl_state_owners);
 278        nfs_free_unique_id(&clp->cl_openowner_id, &sp->so_owner_id);
 279}
 280
 281/*
 282 * nfs4_alloc_state_owner(): this is called on the OPEN or CREATE path to
 283 * create a new state_owner.
 284 *
 285 */
 286static struct nfs4_state_owner *
 287nfs4_alloc_state_owner(void)
 288{
 289        struct nfs4_state_owner *sp;
 290
 291        sp = kzalloc(sizeof(*sp),GFP_KERNEL);
 292        if (!sp)
 293                return NULL;
 294        spin_lock_init(&sp->so_lock);
 295        INIT_LIST_HEAD(&sp->so_states);
 296        INIT_LIST_HEAD(&sp->so_delegations);
 297        rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue");
 298        sp->so_seqid.sequence = &sp->so_sequence;
 299        spin_lock_init(&sp->so_sequence.lock);
 300        INIT_LIST_HEAD(&sp->so_sequence.list);
 301        atomic_set(&sp->so_count, 1);
 302        return sp;
 303}
 304
 305static void
 306nfs4_drop_state_owner(struct nfs4_state_owner *sp)
 307{
 308        if (!RB_EMPTY_NODE(&sp->so_client_node)) {
 309                struct nfs_client *clp = sp->so_client;
 310
 311                spin_lock(&clp->cl_lock);
 312                rb_erase(&sp->so_client_node, &clp->cl_state_owners);
 313                RB_CLEAR_NODE(&sp->so_client_node);
 314                spin_unlock(&clp->cl_lock);
 315        }
 316}
 317
 318struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred)
 319{
 320        struct nfs_client *clp = server->nfs_client;
 321        struct nfs4_state_owner *sp, *new;
 322
 323        spin_lock(&clp->cl_lock);
 324        sp = nfs4_find_state_owner(server, cred);
 325        spin_unlock(&clp->cl_lock);
 326        if (sp != NULL)
 327                return sp;
 328        new = nfs4_alloc_state_owner();
 329        if (new == NULL)
 330                return NULL;
 331        new->so_client = clp;
 332        new->so_server = server;
 333        new->so_cred = cred;
 334        spin_lock(&clp->cl_lock);
 335        sp = nfs4_insert_state_owner(clp, new);
 336        spin_unlock(&clp->cl_lock);
 337        if (sp == new)
 338                get_rpccred(cred);
 339        else {
 340                rpc_destroy_wait_queue(&new->so_sequence.wait);
 341                kfree(new);
 342        }
 343        return sp;
 344}
 345
 346void nfs4_put_state_owner(struct nfs4_state_owner *sp)
 347{
 348        struct nfs_client *clp = sp->so_client;
 349        struct rpc_cred *cred = sp->so_cred;
 350
 351        if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock))
 352                return;
 353        nfs4_remove_state_owner(clp, sp);
 354        spin_unlock(&clp->cl_lock);
 355        rpc_destroy_wait_queue(&sp->so_sequence.wait);
 356        put_rpccred(cred);
 357        kfree(sp);
 358}
 359
 360static struct nfs4_state *
 361nfs4_alloc_open_state(void)
 362{
 363        struct nfs4_state *state;
 364
 365        state = kzalloc(sizeof(*state), GFP_KERNEL);
 366        if (!state)
 367                return NULL;
 368        atomic_set(&state->count, 1);
 369        INIT_LIST_HEAD(&state->lock_states);
 370        spin_lock_init(&state->state_lock);
 371        seqlock_init(&state->seqlock);
 372        return state;
 373}
 374
 375void
 376nfs4_state_set_mode_locked(struct nfs4_state *state, fmode_t fmode)
 377{
 378        if (state->state == fmode)
 379                return;
 380        /* NB! List reordering - see the reclaim code for why.  */
 381        if ((fmode & FMODE_WRITE) != (state->state & FMODE_WRITE)) {
 382                if (fmode & FMODE_WRITE)
 383                        list_move(&state->open_states, &state->owner->so_states);
 384                else
 385                        list_move_tail(&state->open_states, &state->owner->so_states);
 386        }
 387        state->state = fmode;
 388}
 389
 390static struct nfs4_state *
 391__nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner)
 392{
 393        struct nfs_inode *nfsi = NFS_I(inode);
 394        struct nfs4_state *state;
 395
 396        list_for_each_entry(state, &nfsi->open_states, inode_states) {
 397                if (state->owner != owner)
 398                        continue;
 399                if (atomic_inc_not_zero(&state->count))
 400                        return state;
 401        }
 402        return NULL;
 403}
 404
 405static void
 406nfs4_free_open_state(struct nfs4_state *state)
 407{
 408        kfree(state);
 409}
 410
 411struct nfs4_state *
 412nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
 413{
 414        struct nfs4_state *state, *new;
 415        struct nfs_inode *nfsi = NFS_I(inode);
 416
 417        spin_lock(&inode->i_lock);
 418        state = __nfs4_find_state_byowner(inode, owner);
 419        spin_unlock(&inode->i_lock);
 420        if (state)
 421                goto out;
 422        new = nfs4_alloc_open_state();
 423        spin_lock(&owner->so_lock);
 424        spin_lock(&inode->i_lock);
 425        state = __nfs4_find_state_byowner(inode, owner);
 426        if (state == NULL && new != NULL) {
 427                state = new;
 428                state->owner = owner;
 429                atomic_inc(&owner->so_count);
 430                list_add(&state->inode_states, &nfsi->open_states);
 431                state->inode = igrab(inode);
 432                spin_unlock(&inode->i_lock);
 433                /* Note: The reclaim code dictates that we add stateless
 434                 * and read-only stateids to the end of the list */
 435                list_add_tail(&state->open_states, &owner->so_states);
 436                spin_unlock(&owner->so_lock);
 437        } else {
 438                spin_unlock(&inode->i_lock);
 439                spin_unlock(&owner->so_lock);
 440                if (new)
 441                        nfs4_free_open_state(new);
 442        }
 443out:
 444        return state;
 445}
 446
 447void nfs4_put_open_state(struct nfs4_state *state)
 448{
 449        struct inode *inode = state->inode;
 450        struct nfs4_state_owner *owner = state->owner;
 451
 452        if (!atomic_dec_and_lock(&state->count, &owner->so_lock))
 453                return;
 454        spin_lock(&inode->i_lock);
 455        list_del(&state->inode_states);
 456        list_del(&state->open_states);
 457        spin_unlock(&inode->i_lock);
 458        spin_unlock(&owner->so_lock);
 459        iput(inode);
 460        nfs4_free_open_state(state);
 461        nfs4_put_state_owner(owner);
 462}
 463
 464/*
 465 * Close the current file.
 466 */
 467static void __nfs4_close(struct path *path, struct nfs4_state *state, fmode_t fmode, int wait)
 468{
 469        struct nfs4_state_owner *owner = state->owner;
 470        int call_close = 0;
 471        fmode_t newstate;
 472
 473        atomic_inc(&owner->so_count);
 474        /* Protect against nfs4_find_state() */
 475        spin_lock(&owner->so_lock);
 476        switch (fmode & (FMODE_READ | FMODE_WRITE)) {
 477                case FMODE_READ:
 478                        state->n_rdonly--;
 479                        break;
 480                case FMODE_WRITE:
 481                        state->n_wronly--;
 482                        break;
 483                case FMODE_READ|FMODE_WRITE:
 484                        state->n_rdwr--;
 485        }
 486        newstate = FMODE_READ|FMODE_WRITE;
 487        if (state->n_rdwr == 0) {
 488                if (state->n_rdonly == 0) {
 489                        newstate &= ~FMODE_READ;
 490                        call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags);
 491                        call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
 492                }
 493                if (state->n_wronly == 0) {
 494                        newstate &= ~FMODE_WRITE;
 495                        call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags);
 496                        call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
 497                }
 498                if (newstate == 0)
 499                        clear_bit(NFS_DELEGATED_STATE, &state->flags);
 500        }
 501        nfs4_state_set_mode_locked(state, newstate);
 502        spin_unlock(&owner->so_lock);
 503
 504        if (!call_close) {
 505                nfs4_put_open_state(state);
 506                nfs4_put_state_owner(owner);
 507        } else
 508                nfs4_do_close(path, state, wait);
 509}
 510
 511void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode)
 512{
 513        __nfs4_close(path, state, fmode, 0);
 514}
 515
 516void nfs4_close_sync(struct path *path, struct nfs4_state *state, fmode_t fmode)
 517{
 518        __nfs4_close(path, state, fmode, 1);
 519}
 520
 521/*
 522 * Search the state->lock_states for an existing lock_owner
 523 * that is compatible with current->files
 524 */
 525static struct nfs4_lock_state *
 526__nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
 527{
 528        struct nfs4_lock_state *pos;
 529        list_for_each_entry(pos, &state->lock_states, ls_locks) {
 530                if (pos->ls_owner != fl_owner)
 531                        continue;
 532                atomic_inc(&pos->ls_count);
 533                return pos;
 534        }
 535        return NULL;
 536}
 537
 538/*
 539 * Return a compatible lock_state. If no initialized lock_state structure
 540 * exists, return an uninitialized one.
 541 *
 542 */
 543static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
 544{
 545        struct nfs4_lock_state *lsp;
 546        struct nfs_client *clp = state->owner->so_client;
 547
 548        lsp = kzalloc(sizeof(*lsp), GFP_KERNEL);
 549        if (lsp == NULL)
 550                return NULL;
 551        rpc_init_wait_queue(&lsp->ls_sequence.wait, "lock_seqid_waitqueue");
 552        spin_lock_init(&lsp->ls_sequence.lock);
 553        INIT_LIST_HEAD(&lsp->ls_sequence.list);
 554        lsp->ls_seqid.sequence = &lsp->ls_sequence;
 555        atomic_set(&lsp->ls_count, 1);
 556        lsp->ls_state = state;
 557        lsp->ls_owner = fl_owner;
 558        spin_lock(&clp->cl_lock);
 559        nfs_alloc_unique_id(&clp->cl_lockowner_id, &lsp->ls_id, 1, 64);
 560        spin_unlock(&clp->cl_lock);
 561        INIT_LIST_HEAD(&lsp->ls_locks);
 562        return lsp;
 563}
 564
 565static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
 566{
 567        struct nfs_client *clp = lsp->ls_state->owner->so_client;
 568
 569        spin_lock(&clp->cl_lock);
 570        nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id);
 571        spin_unlock(&clp->cl_lock);
 572        rpc_destroy_wait_queue(&lsp->ls_sequence.wait);
 573        kfree(lsp);
 574}
 575
 576/*
 577 * Return a compatible lock_state. If no initialized lock_state structure
 578 * exists, return an uninitialized one.
 579 *
 580 */
 581static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
 582{
 583        struct nfs4_lock_state *lsp, *new = NULL;
 584        
 585        for(;;) {
 586                spin_lock(&state->state_lock);
 587                lsp = __nfs4_find_lock_state(state, owner);
 588                if (lsp != NULL)
 589                        break;
 590                if (new != NULL) {
 591                        list_add(&new->ls_locks, &state->lock_states);
 592                        set_bit(LK_STATE_IN_USE, &state->flags);
 593                        lsp = new;
 594                        new = NULL;
 595                        break;
 596                }
 597                spin_unlock(&state->state_lock);
 598                new = nfs4_alloc_lock_state(state, owner);
 599                if (new == NULL)
 600                        return NULL;
 601        }
 602        spin_unlock(&state->state_lock);
 603        if (new != NULL)
 604                nfs4_free_lock_state(new);
 605        return lsp;
 606}
 607
 608/*
 609 * Release reference to lock_state, and free it if we see that
 610 * it is no longer in use
 611 */
 612void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
 613{
 614        struct nfs4_state *state;
 615
 616        if (lsp == NULL)
 617                return;
 618        state = lsp->ls_state;
 619        if (!atomic_dec_and_lock(&lsp->ls_count, &state->state_lock))
 620                return;
 621        list_del(&lsp->ls_locks);
 622        if (list_empty(&state->lock_states))
 623                clear_bit(LK_STATE_IN_USE, &state->flags);
 624        spin_unlock(&state->state_lock);
 625        nfs4_free_lock_state(lsp);
 626}
 627
 628static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
 629{
 630        struct nfs4_lock_state *lsp = src->fl_u.nfs4_fl.owner;
 631
 632        dst->fl_u.nfs4_fl.owner = lsp;
 633        atomic_inc(&lsp->ls_count);
 634}
 635
 636static void nfs4_fl_release_lock(struct file_lock *fl)
 637{
 638        nfs4_put_lock_state(fl->fl_u.nfs4_fl.owner);
 639}
 640
 641static const struct file_lock_operations nfs4_fl_lock_ops = {
 642        .fl_copy_lock = nfs4_fl_copy_lock,
 643        .fl_release_private = nfs4_fl_release_lock,
 644};
 645
 646int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
 647{
 648        struct nfs4_lock_state *lsp;
 649
 650        if (fl->fl_ops != NULL)
 651                return 0;
 652        lsp = nfs4_get_lock_state(state, fl->fl_owner);
 653        if (lsp == NULL)
 654                return -ENOMEM;
 655        fl->fl_u.nfs4_fl.owner = lsp;
 656        fl->fl_ops = &nfs4_fl_lock_ops;
 657        return 0;
 658}
 659
 660/*
 661 * Byte-range lock aware utility to initialize the stateid of read/write
 662 * requests.
 663 */
 664void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner)
 665{
 666        struct nfs4_lock_state *lsp;
 667        int seq;
 668
 669        do {
 670                seq = read_seqbegin(&state->seqlock);
 671                memcpy(dst, &state->stateid, sizeof(*dst));
 672        } while (read_seqretry(&state->seqlock, seq));
 673        if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
 674                return;
 675
 676        spin_lock(&state->state_lock);
 677        lsp = __nfs4_find_lock_state(state, fl_owner);
 678        if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
 679                memcpy(dst, &lsp->ls_stateid, sizeof(*dst));
 680        spin_unlock(&state->state_lock);
 681        nfs4_put_lock_state(lsp);
 682}
 683
 684struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
 685{
 686        struct nfs_seqid *new;
 687
 688        new = kmalloc(sizeof(*new), GFP_KERNEL);
 689        if (new != NULL) {
 690                new->sequence = counter;
 691                INIT_LIST_HEAD(&new->list);
 692        }
 693        return new;
 694}
 695
 696void nfs_free_seqid(struct nfs_seqid *seqid)
 697{
 698        if (!list_empty(&seqid->list)) {
 699                struct rpc_sequence *sequence = seqid->sequence->sequence;
 700
 701                spin_lock(&sequence->lock);
 702                list_del(&seqid->list);
 703                spin_unlock(&sequence->lock);
 704                rpc_wake_up(&sequence->wait);
 705        }
 706        kfree(seqid);
 707}
 708
 709/*
 710 * Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or
 711 * failed with a seqid incrementing error -
 712 * see comments nfs_fs.h:seqid_mutating_error()
 713 */
 714static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
 715{
 716        BUG_ON(list_first_entry(&seqid->sequence->sequence->list, struct nfs_seqid, list) != seqid);
 717        switch (status) {
 718                case 0:
 719                        break;
 720                case -NFS4ERR_BAD_SEQID:
 721                        if (seqid->sequence->flags & NFS_SEQID_CONFIRMED)
 722                                return;
 723                        printk(KERN_WARNING "NFS: v4 server returned a bad"
 724                                        " sequence-id error on an"
 725                                        " unconfirmed sequence %p!\n",
 726                                        seqid->sequence);
 727                case -NFS4ERR_STALE_CLIENTID:
 728                case -NFS4ERR_STALE_STATEID:
 729                case -NFS4ERR_BAD_STATEID:
 730                case -NFS4ERR_BADXDR:
 731                case -NFS4ERR_RESOURCE:
 732                case -NFS4ERR_NOFILEHANDLE:
 733                        /* Non-seqid mutating errors */
 734                        return;
 735        };
 736        /*
 737         * Note: no locking needed as we are guaranteed to be first
 738         * on the sequence list
 739         */
 740        seqid->sequence->counter++;
 741}
 742
 743void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
 744{
 745        struct nfs4_state_owner *sp = container_of(seqid->sequence,
 746                                        struct nfs4_state_owner, so_seqid);
 747        struct nfs_server *server = sp->so_server;
 748
 749        if (status == -NFS4ERR_BAD_SEQID)
 750                nfs4_drop_state_owner(sp);
 751        if (!nfs4_has_session(server->nfs_client))
 752                nfs_increment_seqid(status, seqid);
 753}
 754
 755/*
 756 * Increment the seqid if the LOCK/LOCKU succeeded, or
 757 * failed with a seqid incrementing error -
 758 * see comments nfs_fs.h:seqid_mutating_error()
 759 */
 760void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
 761{
 762        nfs_increment_seqid(status, seqid);
 763}
 764
 765int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
 766{
 767        struct rpc_sequence *sequence = seqid->sequence->sequence;
 768        int status = 0;
 769
 770        spin_lock(&sequence->lock);
 771        if (list_empty(&seqid->list))
 772                list_add_tail(&seqid->list, &sequence->list);
 773        if (list_first_entry(&sequence->list, struct nfs_seqid, list) == seqid)
 774                goto unlock;
 775        rpc_sleep_on(&sequence->wait, task, NULL);
 776        status = -EAGAIN;
 777unlock:
 778        spin_unlock(&sequence->lock);
 779        return status;
 780}
 781
 782static int nfs4_run_state_manager(void *);
 783
 784static void nfs4_clear_state_manager_bit(struct nfs_client *clp)
 785{
 786        smp_mb__before_clear_bit();
 787        clear_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state);
 788        smp_mb__after_clear_bit();
 789        wake_up_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING);
 790        rpc_wake_up(&clp->cl_rpcwaitq);
 791}
 792
 793/*
 794 * Schedule the nfs_client asynchronous state management routine
 795 */
 796void nfs4_schedule_state_manager(struct nfs_client *clp)
 797{
 798        struct task_struct *task;
 799
 800        if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
 801                return;
 802        __module_get(THIS_MODULE);
 803        atomic_inc(&clp->cl_count);
 804        task = kthread_run(nfs4_run_state_manager, clp, "%s-manager",
 805                                rpc_peeraddr2str(clp->cl_rpcclient,
 806                                                        RPC_DISPLAY_ADDR));
 807        if (!IS_ERR(task))
 808                return;
 809        nfs4_clear_state_manager_bit(clp);
 810        nfs_put_client(clp);
 811        module_put(THIS_MODULE);
 812}
 813
 814/*
 815 * Schedule a state recovery attempt
 816 */
 817void nfs4_schedule_state_recovery(struct nfs_client *clp)
 818{
 819        if (!clp)
 820                return;
 821        if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
 822                set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
 823        nfs4_schedule_state_manager(clp);
 824}
 825
 826static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state)
 827{
 828
 829        set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
 830        /* Don't recover state that expired before the reboot */
 831        if (test_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags)) {
 832                clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
 833                return 0;
 834        }
 835        set_bit(NFS_OWNER_RECLAIM_REBOOT, &state->owner->so_flags);
 836        set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
 837        return 1;
 838}
 839
 840int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state)
 841{
 842        set_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags);
 843        clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
 844        set_bit(NFS_OWNER_RECLAIM_NOGRACE, &state->owner->so_flags);
 845        set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
 846        return 1;
 847}
 848
 849static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops)
 850{
 851        struct inode *inode = state->inode;
 852        struct nfs_inode *nfsi = NFS_I(inode);
 853        struct file_lock *fl;
 854        int status = 0;
 855
 856        if (inode->i_flock == NULL)
 857                return 0;
 858
 859        /* Guard against delegation returns and new lock/unlock calls */
 860        down_write(&nfsi->rwsem);
 861        /* Protect inode->i_flock using the BKL */
 862        lock_kernel();
 863        for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
 864                if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
 865                        continue;
 866                if (nfs_file_open_context(fl->fl_file)->state != state)
 867                        continue;
 868                unlock_kernel();
 869                status = ops->recover_lock(state, fl);
 870                switch (status) {
 871                        case 0:
 872                                break;
 873                        case -ESTALE:
 874                        case -NFS4ERR_ADMIN_REVOKED:
 875                        case -NFS4ERR_STALE_STATEID:
 876                        case -NFS4ERR_BAD_STATEID:
 877                        case -NFS4ERR_EXPIRED:
 878                        case -NFS4ERR_NO_GRACE:
 879                        case -NFS4ERR_STALE_CLIENTID:
 880                                goto out;
 881                        default:
 882                                printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
 883                                                __func__, status);
 884                        case -ENOMEM:
 885                        case -NFS4ERR_DENIED:
 886                        case -NFS4ERR_RECLAIM_BAD:
 887                        case -NFS4ERR_RECLAIM_CONFLICT:
 888                                /* kill_proc(fl->fl_pid, SIGLOST, 1); */
 889                                status = 0;
 890                }
 891                lock_kernel();
 892        }
 893        unlock_kernel();
 894out:
 895        up_write(&nfsi->rwsem);
 896        return status;
 897}
 898
 899static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs4_state_recovery_ops *ops)
 900{
 901        struct nfs4_state *state;
 902        struct nfs4_lock_state *lock;
 903        int status = 0;
 904
 905        /* Note: we rely on the sp->so_states list being ordered 
 906         * so that we always reclaim open(O_RDWR) and/or open(O_WRITE)
 907         * states first.
 908         * This is needed to ensure that the server won't give us any
 909         * read delegations that we have to return if, say, we are
 910         * recovering after a network partition or a reboot from a
 911         * server that doesn't support a grace period.
 912         */
 913restart:
 914        spin_lock(&sp->so_lock);
 915        list_for_each_entry(state, &sp->so_states, open_states) {
 916                if (!test_and_clear_bit(ops->state_flag_bit, &state->flags))
 917                        continue;
 918                if (state->state == 0)
 919                        continue;
 920                atomic_inc(&state->count);
 921                spin_unlock(&sp->so_lock);
 922                status = ops->recover_open(sp, state);
 923                if (status >= 0) {
 924                        status = nfs4_reclaim_locks(state, ops);
 925                        if (status >= 0) {
 926                                list_for_each_entry(lock, &state->lock_states, ls_locks) {
 927                                        if (!(lock->ls_flags & NFS_LOCK_INITIALIZED))
 928                                                printk("%s: Lock reclaim failed!\n",
 929                                                        __func__);
 930                                }
 931                                nfs4_put_open_state(state);
 932                                goto restart;
 933                        }
 934                }
 935                switch (status) {
 936                        default:
 937                                printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
 938                                                __func__, status);
 939                        case -ENOENT:
 940                        case -ENOMEM:
 941                        case -ESTALE:
 942                                /*
 943                                 * Open state on this file cannot be recovered
 944                                 * All we can do is revert to using the zero stateid.
 945                                 */
 946                                memset(state->stateid.data, 0,
 947                                        sizeof(state->stateid.data));
 948                                /* Mark the file as being 'closed' */
 949                                state->state = 0;
 950                                break;
 951                        case -NFS4ERR_ADMIN_REVOKED:
 952                        case -NFS4ERR_STALE_STATEID:
 953                        case -NFS4ERR_BAD_STATEID:
 954                        case -NFS4ERR_RECLAIM_BAD:
 955                        case -NFS4ERR_RECLAIM_CONFLICT:
 956                                nfs4_state_mark_reclaim_nograce(sp->so_client, state);
 957                                break;
 958                        case -NFS4ERR_EXPIRED:
 959                        case -NFS4ERR_NO_GRACE:
 960                                nfs4_state_mark_reclaim_nograce(sp->so_client, state);
 961                        case -NFS4ERR_STALE_CLIENTID:
 962                                goto out_err;
 963                }
 964                nfs4_put_open_state(state);
 965                goto restart;
 966        }
 967        spin_unlock(&sp->so_lock);
 968        return 0;
 969out_err:
 970        nfs4_put_open_state(state);
 971        return status;
 972}
 973
 974static void nfs4_clear_open_state(struct nfs4_state *state)
 975{
 976        struct nfs4_lock_state *lock;
 977
 978        clear_bit(NFS_DELEGATED_STATE, &state->flags);
 979        clear_bit(NFS_O_RDONLY_STATE, &state->flags);
 980        clear_bit(NFS_O_WRONLY_STATE, &state->flags);
 981        clear_bit(NFS_O_RDWR_STATE, &state->flags);
 982        list_for_each_entry(lock, &state->lock_states, ls_locks) {
 983                lock->ls_seqid.flags = 0;
 984                lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
 985        }
 986}
 987
 988static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp, int (*mark_reclaim)(struct nfs_client *clp, struct nfs4_state *state))
 989{
 990        struct nfs4_state_owner *sp;
 991        struct rb_node *pos;
 992        struct nfs4_state *state;
 993
 994        /* Reset all sequence ids to zero */
 995        for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
 996                sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
 997                sp->so_seqid.flags = 0;
 998                spin_lock(&sp->so_lock);
 999                list_for_each_entry(state, &sp->so_states, open_states) {
1000                        if (mark_reclaim(clp, state))
1001                                nfs4_clear_open_state(state);
1002                }
1003                spin_unlock(&sp->so_lock);
1004        }
1005}
1006
1007static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
1008{
1009        /* Mark all delegations for reclaim */
1010        nfs_delegation_mark_reclaim(clp);
1011        nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
1012}
1013
1014static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
1015{
1016        struct nfs4_state_owner *sp;
1017        struct rb_node *pos;
1018        struct nfs4_state *state;
1019
1020        if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
1021                return;
1022
1023        for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
1024                sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
1025                spin_lock(&sp->so_lock);
1026                list_for_each_entry(state, &sp->so_states, open_states) {
1027                        if (!test_and_clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags))
1028                                continue;
1029                        nfs4_state_mark_reclaim_nograce(clp, state);
1030                }
1031                spin_unlock(&sp->so_lock);
1032        }
1033
1034        nfs_delegation_reap_unclaimed(clp);
1035}
1036
1037static void nfs_delegation_clear_all(struct nfs_client *clp)
1038{
1039        nfs_delegation_mark_reclaim(clp);
1040        nfs_delegation_reap_unclaimed(clp);
1041}
1042
1043static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp)
1044{
1045        nfs_delegation_clear_all(clp);
1046        nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce);
1047}
1048
1049static void nfs4_state_end_reclaim_nograce(struct nfs_client *clp)
1050{
1051        clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
1052}
1053
1054static void nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1055{
1056        switch (error) {
1057                case -NFS4ERR_CB_PATH_DOWN:
1058                        nfs_handle_cb_pathdown(clp);
1059                        break;
1060                case -NFS4ERR_STALE_CLIENTID:
1061                case -NFS4ERR_LEASE_MOVED:
1062                        set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1063                        nfs4_state_start_reclaim_reboot(clp);
1064                        break;
1065                case -NFS4ERR_EXPIRED:
1066                        set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1067                        nfs4_state_start_reclaim_nograce(clp);
1068                case -NFS4ERR_BADSESSION:
1069                case -NFS4ERR_BADSLOT:
1070                case -NFS4ERR_BAD_HIGH_SLOT:
1071                case -NFS4ERR_DEADSESSION:
1072                case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1073                case -NFS4ERR_SEQ_FALSE_RETRY:
1074                case -NFS4ERR_SEQ_MISORDERED:
1075                        set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1076        }
1077}
1078
1079static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops)
1080{
1081        struct rb_node *pos;
1082        int status = 0;
1083
1084restart:
1085        spin_lock(&clp->cl_lock);
1086        for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
1087                struct nfs4_state_owner *sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
1088                if (!test_and_clear_bit(ops->owner_flag_bit, &sp->so_flags))
1089                        continue;
1090                atomic_inc(&sp->so_count);
1091                spin_unlock(&clp->cl_lock);
1092                status = nfs4_reclaim_open_state(sp, ops);
1093                if (status < 0) {
1094                        set_bit(ops->owner_flag_bit, &sp->so_flags);
1095                        nfs4_put_state_owner(sp);
1096                        nfs4_recovery_handle_error(clp, status);
1097                        return status;
1098                }
1099                nfs4_put_state_owner(sp);
1100                goto restart;
1101        }
1102        spin_unlock(&clp->cl_lock);
1103        return status;
1104}
1105
1106static int nfs4_check_lease(struct nfs_client *clp)
1107{
1108        struct rpc_cred *cred;
1109        struct nfs4_state_maintenance_ops *ops =
1110                nfs4_state_renewal_ops[clp->cl_minorversion];
1111        int status = -NFS4ERR_EXPIRED;
1112
1113        /* Is the client already known to have an expired lease? */
1114        if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
1115                return 0;
1116        spin_lock(&clp->cl_lock);
1117        cred = ops->get_state_renewal_cred_locked(clp);
1118        spin_unlock(&clp->cl_lock);
1119        if (cred == NULL) {
1120                cred = nfs4_get_setclientid_cred(clp);
1121                if (cred == NULL)
1122                        goto out;
1123        }
1124        status = ops->renew_lease(clp, cred);
1125        put_rpccred(cred);
1126out:
1127        nfs4_recovery_handle_error(clp, status);
1128        return status;
1129}
1130
1131static int nfs4_reclaim_lease(struct nfs_client *clp)
1132{
1133        struct rpc_cred *cred;
1134        struct nfs4_state_recovery_ops *ops =
1135                nfs4_reboot_recovery_ops[clp->cl_minorversion];
1136        int status = -ENOENT;
1137
1138        cred = ops->get_clid_cred(clp);
1139        if (cred != NULL) {
1140                status = ops->establish_clid(clp, cred);
1141                put_rpccred(cred);
1142                /* Handle case where the user hasn't set up machine creds */
1143                if (status == -EACCES && cred == clp->cl_machine_cred) {
1144                        nfs4_clear_machine_cred(clp);
1145                        status = -EAGAIN;
1146                }
1147                if (status == -NFS4ERR_MINOR_VERS_MISMATCH)
1148                        status = -EPROTONOSUPPORT;
1149        }
1150        return status;
1151}
1152
1153#ifdef CONFIG_NFS_V4_1
1154static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err)
1155{
1156        switch (err) {
1157        case -NFS4ERR_STALE_CLIENTID:
1158                set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1159                set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1160        }
1161}
1162
1163static int nfs4_reset_session(struct nfs_client *clp)
1164{
1165        int status;
1166
1167        status = nfs4_proc_destroy_session(clp->cl_session);
1168        if (status && status != -NFS4ERR_BADSESSION &&
1169            status != -NFS4ERR_DEADSESSION) {
1170                nfs4_session_recovery_handle_error(clp, status);
1171                goto out;
1172        }
1173
1174        memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN);
1175        status = nfs4_proc_create_session(clp, 1);
1176        if (status)
1177                nfs4_session_recovery_handle_error(clp, status);
1178                /* fall through*/
1179out:
1180        /* Wake up the next rpc task even on error */
1181        rpc_wake_up_next(&clp->cl_session->fc_slot_table.slot_tbl_waitq);
1182        return status;
1183}
1184
1185static int nfs4_initialize_session(struct nfs_client *clp)
1186{
1187        int status;
1188
1189        status = nfs4_proc_create_session(clp, 0);
1190        if (!status) {
1191                nfs_mark_client_ready(clp, NFS_CS_READY);
1192        } else if (status == -NFS4ERR_STALE_CLIENTID) {
1193                set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1194                set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
1195        } else {
1196                nfs_mark_client_ready(clp, status);
1197        }
1198        return status;
1199}
1200#else /* CONFIG_NFS_V4_1 */
1201static int nfs4_reset_session(struct nfs_client *clp) { return 0; }
1202static int nfs4_initialize_session(struct nfs_client *clp) { return 0; }
1203#endif /* CONFIG_NFS_V4_1 */
1204
1205/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
1206 * on EXCHANGE_ID for v4.1
1207 */
1208static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
1209{
1210        if (nfs4_has_session(clp)) {
1211                switch (status) {
1212                case -NFS4ERR_DELAY:
1213                case -NFS4ERR_CLID_INUSE:
1214                case -EAGAIN:
1215                        break;
1216
1217                case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1218                                         * in nfs4_exchange_id */
1219                default:
1220                        return;
1221                }
1222        }
1223        set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1224}
1225
1226static void nfs4_state_manager(struct nfs_client *clp)
1227{
1228        int status = 0;
1229
1230        /* Ensure exclusive access to NFSv4 state */
1231        for(;;) {
1232                if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
1233                        /* We're going to have to re-establish a clientid */
1234                        status = nfs4_reclaim_lease(clp);
1235                        if (status) {
1236                                nfs4_set_lease_expired(clp, status);
1237                                if (status == -EAGAIN)
1238                                        continue;
1239                                if (clp->cl_cons_state ==
1240                                                        NFS_CS_SESSION_INITING)
1241                                        nfs_mark_client_ready(clp, status);
1242                                goto out_error;
1243                        }
1244                        clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
1245                }
1246
1247                if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) {
1248                        status = nfs4_check_lease(clp);
1249                        if (status != 0)
1250                                continue;
1251                }
1252                /* Initialize or reset the session */
1253                if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)
1254                   && nfs4_has_session(clp)) {
1255                        if (clp->cl_cons_state == NFS_CS_SESSION_INITING)
1256                                status = nfs4_initialize_session(clp);
1257                        else
1258                                status = nfs4_reset_session(clp);
1259                        if (status) {
1260                                if (status == -NFS4ERR_STALE_CLIENTID)
1261                                        continue;
1262                                goto out_error;
1263                        }
1264                }
1265                /* First recover reboot state... */
1266                if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) {
1267                        status = nfs4_do_reclaim(clp,
1268                                nfs4_reboot_recovery_ops[clp->cl_minorversion]);
1269                        if (status == -NFS4ERR_STALE_CLIENTID)
1270                                continue;
1271                        if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
1272                                continue;
1273                        nfs4_state_end_reclaim_reboot(clp);
1274                        continue;
1275                }
1276
1277                /* Now recover expired state... */
1278                if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
1279                        status = nfs4_do_reclaim(clp,
1280                                nfs4_nograce_recovery_ops[clp->cl_minorversion]);
1281                        if (status < 0) {
1282                                set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
1283                                if (status == -NFS4ERR_STALE_CLIENTID)
1284                                        continue;
1285                                if (status == -NFS4ERR_EXPIRED)
1286                                        continue;
1287                                if (test_bit(NFS4CLNT_SESSION_SETUP,
1288                                                                &clp->cl_state))
1289                                        continue;
1290                                goto out_error;
1291                        } else
1292                                nfs4_state_end_reclaim_nograce(clp);
1293                        continue;
1294                }
1295
1296                if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) {
1297                        nfs_client_return_marked_delegations(clp);
1298                        continue;
1299                }
1300
1301                nfs4_clear_state_manager_bit(clp);
1302                /* Did we race with an attempt to give us more work? */
1303                if (clp->cl_state == 0)
1304                        break;
1305                if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
1306                        break;
1307        }
1308        return;
1309out_error:
1310        printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"
1311                        " with error %d\n", clp->cl_hostname, -status);
1312        if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
1313                nfs4_state_end_reclaim_reboot(clp);
1314        nfs4_clear_state_manager_bit(clp);
1315}
1316
1317static int nfs4_run_state_manager(void *ptr)
1318{
1319        struct nfs_client *clp = ptr;
1320
1321        allow_signal(SIGKILL);
1322        nfs4_state_manager(clp);
1323        nfs_put_client(clp);
1324        module_put_and_exit(0);
1325        return 0;
1326}
1327
1328/*
1329 * Local variables:
1330 *  c-basic-offset: 8
1331 * End:
1332 */
1333