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