aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4layouts.c13
-rw-r--r--fs/nfsd/nfs4state.c34
-rw-r--r--fs/nfsd/state.h23
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;
411done: 411done:
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);
415out: 414out:
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
626static int 621static 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
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:
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 */
86struct nfs4_stid { 86struct 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
367static inline void
368update_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);
596void nfs4_unhash_stid(struct nfs4_stid *s); 588void nfs4_unhash_stid(struct nfs4_stid *s);
597void nfs4_put_stid(struct nfs4_stid *s); 589void nfs4_put_stid(struct nfs4_stid *s);
590void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid);
598void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *); 591void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *);
599extern void nfs4_release_reclaim(struct nfsd_net *); 592extern void nfs4_release_reclaim(struct nfsd_net *);
600extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir, 593extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,