diff options
author | Sachin Bhamare <sachin.bhamare@primarydata.com> | 2015-04-27 08:50:14 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2015-05-04 12:02:39 -0400 |
commit | 8287f009bd95a5e548059dba62a67727bb9549cd (patch) | |
tree | 12d451819b0e805fd86172cdb120cb77014c5e75 /fs | |
parent | ebe9cb3bb13e7b9b281969cd279ce70834f7500f (diff) |
nfsd: fix pNFS return on close semantics
For the sake of forgetful clients, the server should return the layouts
to the file system on 'last close' of a file (assuming that there are no
delegations outstanding to that particular client) or on delegreturn
(assuming that there are no opens on a file from that particular
client).
In theory the information is all there in current data structures, but
it's not efficiently available; nfs4_file->fi_ref includes references on
the file across all clients, but we need a per-(client, file) count.
Walking through lots of stateid's to calculate this on each close or
delegreturn would be painful.
This patch introduces infrastructure to maintain per-client opens and
delegation counters on a per-file basis.
[hch: ported to the mainline pNFS support, merged various fixes from Jeff]
Signed-off-by: Sachin Bhamare <sachin.bhamare@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4state.c | 125 | ||||
-rw-r--r-- | fs/nfsd/state.h | 14 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 1 |
3 files changed, 133 insertions, 7 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index fb8c66725035..66067a291267 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -94,6 +94,7 @@ static struct kmem_cache *lockowner_slab; | |||
94 | static struct kmem_cache *file_slab; | 94 | static struct kmem_cache *file_slab; |
95 | static struct kmem_cache *stateid_slab; | 95 | static struct kmem_cache *stateid_slab; |
96 | static struct kmem_cache *deleg_slab; | 96 | static struct kmem_cache *deleg_slab; |
97 | static struct kmem_cache *odstate_slab; | ||
97 | 98 | ||
98 | static void free_session(struct nfsd4_session *); | 99 | static void free_session(struct nfsd4_session *); |
99 | 100 | ||
@@ -281,6 +282,7 @@ put_nfs4_file(struct nfs4_file *fi) | |||
281 | if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) { | 282 | if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) { |
282 | hlist_del_rcu(&fi->fi_hash); | 283 | hlist_del_rcu(&fi->fi_hash); |
283 | spin_unlock(&state_lock); | 284 | spin_unlock(&state_lock); |
285 | WARN_ON_ONCE(!list_empty(&fi->fi_clnt_odstate)); | ||
284 | WARN_ON_ONCE(!list_empty(&fi->fi_delegations)); | 286 | WARN_ON_ONCE(!list_empty(&fi->fi_delegations)); |
285 | call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu); | 287 | call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu); |
286 | } | 288 | } |
@@ -471,6 +473,86 @@ static void nfs4_file_put_access(struct nfs4_file *fp, u32 access) | |||
471 | __nfs4_file_put_access(fp, O_RDONLY); | 473 | __nfs4_file_put_access(fp, O_RDONLY); |
472 | } | 474 | } |
473 | 475 | ||
476 | /* | ||
477 | * Allocate a new open/delegation state counter. This is needed for | ||
478 | * pNFS for proper return on close semantics. | ||
479 | * | ||
480 | * Note that we only allocate it for pNFS-enabled exports, otherwise | ||
481 | * all pointers to struct nfs4_clnt_odstate are always NULL. | ||
482 | */ | ||
483 | static struct nfs4_clnt_odstate * | ||
484 | alloc_clnt_odstate(struct nfs4_client *clp) | ||
485 | { | ||
486 | struct nfs4_clnt_odstate *co; | ||
487 | |||
488 | co = kmem_cache_zalloc(odstate_slab, GFP_KERNEL); | ||
489 | if (co) { | ||
490 | co->co_client = clp; | ||
491 | atomic_set(&co->co_odcount, 1); | ||
492 | } | ||
493 | return co; | ||
494 | } | ||
495 | |||
496 | static void | ||
497 | hash_clnt_odstate_locked(struct nfs4_clnt_odstate *co) | ||
498 | { | ||
499 | struct nfs4_file *fp = co->co_file; | ||
500 | |||
501 | lockdep_assert_held(&fp->fi_lock); | ||
502 | list_add(&co->co_perfile, &fp->fi_clnt_odstate); | ||
503 | } | ||
504 | |||
505 | static inline void | ||
506 | get_clnt_odstate(struct nfs4_clnt_odstate *co) | ||
507 | { | ||
508 | if (co) | ||
509 | atomic_inc(&co->co_odcount); | ||
510 | } | ||
511 | |||
512 | static void | ||
513 | put_clnt_odstate(struct nfs4_clnt_odstate *co) | ||
514 | { | ||
515 | struct nfs4_file *fp; | ||
516 | |||
517 | if (!co) | ||
518 | return; | ||
519 | |||
520 | fp = co->co_file; | ||
521 | if (atomic_dec_and_lock(&co->co_odcount, &fp->fi_lock)) { | ||
522 | list_del(&co->co_perfile); | ||
523 | spin_unlock(&fp->fi_lock); | ||
524 | |||
525 | nfsd4_return_all_file_layouts(co->co_client, fp); | ||
526 | kmem_cache_free(odstate_slab, co); | ||
527 | } | ||
528 | } | ||
529 | |||
530 | static struct nfs4_clnt_odstate * | ||
531 | find_or_hash_clnt_odstate(struct nfs4_file *fp, struct nfs4_clnt_odstate *new) | ||
532 | { | ||
533 | struct nfs4_clnt_odstate *co; | ||
534 | struct nfs4_client *cl; | ||
535 | |||
536 | if (!new) | ||
537 | return NULL; | ||
538 | |||
539 | cl = new->co_client; | ||
540 | |||
541 | spin_lock(&fp->fi_lock); | ||
542 | list_for_each_entry(co, &fp->fi_clnt_odstate, co_perfile) { | ||
543 | if (co->co_client == cl) { | ||
544 | get_clnt_odstate(co); | ||
545 | goto out; | ||
546 | } | ||
547 | } | ||
548 | co = new; | ||
549 | co->co_file = fp; | ||
550 | hash_clnt_odstate_locked(new); | ||
551 | out: | ||
552 | spin_unlock(&fp->fi_lock); | ||
553 | return co; | ||
554 | } | ||
555 | |||
474 | struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, | 556 | struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, |
475 | struct kmem_cache *slab) | 557 | struct kmem_cache *slab) |
476 | { | 558 | { |
@@ -606,7 +688,8 @@ static void block_delegations(struct knfsd_fh *fh) | |||
606 | } | 688 | } |
607 | 689 | ||
608 | static struct nfs4_delegation * | 690 | static struct nfs4_delegation * |
609 | alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh) | 691 | alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh, |
692 | struct nfs4_clnt_odstate *odstate) | ||
610 | { | 693 | { |
611 | struct nfs4_delegation *dp; | 694 | struct nfs4_delegation *dp; |
612 | long n; | 695 | long n; |
@@ -631,6 +714,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh) | |||
631 | INIT_LIST_HEAD(&dp->dl_perfile); | 714 | INIT_LIST_HEAD(&dp->dl_perfile); |
632 | INIT_LIST_HEAD(&dp->dl_perclnt); | 715 | INIT_LIST_HEAD(&dp->dl_perclnt); |
633 | INIT_LIST_HEAD(&dp->dl_recall_lru); | 716 | INIT_LIST_HEAD(&dp->dl_recall_lru); |
717 | dp->dl_clnt_odstate = odstate; | ||
718 | get_clnt_odstate(odstate); | ||
634 | dp->dl_type = NFS4_OPEN_DELEGATE_READ; | 719 | dp->dl_type = NFS4_OPEN_DELEGATE_READ; |
635 | dp->dl_retries = 1; | 720 | dp->dl_retries = 1; |
636 | nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client, | 721 | nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client, |
@@ -714,6 +799,7 @@ static void destroy_delegation(struct nfs4_delegation *dp) | |||
714 | spin_lock(&state_lock); | 799 | spin_lock(&state_lock); |
715 | unhash_delegation_locked(dp); | 800 | unhash_delegation_locked(dp); |
716 | spin_unlock(&state_lock); | 801 | spin_unlock(&state_lock); |
802 | put_clnt_odstate(dp->dl_clnt_odstate); | ||
717 | nfs4_put_deleg_lease(dp->dl_stid.sc_file); | 803 | nfs4_put_deleg_lease(dp->dl_stid.sc_file); |
718 | nfs4_put_stid(&dp->dl_stid); | 804 | nfs4_put_stid(&dp->dl_stid); |
719 | } | 805 | } |
@@ -724,6 +810,7 @@ static void revoke_delegation(struct nfs4_delegation *dp) | |||
724 | 810 | ||
725 | WARN_ON(!list_empty(&dp->dl_recall_lru)); | 811 | WARN_ON(!list_empty(&dp->dl_recall_lru)); |
726 | 812 | ||
813 | put_clnt_odstate(dp->dl_clnt_odstate); | ||
727 | nfs4_put_deleg_lease(dp->dl_stid.sc_file); | 814 | nfs4_put_deleg_lease(dp->dl_stid.sc_file); |
728 | 815 | ||
729 | if (clp->cl_minorversion == 0) | 816 | if (clp->cl_minorversion == 0) |
@@ -933,6 +1020,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid) | |||
933 | { | 1020 | { |
934 | struct nfs4_ol_stateid *stp = openlockstateid(stid); | 1021 | struct nfs4_ol_stateid *stp = openlockstateid(stid); |
935 | 1022 | ||
1023 | put_clnt_odstate(stp->st_clnt_odstate); | ||
936 | release_all_access(stp); | 1024 | release_all_access(stp); |
937 | if (stp->st_stateowner) | 1025 | if (stp->st_stateowner) |
938 | nfs4_put_stateowner(stp->st_stateowner); | 1026 | nfs4_put_stateowner(stp->st_stateowner); |
@@ -1634,6 +1722,7 @@ __destroy_client(struct nfs4_client *clp) | |||
1634 | while (!list_empty(&reaplist)) { | 1722 | while (!list_empty(&reaplist)) { |
1635 | dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); | 1723 | dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); |
1636 | list_del_init(&dp->dl_recall_lru); | 1724 | list_del_init(&dp->dl_recall_lru); |
1725 | put_clnt_odstate(dp->dl_clnt_odstate); | ||
1637 | nfs4_put_deleg_lease(dp->dl_stid.sc_file); | 1726 | nfs4_put_deleg_lease(dp->dl_stid.sc_file); |
1638 | nfs4_put_stid(&dp->dl_stid); | 1727 | nfs4_put_stid(&dp->dl_stid); |
1639 | } | 1728 | } |
@@ -3057,6 +3146,7 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval, | |||
3057 | spin_lock_init(&fp->fi_lock); | 3146 | spin_lock_init(&fp->fi_lock); |
3058 | INIT_LIST_HEAD(&fp->fi_stateids); | 3147 | INIT_LIST_HEAD(&fp->fi_stateids); |
3059 | INIT_LIST_HEAD(&fp->fi_delegations); | 3148 | INIT_LIST_HEAD(&fp->fi_delegations); |
3149 | INIT_LIST_HEAD(&fp->fi_clnt_odstate); | ||
3060 | fh_copy_shallow(&fp->fi_fhandle, fh); | 3150 | fh_copy_shallow(&fp->fi_fhandle, fh); |
3061 | fp->fi_deleg_file = NULL; | 3151 | fp->fi_deleg_file = NULL; |
3062 | fp->fi_had_conflict = false; | 3152 | fp->fi_had_conflict = false; |
@@ -3073,6 +3163,7 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval, | |||
3073 | void | 3163 | void |
3074 | nfsd4_free_slabs(void) | 3164 | nfsd4_free_slabs(void) |
3075 | { | 3165 | { |
3166 | kmem_cache_destroy(odstate_slab); | ||
3076 | kmem_cache_destroy(openowner_slab); | 3167 | kmem_cache_destroy(openowner_slab); |
3077 | kmem_cache_destroy(lockowner_slab); | 3168 | kmem_cache_destroy(lockowner_slab); |
3078 | kmem_cache_destroy(file_slab); | 3169 | kmem_cache_destroy(file_slab); |
@@ -3103,8 +3194,14 @@ nfsd4_init_slabs(void) | |||
3103 | sizeof(struct nfs4_delegation), 0, 0, NULL); | 3194 | sizeof(struct nfs4_delegation), 0, 0, NULL); |
3104 | if (deleg_slab == NULL) | 3195 | if (deleg_slab == NULL) |
3105 | goto out_free_stateid_slab; | 3196 | goto out_free_stateid_slab; |
3197 | odstate_slab = kmem_cache_create("nfsd4_odstate", | ||
3198 | sizeof(struct nfs4_clnt_odstate), 0, 0, NULL); | ||
3199 | if (odstate_slab == NULL) | ||
3200 | goto out_free_deleg_slab; | ||
3106 | return 0; | 3201 | return 0; |
3107 | 3202 | ||
3203 | out_free_deleg_slab: | ||
3204 | kmem_cache_destroy(deleg_slab); | ||
3108 | out_free_stateid_slab: | 3205 | out_free_stateid_slab: |
3109 | kmem_cache_destroy(stateid_slab); | 3206 | kmem_cache_destroy(stateid_slab); |
3110 | out_free_file_slab: | 3207 | out_free_file_slab: |
@@ -3581,6 +3678,14 @@ alloc_stateid: | |||
3581 | open->op_stp = nfs4_alloc_open_stateid(clp); | 3678 | open->op_stp = nfs4_alloc_open_stateid(clp); |
3582 | if (!open->op_stp) | 3679 | if (!open->op_stp) |
3583 | return nfserr_jukebox; | 3680 | return nfserr_jukebox; |
3681 | |||
3682 | if (nfsd4_has_session(cstate) && | ||
3683 | (cstate->current_fh.fh_export->ex_flags & NFSEXP_PNFS)) { | ||
3684 | open->op_odstate = alloc_clnt_odstate(clp); | ||
3685 | if (!open->op_odstate) | ||
3686 | return nfserr_jukebox; | ||
3687 | } | ||
3688 | |||
3584 | return nfs_ok; | 3689 | return nfs_ok; |
3585 | } | 3690 | } |
3586 | 3691 | ||
@@ -3869,7 +3974,7 @@ out_fput: | |||
3869 | 3974 | ||
3870 | static struct nfs4_delegation * | 3975 | static struct nfs4_delegation * |
3871 | nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, | 3976 | nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, |
3872 | struct nfs4_file *fp) | 3977 | struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate) |
3873 | { | 3978 | { |
3874 | int status; | 3979 | int status; |
3875 | struct nfs4_delegation *dp; | 3980 | struct nfs4_delegation *dp; |
@@ -3877,7 +3982,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, | |||
3877 | if (fp->fi_had_conflict) | 3982 | if (fp->fi_had_conflict) |
3878 | return ERR_PTR(-EAGAIN); | 3983 | return ERR_PTR(-EAGAIN); |
3879 | 3984 | ||
3880 | dp = alloc_init_deleg(clp, fh); | 3985 | dp = alloc_init_deleg(clp, fh, odstate); |
3881 | if (!dp) | 3986 | if (!dp) |
3882 | return ERR_PTR(-ENOMEM); | 3987 | return ERR_PTR(-ENOMEM); |
3883 | 3988 | ||
@@ -3903,6 +4008,7 @@ out_unlock: | |||
3903 | spin_unlock(&state_lock); | 4008 | spin_unlock(&state_lock); |
3904 | out: | 4009 | out: |
3905 | if (status) { | 4010 | if (status) { |
4011 | put_clnt_odstate(dp->dl_clnt_odstate); | ||
3906 | nfs4_put_stid(&dp->dl_stid); | 4012 | nfs4_put_stid(&dp->dl_stid); |
3907 | return ERR_PTR(status); | 4013 | return ERR_PTR(status); |
3908 | } | 4014 | } |
@@ -3980,7 +4086,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, | |||
3980 | default: | 4086 | default: |
3981 | goto out_no_deleg; | 4087 | goto out_no_deleg; |
3982 | } | 4088 | } |
3983 | dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file); | 4089 | dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file, stp->st_clnt_odstate); |
3984 | if (IS_ERR(dp)) | 4090 | if (IS_ERR(dp)) |
3985 | goto out_no_deleg; | 4091 | goto out_no_deleg; |
3986 | 4092 | ||
@@ -4069,6 +4175,11 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
4069 | release_open_stateid(stp); | 4175 | release_open_stateid(stp); |
4070 | goto out; | 4176 | goto out; |
4071 | } | 4177 | } |
4178 | |||
4179 | stp->st_clnt_odstate = find_or_hash_clnt_odstate(fp, | ||
4180 | open->op_odstate); | ||
4181 | if (stp->st_clnt_odstate == open->op_odstate) | ||
4182 | open->op_odstate = NULL; | ||
4072 | } | 4183 | } |
4073 | update_stateid(&stp->st_stid.sc_stateid); | 4184 | update_stateid(&stp->st_stid.sc_stateid); |
4074 | memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); | 4185 | memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); |
@@ -4129,6 +4240,8 @@ void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate, | |||
4129 | kmem_cache_free(file_slab, open->op_file); | 4240 | kmem_cache_free(file_slab, open->op_file); |
4130 | if (open->op_stp) | 4241 | if (open->op_stp) |
4131 | nfs4_put_stid(&open->op_stp->st_stid); | 4242 | nfs4_put_stid(&open->op_stp->st_stid); |
4243 | if (open->op_odstate) | ||
4244 | kmem_cache_free(odstate_slab, open->op_odstate); | ||
4132 | } | 4245 | } |
4133 | 4246 | ||
4134 | __be32 | 4247 | __be32 |
@@ -4853,9 +4966,6 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
4853 | update_stateid(&stp->st_stid.sc_stateid); | 4966 | update_stateid(&stp->st_stid.sc_stateid); |
4854 | memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); | 4967 | memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); |
4855 | 4968 | ||
4856 | nfsd4_return_all_file_layouts(stp->st_stateowner->so_client, | ||
4857 | stp->st_stid.sc_file); | ||
4858 | |||
4859 | nfsd4_close_open_stateid(stp); | 4969 | nfsd4_close_open_stateid(stp); |
4860 | 4970 | ||
4861 | /* put reference from nfs4_preprocess_seqid_op */ | 4971 | /* put reference from nfs4_preprocess_seqid_op */ |
@@ -6489,6 +6599,7 @@ nfs4_state_shutdown_net(struct net *net) | |||
6489 | list_for_each_safe(pos, next, &reaplist) { | 6599 | list_for_each_safe(pos, next, &reaplist) { |
6490 | dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); | 6600 | dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); |
6491 | list_del_init(&dp->dl_recall_lru); | 6601 | list_del_init(&dp->dl_recall_lru); |
6602 | put_clnt_odstate(dp->dl_clnt_odstate); | ||
6492 | nfs4_put_deleg_lease(dp->dl_stid.sc_file); | 6603 | nfs4_put_deleg_lease(dp->dl_stid.sc_file); |
6493 | nfs4_put_stid(&dp->dl_stid); | 6604 | nfs4_put_stid(&dp->dl_stid); |
6494 | } | 6605 | } |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 4f3bfeb11766..bde45d90b746 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -126,6 +126,7 @@ struct nfs4_delegation { | |||
126 | struct list_head dl_perfile; | 126 | struct list_head dl_perfile; |
127 | struct list_head dl_perclnt; | 127 | struct list_head dl_perclnt; |
128 | struct list_head dl_recall_lru; /* delegation recalled */ | 128 | struct list_head dl_recall_lru; /* delegation recalled */ |
129 | struct nfs4_clnt_odstate *dl_clnt_odstate; | ||
129 | u32 dl_type; | 130 | u32 dl_type; |
130 | time_t dl_time; | 131 | time_t dl_time; |
131 | /* For recall: */ | 132 | /* For recall: */ |
@@ -465,6 +466,17 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so) | |||
465 | } | 466 | } |
466 | 467 | ||
467 | /* | 468 | /* |
469 | * Per-client state indicating no. of opens and outstanding delegations | ||
470 | * on a file from a particular client.'od' stands for 'open & delegation' | ||
471 | */ | ||
472 | struct nfs4_clnt_odstate { | ||
473 | struct nfs4_client *co_client; | ||
474 | struct nfs4_file *co_file; | ||
475 | struct list_head co_perfile; | ||
476 | atomic_t co_odcount; | ||
477 | }; | ||
478 | |||
479 | /* | ||
468 | * nfs4_file: a file opened by some number of (open) nfs4_stateowners. | 480 | * nfs4_file: a file opened by some number of (open) nfs4_stateowners. |
469 | * | 481 | * |
470 | * These objects are global. nfsd keeps one instance of a nfs4_file per | 482 | * These objects are global. nfsd keeps one instance of a nfs4_file per |
@@ -485,6 +497,7 @@ struct nfs4_file { | |||
485 | struct list_head fi_delegations; | 497 | struct list_head fi_delegations; |
486 | struct rcu_head fi_rcu; | 498 | struct rcu_head fi_rcu; |
487 | }; | 499 | }; |
500 | struct list_head fi_clnt_odstate; | ||
488 | /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ | 501 | /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ |
489 | struct file * fi_fds[3]; | 502 | struct file * fi_fds[3]; |
490 | /* | 503 | /* |
@@ -526,6 +539,7 @@ struct nfs4_ol_stateid { | |||
526 | struct list_head st_perstateowner; | 539 | struct list_head st_perstateowner; |
527 | struct list_head st_locks; | 540 | struct list_head st_locks; |
528 | struct nfs4_stateowner * st_stateowner; | 541 | struct nfs4_stateowner * st_stateowner; |
542 | struct nfs4_clnt_odstate * st_clnt_odstate; | ||
529 | unsigned char st_access_bmap; | 543 | unsigned char st_access_bmap; |
530 | unsigned char st_deny_bmap; | 544 | unsigned char st_deny_bmap; |
531 | struct nfs4_ol_stateid * st_openstp; | 545 | struct nfs4_ol_stateid * st_openstp; |
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index f982ae84f0cd..2f8c092be2b3 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h | |||
@@ -247,6 +247,7 @@ struct nfsd4_open { | |||
247 | struct nfs4_openowner *op_openowner; /* used during processing */ | 247 | struct nfs4_openowner *op_openowner; /* used during processing */ |
248 | struct nfs4_file *op_file; /* used during processing */ | 248 | struct nfs4_file *op_file; /* used during processing */ |
249 | struct nfs4_ol_stateid *op_stp; /* used during processing */ | 249 | struct nfs4_ol_stateid *op_stp; /* used during processing */ |
250 | struct nfs4_clnt_odstate *op_odstate; /* used during processing */ | ||
250 | struct nfs4_acl *op_acl; | 251 | struct nfs4_acl *op_acl; |
251 | struct xdr_netobj op_label; | 252 | struct xdr_netobj op_label; |
252 | }; | 253 | }; |