1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * XDR support for nfsd/protocol version 3. 4 * 5 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> 6 * 7 * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()! 8 */ 9 10 #include <linux/namei.h> 11 #include <linux/nfs3.h> 12 #include <linux/sunrpc/svc_xprt.h> 13 14 #include "nfsd.h" 15 #include "xdr3.h" 16 #include "auth.h" 17 #include "netns.h" 18 #include "vfs.h" 19 #include "nfserr.h" 20 21 /* 22 * Force construction of an empty post-op attr 23 */ 24 static const struct svc_fh nfs3svc_null_fh = { 25 .fh_no_wcc = true, 26 }; 27 28 /* 29 * time_delta. {1, 0} means the server is accurate only 30 * to the nearest second. 31 */ 32 static const struct timespec64 nfs3svc_time_delta = { 33 .tv_sec = 1, 34 .tv_nsec = 0, 35 }; 36 37 /* 38 * Mapping of S_IF* types to NFS file types 39 */ 40 static const u32 nfs3_ftypes[] = { 41 NF3NON, NF3FIFO, NF3CHR, NF3BAD, 42 NF3DIR, NF3BAD, NF3BLK, NF3BAD, 43 NF3REG, NF3BAD, NF3LNK, NF3BAD, 44 NF3SOCK, NF3BAD, NF3LNK, NF3BAD, 45 }; 46 47 48 /* 49 * Basic NFSv3 data types (RFC 1813 Sections 2.5 and 2.6) 50 */ 51 52 static __be32 * 53 encode_nfstime3(__be32 *p, const struct timespec64 *time) 54 { 55 *p++ = cpu_to_be32((u32)time->tv_sec); 56 *p++ = cpu_to_be32(time->tv_nsec); 57 58 return p; 59 } 60 61 static bool 62 svcxdr_decode_nfstime3(struct xdr_stream *xdr, struct timespec64 *timep) 63 { 64 __be32 *p; 65 66 p = xdr_inline_decode(xdr, XDR_UNIT * 2); 67 if (!p) 68 return false; 69 timep->tv_sec = be32_to_cpup(p++); 70 timep->tv_nsec = be32_to_cpup(p); 71 72 return true; 73 } 74 75 /** 76 * svcxdr_decode_nfs_fh3 - Decode an NFSv3 file handle 77 * @xdr: XDR stream positioned at an undecoded NFSv3 FH 78 * @fhp: OUT: filled-in server file handle 79 * 80 * Return values: 81 * %false: The encoded file handle was not valid 82 * %true: @fhp has been initialized 83 */ 84 bool 85 svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp) 86 { 87 __be32 *p; 88 u32 size; 89 90 if (xdr_stream_decode_u32(xdr, &size) < 0) 91 return false; 92 if (size == 0 || size > NFS3_FHSIZE) 93 return false; 94 p = xdr_inline_decode(xdr, size); 95 if (!p) 96 return false; 97 fh_init(fhp, NFS3_FHSIZE); 98 fhp->fh_handle.fh_size = size; 99 memcpy(&fhp->fh_handle.fh_raw, p, size); 100 101 return true; 102 } 103 104 /** 105 * svcxdr_encode_nfsstat3 - Encode an NFSv3 status code 106 * @xdr: XDR stream 107 * @status: status value to encode 108 * 109 * Return values: 110 * %false: Send buffer space was exhausted 111 * %true: Success 112 */ 113 bool 114 svcxdr_encode_nfsstat3(struct xdr_stream *xdr, __be32 status) 115 { 116 __be32 *p; 117 118 p = xdr_reserve_space(xdr, sizeof(status)); 119 if (!p) 120 return false; 121 *p = status; 122 123 return true; 124 } 125 126 static bool 127 svcxdr_encode_nfs_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp) 128 { 129 u32 size = fhp->fh_handle.fh_size; 130 __be32 *p; 131 132 p = xdr_reserve_space(xdr, XDR_UNIT + size); 133 if (!p) 134 return false; 135 *p++ = cpu_to_be32(size); 136 if (size) 137 p[XDR_QUADLEN(size) - 1] = 0; 138 memcpy(p, &fhp->fh_handle.fh_raw, size); 139 140 return true; 141 } 142 143 static bool 144 svcxdr_encode_post_op_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp) 145 { 146 if (xdr_stream_encode_item_present(xdr) < 0) 147 return false; 148 if (!svcxdr_encode_nfs_fh3(xdr, fhp)) 149 return false; 150 151 return true; 152 } 153 154 static bool 155 svcxdr_encode_cookieverf3(struct xdr_stream *xdr, const __be32 *verf) 156 { 157 __be32 *p; 158 159 p = xdr_reserve_space(xdr, NFS3_COOKIEVERFSIZE); 160 if (!p) 161 return false; 162 memcpy(p, verf, NFS3_COOKIEVERFSIZE); 163 164 return true; 165 } 166 167 static bool 168 svcxdr_encode_writeverf3(struct xdr_stream *xdr, const __be32 *verf) 169 { 170 __be32 *p; 171 172 p = xdr_reserve_space(xdr, NFS3_WRITEVERFSIZE); 173 if (!p) 174 return false; 175 memcpy(p, verf, NFS3_WRITEVERFSIZE); 176 177 return true; 178 } 179 180 static bool 181 svcxdr_decode_filename3(struct xdr_stream *xdr, char **name, unsigned int *len) 182 { 183 u32 size, i; 184 __be32 *p; 185 char *c; 186 187 if (xdr_stream_decode_u32(xdr, &size) < 0) 188 return false; 189 if (size == 0 || size > NFS3_MAXNAMLEN) 190 return false; 191 p = xdr_inline_decode(xdr, size); 192 if (!p) 193 return false; 194 195 *len = size; 196 *name = (char *)p; 197 for (i = 0, c = *name; i < size; i++, c++) { 198 if (*c == '\0' || *c == '/') 199 return false; 200 } 201 202 return true; 203 } 204 205 static bool 206 svcxdr_decode_diropargs3(struct xdr_stream *xdr, struct svc_fh *fhp, 207 char **name, unsigned int *len) 208 { 209 return svcxdr_decode_nfs_fh3(xdr, fhp) && 210 svcxdr_decode_filename3(xdr, name, len); 211 } 212 213 static bool 214 svcxdr_decode_sattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr, 215 struct iattr *iap) 216 { 217 u32 set_it; 218 219 iap->ia_valid = 0; 220 221 if (xdr_stream_decode_bool(xdr, &set_it) < 0) 222 return false; 223 if (set_it) { 224 u32 mode; 225 226 if (xdr_stream_decode_u32(xdr, &mode) < 0) 227 return false; 228 iap->ia_valid |= ATTR_MODE; 229 iap->ia_mode = mode; 230 } 231 if (xdr_stream_decode_bool(xdr, &set_it) < 0) 232 return false; 233 if (set_it) { 234 u32 uid; 235 236 if (xdr_stream_decode_u32(xdr, &uid) < 0) 237 return false; 238 iap->ia_uid = make_kuid(nfsd_user_namespace(rqstp), uid); 239 if (uid_valid(iap->ia_uid)) 240 iap->ia_valid |= ATTR_UID; 241 } 242 if (xdr_stream_decode_bool(xdr, &set_it) < 0) 243 return false; 244 if (set_it) { 245 u32 gid; 246 247 if (xdr_stream_decode_u32(xdr, &gid) < 0) 248 return false; 249 iap->ia_gid = make_kgid(nfsd_user_namespace(rqstp), gid); 250 if (gid_valid(iap->ia_gid)) 251 iap->ia_valid |= ATTR_GID; 252 } 253 if (xdr_stream_decode_bool(xdr, &set_it) < 0) 254 return false; 255 if (set_it) { 256 u64 newsize; 257 258 if (xdr_stream_decode_u64(xdr, &newsize) < 0) 259 return false; 260 iap->ia_valid |= ATTR_SIZE; 261 iap->ia_size = newsize; 262 } 263 if (xdr_stream_decode_u32(xdr, &set_it) < 0) 264 return false; 265 switch (set_it) { 266 case DONT_CHANGE: 267 break; 268 case SET_TO_SERVER_TIME: 269 iap->ia_valid |= ATTR_ATIME; 270 break; 271 case SET_TO_CLIENT_TIME: 272 if (!svcxdr_decode_nfstime3(xdr, &iap->ia_atime)) 273 return false; 274 iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET; 275 break; 276 default: 277 return false; 278 } 279 if (xdr_stream_decode_u32(xdr, &set_it) < 0) 280 return false; 281 switch (set_it) { 282 case DONT_CHANGE: 283 break; 284 case SET_TO_SERVER_TIME: 285 iap->ia_valid |= ATTR_MTIME; 286 break; 287 case SET_TO_CLIENT_TIME: 288 if (!svcxdr_decode_nfstime3(xdr, &iap->ia_mtime)) 289 return false; 290 iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET; 291 break; 292 default: 293 return false; 294 } 295 296 return true; 297 } 298 299 static bool 300 svcxdr_decode_sattrguard3(struct xdr_stream *xdr, struct nfsd3_sattrargs *args) 301 { 302 u32 check; 303 304 if (xdr_stream_decode_bool(xdr, &check) < 0) 305 return false; 306 if (check) { 307 if (!svcxdr_decode_nfstime3(xdr, &args->guardtime)) 308 return false; 309 args->check_guard = 1; 310 } else 311 args->check_guard = 0; 312 313 return true; 314 } 315 316 static bool 317 svcxdr_decode_specdata3(struct xdr_stream *xdr, struct nfsd3_mknodargs *args) 318 { 319 __be32 *p; 320 321 p = xdr_inline_decode(xdr, XDR_UNIT * 2); 322 if (!p) 323 return false; 324 args->major = be32_to_cpup(p++); 325 args->minor = be32_to_cpup(p); 326 327 return true; 328 } 329 330 static bool 331 svcxdr_decode_devicedata3(struct svc_rqst *rqstp, struct xdr_stream *xdr, 332 struct nfsd3_mknodargs *args) 333 { 334 return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) && 335 svcxdr_decode_specdata3(xdr, args); 336 } 337 338 static bool 339 svcxdr_encode_fattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr, 340 const struct svc_fh *fhp, const struct kstat *stat) 341 { 342 struct user_namespace *userns = nfsd_user_namespace(rqstp); 343 __be32 *p; 344 u64 fsid; 345 346 p = xdr_reserve_space(xdr, XDR_UNIT * 21); 347 if (!p) 348 return false; 349 350 *p++ = cpu_to_be32(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); 351 *p++ = cpu_to_be32((u32)(stat->mode & S_IALLUGO)); 352 *p++ = cpu_to_be32((u32)stat->nlink); 353 *p++ = cpu_to_be32((u32)from_kuid_munged(userns, stat->uid)); 354 *p++ = cpu_to_be32((u32)from_kgid_munged(userns, stat->gid)); 355 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) 356 p = xdr_encode_hyper(p, (u64)NFS3_MAXPATHLEN); 357 else 358 p = xdr_encode_hyper(p, (u64)stat->size); 359 360 /* used */ 361 p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9); 362 363 /* rdev */ 364 *p++ = cpu_to_be32((u32)MAJOR(stat->rdev)); 365 *p++ = cpu_to_be32((u32)MINOR(stat->rdev)); 366 367 switch(fsid_source(fhp)) { 368 case FSIDSOURCE_FSID: 369 fsid = (u64)fhp->fh_export->ex_fsid; 370 break; 371 case FSIDSOURCE_UUID: 372 fsid = ((u64 *)fhp->fh_export->ex_uuid)[0]; 373 fsid ^= ((u64 *)fhp->fh_export->ex_uuid)[1]; 374 break; 375 default: 376 fsid = (u64)huge_encode_dev(fhp->fh_dentry->d_sb->s_dev); 377 } 378 p = xdr_encode_hyper(p, fsid); 379 380 /* fileid */ 381 p = xdr_encode_hyper(p, stat->ino); 382 383 p = encode_nfstime3(p, &stat->atime); 384 p = encode_nfstime3(p, &stat->mtime); 385 encode_nfstime3(p, &stat->ctime); 386 387 return true; 388 } 389 390 static bool 391 svcxdr_encode_wcc_attr(struct xdr_stream *xdr, const struct svc_fh *fhp) 392 { 393 __be32 *p; 394 395 p = xdr_reserve_space(xdr, XDR_UNIT * 6); 396 if (!p) 397 return false; 398 p = xdr_encode_hyper(p, (u64)fhp->fh_pre_size); 399 p = encode_nfstime3(p, &fhp->fh_pre_mtime); 400 encode_nfstime3(p, &fhp->fh_pre_ctime); 401 402 return true; 403 } 404 405 static bool 406 svcxdr_encode_pre_op_attr(struct xdr_stream *xdr, const struct svc_fh *fhp) 407 { 408 if (!fhp->fh_pre_saved) { 409 if (xdr_stream_encode_item_absent(xdr) < 0) 410 return false; 411 return true; 412 } 413 414 if (xdr_stream_encode_item_present(xdr) < 0) 415 return false; 416 return svcxdr_encode_wcc_attr(xdr, fhp); 417 } 418 419 /** 420 * svcxdr_encode_post_op_attr - Encode NFSv3 post-op attributes 421 * @rqstp: Context of a completed RPC transaction 422 * @xdr: XDR stream 423 * @fhp: File handle to encode 424 * 425 * Return values: 426 * %false: Send buffer space was exhausted 427 * %true: Success 428 */ 429 bool 430 svcxdr_encode_post_op_attr(struct svc_rqst *rqstp, struct xdr_stream *xdr, 431 const struct svc_fh *fhp) 432 { 433 struct dentry *dentry = fhp->fh_dentry; 434 struct kstat stat; 435 436 /* 437 * The inode may be NULL if the call failed because of a 438 * stale file handle. In this case, no attributes are 439 * returned. 440 */ 441 if (fhp->fh_no_wcc || !dentry || !d_really_is_positive(dentry)) 442 goto no_post_op_attrs; 443 if (fh_getattr(fhp, &stat) != nfs_ok) 444 goto no_post_op_attrs; 445 446 if (xdr_stream_encode_item_present(xdr) < 0) 447 return false; 448 lease_get_mtime(d_inode(dentry), &stat.mtime); 449 if (!svcxdr_encode_fattr3(rqstp, xdr, fhp, &stat)) 450 return false; 451 452 return true; 453 454 no_post_op_attrs: 455 return xdr_stream_encode_item_absent(xdr) > 0; 456 } 457 458 /* 459 * Encode weak cache consistency data 460 */ 461 static bool 462 svcxdr_encode_wcc_data(struct svc_rqst *rqstp, struct xdr_stream *xdr, 463 const struct svc_fh *fhp) 464 { 465 struct dentry *dentry = fhp->fh_dentry; 466 467 if (!dentry || !d_really_is_positive(dentry) || !fhp->fh_post_saved) 468 goto neither; 469 470 /* before */ 471 if (!svcxdr_encode_pre_op_attr(xdr, fhp)) 472 return false; 473 474 /* after */ 475 if (xdr_stream_encode_item_present(xdr) < 0) 476 return false; 477 if (!svcxdr_encode_fattr3(rqstp, xdr, fhp, &fhp->fh_post_attr)) 478 return false; 479 480 return true; 481 482 neither: 483 if (xdr_stream_encode_item_absent(xdr) < 0) 484 return false; 485 if (!svcxdr_encode_post_op_attr(rqstp, xdr, fhp)) 486 return false; 487 488 return true; 489 } 490 491 /* 492 * XDR decode functions 493 */ 494 495 bool 496 nfs3svc_decode_fhandleargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 497 { 498 struct nfsd_fhandle *args = rqstp->rq_argp; 499 500 return svcxdr_decode_nfs_fh3(xdr, &args->fh); 501 } 502 503 bool 504 nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 505 { 506 struct nfsd3_sattrargs *args = rqstp->rq_argp; 507 508 return svcxdr_decode_nfs_fh3(xdr, &args->fh) && 509 svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) && 510 svcxdr_decode_sattrguard3(xdr, args); 511 } 512 513 bool 514 nfs3svc_decode_diropargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 515 { 516 struct nfsd3_diropargs *args = rqstp->rq_argp; 517 518 return svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len); 519 } 520 521 bool 522 nfs3svc_decode_accessargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 523 { 524 struct nfsd3_accessargs *args = rqstp->rq_argp; 525 526 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh)) 527 return false; 528 if (xdr_stream_decode_u32(xdr, &args->access) < 0) 529 return false; 530 531 return true; 532 } 533 534 bool 535 nfs3svc_decode_readargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 536 { 537 struct nfsd3_readargs *args = rqstp->rq_argp; 538 539 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh)) 540 return false; 541 if (xdr_stream_decode_u64(xdr, &args->offset) < 0) 542 return false; 543 if (xdr_stream_decode_u32(xdr, &args->count) < 0) 544 return false; 545 546 return true; 547 } 548 549 bool 550 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 551 { 552 struct nfsd3_writeargs *args = rqstp->rq_argp; 553 u32 max_blocksize = svc_max_payload(rqstp); 554 555 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh)) 556 return false; 557 if (xdr_stream_decode_u64(xdr, &args->offset) < 0) 558 return false; 559 if (xdr_stream_decode_u32(xdr, &args->count) < 0) 560 return false; 561 if (xdr_stream_decode_u32(xdr, &args->stable) < 0) 562 return false; 563 if (args->stable > NFS_FILE_SYNC) 564 return false; 565 566 /* opaque data */ 567 if (xdr_stream_decode_u32(xdr, &args->len) < 0) 568 return false; 569 570 /* request sanity */ 571 if (args->count != args->len) 572 return false; 573 if (args->count > max_blocksize) { 574 args->count = max_blocksize; 575 args->len = max_blocksize; 576 } 577 578 return xdr_stream_subsegment(xdr, &args->payload, args->count); 579 } 580 581 bool 582 nfs3svc_decode_createargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 583 { 584 struct nfsd3_createargs *args = rqstp->rq_argp; 585 586 if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len)) 587 return false; 588 if (xdr_stream_decode_u32(xdr, &args->createmode) < 0) 589 return false; 590 switch (args->createmode) { 591 case NFS3_CREATE_UNCHECKED: 592 case NFS3_CREATE_GUARDED: 593 return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs); 594 case NFS3_CREATE_EXCLUSIVE: 595 args->verf = xdr_inline_decode(xdr, NFS3_CREATEVERFSIZE); 596 if (!args->verf) 597 return false; 598 break; 599 default: 600 return false; 601 } 602 return true; 603 } 604 605 bool 606 nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 607 { 608 struct nfsd3_createargs *args = rqstp->rq_argp; 609 610 return svcxdr_decode_diropargs3(xdr, &args->fh, 611 &args->name, &args->len) && 612 svcxdr_decode_sattr3(rqstp, xdr, &args->attrs); 613 } 614 615 bool 616 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 617 { 618 struct nfsd3_symlinkargs *args = rqstp->rq_argp; 619 struct kvec *head = rqstp->rq_arg.head; 620 621 if (!svcxdr_decode_diropargs3(xdr, &args->ffh, &args->fname, &args->flen)) 622 return false; 623 if (!svcxdr_decode_sattr3(rqstp, xdr, &args->attrs)) 624 return false; 625 if (xdr_stream_decode_u32(xdr, &args->tlen) < 0) 626 return false; 627 628 /* symlink_data */ 629 args->first.iov_len = head->iov_len - xdr_stream_pos(xdr); 630 args->first.iov_base = xdr_inline_decode(xdr, args->tlen); 631 return args->first.iov_base != NULL; 632 } 633 634 bool 635 nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 636 { 637 struct nfsd3_mknodargs *args = rqstp->rq_argp; 638 639 if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len)) 640 return false; 641 if (xdr_stream_decode_u32(xdr, &args->ftype) < 0) 642 return false; 643 switch (args->ftype) { 644 case NF3CHR: 645 case NF3BLK: 646 return svcxdr_decode_devicedata3(rqstp, xdr, args); 647 case NF3SOCK: 648 case NF3FIFO: 649 return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs); 650 case NF3REG: 651 case NF3DIR: 652 case NF3LNK: 653 /* Valid XDR but illegal file types */ 654 break; 655 default: 656 return false; 657 } 658 659 return true; 660 } 661 662 bool 663 nfs3svc_decode_renameargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 664 { 665 struct nfsd3_renameargs *args = rqstp->rq_argp; 666 667 return svcxdr_decode_diropargs3(xdr, &args->ffh, 668 &args->fname, &args->flen) && 669 svcxdr_decode_diropargs3(xdr, &args->tfh, 670 &args->tname, &args->tlen); 671 } 672 673 bool 674 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 675 { 676 struct nfsd3_linkargs *args = rqstp->rq_argp; 677 678 return svcxdr_decode_nfs_fh3(xdr, &args->ffh) && 679 svcxdr_decode_diropargs3(xdr, &args->tfh, 680 &args->tname, &args->tlen); 681 } 682 683 bool 684 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 685 { 686 struct nfsd3_readdirargs *args = rqstp->rq_argp; 687 688 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh)) 689 return false; 690 if (xdr_stream_decode_u64(xdr, &args->cookie) < 0) 691 return false; 692 args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE); 693 if (!args->verf) 694 return false; 695 if (xdr_stream_decode_u32(xdr, &args->count) < 0) 696 return false; 697 698 return true; 699 } 700 701 bool 702 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 703 { 704 struct nfsd3_readdirargs *args = rqstp->rq_argp; 705 u32 dircount; 706 707 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh)) 708 return false; 709 if (xdr_stream_decode_u64(xdr, &args->cookie) < 0) 710 return false; 711 args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE); 712 if (!args->verf) 713 return false; 714 /* dircount is ignored */ 715 if (xdr_stream_decode_u32(xdr, &dircount) < 0) 716 return false; 717 if (xdr_stream_decode_u32(xdr, &args->count) < 0) 718 return false; 719 720 return true; 721 } 722 723 bool 724 nfs3svc_decode_commitargs(struct svc_rqst *rqstp, struct xdr_stream *xdr) 725 { 726 struct nfsd3_commitargs *args = rqstp->rq_argp; 727 728 if (!svcxdr_decode_nfs_fh3(xdr, &args->fh)) 729 return false; 730 if (xdr_stream_decode_u64(xdr, &args->offset) < 0) 731 return false; 732 if (xdr_stream_decode_u32(xdr, &args->count) < 0) 733 return false; 734 735 return true; 736 } 737 738 /* 739 * XDR encode functions 740 */ 741 742 /* GETATTR */ 743 bool 744 nfs3svc_encode_getattrres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 745 { 746 struct nfsd3_attrstat *resp = rqstp->rq_resp; 747 748 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 749 return false; 750 switch (resp->status) { 751 case nfs_ok: 752 lease_get_mtime(d_inode(resp->fh.fh_dentry), &resp->stat.mtime); 753 if (!svcxdr_encode_fattr3(rqstp, xdr, &resp->fh, &resp->stat)) 754 return false; 755 break; 756 } 757 758 return true; 759 } 760 761 /* SETATTR, REMOVE, RMDIR */ 762 bool 763 nfs3svc_encode_wccstat(struct svc_rqst *rqstp, struct xdr_stream *xdr) 764 { 765 struct nfsd3_attrstat *resp = rqstp->rq_resp; 766 767 return svcxdr_encode_nfsstat3(xdr, resp->status) && 768 svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh); 769 } 770 771 /* LOOKUP */ 772 bool 773 nfs3svc_encode_lookupres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 774 { 775 struct nfsd3_diropres *resp = rqstp->rq_resp; 776 777 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 778 return false; 779 switch (resp->status) { 780 case nfs_ok: 781 if (!svcxdr_encode_nfs_fh3(xdr, &resp->fh)) 782 return false; 783 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 784 return false; 785 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh)) 786 return false; 787 break; 788 default: 789 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh)) 790 return false; 791 } 792 793 return true; 794 } 795 796 /* ACCESS */ 797 bool 798 nfs3svc_encode_accessres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 799 { 800 struct nfsd3_accessres *resp = rqstp->rq_resp; 801 802 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 803 return false; 804 switch (resp->status) { 805 case nfs_ok: 806 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 807 return false; 808 if (xdr_stream_encode_u32(xdr, resp->access) < 0) 809 return false; 810 break; 811 default: 812 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 813 return false; 814 } 815 816 return true; 817 } 818 819 /* READLINK */ 820 bool 821 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 822 { 823 struct nfsd3_readlinkres *resp = rqstp->rq_resp; 824 struct kvec *head = rqstp->rq_res.head; 825 826 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 827 return false; 828 switch (resp->status) { 829 case nfs_ok: 830 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 831 return false; 832 if (xdr_stream_encode_u32(xdr, resp->len) < 0) 833 return false; 834 svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages, 0, 835 resp->len); 836 if (svc_encode_result_payload(rqstp, head->iov_len, resp->len) < 0) 837 return false; 838 break; 839 default: 840 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 841 return false; 842 } 843 844 return true; 845 } 846 847 /* READ */ 848 bool 849 nfs3svc_encode_readres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 850 { 851 struct nfsd3_readres *resp = rqstp->rq_resp; 852 struct kvec *head = rqstp->rq_res.head; 853 854 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 855 return false; 856 switch (resp->status) { 857 case nfs_ok: 858 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 859 return false; 860 if (xdr_stream_encode_u32(xdr, resp->count) < 0) 861 return false; 862 if (xdr_stream_encode_bool(xdr, resp->eof) < 0) 863 return false; 864 if (xdr_stream_encode_u32(xdr, resp->count) < 0) 865 return false; 866 svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages, 867 rqstp->rq_res.page_base, 868 resp->count); 869 if (svc_encode_result_payload(rqstp, head->iov_len, resp->count) < 0) 870 return false; 871 break; 872 default: 873 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 874 return false; 875 } 876 877 return true; 878 } 879 880 /* WRITE */ 881 bool 882 nfs3svc_encode_writeres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 883 { 884 struct nfsd3_writeres *resp = rqstp->rq_resp; 885 886 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 887 return false; 888 switch (resp->status) { 889 case nfs_ok: 890 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh)) 891 return false; 892 if (xdr_stream_encode_u32(xdr, resp->count) < 0) 893 return false; 894 if (xdr_stream_encode_u32(xdr, resp->committed) < 0) 895 return false; 896 if (!svcxdr_encode_writeverf3(xdr, resp->verf)) 897 return false; 898 break; 899 default: 900 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh)) 901 return false; 902 } 903 904 return true; 905 } 906 907 /* CREATE, MKDIR, SYMLINK, MKNOD */ 908 bool 909 nfs3svc_encode_createres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 910 { 911 struct nfsd3_diropres *resp = rqstp->rq_resp; 912 913 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 914 return false; 915 switch (resp->status) { 916 case nfs_ok: 917 if (!svcxdr_encode_post_op_fh3(xdr, &resp->fh)) 918 return false; 919 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 920 return false; 921 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->dirfh)) 922 return false; 923 break; 924 default: 925 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->dirfh)) 926 return false; 927 } 928 929 return true; 930 } 931 932 /* RENAME */ 933 bool 934 nfs3svc_encode_renameres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 935 { 936 struct nfsd3_renameres *resp = rqstp->rq_resp; 937 938 return svcxdr_encode_nfsstat3(xdr, resp->status) && 939 svcxdr_encode_wcc_data(rqstp, xdr, &resp->ffh) && 940 svcxdr_encode_wcc_data(rqstp, xdr, &resp->tfh); 941 } 942 943 /* LINK */ 944 bool 945 nfs3svc_encode_linkres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 946 { 947 struct nfsd3_linkres *resp = rqstp->rq_resp; 948 949 return svcxdr_encode_nfsstat3(xdr, resp->status) && 950 svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh) && 951 svcxdr_encode_wcc_data(rqstp, xdr, &resp->tfh); 952 } 953 954 /* READDIR */ 955 bool 956 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 957 { 958 struct nfsd3_readdirres *resp = rqstp->rq_resp; 959 struct xdr_buf *dirlist = &resp->dirlist; 960 961 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 962 return false; 963 switch (resp->status) { 964 case nfs_ok: 965 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 966 return false; 967 if (!svcxdr_encode_cookieverf3(xdr, resp->verf)) 968 return false; 969 svcxdr_encode_opaque_pages(rqstp, xdr, dirlist->pages, 0, 970 dirlist->len); 971 /* no more entries */ 972 if (xdr_stream_encode_item_absent(xdr) < 0) 973 return false; 974 if (xdr_stream_encode_bool(xdr, resp->common.err == nfserr_eof) < 0) 975 return false; 976 break; 977 default: 978 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh)) 979 return false; 980 } 981 982 return true; 983 } 984 985 static __be32 986 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, 987 const char *name, int namlen, u64 ino) 988 { 989 struct svc_export *exp; 990 struct dentry *dparent, *dchild; 991 __be32 rv = nfserr_noent; 992 993 dparent = cd->fh.fh_dentry; 994 exp = cd->fh.fh_export; 995 996 if (name_is_dot_dotdot(name, namlen)) { 997 if (namlen == 2) { 998 dchild = dget_parent(dparent); 999 /* 1000 * Don't return filehandle for ".." if we're at 1001 * the filesystem or export root: 1002 */ 1003 if (dchild == dparent) 1004 goto out; 1005 if (dparent == exp->ex_path.dentry) 1006 goto out; 1007 } else 1008 dchild = dget(dparent); 1009 } else 1010 dchild = lookup_one_positive_unlocked(&nop_mnt_idmap, 1011 &QSTR_LEN(name, namlen), 1012 dparent); 1013 if (IS_ERR(dchild)) 1014 return rv; 1015 if (d_mountpoint(dchild)) 1016 goto out; 1017 if (dchild->d_inode->i_ino != ino) 1018 goto out; 1019 rv = fh_compose(fhp, exp, dchild, &cd->fh); 1020 out: 1021 dput(dchild); 1022 return rv; 1023 } 1024 1025 /** 1026 * nfs3svc_encode_cookie3 - Encode a directory offset cookie 1027 * @resp: readdir result context 1028 * @offset: offset cookie to encode 1029 * 1030 * The buffer space for the offset cookie has already been reserved 1031 * by svcxdr_encode_entry3_common(). 1032 */ 1033 void nfs3svc_encode_cookie3(struct nfsd3_readdirres *resp, u64 offset) 1034 { 1035 __be64 cookie = cpu_to_be64(offset); 1036 1037 if (!resp->cookie_offset) 1038 return; 1039 write_bytes_to_xdr_buf(&resp->dirlist, resp->cookie_offset, &cookie, 1040 sizeof(cookie)); 1041 resp->cookie_offset = 0; 1042 } 1043 1044 static bool 1045 svcxdr_encode_entry3_common(struct nfsd3_readdirres *resp, const char *name, 1046 int namlen, loff_t offset, u64 ino) 1047 { 1048 struct xdr_buf *dirlist = &resp->dirlist; 1049 struct xdr_stream *xdr = &resp->xdr; 1050 1051 if (xdr_stream_encode_item_present(xdr) < 0) 1052 return false; 1053 /* fileid */ 1054 if (xdr_stream_encode_u64(xdr, ino) < 0) 1055 return false; 1056 /* name */ 1057 if (xdr_stream_encode_opaque(xdr, name, min(namlen, NFS3_MAXNAMLEN)) < 0) 1058 return false; 1059 /* cookie */ 1060 resp->cookie_offset = dirlist->len; 1061 if (xdr_stream_encode_u64(xdr, OFFSET_MAX) < 0) 1062 return false; 1063 1064 return true; 1065 } 1066 1067 /** 1068 * nfs3svc_encode_entry3 - encode one NFSv3 READDIR entry 1069 * @data: directory context 1070 * @name: name of the object to be encoded 1071 * @namlen: length of that name, in bytes 1072 * @offset: the offset of the previous entry 1073 * @ino: the fileid of this entry 1074 * @d_type: unused 1075 * 1076 * Return values: 1077 * %0: Entry was successfully encoded. 1078 * %-EINVAL: An encoding problem occurred, secondary status code in resp->common.err 1079 * 1080 * On exit, the following fields are updated: 1081 * - resp->xdr 1082 * - resp->common.err 1083 * - resp->cookie_offset 1084 */ 1085 int nfs3svc_encode_entry3(void *data, const char *name, int namlen, 1086 loff_t offset, u64 ino, unsigned int d_type) 1087 { 1088 struct readdir_cd *ccd = data; 1089 struct nfsd3_readdirres *resp = container_of(ccd, 1090 struct nfsd3_readdirres, 1091 common); 1092 unsigned int starting_length = resp->dirlist.len; 1093 1094 /* The offset cookie for the previous entry */ 1095 nfs3svc_encode_cookie3(resp, offset); 1096 1097 if (!svcxdr_encode_entry3_common(resp, name, namlen, offset, ino)) 1098 goto out_toosmall; 1099 1100 xdr_commit_encode(&resp->xdr); 1101 resp->common.err = nfs_ok; 1102 return 0; 1103 1104 out_toosmall: 1105 resp->cookie_offset = 0; 1106 resp->common.err = nfserr_toosmall; 1107 resp->dirlist.len = starting_length; 1108 return -EINVAL; 1109 } 1110 1111 static bool 1112 svcxdr_encode_entry3_plus(struct nfsd3_readdirres *resp, const char *name, 1113 int namlen, u64 ino) 1114 { 1115 struct xdr_stream *xdr = &resp->xdr; 1116 struct svc_fh *fhp = &resp->scratch; 1117 bool result; 1118 1119 result = false; 1120 fh_init(fhp, NFS3_FHSIZE); 1121 if (compose_entry_fh(resp, fhp, name, namlen, ino) != nfs_ok) 1122 goto out_noattrs; 1123 1124 if (!svcxdr_encode_post_op_attr(resp->rqstp, xdr, fhp)) 1125 goto out; 1126 if (!svcxdr_encode_post_op_fh3(xdr, fhp)) 1127 goto out; 1128 result = true; 1129 1130 out: 1131 fh_put(fhp); 1132 return result; 1133 1134 out_noattrs: 1135 if (xdr_stream_encode_item_absent(xdr) < 0) 1136 return false; 1137 if (xdr_stream_encode_item_absent(xdr) < 0) 1138 return false; 1139 return true; 1140 } 1141 1142 /** 1143 * nfs3svc_encode_entryplus3 - encode one NFSv3 READDIRPLUS entry 1144 * @data: directory context 1145 * @name: name of the object to be encoded 1146 * @namlen: length of that name, in bytes 1147 * @offset: the offset of the previous entry 1148 * @ino: the fileid of this entry 1149 * @d_type: unused 1150 * 1151 * Return values: 1152 * %0: Entry was successfully encoded. 1153 * %-EINVAL: An encoding problem occurred, secondary status code in resp->common.err 1154 * 1155 * On exit, the following fields are updated: 1156 * - resp->xdr 1157 * - resp->common.err 1158 * - resp->cookie_offset 1159 */ 1160 int nfs3svc_encode_entryplus3(void *data, const char *name, int namlen, 1161 loff_t offset, u64 ino, unsigned int d_type) 1162 { 1163 struct readdir_cd *ccd = data; 1164 struct nfsd3_readdirres *resp = container_of(ccd, 1165 struct nfsd3_readdirres, 1166 common); 1167 unsigned int starting_length = resp->dirlist.len; 1168 1169 /* The offset cookie for the previous entry */ 1170 nfs3svc_encode_cookie3(resp, offset); 1171 1172 if (!svcxdr_encode_entry3_common(resp, name, namlen, offset, ino)) 1173 goto out_toosmall; 1174 if (!svcxdr_encode_entry3_plus(resp, name, namlen, ino)) 1175 goto out_toosmall; 1176 1177 xdr_commit_encode(&resp->xdr); 1178 resp->common.err = nfs_ok; 1179 return 0; 1180 1181 out_toosmall: 1182 resp->cookie_offset = 0; 1183 resp->common.err = nfserr_toosmall; 1184 resp->dirlist.len = starting_length; 1185 return -EINVAL; 1186 } 1187 1188 static bool 1189 svcxdr_encode_fsstat3resok(struct xdr_stream *xdr, 1190 const struct nfsd3_fsstatres *resp) 1191 { 1192 const struct kstatfs *s = &resp->stats; 1193 u64 bs = s->f_bsize; 1194 __be32 *p; 1195 1196 p = xdr_reserve_space(xdr, XDR_UNIT * 13); 1197 if (!p) 1198 return false; 1199 p = xdr_encode_hyper(p, bs * s->f_blocks); /* total bytes */ 1200 p = xdr_encode_hyper(p, bs * s->f_bfree); /* free bytes */ 1201 p = xdr_encode_hyper(p, bs * s->f_bavail); /* user available bytes */ 1202 p = xdr_encode_hyper(p, s->f_files); /* total inodes */ 1203 p = xdr_encode_hyper(p, s->f_ffree); /* free inodes */ 1204 p = xdr_encode_hyper(p, s->f_ffree); /* user available inodes */ 1205 *p = cpu_to_be32(resp->invarsec); /* mean unchanged time */ 1206 1207 return true; 1208 } 1209 1210 /* FSSTAT */ 1211 bool 1212 nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 1213 { 1214 struct nfsd3_fsstatres *resp = rqstp->rq_resp; 1215 1216 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 1217 return false; 1218 switch (resp->status) { 1219 case nfs_ok: 1220 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh)) 1221 return false; 1222 if (!svcxdr_encode_fsstat3resok(xdr, resp)) 1223 return false; 1224 break; 1225 default: 1226 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh)) 1227 return false; 1228 } 1229 1230 return true; 1231 } 1232 1233 static bool 1234 svcxdr_encode_fsinfo3resok(struct xdr_stream *xdr, 1235 const struct nfsd3_fsinfores *resp) 1236 { 1237 __be32 *p; 1238 1239 p = xdr_reserve_space(xdr, XDR_UNIT * 12); 1240 if (!p) 1241 return false; 1242 *p++ = cpu_to_be32(resp->f_rtmax); 1243 *p++ = cpu_to_be32(resp->f_rtpref); 1244 *p++ = cpu_to_be32(resp->f_rtmult); 1245 *p++ = cpu_to_be32(resp->f_wtmax); 1246 *p++ = cpu_to_be32(resp->f_wtpref); 1247 *p++ = cpu_to_be32(resp->f_wtmult); 1248 *p++ = cpu_to_be32(resp->f_dtpref); 1249 p = xdr_encode_hyper(p, resp->f_maxfilesize); 1250 p = encode_nfstime3(p, &nfs3svc_time_delta); 1251 *p = cpu_to_be32(resp->f_properties); 1252 1253 return true; 1254 } 1255 1256 /* FSINFO */ 1257 bool 1258 nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, struct xdr_stream *xdr) 1259 { 1260 struct nfsd3_fsinfores *resp = rqstp->rq_resp; 1261 1262 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 1263 return false; 1264 switch (resp->status) { 1265 case nfs_ok: 1266 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh)) 1267 return false; 1268 if (!svcxdr_encode_fsinfo3resok(xdr, resp)) 1269 return false; 1270 break; 1271 default: 1272 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh)) 1273 return false; 1274 } 1275 1276 return true; 1277 } 1278 1279 static bool 1280 svcxdr_encode_pathconf3resok(struct xdr_stream *xdr, 1281 const struct nfsd3_pathconfres *resp) 1282 { 1283 __be32 *p; 1284 1285 p = xdr_reserve_space(xdr, XDR_UNIT * 6); 1286 if (!p) 1287 return false; 1288 *p++ = cpu_to_be32(resp->p_link_max); 1289 *p++ = cpu_to_be32(resp->p_name_max); 1290 p = xdr_encode_bool(p, resp->p_no_trunc); 1291 p = xdr_encode_bool(p, resp->p_chown_restricted); 1292 p = xdr_encode_bool(p, resp->p_case_insensitive); 1293 xdr_encode_bool(p, resp->p_case_preserving); 1294 1295 return true; 1296 } 1297 1298 /* PATHCONF */ 1299 bool 1300 nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 1301 { 1302 struct nfsd3_pathconfres *resp = rqstp->rq_resp; 1303 1304 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 1305 return false; 1306 switch (resp->status) { 1307 case nfs_ok: 1308 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh)) 1309 return false; 1310 if (!svcxdr_encode_pathconf3resok(xdr, resp)) 1311 return false; 1312 break; 1313 default: 1314 if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh)) 1315 return false; 1316 } 1317 1318 return true; 1319 } 1320 1321 /* COMMIT */ 1322 bool 1323 nfs3svc_encode_commitres(struct svc_rqst *rqstp, struct xdr_stream *xdr) 1324 { 1325 struct nfsd3_commitres *resp = rqstp->rq_resp; 1326 1327 if (!svcxdr_encode_nfsstat3(xdr, resp->status)) 1328 return false; 1329 switch (resp->status) { 1330 case nfs_ok: 1331 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh)) 1332 return false; 1333 if (!svcxdr_encode_writeverf3(xdr, resp->verf)) 1334 return false; 1335 break; 1336 default: 1337 if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh)) 1338 return false; 1339 } 1340 1341 return true; 1342 } 1343 1344 /* 1345 * XDR release functions 1346 */ 1347 void 1348 nfs3svc_release_fhandle(struct svc_rqst *rqstp) 1349 { 1350 struct nfsd3_attrstat *resp = rqstp->rq_resp; 1351 1352 fh_put(&resp->fh); 1353 } 1354 1355 void 1356 nfs3svc_release_fhandle2(struct svc_rqst *rqstp) 1357 { 1358 struct nfsd3_fhandle_pair *resp = rqstp->rq_resp; 1359 1360 fh_put(&resp->fh1); 1361 fh_put(&resp->fh2); 1362 } 1363