aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2005-09-13 04:25:38 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-13 11:22:32 -0400
commitb59e3c0e172e3f3a147021aa16b929482b8d5846 (patch)
tree60aec6ff8a214adfa828af8a89460aca55731d46 /fs/nfsd
parentf2327d9adb1e948a7041128e971effd8d6e2d42c (diff)
[PATCH] nfsd4: fix open seqid incrementing in lock
In the case of a lock which introduces a new lockowner, the openowner's sequence id should be incremented, even when the operation fails, if the error is a sequence-id-mutating error. The current code fails to do that in some cases. Fix this by using the same sequence-id-incrementing mechanism that all other such operations use. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 11405e530e70..ec2fdb009bf1 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2629,7 +2629,9 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
2629 sop->so_is_open_owner = 0; 2629 sop->so_is_open_owner = 0;
2630 sop->so_id = current_ownerid++; 2630 sop->so_id = current_ownerid++;
2631 sop->so_client = clp; 2631 sop->so_client = clp;
2632 sop->so_seqid = lock->lk_new_lock_seqid; 2632 /* It is the openowner seqid that will be incremented in encode in the
2633 * case of new lockowners; so increment the lock seqid manually: */
2634 sop->so_seqid = lock->lk_new_lock_seqid + 1;
2633 sop->so_confirmed = 1; 2635 sop->so_confirmed = 1;
2634 rp = &sop->so_replay; 2636 rp = &sop->so_replay;
2635 rp->rp_status = NFSERR_SERVERFAULT; 2637 rp->rp_status = NFSERR_SERVERFAULT;
@@ -2684,6 +2686,7 @@ int
2684nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner) 2686nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner)
2685{ 2687{
2686 struct nfs4_stateowner *open_sop = NULL; 2688 struct nfs4_stateowner *open_sop = NULL;
2689 struct nfs4_stateowner *lock_sop = NULL;
2687 struct nfs4_stateid *lock_stp; 2690 struct nfs4_stateid *lock_stp;
2688 struct file *filp; 2691 struct file *filp;
2689 struct file_lock file_lock; 2692 struct file_lock file_lock;
@@ -2718,9 +2721,11 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2718 lock->lk_new_open_seqid, 2721 lock->lk_new_open_seqid,
2719 &lock->lk_new_open_stateid, 2722 &lock->lk_new_open_stateid,
2720 CHECK_FH | OPEN_STATE, 2723 CHECK_FH | OPEN_STATE,
2721 &open_sop, &open_stp, lock); 2724 &lock->lk_stateowner, &open_stp,
2725 lock);
2722 if (status) 2726 if (status)
2723 goto out; 2727 goto out;
2728 open_sop = lock->lk_stateowner;
2724 /* create lockowner and lock stateid */ 2729 /* create lockowner and lock stateid */
2725 fp = open_stp->st_file; 2730 fp = open_stp->st_file;
2726 strhashval = lock_ownerstr_hashval(fp->fi_inode, 2731 strhashval = lock_ownerstr_hashval(fp->fi_inode,
@@ -2730,16 +2735,15 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2730 * the same file, or should they just be allowed (and 2735 * the same file, or should they just be allowed (and
2731 * create new stateids)? */ 2736 * create new stateids)? */
2732 status = nfserr_resource; 2737 status = nfserr_resource;
2733 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock))) 2738 lock_sop = alloc_init_lock_stateowner(strhashval,
2739 open_sop->so_client, open_stp, lock);
2740 if (lock_sop == NULL)
2734 goto out; 2741 goto out;
2735 if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner, 2742 lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
2736 fp, open_stp)) == NULL) { 2743 if (lock_stp == NULL) {
2737 release_stateowner(lock->lk_stateowner); 2744 release_stateowner(lock_sop);
2738 lock->lk_stateowner = NULL;
2739 goto out; 2745 goto out;
2740 } 2746 }
2741 /* bump the open seqid used to create the lock */
2742 open_sop->so_seqid++;
2743 } else { 2747 } else {
2744 /* lock (lock owner + lock stateid) already exists */ 2748 /* lock (lock owner + lock stateid) already exists */
2745 status = nfs4_preprocess_seqid_op(current_fh, 2749 status = nfs4_preprocess_seqid_op(current_fh,
@@ -2749,6 +2753,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2749 &lock->lk_stateowner, &lock_stp, lock); 2753 &lock->lk_stateowner, &lock_stp, lock);
2750 if (status) 2754 if (status)
2751 goto out; 2755 goto out;
2756 lock_sop = lock->lk_stateowner;
2752 } 2757 }
2753 /* lock->lk_stateowner and lock_stp have been created or found */ 2758 /* lock->lk_stateowner and lock_stp have been created or found */
2754 filp = lock_stp->st_vfs_file; 2759 filp = lock_stp->st_vfs_file;
@@ -2779,7 +2784,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2779 status = nfserr_inval; 2784 status = nfserr_inval;
2780 goto out; 2785 goto out;
2781 } 2786 }
2782 file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner; 2787 file_lock.fl_owner = (fl_owner_t)lock_sop;
2783 file_lock.fl_pid = current->tgid; 2788 file_lock.fl_pid = current->tgid;
2784 file_lock.fl_file = filp; 2789 file_lock.fl_file = filp;
2785 file_lock.fl_flags = FL_POSIX; 2790 file_lock.fl_flags = FL_POSIX;
@@ -2835,9 +2840,6 @@ out_destroy_new_stateid:
2835 * An error encountered after instantiation of the new 2840 * An error encountered after instantiation of the new
2836 * stateid has forced us to destroy it. 2841 * stateid has forced us to destroy it.
2837 */ 2842 */
2838 if (!seqid_mutating_err(status))
2839 open_sop->so_seqid--;
2840
2841 release_state_owner(lock_stp, LOCK_STATE); 2843 release_state_owner(lock_stp, LOCK_STATE);
2842 } 2844 }
2843out: 2845out: