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