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 /* Not limited by NFS itself, limited by the generic xattr code */ 11 #define nfs4_xattr_name_maxsz XDR_QUADLEN(XATTR_NAME_MAX) 12 13 #define encode_fallocate_maxsz (encode_stateid_maxsz + \ 14 2 /* offset */ + \ 15 2 /* length */) 16 #define NFS42_WRITE_RES_SIZE (1 /* wr_callback_id size */ +\ 17 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 18 2 /* wr_count */ + \ 19 1 /* wr_committed */ + \ 20 XDR_QUADLEN(NFS4_VERIFIER_SIZE)) 21 #define encode_allocate_maxsz (op_encode_hdr_maxsz + \ 22 encode_fallocate_maxsz) 23 #define decode_allocate_maxsz (op_decode_hdr_maxsz) 24 #define encode_copy_maxsz (op_encode_hdr_maxsz + \ 25 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 26 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 27 2 + 2 + 2 + 1 + 1 + 1 +\ 28 1 + /* One cnr_source_server */\ 29 1 + /* nl4_type */ \ 30 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) 31 #define decode_copy_maxsz (op_decode_hdr_maxsz + \ 32 NFS42_WRITE_RES_SIZE + \ 33 1 /* cr_consecutive */ + \ 34 1 /* cr_synchronous */) 35 #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \ 36 XDR_QUADLEN(NFS4_STATEID_SIZE)) 37 #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz) 38 #define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \ 39 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 40 1 + /* nl4_type */ \ 41 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) 42 #define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \ 43 3 + /* cnr_lease_time */\ 44 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 45 1 + /* Support 1 cnr_source_server */\ 46 1 + /* nl4_type */ \ 47 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) 48 #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ 49 encode_fallocate_maxsz) 50 #define decode_deallocate_maxsz (op_decode_hdr_maxsz) 51 #define encode_read_plus_maxsz (op_encode_hdr_maxsz + \ 52 encode_stateid_maxsz + 3) 53 #define NFS42_READ_PLUS_DATA_SEGMENT_SIZE \ 54 (1 /* data_content4 */ + \ 55 2 /* data_info4.di_offset */ + \ 56 1 /* data_info4.di_length */) 57 #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \ 58 1 /* rpr_eof */ + \ 59 1 /* rpr_contents count */ + \ 60 NFS42_READ_PLUS_DATA_SEGMENT_SIZE) 61 #define encode_seek_maxsz (op_encode_hdr_maxsz + \ 62 encode_stateid_maxsz + \ 63 2 /* offset */ + \ 64 1 /* whence */) 65 #define decode_seek_maxsz (op_decode_hdr_maxsz + \ 66 1 /* eof */ + \ 67 1 /* whence */ + \ 68 2 /* offset */ + \ 69 2 /* length */) 70 #define encode_io_info_maxsz 4 71 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \ 72 2 /* offset */ + \ 73 2 /* length */ + \ 74 encode_stateid_maxsz + \ 75 encode_io_info_maxsz + \ 76 encode_io_info_maxsz + \ 77 1 /* opaque devaddr4 length */ + \ 78 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE)) 79 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz) 80 #define encode_device_error_maxsz (XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \ 81 1 /* status */ + 1 /* opnum */) 82 #define encode_layouterror_maxsz (op_decode_hdr_maxsz + \ 83 2 /* offset */ + \ 84 2 /* length */ + \ 85 encode_stateid_maxsz + \ 86 1 /* Array size */ + \ 87 encode_device_error_maxsz) 88 #define decode_layouterror_maxsz (op_decode_hdr_maxsz) 89 #define encode_clone_maxsz (encode_stateid_maxsz + \ 90 encode_stateid_maxsz + \ 91 2 /* src offset */ + \ 92 2 /* dst offset */ + \ 93 2 /* count */) 94 #define decode_clone_maxsz (op_decode_hdr_maxsz) 95 #define encode_getxattr_maxsz (op_encode_hdr_maxsz + 1 + \ 96 nfs4_xattr_name_maxsz) 97 #define decode_getxattr_maxsz (op_decode_hdr_maxsz + 1 + pagepad_maxsz) 98 #define encode_setxattr_maxsz (op_encode_hdr_maxsz + \ 99 1 + nfs4_xattr_name_maxsz + 1) 100 #define decode_setxattr_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz) 101 #define encode_listxattrs_maxsz (op_encode_hdr_maxsz + 2 + 1) 102 #define decode_listxattrs_maxsz (op_decode_hdr_maxsz + 2 + 1 + 1 + 1) 103 #define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \ 104 nfs4_xattr_name_maxsz) 105 #define decode_removexattr_maxsz (op_decode_hdr_maxsz + \ 106 decode_change_info_maxsz) 107 108 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ 109 encode_sequence_maxsz + \ 110 encode_putfh_maxsz + \ 111 encode_allocate_maxsz + \ 112 encode_getattr_maxsz) 113 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ 114 decode_sequence_maxsz + \ 115 decode_putfh_maxsz + \ 116 decode_allocate_maxsz + \ 117 decode_getattr_maxsz) 118 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \ 119 encode_sequence_maxsz + \ 120 encode_putfh_maxsz + \ 121 encode_savefh_maxsz + \ 122 encode_putfh_maxsz + \ 123 encode_copy_maxsz + \ 124 encode_commit_maxsz) 125 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \ 126 decode_sequence_maxsz + \ 127 decode_putfh_maxsz + \ 128 decode_savefh_maxsz + \ 129 decode_putfh_maxsz + \ 130 decode_copy_maxsz + \ 131 decode_commit_maxsz) 132 #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \ 133 encode_sequence_maxsz + \ 134 encode_putfh_maxsz + \ 135 encode_offload_cancel_maxsz) 136 #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \ 137 decode_sequence_maxsz + \ 138 decode_putfh_maxsz + \ 139 decode_offload_cancel_maxsz) 140 #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \ 141 encode_putfh_maxsz + \ 142 encode_copy_notify_maxsz) 143 #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \ 144 decode_putfh_maxsz + \ 145 decode_copy_notify_maxsz) 146 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ 147 encode_sequence_maxsz + \ 148 encode_putfh_maxsz + \ 149 encode_deallocate_maxsz + \ 150 encode_getattr_maxsz) 151 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ 152 decode_sequence_maxsz + \ 153 decode_putfh_maxsz + \ 154 decode_deallocate_maxsz + \ 155 decode_getattr_maxsz) 156 #define NFS4_enc_read_plus_sz (compound_encode_hdr_maxsz + \ 157 encode_sequence_maxsz + \ 158 encode_putfh_maxsz + \ 159 encode_read_plus_maxsz) 160 #define NFS4_dec_read_plus_sz (compound_decode_hdr_maxsz + \ 161 decode_sequence_maxsz + \ 162 decode_putfh_maxsz + \ 163 decode_read_plus_maxsz) 164 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ 165 encode_sequence_maxsz + \ 166 encode_putfh_maxsz + \ 167 encode_seek_maxsz) 168 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \ 169 decode_sequence_maxsz + \ 170 decode_putfh_maxsz + \ 171 decode_seek_maxsz) 172 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \ 173 encode_sequence_maxsz + \ 174 encode_putfh_maxsz + \ 175 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz) 176 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \ 177 decode_sequence_maxsz + \ 178 decode_putfh_maxsz + \ 179 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz) 180 #define NFS4_enc_layouterror_sz (compound_encode_hdr_maxsz + \ 181 encode_sequence_maxsz + \ 182 encode_putfh_maxsz + \ 183 NFS42_LAYOUTERROR_MAX * \ 184 encode_layouterror_maxsz) 185 #define NFS4_dec_layouterror_sz (compound_decode_hdr_maxsz + \ 186 decode_sequence_maxsz + \ 187 decode_putfh_maxsz + \ 188 NFS42_LAYOUTERROR_MAX * \ 189 decode_layouterror_maxsz) 190 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \ 191 encode_sequence_maxsz + \ 192 encode_putfh_maxsz + \ 193 encode_savefh_maxsz + \ 194 encode_putfh_maxsz + \ 195 encode_clone_maxsz + \ 196 encode_getattr_maxsz) 197 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \ 198 decode_sequence_maxsz + \ 199 decode_putfh_maxsz + \ 200 decode_savefh_maxsz + \ 201 decode_putfh_maxsz + \ 202 decode_clone_maxsz + \ 203 decode_getattr_maxsz) 204 #define NFS4_enc_getxattr_sz (compound_encode_hdr_maxsz + \ 205 encode_sequence_maxsz + \ 206 encode_putfh_maxsz + \ 207 encode_getxattr_maxsz) 208 #define NFS4_dec_getxattr_sz (compound_decode_hdr_maxsz + \ 209 decode_sequence_maxsz + \ 210 decode_putfh_maxsz + \ 211 decode_getxattr_maxsz) 212 #define NFS4_enc_setxattr_sz (compound_encode_hdr_maxsz + \ 213 encode_sequence_maxsz + \ 214 encode_putfh_maxsz + \ 215 encode_setxattr_maxsz + \ 216 encode_getattr_maxsz) 217 #define NFS4_dec_setxattr_sz (compound_decode_hdr_maxsz + \ 218 decode_sequence_maxsz + \ 219 decode_putfh_maxsz + \ 220 decode_setxattr_maxsz + \ 221 decode_getattr_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 /* 711 * Encode SETXATTR request 712 */ 713 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 714 const void *data) 715 { 716 const struct nfs42_setxattrargs *args = data; 717 struct compound_hdr hdr = { 718 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 719 }; 720 721 encode_compound_hdr(xdr, req, &hdr); 722 encode_sequence(xdr, &args->seq_args, &hdr); 723 encode_putfh(xdr, args->fh, &hdr); 724 encode_setxattr(xdr, args, &hdr); 725 encode_getfattr(xdr, args->bitmask, &hdr); 726 encode_nops(&hdr); 727 } 728 729 /* 730 * Encode GETXATTR request 731 */ 732 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 733 const void *data) 734 { 735 const struct nfs42_getxattrargs *args = data; 736 struct compound_hdr hdr = { 737 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 738 }; 739 uint32_t replen; 740 741 encode_compound_hdr(xdr, req, &hdr); 742 encode_sequence(xdr, &args->seq_args, &hdr); 743 encode_putfh(xdr, args->fh, &hdr); 744 replen = hdr.replen + op_decode_hdr_maxsz + 1; 745 encode_getxattr(xdr, args->xattr_name, &hdr); 746 747 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len, 748 replen); 749 750 encode_nops(&hdr); 751 } 752 753 /* 754 * Encode LISTXATTR request 755 */ 756 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req, 757 struct xdr_stream *xdr, const void *data) 758 { 759 const struct nfs42_listxattrsargs *args = data; 760 struct compound_hdr hdr = { 761 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 762 }; 763 uint32_t replen; 764 765 encode_compound_hdr(xdr, req, &hdr); 766 encode_sequence(xdr, &args->seq_args, &hdr); 767 encode_putfh(xdr, args->fh, &hdr); 768 replen = hdr.replen + op_decode_hdr_maxsz + 2 + 1; 769 encode_listxattrs(xdr, args, &hdr); 770 771 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen); 772 773 encode_nops(&hdr); 774 } 775 776 /* 777 * Encode REMOVEXATTR request 778 */ 779 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req, 780 struct xdr_stream *xdr, const void *data) 781 { 782 const struct nfs42_removexattrargs *args = data; 783 struct compound_hdr hdr = { 784 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 785 }; 786 787 encode_compound_hdr(xdr, req, &hdr); 788 encode_sequence(xdr, &args->seq_args, &hdr); 789 encode_putfh(xdr, args->fh, &hdr); 790 encode_removexattr(xdr, args->xattr_name, &hdr); 791 encode_nops(&hdr); 792 } 793 794 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 795 { 796 return decode_op_hdr(xdr, OP_ALLOCATE); 797 } 798 799 static int decode_write_response(struct xdr_stream *xdr, 800 struct nfs42_write_res *res) 801 { 802 __be32 *p; 803 int status, count; 804 805 p = xdr_inline_decode(xdr, 4); 806 if (unlikely(!p)) 807 return -EIO; 808 count = be32_to_cpup(p); 809 if (count > 1) 810 return -EREMOTEIO; 811 else if (count == 1) { 812 status = decode_opaque_fixed(xdr, &res->stateid, 813 NFS4_STATEID_SIZE); 814 if (unlikely(status)) 815 return -EIO; 816 } 817 p = xdr_inline_decode(xdr, 8 + 4); 818 if (unlikely(!p)) 819 return -EIO; 820 p = xdr_decode_hyper(p, &res->count); 821 res->verifier.committed = be32_to_cpup(p); 822 return decode_verifier(xdr, &res->verifier.verifier); 823 } 824 825 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns) 826 { 827 struct nfs42_netaddr *naddr; 828 uint32_t dummy; 829 char *dummy_str; 830 __be32 *p; 831 int status; 832 833 /* nl_type */ 834 p = xdr_inline_decode(xdr, 4); 835 if (unlikely(!p)) 836 return -EIO; 837 ns->nl4_type = be32_to_cpup(p); 838 switch (ns->nl4_type) { 839 case NL4_NAME: 840 case NL4_URL: 841 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 842 if (unlikely(status)) 843 return status; 844 if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) 845 return -EIO; 846 memcpy(&ns->u.nl4_str, dummy_str, dummy); 847 ns->u.nl4_str_sz = dummy; 848 break; 849 case NL4_NETADDR: 850 naddr = &ns->u.nl4_addr; 851 852 /* netid string */ 853 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 854 if (unlikely(status)) 855 return status; 856 if (unlikely(dummy > RPCBIND_MAXNETIDLEN)) 857 return -EIO; 858 naddr->netid_len = dummy; 859 memcpy(naddr->netid, dummy_str, naddr->netid_len); 860 861 /* uaddr string */ 862 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 863 if (unlikely(status)) 864 return status; 865 if (unlikely(dummy > RPCBIND_MAXUADDRLEN)) 866 return -EIO; 867 naddr->addr_len = dummy; 868 memcpy(naddr->addr, dummy_str, naddr->addr_len); 869 break; 870 default: 871 WARN_ON_ONCE(1); 872 return -EIO; 873 } 874 return 0; 875 } 876 877 static int decode_copy_requirements(struct xdr_stream *xdr, 878 struct nfs42_copy_res *res) { 879 __be32 *p; 880 881 p = xdr_inline_decode(xdr, 4 + 4); 882 if (unlikely(!p)) 883 return -EIO; 884 885 res->consecutive = be32_to_cpup(p++); 886 res->synchronous = be32_to_cpup(p++); 887 return 0; 888 } 889 890 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) 891 { 892 int status; 893 894 status = decode_op_hdr(xdr, OP_COPY); 895 if (status == NFS4ERR_OFFLOAD_NO_REQS) { 896 status = decode_copy_requirements(xdr, res); 897 if (status) 898 return status; 899 return NFS4ERR_OFFLOAD_NO_REQS; 900 } else if (status) 901 return status; 902 903 status = decode_write_response(xdr, &res->write_res); 904 if (status) 905 return status; 906 907 return decode_copy_requirements(xdr, res); 908 } 909 910 static int decode_offload_cancel(struct xdr_stream *xdr, 911 struct nfs42_offload_status_res *res) 912 { 913 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); 914 } 915 916 static int decode_copy_notify(struct xdr_stream *xdr, 917 struct nfs42_copy_notify_res *res) 918 { 919 __be32 *p; 920 int status, count; 921 922 status = decode_op_hdr(xdr, OP_COPY_NOTIFY); 923 if (status) 924 return status; 925 /* cnr_lease_time */ 926 p = xdr_inline_decode(xdr, 12); 927 if (unlikely(!p)) 928 return -EIO; 929 p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds); 930 res->cnr_lease_time.nseconds = be32_to_cpup(p); 931 932 status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE); 933 if (unlikely(status)) 934 return -EIO; 935 936 /* number of source addresses */ 937 p = xdr_inline_decode(xdr, 4); 938 if (unlikely(!p)) 939 return -EIO; 940 941 count = be32_to_cpup(p); 942 if (count > 1) 943 pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n", 944 __func__, count); 945 946 status = decode_nl4_server(xdr, &res->cnr_src); 947 if (unlikely(status)) 948 return -EIO; 949 return 0; 950 } 951 952 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 953 { 954 return decode_op_hdr(xdr, OP_DEALLOCATE); 955 } 956 957 struct read_plus_segment { 958 enum data_content4 type; 959 uint64_t offset; 960 union { 961 struct { 962 uint64_t length; 963 } hole; 964 965 struct { 966 uint32_t length; 967 unsigned int from; 968 } data; 969 }; 970 }; 971 972 static inline uint64_t read_plus_segment_length(struct read_plus_segment *seg) 973 { 974 return seg->type == NFS4_CONTENT_DATA ? seg->data.length : seg->hole.length; 975 } 976 977 static int decode_read_plus_segment(struct xdr_stream *xdr, 978 struct read_plus_segment *seg) 979 { 980 __be32 *p; 981 982 p = xdr_inline_decode(xdr, 4); 983 if (!p) 984 return -EIO; 985 seg->type = be32_to_cpup(p++); 986 987 p = xdr_inline_decode(xdr, seg->type == NFS4_CONTENT_DATA ? 12 : 16); 988 if (!p) 989 return -EIO; 990 p = xdr_decode_hyper(p, &seg->offset); 991 992 if (seg->type == NFS4_CONTENT_DATA) { 993 struct xdr_buf buf; 994 uint32_t len = be32_to_cpup(p); 995 996 seg->data.length = len; 997 seg->data.from = xdr_stream_pos(xdr); 998 999 if (!xdr_stream_subsegment(xdr, &buf, xdr_align_size(len))) 1000 return -EIO; 1001 } else if (seg->type == NFS4_CONTENT_HOLE) { 1002 xdr_decode_hyper(p, &seg->hole.length); 1003 } else 1004 return -EINVAL; 1005 return 0; 1006 } 1007 1008 static int process_read_plus_segment(struct xdr_stream *xdr, 1009 struct nfs_pgio_args *args, 1010 struct nfs_pgio_res *res, 1011 struct read_plus_segment *seg) 1012 { 1013 unsigned long offset = seg->offset; 1014 unsigned long length = read_plus_segment_length(seg); 1015 unsigned int bufpos; 1016 1017 if (offset + length < args->offset) 1018 return 0; 1019 else if (offset > args->offset + args->count) { 1020 res->eof = 0; 1021 return 0; 1022 } else if (offset < args->offset) { 1023 length -= (args->offset - offset); 1024 offset = args->offset; 1025 } else if (offset + length > args->offset + args->count) { 1026 length = (args->offset + args->count) - offset; 1027 res->eof = 0; 1028 } 1029 1030 bufpos = xdr->buf->head[0].iov_len + (offset - args->offset); 1031 if (seg->type == NFS4_CONTENT_HOLE) 1032 return xdr_stream_zero(xdr, bufpos, length); 1033 else 1034 return xdr_stream_move_subsegment(xdr, seg->data.from, bufpos, length); 1035 } 1036 1037 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) 1038 { 1039 struct nfs_pgio_header *hdr = 1040 container_of(res, struct nfs_pgio_header, res); 1041 struct nfs_pgio_args *args = &hdr->args; 1042 uint32_t segments; 1043 struct read_plus_segment *segs; 1044 int status, i; 1045 __be32 *p; 1046 1047 status = decode_op_hdr(xdr, OP_READ_PLUS); 1048 if (status) 1049 return status; 1050 1051 p = xdr_inline_decode(xdr, 4 + 4); 1052 if (unlikely(!p)) 1053 return -EIO; 1054 1055 res->count = 0; 1056 res->eof = be32_to_cpup(p++); 1057 segments = be32_to_cpup(p++); 1058 if (segments == 0) 1059 return status; 1060 1061 segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL); 1062 if (!segs) 1063 return -ENOMEM; 1064 1065 status = -EIO; 1066 for (i = 0; i < segments; i++) { 1067 status = decode_read_plus_segment(xdr, &segs[i]); 1068 if (status < 0) 1069 goto out; 1070 } 1071 1072 xdr_set_pagelen(xdr, xdr_align_size(args->count)); 1073 for (i = segments; i > 0; i--) 1074 res->count += process_read_plus_segment(xdr, args, res, &segs[i-1]); 1075 status = 0; 1076 1077 out: 1078 kfree(segs); 1079 return status; 1080 } 1081 1082 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) 1083 { 1084 int status; 1085 __be32 *p; 1086 1087 status = decode_op_hdr(xdr, OP_SEEK); 1088 if (status) 1089 return status; 1090 1091 p = xdr_inline_decode(xdr, 4 + 8); 1092 if (unlikely(!p)) 1093 return -EIO; 1094 1095 res->sr_eof = be32_to_cpup(p++); 1096 p = xdr_decode_hyper(p, &res->sr_offset); 1097 return 0; 1098 } 1099 1100 static int decode_layoutstats(struct xdr_stream *xdr) 1101 { 1102 return decode_op_hdr(xdr, OP_LAYOUTSTATS); 1103 } 1104 1105 static int decode_clone(struct xdr_stream *xdr) 1106 { 1107 return decode_op_hdr(xdr, OP_CLONE); 1108 } 1109 1110 static int decode_layouterror(struct xdr_stream *xdr) 1111 { 1112 return decode_op_hdr(xdr, OP_LAYOUTERROR); 1113 } 1114 1115 static int decode_setxattr(struct xdr_stream *xdr, 1116 struct nfs4_change_info *cinfo) 1117 { 1118 int status; 1119 1120 status = decode_op_hdr(xdr, OP_SETXATTR); 1121 if (status) 1122 goto out; 1123 status = decode_change_info(xdr, cinfo); 1124 out: 1125 return status; 1126 } 1127 1128 static int decode_getxattr(struct xdr_stream *xdr, 1129 struct nfs42_getxattrres *res, 1130 struct rpc_rqst *req) 1131 { 1132 int status; 1133 __be32 *p; 1134 u32 len, rdlen; 1135 1136 status = decode_op_hdr(xdr, OP_GETXATTR); 1137 if (status) 1138 return status; 1139 1140 p = xdr_inline_decode(xdr, 4); 1141 if (unlikely(!p)) 1142 return -EIO; 1143 1144 len = be32_to_cpup(p); 1145 1146 /* 1147 * Only check against the page length here. The actual 1148 * requested length may be smaller, but that is only 1149 * checked against after possibly caching a valid reply. 1150 */ 1151 if (len > req->rq_rcv_buf.page_len) 1152 return -ERANGE; 1153 1154 res->xattr_len = len; 1155 1156 if (len > 0) { 1157 rdlen = xdr_read_pages(xdr, len); 1158 if (rdlen < len) 1159 return -EIO; 1160 } 1161 1162 return 0; 1163 } 1164 1165 static int decode_removexattr(struct xdr_stream *xdr, 1166 struct nfs4_change_info *cinfo) 1167 { 1168 int status; 1169 1170 status = decode_op_hdr(xdr, OP_REMOVEXATTR); 1171 if (status) 1172 goto out; 1173 1174 status = decode_change_info(xdr, cinfo); 1175 out: 1176 return status; 1177 } 1178 1179 static int decode_listxattrs(struct xdr_stream *xdr, 1180 struct nfs42_listxattrsres *res) 1181 { 1182 int status; 1183 __be32 *p; 1184 u32 count, len, ulen; 1185 size_t left, copied; 1186 char *buf; 1187 1188 status = decode_op_hdr(xdr, OP_LISTXATTRS); 1189 if (status) { 1190 /* 1191 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL 1192 * should be translated to ERANGE. 1193 */ 1194 if (status == -ETOOSMALL) 1195 status = -ERANGE; 1196 /* 1197 * Special case: for LISTXATTRS, NFS4ERR_NOXATTR 1198 * should be translated to success with zero-length reply. 1199 */ 1200 if (status == -ENODATA) { 1201 res->eof = true; 1202 status = 0; 1203 } 1204 goto out; 1205 } 1206 1207 p = xdr_inline_decode(xdr, 8); 1208 if (unlikely(!p)) 1209 return -EIO; 1210 1211 xdr_decode_hyper(p, &res->cookie); 1212 1213 p = xdr_inline_decode(xdr, 4); 1214 if (unlikely(!p)) 1215 return -EIO; 1216 1217 left = res->xattr_len; 1218 buf = res->xattr_buf; 1219 1220 count = be32_to_cpup(p); 1221 copied = 0; 1222 1223 /* 1224 * We have asked for enough room to encode the maximum number 1225 * of possible attribute names, so everything should fit. 1226 * 1227 * But, don't rely on that assumption. Just decode entries 1228 * until they don't fit anymore, just in case the server did 1229 * something odd. 1230 */ 1231 while (count--) { 1232 p = xdr_inline_decode(xdr, 4); 1233 if (unlikely(!p)) 1234 return -EIO; 1235 1236 len = be32_to_cpup(p); 1237 if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) { 1238 status = -ERANGE; 1239 goto out; 1240 } 1241 1242 p = xdr_inline_decode(xdr, len); 1243 if (unlikely(!p)) 1244 return -EIO; 1245 1246 ulen = len + XATTR_USER_PREFIX_LEN + 1; 1247 if (buf) { 1248 if (ulen > left) { 1249 status = -ERANGE; 1250 goto out; 1251 } 1252 1253 memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); 1254 memcpy(buf + XATTR_USER_PREFIX_LEN, p, len); 1255 1256 buf[ulen - 1] = 0; 1257 buf += ulen; 1258 left -= ulen; 1259 } 1260 copied += ulen; 1261 } 1262 1263 p = xdr_inline_decode(xdr, 4); 1264 if (unlikely(!p)) 1265 return -EIO; 1266 1267 res->eof = be32_to_cpup(p); 1268 res->copied = copied; 1269 1270 out: 1271 if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX) 1272 status = -E2BIG; 1273 1274 return status; 1275 } 1276 1277 /* 1278 * Decode ALLOCATE request 1279 */ 1280 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, 1281 struct xdr_stream *xdr, 1282 void *data) 1283 { 1284 struct nfs42_falloc_res *res = data; 1285 struct compound_hdr hdr; 1286 int status; 1287 1288 status = decode_compound_hdr(xdr, &hdr); 1289 if (status) 1290 goto out; 1291 status = decode_sequence(xdr, &res->seq_res, rqstp); 1292 if (status) 1293 goto out; 1294 status = decode_putfh(xdr); 1295 if (status) 1296 goto out; 1297 status = decode_allocate(xdr, res); 1298 if (status) 1299 goto out; 1300 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 1301 out: 1302 return status; 1303 } 1304 1305 /* 1306 * Decode COPY response 1307 */ 1308 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp, 1309 struct xdr_stream *xdr, 1310 void *data) 1311 { 1312 struct nfs42_copy_res *res = data; 1313 struct compound_hdr hdr; 1314 int status; 1315 1316 status = decode_compound_hdr(xdr, &hdr); 1317 if (status) 1318 goto out; 1319 status = decode_sequence(xdr, &res->seq_res, rqstp); 1320 if (status) 1321 goto out; 1322 status = decode_putfh(xdr); 1323 if (status) 1324 goto out; 1325 status = decode_savefh(xdr); 1326 if (status) 1327 goto out; 1328 status = decode_putfh(xdr); 1329 if (status) 1330 goto out; 1331 status = decode_copy(xdr, res); 1332 if (status) 1333 goto out; 1334 if (res->commit_res.verf) 1335 status = decode_commit(xdr, &res->commit_res); 1336 out: 1337 return status; 1338 } 1339 1340 /* 1341 * Decode OFFLOAD_CANCEL response 1342 */ 1343 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp, 1344 struct xdr_stream *xdr, 1345 void *data) 1346 { 1347 struct nfs42_offload_status_res *res = data; 1348 struct compound_hdr hdr; 1349 int status; 1350 1351 status = decode_compound_hdr(xdr, &hdr); 1352 if (status) 1353 goto out; 1354 status = decode_sequence(xdr, &res->osr_seq_res, rqstp); 1355 if (status) 1356 goto out; 1357 status = decode_putfh(xdr); 1358 if (status) 1359 goto out; 1360 status = decode_offload_cancel(xdr, res); 1361 1362 out: 1363 return status; 1364 } 1365 1366 /* 1367 * Decode COPY_NOTIFY response 1368 */ 1369 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp, 1370 struct xdr_stream *xdr, 1371 void *data) 1372 { 1373 struct nfs42_copy_notify_res *res = data; 1374 struct compound_hdr hdr; 1375 int status; 1376 1377 status = decode_compound_hdr(xdr, &hdr); 1378 if (status) 1379 goto out; 1380 status = decode_sequence(xdr, &res->cnr_seq_res, rqstp); 1381 if (status) 1382 goto out; 1383 status = decode_putfh(xdr); 1384 if (status) 1385 goto out; 1386 status = decode_copy_notify(xdr, res); 1387 1388 out: 1389 return status; 1390 } 1391 1392 /* 1393 * Decode DEALLOCATE request 1394 */ 1395 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, 1396 struct xdr_stream *xdr, 1397 void *data) 1398 { 1399 struct nfs42_falloc_res *res = data; 1400 struct compound_hdr hdr; 1401 int status; 1402 1403 status = decode_compound_hdr(xdr, &hdr); 1404 if (status) 1405 goto out; 1406 status = decode_sequence(xdr, &res->seq_res, rqstp); 1407 if (status) 1408 goto out; 1409 status = decode_putfh(xdr); 1410 if (status) 1411 goto out; 1412 status = decode_deallocate(xdr, res); 1413 if (status) 1414 goto out; 1415 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 1416 out: 1417 return status; 1418 } 1419 1420 /* 1421 * Decode READ_PLUS request 1422 */ 1423 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp, 1424 struct xdr_stream *xdr, 1425 void *data) 1426 { 1427 struct nfs_pgio_res *res = data; 1428 struct compound_hdr hdr; 1429 int status; 1430 1431 xdr_set_scratch_buffer(xdr, res->scratch, sizeof(res->scratch)); 1432 1433 status = decode_compound_hdr(xdr, &hdr); 1434 if (status) 1435 goto out; 1436 status = decode_sequence(xdr, &res->seq_res, rqstp); 1437 if (status) 1438 goto out; 1439 status = decode_putfh(xdr); 1440 if (status) 1441 goto out; 1442 status = decode_read_plus(xdr, res); 1443 if (!status) 1444 status = res->count; 1445 out: 1446 return status; 1447 } 1448 1449 /* 1450 * Decode SEEK request 1451 */ 1452 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, 1453 struct xdr_stream *xdr, 1454 void *data) 1455 { 1456 struct nfs42_seek_res *res = data; 1457 struct compound_hdr hdr; 1458 int status; 1459 1460 status = decode_compound_hdr(xdr, &hdr); 1461 if (status) 1462 goto out; 1463 status = decode_sequence(xdr, &res->seq_res, rqstp); 1464 if (status) 1465 goto out; 1466 status = decode_putfh(xdr); 1467 if (status) 1468 goto out; 1469 status = decode_seek(xdr, res); 1470 out: 1471 return status; 1472 } 1473 1474 /* 1475 * Decode LAYOUTSTATS request 1476 */ 1477 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, 1478 struct xdr_stream *xdr, 1479 void *data) 1480 { 1481 struct nfs42_layoutstat_res *res = data; 1482 struct compound_hdr hdr; 1483 int status, i; 1484 1485 status = decode_compound_hdr(xdr, &hdr); 1486 if (status) 1487 goto out; 1488 status = decode_sequence(xdr, &res->seq_res, rqstp); 1489 if (status) 1490 goto out; 1491 status = decode_putfh(xdr); 1492 if (status) 1493 goto out; 1494 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 1495 for (i = 0; i < res->num_dev; i++) { 1496 status = decode_layoutstats(xdr); 1497 if (status) 1498 goto out; 1499 } 1500 out: 1501 res->rpc_status = status; 1502 return status; 1503 } 1504 1505 /* 1506 * Decode CLONE request 1507 */ 1508 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp, 1509 struct xdr_stream *xdr, 1510 void *data) 1511 { 1512 struct nfs42_clone_res *res = data; 1513 struct compound_hdr hdr; 1514 int status; 1515 1516 status = decode_compound_hdr(xdr, &hdr); 1517 if (status) 1518 goto out; 1519 status = decode_sequence(xdr, &res->seq_res, rqstp); 1520 if (status) 1521 goto out; 1522 status = decode_putfh(xdr); 1523 if (status) 1524 goto out; 1525 status = decode_savefh(xdr); 1526 if (status) 1527 goto out; 1528 status = decode_putfh(xdr); 1529 if (status) 1530 goto out; 1531 status = decode_clone(xdr); 1532 if (status) 1533 goto out; 1534 decode_getfattr(xdr, res->dst_fattr, res->server); 1535 out: 1536 res->rpc_status = status; 1537 return status; 1538 } 1539 1540 /* 1541 * Decode LAYOUTERROR request 1542 */ 1543 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp, 1544 struct xdr_stream *xdr, 1545 void *data) 1546 { 1547 struct nfs42_layouterror_res *res = data; 1548 struct compound_hdr hdr; 1549 int status, i; 1550 1551 status = decode_compound_hdr(xdr, &hdr); 1552 if (status) 1553 goto out; 1554 status = decode_sequence(xdr, &res->seq_res, rqstp); 1555 if (status) 1556 goto out; 1557 status = decode_putfh(xdr); 1558 1559 for (i = 0; i < res->num_errors && status == 0; i++) 1560 status = decode_layouterror(xdr); 1561 out: 1562 res->rpc_status = status; 1563 return status; 1564 } 1565 1566 /* 1567 * Decode SETXATTR request 1568 */ 1569 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 1570 void *data) 1571 { 1572 struct nfs42_setxattrres *res = data; 1573 struct compound_hdr hdr; 1574 int status; 1575 1576 status = decode_compound_hdr(xdr, &hdr); 1577 if (status) 1578 goto out; 1579 status = decode_sequence(xdr, &res->seq_res, req); 1580 if (status) 1581 goto out; 1582 status = decode_putfh(xdr); 1583 if (status) 1584 goto out; 1585 status = decode_setxattr(xdr, &res->cinfo); 1586 if (status) 1587 goto out; 1588 status = decode_getfattr(xdr, res->fattr, res->server); 1589 out: 1590 return status; 1591 } 1592 1593 /* 1594 * Decode GETXATTR request 1595 */ 1596 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp, 1597 struct xdr_stream *xdr, void *data) 1598 { 1599 struct nfs42_getxattrres *res = data; 1600 struct compound_hdr hdr; 1601 int status; 1602 1603 status = decode_compound_hdr(xdr, &hdr); 1604 if (status) 1605 goto out; 1606 status = decode_sequence(xdr, &res->seq_res, rqstp); 1607 if (status) 1608 goto out; 1609 status = decode_putfh(xdr); 1610 if (status) 1611 goto out; 1612 status = decode_getxattr(xdr, res, rqstp); 1613 out: 1614 return status; 1615 } 1616 1617 /* 1618 * Decode LISTXATTR request 1619 */ 1620 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp, 1621 struct xdr_stream *xdr, void *data) 1622 { 1623 struct nfs42_listxattrsres *res = data; 1624 struct compound_hdr hdr; 1625 int status; 1626 1627 xdr_set_scratch_page(xdr, res->scratch); 1628 1629 status = decode_compound_hdr(xdr, &hdr); 1630 if (status) 1631 goto out; 1632 status = decode_sequence(xdr, &res->seq_res, rqstp); 1633 if (status) 1634 goto out; 1635 status = decode_putfh(xdr); 1636 if (status) 1637 goto out; 1638 status = decode_listxattrs(xdr, res); 1639 out: 1640 return status; 1641 } 1642 1643 /* 1644 * Decode REMOVEXATTR request 1645 */ 1646 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req, 1647 struct xdr_stream *xdr, void *data) 1648 { 1649 struct nfs42_removexattrres *res = data; 1650 struct compound_hdr hdr; 1651 int status; 1652 1653 status = decode_compound_hdr(xdr, &hdr); 1654 if (status) 1655 goto out; 1656 status = decode_sequence(xdr, &res->seq_res, req); 1657 if (status) 1658 goto out; 1659 status = decode_putfh(xdr); 1660 if (status) 1661 goto out; 1662 1663 status = decode_removexattr(xdr, &res->cinfo); 1664 out: 1665 return status; 1666 } 1667 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ 1668