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