/fs/nfs/nfs3xdr.c
C | 2498 lines | 1444 code | 214 blank | 840 comment | 194 complexity | 5d8e77c8f5d197f5d6c8adaaa681b728 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
Large files files are truncated, but you can click here to view the full file
1/* 2 * linux/fs/nfs/nfs3xdr.c 3 * 4 * XDR functions to encode/decode NFSv3 RPC arguments and results. 5 * 6 * Copyright (C) 1996, 1997 Olaf Kirch 7 */ 8 9#include <linux/param.h> 10#include <linux/time.h> 11#include <linux/mm.h> 12#include <linux/errno.h> 13#include <linux/string.h> 14#include <linux/in.h> 15#include <linux/pagemap.h> 16#include <linux/proc_fs.h> 17#include <linux/kdev_t.h> 18#include <linux/sunrpc/clnt.h> 19#include <linux/nfs.h> 20#include <linux/nfs3.h> 21#include <linux/nfs_fs.h> 22#include <linux/nfsacl.h> 23#include "internal.h" 24 25#define NFSDBG_FACILITY NFSDBG_XDR 26 27/* Mapping from NFS error code to "errno" error code. */ 28#define errno_NFSERR_IO EIO 29 30/* 31 * Declare the space requirements for NFS arguments and replies as 32 * number of 32bit-words 33 */ 34#define NFS3_fhandle_sz (1+16) 35#define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */ 36#define NFS3_sattr_sz (15) 37#define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2)) 38#define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2)) 39#define NFS3_fattr_sz (21) 40#define NFS3_cookieverf_sz (NFS3_COOKIEVERFSIZE>>2) 41#define NFS3_wcc_attr_sz (6) 42#define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz) 43#define NFS3_post_op_attr_sz (1+NFS3_fattr_sz) 44#define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz) 45#define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz) 46 47#define NFS3_getattrargs_sz (NFS3_fh_sz) 48#define NFS3_setattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3) 49#define NFS3_lookupargs_sz (NFS3_fh_sz+NFS3_filename_sz) 50#define NFS3_accessargs_sz (NFS3_fh_sz+1) 51#define NFS3_readlinkargs_sz (NFS3_fh_sz) 52#define NFS3_readargs_sz (NFS3_fh_sz+3) 53#define NFS3_writeargs_sz (NFS3_fh_sz+5) 54#define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) 55#define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) 56#define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz) 57#define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) 58#define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz) 59#define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) 60#define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) 61#define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3) 62#define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4) 63#define NFS3_commitargs_sz (NFS3_fh_sz+3) 64 65#define NFS3_getattrres_sz (1+NFS3_fattr_sz) 66#define NFS3_setattrres_sz (1+NFS3_wcc_data_sz) 67#define NFS3_removeres_sz (NFS3_setattrres_sz) 68#define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz)) 69#define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1) 70#define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1) 71#define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3) 72#define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4) 73#define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) 74#define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz)) 75#define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz) 76#define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2) 77#define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13) 78#define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12) 79#define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6) 80#define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) 81 82#define ACL3_getaclargs_sz (NFS3_fh_sz+1) 83#define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \ 84 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) 85#define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \ 86 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) 87#define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) 88 89/* 90 * Map file type to S_IFMT bits 91 */ 92static const umode_t nfs_type2fmt[] = { 93 [NF3BAD] = 0, 94 [NF3REG] = S_IFREG, 95 [NF3DIR] = S_IFDIR, 96 [NF3BLK] = S_IFBLK, 97 [NF3CHR] = S_IFCHR, 98 [NF3LNK] = S_IFLNK, 99 [NF3SOCK] = S_IFSOCK, 100 [NF3FIFO] = S_IFIFO, 101}; 102 103/* 104 * While encoding arguments, set up the reply buffer in advance to 105 * receive reply data directly into the page cache. 106 */ 107static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, 108 unsigned int base, unsigned int len, 109 unsigned int bufsize) 110{ 111 struct rpc_auth *auth = req->rq_cred->cr_auth; 112 unsigned int replen; 113 114 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize; 115 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len); 116} 117 118/* 119 * Handle decode buffer overflows out-of-line. 120 */ 121static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) 122{ 123 dprintk("NFS: %s prematurely hit the end of our receive buffer. " 124 "Remaining buffer length is %tu words.\n", 125 func, xdr->end - xdr->p); 126} 127 128 129/* 130 * Encode/decode NFSv3 basic data types 131 * 132 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813: 133 * "NFS Version 3 Protocol Specification". 134 * 135 * Not all basic data types have their own encoding and decoding 136 * functions. For run-time efficiency, some data types are encoded 137 * or decoded inline. 138 */ 139 140static void encode_uint32(struct xdr_stream *xdr, u32 value) 141{ 142 __be32 *p = xdr_reserve_space(xdr, 4); 143 *p = cpu_to_be32(value); 144} 145 146static int decode_uint32(struct xdr_stream *xdr, u32 *value) 147{ 148 __be32 *p; 149 150 p = xdr_inline_decode(xdr, 4); 151 if (unlikely(p == NULL)) 152 goto out_overflow; 153 *value = be32_to_cpup(p); 154 return 0; 155out_overflow: 156 print_overflow_msg(__func__, xdr); 157 return -EIO; 158} 159 160static int decode_uint64(struct xdr_stream *xdr, u64 *value) 161{ 162 __be32 *p; 163 164 p = xdr_inline_decode(xdr, 8); 165 if (unlikely(p == NULL)) 166 goto out_overflow; 167 xdr_decode_hyper(p, value); 168 return 0; 169out_overflow: 170 print_overflow_msg(__func__, xdr); 171 return -EIO; 172} 173 174/* 175 * fileid3 176 * 177 * typedef uint64 fileid3; 178 */ 179static __be32 *xdr_decode_fileid3(__be32 *p, u64 *fileid) 180{ 181 return xdr_decode_hyper(p, fileid); 182} 183 184static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid) 185{ 186 return decode_uint64(xdr, fileid); 187} 188 189/* 190 * filename3 191 * 192 * typedef string filename3<>; 193 */ 194static void encode_filename3(struct xdr_stream *xdr, 195 const char *name, u32 length) 196{ 197 __be32 *p; 198 199 BUG_ON(length > NFS3_MAXNAMLEN); 200 p = xdr_reserve_space(xdr, 4 + length); 201 xdr_encode_opaque(p, name, length); 202} 203 204static int decode_inline_filename3(struct xdr_stream *xdr, 205 const char **name, u32 *length) 206{ 207 __be32 *p; 208 u32 count; 209 210 p = xdr_inline_decode(xdr, 4); 211 if (unlikely(p == NULL)) 212 goto out_overflow; 213 count = be32_to_cpup(p); 214 if (count > NFS3_MAXNAMLEN) 215 goto out_nametoolong; 216 p = xdr_inline_decode(xdr, count); 217 if (unlikely(p == NULL)) 218 goto out_overflow; 219 *name = (const char *)p; 220 *length = count; 221 return 0; 222 223out_nametoolong: 224 dprintk("NFS: returned filename too long: %u\n", count); 225 return -ENAMETOOLONG; 226out_overflow: 227 print_overflow_msg(__func__, xdr); 228 return -EIO; 229} 230 231/* 232 * nfspath3 233 * 234 * typedef string nfspath3<>; 235 */ 236static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages, 237 const u32 length) 238{ 239 BUG_ON(length > NFS3_MAXPATHLEN); 240 encode_uint32(xdr, length); 241 xdr_write_pages(xdr, pages, 0, length); 242} 243 244static int decode_nfspath3(struct xdr_stream *xdr) 245{ 246 u32 recvd, count; 247 size_t hdrlen; 248 __be32 *p; 249 250 p = xdr_inline_decode(xdr, 4); 251 if (unlikely(p == NULL)) 252 goto out_overflow; 253 count = be32_to_cpup(p); 254 if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN)) 255 goto out_nametoolong; 256 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; 257 recvd = xdr->buf->len - hdrlen; 258 if (unlikely(count > recvd)) 259 goto out_cheating; 260 261 xdr_read_pages(xdr, count); 262 xdr_terminate_string(xdr->buf, count); 263 return 0; 264 265out_nametoolong: 266 dprintk("NFS: returned pathname too long: %u\n", count); 267 return -ENAMETOOLONG; 268out_cheating: 269 dprintk("NFS: server cheating in pathname result: " 270 "count %u > recvd %u\n", count, recvd); 271 return -EIO; 272out_overflow: 273 print_overflow_msg(__func__, xdr); 274 return -EIO; 275} 276 277/* 278 * cookie3 279 * 280 * typedef uint64 cookie3 281 */ 282static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie) 283{ 284 return xdr_encode_hyper(p, cookie); 285} 286 287static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie) 288{ 289 return decode_uint64(xdr, cookie); 290} 291 292/* 293 * cookieverf3 294 * 295 * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE]; 296 */ 297static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier) 298{ 299 memcpy(p, verifier, NFS3_COOKIEVERFSIZE); 300 return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE); 301} 302 303static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier) 304{ 305 __be32 *p; 306 307 p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE); 308 if (unlikely(p == NULL)) 309 goto out_overflow; 310 memcpy(verifier, p, NFS3_COOKIEVERFSIZE); 311 return 0; 312out_overflow: 313 print_overflow_msg(__func__, xdr); 314 return -EIO; 315} 316 317/* 318 * createverf3 319 * 320 * typedef opaque createverf3[NFS3_CREATEVERFSIZE]; 321 */ 322static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier) 323{ 324 __be32 *p; 325 326 p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE); 327 memcpy(p, verifier, NFS3_CREATEVERFSIZE); 328} 329 330static int decode_writeverf3(struct xdr_stream *xdr, __be32 *verifier) 331{ 332 __be32 *p; 333 334 p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE); 335 if (unlikely(p == NULL)) 336 goto out_overflow; 337 memcpy(verifier, p, NFS3_WRITEVERFSIZE); 338 return 0; 339out_overflow: 340 print_overflow_msg(__func__, xdr); 341 return -EIO; 342} 343 344/* 345 * size3 346 * 347 * typedef uint64 size3; 348 */ 349static __be32 *xdr_decode_size3(__be32 *p, u64 *size) 350{ 351 return xdr_decode_hyper(p, size); 352} 353 354/* 355 * nfsstat3 356 * 357 * enum nfsstat3 { 358 * NFS3_OK = 0, 359 * ... 360 * } 361 */ 362#define NFS3_OK NFS_OK 363 364static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status) 365{ 366 __be32 *p; 367 368 p = xdr_inline_decode(xdr, 4); 369 if (unlikely(p == NULL)) 370 goto out_overflow; 371 *status = be32_to_cpup(p); 372 return 0; 373out_overflow: 374 print_overflow_msg(__func__, xdr); 375 return -EIO; 376} 377 378/* 379 * ftype3 380 * 381 * enum ftype3 { 382 * NF3REG = 1, 383 * NF3DIR = 2, 384 * NF3BLK = 3, 385 * NF3CHR = 4, 386 * NF3LNK = 5, 387 * NF3SOCK = 6, 388 * NF3FIFO = 7 389 * }; 390 */ 391static void encode_ftype3(struct xdr_stream *xdr, const u32 type) 392{ 393 BUG_ON(type > NF3FIFO); 394 encode_uint32(xdr, type); 395} 396 397static __be32 *xdr_decode_ftype3(__be32 *p, umode_t *mode) 398{ 399 u32 type; 400 401 type = be32_to_cpup(p++); 402 if (type > NF3FIFO) 403 type = NF3NON; 404 *mode = nfs_type2fmt[type]; 405 return p; 406} 407 408/* 409 * specdata3 410 * 411 * struct specdata3 { 412 * uint32 specdata1; 413 * uint32 specdata2; 414 * }; 415 */ 416static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev) 417{ 418 __be32 *p; 419 420 p = xdr_reserve_space(xdr, 8); 421 *p++ = cpu_to_be32(MAJOR(rdev)); 422 *p = cpu_to_be32(MINOR(rdev)); 423} 424 425static __be32 *xdr_decode_specdata3(__be32 *p, dev_t *rdev) 426{ 427 unsigned int major, minor; 428 429 major = be32_to_cpup(p++); 430 minor = be32_to_cpup(p++); 431 *rdev = MKDEV(major, minor); 432 if (MAJOR(*rdev) != major || MINOR(*rdev) != minor) 433 *rdev = 0; 434 return p; 435} 436 437/* 438 * nfs_fh3 439 * 440 * struct nfs_fh3 { 441 * opaque data<NFS3_FHSIZE>; 442 * }; 443 */ 444static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh) 445{ 446 __be32 *p; 447 448 BUG_ON(fh->size > NFS3_FHSIZE); 449 p = xdr_reserve_space(xdr, 4 + fh->size); 450 xdr_encode_opaque(p, fh->data, fh->size); 451} 452 453static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) 454{ 455 u32 length; 456 __be32 *p; 457 458 p = xdr_inline_decode(xdr, 4); 459 if (unlikely(p == NULL)) 460 goto out_overflow; 461 length = be32_to_cpup(p++); 462 if (unlikely(length > NFS3_FHSIZE)) 463 goto out_toobig; 464 p = xdr_inline_decode(xdr, length); 465 if (unlikely(p == NULL)) 466 goto out_overflow; 467 fh->size = length; 468 memcpy(fh->data, p, length); 469 return 0; 470out_toobig: 471 dprintk("NFS: file handle size (%u) too big\n", length); 472 return -E2BIG; 473out_overflow: 474 print_overflow_msg(__func__, xdr); 475 return -EIO; 476} 477 478static void zero_nfs_fh3(struct nfs_fh *fh) 479{ 480 memset(fh, 0, sizeof(*fh)); 481} 482 483/* 484 * nfstime3 485 * 486 * struct nfstime3 { 487 * uint32 seconds; 488 * uint32 nseconds; 489 * }; 490 */ 491static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep) 492{ 493 *p++ = cpu_to_be32(timep->tv_sec); 494 *p++ = cpu_to_be32(timep->tv_nsec); 495 return p; 496} 497 498static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec *timep) 499{ 500 timep->tv_sec = be32_to_cpup(p++); 501 timep->tv_nsec = be32_to_cpup(p++); 502 return p; 503} 504 505/* 506 * sattr3 507 * 508 * enum time_how { 509 * DONT_CHANGE = 0, 510 * SET_TO_SERVER_TIME = 1, 511 * SET_TO_CLIENT_TIME = 2 512 * }; 513 * 514 * union set_mode3 switch (bool set_it) { 515 * case TRUE: 516 * mode3 mode; 517 * default: 518 * void; 519 * }; 520 * 521 * union set_uid3 switch (bool set_it) { 522 * case TRUE: 523 * uid3 uid; 524 * default: 525 * void; 526 * }; 527 * 528 * union set_gid3 switch (bool set_it) { 529 * case TRUE: 530 * gid3 gid; 531 * default: 532 * void; 533 * }; 534 * 535 * union set_size3 switch (bool set_it) { 536 * case TRUE: 537 * size3 size; 538 * default: 539 * void; 540 * }; 541 * 542 * union set_atime switch (time_how set_it) { 543 * case SET_TO_CLIENT_TIME: 544 * nfstime3 atime; 545 * default: 546 * void; 547 * }; 548 * 549 * union set_mtime switch (time_how set_it) { 550 * case SET_TO_CLIENT_TIME: 551 * nfstime3 mtime; 552 * default: 553 * void; 554 * }; 555 * 556 * struct sattr3 { 557 * set_mode3 mode; 558 * set_uid3 uid; 559 * set_gid3 gid; 560 * set_size3 size; 561 * set_atime atime; 562 * set_mtime mtime; 563 * }; 564 */ 565static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr) 566{ 567 u32 nbytes; 568 __be32 *p; 569 570 /* 571 * In order to make only a single xdr_reserve_space() call, 572 * pre-compute the total number of bytes to be reserved. 573 * Six boolean values, one for each set_foo field, are always 574 * present in the encoded result, so start there. 575 */ 576 nbytes = 6 * 4; 577 if (attr->ia_valid & ATTR_MODE) 578 nbytes += 4; 579 if (attr->ia_valid & ATTR_UID) 580 nbytes += 4; 581 if (attr->ia_valid & ATTR_GID) 582 nbytes += 4; 583 if (attr->ia_valid & ATTR_SIZE) 584 nbytes += 8; 585 if (attr->ia_valid & ATTR_ATIME_SET) 586 nbytes += 8; 587 if (attr->ia_valid & ATTR_MTIME_SET) 588 nbytes += 8; 589 p = xdr_reserve_space(xdr, nbytes); 590 591 if (attr->ia_valid & ATTR_MODE) { 592 *p++ = xdr_one; 593 *p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO); 594 } else 595 *p++ = xdr_zero; 596 597 if (attr->ia_valid & ATTR_UID) { 598 *p++ = xdr_one; 599 *p++ = cpu_to_be32(attr->ia_uid); 600 } else 601 *p++ = xdr_zero; 602 603 if (attr->ia_valid & ATTR_GID) { 604 *p++ = xdr_one; 605 *p++ = cpu_to_be32(attr->ia_gid); 606 } else 607 *p++ = xdr_zero; 608 609 if (attr->ia_valid & ATTR_SIZE) { 610 *p++ = xdr_one; 611 p = xdr_encode_hyper(p, (u64)attr->ia_size); 612 } else 613 *p++ = xdr_zero; 614 615 if (attr->ia_valid & ATTR_ATIME_SET) { 616 *p++ = xdr_two; 617 p = xdr_encode_nfstime3(p, &attr->ia_atime); 618 } else if (attr->ia_valid & ATTR_ATIME) { 619 *p++ = xdr_one; 620 } else 621 *p++ = xdr_zero; 622 623 if (attr->ia_valid & ATTR_MTIME_SET) { 624 *p++ = xdr_two; 625 xdr_encode_nfstime3(p, &attr->ia_mtime); 626 } else if (attr->ia_valid & ATTR_MTIME) { 627 *p = xdr_one; 628 } else 629 *p = xdr_zero; 630} 631 632/* 633 * fattr3 634 * 635 * struct fattr3 { 636 * ftype3 type; 637 * mode3 mode; 638 * uint32 nlink; 639 * uid3 uid; 640 * gid3 gid; 641 * size3 size; 642 * size3 used; 643 * specdata3 rdev; 644 * uint64 fsid; 645 * fileid3 fileid; 646 * nfstime3 atime; 647 * nfstime3 mtime; 648 * nfstime3 ctime; 649 * }; 650 */ 651static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr) 652{ 653 umode_t fmode; 654 __be32 *p; 655 656 p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2); 657 if (unlikely(p == NULL)) 658 goto out_overflow; 659 660 p = xdr_decode_ftype3(p, &fmode); 661 662 fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode; 663 fattr->nlink = be32_to_cpup(p++); 664 fattr->uid = be32_to_cpup(p++); 665 fattr->gid = be32_to_cpup(p++); 666 667 p = xdr_decode_size3(p, &fattr->size); 668 p = xdr_decode_size3(p, &fattr->du.nfs3.used); 669 p = xdr_decode_specdata3(p, &fattr->rdev); 670 671 p = xdr_decode_hyper(p, &fattr->fsid.major); 672 fattr->fsid.minor = 0; 673 674 p = xdr_decode_fileid3(p, &fattr->fileid); 675 p = xdr_decode_nfstime3(p, &fattr->atime); 676 p = xdr_decode_nfstime3(p, &fattr->mtime); 677 xdr_decode_nfstime3(p, &fattr->ctime); 678 679 fattr->valid |= NFS_ATTR_FATTR_V3; 680 return 0; 681out_overflow: 682 print_overflow_msg(__func__, xdr); 683 return -EIO; 684} 685 686/* 687 * post_op_attr 688 * 689 * union post_op_attr switch (bool attributes_follow) { 690 * case TRUE: 691 * fattr3 attributes; 692 * case FALSE: 693 * void; 694 * }; 695 */ 696static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) 697{ 698 __be32 *p; 699 700 p = xdr_inline_decode(xdr, 4); 701 if (unlikely(p == NULL)) 702 goto out_overflow; 703 if (*p != xdr_zero) 704 return decode_fattr3(xdr, fattr); 705 return 0; 706out_overflow: 707 print_overflow_msg(__func__, xdr); 708 return -EIO; 709} 710 711/* 712 * wcc_attr 713 * struct wcc_attr { 714 * size3 size; 715 * nfstime3 mtime; 716 * nfstime3 ctime; 717 * }; 718 */ 719static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) 720{ 721 __be32 *p; 722 723 p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2); 724 if (unlikely(p == NULL)) 725 goto out_overflow; 726 727 fattr->valid |= NFS_ATTR_FATTR_PRESIZE 728 | NFS_ATTR_FATTR_PREMTIME 729 | NFS_ATTR_FATTR_PRECTIME; 730 731 p = xdr_decode_size3(p, &fattr->pre_size); 732 p = xdr_decode_nfstime3(p, &fattr->pre_mtime); 733 xdr_decode_nfstime3(p, &fattr->pre_ctime); 734 735 return 0; 736out_overflow: 737 print_overflow_msg(__func__, xdr); 738 return -EIO; 739} 740 741/* 742 * pre_op_attr 743 * union pre_op_attr switch (bool attributes_follow) { 744 * case TRUE: 745 * wcc_attr attributes; 746 * case FALSE: 747 * void; 748 * }; 749 * 750 * wcc_data 751 * 752 * struct wcc_data { 753 * pre_op_attr before; 754 * post_op_attr after; 755 * }; 756 */ 757static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) 758{ 759 __be32 *p; 760 761 p = xdr_inline_decode(xdr, 4); 762 if (unlikely(p == NULL)) 763 goto out_overflow; 764 if (*p != xdr_zero) 765 return decode_wcc_attr(xdr, fattr); 766 return 0; 767out_overflow: 768 print_overflow_msg(__func__, xdr); 769 return -EIO; 770} 771 772static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr) 773{ 774 int error; 775 776 error = decode_pre_op_attr(xdr, fattr); 777 if (unlikely(error)) 778 goto out; 779 error = decode_post_op_attr(xdr, fattr); 780out: 781 return error; 782} 783 784/* 785 * post_op_fh3 786 * 787 * union post_op_fh3 switch (bool handle_follows) { 788 * case TRUE: 789 * nfs_fh3 handle; 790 * case FALSE: 791 * void; 792 * }; 793 */ 794static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) 795{ 796 __be32 *p = xdr_inline_decode(xdr, 4); 797 if (unlikely(p == NULL)) 798 goto out_overflow; 799 if (*p != xdr_zero) 800 return decode_nfs_fh3(xdr, fh); 801 zero_nfs_fh3(fh); 802 return 0; 803out_overflow: 804 print_overflow_msg(__func__, xdr); 805 return -EIO; 806} 807 808/* 809 * diropargs3 810 * 811 * struct diropargs3 { 812 * nfs_fh3 dir; 813 * filename3 name; 814 * }; 815 */ 816static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh, 817 const char *name, u32 length) 818{ 819 encode_nfs_fh3(xdr, fh); 820 encode_filename3(xdr, name, length); 821} 822 823 824/* 825 * NFSv3 XDR encode functions 826 * 827 * NFSv3 argument types are defined in section 3.3 of RFC 1813: 828 * "NFS Version 3 Protocol Specification". 829 */ 830 831/* 832 * 3.3.1 GETATTR3args 833 * 834 * struct GETATTR3args { 835 * nfs_fh3 object; 836 * }; 837 */ 838static void nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, 839 struct xdr_stream *xdr, 840 const struct nfs_fh *fh) 841{ 842 encode_nfs_fh3(xdr, fh); 843} 844 845/* 846 * 3.3.2 SETATTR3args 847 * 848 * union sattrguard3 switch (bool check) { 849 * case TRUE: 850 * nfstime3 obj_ctime; 851 * case FALSE: 852 * void; 853 * }; 854 * 855 * struct SETATTR3args { 856 * nfs_fh3 object; 857 * sattr3 new_attributes; 858 * sattrguard3 guard; 859 * }; 860 */ 861static void encode_sattrguard3(struct xdr_stream *xdr, 862 const struct nfs3_sattrargs *args) 863{ 864 __be32 *p; 865 866 if (args->guard) { 867 p = xdr_reserve_space(xdr, 4 + 8); 868 *p++ = xdr_one; 869 xdr_encode_nfstime3(p, &args->guardtime); 870 } else { 871 p = xdr_reserve_space(xdr, 4); 872 *p = xdr_zero; 873 } 874} 875 876static void nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, 877 struct xdr_stream *xdr, 878 const struct nfs3_sattrargs *args) 879{ 880 encode_nfs_fh3(xdr, args->fh); 881 encode_sattr3(xdr, args->sattr); 882 encode_sattrguard3(xdr, args); 883} 884 885/* 886 * 3.3.3 LOOKUP3args 887 * 888 * struct LOOKUP3args { 889 * diropargs3 what; 890 * }; 891 */ 892static void nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, 893 struct xdr_stream *xdr, 894 const struct nfs3_diropargs *args) 895{ 896 encode_diropargs3(xdr, args->fh, args->name, args->len); 897} 898 899/* 900 * 3.3.4 ACCESS3args 901 * 902 * struct ACCESS3args { 903 * nfs_fh3 object; 904 * uint32 access; 905 * }; 906 */ 907static void encode_access3args(struct xdr_stream *xdr, 908 const struct nfs3_accessargs *args) 909{ 910 encode_nfs_fh3(xdr, args->fh); 911 encode_uint32(xdr, args->access); 912} 913 914static void nfs3_xdr_enc_access3args(struct rpc_rqst *req, 915 struct xdr_stream *xdr, 916 const struct nfs3_accessargs *args) 917{ 918 encode_access3args(xdr, args); 919} 920 921/* 922 * 3.3.5 READLINK3args 923 * 924 * struct READLINK3args { 925 * nfs_fh3 symlink; 926 * }; 927 */ 928static void nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, 929 struct xdr_stream *xdr, 930 const struct nfs3_readlinkargs *args) 931{ 932 encode_nfs_fh3(xdr, args->fh); 933 prepare_reply_buffer(req, args->pages, args->pgbase, 934 args->pglen, NFS3_readlinkres_sz); 935} 936 937/* 938 * 3.3.6 READ3args 939 * 940 * struct READ3args { 941 * nfs_fh3 file; 942 * offset3 offset; 943 * count3 count; 944 * }; 945 */ 946static void encode_read3args(struct xdr_stream *xdr, 947 const struct nfs_readargs *args) 948{ 949 __be32 *p; 950 951 encode_nfs_fh3(xdr, args->fh); 952 953 p = xdr_reserve_space(xdr, 8 + 4); 954 p = xdr_encode_hyper(p, args->offset); 955 *p = cpu_to_be32(args->count); 956} 957 958static void nfs3_xdr_enc_read3args(struct rpc_rqst *req, 959 struct xdr_stream *xdr, 960 const struct nfs_readargs *args) 961{ 962 encode_read3args(xdr, args); 963 prepare_reply_buffer(req, args->pages, args->pgbase, 964 args->count, NFS3_readres_sz); 965 req->rq_rcv_buf.flags |= XDRBUF_READ; 966} 967 968/* 969 * 3.3.7 WRITE3args 970 * 971 * enum stable_how { 972 * UNSTABLE = 0, 973 * DATA_SYNC = 1, 974 * FILE_SYNC = 2 975 * }; 976 * 977 * struct WRITE3args { 978 * nfs_fh3 file; 979 * offset3 offset; 980 * count3 count; 981 * stable_how stable; 982 * opaque data<>; 983 * }; 984 */ 985static void encode_write3args(struct xdr_stream *xdr, 986 const struct nfs_writeargs *args) 987{ 988 __be32 *p; 989 990 encode_nfs_fh3(xdr, args->fh); 991 992 p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4); 993 p = xdr_encode_hyper(p, args->offset); 994 *p++ = cpu_to_be32(args->count); 995 *p++ = cpu_to_be32(args->stable); 996 *p = cpu_to_be32(args->count); 997 xdr_write_pages(xdr, args->pages, args->pgbase, args->count); 998} 999 1000static void nfs3_xdr_enc_write3args(struct rpc_rqst *req, 1001 struct xdr_stream *xdr, 1002 const struct nfs_writeargs *args) 1003{ 1004 encode_write3args(xdr, args); 1005 xdr->buf->flags |= XDRBUF_WRITE; 1006} 1007 1008/* 1009 * 3.3.8 CREATE3args 1010 * 1011 * enum createmode3 { 1012 * UNCHECKED = 0, 1013 * GUARDED = 1, 1014 * EXCLUSIVE = 2 1015 * }; 1016 * 1017 * union createhow3 switch (createmode3 mode) { 1018 * case UNCHECKED: 1019 * case GUARDED: 1020 * sattr3 obj_attributes; 1021 * case EXCLUSIVE: 1022 * createverf3 verf; 1023 * }; 1024 * 1025 * struct CREATE3args { 1026 * diropargs3 where; 1027 * createhow3 how; 1028 * }; 1029 */ 1030static void encode_createhow3(struct xdr_stream *xdr, 1031 const struct nfs3_createargs *args) 1032{ 1033 encode_uint32(xdr, args->createmode); 1034 switch (args->createmode) { 1035 case NFS3_CREATE_UNCHECKED: 1036 case NFS3_CREATE_GUARDED: 1037 encode_sattr3(xdr, args->sattr); 1038 break; 1039 case NFS3_CREATE_EXCLUSIVE: 1040 encode_createverf3(xdr, args->verifier); 1041 break; 1042 default: 1043 BUG(); 1044 } 1045} 1046 1047static void nfs3_xdr_enc_create3args(struct rpc_rqst *req, 1048 struct xdr_stream *xdr, 1049 const struct nfs3_createargs *args) 1050{ 1051 encode_diropargs3(xdr, args->fh, args->name, args->len); 1052 encode_createhow3(xdr, args); 1053} 1054 1055/* 1056 * 3.3.9 MKDIR3args 1057 * 1058 * struct MKDIR3args { 1059 * diropargs3 where; 1060 * sattr3 attributes; 1061 * }; 1062 */ 1063static void nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, 1064 struct xdr_stream *xdr, 1065 const struct nfs3_mkdirargs *args) 1066{ 1067 encode_diropargs3(xdr, args->fh, args->name, args->len); 1068 encode_sattr3(xdr, args->sattr); 1069} 1070 1071/* 1072 * 3.3.10 SYMLINK3args 1073 * 1074 * struct symlinkdata3 { 1075 * sattr3 symlink_attributes; 1076 * nfspath3 symlink_data; 1077 * }; 1078 * 1079 * struct SYMLINK3args { 1080 * diropargs3 where; 1081 * symlinkdata3 symlink; 1082 * }; 1083 */ 1084static void encode_symlinkdata3(struct xdr_stream *xdr, 1085 const struct nfs3_symlinkargs *args) 1086{ 1087 encode_sattr3(xdr, args->sattr); 1088 encode_nfspath3(xdr, args->pages, args->pathlen); 1089} 1090 1091static void nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, 1092 struct xdr_stream *xdr, 1093 const struct nfs3_symlinkargs *args) 1094{ 1095 encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen); 1096 encode_symlinkdata3(xdr, args); 1097} 1098 1099/* 1100 * 3.3.11 MKNOD3args 1101 * 1102 * struct devicedata3 { 1103 * sattr3 dev_attributes; 1104 * specdata3 spec; 1105 * }; 1106 * 1107 * union mknoddata3 switch (ftype3 type) { 1108 * case NF3CHR: 1109 * case NF3BLK: 1110 * devicedata3 device; 1111 * case NF3SOCK: 1112 * case NF3FIFO: 1113 * sattr3 pipe_attributes; 1114 * default: 1115 * void; 1116 * }; 1117 * 1118 * struct MKNOD3args { 1119 * diropargs3 where; 1120 * mknoddata3 what; 1121 * }; 1122 */ 1123static void encode_devicedata3(struct xdr_stream *xdr, 1124 const struct nfs3_mknodargs *args) 1125{ 1126 encode_sattr3(xdr, args->sattr); 1127 encode_specdata3(xdr, args->rdev); 1128} 1129 1130static void encode_mknoddata3(struct xdr_stream *xdr, 1131 const struct nfs3_mknodargs *args) 1132{ 1133 encode_ftype3(xdr, args->type); 1134 switch (args->type) { 1135 case NF3CHR: 1136 case NF3BLK: 1137 encode_devicedata3(xdr, args); 1138 break; 1139 case NF3SOCK: 1140 case NF3FIFO: 1141 encode_sattr3(xdr, args->sattr); 1142 break; 1143 case NF3REG: 1144 case NF3DIR: 1145 break; 1146 default: 1147 BUG(); 1148 } 1149} 1150 1151static void nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, 1152 struct xdr_stream *xdr, 1153 const struct nfs3_mknodargs *args) 1154{ 1155 encode_diropargs3(xdr, args->fh, args->name, args->len); 1156 encode_mknoddata3(xdr, args); 1157} 1158 1159/* 1160 * 3.3.12 REMOVE3args 1161 * 1162 * struct REMOVE3args { 1163 * diropargs3 object; 1164 * }; 1165 */ 1166static void nfs3_xdr_enc_remove3args(struct rpc_rqst *req, 1167 struct xdr_stream *xdr, 1168 const struct nfs_removeargs *args) 1169{ 1170 encode_diropargs3(xdr, args->fh, args->name.name, args->name.len); 1171} 1172 1173/* 1174 * 3.3.14 RENAME3args 1175 * 1176 * struct RENAME3args { 1177 * diropargs3 from; 1178 * diropargs3 to; 1179 * }; 1180 */ 1181static void nfs3_xdr_enc_rename3args(struct rpc_rqst *req, 1182 struct xdr_stream *xdr, 1183 const struct nfs_renameargs *args) 1184{ 1185 const struct qstr *old = args->old_name; 1186 const struct qstr *new = args->new_name; 1187 1188 encode_diropargs3(xdr, args->old_dir, old->name, old->len); 1189 encode_diropargs3(xdr, args->new_dir, new->name, new->len); 1190} 1191 1192/* 1193 * 3.3.15 LINK3args 1194 * 1195 * struct LINK3args { 1196 * nfs_fh3 file; 1197 * diropargs3 link; 1198 * }; 1199 */ 1200static void nfs3_xdr_enc_link3args(struct rpc_rqst *req, 1201 struct xdr_stream *xdr, 1202 const struct nfs3_linkargs *args) 1203{ 1204 encode_nfs_fh3(xdr, args->fromfh); 1205 encode_diropargs3(xdr, args->tofh, args->toname, args->tolen); 1206} 1207 1208/* 1209 * 3.3.16 READDIR3args 1210 * 1211 * struct READDIR3args { 1212 * nfs_fh3 dir; 1213 * cookie3 cookie; 1214 * cookieverf3 cookieverf; 1215 * count3 count; 1216 * }; 1217 */ 1218static void encode_readdir3args(struct xdr_stream *xdr, 1219 const struct nfs3_readdirargs *args) 1220{ 1221 __be32 *p; 1222 1223 encode_nfs_fh3(xdr, args->fh); 1224 1225 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4); 1226 p = xdr_encode_cookie3(p, args->cookie); 1227 p = xdr_encode_cookieverf3(p, args->verf); 1228 *p = cpu_to_be32(args->count); 1229} 1230 1231static void nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, 1232 struct xdr_stream *xdr, 1233 const struct nfs3_readdirargs *args) 1234{ 1235 encode_readdir3args(xdr, args); 1236 prepare_reply_buffer(req, args->pages, 0, 1237 args->count, NFS3_readdirres_sz); 1238} 1239 1240/* 1241 * 3.3.17 READDIRPLUS3args 1242 * 1243 * struct READDIRPLUS3args { 1244 * nfs_fh3 dir; 1245 * cookie3 cookie; 1246 * cookieverf3 cookieverf; 1247 * count3 dircount; 1248 * count3 maxcount; 1249 * }; 1250 */ 1251static void encode_readdirplus3args(struct xdr_stream *xdr, 1252 const struct nfs3_readdirargs *args) 1253{ 1254 __be32 *p; 1255 1256 encode_nfs_fh3(xdr, args->fh); 1257 1258 p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4); 1259 p = xdr_encode_cookie3(p, args->cookie); 1260 p = xdr_encode_cookieverf3(p, args->verf); 1261 1262 /* 1263 * readdirplus: need dircount + buffer size. 1264 * We just make sure we make dircount big enough 1265 */ 1266 *p++ = cpu_to_be32(args->count >> 3); 1267 1268 *p = cpu_to_be32(args->count); 1269} 1270 1271static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, 1272 struct xdr_stream *xdr, 1273 const struct nfs3_readdirargs *args) 1274{ 1275 encode_readdirplus3args(xdr, args); 1276 prepare_reply_buffer(req, args->pages, 0, 1277 args->count, NFS3_readdirres_sz); 1278} 1279 1280/* 1281 * 3.3.21 COMMIT3args 1282 * 1283 * struct COMMIT3args { 1284 * nfs_fh3 file; 1285 * offset3 offset; 1286 * count3 count; 1287 * }; 1288 */ 1289static void encode_commit3args(struct xdr_stream *xdr, 1290 const struct nfs_writeargs *args) 1291{ 1292 __be32 *p; 1293 1294 encode_nfs_fh3(xdr, args->fh); 1295 1296 p = xdr_reserve_space(xdr, 8 + 4); 1297 p = xdr_encode_hyper(p, args->offset); 1298 *p = cpu_to_be32(args->count); 1299} 1300 1301static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req, 1302 struct xdr_stream *xdr, 1303 const struct nfs_writeargs *args) 1304{ 1305 encode_commit3args(xdr, args); 1306} 1307 1308#ifdef CONFIG_NFS_V3_ACL 1309 1310static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, 1311 struct xdr_stream *xdr, 1312 const struct nfs3_getaclargs *args) 1313{ 1314 encode_nfs_fh3(xdr, args->fh); 1315 encode_uint32(xdr, args->mask); 1316 if (args->mask & (NFS_ACL | NFS_DFACL)) 1317 prepare_reply_buffer(req, args->pages, 0, 1318 NFSACL_MAXPAGES << PAGE_SHIFT, 1319 ACL3_getaclres_sz); 1320} 1321 1322static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, 1323 struct xdr_stream *xdr, 1324 const struct nfs3_setaclargs *args) 1325{ 1326 unsigned int base; 1327 int error; 1328 1329 encode_nfs_fh3(xdr, NFS_FH(args->inode)); 1330 encode_uint32(xdr, args->mask); 1331 1332 base = req->rq_slen; 1333 if (args->npages != 0) 1334 xdr_write_pages(xdr, args->pages, 0, args->len); 1335 else 1336 xdr_reserve_space(xdr, NFS_ACL_INLINE_BUFSIZE); 1337 1338 error = nfsacl_encode(xdr->buf, base, args->inode, 1339 (args->mask & NFS_ACL) ? 1340 args->acl_access : NULL, 1, 0); 1341 BUG_ON(error < 0); 1342 error = nfsacl_encode(xdr->buf, base + error, args->inode, 1343 (args->mask & NFS_DFACL) ? 1344 args->acl_default : NULL, 1, 1345 NFS_ACL_DEFAULT); 1346 BUG_ON(error < 0); 1347} 1348 1349#endif /* CONFIG_NFS_V3_ACL */ 1350 1351/* 1352 * NFSv3 XDR decode functions 1353 * 1354 * NFSv3 result types are defined in section 3.3 of RFC 1813: 1355 * "NFS Version 3 Protocol Specification". 1356 */ 1357 1358/* 1359 * 3.3.1 GETATTR3res 1360 * 1361 * struct GETATTR3resok { 1362 * fattr3 obj_attributes; 1363 * }; 1364 * 1365 * union GETATTR3res switch (nfsstat3 status) { 1366 * case NFS3_OK: 1367 * GETATTR3resok resok; 1368 * default: 1369 * void; 1370 * }; 1371 */ 1372static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, 1373 struct xdr_stream *xdr, 1374 struct nfs_fattr *result) 1375{ 1376 enum nfs_stat status; 1377 int error; 1378 1379 error = decode_nfsstat3(xdr, &status); 1380 if (unlikely(error)) 1381 goto out; 1382 if (status != NFS3_OK) 1383 goto out_default; 1384 error = decode_fattr3(xdr, result); 1385out: 1386 return error; 1387out_default: 1388 return nfs_stat_to_errno(status); 1389} 1390 1391/* 1392 * 3.3.2 SETATTR3res 1393 * 1394 * struct SETATTR3resok { 1395 * wcc_data obj_wcc; 1396 * }; 1397 * 1398 * struct SETATTR3resfail { 1399 * wcc_data obj_wcc; 1400 * }; 1401 * 1402 * union SETATTR3res switch (nfsstat3 status) { 1403 * case NFS3_OK: 1404 * SETATTR3resok resok; 1405 * default: 1406 * SETATTR3resfail resfail; 1407 * }; 1408 */ 1409static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, 1410 struct xdr_stream *xdr, 1411 struct nfs_fattr *result) 1412{ 1413 enum nfs_stat status; 1414 int error; 1415 1416 error = decode_nfsstat3(xdr, &status); 1417 if (unlikely(error)) 1418 goto out; 1419 error = decode_wcc_data(xdr, result); 1420 if (unlikely(error)) 1421 goto out; 1422 if (status != NFS3_OK) 1423 goto out_status; 1424out: 1425 return error; 1426out_status: 1427 return nfs_stat_to_errno(status); 1428} 1429 1430/* 1431 * 3.3.3 LOOKUP3res 1432 * 1433 * struct LOOKUP3resok { 1434 * nfs_fh3 object; 1435 * post_op_attr obj_attributes; 1436 * post_op_attr dir_attributes; 1437 * }; 1438 * 1439 * struct LOOKUP3resfail { 1440 * post_op_attr dir_attributes; 1441 * }; 1442 * 1443 * union LOOKUP3res switch (nfsstat3 status) { 1444 * case NFS3_OK: 1445 * LOOKUP3resok resok; 1446 * default: 1447 * LOOKUP3resfail resfail; 1448 * }; 1449 */ 1450static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, 1451 struct xdr_stream *xdr, 1452 struct nfs3_diropres *result) 1453{ 1454 enum nfs_stat status; 1455 int error; 1456 1457 error = decode_nfsstat3(xdr, &status); 1458 if (unlikely(error)) 1459 goto out; 1460 if (status != NFS3_OK) 1461 goto out_default; 1462 error = decode_nfs_fh3(xdr, result->fh); 1463 if (unlikely(error)) 1464 goto out; 1465 error = decode_post_op_attr(xdr, result->fattr); 1466 if (unlikely(error)) 1467 goto out; 1468 error = decode_post_op_attr(xdr, result->dir_attr); 1469out: 1470 return error; 1471out_default: 1472 error = decode_post_op_attr(xdr, result->dir_attr); 1473 if (unlikely(error)) 1474 goto out; 1475 return nfs_stat_to_errno(status); 1476} 1477 1478/* 1479 * 3.3.4 ACCESS3res 1480 * 1481 * struct ACCESS3resok { 1482 * post_op_attr obj_attributes; 1483 * uint32 access; 1484 * }; 1485 * 1486 * struct ACCESS3resfail { 1487 * post_op_attr obj_attributes; 1488 * }; 1489 * 1490 * union ACCESS3res switch (nfsstat3 status) { 1491 * case NFS3_OK: 1492 * ACCESS3resok resok; 1493 * default: 1494 * ACCESS3resfail resfail; 1495 * }; 1496 */ 1497static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, 1498 struct xdr_stream *xdr, 1499 struct nfs3_accessres *result) 1500{ 1501 enum nfs_stat status; 1502 int error; 1503 1504 error = decode_nfsstat3(xdr, &status); 1505 if (unlikely(error)) 1506 goto out; 1507 error = decode_post_op_attr(xdr, result->fattr); 1508 if (unlikely(error)) 1509 goto out; 1510 if (status != NFS3_OK) 1511 goto out_default; 1512 error = decode_uint32(xdr, &result->access); 1513out: 1514 return error; 1515out_default: 1516 return nfs_stat_to_errno(status); 1517} 1518 1519/* 1520 * 3.3.5 READLINK3res 1521 * 1522 * struct READLINK3resok { 1523 * post_op_attr symlink_attributes; 1524 * nfspath3 data; 1525 * }; 1526 * 1527 * struct READLINK3resfail { 1528 * post_op_attr symlink_attributes; 1529 * }; 1530 * 1531 * union READLINK3res switch (nfsstat3 status) { 1532 * case NFS3_OK: 1533 * READLINK3resok resok; 1534 * default: 1535 * READLINK3resfail resfail; 1536 * }; 1537 */ 1538static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, 1539 struct xdr_stream *xdr, 1540 struct nfs_fattr *result) 1541{ 1542 enum nfs_stat status; 1543 int error; 1544 1545 error = decode_nfsstat3(xdr, &status); 1546 if (unlikely(error)) 1547 goto out; 1548 error = decode_post_op_attr(xdr, result); 1549 if (unlikely(error)) 1550 goto out; 1551 if (status != NFS3_OK) 1552 goto out_default; 1553 error = decode_nfspath3(xdr); 1554out: 1555 return error; 1556out_default: 1557 return nfs_stat_to_errno(status); 1558} 1559 1560/* 1561 * 3.3.6 READ3res 1562 * 1563 * struct READ3resok { 1564 * post_op_attr file_attributes; 1565 * count3 count; 1566 * bool eof; 1567 * opaque data<>; 1568 * }; 1569 * 1570 * struct READ3resfail { 1571 * post_op_attr file_attributes; 1572 * }; 1573 * 1574 * union READ3res switch (nfsstat3 status) { 1575 * case NFS3_OK: 1576 * READ3resok resok; 1577 * default: 1578 * READ3resfail resfail; 1579 * }; 1580 */ 1581static int decode_read3resok(struct xdr_stream *xdr, 1582 struct nfs_readres *result) 1583{ 1584 u32 eof, count, ocount, recvd; 1585 size_t hdrlen; 1586 __be32 *p; 1587 1588 p = xdr_inline_decode(xdr, 4 + 4 + 4); 1589 if (unlikely(p == NULL)) 1590 goto out_overflow; 1591 count = be32_to_cpup(p++); 1592 eof = be32_to_cpup(p++); 1593 ocount = be32_to_cpup(p++); 1594 if (unlikely(ocount != count)) 1595 goto out_mismatch; 1596 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; 1597 recvd = xdr->buf->len - hdrlen; 1598 if (unlikely(count > recvd)) 1599 goto out_cheating; 1600 1601out: 1602 xdr_read_pages(xdr, count); 1603 result->eof = eof; 1604 result->count = count; 1605 return count; 1606out_mismatch: 1607 dprintk("NFS: READ count doesn't match length of opaque: " 1608 "count %u != ocount %u\n", count, ocount); 1609 return -EIO; 1610out_cheating: 1611 dprintk("NFS: server cheating in read result: " 1612 "count %u > recvd %u\n", count, recvd); 1613 count = recvd; 1614 eof = 0; 1615 goto out; 1616out_overflow: 1617 print_overflow_msg(__func__, xdr); 1618 return -EIO; 1619} 1620 1621static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr, 1622 struct nfs_readres *result) 1623{ 1624 enum nfs_stat status; 1625 int error; 1626 1627 error = decode_nfsstat3(xdr, &status); 1628 if (unlikely(error)) 1629 goto out; 1630 error = decode_post_op_attr(xdr, result->fattr); 1631 if (unlikely(error)) 1632 goto out; 1633 if (status != NFS3_OK) 1634 goto out_status; 1635 error = decode_read3resok(xdr, result); 1636out: 1637 return error; 1638out_status: 1639 return nfs_stat_to_errno(status); 1640} 1641 1642/* 1643 * 3.3.7 WRITE3res 1644 * 1645 * enum stable_how { 1646 * UNSTABLE = 0, 1647 * DATA_SYNC = 1, 1648 * FILE_SYNC = 2 1649 * }; 1650 * 1651 * struct WRITE3resok { 1652 * wcc_data file_wcc; 1653 * count3 count; 1654 * stable_how committed; 1655 * writeverf3 verf; 1656 * }; 1657 * 1658 * struct WRITE3resfail { 1659 * wcc_data file_wcc; 1660 * }; 1661 * 1662 * union WRITE3res switch (nfsstat3 status) { 1663 * case NFS3_OK: 1664 * WRITE3resok resok; 1665 * default: 1666 * WRITE3resfail resfail; 1667 * }; 1668 */ 1669static int decode_write3resok(struct xdr_stream *xdr, 1670 struct nfs_writeres *result) 1671{ 1672 __be32 *p; 1673 1674 p = xdr_inline_decode(xdr, 4 + 4 + NFS3_WRITEVERFSIZE); 1675 if (unlikely(p == NULL)) 1676 goto out_overflow; 1677 result->count = be32_to_cpup(p++); 1678 result->verf->committed = be32_to_cpup(p++); 1679 if (unlikely(result->verf->committed > NFS_FILE_SYNC)) 1680 goto out_badvalue; 1681 memcpy(result->verf->verifier, p, NFS3_WRITEVERFSIZE); 1682 return result->count; 1683out_badvalue: 1684 dprintk("NFS: bad stable_how value: %u\n", result->verf->committed); 1685 return -EIO; 1686out_overflow: 1687 print_overflow_msg(__func__, xdr); 1688 return -EIO; 1689} 1690 1691static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr, 1692 struct nfs_writeres *result) 1693{ 1694 enum nfs_stat status; 1695 int error; 1696 1697 error = decode_nfsstat3(xdr, &status); 1698 if (unlikely(error)) 1699 goto out; 1700 error = decode_wcc_data(xdr, result->fattr); 1701 if (unlikely(error)) 1702 goto out; 1703 if (status != NFS3_OK) 1704 goto out_status; 1705 error = decode_write3resok(xdr, result); 1706out: 1707 return error; 1708out_status: 1709 return nfs_stat_to_errno(status); 1710} 1711 1712/* 1713 * 3.3.8 CREATE3res 1714 * 1715 * struct CREATE3resok { 1716 * post_op_fh3 obj; 1717 * post_op_attr obj_attributes; 1718 * wcc_data dir_wcc; 1719 * }; 1720 * 1721 * struct CREATE3resfail { 1722 * wcc_data dir_wcc; 1723 * }; 1724 * 1725 * union CREATE3res switch (nfsstat3 status) { 1726 * case NFS3_OK: 1727 * CREATE3resok resok; 1728 * default: 1729 * CREATE3resfail resfail; 1730 * }; 1731 */ 1732static int decode_create3resok(struct xdr_stream *xdr, 1733 struct nfs3_diropres *result) 1734{ 1735 int error; 1736 1737 error = decode_post_op_fh3(xdr, result->fh); 1738 if (unlikely(error)) 1739 goto out; 1740 error = decode_post_op_attr(xdr, result->fattr); 1741 if (unlikely(error)) 1742 goto out; 1743 /* The server isn't required to return a file handle. 1744 * If it didn't, force the client to perform a LOOKUP 1745 * to determine the correct file handle and attribute 1746 * values for the new object. */ 1747 if (result->fh->size == 0) 1748 result->fattr->valid = 0; 1749 error = decode_wcc_data(xdr, result->dir_attr); 1750out: 1751 return error; 1752} 1753 1754static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, 1755 struct xdr_stream *xdr, 1756 struct nfs3_diropres *result) 1757{ 1758 enum nfs_stat status; 1759 int error; 1760 1761 error = decode_nfsstat3(xdr, &status); 1762 if (unlikely(error)) 1763 goto out; 1764 if (status != NFS3_OK) 1765 goto out_default; 1766 error = decode_create3resok(xdr, result); 1767out: 1768 return error; 1769out_default: 1770 error = decode_wcc_data(xdr, result->dir_attr); 1771 if (unlikely(error)) 1772 goto out; 1773 return nfs_stat_to_errno(status); 1774} 1775 1776/* 1777 * 3.3.12 REMOVE3res 1778 * 1779 * struct REMOVE3resok { 1780 * wcc_data dir_wcc; 1781 * }; 1782 * 1783 * struct REMOVE3resfail { 1784 * wcc_data dir_wcc; 1785 * }; 1786 * 1787 * union REMOVE3res switch (nfsstat3 status) { 1788 * case NFS3_OK: 1789 * REMOVE3resok resok; 1790 * default: 1791 * REMOVE3resfail resfail; 1792 * }; 1793 */ 1794static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, 1795 struct xdr_stream *xdr, 1796 struct nfs_removeres *result) 1797{ 1798 enum nfs_stat status; 1799 int error; 1800 1801 error = decode_nfsstat3(xdr, &status); 1802 if (unlikely(error)) 1803 goto out; 1804 error = decode_wcc_data(xdr, result->dir_attr); 1805 if (unlikely(error)) 1806 goto out; 1807 if (status != NFS3_OK) 1808 goto out_status; 1809out: 1810 return error; 1811out_status: 1812 return nfs_stat_to_errno(status); 1813} 1814 1815/* 1816 * 3.3.14 RENAME3res 1817 * 1818 * struct RENAME3resok { 1819 * wcc_data fromdir_wcc; 1820 * wcc_data todir_wcc; 1821 * }; 1822 * 1823 * struct RENAME3resfail { 1824 * wcc_data fromdir_wcc; 1825 * wcc_data todir_wcc; 1826 * }; 1827 * 1828 * union RENAME3res switch (nfsstat3 status) { 1829 * case NFS3_OK: 1830 * RENAME3resok resok; 1831 * default: 1832 * RENAME3resfail resfail; 1833 * }; 1834 */ 1835static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, 1836 struct xdr_stream *xdr, 1837 struct nfs_renameres *result) 1838{ 1839 enum nfs_stat status; 1840 int error; 1841 1842 error = decode_nfsstat3(xdr, &status); 1843 if (unlikely(error)) 1844 goto out; 1845 error = decode_wcc_data(xdr, result->old_fattr); 1846 if (unlikely(error)) 1847 goto out; 1848 error = decode_wcc_data(xdr, result->new_fattr); 1849 if (unlikely(error)) 1850 goto out; 1851 if (status != NFS3_OK) 1852 goto out_status; 1853out: 1854 return error; 1855out_status: 1856 return nfs_stat_to_errno(status); 1857} 1858 1859/* 1860 * 3.3.15 LINK3res 1861 * 1862 * struct LINK3resok { 1863 * post_op_attr file_attributes; 1864 * wcc_data linkdir_wcc; 1865 * }; 1866 * 1867 * struct LINK3resfail { 1868 * post_op_attr file_attributes; 1869 * wcc_data linkdir_wcc; 1870 * }; 1871 * 1872 * union LINK3res switch (nfsstat3 status) { 1873 * case NFS3_OK: 1874 * LINK3resok resok; 1875 * default: 1876 * LINK3resfail resfail; 1877 * }; 1878 */ 1879static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr, 1880 struct nfs3_linkres *result) 1881{ 1882 enum nfs_stat status; 1883 int error; 1884 1885 error = decode_nfsstat3(xdr, &status); 1886 if (unlikely(error)) 1887 goto out; 1888 error = decode_post_op_attr(xdr, result->fattr); 1889 if (unlikely(error)) 1890 goto out; 1891 error = decode_wcc_data(xdr, result->dir_attr); 1892 if (unlikely(error)) 1893 goto out; 1894 if (status != NFS3_OK) 1895 goto out_status; 1896out: 1897 return error; 1898out_status: 1899 return nfs_stat_to_errno(status); 1900} 1901 1902/** 1903 * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in 1904 * the local page cache 1905 * @xdr: XDR stream where entry resides 1906 * @entry: buffer to fill in with entry data 1907 * @plus: boolean indicating whether this should be a readdirplus entry 1908 * 1909 * Returns zero if successful, otherwise a negative errno value is 1910 * returned. 1911 * 1912 * This function is not invoked during READDIR reply decoding, but 1913 * rather whenever an application invokes the getdents(2) system call 1914 * on a directory already in our cache. 1915 * 1916 * 3.3.16 entry3 1917 * 1918 * struct entry3 { 1919 * fileid3 fileid; 1920 * filename3 name; 1921 * cookie3 cookie; 1922 * fhandle3 filehandle; 1923 * post_op_attr3 attributes; 1924 * entry3 *nextentry; 1925 * }; 1926 * 1927 * 3.3.17 entryplus3 1928 * struct entryplus3 { 1929 * fileid3 fileid; 1930 * filename3 name; 1931 * cookie3 cookie; 1932 * post_op_attr name_attributes; 1933 * post_op_fh3 name_handle; 1934 * entryplus3 *nextentry; 1935 * }; 1936 */ 1937int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, 1938 int plus) 1939{ 1940 struct nfs_entry old = *entry; 1941 __be32 *p; 1942 int error; 1943 1944 p = xdr_inline_decode(xdr, 4); 1945 if (unlikely(p == NULL)) 1946 goto out_overflow; 1947 if (*p == xdr_zero) { 1948 p = xdr_inline_decode(xdr, 4); 1949 if (unlikely(p == NULL)) 1950 goto out_overflow; 1951 if (*p == xdr_zero) 1952 return -EAGAIN; 1953 entry->eof = 1; 1954 return -EBADCOOKIE; 1955 } 1956 1957 error = decode_fileid3(xdr, &entry->ino); 1958 if (unlikely(error)) 1959 return error; 1960 1961 error = decode_inline_filename3(xdr, &entry->name, &entry->len); 1962 if (unlikely(error)) 1963 return error; 1964 1965 entry->prev_cookie = entry->cookie; 1966 error = decode_cookie3(xdr, &entry->cookie); 1967 if (unlikely(error)) 1968 return error; 1969 1970 entry->d_type = DT_UNKNOWN; 1971 1972 if (plus) { 1973 entry->fattr->valid = 0; 1974 error = decode_post_op_attr(xdr, entry->fattr); 1975 if (unlikely(error)) 1976 return error; 1977 if (entry->fattr->valid & NFS_ATTR_FATTR_V3) 1978 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); 1979 1980 /* In fact, a post_op_fh3: */ 1981 p = xdr_inline_decode(xdr, 4); 1982 if (unlikely(p == NULL)) 1983 goto out_overflow; 1984 if (*p != xdr_zero) { 1985 error = decode_nfs_fh3(xdr, entry->fh); 1986 if (unlikely(error)) { 1987 if (error == -E2BIG) 1988 goto out_truncated; 1989 return error; 1990 } 1991 } else 1992 zero_nfs_fh3(entry->fh); 1993 } 1994 1995 return 0; 1996 1997out_overflow: 1998 print_overflow_msg(__func__, xdr); 1999 return -EAGAIN; 2000out_truncated: 2001 dprintk("NFS: directory entry contains invalid file handle\n"); 2002 *entry = old; 2003 return -EAGAIN; 2004} 2005 2006/* 2007 * 3.3.16 READDIR3res 2008 * 2009 * struct dirlist3 { 2010 * entry3 *entries; 2011 * bool eof; 2012 * }; 2013 * 2014 * struct READDIR3resok { 2015 * post_op_attr dir_attributes; 2016 * cookieverf3 cookieverf; 2017 * dirlist3 reply; 2018 * }; 2019 * 2020 * struct READDIR3resfail { 2021 * post_op_attr dir_attributes; 2022 * }; 2023 * 2024 * union READDIR3res switch (nfsstat3 status) { 2025 * case NFS3_OK: 2026 * READDIR3resok resok; 2027 * default: 2028 * READDIR3resfail resfail; 2029 * }; 2030 * 2031 * Read the directory contents into the page cache, but otherwise 2032 * don't touch them. The actual decoding is done by nfs3_decode_entry() 2033 * during subsequent nfs_readdir() calls. 2034 */ 2035static int decode_dirlist3(struct xdr_stream *xdr) 2036{ 2037 u32 recvd, pglen; 2038 size_t hdrlen; 2039 2040 pglen = xdr->buf->page_len; 2041 hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; 2042 recvd = xdr->buf->len - hdrlen; 2043 if (unlikely(pglen > recvd)) 2044 goto out_cheating; 2045out: 2046 xdr_read_pages(xdr, pglen); 2047 return pglen; 2048out_cheating: 2049 dprintk("NFS: server cheating in readdir result: " 2050 "pglen %u > recvd %u\n", pglen, recvd); 2051 pglen = recvd; 2052 goto out; 2053} 2054 2055static int decode_readdir3resok(struct xdr_stream *xdr, 2056 struct nfs3_readdirres *result) 2057{ 2058 int error; 2059 2060 error = decode_post_op_attr(xdr, result->dir_attr); 2061 if (unlikely(error)) 2062 goto out; 2063 /* XXX: do we need to check if result->verf != NULL ? */ 2064 error = decode_cookieverf3(xdr, result->verf); 2065 if (unlikely(error)) 2066 goto out; 2067 error = decode_dirlist3(xdr); 2068out: 2069 return error; 2070} 2071 2072static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, 2073 struct xdr_stream *xdr, 2074 struct nfs3_readdirres *result) 2075{ 2076 enum nfs_stat status; 2077 int error; 2078 2079 error = decode_nfsstat3(xdr, &status); 2080 if (unlikely(error)) 2081 goto out; 2082 if (status != NFS3_OK) 2083 goto out_default; 2084 error = decode_readdir3resok(xdr, result); 2085out: 2086 return error; 2087out_default: 2088 error = decode_post_op_attr(xdr, result->dir_attr); 2089 if (unlikely(error)) 2090 goto out; 2091 return nfs_stat_to_errno(status); 2092} 2093 2094/* 2095 * 3.3.18 FSSTAT3res 2096 * 2097 * struct FSSTAT3resok { 2098 * post_op_attr obj_attributes; 2099 * size3 tbytes; 2100 * size3 fbytes; 2101 * size3 abytes; 2102 * size3 tfiles; 2103 * size3 ffiles; 2104 * size3 afiles; 2105 * uint32 invarsec; 2106 * }; 2107 * 2108 * struct FSSTAT3resfail { 2109 * post_op_attr obj_attributes; 2110 * }; 2111 * 2112 * union FSSTAT3res switch (nfsstat3 status) { 2113 * case NFS3_OK: 2114 * FSSTAT3resok resok; 2115 * default: 2116 * FSSTAT3resfail resfail; 2117 * }; 2118 */ 2119static int decode_fsstat3resok(struct xdr_stream *xdr, 2120 struct nfs_fsstat *result) 2121{ 2122 __be32 *p; 2123 2124 p = xdr_inline_decode(xdr, 8 * 6 + 4); 2125 if (unlikely(p == NULL)) 2126 goto out_overflow; 2127 p = xdr_decode_size3(p, &result->tbytes); 2128 p = xdr_decode_size3(p, &result->fbytes); 2129 p = xdr_decode_size3(p, &result->abytes); 2130 p = xdr_decode_size3(p, &result->tfiles); 2131 p = xdr_decode_size3(p, &result->ffiles); 2132 xdr_decode_size3(p, &result->afiles); 2133 /* ignore invarsec */ 2134 return 0; 2135out_overflow: 2136 print_overflow_msg(__func__, xdr); 2137 return -EIO; 2138} 2139 2140static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, 2141 struct xdr_stream *xdr, 2142 struct nfs_fsstat *result) 2143{ 2144 enum nfs_stat status; 2145 int error; 2146 2147 error = decode_nfsstat3(xdr, &status); 2148 if (unlikely(error)) 2149 goto out; 2150 error = decode_post_op_attr(xdr, result->fattr); 2151 if (unlikely(error)) 2152 goto out; 2153 if (status != NFS3_OK) 2154 goto out_status; 2155 error = decode_fsstat3resok(xdr, result); 2156out: 2157 return error; 2158out_status: 2159 return nfs_stat_to_errno(status); 2160} 2161 2162/* 2163 * 3.3.19 FSINFO3res 2164 * 2165 * struct FSINFO3resok { 2166 * post_op_attr obj_attributes; 2167 * uint32 rtmax; 2168 * uint32 rtpref; 2169 * uint32 rtmult; 2170 * uint32 wtmax; 2171 * uint32 wtpref; 2172 * uint32 wtmult; 2173 * uint32 dtpref; 2174 * size3 maxfilesize; 2175 * nfstime3 time_delta; 2176 * uint32 properties; 2177 * }; 2178 * 2179 * struct FSINFO3resfail { 2180 * post_op_attr obj_attributes; 2181 * }; 2182 * 2183 * union FSINFO3res switch (nfsstat3 status) { 2184 * case NFS3_OK: 2185 * FSINFO3resok resok; 2186 * default: 2187 * FSINFO3resfail resfail; 2188 * }; 2189 */ 2190static int decode_fsinfo3resok(struct xdr_stream *xdr, 2191 struct nfs_fsinfo *result) 2192{ 2193 __be32 *p; 2194 2195 p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4); 2196 if (unlikely(p == NULL)) 2197 goto out_overflow; 2198 result->rtmax = be32_to_cpup(p++); 2199 result->rtpref = be32_to_cpup(p++); 2200 result->rtmult = be32_to_cpup(p++); 2201 result->wtmax = be32_to_cpup(p++); 2202 result->wtpref = be32_to_cpup(p++); 2203 result->wtmult = be32_to_cpup(p++); 2204 result->dtpref = be32_to_cpup(p++); 2205 p = xdr_decode_size3(p, &result->maxfilesize); 2206 xdr_decode_nfstime3(p, &result->time_delta); 2207 2208 /* ignore properties */ 2209 result->lease_time = 0; 2210 return 0; 2211out_overflow: 2212 print_overflow_msg(__func__, xdr); 2213 return -EIO; 2214} 2215 2216static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, 2217 struct xdr_stream *xdr, 2218 struct nfs_fsinfo *result) 2219{ 2220 enum nfs_stat status; 2221 int error; 2222 2223 error = decode_nfsstat3(xdr, &status); 2224 if (unlikely(error)) 2225 goto out; 2226 error = decode_post_op_attr(xdr, result->fattr); 2227 if (unlikely(error)) 2228 goto out; 2229 if (status != NFS3_OK) 2230 goto out_status; 2231 error = decode_fsinfo3resok(xdr, result); 2232out: 2233 return error; 2234out_status: 2235 return nfs_stat_to_errno(status); 2236} 2237 2238/* 2239 * 3.3.20 PATHCONF3res 2240 * 2241 * struct PATHCONF3resok { 2242 * post_op_attr obj_attributes; 2243 * uint32 linkmax; 2244 * uint32 name_max; 2245 * bool no_trunc; 2246 * bool chown_restricted; 2247 * bool case_insensitive; 2248 * bool case_preserving; 2249 * }; 2250 * 2251 * struct PATHCONF3resfail { 2252 * post_op_attr obj_attributes; 2253 * }; 2254 * 2255 * union PATHCONF3res switch (nfsstat3 status) { 2256 * case NFS3_OK: 2257 * PATHCONF3resok resok; 2258 * default: 2259 * PATHCONF3resfail resfail; 2260 * }; 2261 */ 2262static int decode_pathconf3resok(struct xdr_stream *xdr, 2263 struct nfs_pathconf *result) 2264{ 2265 __be32 *p; 2266 2267 p = xdr_inline_decode(xdr, 4 * 6); 2268 if (unlikely(p == NULL)) 2269 goto out_overflow; 2270 result->max_link = be32_to_cpup(p++); 2271 result->max_namelen = be32_to_cpup(p); 2272 /* ignore remaining fields */ 2273 return 0; 2274out_overflow: 2275 print_overflow_msg(__func__, xdr); 2276 return -EIO; 2277} 2278 2279static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, 2280 struct xdr_stream *xdr, 2281 struct nfs_pathconf *result) 2282{ 2283 enum nfs_stat status; 2284 int error; 2285 2286 error = decode_nfsstat3(xdr, &status); 2287 if (unlikely(error)) 2288 goto out; 2289 error = decode_post_op_attr(xdr, result->fattr); 2290 if (unlikely(error)) 2291 goto out; 2292 if (status != NFS3_OK) 2293 goto out_status; 2294 error = decode_pathconf3resok(xdr, result); 2295out: 2296 return error; 2297out_status: 2298 return nfs_stat_to_errno(status); 2299} 2300 2301/* 2302 * 3.3.21 COMMIT3res 2303 * 2304 * struct COMMIT3resok { 2305 * wcc_data file_wcc; 2306 * writeverf3 verf; 2307 * }; 2308 * 2309 * struct COMMIT3resfail { 2310 * wcc_data file_wcc; 2311 * }; 2312 * 2313 * union COMMIT3res switch (nfsstat3 status) { 2314 * case NFS3_OK: 2315 * COMMIT3resok resok; 2316 * default: 2317 * COMMIT3resfail resfail; 2318 * }; 2319 */ 2320static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, 2321 struct xdr_stream *xdr, 2322 struct nfs_writeres *result) 2323{ 2324 enum nfs_stat status; 2325 int error; 2326 2327 error = decode_nfsstat3(xdr, &status); 2328 if (unlikely(error)) 2329 goto out; 2330 error = decode_wcc_data(xdr, result->fattr); 2331 if (unlikely(error)) 2332 goto out; 2333 if (status != NFS3_OK) 2334 goto out_status; 2335 error = decode_writeverf3(xdr, result->verf->verif…
Large files files are truncated, but you can click here to view the full file