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 #define decode_copy_maxsz (op_decode_hdr_maxsz + \ 26 NFS42_WRITE_RES_SIZE + \ 27 1 /* cr_consecutive */ + \ 28 1 /* cr_synchronous */) 29 #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \ 30 XDR_QUADLEN(NFS4_STATEID_SIZE)) 31 #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz) 32 #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ 33 encode_fallocate_maxsz) 34 #define decode_deallocate_maxsz (op_decode_hdr_maxsz) 35 #define encode_seek_maxsz (op_encode_hdr_maxsz + \ 36 encode_stateid_maxsz + \ 37 2 /* offset */ + \ 38 1 /* whence */) 39 #define decode_seek_maxsz (op_decode_hdr_maxsz + \ 40 1 /* eof */ + \ 41 1 /* whence */ + \ 42 2 /* offset */ + \ 43 2 /* length */) 44 #define encode_io_info_maxsz 4 45 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \ 46 2 /* offset */ + \ 47 2 /* length */ + \ 48 encode_stateid_maxsz + \ 49 encode_io_info_maxsz + \ 50 encode_io_info_maxsz + \ 51 1 /* opaque devaddr4 length */ + \ 52 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE)) 53 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz) 54 #define encode_clone_maxsz (encode_stateid_maxsz + \ 55 encode_stateid_maxsz + \ 56 2 /* src offset */ + \ 57 2 /* dst offset */ + \ 58 2 /* count */) 59 #define decode_clone_maxsz (op_decode_hdr_maxsz) 60 61 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ 62 encode_putfh_maxsz + \ 63 encode_allocate_maxsz + \ 64 encode_getattr_maxsz) 65 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ 66 decode_putfh_maxsz + \ 67 decode_allocate_maxsz + \ 68 decode_getattr_maxsz) 69 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \ 70 encode_putfh_maxsz + \ 71 encode_savefh_maxsz + \ 72 encode_putfh_maxsz + \ 73 encode_copy_maxsz + \ 74 encode_commit_maxsz) 75 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \ 76 decode_putfh_maxsz + \ 77 decode_savefh_maxsz + \ 78 decode_putfh_maxsz + \ 79 decode_copy_maxsz + \ 80 decode_commit_maxsz) 81 #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \ 82 encode_putfh_maxsz + \ 83 encode_offload_cancel_maxsz) 84 #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \ 85 decode_putfh_maxsz + \ 86 decode_offload_cancel_maxsz) 87 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ 88 encode_putfh_maxsz + \ 89 encode_deallocate_maxsz + \ 90 encode_getattr_maxsz) 91 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ 92 decode_putfh_maxsz + \ 93 decode_deallocate_maxsz + \ 94 decode_getattr_maxsz) 95 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ 96 encode_putfh_maxsz + \ 97 encode_seek_maxsz) 98 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \ 99 decode_putfh_maxsz + \ 100 decode_seek_maxsz) 101 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \ 102 encode_sequence_maxsz + \ 103 encode_putfh_maxsz + \ 104 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz) 105 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \ 106 decode_sequence_maxsz + \ 107 decode_putfh_maxsz + \ 108 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz) 109 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \ 110 encode_sequence_maxsz + \ 111 encode_putfh_maxsz + \ 112 encode_savefh_maxsz + \ 113 encode_putfh_maxsz + \ 114 encode_clone_maxsz + \ 115 encode_getattr_maxsz) 116 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \ 117 decode_sequence_maxsz + \ 118 decode_putfh_maxsz + \ 119 decode_savefh_maxsz + \ 120 decode_putfh_maxsz + \ 121 decode_clone_maxsz + \ 122 decode_getattr_maxsz) 123 124 static void encode_fallocate(struct xdr_stream *xdr, 125 const struct nfs42_falloc_args *args) 126 { 127 encode_nfs4_stateid(xdr, &args->falloc_stateid); 128 encode_uint64(xdr, args->falloc_offset); 129 encode_uint64(xdr, args->falloc_length); 130 } 131 132 static void encode_allocate(struct xdr_stream *xdr, 133 const struct nfs42_falloc_args *args, 134 struct compound_hdr *hdr) 135 { 136 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr); 137 encode_fallocate(xdr, args); 138 } 139 140 static void encode_copy(struct xdr_stream *xdr, 141 const struct nfs42_copy_args *args, 142 struct compound_hdr *hdr) 143 { 144 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr); 145 encode_nfs4_stateid(xdr, &args->src_stateid); 146 encode_nfs4_stateid(xdr, &args->dst_stateid); 147 148 encode_uint64(xdr, args->src_pos); 149 encode_uint64(xdr, args->dst_pos); 150 encode_uint64(xdr, args->count); 151 152 encode_uint32(xdr, 1); /* consecutive = true */ 153 encode_uint32(xdr, args->sync); 154 encode_uint32(xdr, 0); /* src server list */ 155 } 156 157 static void encode_offload_cancel(struct xdr_stream *xdr, 158 const struct nfs42_offload_status_args *args, 159 struct compound_hdr *hdr) 160 { 161 encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr); 162 encode_nfs4_stateid(xdr, &args->osa_stateid); 163 } 164 165 static void encode_deallocate(struct xdr_stream *xdr, 166 const struct nfs42_falloc_args *args, 167 struct compound_hdr *hdr) 168 { 169 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr); 170 encode_fallocate(xdr, args); 171 } 172 173 static void encode_seek(struct xdr_stream *xdr, 174 const struct nfs42_seek_args *args, 175 struct compound_hdr *hdr) 176 { 177 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr); 178 encode_nfs4_stateid(xdr, &args->sa_stateid); 179 encode_uint64(xdr, args->sa_offset); 180 encode_uint32(xdr, args->sa_what); 181 } 182 183 static void encode_layoutstats(struct xdr_stream *xdr, 184 const struct nfs42_layoutstat_args *args, 185 struct nfs42_layoutstat_devinfo *devinfo, 186 struct compound_hdr *hdr) 187 { 188 __be32 *p; 189 190 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr); 191 p = reserve_space(xdr, 8 + 8); 192 p = xdr_encode_hyper(p, devinfo->offset); 193 p = xdr_encode_hyper(p, devinfo->length); 194 encode_nfs4_stateid(xdr, &args->stateid); 195 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4); 196 p = xdr_encode_hyper(p, devinfo->read_count); 197 p = xdr_encode_hyper(p, devinfo->read_bytes); 198 p = xdr_encode_hyper(p, devinfo->write_count); 199 p = xdr_encode_hyper(p, devinfo->write_bytes); 200 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data, 201 NFS4_DEVICEID4_SIZE); 202 /* Encode layoutupdate4 */ 203 *p++ = cpu_to_be32(devinfo->layout_type); 204 if (devinfo->ld_private.ops) 205 devinfo->ld_private.ops->encode(xdr, args, 206 &devinfo->ld_private); 207 else 208 encode_uint32(xdr, 0); 209 } 210 211 static void encode_clone(struct xdr_stream *xdr, 212 const struct nfs42_clone_args *args, 213 struct compound_hdr *hdr) 214 { 215 __be32 *p; 216 217 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr); 218 encode_nfs4_stateid(xdr, &args->src_stateid); 219 encode_nfs4_stateid(xdr, &args->dst_stateid); 220 p = reserve_space(xdr, 3*8); 221 p = xdr_encode_hyper(p, args->src_offset); 222 p = xdr_encode_hyper(p, args->dst_offset); 223 xdr_encode_hyper(p, args->count); 224 } 225 226 /* 227 * Encode ALLOCATE request 228 */ 229 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, 230 struct xdr_stream *xdr, 231 const void *data) 232 { 233 const struct nfs42_falloc_args *args = data; 234 struct compound_hdr hdr = { 235 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 236 }; 237 238 encode_compound_hdr(xdr, req, &hdr); 239 encode_sequence(xdr, &args->seq_args, &hdr); 240 encode_putfh(xdr, args->falloc_fh, &hdr); 241 encode_allocate(xdr, args, &hdr); 242 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 243 encode_nops(&hdr); 244 } 245 246 static void encode_copy_commit(struct xdr_stream *xdr, 247 const struct nfs42_copy_args *args, 248 struct compound_hdr *hdr) 249 { 250 __be32 *p; 251 252 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr); 253 p = reserve_space(xdr, 12); 254 p = xdr_encode_hyper(p, args->dst_pos); 255 *p = cpu_to_be32(args->count); 256 } 257 258 /* 259 * Encode COPY request 260 */ 261 static void nfs4_xdr_enc_copy(struct rpc_rqst *req, 262 struct xdr_stream *xdr, 263 const void *data) 264 { 265 const struct nfs42_copy_args *args = data; 266 struct compound_hdr hdr = { 267 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 268 }; 269 270 encode_compound_hdr(xdr, req, &hdr); 271 encode_sequence(xdr, &args->seq_args, &hdr); 272 encode_putfh(xdr, args->src_fh, &hdr); 273 encode_savefh(xdr, &hdr); 274 encode_putfh(xdr, args->dst_fh, &hdr); 275 encode_copy(xdr, args, &hdr); 276 if (args->sync) 277 encode_copy_commit(xdr, args, &hdr); 278 encode_nops(&hdr); 279 } 280 281 /* 282 * Encode OFFLOAD_CANEL request 283 */ 284 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, 285 struct xdr_stream *xdr, 286 const void *data) 287 { 288 const struct nfs42_offload_status_args *args = data; 289 struct compound_hdr hdr = { 290 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args), 291 }; 292 293 encode_compound_hdr(xdr, req, &hdr); 294 encode_sequence(xdr, &args->osa_seq_args, &hdr); 295 encode_putfh(xdr, args->osa_src_fh, &hdr); 296 encode_offload_cancel(xdr, args, &hdr); 297 encode_nops(&hdr); 298 } 299 300 /* 301 * Encode DEALLOCATE request 302 */ 303 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, 304 struct xdr_stream *xdr, 305 const void *data) 306 { 307 const struct nfs42_falloc_args *args = data; 308 struct compound_hdr hdr = { 309 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 310 }; 311 312 encode_compound_hdr(xdr, req, &hdr); 313 encode_sequence(xdr, &args->seq_args, &hdr); 314 encode_putfh(xdr, args->falloc_fh, &hdr); 315 encode_deallocate(xdr, args, &hdr); 316 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 317 encode_nops(&hdr); 318 } 319 320 /* 321 * Encode SEEK request 322 */ 323 static void nfs4_xdr_enc_seek(struct rpc_rqst *req, 324 struct xdr_stream *xdr, 325 const void *data) 326 { 327 const struct nfs42_seek_args *args = data; 328 struct compound_hdr hdr = { 329 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 330 }; 331 332 encode_compound_hdr(xdr, req, &hdr); 333 encode_sequence(xdr, &args->seq_args, &hdr); 334 encode_putfh(xdr, args->sa_fh, &hdr); 335 encode_seek(xdr, args, &hdr); 336 encode_nops(&hdr); 337 } 338 339 /* 340 * Encode LAYOUTSTATS request 341 */ 342 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, 343 struct xdr_stream *xdr, 344 const void *data) 345 { 346 const struct nfs42_layoutstat_args *args = data; 347 int i; 348 349 struct compound_hdr hdr = { 350 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 351 }; 352 353 encode_compound_hdr(xdr, req, &hdr); 354 encode_sequence(xdr, &args->seq_args, &hdr); 355 encode_putfh(xdr, args->fh, &hdr); 356 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 357 for (i = 0; i < args->num_dev; i++) 358 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); 359 encode_nops(&hdr); 360 } 361 362 /* 363 * Encode CLONE request 364 */ 365 static void nfs4_xdr_enc_clone(struct rpc_rqst *req, 366 struct xdr_stream *xdr, 367 const void *data) 368 { 369 const struct nfs42_clone_args *args = data; 370 struct compound_hdr hdr = { 371 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 372 }; 373 374 encode_compound_hdr(xdr, req, &hdr); 375 encode_sequence(xdr, &args->seq_args, &hdr); 376 encode_putfh(xdr, args->src_fh, &hdr); 377 encode_savefh(xdr, &hdr); 378 encode_putfh(xdr, args->dst_fh, &hdr); 379 encode_clone(xdr, args, &hdr); 380 encode_getfattr(xdr, args->dst_bitmask, &hdr); 381 encode_nops(&hdr); 382 } 383 384 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 385 { 386 return decode_op_hdr(xdr, OP_ALLOCATE); 387 } 388 389 static int decode_write_response(struct xdr_stream *xdr, 390 struct nfs42_write_res *res) 391 { 392 __be32 *p; 393 int status, count; 394 395 p = xdr_inline_decode(xdr, 4); 396 if (unlikely(!p)) 397 goto out_overflow; 398 count = be32_to_cpup(p); 399 if (count > 1) 400 return -EREMOTEIO; 401 else if (count == 1) { 402 status = decode_opaque_fixed(xdr, &res->stateid, 403 NFS4_STATEID_SIZE); 404 if (unlikely(status)) 405 goto out_overflow; 406 } 407 p = xdr_inline_decode(xdr, 8 + 4); 408 if (unlikely(!p)) 409 goto out_overflow; 410 p = xdr_decode_hyper(p, &res->count); 411 res->verifier.committed = be32_to_cpup(p); 412 return decode_verifier(xdr, &res->verifier.verifier); 413 414 out_overflow: 415 print_overflow_msg(__func__, xdr); 416 return -EIO; 417 } 418 419 static int decode_copy_requirements(struct xdr_stream *xdr, 420 struct nfs42_copy_res *res) { 421 __be32 *p; 422 423 p = xdr_inline_decode(xdr, 4 + 4); 424 if (unlikely(!p)) 425 goto out_overflow; 426 427 res->consecutive = be32_to_cpup(p++); 428 res->synchronous = be32_to_cpup(p++); 429 return 0; 430 out_overflow: 431 print_overflow_msg(__func__, xdr); 432 return -EIO; 433 } 434 435 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) 436 { 437 int status; 438 439 status = decode_op_hdr(xdr, OP_COPY); 440 if (status == NFS4ERR_OFFLOAD_NO_REQS) { 441 status = decode_copy_requirements(xdr, res); 442 if (status) 443 return status; 444 return NFS4ERR_OFFLOAD_NO_REQS; 445 } else if (status) 446 return status; 447 448 status = decode_write_response(xdr, &res->write_res); 449 if (status) 450 return status; 451 452 return decode_copy_requirements(xdr, res); 453 } 454 455 static int decode_offload_cancel(struct xdr_stream *xdr, 456 struct nfs42_offload_status_res *res) 457 { 458 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); 459 } 460 461 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 462 { 463 return decode_op_hdr(xdr, OP_DEALLOCATE); 464 } 465 466 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) 467 { 468 int status; 469 __be32 *p; 470 471 status = decode_op_hdr(xdr, OP_SEEK); 472 if (status) 473 return status; 474 475 p = xdr_inline_decode(xdr, 4 + 8); 476 if (unlikely(!p)) 477 goto out_overflow; 478 479 res->sr_eof = be32_to_cpup(p++); 480 p = xdr_decode_hyper(p, &res->sr_offset); 481 return 0; 482 483 out_overflow: 484 print_overflow_msg(__func__, xdr); 485 return -EIO; 486 } 487 488 static int decode_layoutstats(struct xdr_stream *xdr) 489 { 490 return decode_op_hdr(xdr, OP_LAYOUTSTATS); 491 } 492 493 static int decode_clone(struct xdr_stream *xdr) 494 { 495 return decode_op_hdr(xdr, OP_CLONE); 496 } 497 498 /* 499 * Decode ALLOCATE request 500 */ 501 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, 502 struct xdr_stream *xdr, 503 void *data) 504 { 505 struct nfs42_falloc_res *res = data; 506 struct compound_hdr hdr; 507 int status; 508 509 status = decode_compound_hdr(xdr, &hdr); 510 if (status) 511 goto out; 512 status = decode_sequence(xdr, &res->seq_res, rqstp); 513 if (status) 514 goto out; 515 status = decode_putfh(xdr); 516 if (status) 517 goto out; 518 status = decode_allocate(xdr, res); 519 if (status) 520 goto out; 521 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 522 out: 523 return status; 524 } 525 526 /* 527 * Decode COPY response 528 */ 529 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp, 530 struct xdr_stream *xdr, 531 void *data) 532 { 533 struct nfs42_copy_res *res = data; 534 struct compound_hdr hdr; 535 int status; 536 537 status = decode_compound_hdr(xdr, &hdr); 538 if (status) 539 goto out; 540 status = decode_sequence(xdr, &res->seq_res, rqstp); 541 if (status) 542 goto out; 543 status = decode_putfh(xdr); 544 if (status) 545 goto out; 546 status = decode_savefh(xdr); 547 if (status) 548 goto out; 549 status = decode_putfh(xdr); 550 if (status) 551 goto out; 552 status = decode_copy(xdr, res); 553 if (status) 554 goto out; 555 if (res->commit_res.verf) 556 status = decode_commit(xdr, &res->commit_res); 557 out: 558 return status; 559 } 560 561 /* 562 * Decode OFFLOAD_CANCEL response 563 */ 564 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp, 565 struct xdr_stream *xdr, 566 void *data) 567 { 568 struct nfs42_offload_status_res *res = data; 569 struct compound_hdr hdr; 570 int status; 571 572 status = decode_compound_hdr(xdr, &hdr); 573 if (status) 574 goto out; 575 status = decode_sequence(xdr, &res->osr_seq_res, rqstp); 576 if (status) 577 goto out; 578 status = decode_putfh(xdr); 579 if (status) 580 goto out; 581 status = decode_offload_cancel(xdr, res); 582 583 out: 584 return status; 585 } 586 587 /* 588 * Decode DEALLOCATE request 589 */ 590 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, 591 struct xdr_stream *xdr, 592 void *data) 593 { 594 struct nfs42_falloc_res *res = data; 595 struct compound_hdr hdr; 596 int status; 597 598 status = decode_compound_hdr(xdr, &hdr); 599 if (status) 600 goto out; 601 status = decode_sequence(xdr, &res->seq_res, rqstp); 602 if (status) 603 goto out; 604 status = decode_putfh(xdr); 605 if (status) 606 goto out; 607 status = decode_deallocate(xdr, res); 608 if (status) 609 goto out; 610 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 611 out: 612 return status; 613 } 614 615 /* 616 * Decode SEEK request 617 */ 618 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, 619 struct xdr_stream *xdr, 620 void *data) 621 { 622 struct nfs42_seek_res *res = data; 623 struct compound_hdr hdr; 624 int status; 625 626 status = decode_compound_hdr(xdr, &hdr); 627 if (status) 628 goto out; 629 status = decode_sequence(xdr, &res->seq_res, rqstp); 630 if (status) 631 goto out; 632 status = decode_putfh(xdr); 633 if (status) 634 goto out; 635 status = decode_seek(xdr, res); 636 out: 637 return status; 638 } 639 640 /* 641 * Decode LAYOUTSTATS request 642 */ 643 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, 644 struct xdr_stream *xdr, 645 void *data) 646 { 647 struct nfs42_layoutstat_res *res = data; 648 struct compound_hdr hdr; 649 int status, i; 650 651 status = decode_compound_hdr(xdr, &hdr); 652 if (status) 653 goto out; 654 status = decode_sequence(xdr, &res->seq_res, rqstp); 655 if (status) 656 goto out; 657 status = decode_putfh(xdr); 658 if (status) 659 goto out; 660 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 661 for (i = 0; i < res->num_dev; i++) { 662 status = decode_layoutstats(xdr); 663 if (status) 664 goto out; 665 } 666 out: 667 res->rpc_status = status; 668 return status; 669 } 670 671 /* 672 * Decode CLONE request 673 */ 674 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp, 675 struct xdr_stream *xdr, 676 void *data) 677 { 678 struct nfs42_clone_res *res = data; 679 struct compound_hdr hdr; 680 int status; 681 682 status = decode_compound_hdr(xdr, &hdr); 683 if (status) 684 goto out; 685 status = decode_sequence(xdr, &res->seq_res, rqstp); 686 if (status) 687 goto out; 688 status = decode_putfh(xdr); 689 if (status) 690 goto out; 691 status = decode_savefh(xdr); 692 if (status) 693 goto out; 694 status = decode_putfh(xdr); 695 if (status) 696 goto out; 697 status = decode_clone(xdr); 698 if (status) 699 goto out; 700 status = decode_getfattr(xdr, res->dst_fattr, res->server); 701 702 out: 703 res->rpc_status = status; 704 return status; 705 } 706 707 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ 708