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_offload_status_maxsz (op_encode_hdr_maxsz + \ 39 XDR_QUADLEN(NFS4_STATEID_SIZE)) 40 #define decode_offload_status_maxsz (op_decode_hdr_maxsz + \ 41 2 /* osr_count */ + \ 42 2 /* osr_complete */) 43 #define encode_copy_notify_maxsz (op_encode_hdr_maxsz + \ 44 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 45 1 + /* nl4_type */ \ 46 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) 47 #define decode_copy_notify_maxsz (op_decode_hdr_maxsz + \ 48 3 + /* cnr_lease_time */\ 49 XDR_QUADLEN(NFS4_STATEID_SIZE) + \ 50 1 + /* Support 1 cnr_source_server */\ 51 1 + /* nl4_type */ \ 52 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) 53 #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ 54 encode_fallocate_maxsz) 55 #define decode_deallocate_maxsz (op_decode_hdr_maxsz) 56 #define encode_read_plus_maxsz (op_encode_hdr_maxsz + \ 57 encode_stateid_maxsz + 3) 58 #define NFS42_READ_PLUS_DATA_SEGMENT_SIZE \ 59 (1 /* data_content4 */ + \ 60 2 /* data_info4.di_offset */ + \ 61 1 /* data_info4.di_length */) 62 #define NFS42_READ_PLUS_HOLE_SEGMENT_SIZE \ 63 (1 /* data_content4 */ + \ 64 2 /* data_info4.di_offset */ + \ 65 2 /* data_info4.di_length */) 66 #define READ_PLUS_SEGMENT_SIZE_DIFF (NFS42_READ_PLUS_HOLE_SEGMENT_SIZE - \ 67 NFS42_READ_PLUS_DATA_SEGMENT_SIZE) 68 #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \ 69 1 /* rpr_eof */ + \ 70 1 /* rpr_contents count */ + \ 71 NFS42_READ_PLUS_HOLE_SEGMENT_SIZE) 72 #define encode_seek_maxsz (op_encode_hdr_maxsz + \ 73 encode_stateid_maxsz + \ 74 2 /* offset */ + \ 75 1 /* whence */) 76 #define decode_seek_maxsz (op_decode_hdr_maxsz + \ 77 1 /* eof */ + \ 78 1 /* whence */ + \ 79 2 /* offset */ + \ 80 2 /* length */) 81 #define encode_io_info_maxsz 4 82 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \ 83 2 /* offset */ + \ 84 2 /* length */ + \ 85 encode_stateid_maxsz + \ 86 encode_io_info_maxsz + \ 87 encode_io_info_maxsz + \ 88 1 /* opaque devaddr4 length */ + \ 89 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE)) 90 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz) 91 #define encode_device_error_maxsz (XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \ 92 1 /* status */ + 1 /* opnum */) 93 #define encode_layouterror_maxsz (op_decode_hdr_maxsz + \ 94 2 /* offset */ + \ 95 2 /* length */ + \ 96 encode_stateid_maxsz + \ 97 1 /* Array size */ + \ 98 encode_device_error_maxsz) 99 #define decode_layouterror_maxsz (op_decode_hdr_maxsz) 100 #define encode_clone_maxsz (encode_stateid_maxsz + \ 101 encode_stateid_maxsz + \ 102 2 /* src offset */ + \ 103 2 /* dst offset */ + \ 104 2 /* count */) 105 #define decode_clone_maxsz (op_decode_hdr_maxsz) 106 #define encode_getxattr_maxsz (op_encode_hdr_maxsz + 1 + \ 107 nfs4_xattr_name_maxsz) 108 #define decode_getxattr_maxsz (op_decode_hdr_maxsz + 1 + pagepad_maxsz) 109 #define encode_setxattr_maxsz (op_encode_hdr_maxsz + \ 110 1 + nfs4_xattr_name_maxsz + 1) 111 #define decode_setxattr_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz) 112 #define encode_listxattrs_maxsz (op_encode_hdr_maxsz + 2 + 1) 113 #define decode_listxattrs_maxsz (op_decode_hdr_maxsz + 2 + 1 + 1 + 1) 114 #define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \ 115 nfs4_xattr_name_maxsz) 116 #define decode_removexattr_maxsz (op_decode_hdr_maxsz + \ 117 decode_change_info_maxsz) 118 119 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ 120 encode_sequence_maxsz + \ 121 encode_putfh_maxsz + \ 122 encode_allocate_maxsz + \ 123 encode_getattr_maxsz) 124 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ 125 decode_sequence_maxsz + \ 126 decode_putfh_maxsz + \ 127 decode_allocate_maxsz + \ 128 decode_getattr_maxsz) 129 #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \ 130 encode_sequence_maxsz + \ 131 encode_putfh_maxsz + \ 132 encode_savefh_maxsz + \ 133 encode_putfh_maxsz + \ 134 encode_copy_maxsz + \ 135 encode_commit_maxsz) 136 #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \ 137 decode_sequence_maxsz + \ 138 decode_putfh_maxsz + \ 139 decode_savefh_maxsz + \ 140 decode_putfh_maxsz + \ 141 decode_copy_maxsz + \ 142 decode_commit_maxsz) 143 #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \ 144 encode_sequence_maxsz + \ 145 encode_putfh_maxsz + \ 146 encode_offload_cancel_maxsz) 147 #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \ 148 decode_sequence_maxsz + \ 149 decode_putfh_maxsz + \ 150 decode_offload_cancel_maxsz) 151 #define NFS4_enc_offload_status_sz (compound_encode_hdr_maxsz + \ 152 encode_sequence_maxsz + \ 153 encode_putfh_maxsz + \ 154 encode_offload_status_maxsz) 155 #define NFS4_dec_offload_status_sz (compound_decode_hdr_maxsz + \ 156 decode_sequence_maxsz + \ 157 decode_putfh_maxsz + \ 158 decode_offload_status_maxsz) 159 #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \ 160 encode_sequence_maxsz + \ 161 encode_putfh_maxsz + \ 162 encode_copy_notify_maxsz) 163 #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \ 164 decode_sequence_maxsz + \ 165 decode_putfh_maxsz + \ 166 decode_copy_notify_maxsz) 167 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ 168 encode_sequence_maxsz + \ 169 encode_putfh_maxsz + \ 170 encode_deallocate_maxsz + \ 171 encode_getattr_maxsz) 172 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ 173 decode_sequence_maxsz + \ 174 decode_putfh_maxsz + \ 175 decode_deallocate_maxsz + \ 176 decode_getattr_maxsz) 177 #define NFS4_enc_zero_range_sz (compound_encode_hdr_maxsz + \ 178 encode_sequence_maxsz + \ 179 encode_putfh_maxsz + \ 180 encode_deallocate_maxsz + \ 181 encode_allocate_maxsz + \ 182 encode_getattr_maxsz) 183 #define NFS4_dec_zero_range_sz (compound_decode_hdr_maxsz + \ 184 decode_sequence_maxsz + \ 185 decode_putfh_maxsz + \ 186 decode_deallocate_maxsz + \ 187 decode_allocate_maxsz + \ 188 decode_getattr_maxsz) 189 #define NFS4_enc_read_plus_sz (compound_encode_hdr_maxsz + \ 190 encode_sequence_maxsz + \ 191 encode_putfh_maxsz + \ 192 encode_read_plus_maxsz) 193 #define NFS4_dec_read_plus_sz (compound_decode_hdr_maxsz + \ 194 decode_sequence_maxsz + \ 195 decode_putfh_maxsz + \ 196 decode_read_plus_maxsz) 197 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ 198 encode_sequence_maxsz + \ 199 encode_putfh_maxsz + \ 200 encode_seek_maxsz) 201 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \ 202 decode_sequence_maxsz + \ 203 decode_putfh_maxsz + \ 204 decode_seek_maxsz) 205 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \ 206 encode_sequence_maxsz + \ 207 encode_putfh_maxsz + \ 208 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz) 209 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \ 210 decode_sequence_maxsz + \ 211 decode_putfh_maxsz + \ 212 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz) 213 #define NFS4_enc_layouterror_sz (compound_encode_hdr_maxsz + \ 214 encode_sequence_maxsz + \ 215 encode_putfh_maxsz + \ 216 NFS42_LAYOUTERROR_MAX * \ 217 encode_layouterror_maxsz) 218 #define NFS4_dec_layouterror_sz (compound_decode_hdr_maxsz + \ 219 decode_sequence_maxsz + \ 220 decode_putfh_maxsz + \ 221 NFS42_LAYOUTERROR_MAX * \ 222 decode_layouterror_maxsz) 223 #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \ 224 encode_sequence_maxsz + \ 225 encode_putfh_maxsz + \ 226 encode_savefh_maxsz + \ 227 encode_putfh_maxsz + \ 228 encode_clone_maxsz + \ 229 encode_getattr_maxsz) 230 #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \ 231 decode_sequence_maxsz + \ 232 decode_putfh_maxsz + \ 233 decode_savefh_maxsz + \ 234 decode_putfh_maxsz + \ 235 decode_clone_maxsz + \ 236 decode_getattr_maxsz) 237 #define NFS4_enc_getxattr_sz (compound_encode_hdr_maxsz + \ 238 encode_sequence_maxsz + \ 239 encode_putfh_maxsz + \ 240 encode_getxattr_maxsz) 241 #define NFS4_dec_getxattr_sz (compound_decode_hdr_maxsz + \ 242 decode_sequence_maxsz + \ 243 decode_putfh_maxsz + \ 244 decode_getxattr_maxsz) 245 #define NFS4_enc_setxattr_sz (compound_encode_hdr_maxsz + \ 246 encode_sequence_maxsz + \ 247 encode_putfh_maxsz + \ 248 encode_setxattr_maxsz + \ 249 encode_getattr_maxsz) 250 #define NFS4_dec_setxattr_sz (compound_decode_hdr_maxsz + \ 251 decode_sequence_maxsz + \ 252 decode_putfh_maxsz + \ 253 decode_setxattr_maxsz + \ 254 decode_getattr_maxsz) 255 #define NFS4_enc_listxattrs_sz (compound_encode_hdr_maxsz + \ 256 encode_sequence_maxsz + \ 257 encode_putfh_maxsz + \ 258 encode_listxattrs_maxsz) 259 #define NFS4_dec_listxattrs_sz (compound_decode_hdr_maxsz + \ 260 decode_sequence_maxsz + \ 261 decode_putfh_maxsz + \ 262 decode_listxattrs_maxsz) 263 #define NFS4_enc_removexattr_sz (compound_encode_hdr_maxsz + \ 264 encode_sequence_maxsz + \ 265 encode_putfh_maxsz + \ 266 encode_removexattr_maxsz) 267 #define NFS4_dec_removexattr_sz (compound_decode_hdr_maxsz + \ 268 decode_sequence_maxsz + \ 269 decode_putfh_maxsz + \ 270 decode_removexattr_maxsz) 271 272 /* 273 * These values specify the maximum amount of data that is not 274 * associated with the extended attribute name or extended 275 * attribute list in the SETXATTR, GETXATTR and LISTXATTR 276 * respectively. 277 */ 278 const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 279 compound_encode_hdr_maxsz + 280 encode_sequence_maxsz + 281 encode_putfh_maxsz + 1 + 282 nfs4_xattr_name_maxsz) 283 * XDR_UNIT); 284 285 const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 286 compound_decode_hdr_maxsz + 287 decode_sequence_maxsz + 288 decode_putfh_maxsz + 1) * XDR_UNIT); 289 290 const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 291 compound_decode_hdr_maxsz + 292 decode_sequence_maxsz + 293 decode_putfh_maxsz + 3) * XDR_UNIT); 294 295 static void encode_fallocate(struct xdr_stream *xdr, 296 const struct nfs42_falloc_args *args) 297 { 298 encode_nfs4_stateid(xdr, &args->falloc_stateid); 299 encode_uint64(xdr, args->falloc_offset); 300 encode_uint64(xdr, args->falloc_length); 301 } 302 303 static void encode_allocate(struct xdr_stream *xdr, 304 const struct nfs42_falloc_args *args, 305 struct compound_hdr *hdr) 306 { 307 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr); 308 encode_fallocate(xdr, args); 309 } 310 311 static void encode_nl4_server(struct xdr_stream *xdr, 312 const struct nl4_server *ns) 313 { 314 encode_uint32(xdr, ns->nl4_type); 315 switch (ns->nl4_type) { 316 case NL4_NAME: 317 case NL4_URL: 318 encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str); 319 break; 320 case NL4_NETADDR: 321 encode_string(xdr, ns->u.nl4_addr.netid_len, 322 ns->u.nl4_addr.netid); 323 encode_string(xdr, ns->u.nl4_addr.addr_len, 324 ns->u.nl4_addr.addr); 325 break; 326 default: 327 WARN_ON_ONCE(1); 328 } 329 } 330 331 static void encode_copy(struct xdr_stream *xdr, 332 const struct nfs42_copy_args *args, 333 struct compound_hdr *hdr) 334 { 335 encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr); 336 encode_nfs4_stateid(xdr, &args->src_stateid); 337 encode_nfs4_stateid(xdr, &args->dst_stateid); 338 339 encode_uint64(xdr, args->src_pos); 340 encode_uint64(xdr, args->dst_pos); 341 encode_uint64(xdr, args->count); 342 343 encode_uint32(xdr, 1); /* consecutive = true */ 344 encode_uint32(xdr, args->sync); 345 if (args->cp_src == NULL) { /* intra-ssc */ 346 encode_uint32(xdr, 0); /* no src server list */ 347 return; 348 } 349 encode_uint32(xdr, 1); /* supporting 1 server */ 350 encode_nl4_server(xdr, args->cp_src); 351 } 352 353 static void encode_copy_commit(struct xdr_stream *xdr, 354 const struct nfs42_copy_args *args, 355 struct compound_hdr *hdr) 356 { 357 __be32 *p; 358 359 encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr); 360 p = reserve_space(xdr, 12); 361 p = xdr_encode_hyper(p, args->dst_pos); 362 *p = cpu_to_be32(args->count); 363 } 364 365 static void encode_offload_cancel(struct xdr_stream *xdr, 366 const struct nfs42_offload_status_args *args, 367 struct compound_hdr *hdr) 368 { 369 encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr); 370 encode_nfs4_stateid(xdr, &args->osa_stateid); 371 } 372 373 static void encode_offload_status(struct xdr_stream *xdr, 374 const struct nfs42_offload_status_args *args, 375 struct compound_hdr *hdr) 376 { 377 encode_op_hdr(xdr, OP_OFFLOAD_STATUS, decode_offload_status_maxsz, hdr); 378 encode_nfs4_stateid(xdr, &args->osa_stateid); 379 } 380 381 static void encode_copy_notify(struct xdr_stream *xdr, 382 const struct nfs42_copy_notify_args *args, 383 struct compound_hdr *hdr) 384 { 385 encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr); 386 encode_nfs4_stateid(xdr, &args->cna_src_stateid); 387 encode_nl4_server(xdr, &args->cna_dst); 388 } 389 390 static void encode_deallocate(struct xdr_stream *xdr, 391 const struct nfs42_falloc_args *args, 392 struct compound_hdr *hdr) 393 { 394 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr); 395 encode_fallocate(xdr, args); 396 } 397 398 static void encode_read_plus(struct xdr_stream *xdr, 399 const struct nfs_pgio_args *args, 400 struct compound_hdr *hdr) 401 { 402 encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr); 403 encode_nfs4_stateid(xdr, &args->stateid); 404 encode_uint64(xdr, args->offset); 405 encode_uint32(xdr, args->count); 406 } 407 408 static void encode_seek(struct xdr_stream *xdr, 409 const struct nfs42_seek_args *args, 410 struct compound_hdr *hdr) 411 { 412 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr); 413 encode_nfs4_stateid(xdr, &args->sa_stateid); 414 encode_uint64(xdr, args->sa_offset); 415 encode_uint32(xdr, args->sa_what); 416 } 417 418 static void encode_layoutstats(struct xdr_stream *xdr, 419 const struct nfs42_layoutstat_args *args, 420 struct nfs42_layoutstat_devinfo *devinfo, 421 struct compound_hdr *hdr) 422 { 423 __be32 *p; 424 425 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr); 426 p = reserve_space(xdr, 8 + 8); 427 p = xdr_encode_hyper(p, devinfo->offset); 428 p = xdr_encode_hyper(p, devinfo->length); 429 encode_nfs4_stateid(xdr, &args->stateid); 430 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4); 431 p = xdr_encode_hyper(p, devinfo->read_count); 432 p = xdr_encode_hyper(p, devinfo->read_bytes); 433 p = xdr_encode_hyper(p, devinfo->write_count); 434 p = xdr_encode_hyper(p, devinfo->write_bytes); 435 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data, 436 NFS4_DEVICEID4_SIZE); 437 /* Encode layoutupdate4 */ 438 *p++ = cpu_to_be32(devinfo->layout_type); 439 if (devinfo->ld_private.ops) 440 devinfo->ld_private.ops->encode(xdr, args, 441 &devinfo->ld_private); 442 else 443 encode_uint32(xdr, 0); 444 } 445 446 static void encode_clone(struct xdr_stream *xdr, 447 const struct nfs42_clone_args *args, 448 struct compound_hdr *hdr) 449 { 450 __be32 *p; 451 452 encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr); 453 encode_nfs4_stateid(xdr, &args->src_stateid); 454 encode_nfs4_stateid(xdr, &args->dst_stateid); 455 p = reserve_space(xdr, 3*8); 456 p = xdr_encode_hyper(p, args->src_offset); 457 p = xdr_encode_hyper(p, args->dst_offset); 458 xdr_encode_hyper(p, args->count); 459 } 460 461 static void encode_device_error(struct xdr_stream *xdr, 462 const struct nfs42_device_error *error) 463 { 464 __be32 *p; 465 466 p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4); 467 p = xdr_encode_opaque_fixed(p, error->dev_id.data, 468 NFS4_DEVICEID4_SIZE); 469 *p++ = cpu_to_be32(error->status); 470 *p = cpu_to_be32(error->opnum); 471 } 472 473 static void encode_layouterror(struct xdr_stream *xdr, 474 const struct nfs42_layout_error *args, 475 struct compound_hdr *hdr) 476 { 477 __be32 *p; 478 479 encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr); 480 p = reserve_space(xdr, 8 + 8); 481 p = xdr_encode_hyper(p, args->offset); 482 p = xdr_encode_hyper(p, args->length); 483 encode_nfs4_stateid(xdr, &args->stateid); 484 p = reserve_space(xdr, 4); 485 *p = cpu_to_be32(1); 486 encode_device_error(xdr, &args->errors[0]); 487 } 488 489 static void encode_setxattr(struct xdr_stream *xdr, 490 const struct nfs42_setxattrargs *arg, 491 struct compound_hdr *hdr) 492 { 493 __be32 *p; 494 495 BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE); 496 BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE); 497 498 encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr); 499 p = reserve_space(xdr, 4); 500 *p = cpu_to_be32(arg->xattr_flags); 501 encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name); 502 p = reserve_space(xdr, 4); 503 *p = cpu_to_be32(arg->xattr_len); 504 if (arg->xattr_len) 505 xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len); 506 } 507 508 static void encode_getxattr(struct xdr_stream *xdr, const char *name, 509 struct compound_hdr *hdr) 510 { 511 encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr); 512 encode_string(xdr, strlen(name), name); 513 } 514 515 static void encode_removexattr(struct xdr_stream *xdr, const char *name, 516 struct compound_hdr *hdr) 517 { 518 encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr); 519 encode_string(xdr, strlen(name), name); 520 } 521 522 static void encode_listxattrs(struct xdr_stream *xdr, 523 const struct nfs42_listxattrsargs *arg, 524 struct compound_hdr *hdr) 525 { 526 __be32 *p; 527 528 encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr); 529 530 p = reserve_space(xdr, 12); 531 if (unlikely(!p)) 532 return; 533 534 p = xdr_encode_hyper(p, arg->cookie); 535 /* 536 * RFC 8276 says to specify the full max length of the LISTXATTRS 537 * XDR reply. Count is set to the XDR length of the names array 538 * plus the EOF marker. So, add the cookie and the names count. 539 */ 540 *p = cpu_to_be32(arg->count + 8 + 4); 541 } 542 543 /* 544 * Encode ALLOCATE request 545 */ 546 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, 547 struct xdr_stream *xdr, 548 const void *data) 549 { 550 const struct nfs42_falloc_args *args = data; 551 struct compound_hdr hdr = { 552 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 553 }; 554 555 encode_compound_hdr(xdr, req, &hdr); 556 encode_sequence(xdr, &args->seq_args, &hdr); 557 encode_putfh(xdr, args->falloc_fh, &hdr); 558 encode_allocate(xdr, args, &hdr); 559 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 560 encode_nops(&hdr); 561 } 562 563 /* 564 * Encode COPY request 565 */ 566 static void nfs4_xdr_enc_copy(struct rpc_rqst *req, 567 struct xdr_stream *xdr, 568 const void *data) 569 { 570 const struct nfs42_copy_args *args = data; 571 struct compound_hdr hdr = { 572 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 573 }; 574 575 encode_compound_hdr(xdr, req, &hdr); 576 encode_sequence(xdr, &args->seq_args, &hdr); 577 encode_putfh(xdr, args->src_fh, &hdr); 578 encode_savefh(xdr, &hdr); 579 encode_putfh(xdr, args->dst_fh, &hdr); 580 encode_copy(xdr, args, &hdr); 581 if (args->sync) 582 encode_copy_commit(xdr, args, &hdr); 583 encode_nops(&hdr); 584 } 585 586 /* 587 * Encode OFFLOAD_CANCEL request 588 */ 589 static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req, 590 struct xdr_stream *xdr, 591 const void *data) 592 { 593 const struct nfs42_offload_status_args *args = data; 594 struct compound_hdr hdr = { 595 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args), 596 }; 597 598 encode_compound_hdr(xdr, req, &hdr); 599 encode_sequence(xdr, &args->osa_seq_args, &hdr); 600 encode_putfh(xdr, args->osa_src_fh, &hdr); 601 encode_offload_cancel(xdr, args, &hdr); 602 encode_nops(&hdr); 603 } 604 605 /* 606 * Encode OFFLOAD_STATUS request 607 */ 608 static void nfs4_xdr_enc_offload_status(struct rpc_rqst *req, 609 struct xdr_stream *xdr, 610 const void *data) 611 { 612 const struct nfs42_offload_status_args *args = data; 613 struct compound_hdr hdr = { 614 .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args), 615 }; 616 617 encode_compound_hdr(xdr, req, &hdr); 618 encode_sequence(xdr, &args->osa_seq_args, &hdr); 619 encode_putfh(xdr, args->osa_src_fh, &hdr); 620 encode_offload_status(xdr, args, &hdr); 621 encode_nops(&hdr); 622 } 623 624 /* 625 * Encode COPY_NOTIFY request 626 */ 627 static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req, 628 struct xdr_stream *xdr, 629 const void *data) 630 { 631 const struct nfs42_copy_notify_args *args = data; 632 struct compound_hdr hdr = { 633 .minorversion = nfs4_xdr_minorversion(&args->cna_seq_args), 634 }; 635 636 encode_compound_hdr(xdr, req, &hdr); 637 encode_sequence(xdr, &args->cna_seq_args, &hdr); 638 encode_putfh(xdr, args->cna_src_fh, &hdr); 639 encode_copy_notify(xdr, args, &hdr); 640 encode_nops(&hdr); 641 } 642 643 /* 644 * Encode DEALLOCATE request 645 */ 646 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, 647 struct xdr_stream *xdr, 648 const void *data) 649 { 650 const struct nfs42_falloc_args *args = data; 651 struct compound_hdr hdr = { 652 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 653 }; 654 655 encode_compound_hdr(xdr, req, &hdr); 656 encode_sequence(xdr, &args->seq_args, &hdr); 657 encode_putfh(xdr, args->falloc_fh, &hdr); 658 encode_deallocate(xdr, args, &hdr); 659 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 660 encode_nops(&hdr); 661 } 662 663 /* 664 * Encode ZERO_RANGE request 665 */ 666 static void nfs4_xdr_enc_zero_range(struct rpc_rqst *req, 667 struct xdr_stream *xdr, 668 const void *data) 669 { 670 const struct nfs42_falloc_args *args = data; 671 struct compound_hdr hdr = { 672 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 673 }; 674 675 encode_compound_hdr(xdr, req, &hdr); 676 encode_sequence(xdr, &args->seq_args, &hdr); 677 encode_putfh(xdr, args->falloc_fh, &hdr); 678 encode_deallocate(xdr, args, &hdr); 679 encode_allocate(xdr, args, &hdr); 680 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 681 encode_nops(&hdr); 682 } 683 684 /* 685 * Encode READ_PLUS request 686 */ 687 static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req, 688 struct xdr_stream *xdr, 689 const void *data) 690 { 691 const struct nfs_pgio_args *args = data; 692 struct compound_hdr hdr = { 693 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 694 }; 695 696 encode_compound_hdr(xdr, req, &hdr); 697 encode_sequence(xdr, &args->seq_args, &hdr); 698 encode_putfh(xdr, args->fh, &hdr); 699 encode_read_plus(xdr, args, &hdr); 700 701 rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->count, 702 hdr.replen - READ_PLUS_SEGMENT_SIZE_DIFF); 703 encode_nops(&hdr); 704 } 705 706 /* 707 * Encode SEEK request 708 */ 709 static void nfs4_xdr_enc_seek(struct rpc_rqst *req, 710 struct xdr_stream *xdr, 711 const void *data) 712 { 713 const struct nfs42_seek_args *args = data; 714 struct compound_hdr hdr = { 715 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 716 }; 717 718 encode_compound_hdr(xdr, req, &hdr); 719 encode_sequence(xdr, &args->seq_args, &hdr); 720 encode_putfh(xdr, args->sa_fh, &hdr); 721 encode_seek(xdr, args, &hdr); 722 encode_nops(&hdr); 723 } 724 725 /* 726 * Encode LAYOUTSTATS request 727 */ 728 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, 729 struct xdr_stream *xdr, 730 const void *data) 731 { 732 const struct nfs42_layoutstat_args *args = data; 733 int i; 734 735 struct compound_hdr hdr = { 736 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 737 }; 738 739 encode_compound_hdr(xdr, req, &hdr); 740 encode_sequence(xdr, &args->seq_args, &hdr); 741 encode_putfh(xdr, args->fh, &hdr); 742 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 743 for (i = 0; i < args->num_dev; i++) 744 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); 745 encode_nops(&hdr); 746 } 747 748 /* 749 * Encode CLONE request 750 */ 751 static void nfs4_xdr_enc_clone(struct rpc_rqst *req, 752 struct xdr_stream *xdr, 753 const void *data) 754 { 755 const struct nfs42_clone_args *args = data; 756 struct compound_hdr hdr = { 757 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 758 }; 759 760 encode_compound_hdr(xdr, req, &hdr); 761 encode_sequence(xdr, &args->seq_args, &hdr); 762 encode_putfh(xdr, args->src_fh, &hdr); 763 encode_savefh(xdr, &hdr); 764 encode_putfh(xdr, args->dst_fh, &hdr); 765 encode_clone(xdr, args, &hdr); 766 encode_getfattr(xdr, args->dst_bitmask, &hdr); 767 encode_nops(&hdr); 768 } 769 770 /* 771 * Encode LAYOUTERROR request 772 */ 773 static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req, 774 struct xdr_stream *xdr, 775 const void *data) 776 { 777 const struct nfs42_layouterror_args *args = data; 778 struct compound_hdr hdr = { 779 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 780 }; 781 int i; 782 783 encode_compound_hdr(xdr, req, &hdr); 784 encode_sequence(xdr, &args->seq_args, &hdr); 785 encode_putfh(xdr, NFS_FH(args->inode), &hdr); 786 for (i = 0; i < args->num_errors; i++) 787 encode_layouterror(xdr, &args->errors[i], &hdr); 788 encode_nops(&hdr); 789 } 790 791 /* 792 * Encode SETXATTR request 793 */ 794 static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 795 const void *data) 796 { 797 const struct nfs42_setxattrargs *args = data; 798 struct compound_hdr hdr = { 799 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 800 }; 801 802 encode_compound_hdr(xdr, req, &hdr); 803 encode_sequence(xdr, &args->seq_args, &hdr); 804 encode_putfh(xdr, args->fh, &hdr); 805 encode_setxattr(xdr, args, &hdr); 806 encode_getfattr(xdr, args->bitmask, &hdr); 807 encode_nops(&hdr); 808 } 809 810 /* 811 * Encode GETXATTR request 812 */ 813 static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 814 const void *data) 815 { 816 const struct nfs42_getxattrargs *args = data; 817 struct compound_hdr hdr = { 818 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 819 }; 820 uint32_t replen; 821 822 encode_compound_hdr(xdr, req, &hdr); 823 encode_sequence(xdr, &args->seq_args, &hdr); 824 encode_putfh(xdr, args->fh, &hdr); 825 replen = hdr.replen + op_decode_hdr_maxsz + 1; 826 encode_getxattr(xdr, args->xattr_name, &hdr); 827 828 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len, 829 replen); 830 831 encode_nops(&hdr); 832 } 833 834 /* 835 * Encode LISTXATTR request 836 */ 837 static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req, 838 struct xdr_stream *xdr, const void *data) 839 { 840 const struct nfs42_listxattrsargs *args = data; 841 struct compound_hdr hdr = { 842 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 843 }; 844 uint32_t replen; 845 846 encode_compound_hdr(xdr, req, &hdr); 847 encode_sequence(xdr, &args->seq_args, &hdr); 848 encode_putfh(xdr, args->fh, &hdr); 849 replen = hdr.replen + op_decode_hdr_maxsz + 2 + 1; 850 encode_listxattrs(xdr, args, &hdr); 851 852 rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen); 853 854 encode_nops(&hdr); 855 } 856 857 /* 858 * Encode REMOVEXATTR request 859 */ 860 static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req, 861 struct xdr_stream *xdr, const void *data) 862 { 863 const struct nfs42_removexattrargs *args = data; 864 struct compound_hdr hdr = { 865 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 866 }; 867 868 encode_compound_hdr(xdr, req, &hdr); 869 encode_sequence(xdr, &args->seq_args, &hdr); 870 encode_putfh(xdr, args->fh, &hdr); 871 encode_removexattr(xdr, args->xattr_name, &hdr); 872 encode_nops(&hdr); 873 } 874 875 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 876 { 877 return decode_op_hdr(xdr, OP_ALLOCATE); 878 } 879 880 static int decode_write_response(struct xdr_stream *xdr, 881 struct nfs42_write_res *res) 882 { 883 __be32 *p; 884 int status, count; 885 886 p = xdr_inline_decode(xdr, 4); 887 if (unlikely(!p)) 888 return -EIO; 889 count = be32_to_cpup(p); 890 if (count > 1) 891 return -EREMOTEIO; 892 else if (count == 1) { 893 status = decode_opaque_fixed(xdr, &res->stateid, 894 NFS4_STATEID_SIZE); 895 if (unlikely(status)) 896 return -EIO; 897 } 898 p = xdr_inline_decode(xdr, 8 + 4); 899 if (unlikely(!p)) 900 return -EIO; 901 p = xdr_decode_hyper(p, &res->count); 902 res->verifier.committed = be32_to_cpup(p); 903 return decode_verifier(xdr, &res->verifier.verifier); 904 } 905 906 static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns) 907 { 908 struct nfs42_netaddr *naddr; 909 uint32_t dummy; 910 char *dummy_str; 911 __be32 *p; 912 int status; 913 914 /* nl_type */ 915 p = xdr_inline_decode(xdr, 4); 916 if (unlikely(!p)) 917 return -EIO; 918 ns->nl4_type = be32_to_cpup(p); 919 switch (ns->nl4_type) { 920 case NL4_NAME: 921 case NL4_URL: 922 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 923 if (unlikely(status)) 924 return status; 925 if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) 926 return -EIO; 927 memcpy(&ns->u.nl4_str, dummy_str, dummy); 928 ns->u.nl4_str_sz = dummy; 929 break; 930 case NL4_NETADDR: 931 naddr = &ns->u.nl4_addr; 932 933 /* netid string */ 934 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 935 if (unlikely(status)) 936 return status; 937 if (unlikely(dummy > RPCBIND_MAXNETIDLEN)) 938 return -EIO; 939 naddr->netid_len = dummy; 940 memcpy(naddr->netid, dummy_str, naddr->netid_len); 941 942 /* uaddr string */ 943 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 944 if (unlikely(status)) 945 return status; 946 if (unlikely(dummy > RPCBIND_MAXUADDRLEN)) 947 return -EIO; 948 naddr->addr_len = dummy; 949 memcpy(naddr->addr, dummy_str, naddr->addr_len); 950 break; 951 default: 952 WARN_ON_ONCE(1); 953 return -EIO; 954 } 955 return 0; 956 } 957 958 static int decode_copy_requirements(struct xdr_stream *xdr, 959 struct nfs42_copy_res *res) { 960 __be32 *p; 961 962 p = xdr_inline_decode(xdr, 4 + 4); 963 if (unlikely(!p)) 964 return -EIO; 965 966 res->consecutive = be32_to_cpup(p++); 967 res->synchronous = be32_to_cpup(p++); 968 return 0; 969 } 970 971 static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) 972 { 973 int status; 974 975 status = decode_op_hdr(xdr, OP_COPY); 976 if (status == NFS4ERR_OFFLOAD_NO_REQS) { 977 status = decode_copy_requirements(xdr, res); 978 if (status) 979 return status; 980 return NFS4ERR_OFFLOAD_NO_REQS; 981 } else if (status) 982 return status; 983 984 status = decode_write_response(xdr, &res->write_res); 985 if (status) 986 return status; 987 988 return decode_copy_requirements(xdr, res); 989 } 990 991 static int decode_offload_cancel(struct xdr_stream *xdr, 992 struct nfs42_offload_status_res *res) 993 { 994 return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL); 995 } 996 997 static int decode_offload_status(struct xdr_stream *xdr, 998 struct nfs42_offload_status_res *res) 999 { 1000 ssize_t result; 1001 int status; 1002 1003 status = decode_op_hdr(xdr, OP_OFFLOAD_STATUS); 1004 if (status) 1005 return status; 1006 /* osr_count */ 1007 if (xdr_stream_decode_u64(xdr, &res->osr_count) < 0) 1008 return -EIO; 1009 /* osr_complete<1> */ 1010 result = xdr_stream_decode_uint32_array(xdr, &res->osr_complete, 1); 1011 if (result < 0) 1012 return -EIO; 1013 res->complete_count = result; 1014 return 0; 1015 } 1016 1017 static int decode_copy_notify(struct xdr_stream *xdr, 1018 struct nfs42_copy_notify_res *res) 1019 { 1020 __be32 *p; 1021 int status, count; 1022 1023 status = decode_op_hdr(xdr, OP_COPY_NOTIFY); 1024 if (status) 1025 return status; 1026 /* cnr_lease_time */ 1027 p = xdr_inline_decode(xdr, 12); 1028 if (unlikely(!p)) 1029 return -EIO; 1030 p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds); 1031 res->cnr_lease_time.nseconds = be32_to_cpup(p); 1032 1033 status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE); 1034 if (unlikely(status)) 1035 return -EIO; 1036 1037 /* number of source addresses */ 1038 p = xdr_inline_decode(xdr, 4); 1039 if (unlikely(!p)) 1040 return -EIO; 1041 1042 count = be32_to_cpup(p); 1043 if (count > 1) 1044 pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n", 1045 __func__, count); 1046 1047 status = decode_nl4_server(xdr, &res->cnr_src); 1048 if (unlikely(status)) 1049 return -EIO; 1050 return 0; 1051 } 1052 1053 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 1054 { 1055 return decode_op_hdr(xdr, OP_DEALLOCATE); 1056 } 1057 1058 struct read_plus_segment { 1059 enum data_content4 type; 1060 uint64_t offset; 1061 union { 1062 struct { 1063 uint64_t length; 1064 } hole; 1065 1066 struct { 1067 uint32_t length; 1068 unsigned int from; 1069 } data; 1070 }; 1071 }; 1072 1073 static inline uint64_t read_plus_segment_length(struct read_plus_segment *seg) 1074 { 1075 return seg->type == NFS4_CONTENT_DATA ? seg->data.length : seg->hole.length; 1076 } 1077 1078 static int decode_read_plus_segment(struct xdr_stream *xdr, 1079 struct read_plus_segment *seg) 1080 { 1081 __be32 *p; 1082 1083 p = xdr_inline_decode(xdr, 4); 1084 if (!p) 1085 return -EIO; 1086 seg->type = be32_to_cpup(p++); 1087 1088 p = xdr_inline_decode(xdr, seg->type == NFS4_CONTENT_DATA ? 12 : 16); 1089 if (!p) 1090 return -EIO; 1091 p = xdr_decode_hyper(p, &seg->offset); 1092 1093 if (seg->type == NFS4_CONTENT_DATA) { 1094 struct xdr_buf buf; 1095 uint32_t len = be32_to_cpup(p); 1096 1097 seg->data.length = len; 1098 seg->data.from = xdr_stream_pos(xdr); 1099 1100 if (!xdr_stream_subsegment(xdr, &buf, xdr_align_size(len))) 1101 return -EIO; 1102 } else if (seg->type == NFS4_CONTENT_HOLE) { 1103 xdr_decode_hyper(p, &seg->hole.length); 1104 } else 1105 return -EINVAL; 1106 return 0; 1107 } 1108 1109 static int process_read_plus_segment(struct xdr_stream *xdr, 1110 struct nfs_pgio_args *args, 1111 struct nfs_pgio_res *res, 1112 struct read_plus_segment *seg) 1113 { 1114 unsigned long offset = seg->offset; 1115 unsigned long length = read_plus_segment_length(seg); 1116 unsigned int bufpos; 1117 1118 if (offset + length < args->offset) 1119 return 0; 1120 else if (offset > args->offset + args->count) { 1121 res->eof = 0; 1122 return 0; 1123 } else if (offset < args->offset) { 1124 length -= (args->offset - offset); 1125 offset = args->offset; 1126 } else if (offset + length > args->offset + args->count) { 1127 length = (args->offset + args->count) - offset; 1128 res->eof = 0; 1129 } 1130 1131 bufpos = xdr->buf->head[0].iov_len + (offset - args->offset); 1132 if (seg->type == NFS4_CONTENT_HOLE) 1133 return xdr_stream_zero(xdr, bufpos, length); 1134 else 1135 return xdr_stream_move_subsegment(xdr, seg->data.from, bufpos, length); 1136 } 1137 1138 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) 1139 { 1140 struct nfs_pgio_header *hdr = 1141 container_of(res, struct nfs_pgio_header, res); 1142 struct nfs_pgio_args *args = &hdr->args; 1143 uint32_t segments; 1144 struct read_plus_segment *segs; 1145 int status, i; 1146 __be32 *p; 1147 1148 status = decode_op_hdr(xdr, OP_READ_PLUS); 1149 if (status) 1150 return status; 1151 1152 p = xdr_inline_decode(xdr, 4 + 4); 1153 if (unlikely(!p)) 1154 return -EIO; 1155 1156 res->count = 0; 1157 res->eof = be32_to_cpup(p++); 1158 segments = be32_to_cpup(p++); 1159 if (segments == 0) 1160 return 0; 1161 1162 segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL); 1163 if (!segs) 1164 return -ENOMEM; 1165 1166 for (i = 0; i < segments; i++) { 1167 status = decode_read_plus_segment(xdr, &segs[i]); 1168 if (status < 0) 1169 goto out; 1170 } 1171 1172 xdr_set_pagelen(xdr, xdr_align_size(args->count)); 1173 for (i = segments; i > 0; i--) 1174 res->count += process_read_plus_segment(xdr, args, res, &segs[i-1]); 1175 status = 0; 1176 1177 out: 1178 kfree(segs); 1179 return status; 1180 } 1181 1182 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) 1183 { 1184 int status; 1185 __be32 *p; 1186 1187 status = decode_op_hdr(xdr, OP_SEEK); 1188 if (status) 1189 return status; 1190 1191 p = xdr_inline_decode(xdr, 4 + 8); 1192 if (unlikely(!p)) 1193 return -EIO; 1194 1195 res->sr_eof = be32_to_cpup(p++); 1196 p = xdr_decode_hyper(p, &res->sr_offset); 1197 return 0; 1198 } 1199 1200 static int decode_layoutstats(struct xdr_stream *xdr) 1201 { 1202 return decode_op_hdr(xdr, OP_LAYOUTSTATS); 1203 } 1204 1205 static int decode_clone(struct xdr_stream *xdr) 1206 { 1207 return decode_op_hdr(xdr, OP_CLONE); 1208 } 1209 1210 static int decode_layouterror(struct xdr_stream *xdr) 1211 { 1212 return decode_op_hdr(xdr, OP_LAYOUTERROR); 1213 } 1214 1215 static int decode_setxattr(struct xdr_stream *xdr, 1216 struct nfs4_change_info *cinfo) 1217 { 1218 int status; 1219 1220 status = decode_op_hdr(xdr, OP_SETXATTR); 1221 if (status) 1222 goto out; 1223 status = decode_change_info(xdr, cinfo); 1224 out: 1225 return status; 1226 } 1227 1228 static int decode_getxattr(struct xdr_stream *xdr, 1229 struct nfs42_getxattrres *res, 1230 struct rpc_rqst *req) 1231 { 1232 int status; 1233 __be32 *p; 1234 u32 len, rdlen; 1235 1236 status = decode_op_hdr(xdr, OP_GETXATTR); 1237 if (status) 1238 return status; 1239 1240 p = xdr_inline_decode(xdr, 4); 1241 if (unlikely(!p)) 1242 return -EIO; 1243 1244 len = be32_to_cpup(p); 1245 1246 /* 1247 * Only check against the page length here. The actual 1248 * requested length may be smaller, but that is only 1249 * checked against after possibly caching a valid reply. 1250 */ 1251 if (len > req->rq_rcv_buf.page_len) 1252 return -ERANGE; 1253 1254 res->xattr_len = len; 1255 1256 if (len > 0) { 1257 rdlen = xdr_read_pages(xdr, len); 1258 if (rdlen < len) 1259 return -EIO; 1260 } 1261 1262 return 0; 1263 } 1264 1265 static int decode_removexattr(struct xdr_stream *xdr, 1266 struct nfs4_change_info *cinfo) 1267 { 1268 int status; 1269 1270 status = decode_op_hdr(xdr, OP_REMOVEXATTR); 1271 if (status) 1272 goto out; 1273 1274 status = decode_change_info(xdr, cinfo); 1275 out: 1276 return status; 1277 } 1278 1279 static int decode_listxattrs(struct xdr_stream *xdr, 1280 struct nfs42_listxattrsres *res) 1281 { 1282 int status; 1283 __be32 *p; 1284 u32 count, len, ulen; 1285 size_t left, copied; 1286 char *buf; 1287 1288 status = decode_op_hdr(xdr, OP_LISTXATTRS); 1289 if (status) { 1290 /* 1291 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL 1292 * should be translated to ERANGE. 1293 */ 1294 if (status == -ETOOSMALL) 1295 status = -ERANGE; 1296 /* 1297 * Special case: for LISTXATTRS, NFS4ERR_NOXATTR 1298 * should be translated to success with zero-length reply. 1299 */ 1300 if (status == -ENODATA) { 1301 res->eof = true; 1302 status = 0; 1303 } 1304 goto out; 1305 } 1306 1307 p = xdr_inline_decode(xdr, 8); 1308 if (unlikely(!p)) 1309 return -EIO; 1310 1311 xdr_decode_hyper(p, &res->cookie); 1312 1313 p = xdr_inline_decode(xdr, 4); 1314 if (unlikely(!p)) 1315 return -EIO; 1316 1317 left = res->xattr_len; 1318 buf = res->xattr_buf; 1319 1320 count = be32_to_cpup(p); 1321 copied = 0; 1322 1323 /* 1324 * We have asked for enough room to encode the maximum number 1325 * of possible attribute names, so everything should fit. 1326 * 1327 * But, don't rely on that assumption. Just decode entries 1328 * until they don't fit anymore, just in case the server did 1329 * something odd. 1330 */ 1331 while (count--) { 1332 p = xdr_inline_decode(xdr, 4); 1333 if (unlikely(!p)) 1334 return -EIO; 1335 1336 len = be32_to_cpup(p); 1337 if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) { 1338 status = -ERANGE; 1339 goto out; 1340 } 1341 1342 p = xdr_inline_decode(xdr, len); 1343 if (unlikely(!p)) 1344 return -EIO; 1345 1346 ulen = len + XATTR_USER_PREFIX_LEN + 1; 1347 if (buf) { 1348 if (ulen > left) { 1349 status = -ERANGE; 1350 goto out; 1351 } 1352 1353 memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); 1354 memcpy(buf + XATTR_USER_PREFIX_LEN, p, len); 1355 1356 buf[ulen - 1] = 0; 1357 buf += ulen; 1358 left -= ulen; 1359 } 1360 copied += ulen; 1361 } 1362 1363 p = xdr_inline_decode(xdr, 4); 1364 if (unlikely(!p)) 1365 return -EIO; 1366 1367 res->eof = be32_to_cpup(p); 1368 res->copied = copied; 1369 1370 out: 1371 if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX) 1372 status = -E2BIG; 1373 1374 return status; 1375 } 1376 1377 /* 1378 * Decode ALLOCATE request 1379 */ 1380 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, 1381 struct xdr_stream *xdr, 1382 void *data) 1383 { 1384 struct nfs42_falloc_res *res = data; 1385 struct compound_hdr hdr; 1386 int status; 1387 1388 status = decode_compound_hdr(xdr, &hdr); 1389 if (status) 1390 goto out; 1391 status = decode_sequence(xdr, &res->seq_res, rqstp); 1392 if (status) 1393 goto out; 1394 status = decode_putfh(xdr); 1395 if (status) 1396 goto out; 1397 status = decode_allocate(xdr, res); 1398 if (status) 1399 goto out; 1400 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 1401 out: 1402 return status; 1403 } 1404 1405 /* 1406 * Decode COPY response 1407 */ 1408 static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp, 1409 struct xdr_stream *xdr, 1410 void *data) 1411 { 1412 struct nfs42_copy_res *res = data; 1413 struct compound_hdr hdr; 1414 int status; 1415 1416 status = decode_compound_hdr(xdr, &hdr); 1417 if (status) 1418 goto out; 1419 status = decode_sequence(xdr, &res->seq_res, rqstp); 1420 if (status) 1421 goto out; 1422 status = decode_putfh(xdr); 1423 if (status) 1424 goto out; 1425 status = decode_savefh(xdr); 1426 if (status) 1427 goto out; 1428 status = decode_putfh(xdr); 1429 if (status) 1430 goto out; 1431 status = decode_copy(xdr, res); 1432 if (status) 1433 goto out; 1434 if (res->commit_res.verf) 1435 status = decode_commit(xdr, &res->commit_res); 1436 out: 1437 return status; 1438 } 1439 1440 /* 1441 * Decode OFFLOAD_CANCEL response 1442 */ 1443 static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp, 1444 struct xdr_stream *xdr, 1445 void *data) 1446 { 1447 struct nfs42_offload_status_res *res = data; 1448 struct compound_hdr hdr; 1449 int status; 1450 1451 status = decode_compound_hdr(xdr, &hdr); 1452 if (status) 1453 goto out; 1454 status = decode_sequence(xdr, &res->osr_seq_res, rqstp); 1455 if (status) 1456 goto out; 1457 status = decode_putfh(xdr); 1458 if (status) 1459 goto out; 1460 status = decode_offload_cancel(xdr, res); 1461 1462 out: 1463 return status; 1464 } 1465 1466 /* 1467 * Decode OFFLOAD_STATUS response 1468 */ 1469 static int nfs4_xdr_dec_offload_status(struct rpc_rqst *rqstp, 1470 struct xdr_stream *xdr, 1471 void *data) 1472 { 1473 struct nfs42_offload_status_res *res = data; 1474 struct compound_hdr hdr; 1475 int status; 1476 1477 status = decode_compound_hdr(xdr, &hdr); 1478 if (status) 1479 goto out; 1480 status = decode_sequence(xdr, &res->osr_seq_res, rqstp); 1481 if (status) 1482 goto out; 1483 status = decode_putfh(xdr); 1484 if (status) 1485 goto out; 1486 status = decode_offload_status(xdr, res); 1487 1488 out: 1489 return status; 1490 } 1491 1492 /* 1493 * Decode COPY_NOTIFY response 1494 */ 1495 static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp, 1496 struct xdr_stream *xdr, 1497 void *data) 1498 { 1499 struct nfs42_copy_notify_res *res = data; 1500 struct compound_hdr hdr; 1501 int status; 1502 1503 status = decode_compound_hdr(xdr, &hdr); 1504 if (status) 1505 goto out; 1506 status = decode_sequence(xdr, &res->cnr_seq_res, rqstp); 1507 if (status) 1508 goto out; 1509 status = decode_putfh(xdr); 1510 if (status) 1511 goto out; 1512 status = decode_copy_notify(xdr, res); 1513 1514 out: 1515 return status; 1516 } 1517 1518 /* 1519 * Decode DEALLOCATE request 1520 */ 1521 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, 1522 struct xdr_stream *xdr, 1523 void *data) 1524 { 1525 struct nfs42_falloc_res *res = data; 1526 struct compound_hdr hdr; 1527 int status; 1528 1529 status = decode_compound_hdr(xdr, &hdr); 1530 if (status) 1531 goto out; 1532 status = decode_sequence(xdr, &res->seq_res, rqstp); 1533 if (status) 1534 goto out; 1535 status = decode_putfh(xdr); 1536 if (status) 1537 goto out; 1538 status = decode_deallocate(xdr, res); 1539 if (status) 1540 goto out; 1541 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 1542 out: 1543 return status; 1544 } 1545 1546 /* 1547 * Decode ZERO_RANGE request 1548 */ 1549 static int nfs4_xdr_dec_zero_range(struct rpc_rqst *rqstp, 1550 struct xdr_stream *xdr, 1551 void *data) 1552 { 1553 struct nfs42_falloc_res *res = data; 1554 struct compound_hdr hdr; 1555 int status; 1556 1557 status = decode_compound_hdr(xdr, &hdr); 1558 if (status) 1559 goto out; 1560 status = decode_sequence(xdr, &res->seq_res, rqstp); 1561 if (status) 1562 goto out; 1563 status = decode_putfh(xdr); 1564 if (status) 1565 goto out; 1566 status = decode_deallocate(xdr, res); 1567 if (status) 1568 goto out; 1569 status = decode_allocate(xdr, res); 1570 if (status) 1571 goto out; 1572 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 1573 out: 1574 return status; 1575 } 1576 1577 /* 1578 * Decode READ_PLUS request 1579 */ 1580 static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp, 1581 struct xdr_stream *xdr, 1582 void *data) 1583 { 1584 struct nfs_pgio_res *res = data; 1585 struct compound_hdr hdr; 1586 int status; 1587 1588 xdr_set_scratch_buffer(xdr, res->scratch, READ_PLUS_SCRATCH_SIZE); 1589 1590 status = decode_compound_hdr(xdr, &hdr); 1591 if (status) 1592 goto out; 1593 status = decode_sequence(xdr, &res->seq_res, rqstp); 1594 if (status) 1595 goto out; 1596 status = decode_putfh(xdr); 1597 if (status) 1598 goto out; 1599 status = decode_read_plus(xdr, res); 1600 if (!status) 1601 status = res->count; 1602 out: 1603 return status; 1604 } 1605 1606 /* 1607 * Decode SEEK request 1608 */ 1609 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, 1610 struct xdr_stream *xdr, 1611 void *data) 1612 { 1613 struct nfs42_seek_res *res = data; 1614 struct compound_hdr hdr; 1615 int status; 1616 1617 status = decode_compound_hdr(xdr, &hdr); 1618 if (status) 1619 goto out; 1620 status = decode_sequence(xdr, &res->seq_res, rqstp); 1621 if (status) 1622 goto out; 1623 status = decode_putfh(xdr); 1624 if (status) 1625 goto out; 1626 status = decode_seek(xdr, res); 1627 out: 1628 return status; 1629 } 1630 1631 /* 1632 * Decode LAYOUTSTATS request 1633 */ 1634 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, 1635 struct xdr_stream *xdr, 1636 void *data) 1637 { 1638 struct nfs42_layoutstat_res *res = data; 1639 struct compound_hdr hdr; 1640 int status, i; 1641 1642 status = decode_compound_hdr(xdr, &hdr); 1643 if (status) 1644 goto out; 1645 status = decode_sequence(xdr, &res->seq_res, rqstp); 1646 if (status) 1647 goto out; 1648 status = decode_putfh(xdr); 1649 if (status) 1650 goto out; 1651 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 1652 for (i = 0; i < res->num_dev; i++) { 1653 status = decode_layoutstats(xdr); 1654 if (status) 1655 goto out; 1656 } 1657 out: 1658 res->rpc_status = status; 1659 return status; 1660 } 1661 1662 /* 1663 * Decode CLONE request 1664 */ 1665 static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp, 1666 struct xdr_stream *xdr, 1667 void *data) 1668 { 1669 struct nfs42_clone_res *res = data; 1670 struct compound_hdr hdr; 1671 int status; 1672 1673 status = decode_compound_hdr(xdr, &hdr); 1674 if (status) 1675 goto out; 1676 status = decode_sequence(xdr, &res->seq_res, rqstp); 1677 if (status) 1678 goto out; 1679 status = decode_putfh(xdr); 1680 if (status) 1681 goto out; 1682 status = decode_savefh(xdr); 1683 if (status) 1684 goto out; 1685 status = decode_putfh(xdr); 1686 if (status) 1687 goto out; 1688 status = decode_clone(xdr); 1689 if (status) 1690 goto out; 1691 decode_getfattr(xdr, res->dst_fattr, res->server); 1692 out: 1693 res->rpc_status = status; 1694 return status; 1695 } 1696 1697 /* 1698 * Decode LAYOUTERROR request 1699 */ 1700 static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp, 1701 struct xdr_stream *xdr, 1702 void *data) 1703 { 1704 struct nfs42_layouterror_res *res = data; 1705 struct compound_hdr hdr; 1706 int status, i; 1707 1708 status = decode_compound_hdr(xdr, &hdr); 1709 if (status) 1710 goto out; 1711 status = decode_sequence(xdr, &res->seq_res, rqstp); 1712 if (status) 1713 goto out; 1714 status = decode_putfh(xdr); 1715 1716 for (i = 0; i < res->num_errors && status == 0; i++) 1717 status = decode_layouterror(xdr); 1718 out: 1719 res->rpc_status = status; 1720 return status; 1721 } 1722 1723 /* 1724 * Decode SETXATTR request 1725 */ 1726 static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr, 1727 void *data) 1728 { 1729 struct nfs42_setxattrres *res = data; 1730 struct compound_hdr hdr; 1731 int status; 1732 1733 status = decode_compound_hdr(xdr, &hdr); 1734 if (status) 1735 goto out; 1736 status = decode_sequence(xdr, &res->seq_res, req); 1737 if (status) 1738 goto out; 1739 status = decode_putfh(xdr); 1740 if (status) 1741 goto out; 1742 status = decode_setxattr(xdr, &res->cinfo); 1743 if (status) 1744 goto out; 1745 status = decode_getfattr(xdr, res->fattr, res->server); 1746 out: 1747 return status; 1748 } 1749 1750 /* 1751 * Decode GETXATTR request 1752 */ 1753 static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp, 1754 struct xdr_stream *xdr, void *data) 1755 { 1756 struct nfs42_getxattrres *res = data; 1757 struct compound_hdr hdr; 1758 int status; 1759 1760 status = decode_compound_hdr(xdr, &hdr); 1761 if (status) 1762 goto out; 1763 status = decode_sequence(xdr, &res->seq_res, rqstp); 1764 if (status) 1765 goto out; 1766 status = decode_putfh(xdr); 1767 if (status) 1768 goto out; 1769 status = decode_getxattr(xdr, res, rqstp); 1770 out: 1771 return status; 1772 } 1773 1774 /* 1775 * Decode LISTXATTR request 1776 */ 1777 static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp, 1778 struct xdr_stream *xdr, void *data) 1779 { 1780 struct nfs42_listxattrsres *res = data; 1781 struct compound_hdr hdr; 1782 int status; 1783 1784 xdr_set_scratch_page(xdr, res->scratch); 1785 1786 status = decode_compound_hdr(xdr, &hdr); 1787 if (status) 1788 goto out; 1789 status = decode_sequence(xdr, &res->seq_res, rqstp); 1790 if (status) 1791 goto out; 1792 status = decode_putfh(xdr); 1793 if (status) 1794 goto out; 1795 status = decode_listxattrs(xdr, res); 1796 out: 1797 return status; 1798 } 1799 1800 /* 1801 * Decode REMOVEXATTR request 1802 */ 1803 static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req, 1804 struct xdr_stream *xdr, void *data) 1805 { 1806 struct nfs42_removexattrres *res = data; 1807 struct compound_hdr hdr; 1808 int status; 1809 1810 status = decode_compound_hdr(xdr, &hdr); 1811 if (status) 1812 goto out; 1813 status = decode_sequence(xdr, &res->seq_res, req); 1814 if (status) 1815 goto out; 1816 status = decode_putfh(xdr); 1817 if (status) 1818 goto out; 1819 1820 status = decode_removexattr(xdr, &res->cinfo); 1821 out: 1822 return status; 1823 } 1824 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ 1825