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