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