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 + 1) 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 if (len > req->rq_rcv_buf.page_len) 493 return -ERANGE; 494 495 res->xattr_len = len; 496 497 if (len > 0) { 498 rdlen = xdr_read_pages(xdr, len); 499 if (rdlen < len) 500 return -EIO; 501 } 502 503 return 0; 504 } 505 506 static void encode_removexattr(struct xdr_stream *xdr, const char *name, 507 struct compound_hdr *hdr) 508 { 509 encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr); 510 encode_string(xdr, strlen(name), name); 511 } 512 513 514 static int decode_removexattr(struct xdr_stream *xdr, 515 struct nfs4_change_info *cinfo) 516 { 517 int status; 518 519 status = decode_op_hdr(xdr, OP_REMOVEXATTR); 520 if (status) 521 goto out; 522 523 status = decode_change_info(xdr, cinfo); 524 out: 525 return status; 526 } 527 528 static void encode_listxattrs(struct xdr_stream *xdr, 529 const struct nfs42_listxattrsargs *arg, 530 struct compound_hdr *hdr) 531 { 532 __be32 *p; 533 534 encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr); 535 536 p = reserve_space(xdr, 12); 537 if (unlikely(!p)) 538 return; 539 540 p = xdr_encode_hyper(p, arg->cookie); 541 /* 542 * RFC 8276 says to specify the full max length of the LISTXATTRS 543 * XDR reply. Count is set to the XDR length of the names array 544 * plus the EOF marker. So, add the cookie and the names count. 545 */ 546 *p = cpu_to_be32(arg->count + 8 + 4); 547 } 548 549 static int decode_listxattrs(struct xdr_stream *xdr, 550 struct nfs42_listxattrsres *res) 551 { 552 int status; 553 __be32 *p; 554 u32 count, len, ulen; 555 size_t left, copied; 556 char *buf; 557 558 status = decode_op_hdr(xdr, OP_LISTXATTRS); 559 if (status) { 560 /* 561 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL 562 * should be translated to ERANGE. 563 */ 564 if (status == -ETOOSMALL) 565 status = -ERANGE; 566 goto out; 567 } 568 569 p = xdr_inline_decode(xdr, 8); 570 if (unlikely(!p)) 571 return -EIO; 572 573 xdr_decode_hyper(p, &res->cookie); 574 575 p = xdr_inline_decode(xdr, 4); 576 if (unlikely(!p)) 577 return -EIO; 578 579 left = res->xattr_len; 580 buf = res->xattr_buf; 581 582 count = be32_to_cpup(p); 583 copied = 0; 584 585 /* 586 * We have asked for enough room to encode the maximum number 587 * of possible attribute names, so everything should fit. 588 * 589 * But, don't rely on that assumption. Just decode entries 590 * until they don't fit anymore, just in case the server did 591 * something odd. 592 */ 593 while (count--) { 594 p = xdr_inline_decode(xdr, 4); 595 if (unlikely(!p)) 596 return -EIO; 597 598 len = be32_to_cpup(p); 599 if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) { 600 status = -ERANGE; 601 goto out; 602 } 603 604 p = xdr_inline_decode(xdr, len); 605 if (unlikely(!p)) 606 return -EIO; 607 608 ulen = len + XATTR_USER_PREFIX_LEN + 1; 609 if (buf) { 610 if (ulen > left) { 611 status = -ERANGE; 612 goto out; 613 } 614 615 memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); 616 memcpy(buf + XATTR_USER_PREFIX_LEN, p, len); 617 618 buf[ulen - 1] = 0; 619 buf += ulen; 620 left -= ulen; 621 } 622 copied += ulen; 623 } 624 625 p = xdr_inline_decode(xdr, 4); 626 if (unlikely(!p)) 627 return -EIO; 628 629 res->eof = be32_to_cpup(p); 630 res->copied = copied; 631 632 out: 633 if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX) 634 status = -E2BIG; 635 636 return status; 637 } 638 639 /* 640 * Encode ALLOCATE request 641 */ 642 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, 643 struct xdr_stream *xdr, 644 const void *data) 645 { 646 const struct nfs42_falloc_args *args = data; 647 struct compound_hdr hdr = { 648 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 649 }; 650 651 encode_compound_hdr(xdr, req, &hdr); 652 encode_sequence(xdr, &args->seq_args, &hdr); 653 encode_putfh(xdr, args->falloc_fh, &hdr); 654 encode_allocate(xdr, args, &hdr); 655 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 656 encode_nops(&hdr); 657 } 658 659 static void encode_copy_commit(struct xdr_stream *xdr, 660 const struct nfs42_copy_args *args, 661 struct compound_hdr *hdr) 662 { 663 __be32 *p; 664 665 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr); 666 p = reserve_space(xdr, 12); 667 p = xdr_encode_hyper(p, args->dst_pos); 668 *p = cpu_to_be32(args->count); 669 } 670 671 /* 672 * Encode COPY request 673 */ 674 static void nfs4_xdr_enc_copy(struct rpc_rqst *req, 675 struct xdr_stream *xdr, 676 const void *data) 677 { 678 const struct nfs42_copy_args *args = data; 679 struct compound_hdr hdr = { 680 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 681 }; 682 683 encode_compound_hdr(xdr, req, &hdr); 684 encode_sequence(xdr, &args->seq_args, &hdr); 685 encode_putfh(xdr, args->src_fh, &hdr); 686 encode_savefh(xdr, &hdr); 687 encode_putfh(xdr, args->dst_fh, &hdr); 688 encode_copy(xdr, args, &hdr); 689 if (args->sync) 690 encode_copy_commit(xdr, args, &hdr); 691 encode_nops(&hdr); 692 } 693 694 /* 695 * Encode OFFLOAD_CANEL request 696 */ 697 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, 698 struct xdr_stream *xdr, 699 const void *data) 700 { 701 const struct nfs42_offload_status_args *args = data; 702 struct compound_hdr hdr = { 703 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args), 704 }; 705 706 encode_compound_hdr(xdr, req, &hdr); 707 encode_sequence(xdr, &args->osa_seq_args, &hdr); 708 encode_putfh(xdr, args->osa_src_fh, &hdr); 709 encode_offload_cancel(xdr, args, &hdr); 710 encode_nops(&hdr); 711 } 712 713 /* 714 * Encode COPY_NOTIFY request 715 */ 716 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req, 717 struct xdr_stream *xdr, 718 const void *data) 719 { 720 const struct nfs42_copy_notify_args *args = data; 721 struct compound_hdr hdr = { 722 .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args), 723 }; 724 725 encode_compound_hdr(xdr, req, &hdr); 726 encode_sequence(xdr, &args->cna_seq_args, &hdr); 727 encode_putfh(xdr, args->cna_src_fh, &hdr); 728 encode_copy_notify(xdr, args, &hdr); 729 encode_nops(&hdr); 730 } 731 732 /* 733 * Encode DEALLOCATE request 734 */ 735 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, 736 struct xdr_stream *xdr, 737 const void *data) 738 { 739 const struct nfs42_falloc_args *args = data; 740 struct compound_hdr hdr = { 741 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 742 }; 743 744 encode_compound_hdr(xdr, req, &hdr); 745 encode_sequence(xdr, &args->seq_args, &hdr); 746 encode_putfh(xdr, args->falloc_fh, &hdr); 747 encode_deallocate(xdr, args, &hdr); 748 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 749 encode_nops(&hdr); 750 } 751 752 /* 753 * Encode READ_PLUS request 754 */ 755 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req, 756 struct xdr_stream *xdr, 757 const void *data) 758 { 759 const struct nfs_pgio_args *args = data; 760 struct compound_hdr hdr = { 761 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 762 }; 763 764 encode_compound_hdr(xdr, req, &hdr); 765 encode_sequence(xdr, &args->seq_args, &hdr); 766 encode_putfh(xdr, args->fh, &hdr); 767 encode_read_plus(xdr, args, &hdr); 768 769 rpc_prepare_reply_pages(req, args->pages, args->pgbase, 770 args->count, hdr.replen); 771 encode_nops(&hdr); 772 } 773 774 /* 775 * Encode SEEK request 776 */ 777 static void nfs4_xdr_enc_seek(struct rpc_rqst *req, 778 struct xdr_stream *xdr, 779 const void *data) 780 { 781 const struct nfs42_seek_args *args = data; 782 struct compound_hdr hdr = { 783 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 784 }; 785 786 encode_compound_hdr(xdr, req, &hdr); 787 encode_sequence(xdr, &args->seq_args, &hdr); 788 encode_putfh(xdr, args->sa_fh, &hdr); 789 encode_seek(xdr, args, &hdr); 790 encode_nops(&hdr); 791 } 792 793 /* 794 * Encode LAYOUTSTATS request 795 */ 796 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, 797 struct xdr_stream *xdr, 798 const void *data) 799 { 800 const struct nfs42_layoutstat_args *args = data; 801 int i; 802 803 struct compound_hdr hdr = { 804 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 805 }; 806 807 encode_compound_hdr(xdr, req, &hdr); 808 encode_sequence(xdr, &args->seq_args, &hdr); 809 encode_putfh(xdr, args->fh, &hdr); 810 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 811 for (i = 0; i < args->num_dev; i++) 812 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); 813 encode_nops(&hdr); 814 } 815 816 /* 817 * Encode CLONE request 818 */ 819 static void nfs4_xdr_enc_clone(struct rpc_rqst *req, 820 struct xdr_stream *xdr, 821 const void *data) 822 { 823 const struct nfs42_clone_args *args = data; 824 struct compound_hdr hdr = { 825 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 826 }; 827 828 encode_compound_hdr(xdr, req, &hdr); 829 encode_sequence(xdr, &args->seq_args, &hdr); 830 encode_putfh(xdr, args->src_fh, &hdr); 831 encode_savefh(xdr, &hdr); 832 encode_putfh(xdr, args->dst_fh, &hdr); 833 encode_clone(xdr, args, &hdr); 834 encode_getfattr(xdr, args->dst_bitmask, &hdr); 835 encode_nops(&hdr); 836 } 837 838 /* 839 * Encode LAYOUTERROR request 840 */ 841 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req, 842 struct xdr_stream *xdr, 843 const void *data) 844 { 845 const struct nfs42_layouterror_args *args = data; 846 struct compound_hdr hdr = { 847 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 848 }; 849 int i; 850 851 encode_compound_hdr(xdr, req, &hdr); 852 encode_sequence(xdr, &args->seq_args, &hdr); 853 encode_putfh(xdr, NFS_FH(args->inode), &hdr); 854 for (i = 0; i < args->num_errors; i++) 855 encode_layouterror(xdr, &args->errors[i], &hdr); 856 encode_nops(&hdr); 857 } 858 859 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 860 { 861 return decode_op_hdr(xdr, OP_ALLOCATE); 862 } 863 864 static int decode_write_response(struct xdr_stream *xdr, 865 struct nfs42_write_res *res) 866 { 867 __be32 *p; 868 int status, count; 869 870 p = xdr_inline_decode(xdr, 4); 871 if (unlikely(!p)) 872 return -EIO; 873 count = be32_to_cpup(p); 874 if (count > 1) 875 return -EREMOTEIO; 876 else if (count == 1) { 877 status = decode_opaque_fixed(xdr, &res->stateid, 878 NFS4_STATEID_SIZE); 879 if (unlikely(status)) 880 return -EIO; 881 } 882 p = xdr_inline_decode(xdr, 8 + 4); 883 if (unlikely(!p)) 884 return -EIO; 885 p = xdr_decode_hyper(p, &res->count); 886 res->verifier.committed = be32_to_cpup(p); 887 return decode_verifier(xdr, &res->verifier.verifier); 888 } 889 890 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns) 891 { 892 struct nfs42_netaddr *naddr; 893 uint32_t dummy; 894 char *dummy_str; 895 __be32 *p; 896 int status; 897 898 /* nl_type */ 899 p = xdr_inline_decode(xdr, 4); 900 if (unlikely(!p)) 901 return -EIO; 902 ns->nl4_type = be32_to_cpup(p); 903 switch (ns->nl4_type) { 904 case NL4_NAME: 905 case NL4_URL: 906 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 907 if (unlikely(status)) 908 return status; 909 if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) 910 return -EIO; 911 memcpy(&ns->u.nl4_str, dummy_str, dummy); 912 ns->u.nl4_str_sz = dummy; 913 break; 914 case NL4_NETADDR: 915 naddr = &ns->u.nl4_addr; 916 917 /* netid string */ 918 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 919 if (unlikely(status)) 920 return status; 921 if (unlikely(dummy > RPCBIND_MAXNETIDLEN)) 922 return -EIO; 923 naddr->netid_len = dummy; 924 memcpy(naddr->netid, dummy_str, naddr->netid_len); 925 926 /* uaddr string */ 927 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 928 if (unlikely(status)) 929 return status; 930 if (unlikely(dummy > RPCBIND_MAXUADDRLEN)) 931 return -EIO; 932 naddr->addr_len = dummy; 933 memcpy(naddr->addr, dummy_str, naddr->addr_len); 934 break; 935 default: 936 WARN_ON_ONCE(1); 937 return -EIO; 938 } 939 return 0; 940 } 941 942 static int decode_copy_requirements(struct xdr_stream *xdr, 943 struct nfs42_copy_res *res) { 944 __be32 *p; 945 946 p = xdr_inline_decode(xdr, 4 + 4); 947 if (unlikely(!p)) 948 return -EIO; 949 950 res->consecutive = be32_to_cpup(p++); 951 res->synchronous = be32_to_cpup(p++); 952 return 0; 953 } 954 955 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) 956 { 957 int status; 958 959 status = decode_op_hdr(xdr, OP_COPY); 960 if (status == NFS4ERR_OFFLOAD_NO_REQS) { 961 status = decode_copy_requirements(xdr, res); 962 if (status) 963 return status; 964 return NFS4ERR_OFFLOAD_NO_REQS; 965 } else if (status) 966 return status; 967 968 status = decode_write_response(xdr, &res->write_res); 969 if (status) 970 return status; 971 972 return decode_copy_requirements(xdr, res); 973 } 974 975 static int decode_offload_cancel(struct xdr_stream *xdr, 976 struct nfs42_offload_status_res *res) 977 { 978 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); 979 } 980 981 static int decode_copy_notify(struct xdr_stream *xdr, 982 struct nfs42_copy_notify_res *res) 983 { 984 __be32 *p; 985 int status, count; 986 987 status = decode_op_hdr(xdr, OP_COPY_NOTIFY); 988 if (status) 989 return status; 990 /* cnr_lease_time */ 991 p = xdr_inline_decode(xdr, 12); 992 if (unlikely(!p)) 993 return -EIO; 994 p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds); 995 res->cnr_lease_time.nseconds = be32_to_cpup(p); 996 997 status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE); 998 if (unlikely(status)) 999 return -EIO; 1000 1001 /* number of source addresses */ 1002 p = xdr_inline_decode(xdr, 4); 1003 if (unlikely(!p)) 1004 return -EIO; 1005 1006 count = be32_to_cpup(p); 1007 if (count > 1) 1008 pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n", 1009 __func__, count); 1010 1011 status = decode_nl4_server(xdr, &res->cnr_src); 1012 if (unlikely(status)) 1013 return -EIO; 1014 return 0; 1015 } 1016 1017 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 1018 { 1019 return decode_op_hdr(xdr, OP_DEALLOCATE); 1020 } 1021 1022 static int decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *res, 1023 uint32_t *eof) 1024 { 1025 uint32_t count, recvd; 1026 uint64_t offset; 1027 __be32 *p; 1028 1029 p = xdr_inline_decode(xdr, 8 + 4); 1030 if (unlikely(!p)) 1031 return -EIO; 1032 1033 p = xdr_decode_hyper(p, &offset); 1034 count = be32_to_cpup(p); 1035 recvd = xdr_align_data(xdr, res->count, count); 1036 res->count += recvd; 1037 1038 if (count > recvd) { 1039 dprintk("NFS: server cheating in read reply: " 1040 "count %u > recvd %u\n", count, recvd); 1041 *eof = 0; 1042 return 1; 1043 } 1044 1045 return 0; 1046 } 1047 1048 static int decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *res, 1049 uint32_t *eof) 1050 { 1051 uint64_t offset, length, recvd; 1052 __be32 *p; 1053 1054 p = xdr_inline_decode(xdr, 8 + 8); 1055 if (unlikely(!p)) 1056 return -EIO; 1057 1058 p = xdr_decode_hyper(p, &offset); 1059 p = xdr_decode_hyper(p, &length); 1060 recvd = xdr_expand_hole(xdr, res->count, length); 1061 res->count += recvd; 1062 1063 if (recvd < length) { 1064 *eof = 0; 1065 return 1; 1066 } 1067 return 0; 1068 } 1069 1070 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) 1071 { 1072 uint32_t eof, segments, type; 1073 int status, i; 1074 __be32 *p; 1075 1076 status = decode_op_hdr(xdr, OP_READ_PLUS); 1077 if (status) 1078 return status; 1079 1080 p = xdr_inline_decode(xdr, 4 + 4); 1081 if (unlikely(!p)) 1082 return -EIO; 1083 1084 eof = be32_to_cpup(p++); 1085 segments = be32_to_cpup(p++); 1086 if (segments == 0) 1087 goto out; 1088 1089 for (i = 0; i < segments; i++) { 1090 p = xdr_inline_decode(xdr, 4); 1091 if (unlikely(!p)) 1092 return -EIO; 1093 1094 type = be32_to_cpup(p++); 1095 if (type == NFS4_CONTENT_DATA) 1096 status = decode_read_plus_data(xdr, res, &eof); 1097 else if (type == NFS4_CONTENT_HOLE) 1098 status = decode_read_plus_hole(xdr, res, &eof); 1099 else 1100 return -EINVAL; 1101 1102 if (status < 0) 1103 return status; 1104 if (status > 0) 1105 break; 1106 } 1107 1108 out: 1109 res->eof = eof; 1110 return 0; 1111 } 1112 1113 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) 1114 { 1115 int status; 1116 __be32 *p; 1117 1118 status = decode_op_hdr(xdr, OP_SEEK); 1119 if (status) 1120 return status; 1121 1122 p = xdr_inline_decode(xdr, 4 + 8); 1123 if (unlikely(!p)) 1124 return -EIO; 1125 1126 res->sr_eof = be32_to_cpup(p++); 1127 p = xdr_decode_hyper(p, &res->sr_offset); 1128 return 0; 1129 } 1130 1131 static int decode_layoutstats(struct xdr_stream *xdr) 1132 { 1133 return decode_op_hdr(xdr, OP_LAYOUTSTATS); 1134 } 1135 1136 static int decode_clone(struct xdr_stream *xdr) 1137 { 1138 return decode_op_hdr(xdr, OP_CLONE); 1139 } 1140 1141 static int decode_layouterror(struct xdr_stream *xdr) 1142 { 1143 return decode_op_hdr(xdr, OP_LAYOUTERROR); 1144 } 1145 1146 /* 1147 * Decode ALLOCATE request 1148 */ 1149 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, 1150 struct xdr_stream *xdr, 1151 void *data) 1152 { 1153 struct nfs42_falloc_res *res = data; 1154 struct compound_hdr hdr; 1155 int status; 1156 1157 status = decode_compound_hdr(xdr, &hdr); 1158 if (status) 1159 goto out; 1160 status = decode_sequence(xdr, &res->seq_res, rqstp); 1161 if (status) 1162 goto out; 1163 status = decode_putfh(xdr); 1164 if (status) 1165 goto out; 1166 status = decode_allocate(xdr, res); 1167 if (status) 1168 goto out; 1169 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 1170 out: 1171 return status; 1172 } 1173 1174 /* 1175 * Decode COPY response 1176 */ 1177 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp, 1178 struct xdr_stream *xdr, 1179 void *data) 1180 { 1181 struct nfs42_copy_res *res = data; 1182 struct compound_hdr hdr; 1183 int status; 1184 1185 status = decode_compound_hdr(xdr, &hdr); 1186 if (status) 1187 goto out; 1188 status = decode_sequence(xdr, &res->seq_res, rqstp); 1189 if (status) 1190 goto out; 1191 status = decode_putfh(xdr); 1192 if (status) 1193 goto out; 1194 status = decode_savefh(xdr); 1195 if (status) 1196 goto out; 1197 status = decode_putfh(xdr); 1198 if (status) 1199 goto out; 1200 status = decode_copy(xdr, res); 1201 if (status) 1202 goto out; 1203 if (res->commit_res.verf) 1204 status = decode_commit(xdr, &res->commit_res); 1205 out: 1206 return status; 1207 } 1208 1209 /* 1210 * Decode OFFLOAD_CANCEL response 1211 */ 1212 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp, 1213 struct xdr_stream *xdr, 1214 void *data) 1215 { 1216 struct nfs42_offload_status_res *res = data; 1217 struct compound_hdr hdr; 1218 int status; 1219 1220 status = decode_compound_hdr(xdr, &hdr); 1221 if (status) 1222 goto out; 1223 status = decode_sequence(xdr, &res->osr_seq_res, rqstp); 1224 if (status) 1225 goto out; 1226 status = decode_putfh(xdr); 1227 if (status) 1228 goto out; 1229 status = decode_offload_cancel(xdr, res); 1230 1231 out: 1232 return status; 1233 } 1234 1235 /* 1236 * Decode COPY_NOTIFY response 1237 */ 1238 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp, 1239 struct xdr_stream *xdr, 1240 void *data) 1241 { 1242 struct nfs42_copy_notify_res *res = data; 1243 struct compound_hdr hdr; 1244 int status; 1245 1246 status = decode_compound_hdr(xdr, &hdr); 1247 if (status) 1248 goto out; 1249 status = decode_sequence(xdr, &res->cnr_seq_res, rqstp); 1250 if (status) 1251 goto out; 1252 status = decode_putfh(xdr); 1253 if (status) 1254 goto out; 1255 status = decode_copy_notify(xdr, res); 1256 1257 out: 1258 return status; 1259 } 1260 1261 /* 1262 * Decode DEALLOCATE request 1263 */ 1264 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, 1265 struct xdr_stream *xdr, 1266 void *data) 1267 { 1268 struct nfs42_falloc_res *res = data; 1269 struct compound_hdr hdr; 1270 int status; 1271 1272 status = decode_compound_hdr(xdr, &hdr); 1273 if (status) 1274 goto out; 1275 status = decode_sequence(xdr, &res->seq_res, rqstp); 1276 if (status) 1277 goto out; 1278 status = decode_putfh(xdr); 1279 if (status) 1280 goto out; 1281 status = decode_deallocate(xdr, res); 1282 if (status) 1283 goto out; 1284 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 1285 out: 1286 return status; 1287 } 1288 1289 /* 1290 * Decode READ_PLUS request 1291 */ 1292 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp, 1293 struct xdr_stream *xdr, 1294 void *data) 1295 { 1296 struct nfs_pgio_res *res = data; 1297 struct compound_hdr hdr; 1298 int status; 1299 1300 status = decode_compound_hdr(xdr, &hdr); 1301 if (status) 1302 goto out; 1303 status = decode_sequence(xdr, &res->seq_res, rqstp); 1304 if (status) 1305 goto out; 1306 status = decode_putfh(xdr); 1307 if (status) 1308 goto out; 1309 status = decode_read_plus(xdr, res); 1310 if (!status) 1311 status = res->count; 1312 out: 1313 return status; 1314 } 1315 1316 /* 1317 * Decode SEEK request 1318 */ 1319 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, 1320 struct xdr_stream *xdr, 1321 void *data) 1322 { 1323 struct nfs42_seek_res *res = data; 1324 struct compound_hdr hdr; 1325 int status; 1326 1327 status = decode_compound_hdr(xdr, &hdr); 1328 if (status) 1329 goto out; 1330 status = decode_sequence(xdr, &res->seq_res, rqstp); 1331 if (status) 1332 goto out; 1333 status = decode_putfh(xdr); 1334 if (status) 1335 goto out; 1336 status = decode_seek(xdr, res); 1337 out: 1338 return status; 1339 } 1340 1341 /* 1342 * Decode LAYOUTSTATS request 1343 */ 1344 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, 1345 struct xdr_stream *xdr, 1346 void *data) 1347 { 1348 struct nfs42_layoutstat_res *res = data; 1349 struct compound_hdr hdr; 1350 int status, i; 1351 1352 status = decode_compound_hdr(xdr, &hdr); 1353 if (status) 1354 goto out; 1355 status = decode_sequence(xdr, &res->seq_res, rqstp); 1356 if (status) 1357 goto out; 1358 status = decode_putfh(xdr); 1359 if (status) 1360 goto out; 1361 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 1362 for (i = 0; i < res->num_dev; i++) { 1363 status = decode_layoutstats(xdr); 1364 if (status) 1365 goto out; 1366 } 1367 out: 1368 res->rpc_status = status; 1369 return status; 1370 } 1371 1372 /* 1373 * Decode CLONE request 1374 */ 1375 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp, 1376 struct xdr_stream *xdr, 1377 void *data) 1378 { 1379 struct nfs42_clone_res *res = data; 1380 struct compound_hdr hdr; 1381 int status; 1382 1383 status = decode_compound_hdr(xdr, &hdr); 1384 if (status) 1385 goto out; 1386 status = decode_sequence(xdr, &res->seq_res, rqstp); 1387 if (status) 1388 goto out; 1389 status = decode_putfh(xdr); 1390 if (status) 1391 goto out; 1392 status = decode_savefh(xdr); 1393 if (status) 1394 goto out; 1395 status = decode_putfh(xdr); 1396 if (status) 1397 goto out; 1398 status = decode_clone(xdr); 1399 if (status) 1400 goto out; 1401 status = decode_getfattr(xdr, res->dst_fattr, res->server); 1402 1403 out: 1404 res->rpc_status = status; 1405 return status; 1406 } 1407 1408 /* 1409 * Decode LAYOUTERROR request 1410 */ 1411 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp, 1412 struct xdr_stream *xdr, 1413 void *data) 1414 { 1415 struct nfs42_layouterror_res *res = data; 1416 struct compound_hdr hdr; 1417 int status, i; 1418 1419 status = decode_compound_hdr(xdr, &hdr); 1420 if (status) 1421 goto out; 1422 status = decode_sequence(xdr, &res->seq_res, rqstp); 1423 if (status) 1424 goto out; 1425 status = decode_putfh(xdr); 1426 1427 for (i = 0; i < res->num_errors && status == 0; i++) 1428 status = decode_layouterror(xdr); 1429 out: 1430 res->rpc_status = status; 1431 return status; 1432 } 1433 1434 #ifdef CONFIG_NFS_V4_2 1435 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 1436 const void *data) 1437 { 1438 const struct nfs42_setxattrargs *args = data; 1439 struct compound_hdr hdr = { 1440 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 1441 }; 1442 1443 encode_compound_hdr(xdr, req, &hdr); 1444 encode_sequence(xdr, &args->seq_args, &hdr); 1445 encode_putfh(xdr, args->fh, &hdr); 1446 encode_setxattr(xdr, args, &hdr); 1447 encode_nops(&hdr); 1448 } 1449 1450 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 1451 void *data) 1452 { 1453 struct nfs42_setxattrres *res = data; 1454 struct compound_hdr hdr; 1455 int status; 1456 1457 status = decode_compound_hdr(xdr, &hdr); 1458 if (status) 1459 goto out; 1460 status = decode_sequence(xdr, &res->seq_res, req); 1461 if (status) 1462 goto out; 1463 status = decode_putfh(xdr); 1464 if (status) 1465 goto out; 1466 1467 status = decode_setxattr(xdr, &res->cinfo); 1468 out: 1469 return status; 1470 } 1471 1472 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 1473 const void *data) 1474 { 1475 const struct nfs42_getxattrargs *args = data; 1476 struct compound_hdr hdr = { 1477 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 1478 }; 1479 size_t plen; 1480 1481 encode_compound_hdr(xdr, req, &hdr); 1482 encode_sequence(xdr, &args->seq_args, &hdr); 1483 encode_putfh(xdr, args->fh, &hdr); 1484 encode_getxattr(xdr, args->xattr_name, &hdr); 1485 1486 plen = args->xattr_len ? args->xattr_len : XATTR_SIZE_MAX; 1487 1488 rpc_prepare_reply_pages(req, args->xattr_pages, 0, plen, 1489 hdr.replen); 1490 req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES; 1491 1492 encode_nops(&hdr); 1493 } 1494 1495 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp, 1496 struct xdr_stream *xdr, void *data) 1497 { 1498 struct nfs42_getxattrres *res = data; 1499 struct compound_hdr hdr; 1500 int status; 1501 1502 status = decode_compound_hdr(xdr, &hdr); 1503 if (status) 1504 goto out; 1505 status = decode_sequence(xdr, &res->seq_res, rqstp); 1506 if (status) 1507 goto out; 1508 status = decode_putfh(xdr); 1509 if (status) 1510 goto out; 1511 status = decode_getxattr(xdr, res, rqstp); 1512 out: 1513 return status; 1514 } 1515 1516 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req, 1517 struct xdr_stream *xdr, const void *data) 1518 { 1519 const struct nfs42_listxattrsargs *args = data; 1520 struct compound_hdr hdr = { 1521 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 1522 }; 1523 1524 encode_compound_hdr(xdr, req, &hdr); 1525 encode_sequence(xdr, &args->seq_args, &hdr); 1526 encode_putfh(xdr, args->fh, &hdr); 1527 encode_listxattrs(xdr, args, &hdr); 1528 1529 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, 1530 hdr.replen); 1531 1532 encode_nops(&hdr); 1533 } 1534 1535 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp, 1536 struct xdr_stream *xdr, void *data) 1537 { 1538 struct nfs42_listxattrsres *res = data; 1539 struct compound_hdr hdr; 1540 int status; 1541 1542 xdr_set_scratch_buffer(xdr, page_address(res->scratch), PAGE_SIZE); 1543 1544 status = decode_compound_hdr(xdr, &hdr); 1545 if (status) 1546 goto out; 1547 status = decode_sequence(xdr, &res->seq_res, rqstp); 1548 if (status) 1549 goto out; 1550 status = decode_putfh(xdr); 1551 if (status) 1552 goto out; 1553 status = decode_listxattrs(xdr, res); 1554 out: 1555 return status; 1556 } 1557 1558 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req, 1559 struct xdr_stream *xdr, const void *data) 1560 { 1561 const struct nfs42_removexattrargs *args = data; 1562 struct compound_hdr hdr = { 1563 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 1564 }; 1565 1566 encode_compound_hdr(xdr, req, &hdr); 1567 encode_sequence(xdr, &args->seq_args, &hdr); 1568 encode_putfh(xdr, args->fh, &hdr); 1569 encode_removexattr(xdr, args->xattr_name, &hdr); 1570 encode_nops(&hdr); 1571 } 1572 1573 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req, 1574 struct xdr_stream *xdr, void *data) 1575 { 1576 struct nfs42_removexattrres *res = data; 1577 struct compound_hdr hdr; 1578 int status; 1579 1580 status = decode_compound_hdr(xdr, &hdr); 1581 if (status) 1582 goto out; 1583 status = decode_sequence(xdr, &res->seq_res, req); 1584 if (status) 1585 goto out; 1586 status = decode_putfh(xdr); 1587 if (status) 1588 goto out; 1589 1590 status = decode_removexattr(xdr, &res->cinfo); 1591 out: 1592 return status; 1593 } 1594 #endif 1595 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ 1596