diff options
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 34 |
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 | ||
749 | void | ||
750 | nfs4_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 | |||
748 | static void nfs4_put_deleg_lease(struct nfs4_file *fp) | 761 | static 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; |
5008 | put_stateid: | 5016 | put_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)); | ||
5741 | fput: | 5745 | fput: |
5742 | fput(filp); | 5746 | fput(filp); |
5743 | put_stateid: | 5747 | put_stateid: |