aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/callback_xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/callback_xdr.c')
-rw-r--r--fs/nfs/callback_xdr.c52
1 files changed, 42 insertions, 10 deletions
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index a35582c9d444..f4ccfe6521ec 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -166,9 +166,9 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound
166 if (unlikely(p == NULL)) 166 if (unlikely(p == NULL))
167 return htonl(NFS4ERR_RESOURCE); 167 return htonl(NFS4ERR_RESOURCE);
168 hdr->minorversion = ntohl(*p++); 168 hdr->minorversion = ntohl(*p++);
169 /* Check minor version is zero or one. */ 169 /* Check for minor version support */
170 if (hdr->minorversion <= 1) { 170 if (hdr->minorversion <= NFS4_MAX_MINOR_VERSION) {
171 hdr->cb_ident = ntohl(*p++); /* ignored by v4.1 */ 171 hdr->cb_ident = ntohl(*p++); /* ignored by v4.1 and v4.2 */
172 } else { 172 } else {
173 pr_warn_ratelimited("NFS: %s: NFSv4 server callback with " 173 pr_warn_ratelimited("NFS: %s: NFSv4 server callback with "
174 "illegal minor version %u!\n", 174 "illegal minor version %u!\n",
@@ -786,6 +786,26 @@ static void nfs4_cb_free_slot(struct cb_process_state *cps)
786} 786}
787#endif /* CONFIG_NFS_V4_1 */ 787#endif /* CONFIG_NFS_V4_1 */
788 788
789#ifdef CONFIG_NFS_V4_2
790static __be32
791preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op)
792{
793 __be32 status = preprocess_nfs41_op(nop, op_nr, op);
794 if (status != htonl(NFS4ERR_OP_ILLEGAL))
795 return status;
796
797 if (op_nr == OP_CB_OFFLOAD)
798 return htonl(NFS4ERR_NOTSUPP);
799 return htonl(NFS4ERR_OP_ILLEGAL);
800}
801#else /* CONFIG_NFS_V4_2 */
802static __be32
803preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op)
804{
805 return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
806}
807#endif /* CONFIG_NFS_V4_2 */
808
789static __be32 809static __be32
790preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op) 810preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op)
791{ 811{
@@ -801,8 +821,7 @@ preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op)
801 return htonl(NFS_OK); 821 return htonl(NFS_OK);
802} 822}
803 823
804static __be32 process_op(uint32_t minorversion, int nop, 824static __be32 process_op(int nop, struct svc_rqst *rqstp,
805 struct svc_rqst *rqstp,
806 struct xdr_stream *xdr_in, void *argp, 825 struct xdr_stream *xdr_in, void *argp,
807 struct xdr_stream *xdr_out, void *resp, 826 struct xdr_stream *xdr_out, void *resp,
808 struct cb_process_state *cps) 827 struct cb_process_state *cps)
@@ -819,10 +838,22 @@ static __be32 process_op(uint32_t minorversion, int nop,
819 return status; 838 return status;
820 839
821 dprintk("%s: minorversion=%d nop=%d op_nr=%u\n", 840 dprintk("%s: minorversion=%d nop=%d op_nr=%u\n",
822 __func__, minorversion, nop, op_nr); 841 __func__, cps->minorversion, nop, op_nr);
842
843 switch (cps->minorversion) {
844 case 0:
845 status = preprocess_nfs4_op(op_nr, &op);
846 break;
847 case 1:
848 status = preprocess_nfs41_op(nop, op_nr, &op);
849 break;
850 case 2:
851 status = preprocess_nfs42_op(nop, op_nr, &op);
852 break;
853 default:
854 status = htonl(NFS4ERR_MINOR_VERS_MISMATCH);
855 }
823 856
824 status = minorversion ? preprocess_nfs41_op(nop, op_nr, &op) :
825 preprocess_nfs4_op(op_nr, &op);
826 if (status == htonl(NFS4ERR_OP_ILLEGAL)) 857 if (status == htonl(NFS4ERR_OP_ILLEGAL))
827 op_nr = OP_CB_ILLEGAL; 858 op_nr = OP_CB_ILLEGAL;
828 if (status) 859 if (status)
@@ -885,14 +916,15 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
885 return rpc_drop_reply; 916 return rpc_drop_reply;
886 } 917 }
887 918
919 cps.minorversion = hdr_arg.minorversion;
888 hdr_res.taglen = hdr_arg.taglen; 920 hdr_res.taglen = hdr_arg.taglen;
889 hdr_res.tag = hdr_arg.tag; 921 hdr_res.tag = hdr_arg.tag;
890 if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0) 922 if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
891 return rpc_system_err; 923 return rpc_system_err;
892 924
893 while (status == 0 && nops != hdr_arg.nops) { 925 while (status == 0 && nops != hdr_arg.nops) {
894 status = process_op(hdr_arg.minorversion, nops, rqstp, 926 status = process_op(nops, rqstp, &xdr_in,
895 &xdr_in, argp, &xdr_out, resp, &cps); 927 argp, &xdr_out, resp, &cps);
896 nops++; 928 nops++;
897 } 929 }
898 930