aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index f2ea343086b8..0a697158a4ca 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -575,6 +575,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
575 stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid; 575 stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid;
576 /* Will be incremented before return to client: */ 576 /* Will be incremented before return to client: */
577 atomic_set(&stid->sc_count, 1); 577 atomic_set(&stid->sc_count, 1);
578 spin_lock_init(&stid->sc_lock);
578 579
579 /* 580 /*
580 * It shouldn't be a problem to reuse an opaque stateid value. 581 * It shouldn't be a problem to reuse an opaque stateid value.
@@ -745,6 +746,18 @@ nfs4_put_stid(struct nfs4_stid *s)
745 put_nfs4_file(fp); 746 put_nfs4_file(fp);
746} 747}
747 748
749void
750nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid)
751{
752 stateid_t *src = &stid->sc_stateid;
753
754 spin_lock(&stid->sc_lock);
755 if (unlikely(++src->si_generation == 0))
756 src->si_generation = 1;
757 memcpy(dst, src, sizeof(*dst));
758 spin_unlock(&stid->sc_lock);
759}
760
748static void nfs4_put_deleg_lease(struct nfs4_file *fp) 761static void nfs4_put_deleg_lease(struct nfs4_file *fp)
749{ 762{
750 struct file *filp = NULL; 763 struct file *filp = NULL;
@@ -4221,8 +4234,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
4221 if (stp->st_clnt_odstate == open->op_odstate) 4234 if (stp->st_clnt_odstate == open->op_odstate)
4222 open->op_odstate = NULL; 4235 open->op_odstate = NULL;
4223 } 4236 }
4224 update_stateid(&stp->st_stid.sc_stateid); 4237 nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid);
4225 memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4226 up_read(&stp->st_rwsem); 4238 up_read(&stp->st_rwsem);
4227 4239
4228 if (nfsd4_has_session(&resp->cstate)) { 4240 if (nfsd4_has_session(&resp->cstate)) {
@@ -4925,8 +4937,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4925 goto put_stateid; 4937 goto put_stateid;
4926 } 4938 }
4927 oo->oo_flags |= NFS4_OO_CONFIRMED; 4939 oo->oo_flags |= NFS4_OO_CONFIRMED;
4928 update_stateid(&stp->st_stid.sc_stateid); 4940 nfs4_inc_and_copy_stateid(&oc->oc_resp_stateid, &stp->st_stid);
4929 memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4930 up_write(&stp->st_rwsem); 4941 up_write(&stp->st_rwsem);
4931 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", 4942 dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
4932 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid)); 4943 __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
@@ -4999,11 +5010,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
4999 goto put_stateid; 5010 goto put_stateid;
5000 } 5011 }
5001 nfs4_stateid_downgrade(stp, od->od_share_access); 5012 nfs4_stateid_downgrade(stp, od->od_share_access);
5002
5003 reset_union_bmap_deny(od->od_share_deny, stp); 5013 reset_union_bmap_deny(od->od_share_deny, stp);
5004 5014 nfs4_inc_and_copy_stateid(&od->od_stateid, &stp->st_stid);
5005 update_stateid(&stp->st_stid.sc_stateid);
5006 memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
5007 status = nfs_ok; 5015 status = nfs_ok;
5008put_stateid: 5016put_stateid:
5009 up_write(&stp->st_rwsem); 5017 up_write(&stp->st_rwsem);
@@ -5058,8 +5066,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5058 nfsd4_bump_seqid(cstate, status); 5066 nfsd4_bump_seqid(cstate, status);
5059 if (status) 5067 if (status)
5060 goto out; 5068 goto out;
5061 update_stateid(&stp->st_stid.sc_stateid); 5069 nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
5062 memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
5063 up_write(&stp->st_rwsem); 5070 up_write(&stp->st_rwsem);
5064 5071
5065 nfsd4_close_open_stateid(stp); 5072 nfsd4_close_open_stateid(stp);
@@ -5542,9 +5549,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5542 err = vfs_lock_file(filp, F_SETLK, file_lock, conflock); 5549 err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
5543 switch (-err) { 5550 switch (-err) {
5544 case 0: /* success! */ 5551 case 0: /* success! */
5545 update_stateid(&lock_stp->st_stid.sc_stateid); 5552 nfs4_inc_and_copy_stateid(&lock->lk_resp_stateid, &lock_stp->st_stid);
5546 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid,
5547 sizeof(stateid_t));
5548 status = 0; 5553 status = 0;
5549 break; 5554 break;
5550 case (EAGAIN): /* conflock holds conflicting lock */ 5555 case (EAGAIN): /* conflock holds conflicting lock */
@@ -5736,8 +5741,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
5736 dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n"); 5741 dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
5737 goto out_nfserr; 5742 goto out_nfserr;
5738 } 5743 }
5739 update_stateid(&stp->st_stid.sc_stateid); 5744 nfs4_inc_and_copy_stateid(&locku->lu_stateid, &stp->st_stid);
5740 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
5741fput: 5745fput:
5742 fput(filp); 5746 fput(filp);
5743put_stateid: 5747put_stateid: