1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com> 4 */ 5 #ifndef __LINUX_FS_NFS_NFS4_2XDR_H 6 #define __LINUX_FS_NFS_NFS4_2XDR_H 7 8 #include "nfs42.h" 9 10 #define encode_fallocate_maxsz (encode_stateid_maxsz + \ 11 2 /* offset */ + \ 12 2 /* length */) 13 #define NFS42_WRITE_RES_SIZE (1 /* wr_callback_id size */ +\ 14 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 15 2 /* wr_count */ + \ 16 1 /* wr_committed */ + \ 17 XDR_QUADLEN(NFS4_VERIFIER_SIZE)) 18 #define encode_allocate_maxsz (op_encode_hdr_maxsz + \ 19 encode_fallocate_maxsz) 20 #define decode_allocate_maxsz (op_decode_hdr_maxsz) 21 #define encode_copy_maxsz (op_encode_hdr_maxsz + \ 22 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 23 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 24 2 + 2 + 2 + 1 + 1 + 1 +\ 25 1 + /* One cnr_source_server */\ 26 1 + /* nl4_type */ \ 27 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) 28 #define decode_copy_maxsz (op_decode_hdr_maxsz + \ 29 NFS42_WRITE_RES_SIZE + \ 30 1 /* cr_consecutive */ + \ 31 1 /* cr_synchronous */) 32 #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \ 33 XDR_QUADLEN(NFS4_STATEID_SIZE)) 34 #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz) 35 #define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \ 36 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 37 1 + /* nl4_type */ \ 38 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) 39 #define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \ 40 3 + /* cnr_lease_time */\ 41 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 42 1 + /* Support 1 cnr_source_server */\ 43 1 + /* nl4_type */ \ 44 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) 45 #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ 46 encode_fallocate_maxsz) 47 #define decode_deallocate_maxsz (op_decode_hdr_maxsz) 48 #define encode_read_plus_maxsz (op_encode_hdr_maxsz + \ 49 encode_stateid_maxsz + 3) 50 #define NFS42_READ_PLUS_SEGMENT_SIZE (1 /* data_content4 */ + \ 51 2 /* data_info4.di_offset */ + \ 52 2 /* data_info4.di_length */) 53 #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \ 54 1 /* rpr_eof */ + \ 55 1 /* rpr_contents count */ + \ 56 2 * NFS42_READ_PLUS_SEGMENT_SIZE) 57 #define encode_seek_maxsz (op_encode_hdr_maxsz + \ 58 encode_stateid_maxsz + \ 59 2 /* offset */ + \ 60 1 /* whence */) 61 #define decode_seek_maxsz (op_decode_hdr_maxsz + \ 62 1 /* eof */ + \ 63 1 /* whence */ + \ 64 2 /* offset */ + \ 65 2 /* length */) 66 #define encode_io_info_maxsz 4 67 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \ 68 2 /* offset */ + \ 69 2 /* length */ + \ 70 encode_stateid_maxsz + \ 71 encode_io_info_maxsz + \ 72 encode_io_info_maxsz + \ 73 1 /* opaque devaddr4 length */ + \ 74 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE)) 75 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz) 76 #define encode_device_error_maxsz (XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \ 77 1 /* status */ + 1 /* opnum */) 78 #define encode_layouterror_maxsz (op_decode_hdr_maxsz + \ 79 2 /* offset */ + \ 80 2 /* length */ + \ 81 encode_stateid_maxsz + \ 82 1 /* Array size */ + \ 83 encode_device_error_maxsz) 84 #define decode_layouterror_maxsz (op_decode_hdr_maxsz) 85 #define encode_clone_maxsz (encode_stateid_maxsz + \ 86 encode_stateid_maxsz + \ 87 2 /* src offset */ + \ 88 2 /* dst offset */ + \ 89 2 /* count */) 90 #define decode_clone_maxsz (op_decode_hdr_maxsz) 91 92 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ 93 encode_sequence_maxsz + \ 94 encode_putfh_maxsz + \ 95 encode_allocate_maxsz + \ 96 encode_getattr_maxsz) 97 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ 98 decode_sequence_maxsz + \ 99 decode_putfh_maxsz + \ 100 decode_allocate_maxsz + \ 101 decode_getattr_maxsz) 102 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \ 103 encode_sequence_maxsz + \ 104 encode_putfh_maxsz + \ 105 encode_savefh_maxsz + \ 106 encode_putfh_maxsz + \ 107 encode_copy_maxsz + \ 108 encode_commit_maxsz) 109 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \ 110 decode_sequence_maxsz + \ 111 decode_putfh_maxsz + \ 112 decode_savefh_maxsz + \ 113 decode_putfh_maxsz + \ 114 decode_copy_maxsz + \ 115 decode_commit_maxsz) 116 #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \ 117 encode_sequence_maxsz + \ 118 encode_putfh_maxsz + \ 119 encode_offload_cancel_maxsz) 120 #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \ 121 decode_sequence_maxsz + \ 122 decode_putfh_maxsz + \ 123 decode_offload_cancel_maxsz) 124 #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \ 125 encode_putfh_maxsz + \ 126 encode_copy_notify_maxsz) 127 #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \ 128 decode_putfh_maxsz + \ 129 decode_copy_notify_maxsz) 130 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ 131 encode_sequence_maxsz + \ 132 encode_putfh_maxsz + \ 133 encode_deallocate_maxsz + \ 134 encode_getattr_maxsz) 135 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ 136 decode_sequence_maxsz + \ 137 decode_putfh_maxsz + \ 138 decode_deallocate_maxsz + \ 139 decode_getattr_maxsz) 140 #define NFS4_enc_read_plus_sz (compound_encode_hdr_maxsz + \ 141 encode_sequence_maxsz + \ 142 encode_putfh_maxsz + \ 143 encode_read_plus_maxsz) 144 #define NFS4_dec_read_plus_sz (compound_decode_hdr_maxsz + \ 145 decode_sequence_maxsz + \ 146 decode_putfh_maxsz + \ 147 decode_read_plus_maxsz) 148 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ 149 encode_sequence_maxsz + \ 150 encode_putfh_maxsz + \ 151 encode_seek_maxsz) 152 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \ 153 decode_sequence_maxsz + \ 154 decode_putfh_maxsz + \ 155 decode_seek_maxsz) 156 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \ 157 encode_sequence_maxsz + \ 158 encode_putfh_maxsz + \ 159 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz) 160 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \ 161 decode_sequence_maxsz + \ 162 decode_putfh_maxsz + \ 163 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz) 164 #define NFS4_enc_layouterror_sz (compound_encode_hdr_maxsz + \ 165 encode_sequence_maxsz + \ 166 encode_putfh_maxsz + \ 167 NFS42_LAYOUTERROR_MAX * \ 168 encode_layouterror_maxsz) 169 #define NFS4_dec_layouterror_sz (compound_decode_hdr_maxsz + \ 170 decode_sequence_maxsz + \ 171 decode_putfh_maxsz + \ 172 NFS42_LAYOUTERROR_MAX * \ 173 decode_layouterror_maxsz) 174 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \ 175 encode_sequence_maxsz + \ 176 encode_putfh_maxsz + \ 177 encode_savefh_maxsz + \ 178 encode_putfh_maxsz + \ 179 encode_clone_maxsz + \ 180 encode_getattr_maxsz) 181 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \ 182 decode_sequence_maxsz + \ 183 decode_putfh_maxsz + \ 184 decode_savefh_maxsz + \ 185 decode_putfh_maxsz + \ 186 decode_clone_maxsz + \ 187 decode_getattr_maxsz) 188 189 /* Not limited by NFS itself, limited by the generic xattr code */ 190 #define nfs4_xattr_name_maxsz XDR_QUADLEN(XATTR_NAME_MAX) 191 192 #define encode_getxattr_maxsz (op_encode_hdr_maxsz + 1 + \ 193 nfs4_xattr_name_maxsz) 194 #define decode_getxattr_maxsz (op_decode_hdr_maxsz + 1 + pagepad_maxsz) 195 #define encode_setxattr_maxsz (op_encode_hdr_maxsz + \ 196 1 + nfs4_xattr_name_maxsz + 1) 197 #define decode_setxattr_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz) 198 #define encode_listxattrs_maxsz (op_encode_hdr_maxsz + 2 + 1) 199 #define decode_listxattrs_maxsz (op_decode_hdr_maxsz + 2 + 1 + 1 + 1) 200 #define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \ 201 nfs4_xattr_name_maxsz) 202 #define decode_removexattr_maxsz (op_decode_hdr_maxsz + \ 203 decode_change_info_maxsz) 204 205 #define NFS4_enc_getxattr_sz (compound_encode_hdr_maxsz + \ 206 encode_sequence_maxsz + \ 207 encode_putfh_maxsz + \ 208 encode_getxattr_maxsz) 209 #define NFS4_dec_getxattr_sz (compound_decode_hdr_maxsz + \ 210 decode_sequence_maxsz + \ 211 decode_putfh_maxsz + \ 212 decode_getxattr_maxsz) 213 #define NFS4_enc_setxattr_sz (compound_encode_hdr_maxsz + \ 214 encode_sequence_maxsz + \ 215 encode_putfh_maxsz + \ 216 encode_setxattr_maxsz) 217 #define NFS4_dec_setxattr_sz (compound_decode_hdr_maxsz + \ 218 decode_sequence_maxsz + \ 219 decode_putfh_maxsz + \ 220 decode_setxattr_maxsz) 221 #define NFS4_enc_listxattrs_sz (compound_encode_hdr_maxsz + \ 222 encode_sequence_maxsz + \ 223 encode_putfh_maxsz + \ 224 encode_listxattrs_maxsz) 225 #define NFS4_dec_listxattrs_sz (compound_decode_hdr_maxsz + \ 226 decode_sequence_maxsz + \ 227 decode_putfh_maxsz + \ 228 decode_listxattrs_maxsz) 229 #define NFS4_enc_removexattr_sz (compound_encode_hdr_maxsz + \ 230 encode_sequence_maxsz + \ 231 encode_putfh_maxsz + \ 232 encode_removexattr_maxsz) 233 #define NFS4_dec_removexattr_sz (compound_decode_hdr_maxsz + \ 234 decode_sequence_maxsz + \ 235 decode_putfh_maxsz + \ 236 decode_removexattr_maxsz) 237 238 /* 239 * These values specify the maximum amount of data that is not 240 * associated with the extended attribute name or extended 241 * attribute list in the SETXATTR, GETXATTR and LISTXATTR 242 * respectively. 243 */ 244 const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 245 compound_encode_hdr_maxsz + 246 encode_sequence_maxsz + 247 encode_putfh_maxsz + 1 + 248 nfs4_xattr_name_maxsz) 249 * XDR_UNIT); 250 251 const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 252 compound_decode_hdr_maxsz + 253 decode_sequence_maxsz + 254 decode_putfh_maxsz + 1) * XDR_UNIT); 255 256 const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 257 compound_decode_hdr_maxsz + 258 decode_sequence_maxsz + 259 decode_putfh_maxsz + 3) * XDR_UNIT); 260 261 static void encode_fallocate(struct xdr_stream *xdr, 262 const struct nfs42_falloc_args *args) 263 { 264 encode_nfs4_stateid(xdr, &args->falloc_stateid); 265 encode_uint64(xdr, args->falloc_offset); 266 encode_uint64(xdr, args->falloc_length); 267 } 268 269 static void encode_allocate(struct xdr_stream *xdr, 270 const struct nfs42_falloc_args *args, 271 struct compound_hdr *hdr) 272 { 273 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr); 274 encode_fallocate(xdr, args); 275 } 276 277 static void encode_nl4_server(struct xdr_stream *xdr, 278 const struct nl4_server *ns) 279 { 280 encode_uint32(xdr, ns->nl4_type); 281 switch (ns->nl4_type) { 282 case NL4_NAME: 283 case NL4_URL: 284 encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str); 285 break; 286 case NL4_NETADDR: 287 encode_string(xdr, ns->u.nl4_addr.netid_len, 288 ns->u.nl4_addr.netid); 289 encode_string(xdr, ns->u.nl4_addr.addr_len, 290 ns->u.nl4_addr.addr); 291 break; 292 default: 293 WARN_ON_ONCE(1); 294 } 295 } 296 297 static void encode_copy(struct xdr_stream *xdr, 298 const struct nfs42_copy_args *args, 299 struct compound_hdr *hdr) 300 { 301 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr); 302 encode_nfs4_stateid(xdr, &args->src_stateid); 303 encode_nfs4_stateid(xdr, &args->dst_stateid); 304 305 encode_uint64(xdr, args->src_pos); 306 encode_uint64(xdr, args->dst_pos); 307 encode_uint64(xdr, args->count); 308 309 encode_uint32(xdr, 1); /* consecutive = true */ 310 encode_uint32(xdr, args->sync); 311 if (args->cp_src == NULL) { /* intra-ssc */ 312 encode_uint32(xdr, 0); /* no src server list */ 313 return; 314 } 315 encode_uint32(xdr, 1); /* supporting 1 server */ 316 encode_nl4_server(xdr, args->cp_src); 317 } 318 319 static void encode_offload_cancel(struct xdr_stream *xdr, 320 const struct nfs42_offload_status_args *args, 321 struct compound_hdr *hdr) 322 { 323 encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr); 324 encode_nfs4_stateid(xdr, &args->osa_stateid); 325 } 326 327 static void encode_copy_notify(struct xdr_stream *xdr, 328 const struct nfs42_copy_notify_args *args, 329 struct compound_hdr *hdr) 330 { 331 encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr); 332 encode_nfs4_stateid(xdr, &args->cna_src_stateid); 333 encode_nl4_server(xdr, &args->cna_dst); 334 } 335 336 static void encode_deallocate(struct xdr_stream *xdr, 337 const struct nfs42_falloc_args *args, 338 struct compound_hdr *hdr) 339 { 340 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr); 341 encode_fallocate(xdr, args); 342 } 343 344 static void encode_read_plus(struct xdr_stream *xdr, 345 const struct nfs_pgio_args *args, 346 struct compound_hdr *hdr) 347 { 348 encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr); 349 encode_nfs4_stateid(xdr, &args->stateid); 350 encode_uint64(xdr, args->offset); 351 encode_uint32(xdr, args->count); 352 } 353 354 static void encode_seek(struct xdr_stream *xdr, 355 const struct nfs42_seek_args *args, 356 struct compound_hdr *hdr) 357 { 358 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr); 359 encode_nfs4_stateid(xdr, &args->sa_stateid); 360 encode_uint64(xdr, args->sa_offset); 361 encode_uint32(xdr, args->sa_what); 362 } 363 364 static void encode_layoutstats(struct xdr_stream *xdr, 365 const struct nfs42_layoutstat_args *args, 366 struct nfs42_layoutstat_devinfo *devinfo, 367 struct compound_hdr *hdr) 368 { 369 __be32 *p; 370 371 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr); 372 p = reserve_space(xdr, 8 + 8); 373 p = xdr_encode_hyper(p, devinfo->offset); 374 p = xdr_encode_hyper(p, devinfo->length); 375 encode_nfs4_stateid(xdr, &args->stateid); 376 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4); 377 p = xdr_encode_hyper(p, devinfo->read_count); 378 p = xdr_encode_hyper(p, devinfo->read_bytes); 379 p = xdr_encode_hyper(p, devinfo->write_count); 380 p = xdr_encode_hyper(p, devinfo->write_bytes); 381 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data, 382 NFS4_DEVICEID4_SIZE); 383 /* Encode layoutupdate4 */ 384 *p++ = cpu_to_be32(devinfo->layout_type); 385 if (devinfo->ld_private.ops) 386 devinfo->ld_private.ops->encode(xdr, args, 387 &devinfo->ld_private); 388 else 389 encode_uint32(xdr, 0); 390 } 391 392 static void encode_clone(struct xdr_stream *xdr, 393 const struct nfs42_clone_args *args, 394 struct compound_hdr *hdr) 395 { 396 __be32 *p; 397 398 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr); 399 encode_nfs4_stateid(xdr, &args->src_stateid); 400 encode_nfs4_stateid(xdr, &args->dst_stateid); 401 p = reserve_space(xdr, 3*8); 402 p = xdr_encode_hyper(p, args->src_offset); 403 p = xdr_encode_hyper(p, args->dst_offset); 404 xdr_encode_hyper(p, args->count); 405 } 406 407 static void encode_device_error(struct xdr_stream *xdr, 408 const struct nfs42_device_error *error) 409 { 410 __be32 *p; 411 412 p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4); 413 p = xdr_encode_opaque_fixed(p, error->dev_id.data, 414 NFS4_DEVICEID4_SIZE); 415 *p++ = cpu_to_be32(error->status); 416 *p = cpu_to_be32(error->opnum); 417 } 418 419 static void encode_layouterror(struct xdr_stream *xdr, 420 const struct nfs42_layout_error *args, 421 struct compound_hdr *hdr) 422 { 423 __be32 *p; 424 425 encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr); 426 p = reserve_space(xdr, 8 + 8); 427 p = xdr_encode_hyper(p, args->offset); 428 p = xdr_encode_hyper(p, args->length); 429 encode_nfs4_stateid(xdr, &args->stateid); 430 p = reserve_space(xdr, 4); 431 *p = cpu_to_be32(1); 432 encode_device_error(xdr, &args->errors[0]); 433 } 434 435 static void encode_setxattr(struct xdr_stream *xdr, 436 const struct nfs42_setxattrargs *arg, 437 struct compound_hdr *hdr) 438 { 439 __be32 *p; 440 441 BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE); 442 BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE); 443 444 encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr); 445 p = reserve_space(xdr, 4); 446 *p = cpu_to_be32(arg->xattr_flags); 447 encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name); 448 p = reserve_space(xdr, 4); 449 *p = cpu_to_be32(arg->xattr_len); 450 if (arg->xattr_len) 451 xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len); 452 } 453 454 static int decode_setxattr(struct xdr_stream *xdr, 455 struct nfs4_change_info *cinfo) 456 { 457 int status; 458 459 status = decode_op_hdr(xdr, OP_SETXATTR); 460 if (status) 461 goto out; 462 status = decode_change_info(xdr, cinfo); 463 out: 464 return status; 465 } 466 467 468 static void encode_getxattr(struct xdr_stream *xdr, const char *name, 469 struct compound_hdr *hdr) 470 { 471 encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr); 472 encode_string(xdr, strlen(name), name); 473 } 474 475 static int decode_getxattr(struct xdr_stream *xdr, 476 struct nfs42_getxattrres *res, 477 struct rpc_rqst *req) 478 { 479 int status; 480 __be32 *p; 481 u32 len, rdlen; 482 483 status = decode_op_hdr(xdr, OP_GETXATTR); 484 if (status) 485 return status; 486 487 p = xdr_inline_decode(xdr, 4); 488 if (unlikely(!p)) 489 return -EIO; 490 491 len = be32_to_cpup(p); 492 493 /* 494 * Only check against the page length here. The actual 495 * requested length may be smaller, but that is only 496 * checked against after possibly caching a valid reply. 497 */ 498 if (len > req->rq_rcv_buf.page_len) 499 return -ERANGE; 500 501 res->xattr_len = len; 502 503 if (len > 0) { 504 rdlen = xdr_read_pages(xdr, len); 505 if (rdlen < len) 506 return -EIO; 507 } 508 509 return 0; 510 } 511 512 static void encode_removexattr(struct xdr_stream *xdr, const char *name, 513 struct compound_hdr *hdr) 514 { 515 encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr); 516 encode_string(xdr, strlen(name), name); 517 } 518 519 520 static int decode_removexattr(struct xdr_stream *xdr, 521 struct nfs4_change_info *cinfo) 522 { 523 int status; 524 525 status = decode_op_hdr(xdr, OP_REMOVEXATTR); 526 if (status) 527 goto out; 528 529 status = decode_change_info(xdr, cinfo); 530 out: 531 return status; 532 } 533 534 static void encode_listxattrs(struct xdr_stream *xdr, 535 const struct nfs42_listxattrsargs *arg, 536 struct compound_hdr *hdr) 537 { 538 __be32 *p; 539 540 encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr); 541 542 p = reserve_space(xdr, 12); 543 if (unlikely(!p)) 544 return; 545 546 p = xdr_encode_hyper(p, arg->cookie); 547 /* 548 * RFC 8276 says to specify the full max length of the LISTXATTRS 549 * XDR reply. Count is set to the XDR length of the names array 550 * plus the EOF marker. So, add the cookie and the names count. 551 */ 552 *p = cpu_to_be32(arg->count + 8 + 4); 553 } 554 555 static int decode_listxattrs(struct xdr_stream *xdr, 556 struct nfs42_listxattrsres *res) 557 { 558 int status; 559 __be32 *p; 560 u32 count, len, ulen; 561 size_t left, copied; 562 char *buf; 563 564 status = decode_op_hdr(xdr, OP_LISTXATTRS); 565 if (status) { 566 /* 567 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL 568 * should be translated to ERANGE. 569 */ 570 if (status == -ETOOSMALL) 571 status = -ERANGE; 572 /* 573 * Special case: for LISTXATTRS, NFS4ERR_NOXATTR 574 * should be translated to success with zero-length reply. 575 */ 576 if (status == -ENODATA) { 577 res->eof = true; 578 status = 0; 579 } 580 goto out; 581 } 582 583 p = xdr_inline_decode(xdr, 8); 584 if (unlikely(!p)) 585 return -EIO; 586 587 xdr_decode_hyper(p, &res->cookie); 588 589 p = xdr_inline_decode(xdr, 4); 590 if (unlikely(!p)) 591 return -EIO; 592 593 left = res->xattr_len; 594 buf = res->xattr_buf; 595 596 count = be32_to_cpup(p); 597 copied = 0; 598 599 /* 600 * We have asked for enough room to encode the maximum number 601 * of possible attribute names, so everything should fit. 602 * 603 * But, don't rely on that assumption. Just decode entries 604 * until they don't fit anymore, just in case the server did 605 * something odd. 606 */ 607 while (count--) { 608 p = xdr_inline_decode(xdr, 4); 609 if (unlikely(!p)) 610 return -EIO; 611 612 len = be32_to_cpup(p); 613 if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) { 614 status = -ERANGE; 615 goto out; 616 } 617 618 p = xdr_inline_decode(xdr, len); 619 if (unlikely(!p)) 620 return -EIO; 621 622 ulen = len + XATTR_USER_PREFIX_LEN + 1; 623 if (buf) { 624 if (ulen > left) { 625 status = -ERANGE; 626 goto out; 627 } 628 629 memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); 630 memcpy(buf + XATTR_USER_PREFIX_LEN, p, len); 631 632 buf[ulen - 1] = 0; 633 buf += ulen; 634 left -= ulen; 635 } 636 copied += ulen; 637 } 638 639 p = xdr_inline_decode(xdr, 4); 640 if (unlikely(!p)) 641 return -EIO; 642 643 res->eof = be32_to_cpup(p); 644 res->copied = copied; 645 646 out: 647 if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX) 648 status = -E2BIG; 649 650 return status; 651 } 652 653 /* 654 * Encode ALLOCATE request 655 */ 656 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, 657 struct xdr_stream *xdr, 658 const void *data) 659 { 660 const struct nfs42_falloc_args *args = data; 661 struct compound_hdr hdr = { 662 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 663 }; 664 665 encode_compound_hdr(xdr, req, &hdr); 666 encode_sequence(xdr, &args->seq_args, &hdr); 667 encode_putfh(xdr, args->falloc_fh, &hdr); 668 encode_allocate(xdr, args, &hdr); 669 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 670 encode_nops(&hdr); 671 } 672 673 static void encode_copy_commit(struct xdr_stream *xdr, 674 const struct nfs42_copy_args *args, 675 struct compound_hdr *hdr) 676 { 677 __be32 *p; 678 679 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr); 680 p = reserve_space(xdr, 12); 681 p = xdr_encode_hyper(p, args->dst_pos); 682 *p = cpu_to_be32(args->count); 683 } 684 685 /* 686 * Encode COPY request 687 */ 688 static void nfs4_xdr_enc_copy(struct rpc_rqst *req, 689 struct xdr_stream *xdr, 690 const void *data) 691 { 692 const struct nfs42_copy_args *args = data; 693 struct compound_hdr hdr = { 694 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 695 }; 696 697 encode_compound_hdr(xdr, req, &hdr); 698 encode_sequence(xdr, &args->seq_args, &hdr); 699 encode_putfh(xdr, args->src_fh, &hdr); 700 encode_savefh(xdr, &hdr); 701 encode_putfh(xdr, args->dst_fh, &hdr); 702 encode_copy(xdr, args, &hdr); 703 if (args->sync) 704 encode_copy_commit(xdr, args, &hdr); 705 encode_nops(&hdr); 706 } 707 708 /* 709 * Encode OFFLOAD_CANEL request 710 */ 711 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, 712 struct xdr_stream *xdr, 713 const void *data) 714 { 715 const struct nfs42_offload_status_args *args = data; 716 struct compound_hdr hdr = { 717 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args), 718 }; 719 720 encode_compound_hdr(xdr, req, &hdr); 721 encode_sequence(xdr, &args->osa_seq_args, &hdr); 722 encode_putfh(xdr, args->osa_src_fh, &hdr); 723 encode_offload_cancel(xdr, args, &hdr); 724 encode_nops(&hdr); 725 } 726 727 /* 728 * Encode COPY_NOTIFY request 729 */ 730 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req, 731 struct xdr_stream *xdr, 732 const void *data) 733 { 734 const struct nfs42_copy_notify_args *args = data; 735 struct compound_hdr hdr = { 736 .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args), 737 }; 738 739 encode_compound_hdr(xdr, req, &hdr); 740 encode_sequence(xdr, &args->cna_seq_args, &hdr); 741 encode_putfh(xdr, args->cna_src_fh, &hdr); 742 encode_copy_notify(xdr, args, &hdr); 743 encode_nops(&hdr); 744 } 745 746 /* 747 * Encode DEALLOCATE request 748 */ 749 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, 750 struct xdr_stream *xdr, 751 const void *data) 752 { 753 const struct nfs42_falloc_args *args = data; 754 struct compound_hdr hdr = { 755 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 756 }; 757 758 encode_compound_hdr(xdr, req, &hdr); 759 encode_sequence(xdr, &args->seq_args, &hdr); 760 encode_putfh(xdr, args->falloc_fh, &hdr); 761 encode_deallocate(xdr, args, &hdr); 762 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 763 encode_nops(&hdr); 764 } 765 766 /* 767 * Encode READ_PLUS request 768 */ 769 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req, 770 struct xdr_stream *xdr, 771 const void *data) 772 { 773 const struct nfs_pgio_args *args = data; 774 struct compound_hdr hdr = { 775 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 776 }; 777 778 encode_compound_hdr(xdr, req, &hdr); 779 encode_sequence(xdr, &args->seq_args, &hdr); 780 encode_putfh(xdr, args->fh, &hdr); 781 encode_read_plus(xdr, args, &hdr); 782 783 rpc_prepare_reply_pages(req, args->pages, args->pgbase, 784 args->count, hdr.replen); 785 encode_nops(&hdr); 786 } 787 788 /* 789 * Encode SEEK request 790 */ 791 static void nfs4_xdr_enc_seek(struct rpc_rqst *req, 792 struct xdr_stream *xdr, 793 const void *data) 794 { 795 const struct nfs42_seek_args *args = data; 796 struct compound_hdr hdr = { 797 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 798 }; 799 800 encode_compound_hdr(xdr, req, &hdr); 801 encode_sequence(xdr, &args->seq_args, &hdr); 802 encode_putfh(xdr, args->sa_fh, &hdr); 803 encode_seek(xdr, args, &hdr); 804 encode_nops(&hdr); 805 } 806 807 /* 808 * Encode LAYOUTSTATS request 809 */ 810 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, 811 struct xdr_stream *xdr, 812 const void *data) 813 { 814 const struct nfs42_layoutstat_args *args = data; 815 int i; 816 817 struct compound_hdr hdr = { 818 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 819 }; 820 821 encode_compound_hdr(xdr, req, &hdr); 822 encode_sequence(xdr, &args->seq_args, &hdr); 823 encode_putfh(xdr, args->fh, &hdr); 824 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 825 for (i = 0; i < args->num_dev; i++) 826 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); 827 encode_nops(&hdr); 828 } 829 830 /* 831 * Encode CLONE request 832 */ 833 static void nfs4_xdr_enc_clone(struct rpc_rqst *req, 834 struct xdr_stream *xdr, 835 const void *data) 836 { 837 const struct nfs42_clone_args *args = data; 838 struct compound_hdr hdr = { 839 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 840 }; 841 842 encode_compound_hdr(xdr, req, &hdr); 843 encode_sequence(xdr, &args->seq_args, &hdr); 844 encode_putfh(xdr, args->src_fh, &hdr); 845 encode_savefh(xdr, &hdr); 846 encode_putfh(xdr, args->dst_fh, &hdr); 847 encode_clone(xdr, args, &hdr); 848 encode_getfattr(xdr, args->dst_bitmask, &hdr); 849 encode_nops(&hdr); 850 } 851 852 /* 853 * Encode LAYOUTERROR request 854 */ 855 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req, 856 struct xdr_stream *xdr, 857 const void *data) 858 { 859 const struct nfs42_layouterror_args *args = data; 860 struct compound_hdr hdr = { 861 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 862 }; 863 int i; 864 865 encode_compound_hdr(xdr, req, &hdr); 866 encode_sequence(xdr, &args->seq_args, &hdr); 867 encode_putfh(xdr, NFS_FH(args->inode), &hdr); 868 for (i = 0; i < args->num_errors; i++) 869 encode_layouterror(xdr, &args->errors[i], &hdr); 870 encode_nops(&hdr); 871 } 872 873 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 874 { 875 return decode_op_hdr(xdr, OP_ALLOCATE); 876 } 877 878 static int decode_write_response(struct xdr_stream *xdr, 879 struct nfs42_write_res *res) 880 { 881 __be32 *p; 882 int status, count; 883 884 p = xdr_inline_decode(xdr, 4); 885 if (unlikely(!p)) 886 return -EIO; 887 count = be32_to_cpup(p); 888 if (count > 1) 889 return -EREMOTEIO; 890 else if (count == 1) { 891 status = decode_opaque_fixed(xdr, &res->stateid, 892 NFS4_STATEID_SIZE); 893 if (unlikely(status)) 894 return -EIO; 895 } 896 p = xdr_inline_decode(xdr, 8 + 4); 897 if (unlikely(!p)) 898 return -EIO; 899 p = xdr_decode_hyper(p, &res->count); 900 res->verifier.committed = be32_to_cpup(p); 901 return decode_verifier(xdr, &res->verifier.verifier); 902 } 903 904 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns) 905 { 906 struct nfs42_netaddr *naddr; 907 uint32_t dummy; 908 char *dummy_str; 909 __be32 *p; 910 int status; 911 912 /* nl_type */ 913 p = xdr_inline_decode(xdr, 4); 914 if (unlikely(!p)) 915 return -EIO; 916 ns->nl4_type = be32_to_cpup(p); 917 switch (ns->nl4_type) { 918 case NL4_NAME: 919 case NL4_URL: 920 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 921 if (unlikely(status)) 922 return status; 923 if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) 924 return -EIO; 925 memcpy(&ns->u.nl4_str, dummy_str, dummy); 926 ns->u.nl4_str_sz = dummy; 927 break; 928 case NL4_NETADDR: 929 naddr = &ns->u.nl4_addr; 930 931 /* netid string */ 932 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 933 if (unlikely(status)) 934 return status; 935 if (unlikely(dummy > RPCBIND_MAXNETIDLEN)) 936 return -EIO; 937 naddr->netid_len = dummy; 938 memcpy(naddr->netid, dummy_str, naddr->netid_len); 939 940 /* uaddr string */ 941 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 942 if (unlikely(status)) 943 return status; 944 if (unlikely(dummy > RPCBIND_MAXUADDRLEN)) 945 return -EIO; 946 naddr->addr_len = dummy; 947 memcpy(naddr->addr, dummy_str, naddr->addr_len); 948 break; 949 default: 950 WARN_ON_ONCE(1); 951 return -EIO; 952 } 953 return 0; 954 } 955 956 static int decode_copy_requirements(struct xdr_stream *xdr, 957 struct nfs42_copy_res *res) { 958 __be32 *p; 959 960 p = xdr_inline_decode(xdr, 4 + 4); 961 if (unlikely(!p)) 962 return -EIO; 963 964 res->consecutive = be32_to_cpup(p++); 965 res->synchronous = be32_to_cpup(p++); 966 return 0; 967 } 968 969 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) 970 { 971 int status; 972 973 status = decode_op_hdr(xdr, OP_COPY); 974 if (status == NFS4ERR_OFFLOAD_NO_REQS) { 975 status = decode_copy_requirements(xdr, res); 976 if (status) 977 return status; 978 return NFS4ERR_OFFLOAD_NO_REQS; 979 } else if (status) 980 return status; 981 982 status = decode_write_response(xdr, &res->write_res); 983 if (status) 984 return status; 985 986 return decode_copy_requirements(xdr, res); 987 } 988 989 static int decode_offload_cancel(struct xdr_stream *xdr, 990 struct nfs42_offload_status_res *res) 991 { 992 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); 993 } 994 995 static int decode_copy_notify(struct xdr_stream *xdr, 996 struct nfs42_copy_notify_res *res) 997 { 998 __be32 *p; 999 int status, count; 1000 1001 status = decode_op_hdr(xdr, OP_COPY_NOTIFY); 1002 if (status) 1003 return status; 1004 /* cnr_lease_time */ 1005 p = xdr_inline_decode(xdr, 12); 1006 if (unlikely(!p)) 1007 return -EIO; 1008 p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds); 1009 res->cnr_lease_time.nseconds = be32_to_cpup(p); 1010 1011 status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE); 1012 if (unlikely(status)) 1013 return -EIO; 1014 1015 /* number of source addresses */ 1016 p = xdr_inline_decode(xdr, 4); 1017 if (unlikely(!p)) 1018 return -EIO; 1019 1020 count = be32_to_cpup(p); 1021 if (count > 1) 1022 pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n", 1023 __func__, count); 1024 1025 status = decode_nl4_server(xdr, &res->cnr_src); 1026 if (unlikely(status)) 1027 return -EIO; 1028 return 0; 1029 } 1030 1031 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 1032 { 1033 return decode_op_hdr(xdr, OP_DEALLOCATE); 1034 } 1035 1036 struct read_plus_segment { 1037 enum data_content4 type; 1038 uint64_t offset; 1039 union { 1040 struct { 1041 uint64_t length; 1042 } hole; 1043 1044 struct { 1045 uint32_t length; 1046 unsigned int from; 1047 } data; 1048 }; 1049 }; 1050 1051 static inline uint64_t read_plus_segment_length(struct read_plus_segment *seg) 1052 { 1053 return seg->type == NFS4_CONTENT_DATA ? seg->data.length : seg->hole.length; 1054 } 1055 1056 static int decode_read_plus_segment(struct xdr_stream *xdr, 1057 struct read_plus_segment *seg) 1058 { 1059 __be32 *p; 1060 1061 p = xdr_inline_decode(xdr, 4); 1062 if (!p) 1063 return -EIO; 1064 seg->type = be32_to_cpup(p++); 1065 1066 p = xdr_inline_decode(xdr, seg->type == NFS4_CONTENT_DATA ? 12 : 16); 1067 if (!p) 1068 return -EIO; 1069 p = xdr_decode_hyper(p, &seg->offset); 1070 1071 if (seg->type == NFS4_CONTENT_DATA) { 1072 struct xdr_buf buf; 1073 uint32_t len = be32_to_cpup(p); 1074 1075 seg->data.length = len; 1076 seg->data.from = xdr_stream_pos(xdr); 1077 1078 if (!xdr_stream_subsegment(xdr, &buf, xdr_align_size(len))) 1079 return -EIO; 1080 } else if (seg->type == NFS4_CONTENT_HOLE) { 1081 xdr_decode_hyper(p, &seg->hole.length); 1082 } else 1083 return -EINVAL; 1084 return 0; 1085 } 1086 1087 static int process_read_plus_segment(struct xdr_stream *xdr, 1088 struct nfs_pgio_args *args, 1089 struct nfs_pgio_res *res, 1090 struct read_plus_segment *seg) 1091 { 1092 unsigned long offset = seg->offset; 1093 unsigned long length = read_plus_segment_length(seg); 1094 unsigned int bufpos; 1095 1096 if (offset + length < args->offset) 1097 return 0; 1098 else if (offset > args->offset + args->count) { 1099 res->eof = 0; 1100 return 0; 1101 } else if (offset < args->offset) { 1102 length -= (args->offset - offset); 1103 offset = args->offset; 1104 } else if (offset + length > args->offset + args->count) { 1105 length = (args->offset + args->count) - offset; 1106 res->eof = 0; 1107 } 1108 1109 bufpos = xdr->buf->head[0].iov_len + (offset - args->offset); 1110 if (seg->type == NFS4_CONTENT_HOLE) 1111 return xdr_stream_zero(xdr, bufpos, length); 1112 else 1113 return xdr_stream_move_subsegment(xdr, seg->data.from, bufpos, length); 1114 } 1115 1116 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) 1117 { 1118 struct nfs_pgio_header *hdr = 1119 container_of(res, struct nfs_pgio_header, res); 1120 struct nfs_pgio_args *args = &hdr->args; 1121 uint32_t segments; 1122 struct read_plus_segment *segs; 1123 int status, i; 1124 char scratch_buf[16]; 1125 __be32 *p; 1126 1127 status = decode_op_hdr(xdr, OP_READ_PLUS); 1128 if (status) 1129 return status; 1130 1131 p = xdr_inline_decode(xdr, 4 + 4); 1132 if (unlikely(!p)) 1133 return -EIO; 1134 1135 res->count = 0; 1136 res->eof = be32_to_cpup(p++); 1137 segments = be32_to_cpup(p++); 1138 if (segments == 0) 1139 return status; 1140 1141 segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL); 1142 if (!segs) 1143 return -ENOMEM; 1144 1145 xdr_set_scratch_buffer(xdr, &scratch_buf, 32); 1146 status = -EIO; 1147 for (i = 0; i < segments; i++) { 1148 status = decode_read_plus_segment(xdr, &segs[i]); 1149 if (status < 0) 1150 goto out; 1151 } 1152 1153 xdr_set_pagelen(xdr, xdr_align_size(args->count)); 1154 for (i = segments; i > 0; i--) 1155 res->count += process_read_plus_segment(xdr, args, res, &segs[i-1]); 1156 status = 0; 1157 1158 out: 1159 kfree(segs); 1160 return status; 1161 } 1162 1163 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) 1164 { 1165 int status; 1166 __be32 *p; 1167 1168 status = decode_op_hdr(xdr, OP_SEEK); 1169 if (status) 1170 return status; 1171 1172 p = xdr_inline_decode(xdr, 4 + 8); 1173 if (unlikely(!p)) 1174 return -EIO; 1175 1176 res->sr_eof = be32_to_cpup(p++); 1177 p = xdr_decode_hyper(p, &res->sr_offset); 1178 return 0; 1179 } 1180 1181 static int decode_layoutstats(struct xdr_stream *xdr) 1182 { 1183 return decode_op_hdr(xdr, OP_LAYOUTSTATS); 1184 } 1185 1186 static int decode_clone(struct xdr_stream *xdr) 1187 { 1188 return decode_op_hdr(xdr, OP_CLONE); 1189 } 1190 1191 static int decode_layouterror(struct xdr_stream *xdr) 1192 { 1193 return decode_op_hdr(xdr, OP_LAYOUTERROR); 1194 } 1195 1196 /* 1197 * Decode ALLOCATE request 1198 */ 1199 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, 1200 struct xdr_stream *xdr, 1201 void *data) 1202 { 1203 struct nfs42_falloc_res *res = data; 1204 struct compound_hdr hdr; 1205 int status; 1206 1207 status = decode_compound_hdr(xdr, &hdr); 1208 if (status) 1209 goto out; 1210 status = decode_sequence(xdr, &res->seq_res, rqstp); 1211 if (status) 1212 goto out; 1213 status = decode_putfh(xdr); 1214 if (status) 1215 goto out; 1216 status = decode_allocate(xdr, res); 1217 if (status) 1218 goto out; 1219 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 1220 out: 1221 return status; 1222 } 1223 1224 /* 1225 * Decode COPY response 1226 */ 1227 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp, 1228 struct xdr_stream *xdr, 1229 void *data) 1230 { 1231 struct nfs42_copy_res *res = data; 1232 struct compound_hdr hdr; 1233 int status; 1234 1235 status = decode_compound_hdr(xdr, &hdr); 1236 if (status) 1237 goto out; 1238 status = decode_sequence(xdr, &res->seq_res, rqstp); 1239 if (status) 1240 goto out; 1241 status = decode_putfh(xdr); 1242 if (status) 1243 goto out; 1244 status = decode_savefh(xdr); 1245 if (status) 1246 goto out; 1247 status = decode_putfh(xdr); 1248 if (status) 1249 goto out; 1250 status = decode_copy(xdr, res); 1251 if (status) 1252 goto out; 1253 if (res->commit_res.verf) 1254 status = decode_commit(xdr, &res->commit_res); 1255 out: 1256 return status; 1257 } 1258 1259 /* 1260 * Decode OFFLOAD_CANCEL response 1261 */ 1262 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp, 1263 struct xdr_stream *xdr, 1264 void *data) 1265 { 1266 struct nfs42_offload_status_res *res = data; 1267 struct compound_hdr hdr; 1268 int status; 1269 1270 status = decode_compound_hdr(xdr, &hdr); 1271 if (status) 1272 goto out; 1273 status = decode_sequence(xdr, &res->osr_seq_res, rqstp); 1274 if (status) 1275 goto out; 1276 status = decode_putfh(xdr); 1277 if (status) 1278 goto out; 1279 status = decode_offload_cancel(xdr, res); 1280 1281 out: 1282 return status; 1283 } 1284 1285 /* 1286 * Decode COPY_NOTIFY response 1287 */ 1288 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp, 1289 struct xdr_stream *xdr, 1290 void *data) 1291 { 1292 struct nfs42_copy_notify_res *res = data; 1293 struct compound_hdr hdr; 1294 int status; 1295 1296 status = decode_compound_hdr(xdr, &hdr); 1297 if (status) 1298 goto out; 1299 status = decode_sequence(xdr, &res->cnr_seq_res, rqstp); 1300 if (status) 1301 goto out; 1302 status = decode_putfh(xdr); 1303 if (status) 1304 goto out; 1305 status = decode_copy_notify(xdr, res); 1306 1307 out: 1308 return status; 1309 } 1310 1311 /* 1312 * Decode DEALLOCATE request 1313 */ 1314 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, 1315 struct xdr_stream *xdr, 1316 void *data) 1317 { 1318 struct nfs42_falloc_res *res = data; 1319 struct compound_hdr hdr; 1320 int status; 1321 1322 status = decode_compound_hdr(xdr, &hdr); 1323 if (status) 1324 goto out; 1325 status = decode_sequence(xdr, &res->seq_res, rqstp); 1326 if (status) 1327 goto out; 1328 status = decode_putfh(xdr); 1329 if (status) 1330 goto out; 1331 status = decode_deallocate(xdr, res); 1332 if (status) 1333 goto out; 1334 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 1335 out: 1336 return status; 1337 } 1338 1339 /* 1340 * Decode READ_PLUS request 1341 */ 1342 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp, 1343 struct xdr_stream *xdr, 1344 void *data) 1345 { 1346 struct nfs_pgio_res *res = data; 1347 struct compound_hdr hdr; 1348 int status; 1349 1350 status = decode_compound_hdr(xdr, &hdr); 1351 if (status) 1352 goto out; 1353 status = decode_sequence(xdr, &res->seq_res, rqstp); 1354 if (status) 1355 goto out; 1356 status = decode_putfh(xdr); 1357 if (status) 1358 goto out; 1359 status = decode_read_plus(xdr, res); 1360 if (!status) 1361 status = res->count; 1362 out: 1363 return status; 1364 } 1365 1366 /* 1367 * Decode SEEK request 1368 */ 1369 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, 1370 struct xdr_stream *xdr, 1371 void *data) 1372 { 1373 struct nfs42_seek_res *res = data; 1374 struct compound_hdr hdr; 1375 int status; 1376 1377 status = decode_compound_hdr(xdr, &hdr); 1378 if (status) 1379 goto out; 1380 status = decode_sequence(xdr, &res->seq_res, rqstp); 1381 if (status) 1382 goto out; 1383 status = decode_putfh(xdr); 1384 if (status) 1385 goto out; 1386 status = decode_seek(xdr, res); 1387 out: 1388 return status; 1389 } 1390 1391 /* 1392 * Decode LAYOUTSTATS request 1393 */ 1394 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, 1395 struct xdr_stream *xdr, 1396 void *data) 1397 { 1398 struct nfs42_layoutstat_res *res = data; 1399 struct compound_hdr hdr; 1400 int status, i; 1401 1402 status = decode_compound_hdr(xdr, &hdr); 1403 if (status) 1404 goto out; 1405 status = decode_sequence(xdr, &res->seq_res, rqstp); 1406 if (status) 1407 goto out; 1408 status = decode_putfh(xdr); 1409 if (status) 1410 goto out; 1411 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 1412 for (i = 0; i < res->num_dev; i++) { 1413 status = decode_layoutstats(xdr); 1414 if (status) 1415 goto out; 1416 } 1417 out: 1418 res->rpc_status = status; 1419 return status; 1420 } 1421 1422 /* 1423 * Decode CLONE request 1424 */ 1425 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp, 1426 struct xdr_stream *xdr, 1427 void *data) 1428 { 1429 struct nfs42_clone_res *res = data; 1430 struct compound_hdr hdr; 1431 int status; 1432 1433 status = decode_compound_hdr(xdr, &hdr); 1434 if (status) 1435 goto out; 1436 status = decode_sequence(xdr, &res->seq_res, rqstp); 1437 if (status) 1438 goto out; 1439 status = decode_putfh(xdr); 1440 if (status) 1441 goto out; 1442 status = decode_savefh(xdr); 1443 if (status) 1444 goto out; 1445 status = decode_putfh(xdr); 1446 if (status) 1447 goto out; 1448 status = decode_clone(xdr); 1449 if (status) 1450 goto out; 1451 decode_getfattr(xdr, res->dst_fattr, res->server); 1452 out: 1453 res->rpc_status = status; 1454 return status; 1455 } 1456 1457 /* 1458 * Decode LAYOUTERROR request 1459 */ 1460 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp, 1461 struct xdr_stream *xdr, 1462 void *data) 1463 { 1464 struct nfs42_layouterror_res *res = data; 1465 struct compound_hdr hdr; 1466 int status, i; 1467 1468 status = decode_compound_hdr(xdr, &hdr); 1469 if (status) 1470 goto out; 1471 status = decode_sequence(xdr, &res->seq_res, rqstp); 1472 if (status) 1473 goto out; 1474 status = decode_putfh(xdr); 1475 1476 for (i = 0; i < res->num_errors && status == 0; i++) 1477 status = decode_layouterror(xdr); 1478 out: 1479 res->rpc_status = status; 1480 return status; 1481 } 1482 1483 #ifdef CONFIG_NFS_V4_2 1484 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 1485 const void *data) 1486 { 1487 const struct nfs42_setxattrargs *args = data; 1488 struct compound_hdr hdr = { 1489 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 1490 }; 1491 1492 encode_compound_hdr(xdr, req, &hdr); 1493 encode_sequence(xdr, &args->seq_args, &hdr); 1494 encode_putfh(xdr, args->fh, &hdr); 1495 encode_setxattr(xdr, args, &hdr); 1496 encode_nops(&hdr); 1497 } 1498 1499 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 1500 void *data) 1501 { 1502 struct nfs42_setxattrres *res = data; 1503 struct compound_hdr hdr; 1504 int status; 1505 1506 status = decode_compound_hdr(xdr, &hdr); 1507 if (status) 1508 goto out; 1509 status = decode_sequence(xdr, &res->seq_res, req); 1510 if (status) 1511 goto out; 1512 status = decode_putfh(xdr); 1513 if (status) 1514 goto out; 1515 1516 status = decode_setxattr(xdr, &res->cinfo); 1517 out: 1518 return status; 1519 } 1520 1521 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 1522 const void *data) 1523 { 1524 const struct nfs42_getxattrargs *args = data; 1525 struct compound_hdr hdr = { 1526 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 1527 }; 1528 uint32_t replen; 1529 1530 encode_compound_hdr(xdr, req, &hdr); 1531 encode_sequence(xdr, &args->seq_args, &hdr); 1532 encode_putfh(xdr, args->fh, &hdr); 1533 replen = hdr.replen + op_decode_hdr_maxsz + 1; 1534 encode_getxattr(xdr, args->xattr_name, &hdr); 1535 1536 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len, 1537 replen); 1538 1539 encode_nops(&hdr); 1540 } 1541 1542 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp, 1543 struct xdr_stream *xdr, void *data) 1544 { 1545 struct nfs42_getxattrres *res = data; 1546 struct compound_hdr hdr; 1547 int status; 1548 1549 status = decode_compound_hdr(xdr, &hdr); 1550 if (status) 1551 goto out; 1552 status = decode_sequence(xdr, &res->seq_res, rqstp); 1553 if (status) 1554 goto out; 1555 status = decode_putfh(xdr); 1556 if (status) 1557 goto out; 1558 status = decode_getxattr(xdr, res, rqstp); 1559 out: 1560 return status; 1561 } 1562 1563 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req, 1564 struct xdr_stream *xdr, const void *data) 1565 { 1566 const struct nfs42_listxattrsargs *args = data; 1567 struct compound_hdr hdr = { 1568 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 1569 }; 1570 uint32_t replen; 1571 1572 encode_compound_hdr(xdr, req, &hdr); 1573 encode_sequence(xdr, &args->seq_args, &hdr); 1574 encode_putfh(xdr, args->fh, &hdr); 1575 replen = hdr.replen + op_decode_hdr_maxsz + 2 + 1; 1576 encode_listxattrs(xdr, args, &hdr); 1577 1578 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen); 1579 1580 encode_nops(&hdr); 1581 } 1582 1583 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp, 1584 struct xdr_stream *xdr, void *data) 1585 { 1586 struct nfs42_listxattrsres *res = data; 1587 struct compound_hdr hdr; 1588 int status; 1589 1590 xdr_set_scratch_page(xdr, res->scratch); 1591 1592 status = decode_compound_hdr(xdr, &hdr); 1593 if (status) 1594 goto out; 1595 status = decode_sequence(xdr, &res->seq_res, rqstp); 1596 if (status) 1597 goto out; 1598 status = decode_putfh(xdr); 1599 if (status) 1600 goto out; 1601 status = decode_listxattrs(xdr, res); 1602 out: 1603 return status; 1604 } 1605 1606 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req, 1607 struct xdr_stream *xdr, const void *data) 1608 { 1609 const struct nfs42_removexattrargs *args = data; 1610 struct compound_hdr hdr = { 1611 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 1612 }; 1613 1614 encode_compound_hdr(xdr, req, &hdr); 1615 encode_sequence(xdr, &args->seq_args, &hdr); 1616 encode_putfh(xdr, args->fh, &hdr); 1617 encode_removexattr(xdr, args->xattr_name, &hdr); 1618 encode_nops(&hdr); 1619 } 1620 1621 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req, 1622 struct xdr_stream *xdr, void *data) 1623 { 1624 struct nfs42_removexattrres *res = data; 1625 struct compound_hdr hdr; 1626 int status; 1627 1628 status = decode_compound_hdr(xdr, &hdr); 1629 if (status) 1630 goto out; 1631 status = decode_sequence(xdr, &res->seq_res, req); 1632 if (status) 1633 goto out; 1634 status = decode_putfh(xdr); 1635 if (status) 1636 goto out; 1637 1638 status = decode_removexattr(xdr, &res->cinfo); 1639 out: 1640 return status; 1641 } 1642 #endif 1643 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ 1644