Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
0004  */
0005 #ifndef __LINUX_FS_NFS_NFS4_2XDR_H
0006 #define __LINUX_FS_NFS_NFS4_2XDR_H
0007 
0008 #include "nfs42.h"
0009 
0010 #define encode_fallocate_maxsz      (encode_stateid_maxsz + \
0011                      2 /* offset */ + \
0012                      2 /* length */)
0013 #define NFS42_WRITE_RES_SIZE        (1 /* wr_callback_id size */ +\
0014                      XDR_QUADLEN(NFS4_STATEID_SIZE) + \
0015                      2 /* wr_count */ + \
0016                      1 /* wr_committed */ + \
0017                      XDR_QUADLEN(NFS4_VERIFIER_SIZE))
0018 #define encode_allocate_maxsz       (op_encode_hdr_maxsz + \
0019                      encode_fallocate_maxsz)
0020 #define decode_allocate_maxsz       (op_decode_hdr_maxsz)
0021 #define encode_copy_maxsz       (op_encode_hdr_maxsz +          \
0022                      XDR_QUADLEN(NFS4_STATEID_SIZE) + \
0023                      XDR_QUADLEN(NFS4_STATEID_SIZE) + \
0024                      2 + 2 + 2 + 1 + 1 + 1 +\
0025                      1 + /* One cnr_source_server */\
0026                      1 + /* nl4_type */ \
0027                      1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
0028 #define decode_copy_maxsz       (op_decode_hdr_maxsz + \
0029                      NFS42_WRITE_RES_SIZE + \
0030                      1 /* cr_consecutive */ + \
0031                      1 /* cr_synchronous */)
0032 #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \
0033                      XDR_QUADLEN(NFS4_STATEID_SIZE))
0034 #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz)
0035 #define encode_copy_notify_maxsz    (op_encode_hdr_maxsz + \
0036                      XDR_QUADLEN(NFS4_STATEID_SIZE) + \
0037                      1 + /* nl4_type */ \
0038                      1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
0039 #define decode_copy_notify_maxsz    (op_decode_hdr_maxsz + \
0040                      3 + /* cnr_lease_time */\
0041                      XDR_QUADLEN(NFS4_STATEID_SIZE) + \
0042                      1 + /* Support 1 cnr_source_server */\
0043                      1 + /* nl4_type */ \
0044                      1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
0045 #define encode_deallocate_maxsz     (op_encode_hdr_maxsz + \
0046                      encode_fallocate_maxsz)
0047 #define decode_deallocate_maxsz     (op_decode_hdr_maxsz)
0048 #define encode_read_plus_maxsz      (op_encode_hdr_maxsz + \
0049                      encode_stateid_maxsz + 3)
0050 #define NFS42_READ_PLUS_SEGMENT_SIZE    (1 /* data_content4 */ + \
0051                      2 /* data_info4.di_offset */ + \
0052                      2 /* data_info4.di_length */)
0053 #define decode_read_plus_maxsz      (op_decode_hdr_maxsz + \
0054                      1 /* rpr_eof */ + \
0055                      1 /* rpr_contents count */ + \
0056                      2 * NFS42_READ_PLUS_SEGMENT_SIZE)
0057 #define encode_seek_maxsz       (op_encode_hdr_maxsz + \
0058                      encode_stateid_maxsz + \
0059                      2 /* offset */ + \
0060                      1 /* whence */)
0061 #define decode_seek_maxsz       (op_decode_hdr_maxsz + \
0062                      1 /* eof */ + \
0063                      1 /* whence */ + \
0064                      2 /* offset */ + \
0065                      2 /* length */)
0066 #define encode_io_info_maxsz        4
0067 #define encode_layoutstats_maxsz    (op_decode_hdr_maxsz + \
0068                     2 /* offset */ + \
0069                     2 /* length */ + \
0070                     encode_stateid_maxsz + \
0071                     encode_io_info_maxsz + \
0072                     encode_io_info_maxsz + \
0073                     1 /* opaque devaddr4 length */ + \
0074                     XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
0075 #define decode_layoutstats_maxsz    (op_decode_hdr_maxsz)
0076 #define encode_device_error_maxsz   (XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
0077                     1 /* status */ + 1 /* opnum */)
0078 #define encode_layouterror_maxsz    (op_decode_hdr_maxsz + \
0079                     2 /* offset */ + \
0080                     2 /* length */ + \
0081                     encode_stateid_maxsz + \
0082                     1 /* Array size */ + \
0083                     encode_device_error_maxsz)
0084 #define decode_layouterror_maxsz    (op_decode_hdr_maxsz)
0085 #define encode_clone_maxsz      (encode_stateid_maxsz + \
0086                     encode_stateid_maxsz + \
0087                     2 /* src offset */ + \
0088                     2 /* dst offset */ + \
0089                     2 /* count */)
0090 #define decode_clone_maxsz      (op_decode_hdr_maxsz)
0091 
0092 #define NFS4_enc_allocate_sz        (compound_encode_hdr_maxsz + \
0093                      encode_sequence_maxsz + \
0094                      encode_putfh_maxsz + \
0095                      encode_allocate_maxsz + \
0096                      encode_getattr_maxsz)
0097 #define NFS4_dec_allocate_sz        (compound_decode_hdr_maxsz + \
0098                      decode_sequence_maxsz + \
0099                      decode_putfh_maxsz + \
0100                      decode_allocate_maxsz + \
0101                      decode_getattr_maxsz)
0102 #define NFS4_enc_copy_sz        (compound_encode_hdr_maxsz + \
0103                      encode_sequence_maxsz + \
0104                      encode_putfh_maxsz + \
0105                      encode_savefh_maxsz + \
0106                      encode_putfh_maxsz + \
0107                      encode_copy_maxsz + \
0108                      encode_commit_maxsz)
0109 #define NFS4_dec_copy_sz        (compound_decode_hdr_maxsz + \
0110                      decode_sequence_maxsz + \
0111                      decode_putfh_maxsz + \
0112                      decode_savefh_maxsz + \
0113                      decode_putfh_maxsz + \
0114                      decode_copy_maxsz + \
0115                      decode_commit_maxsz)
0116 #define NFS4_enc_offload_cancel_sz  (compound_encode_hdr_maxsz + \
0117                      encode_sequence_maxsz + \
0118                      encode_putfh_maxsz + \
0119                      encode_offload_cancel_maxsz)
0120 #define NFS4_dec_offload_cancel_sz  (compound_decode_hdr_maxsz + \
0121                      decode_sequence_maxsz + \
0122                      decode_putfh_maxsz + \
0123                      decode_offload_cancel_maxsz)
0124 #define NFS4_enc_copy_notify_sz     (compound_encode_hdr_maxsz + \
0125                      encode_putfh_maxsz + \
0126                      encode_copy_notify_maxsz)
0127 #define NFS4_dec_copy_notify_sz     (compound_decode_hdr_maxsz + \
0128                      decode_putfh_maxsz + \
0129                      decode_copy_notify_maxsz)
0130 #define NFS4_enc_deallocate_sz      (compound_encode_hdr_maxsz + \
0131                      encode_sequence_maxsz + \
0132                      encode_putfh_maxsz + \
0133                      encode_deallocate_maxsz + \
0134                      encode_getattr_maxsz)
0135 #define NFS4_dec_deallocate_sz      (compound_decode_hdr_maxsz + \
0136                      decode_sequence_maxsz + \
0137                      decode_putfh_maxsz + \
0138                      decode_deallocate_maxsz + \
0139                      decode_getattr_maxsz)
0140 #define NFS4_enc_read_plus_sz       (compound_encode_hdr_maxsz + \
0141                      encode_sequence_maxsz + \
0142                      encode_putfh_maxsz + \
0143                      encode_read_plus_maxsz)
0144 #define NFS4_dec_read_plus_sz       (compound_decode_hdr_maxsz + \
0145                      decode_sequence_maxsz + \
0146                      decode_putfh_maxsz + \
0147                      decode_read_plus_maxsz)
0148 #define NFS4_enc_seek_sz        (compound_encode_hdr_maxsz + \
0149                      encode_sequence_maxsz + \
0150                      encode_putfh_maxsz + \
0151                      encode_seek_maxsz)
0152 #define NFS4_dec_seek_sz        (compound_decode_hdr_maxsz + \
0153                      decode_sequence_maxsz + \
0154                      decode_putfh_maxsz + \
0155                      decode_seek_maxsz)
0156 #define NFS4_enc_layoutstats_sz     (compound_encode_hdr_maxsz + \
0157                      encode_sequence_maxsz + \
0158                      encode_putfh_maxsz + \
0159                      PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
0160 #define NFS4_dec_layoutstats_sz     (compound_decode_hdr_maxsz + \
0161                      decode_sequence_maxsz + \
0162                      decode_putfh_maxsz + \
0163                      PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
0164 #define NFS4_enc_layouterror_sz     (compound_encode_hdr_maxsz + \
0165                      encode_sequence_maxsz + \
0166                      encode_putfh_maxsz + \
0167                      NFS42_LAYOUTERROR_MAX * \
0168                      encode_layouterror_maxsz)
0169 #define NFS4_dec_layouterror_sz     (compound_decode_hdr_maxsz + \
0170                      decode_sequence_maxsz + \
0171                      decode_putfh_maxsz + \
0172                      NFS42_LAYOUTERROR_MAX * \
0173                      decode_layouterror_maxsz)
0174 #define NFS4_enc_clone_sz       (compound_encode_hdr_maxsz + \
0175                      encode_sequence_maxsz + \
0176                      encode_putfh_maxsz + \
0177                      encode_savefh_maxsz + \
0178                      encode_putfh_maxsz + \
0179                      encode_clone_maxsz + \
0180                      encode_getattr_maxsz)
0181 #define NFS4_dec_clone_sz       (compound_decode_hdr_maxsz + \
0182                      decode_sequence_maxsz + \
0183                      decode_putfh_maxsz + \
0184                      decode_savefh_maxsz + \
0185                      decode_putfh_maxsz + \
0186                      decode_clone_maxsz + \
0187                      decode_getattr_maxsz)
0188 
0189 /* Not limited by NFS itself, limited by the generic xattr code */
0190 #define nfs4_xattr_name_maxsz   XDR_QUADLEN(XATTR_NAME_MAX)
0191 
0192 #define encode_getxattr_maxsz   (op_encode_hdr_maxsz + 1 + \
0193                  nfs4_xattr_name_maxsz)
0194 #define decode_getxattr_maxsz   (op_decode_hdr_maxsz + 1 + pagepad_maxsz)
0195 #define encode_setxattr_maxsz   (op_encode_hdr_maxsz + \
0196                  1 + nfs4_xattr_name_maxsz + 1)
0197 #define decode_setxattr_maxsz   (op_decode_hdr_maxsz + decode_change_info_maxsz)
0198 #define encode_listxattrs_maxsz  (op_encode_hdr_maxsz + 2 + 1)
0199 #define decode_listxattrs_maxsz  (op_decode_hdr_maxsz + 2 + 1 + 1 + 1)
0200 #define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \
0201                   nfs4_xattr_name_maxsz)
0202 #define decode_removexattr_maxsz (op_decode_hdr_maxsz + \
0203                   decode_change_info_maxsz)
0204 
0205 #define NFS4_enc_getxattr_sz    (compound_encode_hdr_maxsz + \
0206                 encode_sequence_maxsz + \
0207                 encode_putfh_maxsz + \
0208                 encode_getxattr_maxsz)
0209 #define NFS4_dec_getxattr_sz    (compound_decode_hdr_maxsz + \
0210                 decode_sequence_maxsz + \
0211                 decode_putfh_maxsz + \
0212                 decode_getxattr_maxsz)
0213 #define NFS4_enc_setxattr_sz    (compound_encode_hdr_maxsz + \
0214                 encode_sequence_maxsz + \
0215                 encode_putfh_maxsz + \
0216                 encode_setxattr_maxsz)
0217 #define NFS4_dec_setxattr_sz    (compound_decode_hdr_maxsz + \
0218                 decode_sequence_maxsz + \
0219                 decode_putfh_maxsz + \
0220                 decode_setxattr_maxsz)
0221 #define NFS4_enc_listxattrs_sz  (compound_encode_hdr_maxsz + \
0222                 encode_sequence_maxsz + \
0223                 encode_putfh_maxsz + \
0224                 encode_listxattrs_maxsz)
0225 #define NFS4_dec_listxattrs_sz  (compound_decode_hdr_maxsz + \
0226                 decode_sequence_maxsz + \
0227                 decode_putfh_maxsz + \
0228                 decode_listxattrs_maxsz)
0229 #define NFS4_enc_removexattr_sz (compound_encode_hdr_maxsz + \
0230                 encode_sequence_maxsz + \
0231                 encode_putfh_maxsz + \
0232                 encode_removexattr_maxsz)
0233 #define NFS4_dec_removexattr_sz (compound_decode_hdr_maxsz + \
0234                 decode_sequence_maxsz + \
0235                 decode_putfh_maxsz + \
0236                 decode_removexattr_maxsz)
0237 
0238 /*
0239  * These values specify the maximum amount of data that is not
0240  * associated with the extended attribute name or extended
0241  * attribute list in the SETXATTR, GETXATTR and LISTXATTR
0242  * respectively.
0243  */
0244 const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
0245                     compound_encode_hdr_maxsz +
0246                     encode_sequence_maxsz +
0247                     encode_putfh_maxsz + 1 +
0248                     nfs4_xattr_name_maxsz)
0249                     * XDR_UNIT);
0250 
0251 const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
0252                     compound_decode_hdr_maxsz +
0253                     decode_sequence_maxsz +
0254                     decode_putfh_maxsz + 1) * XDR_UNIT);
0255 
0256 const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
0257                     compound_decode_hdr_maxsz +
0258                     decode_sequence_maxsz +
0259                     decode_putfh_maxsz + 3) * XDR_UNIT);
0260 
0261 static void encode_fallocate(struct xdr_stream *xdr,
0262                  const struct nfs42_falloc_args *args)
0263 {
0264     encode_nfs4_stateid(xdr, &args->falloc_stateid);
0265     encode_uint64(xdr, args->falloc_offset);
0266     encode_uint64(xdr, args->falloc_length);
0267 }
0268 
0269 static void encode_allocate(struct xdr_stream *xdr,
0270                 const struct nfs42_falloc_args *args,
0271                 struct compound_hdr *hdr)
0272 {
0273     encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
0274     encode_fallocate(xdr, args);
0275 }
0276 
0277 static void encode_nl4_server(struct xdr_stream *xdr,
0278                   const struct nl4_server *ns)
0279 {
0280     encode_uint32(xdr, ns->nl4_type);
0281     switch (ns->nl4_type) {
0282     case NL4_NAME:
0283     case NL4_URL:
0284         encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
0285         break;
0286     case NL4_NETADDR:
0287         encode_string(xdr, ns->u.nl4_addr.netid_len,
0288                   ns->u.nl4_addr.netid);
0289         encode_string(xdr, ns->u.nl4_addr.addr_len,
0290                   ns->u.nl4_addr.addr);
0291         break;
0292     default:
0293         WARN_ON_ONCE(1);
0294     }
0295 }
0296 
0297 static void encode_copy(struct xdr_stream *xdr,
0298             const struct nfs42_copy_args *args,
0299             struct compound_hdr *hdr)
0300 {
0301     encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
0302     encode_nfs4_stateid(xdr, &args->src_stateid);
0303     encode_nfs4_stateid(xdr, &args->dst_stateid);
0304 
0305     encode_uint64(xdr, args->src_pos);
0306     encode_uint64(xdr, args->dst_pos);
0307     encode_uint64(xdr, args->count);
0308 
0309     encode_uint32(xdr, 1); /* consecutive = true */
0310     encode_uint32(xdr, args->sync);
0311     if (args->cp_src == NULL) { /* intra-ssc */
0312         encode_uint32(xdr, 0); /* no src server list */
0313         return;
0314     }
0315     encode_uint32(xdr, 1); /* supporting 1 server */
0316     encode_nl4_server(xdr, args->cp_src);
0317 }
0318 
0319 static void encode_offload_cancel(struct xdr_stream *xdr,
0320                   const struct nfs42_offload_status_args *args,
0321                   struct compound_hdr *hdr)
0322 {
0323     encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
0324     encode_nfs4_stateid(xdr, &args->osa_stateid);
0325 }
0326 
0327 static void encode_copy_notify(struct xdr_stream *xdr,
0328                    const struct nfs42_copy_notify_args *args,
0329                    struct compound_hdr *hdr)
0330 {
0331     encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
0332     encode_nfs4_stateid(xdr, &args->cna_src_stateid);
0333     encode_nl4_server(xdr, &args->cna_dst);
0334 }
0335 
0336 static void encode_deallocate(struct xdr_stream *xdr,
0337                   const struct nfs42_falloc_args *args,
0338                   struct compound_hdr *hdr)
0339 {
0340     encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
0341     encode_fallocate(xdr, args);
0342 }
0343 
0344 static void encode_read_plus(struct xdr_stream *xdr,
0345                  const struct nfs_pgio_args *args,
0346                  struct compound_hdr *hdr)
0347 {
0348     encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr);
0349     encode_nfs4_stateid(xdr, &args->stateid);
0350     encode_uint64(xdr, args->offset);
0351     encode_uint32(xdr, args->count);
0352 }
0353 
0354 static void encode_seek(struct xdr_stream *xdr,
0355             const struct nfs42_seek_args *args,
0356             struct compound_hdr *hdr)
0357 {
0358     encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
0359     encode_nfs4_stateid(xdr, &args->sa_stateid);
0360     encode_uint64(xdr, args->sa_offset);
0361     encode_uint32(xdr, args->sa_what);
0362 }
0363 
0364 static void encode_layoutstats(struct xdr_stream *xdr,
0365                    const struct nfs42_layoutstat_args *args,
0366                    struct nfs42_layoutstat_devinfo *devinfo,
0367                    struct compound_hdr *hdr)
0368 {
0369     __be32 *p;
0370 
0371     encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
0372     p = reserve_space(xdr, 8 + 8);
0373     p = xdr_encode_hyper(p, devinfo->offset);
0374     p = xdr_encode_hyper(p, devinfo->length);
0375     encode_nfs4_stateid(xdr, &args->stateid);
0376     p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
0377     p = xdr_encode_hyper(p, devinfo->read_count);
0378     p = xdr_encode_hyper(p, devinfo->read_bytes);
0379     p = xdr_encode_hyper(p, devinfo->write_count);
0380     p = xdr_encode_hyper(p, devinfo->write_bytes);
0381     p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
0382             NFS4_DEVICEID4_SIZE);
0383     /* Encode layoutupdate4 */
0384     *p++ = cpu_to_be32(devinfo->layout_type);
0385     if (devinfo->ld_private.ops)
0386         devinfo->ld_private.ops->encode(xdr, args,
0387                 &devinfo->ld_private);
0388     else
0389         encode_uint32(xdr, 0);
0390 }
0391 
0392 static void encode_clone(struct xdr_stream *xdr,
0393              const struct nfs42_clone_args *args,
0394              struct compound_hdr *hdr)
0395 {
0396     __be32 *p;
0397 
0398     encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
0399     encode_nfs4_stateid(xdr, &args->src_stateid);
0400     encode_nfs4_stateid(xdr, &args->dst_stateid);
0401     p = reserve_space(xdr, 3*8);
0402     p = xdr_encode_hyper(p, args->src_offset);
0403     p = xdr_encode_hyper(p, args->dst_offset);
0404     xdr_encode_hyper(p, args->count);
0405 }
0406 
0407 static void encode_device_error(struct xdr_stream *xdr,
0408                 const struct nfs42_device_error *error)
0409 {
0410     __be32 *p;
0411 
0412     p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4);
0413     p = xdr_encode_opaque_fixed(p, error->dev_id.data,
0414             NFS4_DEVICEID4_SIZE);
0415     *p++ = cpu_to_be32(error->status);
0416     *p = cpu_to_be32(error->opnum);
0417 }
0418 
0419 static void encode_layouterror(struct xdr_stream *xdr,
0420                    const struct nfs42_layout_error *args,
0421                    struct compound_hdr *hdr)
0422 {
0423     __be32 *p;
0424 
0425     encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr);
0426     p = reserve_space(xdr, 8 + 8);
0427     p = xdr_encode_hyper(p, args->offset);
0428     p = xdr_encode_hyper(p, args->length);
0429     encode_nfs4_stateid(xdr, &args->stateid);
0430     p = reserve_space(xdr, 4);
0431     *p = cpu_to_be32(1);
0432     encode_device_error(xdr, &args->errors[0]);
0433 }
0434 
0435 static void encode_setxattr(struct xdr_stream *xdr,
0436                 const struct nfs42_setxattrargs *arg,
0437                 struct compound_hdr *hdr)
0438 {
0439     __be32 *p;
0440 
0441     BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
0442     BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
0443 
0444     encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr);
0445     p = reserve_space(xdr, 4);
0446     *p = cpu_to_be32(arg->xattr_flags);
0447     encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name);
0448     p = reserve_space(xdr, 4);
0449     *p = cpu_to_be32(arg->xattr_len);
0450     if (arg->xattr_len)
0451         xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
0452 }
0453 
0454 static int decode_setxattr(struct xdr_stream *xdr,
0455                struct nfs4_change_info *cinfo)
0456 {
0457     int status;
0458 
0459     status = decode_op_hdr(xdr, OP_SETXATTR);
0460     if (status)
0461         goto out;
0462     status = decode_change_info(xdr, cinfo);
0463 out:
0464     return status;
0465 }
0466 
0467 
0468 static void encode_getxattr(struct xdr_stream *xdr, const char *name,
0469                 struct compound_hdr *hdr)
0470 {
0471     encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
0472     encode_string(xdr, strlen(name), name);
0473 }
0474 
0475 static int decode_getxattr(struct xdr_stream *xdr,
0476                struct nfs42_getxattrres *res,
0477                struct rpc_rqst *req)
0478 {
0479     int status;
0480     __be32 *p;
0481     u32 len, rdlen;
0482 
0483     status = decode_op_hdr(xdr, OP_GETXATTR);
0484     if (status)
0485         return status;
0486 
0487     p = xdr_inline_decode(xdr, 4);
0488     if (unlikely(!p))
0489         return -EIO;
0490 
0491     len = be32_to_cpup(p);
0492 
0493     /*
0494      * Only check against the page length here. The actual
0495      * requested length may be smaller, but that is only
0496      * checked against after possibly caching a valid reply.
0497      */
0498     if (len > req->rq_rcv_buf.page_len)
0499         return -ERANGE;
0500 
0501     res->xattr_len = len;
0502 
0503     if (len > 0) {
0504         rdlen = xdr_read_pages(xdr, len);
0505         if (rdlen < len)
0506             return -EIO;
0507     }
0508 
0509     return 0;
0510 }
0511 
0512 static void encode_removexattr(struct xdr_stream *xdr, const char *name,
0513                    struct compound_hdr *hdr)
0514 {
0515     encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
0516     encode_string(xdr, strlen(name), name);
0517 }
0518 
0519 
0520 static int decode_removexattr(struct xdr_stream *xdr,
0521                struct nfs4_change_info *cinfo)
0522 {
0523     int status;
0524 
0525     status = decode_op_hdr(xdr, OP_REMOVEXATTR);
0526     if (status)
0527         goto out;
0528 
0529     status = decode_change_info(xdr, cinfo);
0530 out:
0531     return status;
0532 }
0533 
0534 static void encode_listxattrs(struct xdr_stream *xdr,
0535                  const struct nfs42_listxattrsargs *arg,
0536                  struct compound_hdr *hdr)
0537 {
0538     __be32 *p;
0539 
0540     encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr);
0541 
0542     p = reserve_space(xdr, 12);
0543     if (unlikely(!p))
0544         return;
0545 
0546     p = xdr_encode_hyper(p, arg->cookie);
0547     /*
0548      * RFC 8276 says to specify the full max length of the LISTXATTRS
0549      * XDR reply. Count is set to the XDR length of the names array
0550      * plus the EOF marker. So, add the cookie and the names count.
0551      */
0552     *p = cpu_to_be32(arg->count + 8 + 4);
0553 }
0554 
0555 static int decode_listxattrs(struct xdr_stream *xdr,
0556                 struct nfs42_listxattrsres *res)
0557 {
0558     int status;
0559     __be32 *p;
0560     u32 count, len, ulen;
0561     size_t left, copied;
0562     char *buf;
0563 
0564     status = decode_op_hdr(xdr, OP_LISTXATTRS);
0565     if (status) {
0566         /*
0567          * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
0568          * should be translated to ERANGE.
0569          */
0570         if (status == -ETOOSMALL)
0571             status = -ERANGE;
0572         goto out;
0573     }
0574 
0575     p = xdr_inline_decode(xdr, 8);
0576     if (unlikely(!p))
0577         return -EIO;
0578 
0579     xdr_decode_hyper(p, &res->cookie);
0580 
0581     p = xdr_inline_decode(xdr, 4);
0582     if (unlikely(!p))
0583         return -EIO;
0584 
0585     left = res->xattr_len;
0586     buf = res->xattr_buf;
0587 
0588     count = be32_to_cpup(p);
0589     copied = 0;
0590 
0591     /*
0592      * We have asked for enough room to encode the maximum number
0593      * of possible attribute names, so everything should fit.
0594      *
0595      * But, don't rely on that assumption. Just decode entries
0596      * until they don't fit anymore, just in case the server did
0597      * something odd.
0598      */
0599     while (count--) {
0600         p = xdr_inline_decode(xdr, 4);
0601         if (unlikely(!p))
0602             return -EIO;
0603 
0604         len = be32_to_cpup(p);
0605         if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
0606             status = -ERANGE;
0607             goto out;
0608         }
0609 
0610         p = xdr_inline_decode(xdr, len);
0611         if (unlikely(!p))
0612             return -EIO;
0613 
0614         ulen = len + XATTR_USER_PREFIX_LEN + 1;
0615         if (buf) {
0616             if (ulen > left) {
0617                 status = -ERANGE;
0618                 goto out;
0619             }
0620 
0621             memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
0622             memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
0623 
0624             buf[ulen - 1] = 0;
0625             buf += ulen;
0626             left -= ulen;
0627         }
0628         copied += ulen;
0629     }
0630 
0631     p = xdr_inline_decode(xdr, 4);
0632     if (unlikely(!p))
0633         return -EIO;
0634 
0635     res->eof = be32_to_cpup(p);
0636     res->copied = copied;
0637 
0638 out:
0639     if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
0640         status = -E2BIG;
0641 
0642     return status;
0643 }
0644 
0645 /*
0646  * Encode ALLOCATE request
0647  */
0648 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
0649                   struct xdr_stream *xdr,
0650                   const void *data)
0651 {
0652     const struct nfs42_falloc_args *args = data;
0653     struct compound_hdr hdr = {
0654         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
0655     };
0656 
0657     encode_compound_hdr(xdr, req, &hdr);
0658     encode_sequence(xdr, &args->seq_args, &hdr);
0659     encode_putfh(xdr, args->falloc_fh, &hdr);
0660     encode_allocate(xdr, args, &hdr);
0661     encode_getfattr(xdr, args->falloc_bitmask, &hdr);
0662     encode_nops(&hdr);
0663 }
0664 
0665 static void encode_copy_commit(struct xdr_stream *xdr,
0666               const struct nfs42_copy_args *args,
0667               struct compound_hdr *hdr)
0668 {
0669     __be32 *p;
0670 
0671     encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
0672     p = reserve_space(xdr, 12);
0673     p = xdr_encode_hyper(p, args->dst_pos);
0674     *p = cpu_to_be32(args->count);
0675 }
0676 
0677 /*
0678  * Encode COPY request
0679  */
0680 static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
0681                   struct xdr_stream *xdr,
0682                   const void *data)
0683 {
0684     const struct nfs42_copy_args *args = data;
0685     struct compound_hdr hdr = {
0686         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
0687     };
0688 
0689     encode_compound_hdr(xdr, req, &hdr);
0690     encode_sequence(xdr, &args->seq_args, &hdr);
0691     encode_putfh(xdr, args->src_fh, &hdr);
0692     encode_savefh(xdr, &hdr);
0693     encode_putfh(xdr, args->dst_fh, &hdr);
0694     encode_copy(xdr, args, &hdr);
0695     if (args->sync)
0696         encode_copy_commit(xdr, args, &hdr);
0697     encode_nops(&hdr);
0698 }
0699 
0700 /*
0701  * Encode OFFLOAD_CANEL request
0702  */
0703 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
0704                     struct xdr_stream *xdr,
0705                     const void *data)
0706 {
0707     const struct nfs42_offload_status_args *args = data;
0708     struct compound_hdr hdr = {
0709         .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
0710     };
0711 
0712     encode_compound_hdr(xdr, req, &hdr);
0713     encode_sequence(xdr, &args->osa_seq_args, &hdr);
0714     encode_putfh(xdr, args->osa_src_fh, &hdr);
0715     encode_offload_cancel(xdr, args, &hdr);
0716     encode_nops(&hdr);
0717 }
0718 
0719 /*
0720  * Encode COPY_NOTIFY request
0721  */
0722 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
0723                      struct xdr_stream *xdr,
0724                      const void *data)
0725 {
0726     const struct nfs42_copy_notify_args *args = data;
0727     struct compound_hdr hdr = {
0728         .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
0729     };
0730 
0731     encode_compound_hdr(xdr, req, &hdr);
0732     encode_sequence(xdr, &args->cna_seq_args, &hdr);
0733     encode_putfh(xdr, args->cna_src_fh, &hdr);
0734     encode_copy_notify(xdr, args, &hdr);
0735     encode_nops(&hdr);
0736 }
0737 
0738 /*
0739  * Encode DEALLOCATE request
0740  */
0741 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
0742                     struct xdr_stream *xdr,
0743                     const void *data)
0744 {
0745     const struct nfs42_falloc_args *args = data;
0746     struct compound_hdr hdr = {
0747         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
0748     };
0749 
0750     encode_compound_hdr(xdr, req, &hdr);
0751     encode_sequence(xdr, &args->seq_args, &hdr);
0752     encode_putfh(xdr, args->falloc_fh, &hdr);
0753     encode_deallocate(xdr, args, &hdr);
0754     encode_getfattr(xdr, args->falloc_bitmask, &hdr);
0755     encode_nops(&hdr);
0756 }
0757 
0758 /*
0759  * Encode READ_PLUS request
0760  */
0761 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req,
0762                    struct xdr_stream *xdr,
0763                    const void *data)
0764 {
0765     const struct nfs_pgio_args *args = data;
0766     struct compound_hdr hdr = {
0767         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
0768     };
0769 
0770     encode_compound_hdr(xdr, req, &hdr);
0771     encode_sequence(xdr, &args->seq_args, &hdr);
0772     encode_putfh(xdr, args->fh, &hdr);
0773     encode_read_plus(xdr, args, &hdr);
0774 
0775     rpc_prepare_reply_pages(req, args->pages, args->pgbase,
0776                 args->count, hdr.replen);
0777     encode_nops(&hdr);
0778 }
0779 
0780 /*
0781  * Encode SEEK request
0782  */
0783 static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
0784                   struct xdr_stream *xdr,
0785                   const void *data)
0786 {
0787     const struct nfs42_seek_args *args = data;
0788     struct compound_hdr hdr = {
0789         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
0790     };
0791 
0792     encode_compound_hdr(xdr, req, &hdr);
0793     encode_sequence(xdr, &args->seq_args, &hdr);
0794     encode_putfh(xdr, args->sa_fh, &hdr);
0795     encode_seek(xdr, args, &hdr);
0796     encode_nops(&hdr);
0797 }
0798 
0799 /*
0800  * Encode LAYOUTSTATS request
0801  */
0802 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
0803                      struct xdr_stream *xdr,
0804                      const void *data)
0805 {
0806     const struct nfs42_layoutstat_args *args = data;
0807     int i;
0808 
0809     struct compound_hdr hdr = {
0810         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
0811     };
0812 
0813     encode_compound_hdr(xdr, req, &hdr);
0814     encode_sequence(xdr, &args->seq_args, &hdr);
0815     encode_putfh(xdr, args->fh, &hdr);
0816     WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
0817     for (i = 0; i < args->num_dev; i++)
0818         encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
0819     encode_nops(&hdr);
0820 }
0821 
0822 /*
0823  * Encode CLONE request
0824  */
0825 static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
0826                    struct xdr_stream *xdr,
0827                    const void *data)
0828 {
0829     const struct nfs42_clone_args *args = data;
0830     struct compound_hdr hdr = {
0831         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
0832     };
0833 
0834     encode_compound_hdr(xdr, req, &hdr);
0835     encode_sequence(xdr, &args->seq_args, &hdr);
0836     encode_putfh(xdr, args->src_fh, &hdr);
0837     encode_savefh(xdr, &hdr);
0838     encode_putfh(xdr, args->dst_fh, &hdr);
0839     encode_clone(xdr, args, &hdr);
0840     encode_getfattr(xdr, args->dst_bitmask, &hdr);
0841     encode_nops(&hdr);
0842 }
0843 
0844 /*
0845  * Encode LAYOUTERROR request
0846  */
0847 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
0848                      struct xdr_stream *xdr,
0849                      const void *data)
0850 {
0851     const struct nfs42_layouterror_args *args = data;
0852     struct compound_hdr hdr = {
0853         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
0854     };
0855     int i;
0856 
0857     encode_compound_hdr(xdr, req, &hdr);
0858     encode_sequence(xdr, &args->seq_args, &hdr);
0859     encode_putfh(xdr, NFS_FH(args->inode), &hdr);
0860     for (i = 0; i < args->num_errors; i++)
0861         encode_layouterror(xdr, &args->errors[i], &hdr);
0862     encode_nops(&hdr);
0863 }
0864 
0865 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
0866 {
0867     return decode_op_hdr(xdr, OP_ALLOCATE);
0868 }
0869 
0870 static int decode_write_response(struct xdr_stream *xdr,
0871                  struct nfs42_write_res *res)
0872 {
0873     __be32 *p;
0874     int status, count;
0875 
0876     p = xdr_inline_decode(xdr, 4);
0877     if (unlikely(!p))
0878         return -EIO;
0879     count = be32_to_cpup(p);
0880     if (count > 1)
0881         return -EREMOTEIO;
0882     else if (count == 1) {
0883         status = decode_opaque_fixed(xdr, &res->stateid,
0884                 NFS4_STATEID_SIZE);
0885         if (unlikely(status))
0886             return -EIO;
0887     }
0888     p = xdr_inline_decode(xdr, 8 + 4);
0889     if (unlikely(!p))
0890         return -EIO;
0891     p = xdr_decode_hyper(p, &res->count);
0892     res->verifier.committed = be32_to_cpup(p);
0893     return decode_verifier(xdr, &res->verifier.verifier);
0894 }
0895 
0896 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
0897 {
0898     struct nfs42_netaddr *naddr;
0899     uint32_t dummy;
0900     char *dummy_str;
0901     __be32 *p;
0902     int status;
0903 
0904     /* nl_type */
0905     p = xdr_inline_decode(xdr, 4);
0906     if (unlikely(!p))
0907         return -EIO;
0908     ns->nl4_type = be32_to_cpup(p);
0909     switch (ns->nl4_type) {
0910     case NL4_NAME:
0911     case NL4_URL:
0912         status = decode_opaque_inline(xdr, &dummy, &dummy_str);
0913         if (unlikely(status))
0914             return status;
0915         if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
0916             return -EIO;
0917         memcpy(&ns->u.nl4_str, dummy_str, dummy);
0918         ns->u.nl4_str_sz = dummy;
0919         break;
0920     case NL4_NETADDR:
0921         naddr = &ns->u.nl4_addr;
0922 
0923         /* netid string */
0924         status = decode_opaque_inline(xdr, &dummy, &dummy_str);
0925         if (unlikely(status))
0926             return status;
0927         if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
0928             return -EIO;
0929         naddr->netid_len = dummy;
0930         memcpy(naddr->netid, dummy_str, naddr->netid_len);
0931 
0932         /* uaddr string */
0933         status = decode_opaque_inline(xdr, &dummy, &dummy_str);
0934         if (unlikely(status))
0935             return status;
0936         if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
0937             return -EIO;
0938         naddr->addr_len = dummy;
0939         memcpy(naddr->addr, dummy_str, naddr->addr_len);
0940         break;
0941     default:
0942         WARN_ON_ONCE(1);
0943         return -EIO;
0944     }
0945     return 0;
0946 }
0947 
0948 static int decode_copy_requirements(struct xdr_stream *xdr,
0949                     struct nfs42_copy_res *res) {
0950     __be32 *p;
0951 
0952     p = xdr_inline_decode(xdr, 4 + 4);
0953     if (unlikely(!p))
0954         return -EIO;
0955 
0956     res->consecutive = be32_to_cpup(p++);
0957     res->synchronous = be32_to_cpup(p++);
0958     return 0;
0959 }
0960 
0961 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
0962 {
0963     int status;
0964 
0965     status = decode_op_hdr(xdr, OP_COPY);
0966     if (status == NFS4ERR_OFFLOAD_NO_REQS) {
0967         status = decode_copy_requirements(xdr, res);
0968         if (status)
0969             return status;
0970         return NFS4ERR_OFFLOAD_NO_REQS;
0971     } else if (status)
0972         return status;
0973 
0974     status = decode_write_response(xdr, &res->write_res);
0975     if (status)
0976         return status;
0977 
0978     return decode_copy_requirements(xdr, res);
0979 }
0980 
0981 static int decode_offload_cancel(struct xdr_stream *xdr,
0982                  struct nfs42_offload_status_res *res)
0983 {
0984     return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
0985 }
0986 
0987 static int decode_copy_notify(struct xdr_stream *xdr,
0988                   struct nfs42_copy_notify_res *res)
0989 {
0990     __be32 *p;
0991     int status, count;
0992 
0993     status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
0994     if (status)
0995         return status;
0996     /* cnr_lease_time */
0997     p = xdr_inline_decode(xdr, 12);
0998     if (unlikely(!p))
0999         return -EIO;
1000     p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
1001     res->cnr_lease_time.nseconds = be32_to_cpup(p);
1002 
1003     status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
1004     if (unlikely(status))
1005         return -EIO;
1006 
1007     /* number of source addresses */
1008     p = xdr_inline_decode(xdr, 4);
1009     if (unlikely(!p))
1010         return -EIO;
1011 
1012     count = be32_to_cpup(p);
1013     if (count > 1)
1014         pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
1015              __func__, count);
1016 
1017     status = decode_nl4_server(xdr, &res->cnr_src);
1018     if (unlikely(status))
1019         return -EIO;
1020     return 0;
1021 }
1022 
1023 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
1024 {
1025     return decode_op_hdr(xdr, OP_DEALLOCATE);
1026 }
1027 
1028 struct read_plus_segment {
1029     enum data_content4 type;
1030     uint64_t offset;
1031     union {
1032         struct {
1033             uint64_t length;
1034         } hole;
1035 
1036         struct {
1037             uint32_t length;
1038             unsigned int from;
1039         } data;
1040     };
1041 };
1042 
1043 static inline uint64_t read_plus_segment_length(struct read_plus_segment *seg)
1044 {
1045     return seg->type == NFS4_CONTENT_DATA ? seg->data.length : seg->hole.length;
1046 }
1047 
1048 static int decode_read_plus_segment(struct xdr_stream *xdr,
1049                     struct read_plus_segment *seg)
1050 {
1051     __be32 *p;
1052 
1053     p = xdr_inline_decode(xdr, 4);
1054     if (!p)
1055         return -EIO;
1056     seg->type = be32_to_cpup(p++);
1057 
1058     p = xdr_inline_decode(xdr, seg->type == NFS4_CONTENT_DATA ? 12 : 16);
1059     if (!p)
1060         return -EIO;
1061     p = xdr_decode_hyper(p, &seg->offset);
1062 
1063     if (seg->type == NFS4_CONTENT_DATA) {
1064         struct xdr_buf buf;
1065         uint32_t len = be32_to_cpup(p);
1066 
1067         seg->data.length = len;
1068         seg->data.from = xdr_stream_pos(xdr);
1069 
1070         if (!xdr_stream_subsegment(xdr, &buf, xdr_align_size(len)))
1071             return -EIO;
1072     } else if (seg->type == NFS4_CONTENT_HOLE) {
1073         xdr_decode_hyper(p, &seg->hole.length);
1074     } else
1075         return -EINVAL;
1076     return 0;
1077 }
1078 
1079 static int process_read_plus_segment(struct xdr_stream *xdr,
1080                      struct nfs_pgio_args *args,
1081                      struct nfs_pgio_res *res,
1082                      struct read_plus_segment *seg)
1083 {
1084     unsigned long offset = seg->offset;
1085     unsigned long length = read_plus_segment_length(seg);
1086     unsigned int bufpos;
1087 
1088     if (offset + length < args->offset)
1089         return 0;
1090     else if (offset > args->offset + args->count) {
1091         res->eof = 0;
1092         return 0;
1093     } else if (offset < args->offset) {
1094         length -= (args->offset - offset);
1095         offset = args->offset;
1096     } else if (offset + length > args->offset + args->count) {
1097         length = (args->offset + args->count) - offset;
1098         res->eof = 0;
1099     }
1100 
1101     bufpos = xdr->buf->head[0].iov_len + (offset - args->offset);
1102     if (seg->type == NFS4_CONTENT_HOLE)
1103         return xdr_stream_zero(xdr, bufpos, length);
1104     else
1105         return xdr_stream_move_subsegment(xdr, seg->data.from, bufpos, length);
1106 }
1107 
1108 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
1109 {
1110     struct nfs_pgio_header *hdr =
1111         container_of(res, struct nfs_pgio_header, res);
1112     struct nfs_pgio_args *args = &hdr->args;
1113     uint32_t segments;
1114     struct read_plus_segment *segs;
1115     int status, i;
1116     char scratch_buf[16];
1117     __be32 *p;
1118 
1119     status = decode_op_hdr(xdr, OP_READ_PLUS);
1120     if (status)
1121         return status;
1122 
1123     p = xdr_inline_decode(xdr, 4 + 4);
1124     if (unlikely(!p))
1125         return -EIO;
1126 
1127     res->count = 0;
1128     res->eof = be32_to_cpup(p++);
1129     segments = be32_to_cpup(p++);
1130     if (segments == 0)
1131         return status;
1132 
1133     segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL);
1134     if (!segs)
1135         return -ENOMEM;
1136 
1137     xdr_set_scratch_buffer(xdr, &scratch_buf, 32);
1138     status = -EIO;
1139     for (i = 0; i < segments; i++) {
1140         status = decode_read_plus_segment(xdr, &segs[i]);
1141         if (status < 0)
1142             goto out;
1143     }
1144 
1145     xdr_set_pagelen(xdr, xdr_align_size(args->count));
1146     for (i = segments; i > 0; i--)
1147         res->count += process_read_plus_segment(xdr, args, res, &segs[i-1]);
1148     status = 0;
1149 
1150 out:
1151     kfree(segs);
1152     return status;
1153 }
1154 
1155 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
1156 {
1157     int status;
1158     __be32 *p;
1159 
1160     status = decode_op_hdr(xdr, OP_SEEK);
1161     if (status)
1162         return status;
1163 
1164     p = xdr_inline_decode(xdr, 4 + 8);
1165     if (unlikely(!p))
1166         return -EIO;
1167 
1168     res->sr_eof = be32_to_cpup(p++);
1169     p = xdr_decode_hyper(p, &res->sr_offset);
1170     return 0;
1171 }
1172 
1173 static int decode_layoutstats(struct xdr_stream *xdr)
1174 {
1175     return decode_op_hdr(xdr, OP_LAYOUTSTATS);
1176 }
1177 
1178 static int decode_clone(struct xdr_stream *xdr)
1179 {
1180     return decode_op_hdr(xdr, OP_CLONE);
1181 }
1182 
1183 static int decode_layouterror(struct xdr_stream *xdr)
1184 {
1185     return decode_op_hdr(xdr, OP_LAYOUTERROR);
1186 }
1187 
1188 /*
1189  * Decode ALLOCATE request
1190  */
1191 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
1192                  struct xdr_stream *xdr,
1193                  void *data)
1194 {
1195     struct nfs42_falloc_res *res = data;
1196     struct compound_hdr hdr;
1197     int status;
1198 
1199     status = decode_compound_hdr(xdr, &hdr);
1200     if (status)
1201         goto out;
1202     status = decode_sequence(xdr, &res->seq_res, rqstp);
1203     if (status)
1204         goto out;
1205     status = decode_putfh(xdr);
1206     if (status)
1207         goto out;
1208     status = decode_allocate(xdr, res);
1209     if (status)
1210         goto out;
1211     decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1212 out:
1213     return status;
1214 }
1215 
1216 /*
1217  * Decode COPY response
1218  */
1219 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
1220                  struct xdr_stream *xdr,
1221                  void *data)
1222 {
1223     struct nfs42_copy_res *res = data;
1224     struct compound_hdr hdr;
1225     int status;
1226 
1227     status = decode_compound_hdr(xdr, &hdr);
1228     if (status)
1229         goto out;
1230     status = decode_sequence(xdr, &res->seq_res, rqstp);
1231     if (status)
1232         goto out;
1233     status = decode_putfh(xdr);
1234     if (status)
1235         goto out;
1236     status = decode_savefh(xdr);
1237     if (status)
1238         goto out;
1239     status = decode_putfh(xdr);
1240     if (status)
1241         goto out;
1242     status = decode_copy(xdr, res);
1243     if (status)
1244         goto out;
1245     if (res->commit_res.verf)
1246         status = decode_commit(xdr, &res->commit_res);
1247 out:
1248     return status;
1249 }
1250 
1251 /*
1252  * Decode OFFLOAD_CANCEL response
1253  */
1254 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
1255                        struct xdr_stream *xdr,
1256                        void *data)
1257 {
1258     struct nfs42_offload_status_res *res = data;
1259     struct compound_hdr hdr;
1260     int status;
1261 
1262     status = decode_compound_hdr(xdr, &hdr);
1263     if (status)
1264         goto out;
1265     status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1266     if (status)
1267         goto out;
1268     status = decode_putfh(xdr);
1269     if (status)
1270         goto out;
1271     status = decode_offload_cancel(xdr, res);
1272 
1273 out:
1274     return status;
1275 }
1276 
1277 /*
1278  * Decode COPY_NOTIFY response
1279  */
1280 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
1281                     struct xdr_stream *xdr,
1282                     void *data)
1283 {
1284     struct nfs42_copy_notify_res *res = data;
1285     struct compound_hdr hdr;
1286     int status;
1287 
1288     status = decode_compound_hdr(xdr, &hdr);
1289     if (status)
1290         goto out;
1291     status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
1292     if (status)
1293         goto out;
1294     status = decode_putfh(xdr);
1295     if (status)
1296         goto out;
1297     status = decode_copy_notify(xdr, res);
1298 
1299 out:
1300     return status;
1301 }
1302 
1303 /*
1304  * Decode DEALLOCATE request
1305  */
1306 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
1307                    struct xdr_stream *xdr,
1308                    void *data)
1309 {
1310     struct nfs42_falloc_res *res = data;
1311     struct compound_hdr hdr;
1312     int status;
1313 
1314     status = decode_compound_hdr(xdr, &hdr);
1315     if (status)
1316         goto out;
1317     status = decode_sequence(xdr, &res->seq_res, rqstp);
1318     if (status)
1319         goto out;
1320     status = decode_putfh(xdr);
1321     if (status)
1322         goto out;
1323     status = decode_deallocate(xdr, res);
1324     if (status)
1325         goto out;
1326     decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1327 out:
1328     return status;
1329 }
1330 
1331 /*
1332  * Decode READ_PLUS request
1333  */
1334 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp,
1335                   struct xdr_stream *xdr,
1336                   void *data)
1337 {
1338     struct nfs_pgio_res *res = data;
1339     struct compound_hdr hdr;
1340     int status;
1341 
1342     status = decode_compound_hdr(xdr, &hdr);
1343     if (status)
1344         goto out;
1345     status = decode_sequence(xdr, &res->seq_res, rqstp);
1346     if (status)
1347         goto out;
1348     status = decode_putfh(xdr);
1349     if (status)
1350         goto out;
1351     status = decode_read_plus(xdr, res);
1352     if (!status)
1353         status = res->count;
1354 out:
1355     return status;
1356 }
1357 
1358 /*
1359  * Decode SEEK request
1360  */
1361 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
1362                  struct xdr_stream *xdr,
1363                  void *data)
1364 {
1365     struct nfs42_seek_res *res = data;
1366     struct compound_hdr hdr;
1367     int status;
1368 
1369     status = decode_compound_hdr(xdr, &hdr);
1370     if (status)
1371         goto out;
1372     status = decode_sequence(xdr, &res->seq_res, rqstp);
1373     if (status)
1374         goto out;
1375     status = decode_putfh(xdr);
1376     if (status)
1377         goto out;
1378     status = decode_seek(xdr, res);
1379 out:
1380     return status;
1381 }
1382 
1383 /*
1384  * Decode LAYOUTSTATS request
1385  */
1386 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
1387                     struct xdr_stream *xdr,
1388                     void *data)
1389 {
1390     struct nfs42_layoutstat_res *res = data;
1391     struct compound_hdr hdr;
1392     int status, i;
1393 
1394     status = decode_compound_hdr(xdr, &hdr);
1395     if (status)
1396         goto out;
1397     status = decode_sequence(xdr, &res->seq_res, rqstp);
1398     if (status)
1399         goto out;
1400     status = decode_putfh(xdr);
1401     if (status)
1402         goto out;
1403     WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
1404     for (i = 0; i < res->num_dev; i++) {
1405         status = decode_layoutstats(xdr);
1406         if (status)
1407             goto out;
1408     }
1409 out:
1410     res->rpc_status = status;
1411     return status;
1412 }
1413 
1414 /*
1415  * Decode CLONE request
1416  */
1417 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
1418                   struct xdr_stream *xdr,
1419                   void *data)
1420 {
1421     struct nfs42_clone_res *res = data;
1422     struct compound_hdr hdr;
1423     int status;
1424 
1425     status = decode_compound_hdr(xdr, &hdr);
1426     if (status)
1427         goto out;
1428     status = decode_sequence(xdr, &res->seq_res, rqstp);
1429     if (status)
1430         goto out;
1431     status = decode_putfh(xdr);
1432     if (status)
1433         goto out;
1434     status = decode_savefh(xdr);
1435     if (status)
1436         goto out;
1437     status = decode_putfh(xdr);
1438     if (status)
1439         goto out;
1440     status = decode_clone(xdr);
1441     if (status)
1442         goto out;
1443     decode_getfattr(xdr, res->dst_fattr, res->server);
1444 out:
1445     res->rpc_status = status;
1446     return status;
1447 }
1448 
1449 /*
1450  * Decode LAYOUTERROR request
1451  */
1452 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
1453                     struct xdr_stream *xdr,
1454                     void *data)
1455 {
1456     struct nfs42_layouterror_res *res = data;
1457     struct compound_hdr hdr;
1458     int status, i;
1459 
1460     status = decode_compound_hdr(xdr, &hdr);
1461     if (status)
1462         goto out;
1463     status = decode_sequence(xdr, &res->seq_res, rqstp);
1464     if (status)
1465         goto out;
1466     status = decode_putfh(xdr);
1467 
1468     for (i = 0; i < res->num_errors && status == 0; i++)
1469         status = decode_layouterror(xdr);
1470 out:
1471     res->rpc_status = status;
1472     return status;
1473 }
1474 
1475 #ifdef CONFIG_NFS_V4_2
1476 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1477                   const void *data)
1478 {
1479     const struct nfs42_setxattrargs *args = data;
1480     struct compound_hdr hdr = {
1481         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1482     };
1483 
1484     encode_compound_hdr(xdr, req, &hdr);
1485     encode_sequence(xdr, &args->seq_args, &hdr);
1486     encode_putfh(xdr, args->fh, &hdr);
1487     encode_setxattr(xdr, args, &hdr);
1488     encode_nops(&hdr);
1489 }
1490 
1491 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1492                  void *data)
1493 {
1494     struct nfs42_setxattrres *res = data;
1495     struct compound_hdr hdr;
1496     int status;
1497 
1498     status = decode_compound_hdr(xdr, &hdr);
1499     if (status)
1500         goto out;
1501     status = decode_sequence(xdr, &res->seq_res, req);
1502     if (status)
1503         goto out;
1504     status = decode_putfh(xdr);
1505     if (status)
1506         goto out;
1507 
1508     status = decode_setxattr(xdr, &res->cinfo);
1509 out:
1510     return status;
1511 }
1512 
1513 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
1514                   const void *data)
1515 {
1516     const struct nfs42_getxattrargs *args = data;
1517     struct compound_hdr hdr = {
1518         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1519     };
1520     uint32_t replen;
1521 
1522     encode_compound_hdr(xdr, req, &hdr);
1523     encode_sequence(xdr, &args->seq_args, &hdr);
1524     encode_putfh(xdr, args->fh, &hdr);
1525     replen = hdr.replen + op_decode_hdr_maxsz + 1;
1526     encode_getxattr(xdr, args->xattr_name, &hdr);
1527 
1528     rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len,
1529                 replen);
1530 
1531     encode_nops(&hdr);
1532 }
1533 
1534 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
1535                  struct xdr_stream *xdr, void *data)
1536 {
1537     struct nfs42_getxattrres *res = data;
1538     struct compound_hdr hdr;
1539     int status;
1540 
1541     status = decode_compound_hdr(xdr, &hdr);
1542     if (status)
1543         goto out;
1544     status = decode_sequence(xdr, &res->seq_res, rqstp);
1545     if (status)
1546         goto out;
1547     status = decode_putfh(xdr);
1548     if (status)
1549         goto out;
1550     status = decode_getxattr(xdr, res, rqstp);
1551 out:
1552     return status;
1553 }
1554 
1555 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
1556                     struct xdr_stream *xdr, const void *data)
1557 {
1558     const struct nfs42_listxattrsargs *args = data;
1559     struct compound_hdr hdr = {
1560         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1561     };
1562     uint32_t replen;
1563 
1564     encode_compound_hdr(xdr, req, &hdr);
1565     encode_sequence(xdr, &args->seq_args, &hdr);
1566     encode_putfh(xdr, args->fh, &hdr);
1567     replen = hdr.replen + op_decode_hdr_maxsz + 2 + 1;
1568     encode_listxattrs(xdr, args, &hdr);
1569 
1570     rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen);
1571 
1572     encode_nops(&hdr);
1573 }
1574 
1575 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
1576                    struct xdr_stream *xdr, void *data)
1577 {
1578     struct nfs42_listxattrsres *res = data;
1579     struct compound_hdr hdr;
1580     int status;
1581 
1582     xdr_set_scratch_page(xdr, res->scratch);
1583 
1584     status = decode_compound_hdr(xdr, &hdr);
1585     if (status)
1586         goto out;
1587     status = decode_sequence(xdr, &res->seq_res, rqstp);
1588     if (status)
1589         goto out;
1590     status = decode_putfh(xdr);
1591     if (status)
1592         goto out;
1593     status = decode_listxattrs(xdr, res);
1594 out:
1595     return status;
1596 }
1597 
1598 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
1599                      struct xdr_stream *xdr, const void *data)
1600 {
1601     const struct nfs42_removexattrargs *args = data;
1602     struct compound_hdr hdr = {
1603         .minorversion = nfs4_xdr_minorversion(&args->seq_args),
1604     };
1605 
1606     encode_compound_hdr(xdr, req, &hdr);
1607     encode_sequence(xdr, &args->seq_args, &hdr);
1608     encode_putfh(xdr, args->fh, &hdr);
1609     encode_removexattr(xdr, args->xattr_name, &hdr);
1610     encode_nops(&hdr);
1611 }
1612 
1613 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
1614                     struct xdr_stream *xdr, void *data)
1615 {
1616     struct nfs42_removexattrres *res = data;
1617     struct compound_hdr hdr;
1618     int status;
1619 
1620     status = decode_compound_hdr(xdr, &hdr);
1621     if (status)
1622         goto out;
1623     status = decode_sequence(xdr, &res->seq_res, req);
1624     if (status)
1625         goto out;
1626     status = decode_putfh(xdr);
1627     if (status)
1628         goto out;
1629 
1630     status = decode_removexattr(xdr, &res->cinfo);
1631 out:
1632     return status;
1633 }
1634 #endif
1635 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */