diff options
-rw-r--r-- | fs/nfsd/nfs4layouts.c | 13 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 34 | ||||
-rw-r--r-- | fs/nfsd/state.h | 23 |
3 files changed, 31 insertions, 39 deletions
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index 4a68ab901b4b..9ffef06b30d5 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c | |||
@@ -409,8 +409,7 @@ nfsd4_insert_layout(struct nfsd4_layoutget *lgp, struct nfs4_layout_stateid *ls) | |||
409 | list_add_tail(&new->lo_perstate, &ls->ls_layouts); | 409 | list_add_tail(&new->lo_perstate, &ls->ls_layouts); |
410 | new = NULL; | 410 | new = NULL; |
411 | done: | 411 | done: |
412 | update_stateid(&ls->ls_stid.sc_stateid); | 412 | nfs4_inc_and_copy_stateid(&lgp->lg_sid, &ls->ls_stid); |
413 | memcpy(&lgp->lg_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t)); | ||
414 | spin_unlock(&ls->ls_lock); | 413 | spin_unlock(&ls->ls_lock); |
415 | out: | 414 | out: |
416 | spin_unlock(&fp->fi_lock); | 415 | spin_unlock(&fp->fi_lock); |
@@ -484,11 +483,8 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp, | |||
484 | } | 483 | } |
485 | } | 484 | } |
486 | if (!list_empty(&ls->ls_layouts)) { | 485 | if (!list_empty(&ls->ls_layouts)) { |
487 | if (found) { | 486 | if (found) |
488 | update_stateid(&ls->ls_stid.sc_stateid); | 487 | nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid); |
489 | memcpy(&lrp->lr_sid, &ls->ls_stid.sc_stateid, | ||
490 | sizeof(stateid_t)); | ||
491 | } | ||
492 | lrp->lrs_present = 1; | 488 | lrp->lrs_present = 1; |
493 | } else { | 489 | } else { |
494 | trace_layoutstate_unhash(&ls->ls_stid.sc_stateid); | 490 | trace_layoutstate_unhash(&ls->ls_stid.sc_stateid); |
@@ -619,8 +615,7 @@ nfsd4_cb_layout_prepare(struct nfsd4_callback *cb) | |||
619 | container_of(cb, struct nfs4_layout_stateid, ls_recall); | 615 | container_of(cb, struct nfs4_layout_stateid, ls_recall); |
620 | 616 | ||
621 | mutex_lock(&ls->ls_mutex); | 617 | mutex_lock(&ls->ls_mutex); |
622 | update_stateid(&ls->ls_stid.sc_stateid); | 618 | nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid); |
623 | memcpy(&ls->ls_recall_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t)); | ||
624 | } | 619 | } |
625 | 620 | ||
626 | static int | 621 | static int |
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: |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 1fa0f3848d4e..77fdf4de91ba 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -84,7 +84,7 @@ struct nfsd4_callback_ops { | |||
84 | * fields that are of general use to any stateid. | 84 | * fields that are of general use to any stateid. |
85 | */ | 85 | */ |
86 | struct nfs4_stid { | 86 | struct nfs4_stid { |
87 | atomic_t sc_count; | 87 | atomic_t sc_count; |
88 | #define NFS4_OPEN_STID 1 | 88 | #define NFS4_OPEN_STID 1 |
89 | #define NFS4_LOCK_STID 2 | 89 | #define NFS4_LOCK_STID 2 |
90 | #define NFS4_DELEG_STID 4 | 90 | #define NFS4_DELEG_STID 4 |
@@ -94,11 +94,12 @@ struct nfs4_stid { | |||
94 | #define NFS4_REVOKED_DELEG_STID 16 | 94 | #define NFS4_REVOKED_DELEG_STID 16 |
95 | #define NFS4_CLOSED_DELEG_STID 32 | 95 | #define NFS4_CLOSED_DELEG_STID 32 |
96 | #define NFS4_LAYOUT_STID 64 | 96 | #define NFS4_LAYOUT_STID 64 |
97 | unsigned char sc_type; | 97 | unsigned char sc_type; |
98 | stateid_t sc_stateid; | 98 | stateid_t sc_stateid; |
99 | struct nfs4_client *sc_client; | 99 | spinlock_t sc_lock; |
100 | struct nfs4_file *sc_file; | 100 | struct nfs4_client *sc_client; |
101 | void (*sc_free)(struct nfs4_stid *); | 101 | struct nfs4_file *sc_file; |
102 | void (*sc_free)(struct nfs4_stid *); | ||
102 | }; | 103 | }; |
103 | 104 | ||
104 | /* | 105 | /* |
@@ -364,15 +365,6 @@ struct nfs4_client_reclaim { | |||
364 | char cr_recdir[HEXDIR_LEN]; /* recover dir */ | 365 | char cr_recdir[HEXDIR_LEN]; /* recover dir */ |
365 | }; | 366 | }; |
366 | 367 | ||
367 | static inline void | ||
368 | update_stateid(stateid_t *stateid) | ||
369 | { | ||
370 | stateid->si_generation++; | ||
371 | /* Wraparound recommendation from 3530bis-13 9.1.3.2: */ | ||
372 | if (stateid->si_generation == 0) | ||
373 | stateid->si_generation = 1; | ||
374 | } | ||
375 | |||
376 | /* A reasonable value for REPLAY_ISIZE was estimated as follows: | 368 | /* A reasonable value for REPLAY_ISIZE was estimated as follows: |
377 | * The OPEN response, typically the largest, requires | 369 | * The OPEN response, typically the largest, requires |
378 | * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) + | 370 | * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) + |
@@ -595,6 +587,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, | |||
595 | struct kmem_cache *slab); | 587 | struct kmem_cache *slab); |
596 | void nfs4_unhash_stid(struct nfs4_stid *s); | 588 | void nfs4_unhash_stid(struct nfs4_stid *s); |
597 | void nfs4_put_stid(struct nfs4_stid *s); | 589 | void nfs4_put_stid(struct nfs4_stid *s); |
590 | void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid); | ||
598 | void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *); | 591 | void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *); |
599 | extern void nfs4_release_reclaim(struct nfsd_net *); | 592 | extern void nfs4_release_reclaim(struct nfsd_net *); |
600 | extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir, | 593 | extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir, |