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 goto out; 573 } 574 575 p = xdr_inline_decode(xdr, 8); 576 if (unlikely(!p)) 577 return -EIO; 578 579 xdr_decode_hyper(p, &res->cookie); 580 581 p = xdr_inline_decode(xdr, 4); 582 if (unlikely(!p)) 583 return -EIO; 584 585 left = res->xattr_len; 586 buf = res->xattr_buf; 587 588 count = be32_to_cpup(p); 589 copied = 0; 590 591 /* 592 * We have asked for enough room to encode the maximum number 593 * of possible attribute names, so everything should fit. 594 * 595 * But, don't rely on that assumption. Just decode entries 596 * until they don't fit anymore, just in case the server did 597 * something odd. 598 */ 599 while (count--) { 600 p = xdr_inline_decode(xdr, 4); 601 if (unlikely(!p)) 602 return -EIO; 603 604 len = be32_to_cpup(p); 605 if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) { 606 status = -ERANGE; 607 goto out; 608 } 609 610 p = xdr_inline_decode(xdr, len); 611 if (unlikely(!p)) 612 return -EIO; 613 614 ulen = len + XATTR_USER_PREFIX_LEN + 1; 615 if (buf) { 616 if (ulen > left) { 617 status = -ERANGE; 618 goto out; 619 } 620 621 memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); 622 memcpy(buf + XATTR_USER_PREFIX_LEN, p, len); 623 624 buf[ulen - 1] = 0; 625 buf += ulen; 626 left -= ulen; 627 } 628 copied += ulen; 629 } 630 631 p = xdr_inline_decode(xdr, 4); 632 if (unlikely(!p)) 633 return -EIO; 634 635 res->eof = be32_to_cpup(p); 636 res->copied = copied; 637 638 out: 639 if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX) 640 status = -E2BIG; 641 642 return status; 643 } 644 645 /* 646 * Encode ALLOCATE request 647 */ 648 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, 649 struct xdr_stream *xdr, 650 const void *data) 651 { 652 const struct nfs42_falloc_args *args = data; 653 struct compound_hdr hdr = { 654 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 655 }; 656 657 encode_compound_hdr(xdr, req, &hdr); 658 encode_sequence(xdr, &args->seq_args, &hdr); 659 encode_putfh(xdr, args->falloc_fh, &hdr); 660 encode_allocate(xdr, args, &hdr); 661 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 662 encode_nops(&hdr); 663 } 664 665 static void encode_copy_commit(struct xdr_stream *xdr, 666 const struct nfs42_copy_args *args, 667 struct compound_hdr *hdr) 668 { 669 __be32 *p; 670 671 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr); 672 p = reserve_space(xdr, 12); 673 p = xdr_encode_hyper(p, args->dst_pos); 674 *p = cpu_to_be32(args->count); 675 } 676 677 /* 678 * Encode COPY request 679 */ 680 static void nfs4_xdr_enc_copy(struct rpc_rqst *req, 681 struct xdr_stream *xdr, 682 const void *data) 683 { 684 const struct nfs42_copy_args *args = data; 685 struct compound_hdr hdr = { 686 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 687 }; 688 689 encode_compound_hdr(xdr, req, &hdr); 690 encode_sequence(xdr, &args->seq_args, &hdr); 691 encode_putfh(xdr, args->src_fh, &hdr); 692 encode_savefh(xdr, &hdr); 693 encode_putfh(xdr, args->dst_fh, &hdr); 694 encode_copy(xdr, args, &hdr); 695 if (args->sync) 696 encode_copy_commit(xdr, args, &hdr); 697 encode_nops(&hdr); 698 } 699 700 /* 701 * Encode OFFLOAD_CANEL request 702 */ 703 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, 704 struct xdr_stream *xdr, 705 const void *data) 706 { 707 const struct nfs42_offload_status_args *args = data; 708 struct compound_hdr hdr = { 709 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args), 710 }; 711 712 encode_compound_hdr(xdr, req, &hdr); 713 encode_sequence(xdr, &args->osa_seq_args, &hdr); 714 encode_putfh(xdr, args->osa_src_fh, &hdr); 715 encode_offload_cancel(xdr, args, &hdr); 716 encode_nops(&hdr); 717 } 718 719 /* 720 * Encode COPY_NOTIFY request 721 */ 722 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req, 723 struct xdr_stream *xdr, 724 const void *data) 725 { 726 const struct nfs42_copy_notify_args *args = data; 727 struct compound_hdr hdr = { 728 .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args), 729 }; 730 731 encode_compound_hdr(xdr, req, &hdr); 732 encode_sequence(xdr, &args->cna_seq_args, &hdr); 733 encode_putfh(xdr, args->cna_src_fh, &hdr); 734 encode_copy_notify(xdr, args, &hdr); 735 encode_nops(&hdr); 736 } 737 738 /* 739 * Encode DEALLOCATE request 740 */ 741 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, 742 struct xdr_stream *xdr, 743 const void *data) 744 { 745 const struct nfs42_falloc_args *args = data; 746 struct compound_hdr hdr = { 747 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 748 }; 749 750 encode_compound_hdr(xdr, req, &hdr); 751 encode_sequence(xdr, &args->seq_args, &hdr); 752 encode_putfh(xdr, args->falloc_fh, &hdr); 753 encode_deallocate(xdr, args, &hdr); 754 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 755 encode_nops(&hdr); 756 } 757 758 /* 759 * Encode READ_PLUS request 760 */ 761 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req, 762 struct xdr_stream *xdr, 763 const void *data) 764 { 765 const struct nfs_pgio_args *args = data; 766 struct compound_hdr hdr = { 767 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 768 }; 769 770 encode_compound_hdr(xdr, req, &hdr); 771 encode_sequence(xdr, &args->seq_args, &hdr); 772 encode_putfh(xdr, args->fh, &hdr); 773 encode_read_plus(xdr, args, &hdr); 774 775 rpc_prepare_reply_pages(req, args->pages, args->pgbase, 776 args->count, hdr.replen); 777 encode_nops(&hdr); 778 } 779 780 /* 781 * Encode SEEK request 782 */ 783 static void nfs4_xdr_enc_seek(struct rpc_rqst *req, 784 struct xdr_stream *xdr, 785 const void *data) 786 { 787 const struct nfs42_seek_args *args = data; 788 struct compound_hdr hdr = { 789 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 790 }; 791 792 encode_compound_hdr(xdr, req, &hdr); 793 encode_sequence(xdr, &args->seq_args, &hdr); 794 encode_putfh(xdr, args->sa_fh, &hdr); 795 encode_seek(xdr, args, &hdr); 796 encode_nops(&hdr); 797 } 798 799 /* 800 * Encode LAYOUTSTATS request 801 */ 802 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, 803 struct xdr_stream *xdr, 804 const void *data) 805 { 806 const struct nfs42_layoutstat_args *args = data; 807 int i; 808 809 struct compound_hdr hdr = { 810 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 811 }; 812 813 encode_compound_hdr(xdr, req, &hdr); 814 encode_sequence(xdr, &args->seq_args, &hdr); 815 encode_putfh(xdr, args->fh, &hdr); 816 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 817 for (i = 0; i < args->num_dev; i++) 818 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); 819 encode_nops(&hdr); 820 } 821 822 /* 823 * Encode CLONE request 824 */ 825 static void nfs4_xdr_enc_clone(struct rpc_rqst *req, 826 struct xdr_stream *xdr, 827 const void *data) 828 { 829 const struct nfs42_clone_args *args = data; 830 struct compound_hdr hdr = { 831 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 832 }; 833 834 encode_compound_hdr(xdr, req, &hdr); 835 encode_sequence(xdr, &args->seq_args, &hdr); 836 encode_putfh(xdr, args->src_fh, &hdr); 837 encode_savefh(xdr, &hdr); 838 encode_putfh(xdr, args->dst_fh, &hdr); 839 encode_clone(xdr, args, &hdr); 840 encode_getfattr(xdr, args->dst_bitmask, &hdr); 841 encode_nops(&hdr); 842 } 843 844 /* 845 * Encode LAYOUTERROR request 846 */ 847 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req, 848 struct xdr_stream *xdr, 849 const void *data) 850 { 851 const struct nfs42_layouterror_args *args = data; 852 struct compound_hdr hdr = { 853 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 854 }; 855 int i; 856 857 encode_compound_hdr(xdr, req, &hdr); 858 encode_sequence(xdr, &args->seq_args, &hdr); 859 encode_putfh(xdr, NFS_FH(args->inode), &hdr); 860 for (i = 0; i < args->num_errors; i++) 861 encode_layouterror(xdr, &args->errors[i], &hdr); 862 encode_nops(&hdr); 863 } 864 865 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 866 { 867 return decode_op_hdr(xdr, OP_ALLOCATE); 868 } 869 870 static int decode_write_response(struct xdr_stream *xdr, 871 struct nfs42_write_res *res) 872 { 873 __be32 *p; 874 int status, count; 875 876 p = xdr_inline_decode(xdr, 4); 877 if (unlikely(!p)) 878 return -EIO; 879 count = be32_to_cpup(p); 880 if (count > 1) 881 return -EREMOTEIO; 882 else if (count == 1) { 883 status = decode_opaque_fixed(xdr, &res->stateid, 884 NFS4_STATEID_SIZE); 885 if (unlikely(status)) 886 return -EIO; 887 } 888 p = xdr_inline_decode(xdr, 8 + 4); 889 if (unlikely(!p)) 890 return -EIO; 891 p = xdr_decode_hyper(p, &res->count); 892 res->verifier.committed = be32_to_cpup(p); 893 return decode_verifier(xdr, &res->verifier.verifier); 894 } 895 896 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns) 897 { 898 struct nfs42_netaddr *naddr; 899 uint32_t dummy; 900 char *dummy_str; 901 __be32 *p; 902 int status; 903 904 /* nl_type */ 905 p = xdr_inline_decode(xdr, 4); 906 if (unlikely(!p)) 907 return -EIO; 908 ns->nl4_type = be32_to_cpup(p); 909 switch (ns->nl4_type) { 910 case NL4_NAME: 911 case NL4_URL: 912 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 913 if (unlikely(status)) 914 return status; 915 if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) 916 return -EIO; 917 memcpy(&ns->u.nl4_str, dummy_str, dummy); 918 ns->u.nl4_str_sz = dummy; 919 break; 920 case NL4_NETADDR: 921 naddr = &ns->u.nl4_addr; 922 923 /* netid string */ 924 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 925 if (unlikely(status)) 926 return status; 927 if (unlikely(dummy > RPCBIND_MAXNETIDLEN)) 928 return -EIO; 929 naddr->netid_len = dummy; 930 memcpy(naddr->netid, dummy_str, naddr->netid_len); 931 932 /* uaddr string */ 933 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 934 if (unlikely(status)) 935 return status; 936 if (unlikely(dummy > RPCBIND_MAXUADDRLEN)) 937 return -EIO; 938 naddr->addr_len = dummy; 939 memcpy(naddr->addr, dummy_str, naddr->addr_len); 940 break; 941 default: 942 WARN_ON_ONCE(1); 943 return -EIO; 944 } 945 return 0; 946 } 947 948 static int decode_copy_requirements(struct xdr_stream *xdr, 949 struct nfs42_copy_res *res) { 950 __be32 *p; 951 952 p = xdr_inline_decode(xdr, 4 + 4); 953 if (unlikely(!p)) 954 return -EIO; 955 956 res->consecutive = be32_to_cpup(p++); 957 res->synchronous = be32_to_cpup(p++); 958 return 0; 959 } 960 961 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) 962 { 963 int status; 964 965 status = decode_op_hdr(xdr, OP_COPY); 966 if (status == NFS4ERR_OFFLOAD_NO_REQS) { 967 status = decode_copy_requirements(xdr, res); 968 if (status) 969 return status; 970 return NFS4ERR_OFFLOAD_NO_REQS; 971 } else if (status) 972 return status; 973 974 status = decode_write_response(xdr, &res->write_res); 975 if (status) 976 return status; 977 978 return decode_copy_requirements(xdr, res); 979 } 980 981 static int decode_offload_cancel(struct xdr_stream *xdr, 982 struct nfs42_offload_status_res *res) 983 { 984 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); 985 } 986 987 static int decode_copy_notify(struct xdr_stream *xdr, 988 struct nfs42_copy_notify_res *res) 989 { 990 __be32 *p; 991 int status, count; 992 993 status = decode_op_hdr(xdr, OP_COPY_NOTIFY); 994 if (status) 995 return status; 996 /* cnr_lease_time */ 997 p = xdr_inline_decode(xdr, 12); 998 if (unlikely(!p)) 999 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 */ 1636