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