diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 265 |
1 files changed, 160 insertions, 105 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index afe587d82f1e..5ef4c57618fe 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -69,10 +69,8 @@ init_nfsv4_state(struct nfs_server *server) | |||
69 | void | 69 | void |
70 | destroy_nfsv4_state(struct nfs_server *server) | 70 | destroy_nfsv4_state(struct nfs_server *server) |
71 | { | 71 | { |
72 | if (server->mnt_path) { | 72 | kfree(server->mnt_path); |
73 | kfree(server->mnt_path); | 73 | server->mnt_path = NULL; |
74 | server->mnt_path = NULL; | ||
75 | } | ||
76 | if (server->nfs4_state) { | 74 | if (server->nfs4_state) { |
77 | nfs4_put_client(server->nfs4_state); | 75 | nfs4_put_client(server->nfs4_state); |
78 | server->nfs4_state = NULL; | 76 | server->nfs4_state = NULL; |
@@ -264,13 +262,16 @@ nfs4_alloc_state_owner(void) | |||
264 | { | 262 | { |
265 | struct nfs4_state_owner *sp; | 263 | struct nfs4_state_owner *sp; |
266 | 264 | ||
267 | sp = kmalloc(sizeof(*sp),GFP_KERNEL); | 265 | sp = kzalloc(sizeof(*sp),GFP_KERNEL); |
268 | if (!sp) | 266 | if (!sp) |
269 | return NULL; | 267 | return NULL; |
270 | init_MUTEX(&sp->so_sema); | 268 | spin_lock_init(&sp->so_lock); |
271 | sp->so_seqid = 0; /* arbitrary */ | ||
272 | INIT_LIST_HEAD(&sp->so_states); | 269 | INIT_LIST_HEAD(&sp->so_states); |
273 | INIT_LIST_HEAD(&sp->so_delegations); | 270 | INIT_LIST_HEAD(&sp->so_delegations); |
271 | rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue"); | ||
272 | sp->so_seqid.sequence = &sp->so_sequence; | ||
273 | spin_lock_init(&sp->so_sequence.lock); | ||
274 | INIT_LIST_HEAD(&sp->so_sequence.list); | ||
274 | atomic_set(&sp->so_count, 1); | 275 | atomic_set(&sp->so_count, 1); |
275 | return sp; | 276 | return sp; |
276 | } | 277 | } |
@@ -308,8 +309,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct | |||
308 | new = NULL; | 309 | new = NULL; |
309 | } | 310 | } |
310 | spin_unlock(&clp->cl_lock); | 311 | spin_unlock(&clp->cl_lock); |
311 | if (new) | 312 | kfree(new); |
312 | kfree(new); | ||
313 | if (sp != NULL) | 313 | if (sp != NULL) |
314 | return sp; | 314 | return sp; |
315 | put_rpccred(cred); | 315 | put_rpccred(cred); |
@@ -359,35 +359,25 @@ nfs4_alloc_open_state(void) | |||
359 | memset(state->stateid.data, 0, sizeof(state->stateid.data)); | 359 | memset(state->stateid.data, 0, sizeof(state->stateid.data)); |
360 | atomic_set(&state->count, 1); | 360 | atomic_set(&state->count, 1); |
361 | INIT_LIST_HEAD(&state->lock_states); | 361 | INIT_LIST_HEAD(&state->lock_states); |
362 | init_MUTEX(&state->lock_sema); | ||
363 | spin_lock_init(&state->state_lock); | 362 | spin_lock_init(&state->state_lock); |
364 | return state; | 363 | return state; |
365 | } | 364 | } |
366 | 365 | ||
367 | static struct nfs4_state * | 366 | void |
368 | __nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode) | 367 | nfs4_state_set_mode_locked(struct nfs4_state *state, mode_t mode) |
369 | { | 368 | { |
370 | struct nfs_inode *nfsi = NFS_I(inode); | 369 | if (state->state == mode) |
371 | struct nfs4_state *state; | 370 | return; |
372 | 371 | /* NB! List reordering - see the reclaim code for why. */ | |
373 | mode &= (FMODE_READ|FMODE_WRITE); | 372 | if ((mode & FMODE_WRITE) != (state->state & FMODE_WRITE)) { |
374 | list_for_each_entry(state, &nfsi->open_states, inode_states) { | ||
375 | if (state->owner->so_cred != cred) | ||
376 | continue; | ||
377 | if ((mode & FMODE_READ) != 0 && state->nreaders == 0) | ||
378 | continue; | ||
379 | if ((mode & FMODE_WRITE) != 0 && state->nwriters == 0) | ||
380 | continue; | ||
381 | if ((state->state & mode) != mode) | ||
382 | continue; | ||
383 | atomic_inc(&state->count); | ||
384 | if (mode & FMODE_READ) | ||
385 | state->nreaders++; | ||
386 | if (mode & FMODE_WRITE) | 373 | if (mode & FMODE_WRITE) |
387 | state->nwriters++; | 374 | list_move(&state->open_states, &state->owner->so_states); |
388 | return state; | 375 | else |
376 | list_move_tail(&state->open_states, &state->owner->so_states); | ||
389 | } | 377 | } |
390 | return NULL; | 378 | if (mode == 0) |
379 | list_del_init(&state->inode_states); | ||
380 | state->state = mode; | ||
391 | } | 381 | } |
392 | 382 | ||
393 | static struct nfs4_state * | 383 | static struct nfs4_state * |
@@ -398,7 +388,7 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner) | |||
398 | 388 | ||
399 | list_for_each_entry(state, &nfsi->open_states, inode_states) { | 389 | list_for_each_entry(state, &nfsi->open_states, inode_states) { |
400 | /* Is this in the process of being freed? */ | 390 | /* Is this in the process of being freed? */ |
401 | if (state->nreaders == 0 && state->nwriters == 0) | 391 | if (state->state == 0) |
402 | continue; | 392 | continue; |
403 | if (state->owner == owner) { | 393 | if (state->owner == owner) { |
404 | atomic_inc(&state->count); | 394 | atomic_inc(&state->count); |
@@ -408,17 +398,6 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner) | |||
408 | return NULL; | 398 | return NULL; |
409 | } | 399 | } |
410 | 400 | ||
411 | struct nfs4_state * | ||
412 | nfs4_find_state(struct inode *inode, struct rpc_cred *cred, mode_t mode) | ||
413 | { | ||
414 | struct nfs4_state *state; | ||
415 | |||
416 | spin_lock(&inode->i_lock); | ||
417 | state = __nfs4_find_state(inode, cred, mode); | ||
418 | spin_unlock(&inode->i_lock); | ||
419 | return state; | ||
420 | } | ||
421 | |||
422 | static void | 401 | static void |
423 | nfs4_free_open_state(struct nfs4_state *state) | 402 | nfs4_free_open_state(struct nfs4_state *state) |
424 | { | 403 | { |
@@ -437,21 +416,23 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner) | |||
437 | if (state) | 416 | if (state) |
438 | goto out; | 417 | goto out; |
439 | new = nfs4_alloc_open_state(); | 418 | new = nfs4_alloc_open_state(); |
419 | spin_lock(&owner->so_lock); | ||
440 | spin_lock(&inode->i_lock); | 420 | spin_lock(&inode->i_lock); |
441 | state = __nfs4_find_state_byowner(inode, owner); | 421 | state = __nfs4_find_state_byowner(inode, owner); |
442 | if (state == NULL && new != NULL) { | 422 | if (state == NULL && new != NULL) { |
443 | state = new; | 423 | state = new; |
444 | /* Caller *must* be holding owner->so_sem */ | ||
445 | /* Note: The reclaim code dictates that we add stateless | ||
446 | * and read-only stateids to the end of the list */ | ||
447 | list_add_tail(&state->open_states, &owner->so_states); | ||
448 | state->owner = owner; | 424 | state->owner = owner; |
449 | atomic_inc(&owner->so_count); | 425 | atomic_inc(&owner->so_count); |
450 | list_add(&state->inode_states, &nfsi->open_states); | 426 | list_add(&state->inode_states, &nfsi->open_states); |
451 | state->inode = igrab(inode); | 427 | state->inode = igrab(inode); |
452 | spin_unlock(&inode->i_lock); | 428 | spin_unlock(&inode->i_lock); |
429 | /* Note: The reclaim code dictates that we add stateless | ||
430 | * and read-only stateids to the end of the list */ | ||
431 | list_add_tail(&state->open_states, &owner->so_states); | ||
432 | spin_unlock(&owner->so_lock); | ||
453 | } else { | 433 | } else { |
454 | spin_unlock(&inode->i_lock); | 434 | spin_unlock(&inode->i_lock); |
435 | spin_unlock(&owner->so_lock); | ||
455 | if (new) | 436 | if (new) |
456 | nfs4_free_open_state(new); | 437 | nfs4_free_open_state(new); |
457 | } | 438 | } |
@@ -461,68 +442,59 @@ out: | |||
461 | 442 | ||
462 | /* | 443 | /* |
463 | * Beware! Caller must be holding exactly one | 444 | * Beware! Caller must be holding exactly one |
464 | * reference to clp->cl_sem and owner->so_sema! | 445 | * reference to clp->cl_sem! |
465 | */ | 446 | */ |
466 | void nfs4_put_open_state(struct nfs4_state *state) | 447 | void nfs4_put_open_state(struct nfs4_state *state) |
467 | { | 448 | { |
468 | struct inode *inode = state->inode; | 449 | struct inode *inode = state->inode; |
469 | struct nfs4_state_owner *owner = state->owner; | 450 | struct nfs4_state_owner *owner = state->owner; |
470 | 451 | ||
471 | if (!atomic_dec_and_lock(&state->count, &inode->i_lock)) | 452 | if (!atomic_dec_and_lock(&state->count, &owner->so_lock)) |
472 | return; | 453 | return; |
454 | spin_lock(&inode->i_lock); | ||
473 | if (!list_empty(&state->inode_states)) | 455 | if (!list_empty(&state->inode_states)) |
474 | list_del(&state->inode_states); | 456 | list_del(&state->inode_states); |
475 | spin_unlock(&inode->i_lock); | ||
476 | list_del(&state->open_states); | 457 | list_del(&state->open_states); |
458 | spin_unlock(&inode->i_lock); | ||
459 | spin_unlock(&owner->so_lock); | ||
477 | iput(inode); | 460 | iput(inode); |
478 | BUG_ON (state->state != 0); | ||
479 | nfs4_free_open_state(state); | 461 | nfs4_free_open_state(state); |
480 | nfs4_put_state_owner(owner); | 462 | nfs4_put_state_owner(owner); |
481 | } | 463 | } |
482 | 464 | ||
483 | /* | 465 | /* |
484 | * Beware! Caller must be holding no references to clp->cl_sem! | 466 | * Close the current file. |
485 | * of owner->so_sema! | ||
486 | */ | 467 | */ |
487 | void nfs4_close_state(struct nfs4_state *state, mode_t mode) | 468 | void nfs4_close_state(struct nfs4_state *state, mode_t mode) |
488 | { | 469 | { |
489 | struct inode *inode = state->inode; | 470 | struct inode *inode = state->inode; |
490 | struct nfs4_state_owner *owner = state->owner; | 471 | struct nfs4_state_owner *owner = state->owner; |
491 | struct nfs4_client *clp = owner->so_client; | 472 | int oldstate, newstate = 0; |
492 | int newstate; | ||
493 | 473 | ||
494 | atomic_inc(&owner->so_count); | 474 | atomic_inc(&owner->so_count); |
495 | down_read(&clp->cl_sem); | ||
496 | down(&owner->so_sema); | ||
497 | /* Protect against nfs4_find_state() */ | 475 | /* Protect against nfs4_find_state() */ |
476 | spin_lock(&owner->so_lock); | ||
498 | spin_lock(&inode->i_lock); | 477 | spin_lock(&inode->i_lock); |
499 | if (mode & FMODE_READ) | 478 | if (mode & FMODE_READ) |
500 | state->nreaders--; | 479 | state->nreaders--; |
501 | if (mode & FMODE_WRITE) | 480 | if (mode & FMODE_WRITE) |
502 | state->nwriters--; | 481 | state->nwriters--; |
503 | if (state->nwriters == 0) { | 482 | oldstate = newstate = state->state; |
504 | if (state->nreaders == 0) | 483 | if (state->nreaders == 0) |
505 | list_del_init(&state->inode_states); | 484 | newstate &= ~FMODE_READ; |
506 | /* See reclaim code */ | 485 | if (state->nwriters == 0) |
507 | list_move_tail(&state->open_states, &owner->so_states); | 486 | newstate &= ~FMODE_WRITE; |
487 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { | ||
488 | nfs4_state_set_mode_locked(state, newstate); | ||
489 | oldstate = newstate; | ||
508 | } | 490 | } |
509 | spin_unlock(&inode->i_lock); | 491 | spin_unlock(&inode->i_lock); |
510 | newstate = 0; | 492 | spin_unlock(&owner->so_lock); |
511 | if (state->state != 0) { | 493 | |
512 | if (state->nreaders) | 494 | if (oldstate != newstate && nfs4_do_close(inode, state) == 0) |
513 | newstate |= FMODE_READ; | 495 | return; |
514 | if (state->nwriters) | ||
515 | newstate |= FMODE_WRITE; | ||
516 | if (state->state == newstate) | ||
517 | goto out; | ||
518 | if (nfs4_do_close(inode, state, newstate) == -EINPROGRESS) | ||
519 | return; | ||
520 | } | ||
521 | out: | ||
522 | nfs4_put_open_state(state); | 496 | nfs4_put_open_state(state); |
523 | up(&owner->so_sema); | ||
524 | nfs4_put_state_owner(owner); | 497 | nfs4_put_state_owner(owner); |
525 | up_read(&clp->cl_sem); | ||
526 | } | 498 | } |
527 | 499 | ||
528 | /* | 500 | /* |
@@ -546,19 +518,16 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) | |||
546 | * Return a compatible lock_state. If no initialized lock_state structure | 518 | * Return a compatible lock_state. If no initialized lock_state structure |
547 | * exists, return an uninitialized one. | 519 | * exists, return an uninitialized one. |
548 | * | 520 | * |
549 | * The caller must be holding state->lock_sema | ||
550 | */ | 521 | */ |
551 | static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) | 522 | static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) |
552 | { | 523 | { |
553 | struct nfs4_lock_state *lsp; | 524 | struct nfs4_lock_state *lsp; |
554 | struct nfs4_client *clp = state->owner->so_client; | 525 | struct nfs4_client *clp = state->owner->so_client; |
555 | 526 | ||
556 | lsp = kmalloc(sizeof(*lsp), GFP_KERNEL); | 527 | lsp = kzalloc(sizeof(*lsp), GFP_KERNEL); |
557 | if (lsp == NULL) | 528 | if (lsp == NULL) |
558 | return NULL; | 529 | return NULL; |
559 | lsp->ls_flags = 0; | 530 | lsp->ls_seqid.sequence = &state->owner->so_sequence; |
560 | lsp->ls_seqid = 0; /* arbitrary */ | ||
561 | memset(lsp->ls_stateid.data, 0, sizeof(lsp->ls_stateid.data)); | ||
562 | atomic_set(&lsp->ls_count, 1); | 531 | atomic_set(&lsp->ls_count, 1); |
563 | lsp->ls_owner = fl_owner; | 532 | lsp->ls_owner = fl_owner; |
564 | spin_lock(&clp->cl_lock); | 533 | spin_lock(&clp->cl_lock); |
@@ -572,7 +541,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f | |||
572 | * Return a compatible lock_state. If no initialized lock_state structure | 541 | * Return a compatible lock_state. If no initialized lock_state structure |
573 | * exists, return an uninitialized one. | 542 | * exists, return an uninitialized one. |
574 | * | 543 | * |
575 | * The caller must be holding state->lock_sema and clp->cl_sem | 544 | * The caller must be holding clp->cl_sem |
576 | */ | 545 | */ |
577 | static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) | 546 | static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) |
578 | { | 547 | { |
@@ -605,7 +574,7 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_ | |||
605 | * Release reference to lock_state, and free it if we see that | 574 | * Release reference to lock_state, and free it if we see that |
606 | * it is no longer in use | 575 | * it is no longer in use |
607 | */ | 576 | */ |
608 | static void nfs4_put_lock_state(struct nfs4_lock_state *lsp) | 577 | void nfs4_put_lock_state(struct nfs4_lock_state *lsp) |
609 | { | 578 | { |
610 | struct nfs4_state *state; | 579 | struct nfs4_state *state; |
611 | 580 | ||
@@ -673,29 +642,94 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f | |||
673 | nfs4_put_lock_state(lsp); | 642 | nfs4_put_lock_state(lsp); |
674 | } | 643 | } |
675 | 644 | ||
676 | /* | 645 | struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) |
677 | * Called with state->lock_sema and clp->cl_sem held. | 646 | { |
678 | */ | 647 | struct rpc_sequence *sequence = counter->sequence; |
679 | void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *lsp) | 648 | struct nfs_seqid *new; |
649 | |||
650 | new = kmalloc(sizeof(*new), GFP_KERNEL); | ||
651 | if (new != NULL) { | ||
652 | new->sequence = counter; | ||
653 | spin_lock(&sequence->lock); | ||
654 | list_add_tail(&new->list, &sequence->list); | ||
655 | spin_unlock(&sequence->lock); | ||
656 | } | ||
657 | return new; | ||
658 | } | ||
659 | |||
660 | void nfs_free_seqid(struct nfs_seqid *seqid) | ||
680 | { | 661 | { |
681 | if (status == NFS_OK || seqid_mutating_err(-status)) | 662 | struct rpc_sequence *sequence = seqid->sequence->sequence; |
682 | lsp->ls_seqid++; | 663 | |
664 | spin_lock(&sequence->lock); | ||
665 | list_del(&seqid->list); | ||
666 | spin_unlock(&sequence->lock); | ||
667 | rpc_wake_up(&sequence->wait); | ||
668 | kfree(seqid); | ||
683 | } | 669 | } |
684 | 670 | ||
685 | /* | 671 | /* |
686 | * Called with sp->so_sema and clp->cl_sem held. | 672 | * Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or |
687 | * | 673 | * failed with a seqid incrementing error - |
688 | * Increment the seqid if the OPEN/OPEN_DOWNGRADE/CLOSE succeeded, or | 674 | * see comments nfs_fs.h:seqid_mutating_error() |
689 | * failed with a seqid incrementing error - | 675 | */ |
690 | * see comments nfs_fs.h:seqid_mutating_error() | 676 | static inline void nfs_increment_seqid(int status, struct nfs_seqid *seqid) |
691 | */ | 677 | { |
692 | void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp) | 678 | switch (status) { |
693 | { | 679 | case 0: |
694 | if (status == NFS_OK || seqid_mutating_err(-status)) | 680 | break; |
695 | sp->so_seqid++; | 681 | case -NFS4ERR_BAD_SEQID: |
696 | /* If the server returns BAD_SEQID, unhash state_owner here */ | 682 | case -NFS4ERR_STALE_CLIENTID: |
697 | if (status == -NFS4ERR_BAD_SEQID) | 683 | case -NFS4ERR_STALE_STATEID: |
684 | case -NFS4ERR_BAD_STATEID: | ||
685 | case -NFS4ERR_BADXDR: | ||
686 | case -NFS4ERR_RESOURCE: | ||
687 | case -NFS4ERR_NOFILEHANDLE: | ||
688 | /* Non-seqid mutating errors */ | ||
689 | return; | ||
690 | }; | ||
691 | /* | ||
692 | * Note: no locking needed as we are guaranteed to be first | ||
693 | * on the sequence list | ||
694 | */ | ||
695 | seqid->sequence->counter++; | ||
696 | } | ||
697 | |||
698 | void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid) | ||
699 | { | ||
700 | if (status == -NFS4ERR_BAD_SEQID) { | ||
701 | struct nfs4_state_owner *sp = container_of(seqid->sequence, | ||
702 | struct nfs4_state_owner, so_seqid); | ||
698 | nfs4_drop_state_owner(sp); | 703 | nfs4_drop_state_owner(sp); |
704 | } | ||
705 | return nfs_increment_seqid(status, seqid); | ||
706 | } | ||
707 | |||
708 | /* | ||
709 | * Increment the seqid if the LOCK/LOCKU succeeded, or | ||
710 | * failed with a seqid incrementing error - | ||
711 | * see comments nfs_fs.h:seqid_mutating_error() | ||
712 | */ | ||
713 | void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid) | ||
714 | { | ||
715 | return nfs_increment_seqid(status, seqid); | ||
716 | } | ||
717 | |||
718 | int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task) | ||
719 | { | ||
720 | struct rpc_sequence *sequence = seqid->sequence->sequence; | ||
721 | int status = 0; | ||
722 | |||
723 | if (sequence->list.next == &seqid->list) | ||
724 | goto out; | ||
725 | spin_lock(&sequence->lock); | ||
726 | if (sequence->list.next != &seqid->list) { | ||
727 | rpc_sleep_on(&sequence->wait, task, NULL, NULL); | ||
728 | status = -EAGAIN; | ||
729 | } | ||
730 | spin_unlock(&sequence->lock); | ||
731 | out: | ||
732 | return status; | ||
699 | } | 733 | } |
700 | 734 | ||
701 | static int reclaimer(void *); | 735 | static int reclaimer(void *); |
@@ -747,7 +781,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s | |||
747 | int status = 0; | 781 | int status = 0; |
748 | 782 | ||
749 | for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { | 783 | for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { |
750 | if (!(fl->fl_flags & FL_POSIX)) | 784 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) |
751 | continue; | 785 | continue; |
752 | if (((struct nfs_open_context *)fl->fl_file->private_data)->state != state) | 786 | if (((struct nfs_open_context *)fl->fl_file->private_data)->state != state) |
753 | continue; | 787 | continue; |
@@ -762,7 +796,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s | |||
762 | case -NFS4ERR_NO_GRACE: | 796 | case -NFS4ERR_NO_GRACE: |
763 | case -NFS4ERR_RECLAIM_BAD: | 797 | case -NFS4ERR_RECLAIM_BAD: |
764 | case -NFS4ERR_RECLAIM_CONFLICT: | 798 | case -NFS4ERR_RECLAIM_CONFLICT: |
765 | /* kill_proc(fl->fl_owner, SIGLOST, 1); */ | 799 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ |
766 | break; | 800 | break; |
767 | case -NFS4ERR_STALE_CLIENTID: | 801 | case -NFS4ERR_STALE_CLIENTID: |
768 | goto out_err; | 802 | goto out_err; |
@@ -791,8 +825,6 @@ static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct n | |||
791 | if (state->state == 0) | 825 | if (state->state == 0) |
792 | continue; | 826 | continue; |
793 | status = ops->recover_open(sp, state); | 827 | status = ops->recover_open(sp, state); |
794 | list_for_each_entry(lock, &state->lock_states, ls_locks) | ||
795 | lock->ls_flags &= ~NFS_LOCK_INITIALIZED; | ||
796 | if (status >= 0) { | 828 | if (status >= 0) { |
797 | status = nfs4_reclaim_locks(ops, state); | 829 | status = nfs4_reclaim_locks(ops, state); |
798 | if (status < 0) | 830 | if (status < 0) |
@@ -831,6 +863,28 @@ out_err: | |||
831 | return status; | 863 | return status; |
832 | } | 864 | } |
833 | 865 | ||
866 | static void nfs4_state_mark_reclaim(struct nfs4_client *clp) | ||
867 | { | ||
868 | struct nfs4_state_owner *sp; | ||
869 | struct nfs4_state *state; | ||
870 | struct nfs4_lock_state *lock; | ||
871 | |||
872 | /* Reset all sequence ids to zero */ | ||
873 | list_for_each_entry(sp, &clp->cl_state_owners, so_list) { | ||
874 | sp->so_seqid.counter = 0; | ||
875 | sp->so_seqid.flags = 0; | ||
876 | spin_lock(&sp->so_lock); | ||
877 | list_for_each_entry(state, &sp->so_states, open_states) { | ||
878 | list_for_each_entry(lock, &state->lock_states, ls_locks) { | ||
879 | lock->ls_seqid.counter = 0; | ||
880 | lock->ls_seqid.flags = 0; | ||
881 | lock->ls_flags &= ~NFS_LOCK_INITIALIZED; | ||
882 | } | ||
883 | } | ||
884 | spin_unlock(&sp->so_lock); | ||
885 | } | ||
886 | } | ||
887 | |||
834 | static int reclaimer(void *ptr) | 888 | static int reclaimer(void *ptr) |
835 | { | 889 | { |
836 | struct reclaimer_args *args = (struct reclaimer_args *)ptr; | 890 | struct reclaimer_args *args = (struct reclaimer_args *)ptr; |
@@ -864,6 +918,7 @@ restart_loop: | |||
864 | default: | 918 | default: |
865 | ops = &nfs4_network_partition_recovery_ops; | 919 | ops = &nfs4_network_partition_recovery_ops; |
866 | }; | 920 | }; |
921 | nfs4_state_mark_reclaim(clp); | ||
867 | status = __nfs4_init_client(clp); | 922 | status = __nfs4_init_client(clp); |
868 | if (status) | 923 | if (status) |
869 | goto out_error; | 924 | goto out_error; |