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