0001
0002
0003
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 + \
0012 2 )
0013 #define NFS42_WRITE_RES_SIZE (1 +\
0014 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
0015 2 + \
0016 1 + \
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 + \
0026 1 + \
0027 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
0028 #define decode_copy_maxsz (op_decode_hdr_maxsz + \
0029 NFS42_WRITE_RES_SIZE + \
0030 1 + \
0031 1 )
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 + \
0038 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
0039 #define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \
0040 3 + \
0041 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
0042 1 + \
0043 1 + \
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 + \
0051 2 + \
0052 2 )
0053 #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \
0054 1 + \
0055 1 + \
0056 2 * NFS42_READ_PLUS_SEGMENT_SIZE)
0057 #define encode_seek_maxsz (op_encode_hdr_maxsz + \
0058 encode_stateid_maxsz + \
0059 2 + \
0060 1 )
0061 #define decode_seek_maxsz (op_decode_hdr_maxsz + \
0062 1 + \
0063 1 + \
0064 2 + \
0065 2 )
0066 #define encode_io_info_maxsz 4
0067 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
0068 2 + \
0069 2 + \
0070 encode_stateid_maxsz + \
0071 encode_io_info_maxsz + \
0072 encode_io_info_maxsz + \
0073 1 + \
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 + 1 )
0078 #define encode_layouterror_maxsz (op_decode_hdr_maxsz + \
0079 2 + \
0080 2 + \
0081 encode_stateid_maxsz + \
0082 1 + \
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 + \
0088 2 + \
0089 2 )
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
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
0240
0241
0242
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);
0310 encode_uint32(xdr, args->sync);
0311 if (args->cp_src == NULL) {
0312 encode_uint32(xdr, 0);
0313 return;
0314 }
0315 encode_uint32(xdr, 1);
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
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
0495
0496
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
0549
0550
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
0568
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
0593
0594
0595
0596
0597
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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