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/sunrpc/svc_xprt.h> 12 #include "xdr3.h" 13 #include "auth.h" 14 #include "netns.h" 15 #include "vfs.h" 16 17 #define NFSDDBG_FACILITY NFSDDBG_XDR 18 19 20 /* 21 * Mapping of S_IF* types to NFS file types 22 */ 23 static u32 nfs3_ftypes[] = { 24 NF3NON, NF3FIFO, NF3CHR, NF3BAD, 25 NF3DIR, NF3BAD, NF3BLK, NF3BAD, 26 NF3REG, NF3BAD, NF3LNK, NF3BAD, 27 NF3SOCK, NF3BAD, NF3LNK, NF3BAD, 28 }; 29 30 /* 31 * XDR functions for basic NFS types 32 */ 33 static __be32 * 34 encode_time3(__be32 *p, struct timespec *time) 35 { 36 *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); 37 return p; 38 } 39 40 static __be32 * 41 decode_time3(__be32 *p, struct timespec *time) 42 { 43 time->tv_sec = ntohl(*p++); 44 time->tv_nsec = ntohl(*p++); 45 return p; 46 } 47 48 static __be32 * 49 decode_fh(__be32 *p, struct svc_fh *fhp) 50 { 51 unsigned int size; 52 fh_init(fhp, NFS3_FHSIZE); 53 size = ntohl(*p++); 54 if (size > NFS3_FHSIZE) 55 return NULL; 56 57 memcpy(&fhp->fh_handle.fh_base, p, size); 58 fhp->fh_handle.fh_size = size; 59 return p + XDR_QUADLEN(size); 60 } 61 62 /* Helper function for NFSv3 ACL code */ 63 __be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp) 64 { 65 return decode_fh(p, fhp); 66 } 67 68 static __be32 * 69 encode_fh(__be32 *p, struct svc_fh *fhp) 70 { 71 unsigned int size = fhp->fh_handle.fh_size; 72 *p++ = htonl(size); 73 if (size) p[XDR_QUADLEN(size)-1]=0; 74 memcpy(p, &fhp->fh_handle.fh_base, size); 75 return p + XDR_QUADLEN(size); 76 } 77 78 /* 79 * Decode a file name and make sure that the path contains 80 * no slashes or null bytes. 81 */ 82 static __be32 * 83 decode_filename(__be32 *p, char **namp, unsigned int *lenp) 84 { 85 char *name; 86 unsigned int i; 87 88 if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXNAMLEN)) != NULL) { 89 for (i = 0, name = *namp; i < *lenp; i++, name++) { 90 if (*name == '\0' || *name == '/') 91 return NULL; 92 } 93 } 94 95 return p; 96 } 97 98 static __be32 * 99 decode_sattr3(__be32 *p, struct iattr *iap) 100 { 101 u32 tmp; 102 103 iap->ia_valid = 0; 104 105 if (*p++) { 106 iap->ia_valid |= ATTR_MODE; 107 iap->ia_mode = ntohl(*p++); 108 } 109 if (*p++) { 110 iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++)); 111 if (uid_valid(iap->ia_uid)) 112 iap->ia_valid |= ATTR_UID; 113 } 114 if (*p++) { 115 iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++)); 116 if (gid_valid(iap->ia_gid)) 117 iap->ia_valid |= ATTR_GID; 118 } 119 if (*p++) { 120 u64 newsize; 121 122 iap->ia_valid |= ATTR_SIZE; 123 p = xdr_decode_hyper(p, &newsize); 124 iap->ia_size = min_t(u64, newsize, NFS_OFFSET_MAX); 125 } 126 if ((tmp = ntohl(*p++)) == 1) { /* set to server time */ 127 iap->ia_valid |= ATTR_ATIME; 128 } else if (tmp == 2) { /* set to client time */ 129 iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET; 130 iap->ia_atime.tv_sec = ntohl(*p++); 131 iap->ia_atime.tv_nsec = ntohl(*p++); 132 } 133 if ((tmp = ntohl(*p++)) == 1) { /* set to server time */ 134 iap->ia_valid |= ATTR_MTIME; 135 } else if (tmp == 2) { /* set to client time */ 136 iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET; 137 iap->ia_mtime.tv_sec = ntohl(*p++); 138 iap->ia_mtime.tv_nsec = ntohl(*p++); 139 } 140 return p; 141 } 142 143 static __be32 *encode_fsid(__be32 *p, struct svc_fh *fhp) 144 { 145 u64 f; 146 switch(fsid_source(fhp)) { 147 default: 148 case FSIDSOURCE_DEV: 149 p = xdr_encode_hyper(p, (u64)huge_encode_dev 150 (fhp->fh_dentry->d_sb->s_dev)); 151 break; 152 case FSIDSOURCE_FSID: 153 p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid); 154 break; 155 case FSIDSOURCE_UUID: 156 f = ((u64*)fhp->fh_export->ex_uuid)[0]; 157 f ^= ((u64*)fhp->fh_export->ex_uuid)[1]; 158 p = xdr_encode_hyper(p, f); 159 break; 160 } 161 return p; 162 } 163 164 static __be32 * 165 encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, 166 struct kstat *stat) 167 { 168 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); 169 *p++ = htonl((u32) (stat->mode & S_IALLUGO)); 170 *p++ = htonl((u32) stat->nlink); 171 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 172 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); 173 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) { 174 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); 175 } else { 176 p = xdr_encode_hyper(p, (u64) stat->size); 177 } 178 p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9); 179 *p++ = htonl((u32) MAJOR(stat->rdev)); 180 *p++ = htonl((u32) MINOR(stat->rdev)); 181 p = encode_fsid(p, fhp); 182 p = xdr_encode_hyper(p, stat->ino); 183 p = encode_time3(p, &stat->atime); 184 p = encode_time3(p, &stat->mtime); 185 p = encode_time3(p, &stat->ctime); 186 187 return p; 188 } 189 190 static __be32 * 191 encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) 192 { 193 /* Attributes to follow */ 194 *p++ = xdr_one; 195 return encode_fattr3(rqstp, p, fhp, &fhp->fh_post_attr); 196 } 197 198 /* 199 * Encode post-operation attributes. 200 * The inode may be NULL if the call failed because of a stale file 201 * handle. In this case, no attributes are returned. 202 */ 203 static __be32 * 204 encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) 205 { 206 struct dentry *dentry = fhp->fh_dentry; 207 if (dentry && d_really_is_positive(dentry)) { 208 __be32 err; 209 struct kstat stat; 210 211 err = fh_getattr(fhp, &stat); 212 if (!err) { 213 *p++ = xdr_one; /* attributes follow */ 214 lease_get_mtime(d_inode(dentry), &stat.mtime); 215 return encode_fattr3(rqstp, p, fhp, &stat); 216 } 217 } 218 *p++ = xdr_zero; 219 return p; 220 } 221 222 /* Helper for NFSv3 ACLs */ 223 __be32 * 224 nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) 225 { 226 return encode_post_op_attr(rqstp, p, fhp); 227 } 228 229 /* 230 * Enocde weak cache consistency data 231 */ 232 static __be32 * 233 encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) 234 { 235 struct dentry *dentry = fhp->fh_dentry; 236 237 if (dentry && d_really_is_positive(dentry) && fhp->fh_post_saved) { 238 if (fhp->fh_pre_saved) { 239 *p++ = xdr_one; 240 p = xdr_encode_hyper(p, (u64) fhp->fh_pre_size); 241 p = encode_time3(p, &fhp->fh_pre_mtime); 242 p = encode_time3(p, &fhp->fh_pre_ctime); 243 } else { 244 *p++ = xdr_zero; 245 } 246 return encode_saved_post_attr(rqstp, p, fhp); 247 } 248 /* no pre- or post-attrs */ 249 *p++ = xdr_zero; 250 return encode_post_op_attr(rqstp, p, fhp); 251 } 252 253 /* 254 * Fill in the pre_op attr for the wcc data 255 */ 256 void fill_pre_wcc(struct svc_fh *fhp) 257 { 258 struct inode *inode; 259 struct kstat stat; 260 __be32 err; 261 262 if (fhp->fh_pre_saved) 263 return; 264 265 inode = d_inode(fhp->fh_dentry); 266 err = fh_getattr(fhp, &stat); 267 if (err) { 268 /* Grab the times from inode anyway */ 269 stat.mtime = inode->i_mtime; 270 stat.ctime = inode->i_ctime; 271 stat.size = inode->i_size; 272 } 273 274 fhp->fh_pre_mtime = stat.mtime; 275 fhp->fh_pre_ctime = stat.ctime; 276 fhp->fh_pre_size = stat.size; 277 fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode); 278 fhp->fh_pre_saved = true; 279 } 280 281 /* 282 * Fill in the post_op attr for the wcc data 283 */ 284 void fill_post_wcc(struct svc_fh *fhp) 285 { 286 __be32 err; 287 288 if (fhp->fh_post_saved) 289 printk("nfsd: inode locked twice during operation.\n"); 290 291 err = fh_getattr(fhp, &fhp->fh_post_attr); 292 fhp->fh_post_change = nfsd4_change_attribute(&fhp->fh_post_attr, 293 d_inode(fhp->fh_dentry)); 294 if (err) { 295 fhp->fh_post_saved = false; 296 /* Grab the ctime anyway - set_change_info might use it */ 297 fhp->fh_post_attr.ctime = d_inode(fhp->fh_dentry)->i_ctime; 298 } else 299 fhp->fh_post_saved = true; 300 } 301 302 /* 303 * XDR decode functions 304 */ 305 int 306 nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p) 307 { 308 struct nfsd_fhandle *args = rqstp->rq_argp; 309 310 p = decode_fh(p, &args->fh); 311 if (!p) 312 return 0; 313 return xdr_argsize_check(rqstp, p); 314 } 315 316 int 317 nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p) 318 { 319 struct nfsd3_sattrargs *args = rqstp->rq_argp; 320 321 p = decode_fh(p, &args->fh); 322 if (!p) 323 return 0; 324 p = decode_sattr3(p, &args->attrs); 325 326 if ((args->check_guard = ntohl(*p++)) != 0) { 327 struct timespec time; 328 p = decode_time3(p, &time); 329 args->guardtime = time.tv_sec; 330 } 331 332 return xdr_argsize_check(rqstp, p); 333 } 334 335 int 336 nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p) 337 { 338 struct nfsd3_diropargs *args = rqstp->rq_argp; 339 340 if (!(p = decode_fh(p, &args->fh)) 341 || !(p = decode_filename(p, &args->name, &args->len))) 342 return 0; 343 344 return xdr_argsize_check(rqstp, p); 345 } 346 347 int 348 nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p) 349 { 350 struct nfsd3_accessargs *args = rqstp->rq_argp; 351 352 p = decode_fh(p, &args->fh); 353 if (!p) 354 return 0; 355 args->access = ntohl(*p++); 356 357 return xdr_argsize_check(rqstp, p); 358 } 359 360 int 361 nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p) 362 { 363 struct nfsd3_readargs *args = rqstp->rq_argp; 364 unsigned int len; 365 int v; 366 u32 max_blocksize = svc_max_payload(rqstp); 367 368 p = decode_fh(p, &args->fh); 369 if (!p) 370 return 0; 371 p = xdr_decode_hyper(p, &args->offset); 372 373 args->count = ntohl(*p++); 374 len = min(args->count, max_blocksize); 375 376 /* set up the kvec */ 377 v=0; 378 while (len > 0) { 379 struct page *p = *(rqstp->rq_next_page++); 380 381 rqstp->rq_vec[v].iov_base = page_address(p); 382 rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE); 383 len -= rqstp->rq_vec[v].iov_len; 384 v++; 385 } 386 args->vlen = v; 387 return xdr_argsize_check(rqstp, p); 388 } 389 390 int 391 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p) 392 { 393 struct nfsd3_writeargs *args = rqstp->rq_argp; 394 unsigned int len, hdr, dlen; 395 u32 max_blocksize = svc_max_payload(rqstp); 396 struct kvec *head = rqstp->rq_arg.head; 397 struct kvec *tail = rqstp->rq_arg.tail; 398 399 p = decode_fh(p, &args->fh); 400 if (!p) 401 return 0; 402 p = xdr_decode_hyper(p, &args->offset); 403 404 args->count = ntohl(*p++); 405 args->stable = ntohl(*p++); 406 len = args->len = ntohl(*p++); 407 if ((void *)p > head->iov_base + head->iov_len) 408 return 0; 409 /* 410 * The count must equal the amount of data passed. 411 */ 412 if (args->count != args->len) 413 return 0; 414 415 /* 416 * Check to make sure that we got the right number of 417 * bytes. 418 */ 419 hdr = (void*)p - head->iov_base; 420 dlen = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len - hdr; 421 /* 422 * Round the length of the data which was specified up to 423 * the next multiple of XDR units and then compare that 424 * against the length which was actually received. 425 * Note that when RPCSEC/GSS (for example) is used, the 426 * data buffer can be padded so dlen might be larger 427 * than required. It must never be smaller. 428 */ 429 if (dlen < XDR_QUADLEN(len)*4) 430 return 0; 431 432 if (args->count > max_blocksize) { 433 args->count = max_blocksize; 434 len = args->len = max_blocksize; 435 } 436 437 args->first.iov_base = (void *)p; 438 args->first.iov_len = head->iov_len - hdr; 439 return 1; 440 } 441 442 int 443 nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p) 444 { 445 struct nfsd3_createargs *args = rqstp->rq_argp; 446 447 if (!(p = decode_fh(p, &args->fh)) 448 || !(p = decode_filename(p, &args->name, &args->len))) 449 return 0; 450 451 switch (args->createmode = ntohl(*p++)) { 452 case NFS3_CREATE_UNCHECKED: 453 case NFS3_CREATE_GUARDED: 454 p = decode_sattr3(p, &args->attrs); 455 break; 456 case NFS3_CREATE_EXCLUSIVE: 457 args->verf = p; 458 p += 2; 459 break; 460 default: 461 return 0; 462 } 463 464 return xdr_argsize_check(rqstp, p); 465 } 466 467 int 468 nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p) 469 { 470 struct nfsd3_createargs *args = rqstp->rq_argp; 471 472 if (!(p = decode_fh(p, &args->fh)) || 473 !(p = decode_filename(p, &args->name, &args->len))) 474 return 0; 475 p = decode_sattr3(p, &args->attrs); 476 477 return xdr_argsize_check(rqstp, p); 478 } 479 480 int 481 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p) 482 { 483 struct nfsd3_symlinkargs *args = rqstp->rq_argp; 484 char *base = (char *)p; 485 size_t dlen; 486 487 if (!(p = decode_fh(p, &args->ffh)) || 488 !(p = decode_filename(p, &args->fname, &args->flen))) 489 return 0; 490 p = decode_sattr3(p, &args->attrs); 491 492 args->tlen = ntohl(*p++); 493 494 args->first.iov_base = p; 495 args->first.iov_len = rqstp->rq_arg.head[0].iov_len; 496 args->first.iov_len -= (char *)p - base; 497 498 dlen = args->first.iov_len + rqstp->rq_arg.page_len + 499 rqstp->rq_arg.tail[0].iov_len; 500 if (dlen < XDR_QUADLEN(args->tlen) << 2) 501 return 0; 502 return 1; 503 } 504 505 int 506 nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p) 507 { 508 struct nfsd3_mknodargs *args = rqstp->rq_argp; 509 510 if (!(p = decode_fh(p, &args->fh)) 511 || !(p = decode_filename(p, &args->name, &args->len))) 512 return 0; 513 514 args->ftype = ntohl(*p++); 515 516 if (args->ftype == NF3BLK || args->ftype == NF3CHR 517 || args->ftype == NF3SOCK || args->ftype == NF3FIFO) 518 p = decode_sattr3(p, &args->attrs); 519 520 if (args->ftype == NF3BLK || args->ftype == NF3CHR) { 521 args->major = ntohl(*p++); 522 args->minor = ntohl(*p++); 523 } 524 525 return xdr_argsize_check(rqstp, p); 526 } 527 528 int 529 nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p) 530 { 531 struct nfsd3_renameargs *args = rqstp->rq_argp; 532 533 if (!(p = decode_fh(p, &args->ffh)) 534 || !(p = decode_filename(p, &args->fname, &args->flen)) 535 || !(p = decode_fh(p, &args->tfh)) 536 || !(p = decode_filename(p, &args->tname, &args->tlen))) 537 return 0; 538 539 return xdr_argsize_check(rqstp, p); 540 } 541 542 int 543 nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p) 544 { 545 struct nfsd3_readlinkargs *args = rqstp->rq_argp; 546 547 p = decode_fh(p, &args->fh); 548 if (!p) 549 return 0; 550 args->buffer = page_address(*(rqstp->rq_next_page++)); 551 552 return xdr_argsize_check(rqstp, p); 553 } 554 555 int 556 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p) 557 { 558 struct nfsd3_linkargs *args = rqstp->rq_argp; 559 560 if (!(p = decode_fh(p, &args->ffh)) 561 || !(p = decode_fh(p, &args->tfh)) 562 || !(p = decode_filename(p, &args->tname, &args->tlen))) 563 return 0; 564 565 return xdr_argsize_check(rqstp, p); 566 } 567 568 int 569 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p) 570 { 571 struct nfsd3_readdirargs *args = rqstp->rq_argp; 572 p = decode_fh(p, &args->fh); 573 if (!p) 574 return 0; 575 p = xdr_decode_hyper(p, &args->cookie); 576 args->verf = p; p += 2; 577 args->dircount = ~0; 578 args->count = ntohl(*p++); 579 args->count = min_t(u32, args->count, PAGE_SIZE); 580 args->buffer = page_address(*(rqstp->rq_next_page++)); 581 582 return xdr_argsize_check(rqstp, p); 583 } 584 585 int 586 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p) 587 { 588 struct nfsd3_readdirargs *args = rqstp->rq_argp; 589 int len; 590 u32 max_blocksize = svc_max_payload(rqstp); 591 592 p = decode_fh(p, &args->fh); 593 if (!p) 594 return 0; 595 p = xdr_decode_hyper(p, &args->cookie); 596 args->verf = p; p += 2; 597 args->dircount = ntohl(*p++); 598 args->count = ntohl(*p++); 599 600 len = args->count = min(args->count, max_blocksize); 601 while (len > 0) { 602 struct page *p = *(rqstp->rq_next_page++); 603 if (!args->buffer) 604 args->buffer = page_address(p); 605 len -= PAGE_SIZE; 606 } 607 608 return xdr_argsize_check(rqstp, p); 609 } 610 611 int 612 nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p) 613 { 614 struct nfsd3_commitargs *args = rqstp->rq_argp; 615 p = decode_fh(p, &args->fh); 616 if (!p) 617 return 0; 618 p = xdr_decode_hyper(p, &args->offset); 619 args->count = ntohl(*p++); 620 621 return xdr_argsize_check(rqstp, p); 622 } 623 624 /* 625 * XDR encode functions 626 */ 627 /* 628 * There must be an encoding function for void results so svc_process 629 * will work properly. 630 */ 631 int 632 nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p) 633 { 634 return xdr_ressize_check(rqstp, p); 635 } 636 637 /* GETATTR */ 638 int 639 nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p) 640 { 641 struct nfsd3_attrstat *resp = rqstp->rq_resp; 642 643 if (resp->status == 0) { 644 lease_get_mtime(d_inode(resp->fh.fh_dentry), 645 &resp->stat.mtime); 646 p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat); 647 } 648 return xdr_ressize_check(rqstp, p); 649 } 650 651 /* SETATTR, REMOVE, RMDIR */ 652 int 653 nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p) 654 { 655 struct nfsd3_attrstat *resp = rqstp->rq_resp; 656 657 p = encode_wcc_data(rqstp, p, &resp->fh); 658 return xdr_ressize_check(rqstp, p); 659 } 660 661 /* LOOKUP */ 662 int 663 nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p) 664 { 665 struct nfsd3_diropres *resp = rqstp->rq_resp; 666 667 if (resp->status == 0) { 668 p = encode_fh(p, &resp->fh); 669 p = encode_post_op_attr(rqstp, p, &resp->fh); 670 } 671 p = encode_post_op_attr(rqstp, p, &resp->dirfh); 672 return xdr_ressize_check(rqstp, p); 673 } 674 675 /* ACCESS */ 676 int 677 nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p) 678 { 679 struct nfsd3_accessres *resp = rqstp->rq_resp; 680 681 p = encode_post_op_attr(rqstp, p, &resp->fh); 682 if (resp->status == 0) 683 *p++ = htonl(resp->access); 684 return xdr_ressize_check(rqstp, p); 685 } 686 687 /* READLINK */ 688 int 689 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p) 690 { 691 struct nfsd3_readlinkres *resp = rqstp->rq_resp; 692 693 p = encode_post_op_attr(rqstp, p, &resp->fh); 694 if (resp->status == 0) { 695 *p++ = htonl(resp->len); 696 xdr_ressize_check(rqstp, p); 697 rqstp->rq_res.page_len = resp->len; 698 if (resp->len & 3) { 699 /* need to pad the tail */ 700 rqstp->rq_res.tail[0].iov_base = p; 701 *p = 0; 702 rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); 703 } 704 return 1; 705 } else 706 return xdr_ressize_check(rqstp, p); 707 } 708 709 /* READ */ 710 int 711 nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p) 712 { 713 struct nfsd3_readres *resp = rqstp->rq_resp; 714 715 p = encode_post_op_attr(rqstp, p, &resp->fh); 716 if (resp->status == 0) { 717 *p++ = htonl(resp->count); 718 *p++ = htonl(resp->eof); 719 *p++ = htonl(resp->count); /* xdr opaque count */ 720 xdr_ressize_check(rqstp, p); 721 /* now update rqstp->rq_res to reflect data as well */ 722 rqstp->rq_res.page_len = resp->count; 723 if (resp->count & 3) { 724 /* need to pad the tail */ 725 rqstp->rq_res.tail[0].iov_base = p; 726 *p = 0; 727 rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3); 728 } 729 return 1; 730 } else 731 return xdr_ressize_check(rqstp, p); 732 } 733 734 /* WRITE */ 735 int 736 nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p) 737 { 738 struct nfsd3_writeres *resp = rqstp->rq_resp; 739 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 740 741 p = encode_wcc_data(rqstp, p, &resp->fh); 742 if (resp->status == 0) { 743 *p++ = htonl(resp->count); 744 *p++ = htonl(resp->committed); 745 /* unique identifier, y2038 overflow can be ignored */ 746 *p++ = htonl((u32)nn->nfssvc_boot.tv_sec); 747 *p++ = htonl(nn->nfssvc_boot.tv_nsec); 748 } 749 return xdr_ressize_check(rqstp, p); 750 } 751 752 /* CREATE, MKDIR, SYMLINK, MKNOD */ 753 int 754 nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p) 755 { 756 struct nfsd3_diropres *resp = rqstp->rq_resp; 757 758 if (resp->status == 0) { 759 *p++ = xdr_one; 760 p = encode_fh(p, &resp->fh); 761 p = encode_post_op_attr(rqstp, p, &resp->fh); 762 } 763 p = encode_wcc_data(rqstp, p, &resp->dirfh); 764 return xdr_ressize_check(rqstp, p); 765 } 766 767 /* RENAME */ 768 int 769 nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p) 770 { 771 struct nfsd3_renameres *resp = rqstp->rq_resp; 772 773 p = encode_wcc_data(rqstp, p, &resp->ffh); 774 p = encode_wcc_data(rqstp, p, &resp->tfh); 775 return xdr_ressize_check(rqstp, p); 776 } 777 778 /* LINK */ 779 int 780 nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p) 781 { 782 struct nfsd3_linkres *resp = rqstp->rq_resp; 783 784 p = encode_post_op_attr(rqstp, p, &resp->fh); 785 p = encode_wcc_data(rqstp, p, &resp->tfh); 786 return xdr_ressize_check(rqstp, p); 787 } 788 789 /* READDIR */ 790 int 791 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p) 792 { 793 struct nfsd3_readdirres *resp = rqstp->rq_resp; 794 795 p = encode_post_op_attr(rqstp, p, &resp->fh); 796 797 if (resp->status == 0) { 798 /* stupid readdir cookie */ 799 memcpy(p, resp->verf, 8); p += 2; 800 xdr_ressize_check(rqstp, p); 801 if (rqstp->rq_res.head[0].iov_len + (2<<2) > PAGE_SIZE) 802 return 1; /*No room for trailer */ 803 rqstp->rq_res.page_len = (resp->count) << 2; 804 805 /* add the 'tail' to the end of the 'head' page - page 0. */ 806 rqstp->rq_res.tail[0].iov_base = p; 807 *p++ = 0; /* no more entries */ 808 *p++ = htonl(resp->common.err == nfserr_eof); 809 rqstp->rq_res.tail[0].iov_len = 2<<2; 810 return 1; 811 } else 812 return xdr_ressize_check(rqstp, p); 813 } 814 815 static __be32 * 816 encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, 817 int namlen, u64 ino) 818 { 819 *p++ = xdr_one; /* mark entry present */ 820 p = xdr_encode_hyper(p, ino); /* file id */ 821 p = xdr_encode_array(p, name, namlen);/* name length & name */ 822 823 cd->offset = p; /* remember pointer */ 824 p = xdr_encode_hyper(p, NFS_OFFSET_MAX);/* offset of next entry */ 825 826 return p; 827 } 828 829 static __be32 830 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, 831 const char *name, int namlen, u64 ino) 832 { 833 struct svc_export *exp; 834 struct dentry *dparent, *dchild; 835 __be32 rv = nfserr_noent; 836 837 dparent = cd->fh.fh_dentry; 838 exp = cd->fh.fh_export; 839 840 if (isdotent(name, namlen)) { 841 if (namlen == 2) { 842 dchild = dget_parent(dparent); 843 /* filesystem root - cannot return filehandle for ".." */ 844 if (dchild == dparent) 845 goto out; 846 } else 847 dchild = dget(dparent); 848 } else 849 dchild = lookup_one_len_unlocked(name, dparent, namlen); 850 if (IS_ERR(dchild)) 851 return rv; 852 if (d_mountpoint(dchild)) 853 goto out; 854 if (d_really_is_negative(dchild)) 855 goto out; 856 if (dchild->d_inode->i_ino != ino) 857 goto out; 858 rv = fh_compose(fhp, exp, dchild, &cd->fh); 859 out: 860 dput(dchild); 861 return rv; 862 } 863 864 static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen, u64 ino) 865 { 866 struct svc_fh *fh = &cd->scratch; 867 __be32 err; 868 869 fh_init(fh, NFS3_FHSIZE); 870 err = compose_entry_fh(cd, fh, name, namlen, ino); 871 if (err) { 872 *p++ = 0; 873 *p++ = 0; 874 goto out; 875 } 876 p = encode_post_op_attr(cd->rqstp, p, fh); 877 *p++ = xdr_one; /* yes, a file handle follows */ 878 p = encode_fh(p, fh); 879 out: 880 fh_put(fh); 881 return p; 882 } 883 884 /* 885 * Encode a directory entry. This one works for both normal readdir 886 * and readdirplus. 887 * The normal readdir reply requires 2 (fileid) + 1 (stringlen) 888 * + string + 2 (cookie) + 1 (next) words, i.e. 6 + strlen. 889 * 890 * The readdirplus baggage is 1+21 words for post_op_attr, plus the 891 * file handle. 892 */ 893 894 #define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1) 895 #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2)) 896 static int 897 encode_entry(struct readdir_cd *ccd, const char *name, int namlen, 898 loff_t offset, u64 ino, unsigned int d_type, int plus) 899 { 900 struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, 901 common); 902 __be32 *p = cd->buffer; 903 caddr_t curr_page_addr = NULL; 904 struct page ** page; 905 int slen; /* string (name) length */ 906 int elen; /* estimated entry length in words */ 907 int num_entry_words = 0; /* actual number of words */ 908 909 if (cd->offset) { 910 u64 offset64 = offset; 911 912 if (unlikely(cd->offset1)) { 913 /* we ended up with offset on a page boundary */ 914 *cd->offset = htonl(offset64 >> 32); 915 *cd->offset1 = htonl(offset64 & 0xffffffff); 916 cd->offset1 = NULL; 917 } else { 918 xdr_encode_hyper(cd->offset, offset64); 919 } 920 } 921 922 /* 923 dprintk("encode_entry(%.*s @%ld%s)\n", 924 namlen, name, (long) offset, plus? " plus" : ""); 925 */ 926 927 /* truncate filename if too long */ 928 namlen = min(namlen, NFS3_MAXNAMLEN); 929 930 slen = XDR_QUADLEN(namlen); 931 elen = slen + NFS3_ENTRY_BAGGAGE 932 + (plus? NFS3_ENTRYPLUS_BAGGAGE : 0); 933 934 if (cd->buflen < elen) { 935 cd->common.err = nfserr_toosmall; 936 return -EINVAL; 937 } 938 939 /* determine which page in rq_respages[] we are currently filling */ 940 for (page = cd->rqstp->rq_respages + 1; 941 page < cd->rqstp->rq_next_page; page++) { 942 curr_page_addr = page_address(*page); 943 944 if (((caddr_t)cd->buffer >= curr_page_addr) && 945 ((caddr_t)cd->buffer < curr_page_addr + PAGE_SIZE)) 946 break; 947 } 948 949 if ((caddr_t)(cd->buffer + elen) < (curr_page_addr + PAGE_SIZE)) { 950 /* encode entry in current page */ 951 952 p = encode_entry_baggage(cd, p, name, namlen, ino); 953 954 if (plus) 955 p = encode_entryplus_baggage(cd, p, name, namlen, ino); 956 num_entry_words = p - cd->buffer; 957 } else if (*(page+1) != NULL) { 958 /* temporarily encode entry into next page, then move back to 959 * current and next page in rq_respages[] */ 960 __be32 *p1, *tmp; 961 int len1, len2; 962 963 /* grab next page for temporary storage of entry */ 964 p1 = tmp = page_address(*(page+1)); 965 966 p1 = encode_entry_baggage(cd, p1, name, namlen, ino); 967 968 if (plus) 969 p1 = encode_entryplus_baggage(cd, p1, name, namlen, ino); 970 971 /* determine entry word length and lengths to go in pages */ 972 num_entry_words = p1 - tmp; 973 len1 = curr_page_addr + PAGE_SIZE - (caddr_t)cd->buffer; 974 if ((num_entry_words << 2) < len1) { 975 /* the actual number of words in the entry is less 976 * than elen and can still fit in the current page 977 */ 978 memmove(p, tmp, num_entry_words << 2); 979 p += num_entry_words; 980 981 /* update offset */ 982 cd->offset = cd->buffer + (cd->offset - tmp); 983 } else { 984 unsigned int offset_r = (cd->offset - tmp) << 2; 985 986 /* update pointer to offset location. 987 * This is a 64bit quantity, so we need to 988 * deal with 3 cases: 989 * - entirely in first page 990 * - entirely in second page 991 * - 4 bytes in each page 992 */ 993 if (offset_r + 8 <= len1) { 994 cd->offset = p + (cd->offset - tmp); 995 } else if (offset_r >= len1) { 996 cd->offset -= len1 >> 2; 997 } else { 998 /* sitting on the fence */ 999 BUG_ON(offset_r != len1 - 4); 1000 cd->offset = p + (cd->offset - tmp); 1001 cd->offset1 = tmp; 1002 } 1003 1004 len2 = (num_entry_words << 2) - len1; 1005 1006 /* move from temp page to current and next pages */ 1007 memmove(p, tmp, len1); 1008 memmove(tmp, (caddr_t)tmp+len1, len2); 1009 1010 p = tmp + (len2 >> 2); 1011 } 1012 } 1013 else { 1014 cd->common.err = nfserr_toosmall; 1015 return -EINVAL; 1016 } 1017 1018 cd->buflen -= num_entry_words; 1019 cd->buffer = p; 1020 cd->common.err = nfs_ok; 1021 return 0; 1022 1023 } 1024 1025 int 1026 nfs3svc_encode_entry(void *cd, const char *name, 1027 int namlen, loff_t offset, u64 ino, unsigned int d_type) 1028 { 1029 return encode_entry(cd, name, namlen, offset, ino, d_type, 0); 1030 } 1031 1032 int 1033 nfs3svc_encode_entry_plus(void *cd, const char *name, 1034 int namlen, loff_t offset, u64 ino, 1035 unsigned int d_type) 1036 { 1037 return encode_entry(cd, name, namlen, offset, ino, d_type, 1); 1038 } 1039 1040 /* FSSTAT */ 1041 int 1042 nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p) 1043 { 1044 struct nfsd3_fsstatres *resp = rqstp->rq_resp; 1045 struct kstatfs *s = &resp->stats; 1046 u64 bs = s->f_bsize; 1047 1048 *p++ = xdr_zero; /* no post_op_attr */ 1049 1050 if (resp->status == 0) { 1051 p = xdr_encode_hyper(p, bs * s->f_blocks); /* total bytes */ 1052 p = xdr_encode_hyper(p, bs * s->f_bfree); /* free bytes */ 1053 p = xdr_encode_hyper(p, bs * s->f_bavail); /* user available bytes */ 1054 p = xdr_encode_hyper(p, s->f_files); /* total inodes */ 1055 p = xdr_encode_hyper(p, s->f_ffree); /* free inodes */ 1056 p = xdr_encode_hyper(p, s->f_ffree); /* user available inodes */ 1057 *p++ = htonl(resp->invarsec); /* mean unchanged time */ 1058 } 1059 return xdr_ressize_check(rqstp, p); 1060 } 1061 1062 /* FSINFO */ 1063 int 1064 nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p) 1065 { 1066 struct nfsd3_fsinfores *resp = rqstp->rq_resp; 1067 1068 *p++ = xdr_zero; /* no post_op_attr */ 1069 1070 if (resp->status == 0) { 1071 *p++ = htonl(resp->f_rtmax); 1072 *p++ = htonl(resp->f_rtpref); 1073 *p++ = htonl(resp->f_rtmult); 1074 *p++ = htonl(resp->f_wtmax); 1075 *p++ = htonl(resp->f_wtpref); 1076 *p++ = htonl(resp->f_wtmult); 1077 *p++ = htonl(resp->f_dtpref); 1078 p = xdr_encode_hyper(p, resp->f_maxfilesize); 1079 *p++ = xdr_one; 1080 *p++ = xdr_zero; 1081 *p++ = htonl(resp->f_properties); 1082 } 1083 1084 return xdr_ressize_check(rqstp, p); 1085 } 1086 1087 /* PATHCONF */ 1088 int 1089 nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p) 1090 { 1091 struct nfsd3_pathconfres *resp = rqstp->rq_resp; 1092 1093 *p++ = xdr_zero; /* no post_op_attr */ 1094 1095 if (resp->status == 0) { 1096 *p++ = htonl(resp->p_link_max); 1097 *p++ = htonl(resp->p_name_max); 1098 *p++ = htonl(resp->p_no_trunc); 1099 *p++ = htonl(resp->p_chown_restricted); 1100 *p++ = htonl(resp->p_case_insensitive); 1101 *p++ = htonl(resp->p_case_preserving); 1102 } 1103 1104 return xdr_ressize_check(rqstp, p); 1105 } 1106 1107 /* COMMIT */ 1108 int 1109 nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p) 1110 { 1111 struct nfsd3_commitres *resp = rqstp->rq_resp; 1112 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 1113 1114 p = encode_wcc_data(rqstp, p, &resp->fh); 1115 /* Write verifier */ 1116 if (resp->status == 0) { 1117 /* unique identifier, y2038 overflow can be ignored */ 1118 *p++ = htonl((u32)nn->nfssvc_boot.tv_sec); 1119 *p++ = htonl(nn->nfssvc_boot.tv_nsec); 1120 } 1121 return xdr_ressize_check(rqstp, p); 1122 } 1123 1124 /* 1125 * XDR release functions 1126 */ 1127 void 1128 nfs3svc_release_fhandle(struct svc_rqst *rqstp) 1129 { 1130 struct nfsd3_attrstat *resp = rqstp->rq_resp; 1131 1132 fh_put(&resp->fh); 1133 } 1134 1135 void 1136 nfs3svc_release_fhandle2(struct svc_rqst *rqstp) 1137 { 1138 struct nfsd3_fhandle_pair *resp = rqstp->rq_resp; 1139 1140 fh_put(&resp->fh1); 1141 fh_put(&resp->fh2); 1142 } 1143