diff options
-rw-r--r-- | fs/nfsd/nfs4proc.c | 40 | ||||
-rw-r--r-- | include/linux/nfsd/xdr4.h | 9 |
2 files changed, 14 insertions, 35 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index f156b85b4129..7bb8cb321dfe 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -809,29 +809,6 @@ static inline void nfsd4_increment_op_stats(u32 opnum) | |||
809 | nfsdstats.nfs4_opcount[opnum]++; | 809 | nfsdstats.nfs4_opcount[opnum]++; |
810 | } | 810 | } |
811 | 811 | ||
812 | static void cstate_free(struct nfsd4_compound_state *cstate) | ||
813 | { | ||
814 | if (cstate == NULL) | ||
815 | return; | ||
816 | fh_put(&cstate->current_fh); | ||
817 | fh_put(&cstate->save_fh); | ||
818 | BUG_ON(cstate->replay_owner); | ||
819 | kfree(cstate); | ||
820 | } | ||
821 | |||
822 | static struct nfsd4_compound_state *cstate_alloc(void) | ||
823 | { | ||
824 | struct nfsd4_compound_state *cstate; | ||
825 | |||
826 | cstate = kmalloc(sizeof(struct nfsd4_compound_state), GFP_KERNEL); | ||
827 | if (cstate == NULL) | ||
828 | return NULL; | ||
829 | fh_init(&cstate->current_fh, NFS4_FHSIZE); | ||
830 | fh_init(&cstate->save_fh, NFS4_FHSIZE); | ||
831 | cstate->replay_owner = NULL; | ||
832 | return cstate; | ||
833 | } | ||
834 | |||
835 | typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, | 812 | typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, |
836 | void *); | 813 | void *); |
837 | 814 | ||
@@ -859,12 +836,13 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
859 | { | 836 | { |
860 | struct nfsd4_op *op; | 837 | struct nfsd4_op *op; |
861 | struct nfsd4_operation *opdesc; | 838 | struct nfsd4_operation *opdesc; |
862 | struct nfsd4_compound_state *cstate = NULL; | 839 | struct nfsd4_compound_state *cstate = &resp->cstate; |
863 | int slack_bytes; | 840 | int slack_bytes; |
864 | __be32 status; | 841 | __be32 status; |
865 | 842 | ||
866 | resp->xbuf = &rqstp->rq_res; | 843 | resp->xbuf = &rqstp->rq_res; |
867 | resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; | 844 | resp->p = rqstp->rq_res.head[0].iov_base + |
845 | rqstp->rq_res.head[0].iov_len; | ||
868 | resp->tagp = resp->p; | 846 | resp->tagp = resp->p; |
869 | /* reserve space for: taglen, tag, and opcnt */ | 847 | /* reserve space for: taglen, tag, and opcnt */ |
870 | resp->p += 2 + XDR_QUADLEN(args->taglen); | 848 | resp->p += 2 + XDR_QUADLEN(args->taglen); |
@@ -873,6 +851,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
873 | resp->tag = args->tag; | 851 | resp->tag = args->tag; |
874 | resp->opcnt = 0; | 852 | resp->opcnt = 0; |
875 | resp->rqstp = rqstp; | 853 | resp->rqstp = rqstp; |
854 | resp->cstate.replay_owner = NULL; | ||
855 | fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); | ||
856 | fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); | ||
876 | 857 | ||
877 | /* | 858 | /* |
878 | * According to RFC3010, this takes precedence over all other errors. | 859 | * According to RFC3010, this takes precedence over all other errors. |
@@ -881,11 +862,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
881 | if (args->minorversion > NFSD_SUPPORTED_MINOR_VERSION) | 862 | if (args->minorversion > NFSD_SUPPORTED_MINOR_VERSION) |
882 | goto out; | 863 | goto out; |
883 | 864 | ||
884 | status = nfserr_resource; | ||
885 | cstate = cstate_alloc(); | ||
886 | if (cstate == NULL) | ||
887 | goto out; | ||
888 | |||
889 | status = nfs_ok; | 865 | status = nfs_ok; |
890 | while (!status && resp->opcnt < args->opcnt) { | 866 | while (!status && resp->opcnt < args->opcnt) { |
891 | op = &args->ops[resp->opcnt++]; | 867 | op = &args->ops[resp->opcnt++]; |
@@ -958,7 +934,9 @@ encode_op: | |||
958 | nfsd4_increment_op_stats(op->opnum); | 934 | nfsd4_increment_op_stats(op->opnum); |
959 | } | 935 | } |
960 | 936 | ||
961 | cstate_free(cstate); | 937 | fh_put(&resp->cstate.current_fh); |
938 | fh_put(&resp->cstate.save_fh); | ||
939 | BUG_ON(resp->cstate.replay_owner); | ||
962 | out: | 940 | out: |
963 | nfsd4_release_compoundargs(args); | 941 | nfsd4_release_compoundargs(args); |
964 | dprintk("nfsv4 compound returned %d\n", ntohl(status)); | 942 | dprintk("nfsv4 compound returned %d\n", ntohl(status)); |
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h index 27bd3e38ec5a..fd15ddc3359d 100644 --- a/include/linux/nfsd/xdr4.h +++ b/include/linux/nfsd/xdr4.h | |||
@@ -45,9 +45,9 @@ | |||
45 | #define XDR_LEN(n) (((n) + 3) & ~3) | 45 | #define XDR_LEN(n) (((n) + 3) & ~3) |
46 | 46 | ||
47 | struct nfsd4_compound_state { | 47 | struct nfsd4_compound_state { |
48 | struct svc_fh current_fh; | 48 | struct svc_fh current_fh; |
49 | struct svc_fh save_fh; | 49 | struct svc_fh save_fh; |
50 | struct nfs4_stateowner *replay_owner; | 50 | struct nfs4_stateowner *replay_owner; |
51 | }; | 51 | }; |
52 | 52 | ||
53 | struct nfsd4_change_info { | 53 | struct nfsd4_change_info { |
@@ -416,7 +416,8 @@ struct nfsd4_compoundres { | |||
416 | u32 taglen; | 416 | u32 taglen; |
417 | char * tag; | 417 | char * tag; |
418 | u32 opcnt; | 418 | u32 opcnt; |
419 | __be32 * tagp; /* where to encode tag and opcount */ | 419 | __be32 * tagp; /* tag, opcount encode location */ |
420 | struct nfsd4_compound_state cstate; | ||
420 | }; | 421 | }; |
421 | 422 | ||
422 | #define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) | 423 | #define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) |