list_add_tail(&new->lo_perstate, &ls->ls_layouts);
        new = NULL;
 done:
-       update_stateid(&ls->ls_stid.sc_stateid);
-       memcpy(&lgp->lg_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&lgp->lg_sid, &ls->ls_stid);
        spin_unlock(&ls->ls_lock);
 out:
        spin_unlock(&fp->fi_lock);
                }
        }
        if (!list_empty(&ls->ls_layouts)) {
-               if (found) {
-                       update_stateid(&ls->ls_stid.sc_stateid);
-                       memcpy(&lrp->lr_sid, &ls->ls_stid.sc_stateid,
-                               sizeof(stateid_t));
-               }
+               if (found)
+                       nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid);
                lrp->lrs_present = 1;
        } else {
                trace_layoutstate_unhash(&ls->ls_stid.sc_stateid);
                container_of(cb, struct nfs4_layout_stateid, ls_recall);
 
        mutex_lock(&ls->ls_mutex);
-       update_stateid(&ls->ls_stid.sc_stateid);
-       memcpy(&ls->ls_recall_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&ls->ls_recall_sid, &ls->ls_stid);
 }
 
 static int
 
        stid->sc_stateid.si_opaque.so_clid = cl->cl_clientid;
        /* Will be incremented before return to client: */
        atomic_set(&stid->sc_count, 1);
+       spin_lock_init(&stid->sc_lock);
 
        /*
         * It shouldn't be a problem to reuse an opaque stateid value.
                put_nfs4_file(fp);
 }
 
+void
+nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid)
+{
+       stateid_t *src = &stid->sc_stateid;
+
+       spin_lock(&stid->sc_lock);
+       if (unlikely(++src->si_generation == 0))
+               src->si_generation = 1;
+       memcpy(dst, src, sizeof(*dst));
+       spin_unlock(&stid->sc_lock);
+}
+
 static void nfs4_put_deleg_lease(struct nfs4_file *fp)
 {
        struct file *filp = NULL;
                if (stp->st_clnt_odstate == open->op_odstate)
                        open->op_odstate = NULL;
        }
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid);
        up_read(&stp->st_rwsem);
 
        if (nfsd4_has_session(&resp->cstate)) {
                goto put_stateid;
        }
        oo->oo_flags |= NFS4_OO_CONFIRMED;
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&oc->oc_resp_stateid, &stp->st_stid);
        up_write(&stp->st_rwsem);
        dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
                __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
                goto put_stateid;
        }
        nfs4_stateid_downgrade(stp, od->od_share_access);
-
        reset_union_bmap_deny(od->od_share_deny, stp);
-
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&od->od_stateid, &stp->st_stid);
        status = nfs_ok;
 put_stateid:
        up_write(&stp->st_rwsem);
        nfsd4_bump_seqid(cstate, status);
        if (status)
                goto out; 
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
        up_write(&stp->st_rwsem);
 
        nfsd4_close_open_stateid(stp);
        err = vfs_lock_file(filp, F_SETLK, file_lock, conflock);
        switch (-err) {
        case 0: /* success! */
-               update_stateid(&lock_stp->st_stid.sc_stateid);
-               memcpy(&lock->lk_resp_stateid, &lock_stp->st_stid.sc_stateid, 
-                               sizeof(stateid_t));
+               nfs4_inc_and_copy_stateid(&lock->lk_resp_stateid, &lock_stp->st_stid);
                status = 0;
                break;
        case (EAGAIN):          /* conflock holds conflicting lock */
                dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
                goto out_nfserr;
        }
-       update_stateid(&stp->st_stid.sc_stateid);
-       memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       nfs4_inc_and_copy_stateid(&locku->lu_stateid, &stp->st_stid);
 fput:
        fput(filp);
 put_stateid:
 
  * fields that are of general use to any stateid.
  */
 struct nfs4_stid {
-       atomic_t sc_count;
+       atomic_t                sc_count;
 #define NFS4_OPEN_STID 1
 #define NFS4_LOCK_STID 2
 #define NFS4_DELEG_STID 4
 #define NFS4_REVOKED_DELEG_STID 16
 #define NFS4_CLOSED_DELEG_STID 32
 #define NFS4_LAYOUT_STID 64
-       unsigned char sc_type;
-       stateid_t sc_stateid;
-       struct nfs4_client *sc_client;
-       struct nfs4_file *sc_file;
-       void (*sc_free)(struct nfs4_stid *);
+       unsigned char           sc_type;
+       stateid_t               sc_stateid;
+       spinlock_t              sc_lock;
+       struct nfs4_client      *sc_client;
+       struct nfs4_file        *sc_file;
+       void                    (*sc_free)(struct nfs4_stid *);
 };
 
 /*
        char                    cr_recdir[HEXDIR_LEN]; /* recover dir */
 };
 
-static inline void
-update_stateid(stateid_t *stateid)
-{
-       stateid->si_generation++;
-       /* Wraparound recommendation from 3530bis-13 9.1.3.2: */
-       if (stateid->si_generation == 0)
-               stateid->si_generation = 1;
-}
-
 /* A reasonable value for REPLAY_ISIZE was estimated as follows:  
  * The OPEN response, typically the largest, requires 
  *   4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) +  8(verifier) + 
                struct kmem_cache *slab);
 void nfs4_unhash_stid(struct nfs4_stid *s);
 void nfs4_put_stid(struct nfs4_stid *s);
+void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid);
 void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *);
 extern void nfs4_release_reclaim(struct nfsd_net *);
 extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,