1 /* 2 * Server-side XDR for NFSv4 3 * 4 * Copyright (c) 2002 The Regents of the University of Michigan. 5 * All rights reserved. 6 * 7 * Kendrick Smith <kmsmith@umich.edu> 8 * Andy Adamson <andros@umich.edu> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 * TODO: Neil Brown made the following observation: We currently 36 * initially reserve NFSD_BUFSIZE space on the transmit queue and 37 * never release any of that until the request is complete. 38 * It would be good to calculate a new maximum response size while 39 * decoding the COMPOUND, and call svc_reserve with this number 40 * at the end of nfs4svc_decode_compoundargs. 41 */ 42 43 #include <linux/param.h> 44 #include <linux/smp.h> 45 #include <linux/fs.h> 46 #include <linux/namei.h> 47 #include <linux/vfs.h> 48 #include <linux/utsname.h> 49 #include <linux/sunrpc/xdr.h> 50 #include <linux/sunrpc/svc.h> 51 #include <linux/sunrpc/clnt.h> 52 #include <linux/nfsd/nfsd.h> 53 #include <linux/nfsd/state.h> 54 #include <linux/nfsd/xdr4.h> 55 #include <linux/nfsd_idmap.h> 56 #include <linux/nfs4.h> 57 #include <linux/nfs4_acl.h> 58 #include <linux/sunrpc/gss_api.h> 59 #include <linux/sunrpc/svcauth_gss.h> 60 61 #define NFSDDBG_FACILITY NFSDDBG_XDR 62 63 /* 64 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing 65 * directory in order to indicate to the client that a filesystem boundary is present 66 * We use a fixed fsid for a referral 67 */ 68 #define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL 69 #define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL 70 71 static __be32 72 check_filename(char *str, int len, __be32 err) 73 { 74 int i; 75 76 if (len == 0) 77 return nfserr_inval; 78 if (isdotent(str, len)) 79 return err; 80 for (i = 0; i < len; i++) 81 if (str[i] == '/') 82 return err; 83 return 0; 84 } 85 86 /* 87 * START OF "GENERIC" DECODE ROUTINES. 88 * These may look a little ugly since they are imported from a "generic" 89 * set of XDR encode/decode routines which are intended to be shared by 90 * all of our NFSv4 implementations (OpenBSD, MacOS X...). 91 * 92 * If the pain of reading these is too great, it should be a straightforward 93 * task to translate them into Linux-specific versions which are more 94 * consistent with the style used in NFSv2/v3... 95 */ 96 #define DECODE_HEAD \ 97 __be32 *p; \ 98 __be32 status 99 #define DECODE_TAIL \ 100 status = 0; \ 101 out: \ 102 return status; \ 103 xdr_error: \ 104 dprintk("NFSD: xdr error (%s:%d)\n", \ 105 __FILE__, __LINE__); \ 106 status = nfserr_bad_xdr; \ 107 goto out 108 109 #define READ32(x) (x) = ntohl(*p++) 110 #define READ64(x) do { \ 111 (x) = (u64)ntohl(*p++) << 32; \ 112 (x) |= ntohl(*p++); \ 113 } while (0) 114 #define READTIME(x) do { \ 115 p++; \ 116 (x) = ntohl(*p++); \ 117 p++; \ 118 } while (0) 119 #define READMEM(x,nbytes) do { \ 120 x = (char *)p; \ 121 p += XDR_QUADLEN(nbytes); \ 122 } while (0) 123 #define SAVEMEM(x,nbytes) do { \ 124 if (!(x = (p==argp->tmp || p == argp->tmpp) ? \ 125 savemem(argp, p, nbytes) : \ 126 (char *)p)) { \ 127 dprintk("NFSD: xdr error (%s:%d)\n", \ 128 __FILE__, __LINE__); \ 129 goto xdr_error; \ 130 } \ 131 p += XDR_QUADLEN(nbytes); \ 132 } while (0) 133 #define COPYMEM(x,nbytes) do { \ 134 memcpy((x), p, nbytes); \ 135 p += XDR_QUADLEN(nbytes); \ 136 } while (0) 137 138 /* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */ 139 #define READ_BUF(nbytes) do { \ 140 if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) { \ 141 p = argp->p; \ 142 argp->p += XDR_QUADLEN(nbytes); \ 143 } else if (!(p = read_buf(argp, nbytes))) { \ 144 dprintk("NFSD: xdr error (%s:%d)\n", \ 145 __FILE__, __LINE__); \ 146 goto xdr_error; \ 147 } \ 148 } while (0) 149 150 static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) 151 { 152 /* We want more bytes than seem to be available. 153 * Maybe we need a new page, maybe we have just run out 154 */ 155 unsigned int avail = (char *)argp->end - (char *)argp->p; 156 __be32 *p; 157 if (avail + argp->pagelen < nbytes) 158 return NULL; 159 if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ 160 return NULL; 161 /* ok, we can do it with the current plus the next page */ 162 if (nbytes <= sizeof(argp->tmp)) 163 p = argp->tmp; 164 else { 165 kfree(argp->tmpp); 166 p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL); 167 if (!p) 168 return NULL; 169 170 } 171 /* 172 * The following memcpy is safe because read_buf is always 173 * called with nbytes > avail, and the two cases above both 174 * guarantee p points to at least nbytes bytes. 175 */ 176 memcpy(p, argp->p, avail); 177 /* step to next page */ 178 argp->p = page_address(argp->pagelist[0]); 179 argp->pagelist++; 180 if (argp->pagelen < PAGE_SIZE) { 181 argp->end = p + (argp->pagelen>>2); 182 argp->pagelen = 0; 183 } else { 184 argp->end = p + (PAGE_SIZE>>2); 185 argp->pagelen -= PAGE_SIZE; 186 } 187 memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); 188 argp->p += XDR_QUADLEN(nbytes - avail); 189 return p; 190 } 191 192 static int zero_clientid(clientid_t *clid) 193 { 194 return (clid->cl_boot == 0) && (clid->cl_id == 0); 195 } 196 197 static int 198 defer_free(struct nfsd4_compoundargs *argp, 199 void (*release)(const void *), void *p) 200 { 201 struct tmpbuf *tb; 202 203 tb = kmalloc(sizeof(*tb), GFP_KERNEL); 204 if (!tb) 205 return -ENOMEM; 206 tb->buf = p; 207 tb->release = release; 208 tb->next = argp->to_free; 209 argp->to_free = tb; 210 return 0; 211 } 212 213 static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes) 214 { 215 if (p == argp->tmp) { 216 p = kmalloc(nbytes, GFP_KERNEL); 217 if (!p) 218 return NULL; 219 memcpy(p, argp->tmp, nbytes); 220 } else { 221 BUG_ON(p != argp->tmpp); 222 argp->tmpp = NULL; 223 } 224 if (defer_free(argp, kfree, p)) { 225 kfree(p); 226 return NULL; 227 } else 228 return (char *)p; 229 } 230 231 static __be32 232 nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) 233 { 234 u32 bmlen; 235 DECODE_HEAD; 236 237 bmval[0] = 0; 238 bmval[1] = 0; 239 bmval[2] = 0; 240 241 READ_BUF(4); 242 READ32(bmlen); 243 if (bmlen > 1000) 244 goto xdr_error; 245 246 READ_BUF(bmlen << 2); 247 if (bmlen > 0) 248 READ32(bmval[0]); 249 if (bmlen > 1) 250 READ32(bmval[1]); 251 if (bmlen > 2) 252 READ32(bmval[2]); 253 254 DECODE_TAIL; 255 } 256 257 static u32 nfsd_attrmask[] = { 258 NFSD_WRITEABLE_ATTRS_WORD0, 259 NFSD_WRITEABLE_ATTRS_WORD1, 260 NFSD_WRITEABLE_ATTRS_WORD2 261 }; 262 263 static u32 nfsd41_ex_attrmask[] = { 264 NFSD_SUPPATTR_EXCLCREAT_WORD0, 265 NFSD_SUPPATTR_EXCLCREAT_WORD1, 266 NFSD_SUPPATTR_EXCLCREAT_WORD2 267 }; 268 269 static __be32 270 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable, 271 struct iattr *iattr, struct nfs4_acl **acl) 272 { 273 int expected_len, len = 0; 274 u32 dummy32; 275 char *buf; 276 int host_err; 277 278 DECODE_HEAD; 279 iattr->ia_valid = 0; 280 if ((status = nfsd4_decode_bitmap(argp, bmval))) 281 return status; 282 283 /* 284 * According to spec, unsupported attributes return ERR_ATTRNOTSUPP; 285 * read-only attributes return ERR_INVAL. 286 */ 287 if ((bmval[0] & ~nfsd_suppattrs0(argp->minorversion)) || 288 (bmval[1] & ~nfsd_suppattrs1(argp->minorversion)) || 289 (bmval[2] & ~nfsd_suppattrs2(argp->minorversion))) 290 return nfserr_attrnotsupp; 291 if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) || 292 (bmval[2] & ~writable[2])) 293 return nfserr_inval; 294 295 READ_BUF(4); 296 READ32(expected_len); 297 298 if (bmval[0] & FATTR4_WORD0_SIZE) { 299 READ_BUF(8); 300 len += 8; 301 READ64(iattr->ia_size); 302 iattr->ia_valid |= ATTR_SIZE; 303 } 304 if (bmval[0] & FATTR4_WORD0_ACL) { 305 int nace; 306 struct nfs4_ace *ace; 307 308 READ_BUF(4); len += 4; 309 READ32(nace); 310 311 if (nace > NFS4_ACL_MAX) 312 return nfserr_resource; 313 314 *acl = nfs4_acl_new(nace); 315 if (*acl == NULL) { 316 host_err = -ENOMEM; 317 goto out_nfserr; 318 } 319 defer_free(argp, kfree, *acl); 320 321 (*acl)->naces = nace; 322 for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) { 323 READ_BUF(16); len += 16; 324 READ32(ace->type); 325 READ32(ace->flag); 326 READ32(ace->access_mask); 327 READ32(dummy32); 328 READ_BUF(dummy32); 329 len += XDR_QUADLEN(dummy32) << 2; 330 READMEM(buf, dummy32); 331 ace->whotype = nfs4_acl_get_whotype(buf, dummy32); 332 host_err = 0; 333 if (ace->whotype != NFS4_ACL_WHO_NAMED) 334 ace->who = 0; 335 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) 336 host_err = nfsd_map_name_to_gid(argp->rqstp, 337 buf, dummy32, &ace->who); 338 else 339 host_err = nfsd_map_name_to_uid(argp->rqstp, 340 buf, dummy32, &ace->who); 341 if (host_err) 342 goto out_nfserr; 343 } 344 } else 345 *acl = NULL; 346 if (bmval[1] & FATTR4_WORD1_MODE) { 347 READ_BUF(4); 348 len += 4; 349 READ32(iattr->ia_mode); 350 iattr->ia_mode &= (S_IFMT | S_IALLUGO); 351 iattr->ia_valid |= ATTR_MODE; 352 } 353 if (bmval[1] & FATTR4_WORD1_OWNER) { 354 READ_BUF(4); 355 len += 4; 356 READ32(dummy32); 357 READ_BUF(dummy32); 358 len += (XDR_QUADLEN(dummy32) << 2); 359 READMEM(buf, dummy32); 360 if ((host_err = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) 361 goto out_nfserr; 362 iattr->ia_valid |= ATTR_UID; 363 } 364 if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) { 365 READ_BUF(4); 366 len += 4; 367 READ32(dummy32); 368 READ_BUF(dummy32); 369 len += (XDR_QUADLEN(dummy32) << 2); 370 READMEM(buf, dummy32); 371 if ((host_err = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) 372 goto out_nfserr; 373 iattr->ia_valid |= ATTR_GID; 374 } 375 if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { 376 READ_BUF(4); 377 len += 4; 378 READ32(dummy32); 379 switch (dummy32) { 380 case NFS4_SET_TO_CLIENT_TIME: 381 /* We require the high 32 bits of 'seconds' to be 0, and we ignore 382 all 32 bits of 'nseconds'. */ 383 READ_BUF(12); 384 len += 12; 385 READ32(dummy32); 386 if (dummy32) 387 return nfserr_inval; 388 READ32(iattr->ia_atime.tv_sec); 389 READ32(iattr->ia_atime.tv_nsec); 390 if (iattr->ia_atime.tv_nsec >= (u32)1000000000) 391 return nfserr_inval; 392 iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET); 393 break; 394 case NFS4_SET_TO_SERVER_TIME: 395 iattr->ia_valid |= ATTR_ATIME; 396 break; 397 default: 398 goto xdr_error; 399 } 400 } 401 if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) { 402 READ_BUF(4); 403 len += 4; 404 READ32(dummy32); 405 switch (dummy32) { 406 case NFS4_SET_TO_CLIENT_TIME: 407 /* We require the high 32 bits of 'seconds' to be 0, and we ignore 408 all 32 bits of 'nseconds'. */ 409 READ_BUF(12); 410 len += 12; 411 READ32(dummy32); 412 if (dummy32) 413 return nfserr_inval; 414 READ32(iattr->ia_mtime.tv_sec); 415 READ32(iattr->ia_mtime.tv_nsec); 416 if (iattr->ia_mtime.tv_nsec >= (u32)1000000000) 417 return nfserr_inval; 418 iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET); 419 break; 420 case NFS4_SET_TO_SERVER_TIME: 421 iattr->ia_valid |= ATTR_MTIME; 422 break; 423 default: 424 goto xdr_error; 425 } 426 } 427 BUG_ON(bmval[2]); /* no such writeable attr supported yet */ 428 if (len != expected_len) 429 goto xdr_error; 430 431 DECODE_TAIL; 432 433 out_nfserr: 434 status = nfserrno(host_err); 435 goto out; 436 } 437 438 static __be32 439 nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid) 440 { 441 DECODE_HEAD; 442 443 READ_BUF(sizeof(stateid_t)); 444 READ32(sid->si_generation); 445 COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t)); 446 447 DECODE_TAIL; 448 } 449 450 static __be32 451 nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access) 452 { 453 DECODE_HEAD; 454 455 READ_BUF(4); 456 READ32(access->ac_req_access); 457 458 DECODE_TAIL; 459 } 460 461 static __be32 462 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) 463 { 464 DECODE_HEAD; 465 466 close->cl_stateowner = NULL; 467 READ_BUF(4); 468 READ32(close->cl_seqid); 469 return nfsd4_decode_stateid(argp, &close->cl_stateid); 470 471 DECODE_TAIL; 472 } 473 474 475 static __be32 476 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) 477 { 478 DECODE_HEAD; 479 480 READ_BUF(12); 481 READ64(commit->co_offset); 482 READ32(commit->co_count); 483 484 DECODE_TAIL; 485 } 486 487 static __be32 488 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) 489 { 490 DECODE_HEAD; 491 492 READ_BUF(4); 493 READ32(create->cr_type); 494 switch (create->cr_type) { 495 case NF4LNK: 496 READ_BUF(4); 497 READ32(create->cr_linklen); 498 READ_BUF(create->cr_linklen); 499 SAVEMEM(create->cr_linkname, create->cr_linklen); 500 break; 501 case NF4BLK: 502 case NF4CHR: 503 READ_BUF(8); 504 READ32(create->cr_specdata1); 505 READ32(create->cr_specdata2); 506 break; 507 case NF4SOCK: 508 case NF4FIFO: 509 case NF4DIR: 510 default: 511 break; 512 } 513 514 READ_BUF(4); 515 READ32(create->cr_namelen); 516 READ_BUF(create->cr_namelen); 517 SAVEMEM(create->cr_name, create->cr_namelen); 518 if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval))) 519 return status; 520 521 status = nfsd4_decode_fattr(argp, create->cr_bmval, nfsd_attrmask, 522 &create->cr_iattr, &create->cr_acl); 523 if (status) 524 goto out; 525 526 DECODE_TAIL; 527 } 528 529 static inline __be32 530 nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) 531 { 532 return nfsd4_decode_stateid(argp, &dr->dr_stateid); 533 } 534 535 static inline __be32 536 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) 537 { 538 return nfsd4_decode_bitmap(argp, getattr->ga_bmval); 539 } 540 541 static __be32 542 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) 543 { 544 DECODE_HEAD; 545 546 READ_BUF(4); 547 READ32(link->li_namelen); 548 READ_BUF(link->li_namelen); 549 SAVEMEM(link->li_name, link->li_namelen); 550 if ((status = check_filename(link->li_name, link->li_namelen, nfserr_inval))) 551 return status; 552 553 DECODE_TAIL; 554 } 555 556 static __be32 557 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) 558 { 559 DECODE_HEAD; 560 561 lock->lk_replay_owner = NULL; 562 /* 563 * type, reclaim(boolean), offset, length, new_lock_owner(boolean) 564 */ 565 READ_BUF(28); 566 READ32(lock->lk_type); 567 if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT)) 568 goto xdr_error; 569 READ32(lock->lk_reclaim); 570 READ64(lock->lk_offset); 571 READ64(lock->lk_length); 572 READ32(lock->lk_is_new); 573 574 if (lock->lk_is_new) { 575 READ_BUF(4); 576 READ32(lock->lk_new_open_seqid); 577 status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid); 578 if (status) 579 return status; 580 READ_BUF(8 + sizeof(clientid_t)); 581 READ32(lock->lk_new_lock_seqid); 582 COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t)); 583 READ32(lock->lk_new_owner.len); 584 READ_BUF(lock->lk_new_owner.len); 585 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len); 586 } else { 587 status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid); 588 if (status) 589 return status; 590 READ_BUF(4); 591 READ32(lock->lk_old_lock_seqid); 592 } 593 594 DECODE_TAIL; 595 } 596 597 static __be32 598 nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) 599 { 600 DECODE_HEAD; 601 602 READ_BUF(32); 603 READ32(lockt->lt_type); 604 if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT)) 605 goto xdr_error; 606 READ64(lockt->lt_offset); 607 READ64(lockt->lt_length); 608 COPYMEM(&lockt->lt_clientid, 8); 609 READ32(lockt->lt_owner.len); 610 READ_BUF(lockt->lt_owner.len); 611 READMEM(lockt->lt_owner.data, lockt->lt_owner.len); 612 613 if (argp->minorversion && !zero_clientid(&lockt->lt_clientid)) 614 return nfserr_inval; 615 DECODE_TAIL; 616 } 617 618 static __be32 619 nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) 620 { 621 DECODE_HEAD; 622 623 locku->lu_stateowner = NULL; 624 READ_BUF(8); 625 READ32(locku->lu_type); 626 if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT)) 627 goto xdr_error; 628 READ32(locku->lu_seqid); 629 status = nfsd4_decode_stateid(argp, &locku->lu_stateid); 630 if (status) 631 return status; 632 READ_BUF(16); 633 READ64(locku->lu_offset); 634 READ64(locku->lu_length); 635 636 DECODE_TAIL; 637 } 638 639 static __be32 640 nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup) 641 { 642 DECODE_HEAD; 643 644 READ_BUF(4); 645 READ32(lookup->lo_len); 646 READ_BUF(lookup->lo_len); 647 SAVEMEM(lookup->lo_name, lookup->lo_len); 648 if ((status = check_filename(lookup->lo_name, lookup->lo_len, nfserr_noent))) 649 return status; 650 651 DECODE_TAIL; 652 } 653 654 static __be32 655 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) 656 { 657 DECODE_HEAD; 658 659 memset(open->op_bmval, 0, sizeof(open->op_bmval)); 660 open->op_iattr.ia_valid = 0; 661 open->op_stateowner = NULL; 662 663 /* seqid, share_access, share_deny, clientid, ownerlen */ 664 READ_BUF(16 + sizeof(clientid_t)); 665 READ32(open->op_seqid); 666 READ32(open->op_share_access); 667 READ32(open->op_share_deny); 668 COPYMEM(&open->op_clientid, sizeof(clientid_t)); 669 READ32(open->op_owner.len); 670 671 /* owner, open_flag */ 672 READ_BUF(open->op_owner.len + 4); 673 SAVEMEM(open->op_owner.data, open->op_owner.len); 674 READ32(open->op_create); 675 switch (open->op_create) { 676 case NFS4_OPEN_NOCREATE: 677 break; 678 case NFS4_OPEN_CREATE: 679 READ_BUF(4); 680 READ32(open->op_createmode); 681 switch (open->op_createmode) { 682 case NFS4_CREATE_UNCHECKED: 683 case NFS4_CREATE_GUARDED: 684 status = nfsd4_decode_fattr(argp, open->op_bmval, 685 nfsd_attrmask, &open->op_iattr, &open->op_acl); 686 if (status) 687 goto out; 688 break; 689 case NFS4_CREATE_EXCLUSIVE: 690 READ_BUF(8); 691 COPYMEM(open->op_verf.data, 8); 692 break; 693 case NFS4_CREATE_EXCLUSIVE4_1: 694 if (argp->minorversion < 1) 695 goto xdr_error; 696 READ_BUF(8); 697 COPYMEM(open->op_verf.data, 8); 698 status = nfsd4_decode_fattr(argp, open->op_bmval, 699 nfsd41_ex_attrmask, &open->op_iattr, 700 &open->op_acl); 701 if (status) 702 goto out; 703 break; 704 default: 705 goto xdr_error; 706 } 707 break; 708 default: 709 goto xdr_error; 710 } 711 712 /* open_claim */ 713 READ_BUF(4); 714 READ32(open->op_claim_type); 715 switch (open->op_claim_type) { 716 case NFS4_OPEN_CLAIM_NULL: 717 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 718 READ_BUF(4); 719 READ32(open->op_fname.len); 720 READ_BUF(open->op_fname.len); 721 SAVEMEM(open->op_fname.data, open->op_fname.len); 722 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval))) 723 return status; 724 break; 725 case NFS4_OPEN_CLAIM_PREVIOUS: 726 READ_BUF(4); 727 READ32(open->op_delegate_type); 728 break; 729 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 730 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid); 731 if (status) 732 return status; 733 READ_BUF(4); 734 READ32(open->op_fname.len); 735 READ_BUF(open->op_fname.len); 736 SAVEMEM(open->op_fname.data, open->op_fname.len); 737 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval))) 738 return status; 739 break; 740 default: 741 goto xdr_error; 742 } 743 744 DECODE_TAIL; 745 } 746 747 static __be32 748 nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) 749 { 750 DECODE_HEAD; 751 752 open_conf->oc_stateowner = NULL; 753 status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid); 754 if (status) 755 return status; 756 READ_BUF(4); 757 READ32(open_conf->oc_seqid); 758 759 DECODE_TAIL; 760 } 761 762 static __be32 763 nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) 764 { 765 DECODE_HEAD; 766 767 open_down->od_stateowner = NULL; 768 status = nfsd4_decode_stateid(argp, &open_down->od_stateid); 769 if (status) 770 return status; 771 READ_BUF(12); 772 READ32(open_down->od_seqid); 773 READ32(open_down->od_share_access); 774 READ32(open_down->od_share_deny); 775 776 DECODE_TAIL; 777 } 778 779 static __be32 780 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) 781 { 782 DECODE_HEAD; 783 784 READ_BUF(4); 785 READ32(putfh->pf_fhlen); 786 if (putfh->pf_fhlen > NFS4_FHSIZE) 787 goto xdr_error; 788 READ_BUF(putfh->pf_fhlen); 789 SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen); 790 791 DECODE_TAIL; 792 } 793 794 static __be32 795 nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) 796 { 797 DECODE_HEAD; 798 799 status = nfsd4_decode_stateid(argp, &read->rd_stateid); 800 if (status) 801 return status; 802 READ_BUF(12); 803 READ64(read->rd_offset); 804 READ32(read->rd_length); 805 806 DECODE_TAIL; 807 } 808 809 static __be32 810 nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir) 811 { 812 DECODE_HEAD; 813 814 READ_BUF(24); 815 READ64(readdir->rd_cookie); 816 COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data)); 817 READ32(readdir->rd_dircount); /* just in case you needed a useless field... */ 818 READ32(readdir->rd_maxcount); 819 if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval))) 820 goto out; 821 822 DECODE_TAIL; 823 } 824 825 static __be32 826 nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove) 827 { 828 DECODE_HEAD; 829 830 READ_BUF(4); 831 READ32(remove->rm_namelen); 832 READ_BUF(remove->rm_namelen); 833 SAVEMEM(remove->rm_name, remove->rm_namelen); 834 if ((status = check_filename(remove->rm_name, remove->rm_namelen, nfserr_noent))) 835 return status; 836 837 DECODE_TAIL; 838 } 839 840 static __be32 841 nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename) 842 { 843 DECODE_HEAD; 844 845 READ_BUF(4); 846 READ32(rename->rn_snamelen); 847 READ_BUF(rename->rn_snamelen + 4); 848 SAVEMEM(rename->rn_sname, rename->rn_snamelen); 849 READ32(rename->rn_tnamelen); 850 READ_BUF(rename->rn_tnamelen); 851 SAVEMEM(rename->rn_tname, rename->rn_tnamelen); 852 if ((status = check_filename(rename->rn_sname, rename->rn_snamelen, nfserr_noent))) 853 return status; 854 if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen, nfserr_inval))) 855 return status; 856 857 DECODE_TAIL; 858 } 859 860 static __be32 861 nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) 862 { 863 DECODE_HEAD; 864 865 READ_BUF(sizeof(clientid_t)); 866 COPYMEM(clientid, sizeof(clientid_t)); 867 868 DECODE_TAIL; 869 } 870 871 static __be32 872 nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp, 873 struct nfsd4_secinfo *secinfo) 874 { 875 DECODE_HEAD; 876 877 READ_BUF(4); 878 READ32(secinfo->si_namelen); 879 READ_BUF(secinfo->si_namelen); 880 SAVEMEM(secinfo->si_name, secinfo->si_namelen); 881 status = check_filename(secinfo->si_name, secinfo->si_namelen, 882 nfserr_noent); 883 if (status) 884 return status; 885 DECODE_TAIL; 886 } 887 888 static __be32 889 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) 890 { 891 __be32 status; 892 893 status = nfsd4_decode_stateid(argp, &setattr->sa_stateid); 894 if (status) 895 return status; 896 return nfsd4_decode_fattr(argp, setattr->sa_bmval, nfsd_attrmask, 897 &setattr->sa_iattr, &setattr->sa_acl); 898 } 899 900 static __be32 901 nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid) 902 { 903 DECODE_HEAD; 904 905 READ_BUF(12); 906 COPYMEM(setclientid->se_verf.data, 8); 907 READ32(setclientid->se_namelen); 908 909 READ_BUF(setclientid->se_namelen + 8); 910 SAVEMEM(setclientid->se_name, setclientid->se_namelen); 911 READ32(setclientid->se_callback_prog); 912 READ32(setclientid->se_callback_netid_len); 913 914 READ_BUF(setclientid->se_callback_netid_len + 4); 915 SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len); 916 READ32(setclientid->se_callback_addr_len); 917 918 READ_BUF(setclientid->se_callback_addr_len + 4); 919 SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len); 920 READ32(setclientid->se_callback_ident); 921 922 DECODE_TAIL; 923 } 924 925 static __be32 926 nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c) 927 { 928 DECODE_HEAD; 929 930 READ_BUF(8 + sizeof(nfs4_verifier)); 931 COPYMEM(&scd_c->sc_clientid, 8); 932 COPYMEM(&scd_c->sc_confirm, sizeof(nfs4_verifier)); 933 934 DECODE_TAIL; 935 } 936 937 /* Also used for NVERIFY */ 938 static __be32 939 nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) 940 { 941 #if 0 942 struct nfsd4_compoundargs save = { 943 .p = argp->p, 944 .end = argp->end, 945 .rqstp = argp->rqstp, 946 }; 947 u32 ve_bmval[2]; 948 struct iattr ve_iattr; /* request */ 949 struct nfs4_acl *ve_acl; /* request */ 950 #endif 951 DECODE_HEAD; 952 953 if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval))) 954 goto out; 955 956 /* For convenience's sake, we compare raw xdr'd attributes in 957 * nfsd4_proc_verify; however we still decode here just to return 958 * correct error in case of bad xdr. */ 959 #if 0 960 status = nfsd4_decode_fattr(ve_bmval, &ve_iattr, &ve_acl); 961 if (status == nfserr_inval) { 962 status = nfserrno(status); 963 goto out; 964 } 965 #endif 966 READ_BUF(4); 967 READ32(verify->ve_attrlen); 968 READ_BUF(verify->ve_attrlen); 969 SAVEMEM(verify->ve_attrval, verify->ve_attrlen); 970 971 DECODE_TAIL; 972 } 973 974 static __be32 975 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) 976 { 977 int avail; 978 int v; 979 int len; 980 DECODE_HEAD; 981 982 status = nfsd4_decode_stateid(argp, &write->wr_stateid); 983 if (status) 984 return status; 985 READ_BUF(16); 986 READ64(write->wr_offset); 987 READ32(write->wr_stable_how); 988 if (write->wr_stable_how > 2) 989 goto xdr_error; 990 READ32(write->wr_buflen); 991 992 /* Sorry .. no magic macros for this.. * 993 * READ_BUF(write->wr_buflen); 994 * SAVEMEM(write->wr_buf, write->wr_buflen); 995 */ 996 avail = (char*)argp->end - (char*)argp->p; 997 if (avail + argp->pagelen < write->wr_buflen) { 998 dprintk("NFSD: xdr error (%s:%d)\n", 999 __FILE__, __LINE__); 1000 goto xdr_error; 1001 } 1002 argp->rqstp->rq_vec[0].iov_base = p; 1003 argp->rqstp->rq_vec[0].iov_len = avail; 1004 v = 0; 1005 len = write->wr_buflen; 1006 while (len > argp->rqstp->rq_vec[v].iov_len) { 1007 len -= argp->rqstp->rq_vec[v].iov_len; 1008 v++; 1009 argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]); 1010 argp->pagelist++; 1011 if (argp->pagelen >= PAGE_SIZE) { 1012 argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE; 1013 argp->pagelen -= PAGE_SIZE; 1014 } else { 1015 argp->rqstp->rq_vec[v].iov_len = argp->pagelen; 1016 argp->pagelen -= len; 1017 } 1018 } 1019 argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len); 1020 argp->p = (__be32*) (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2)); 1021 argp->rqstp->rq_vec[v].iov_len = len; 1022 write->wr_vlen = v+1; 1023 1024 DECODE_TAIL; 1025 } 1026 1027 static __be32 1028 nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner) 1029 { 1030 DECODE_HEAD; 1031 1032 READ_BUF(12); 1033 COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t)); 1034 READ32(rlockowner->rl_owner.len); 1035 READ_BUF(rlockowner->rl_owner.len); 1036 READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len); 1037 1038 if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid)) 1039 return nfserr_inval; 1040 DECODE_TAIL; 1041 } 1042 1043 static __be32 1044 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, 1045 struct nfsd4_exchange_id *exid) 1046 { 1047 int dummy; 1048 DECODE_HEAD; 1049 1050 READ_BUF(NFS4_VERIFIER_SIZE); 1051 COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE); 1052 1053 READ_BUF(4); 1054 READ32(exid->clname.len); 1055 1056 READ_BUF(exid->clname.len); 1057 SAVEMEM(exid->clname.data, exid->clname.len); 1058 1059 READ_BUF(4); 1060 READ32(exid->flags); 1061 1062 /* Ignore state_protect4_a */ 1063 READ_BUF(4); 1064 READ32(exid->spa_how); 1065 switch (exid->spa_how) { 1066 case SP4_NONE: 1067 break; 1068 case SP4_MACH_CRED: 1069 /* spo_must_enforce */ 1070 READ_BUF(4); 1071 READ32(dummy); 1072 READ_BUF(dummy * 4); 1073 p += dummy; 1074 1075 /* spo_must_allow */ 1076 READ_BUF(4); 1077 READ32(dummy); 1078 READ_BUF(dummy * 4); 1079 p += dummy; 1080 break; 1081 case SP4_SSV: 1082 /* ssp_ops */ 1083 READ_BUF(4); 1084 READ32(dummy); 1085 READ_BUF(dummy * 4); 1086 p += dummy; 1087 1088 READ_BUF(4); 1089 READ32(dummy); 1090 READ_BUF(dummy * 4); 1091 p += dummy; 1092 1093 /* ssp_hash_algs<> */ 1094 READ_BUF(4); 1095 READ32(dummy); 1096 READ_BUF(dummy); 1097 p += XDR_QUADLEN(dummy); 1098 1099 /* ssp_encr_algs<> */ 1100 READ_BUF(4); 1101 READ32(dummy); 1102 READ_BUF(dummy); 1103 p += XDR_QUADLEN(dummy); 1104 1105 /* ssp_window and ssp_num_gss_handles */ 1106 READ_BUF(8); 1107 READ32(dummy); 1108 READ32(dummy); 1109 break; 1110 default: 1111 goto xdr_error; 1112 } 1113 1114 /* Ignore Implementation ID */ 1115 READ_BUF(4); /* nfs_impl_id4 array length */ 1116 READ32(dummy); 1117 1118 if (dummy > 1) 1119 goto xdr_error; 1120 1121 if (dummy == 1) { 1122 /* nii_domain */ 1123 READ_BUF(4); 1124 READ32(dummy); 1125 READ_BUF(dummy); 1126 p += XDR_QUADLEN(dummy); 1127 1128 /* nii_name */ 1129 READ_BUF(4); 1130 READ32(dummy); 1131 READ_BUF(dummy); 1132 p += XDR_QUADLEN(dummy); 1133 1134 /* nii_date */ 1135 READ_BUF(12); 1136 p += 3; 1137 } 1138 DECODE_TAIL; 1139 } 1140 1141 static __be32 1142 nfsd4_decode_create_session(struct nfsd4_compoundargs *argp, 1143 struct nfsd4_create_session *sess) 1144 { 1145 DECODE_HEAD; 1146 1147 u32 dummy; 1148 char *machine_name; 1149 int i; 1150 int nr_secflavs; 1151 1152 READ_BUF(16); 1153 COPYMEM(&sess->clientid, 8); 1154 READ32(sess->seqid); 1155 READ32(sess->flags); 1156 1157 /* Fore channel attrs */ 1158 READ_BUF(28); 1159 READ32(dummy); /* headerpadsz is always 0 */ 1160 READ32(sess->fore_channel.maxreq_sz); 1161 READ32(sess->fore_channel.maxresp_sz); 1162 READ32(sess->fore_channel.maxresp_cached); 1163 READ32(sess->fore_channel.maxops); 1164 READ32(sess->fore_channel.maxreqs); 1165 READ32(sess->fore_channel.nr_rdma_attrs); 1166 if (sess->fore_channel.nr_rdma_attrs == 1) { 1167 READ_BUF(4); 1168 READ32(sess->fore_channel.rdma_attrs); 1169 } else if (sess->fore_channel.nr_rdma_attrs > 1) { 1170 dprintk("Too many fore channel attr bitmaps!\n"); 1171 goto xdr_error; 1172 } 1173 1174 /* Back channel attrs */ 1175 READ_BUF(28); 1176 READ32(dummy); /* headerpadsz is always 0 */ 1177 READ32(sess->back_channel.maxreq_sz); 1178 READ32(sess->back_channel.maxresp_sz); 1179 READ32(sess->back_channel.maxresp_cached); 1180 READ32(sess->back_channel.maxops); 1181 READ32(sess->back_channel.maxreqs); 1182 READ32(sess->back_channel.nr_rdma_attrs); 1183 if (sess->back_channel.nr_rdma_attrs == 1) { 1184 READ_BUF(4); 1185 READ32(sess->back_channel.rdma_attrs); 1186 } else if (sess->back_channel.nr_rdma_attrs > 1) { 1187 dprintk("Too many back channel attr bitmaps!\n"); 1188 goto xdr_error; 1189 } 1190 1191 READ_BUF(8); 1192 READ32(sess->callback_prog); 1193 1194 /* callback_sec_params4 */ 1195 READ32(nr_secflavs); 1196 for (i = 0; i < nr_secflavs; ++i) { 1197 READ_BUF(4); 1198 READ32(dummy); 1199 switch (dummy) { 1200 case RPC_AUTH_NULL: 1201 /* Nothing to read */ 1202 break; 1203 case RPC_AUTH_UNIX: 1204 READ_BUF(8); 1205 /* stamp */ 1206 READ32(dummy); 1207 1208 /* machine name */ 1209 READ32(dummy); 1210 READ_BUF(dummy); 1211 SAVEMEM(machine_name, dummy); 1212 1213 /* uid, gid */ 1214 READ_BUF(8); 1215 READ32(sess->uid); 1216 READ32(sess->gid); 1217 1218 /* more gids */ 1219 READ_BUF(4); 1220 READ32(dummy); 1221 READ_BUF(dummy * 4); 1222 for (i = 0; i < dummy; ++i) 1223 READ32(dummy); 1224 break; 1225 case RPC_AUTH_GSS: 1226 dprintk("RPC_AUTH_GSS callback secflavor " 1227 "not supported!\n"); 1228 READ_BUF(8); 1229 /* gcbp_service */ 1230 READ32(dummy); 1231 /* gcbp_handle_from_server */ 1232 READ32(dummy); 1233 READ_BUF(dummy); 1234 p += XDR_QUADLEN(dummy); 1235 /* gcbp_handle_from_client */ 1236 READ_BUF(4); 1237 READ32(dummy); 1238 READ_BUF(dummy); 1239 p += XDR_QUADLEN(dummy); 1240 break; 1241 default: 1242 dprintk("Illegal callback secflavor\n"); 1243 return nfserr_inval; 1244 } 1245 } 1246 DECODE_TAIL; 1247 } 1248 1249 static __be32 1250 nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp, 1251 struct nfsd4_destroy_session *destroy_session) 1252 { 1253 DECODE_HEAD; 1254 READ_BUF(NFS4_MAX_SESSIONID_LEN); 1255 COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN); 1256 1257 DECODE_TAIL; 1258 } 1259 1260 static __be32 1261 nfsd4_decode_sequence(struct nfsd4_compoundargs *argp, 1262 struct nfsd4_sequence *seq) 1263 { 1264 DECODE_HEAD; 1265 1266 READ_BUF(NFS4_MAX_SESSIONID_LEN + 16); 1267 COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN); 1268 READ32(seq->seqid); 1269 READ32(seq->slotid); 1270 READ32(seq->maxslots); 1271 READ32(seq->cachethis); 1272 1273 DECODE_TAIL; 1274 } 1275 1276 static __be32 1277 nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p) 1278 { 1279 return nfs_ok; 1280 } 1281 1282 static __be32 1283 nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p) 1284 { 1285 return nfserr_notsupp; 1286 } 1287 1288 typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *); 1289 1290 static nfsd4_dec nfsd4_dec_ops[] = { 1291 [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, 1292 [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, 1293 [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, 1294 [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create, 1295 [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp, 1296 [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn, 1297 [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr, 1298 [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop, 1299 [OP_LINK] = (nfsd4_dec)nfsd4_decode_link, 1300 [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock, 1301 [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt, 1302 [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku, 1303 [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup, 1304 [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop, 1305 [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify, 1306 [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open, 1307 [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp, 1308 [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, 1309 [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, 1310 [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, 1311 [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_noop, 1312 [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, 1313 [OP_READ] = (nfsd4_dec)nfsd4_decode_read, 1314 [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, 1315 [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop, 1316 [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove, 1317 [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename, 1318 [OP_RENEW] = (nfsd4_dec)nfsd4_decode_renew, 1319 [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop, 1320 [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop, 1321 [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo, 1322 [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr, 1323 [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_setclientid, 1324 [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm, 1325 [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, 1326 [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, 1327 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, 1328 }; 1329 1330 static nfsd4_dec nfsd41_dec_ops[] = { 1331 [OP_ACCESS] (nfsd4_dec)nfsd4_decode_access, 1332 [OP_CLOSE] (nfsd4_dec)nfsd4_decode_close, 1333 [OP_COMMIT] (nfsd4_dec)nfsd4_decode_commit, 1334 [OP_CREATE] (nfsd4_dec)nfsd4_decode_create, 1335 [OP_DELEGPURGE] (nfsd4_dec)nfsd4_decode_notsupp, 1336 [OP_DELEGRETURN] (nfsd4_dec)nfsd4_decode_delegreturn, 1337 [OP_GETATTR] (nfsd4_dec)nfsd4_decode_getattr, 1338 [OP_GETFH] (nfsd4_dec)nfsd4_decode_noop, 1339 [OP_LINK] (nfsd4_dec)nfsd4_decode_link, 1340 [OP_LOCK] (nfsd4_dec)nfsd4_decode_lock, 1341 [OP_LOCKT] (nfsd4_dec)nfsd4_decode_lockt, 1342 [OP_LOCKU] (nfsd4_dec)nfsd4_decode_locku, 1343 [OP_LOOKUP] (nfsd4_dec)nfsd4_decode_lookup, 1344 [OP_LOOKUPP] (nfsd4_dec)nfsd4_decode_noop, 1345 [OP_NVERIFY] (nfsd4_dec)nfsd4_decode_verify, 1346 [OP_OPEN] (nfsd4_dec)nfsd4_decode_open, 1347 [OP_OPENATTR] (nfsd4_dec)nfsd4_decode_notsupp, 1348 [OP_OPEN_CONFIRM] (nfsd4_dec)nfsd4_decode_notsupp, 1349 [OP_OPEN_DOWNGRADE] (nfsd4_dec)nfsd4_decode_open_downgrade, 1350 [OP_PUTFH] (nfsd4_dec)nfsd4_decode_putfh, 1351 [OP_PUTPUBFH] (nfsd4_dec)nfsd4_decode_notsupp, 1352 [OP_PUTROOTFH] (nfsd4_dec)nfsd4_decode_noop, 1353 [OP_READ] (nfsd4_dec)nfsd4_decode_read, 1354 [OP_READDIR] (nfsd4_dec)nfsd4_decode_readdir, 1355 [OP_READLINK] (nfsd4_dec)nfsd4_decode_noop, 1356 [OP_REMOVE] (nfsd4_dec)nfsd4_decode_remove, 1357 [OP_RENAME] (nfsd4_dec)nfsd4_decode_rename, 1358 [OP_RENEW] (nfsd4_dec)nfsd4_decode_notsupp, 1359 [OP_RESTOREFH] (nfsd4_dec)nfsd4_decode_noop, 1360 [OP_SAVEFH] (nfsd4_dec)nfsd4_decode_noop, 1361 [OP_SECINFO] (nfsd4_dec)nfsd4_decode_secinfo, 1362 [OP_SETATTR] (nfsd4_dec)nfsd4_decode_setattr, 1363 [OP_SETCLIENTID] (nfsd4_dec)nfsd4_decode_notsupp, 1364 [OP_SETCLIENTID_CONFIRM](nfsd4_dec)nfsd4_decode_notsupp, 1365 [OP_VERIFY] (nfsd4_dec)nfsd4_decode_verify, 1366 [OP_WRITE] (nfsd4_dec)nfsd4_decode_write, 1367 [OP_RELEASE_LOCKOWNER] (nfsd4_dec)nfsd4_decode_notsupp, 1368 1369 /* new operations for NFSv4.1 */ 1370 [OP_BACKCHANNEL_CTL] (nfsd4_dec)nfsd4_decode_notsupp, 1371 [OP_BIND_CONN_TO_SESSION](nfsd4_dec)nfsd4_decode_notsupp, 1372 [OP_EXCHANGE_ID] (nfsd4_dec)nfsd4_decode_exchange_id, 1373 [OP_CREATE_SESSION] (nfsd4_dec)nfsd4_decode_create_session, 1374 [OP_DESTROY_SESSION] (nfsd4_dec)nfsd4_decode_destroy_session, 1375 [OP_FREE_STATEID] (nfsd4_dec)nfsd4_decode_notsupp, 1376 [OP_GET_DIR_DELEGATION] (nfsd4_dec)nfsd4_decode_notsupp, 1377 [OP_GETDEVICEINFO] (nfsd4_dec)nfsd4_decode_notsupp, 1378 [OP_GETDEVICELIST] (nfsd4_dec)nfsd4_decode_notsupp, 1379 [OP_LAYOUTCOMMIT] (nfsd4_dec)nfsd4_decode_notsupp, 1380 [OP_LAYOUTGET] (nfsd4_dec)nfsd4_decode_notsupp, 1381 [OP_LAYOUTRETURN] (nfsd4_dec)nfsd4_decode_notsupp, 1382 [OP_SECINFO_NO_NAME] (nfsd4_dec)nfsd4_decode_notsupp, 1383 [OP_SEQUENCE] (nfsd4_dec)nfsd4_decode_sequence, 1384 [OP_SET_SSV] (nfsd4_dec)nfsd4_decode_notsupp, 1385 [OP_TEST_STATEID] (nfsd4_dec)nfsd4_decode_notsupp, 1386 [OP_WANT_DELEGATION] (nfsd4_dec)nfsd4_decode_notsupp, 1387 [OP_DESTROY_CLIENTID] (nfsd4_dec)nfsd4_decode_notsupp, 1388 [OP_RECLAIM_COMPLETE] (nfsd4_dec)nfsd4_decode_notsupp, 1389 }; 1390 1391 struct nfsd4_minorversion_ops { 1392 nfsd4_dec *decoders; 1393 int nops; 1394 }; 1395 1396 static struct nfsd4_minorversion_ops nfsd4_minorversion[] = { 1397 [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) }, 1398 [1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) }, 1399 }; 1400 1401 static __be32 1402 nfsd4_decode_compound(struct nfsd4_compoundargs *argp) 1403 { 1404 DECODE_HEAD; 1405 struct nfsd4_op *op; 1406 struct nfsd4_minorversion_ops *ops; 1407 int i; 1408 1409 /* 1410 * XXX: According to spec, we should check the tag 1411 * for UTF-8 compliance. I'm postponing this for 1412 * now because it seems that some clients do use 1413 * binary tags. 1414 */ 1415 READ_BUF(4); 1416 READ32(argp->taglen); 1417 READ_BUF(argp->taglen + 8); 1418 SAVEMEM(argp->tag, argp->taglen); 1419 READ32(argp->minorversion); 1420 READ32(argp->opcnt); 1421 1422 if (argp->taglen > NFSD4_MAX_TAGLEN) 1423 goto xdr_error; 1424 if (argp->opcnt > 100) 1425 goto xdr_error; 1426 1427 if (argp->opcnt > ARRAY_SIZE(argp->iops)) { 1428 argp->ops = kmalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL); 1429 if (!argp->ops) { 1430 argp->ops = argp->iops; 1431 dprintk("nfsd: couldn't allocate room for COMPOUND\n"); 1432 goto xdr_error; 1433 } 1434 } 1435 1436 if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion)) 1437 argp->opcnt = 0; 1438 1439 ops = &nfsd4_minorversion[argp->minorversion]; 1440 for (i = 0; i < argp->opcnt; i++) { 1441 op = &argp->ops[i]; 1442 op->replay = NULL; 1443 1444 /* 1445 * We can't use READ_BUF() here because we need to handle 1446 * a missing opcode as an OP_WRITE + 1. So we need to check 1447 * to see if we're truly at the end of our buffer or if there 1448 * is another page we need to flip to. 1449 */ 1450 1451 if (argp->p == argp->end) { 1452 if (argp->pagelen < 4) { 1453 /* There isn't an opcode still on the wire */ 1454 op->opnum = OP_WRITE + 1; 1455 op->status = nfserr_bad_xdr; 1456 argp->opcnt = i+1; 1457 break; 1458 } 1459 1460 /* 1461 * False alarm. We just hit a page boundary, but there 1462 * is still data available. Move pointer across page 1463 * boundary. *snip from READ_BUF* 1464 */ 1465 argp->p = page_address(argp->pagelist[0]); 1466 argp->pagelist++; 1467 if (argp->pagelen < PAGE_SIZE) { 1468 argp->end = p + (argp->pagelen>>2); 1469 argp->pagelen = 0; 1470 } else { 1471 argp->end = p + (PAGE_SIZE>>2); 1472 argp->pagelen -= PAGE_SIZE; 1473 } 1474 } 1475 op->opnum = ntohl(*argp->p++); 1476 1477 if (op->opnum >= OP_ACCESS && op->opnum < ops->nops) 1478 op->status = ops->decoders[op->opnum](argp, &op->u); 1479 else { 1480 op->opnum = OP_ILLEGAL; 1481 op->status = nfserr_op_illegal; 1482 } 1483 1484 if (op->status) { 1485 argp->opcnt = i+1; 1486 break; 1487 } 1488 } 1489 1490 DECODE_TAIL; 1491 } 1492 /* 1493 * END OF "GENERIC" DECODE ROUTINES. 1494 */ 1495 1496 /* 1497 * START OF "GENERIC" ENCODE ROUTINES. 1498 * These may look a little ugly since they are imported from a "generic" 1499 * set of XDR encode/decode routines which are intended to be shared by 1500 * all of our NFSv4 implementations (OpenBSD, MacOS X...). 1501 * 1502 * If the pain of reading these is too great, it should be a straightforward 1503 * task to translate them into Linux-specific versions which are more 1504 * consistent with the style used in NFSv2/v3... 1505 */ 1506 #define ENCODE_HEAD __be32 *p 1507 1508 #define WRITE32(n) *p++ = htonl(n) 1509 #define WRITE64(n) do { \ 1510 *p++ = htonl((u32)((n) >> 32)); \ 1511 *p++ = htonl((u32)(n)); \ 1512 } while (0) 1513 #define WRITEMEM(ptr,nbytes) do { if (nbytes > 0) { \ 1514 *(p + XDR_QUADLEN(nbytes) -1) = 0; \ 1515 memcpy(p, ptr, nbytes); \ 1516 p += XDR_QUADLEN(nbytes); \ 1517 }} while (0) 1518 #define WRITECINFO(c) do { \ 1519 *p++ = htonl(c.atomic); \ 1520 *p++ = htonl(c.before_ctime_sec); \ 1521 *p++ = htonl(c.before_ctime_nsec); \ 1522 *p++ = htonl(c.after_ctime_sec); \ 1523 *p++ = htonl(c.after_ctime_nsec); \ 1524 } while (0) 1525 1526 #define RESERVE_SPACE(nbytes) do { \ 1527 p = resp->p; \ 1528 BUG_ON(p + XDR_QUADLEN(nbytes) > resp->end); \ 1529 } while (0) 1530 #define ADJUST_ARGS() resp->p = p 1531 1532 /* 1533 * Header routine to setup seqid operation replay cache 1534 */ 1535 #define ENCODE_SEQID_OP_HEAD \ 1536 __be32 *save; \ 1537 \ 1538 save = resp->p; 1539 1540 /* 1541 * Routine for encoding the result of a "seqid-mutating" NFSv4 operation. This 1542 * is where sequence id's are incremented, and the replay cache is filled. 1543 * Note that we increment sequence id's here, at the last moment, so we're sure 1544 * we know whether the error to be returned is a sequence id mutating error. 1545 */ 1546 1547 #define ENCODE_SEQID_OP_TAIL(stateowner) do { \ 1548 if (seqid_mutating_err(nfserr) && stateowner) { \ 1549 stateowner->so_seqid++; \ 1550 stateowner->so_replay.rp_status = nfserr; \ 1551 stateowner->so_replay.rp_buflen = \ 1552 (((char *)(resp)->p - (char *)save)); \ 1553 memcpy(stateowner->so_replay.rp_buf, save, \ 1554 stateowner->so_replay.rp_buflen); \ 1555 } } while (0); 1556 1557 /* Encode as an array of strings the string given with components 1558 * seperated @sep. 1559 */ 1560 static __be32 nfsd4_encode_components(char sep, char *components, 1561 __be32 **pp, int *buflen) 1562 { 1563 __be32 *p = *pp; 1564 __be32 *countp = p; 1565 int strlen, count=0; 1566 char *str, *end; 1567 1568 dprintk("nfsd4_encode_components(%s)\n", components); 1569 if ((*buflen -= 4) < 0) 1570 return nfserr_resource; 1571 WRITE32(0); /* We will fill this in with @count later */ 1572 end = str = components; 1573 while (*end) { 1574 for (; *end && (*end != sep); end++) 1575 ; /* Point to end of component */ 1576 strlen = end - str; 1577 if (strlen) { 1578 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0) 1579 return nfserr_resource; 1580 WRITE32(strlen); 1581 WRITEMEM(str, strlen); 1582 count++; 1583 } 1584 else 1585 end++; 1586 str = end; 1587 } 1588 *pp = p; 1589 p = countp; 1590 WRITE32(count); 1591 return 0; 1592 } 1593 1594 /* 1595 * encode a location element of a fs_locations structure 1596 */ 1597 static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location, 1598 __be32 **pp, int *buflen) 1599 { 1600 __be32 status; 1601 __be32 *p = *pp; 1602 1603 status = nfsd4_encode_components(':', location->hosts, &p, buflen); 1604 if (status) 1605 return status; 1606 status = nfsd4_encode_components('/', location->path, &p, buflen); 1607 if (status) 1608 return status; 1609 *pp = p; 1610 return 0; 1611 } 1612 1613 /* 1614 * Return the path to an export point in the pseudo filesystem namespace 1615 * Returned string is safe to use as long as the caller holds a reference 1616 * to @exp. 1617 */ 1618 static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat) 1619 { 1620 struct svc_fh tmp_fh; 1621 char *path, *rootpath; 1622 1623 fh_init(&tmp_fh, NFS4_FHSIZE); 1624 *stat = exp_pseudoroot(rqstp, &tmp_fh); 1625 if (*stat) 1626 return NULL; 1627 rootpath = tmp_fh.fh_export->ex_pathname; 1628 1629 path = exp->ex_pathname; 1630 1631 if (strncmp(path, rootpath, strlen(rootpath))) { 1632 dprintk("nfsd: fs_locations failed;" 1633 "%s is not contained in %s\n", path, rootpath); 1634 *stat = nfserr_notsupp; 1635 return NULL; 1636 } 1637 1638 return path + strlen(rootpath); 1639 } 1640 1641 /* 1642 * encode a fs_locations structure 1643 */ 1644 static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp, 1645 struct svc_export *exp, 1646 __be32 **pp, int *buflen) 1647 { 1648 __be32 status; 1649 int i; 1650 __be32 *p = *pp; 1651 struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs; 1652 char *root = nfsd4_path(rqstp, exp, &status); 1653 1654 if (status) 1655 return status; 1656 status = nfsd4_encode_components('/', root, &p, buflen); 1657 if (status) 1658 return status; 1659 if ((*buflen -= 4) < 0) 1660 return nfserr_resource; 1661 WRITE32(fslocs->locations_count); 1662 for (i=0; i<fslocs->locations_count; i++) { 1663 status = nfsd4_encode_fs_location4(&fslocs->locations[i], 1664 &p, buflen); 1665 if (status) 1666 return status; 1667 } 1668 *pp = p; 1669 return 0; 1670 } 1671 1672 static u32 nfs4_ftypes[16] = { 1673 NF4BAD, NF4FIFO, NF4CHR, NF4BAD, 1674 NF4DIR, NF4BAD, NF4BLK, NF4BAD, 1675 NF4REG, NF4BAD, NF4LNK, NF4BAD, 1676 NF4SOCK, NF4BAD, NF4LNK, NF4BAD, 1677 }; 1678 1679 static __be32 1680 nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1681 __be32 **p, int *buflen) 1682 { 1683 int status; 1684 1685 if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4) 1686 return nfserr_resource; 1687 if (whotype != NFS4_ACL_WHO_NAMED) 1688 status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1)); 1689 else if (group) 1690 status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1)); 1691 else 1692 status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1)); 1693 if (status < 0) 1694 return nfserrno(status); 1695 *p = xdr_encode_opaque(*p, NULL, status); 1696 *buflen -= (XDR_QUADLEN(status) << 2) + 4; 1697 BUG_ON(*buflen < 0); 1698 return 0; 1699 } 1700 1701 static inline __be32 1702 nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen) 1703 { 1704 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen); 1705 } 1706 1707 static inline __be32 1708 nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen) 1709 { 1710 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen); 1711 } 1712 1713 static inline __be32 1714 nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1715 __be32 **p, int *buflen) 1716 { 1717 return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); 1718 } 1719 1720 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ 1721 FATTR4_WORD0_RDATTR_ERROR) 1722 #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID 1723 1724 static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err) 1725 { 1726 /* As per referral draft: */ 1727 if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS || 1728 *bmval1 & ~WORD1_ABSENT_FS_ATTRS) { 1729 if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR || 1730 *bmval0 & FATTR4_WORD0_FS_LOCATIONS) 1731 *rdattr_err = NFSERR_MOVED; 1732 else 1733 return nfserr_moved; 1734 } 1735 *bmval0 &= WORD0_ABSENT_FS_ATTRS; 1736 *bmval1 &= WORD1_ABSENT_FS_ATTRS; 1737 return 0; 1738 } 1739 1740 /* 1741 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle 1742 * ourselves. 1743 * 1744 * @countp is the buffer size in _words_; upon successful return this becomes 1745 * replaced with the number of words written. 1746 */ 1747 __be32 1748 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 1749 struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval, 1750 struct svc_rqst *rqstp, int ignore_crossmnt) 1751 { 1752 u32 bmval0 = bmval[0]; 1753 u32 bmval1 = bmval[1]; 1754 u32 bmval2 = bmval[2]; 1755 struct kstat stat; 1756 struct svc_fh tempfh; 1757 struct kstatfs statfs; 1758 int buflen = *countp << 2; 1759 __be32 *attrlenp; 1760 u32 dummy; 1761 u64 dummy64; 1762 u32 rdattr_err = 0; 1763 __be32 *p = buffer; 1764 __be32 status; 1765 int err; 1766 int aclsupport = 0; 1767 struct nfs4_acl *acl = NULL; 1768 struct nfsd4_compoundres *resp = rqstp->rq_resp; 1769 u32 minorversion = resp->cstate.minorversion; 1770 1771 BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); 1772 BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion)); 1773 BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion)); 1774 BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion)); 1775 1776 if (exp->ex_fslocs.migrated) { 1777 BUG_ON(bmval[2]); 1778 status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err); 1779 if (status) 1780 goto out; 1781 } 1782 1783 err = vfs_getattr(exp->ex_path.mnt, dentry, &stat); 1784 if (err) 1785 goto out_nfserr; 1786 if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | 1787 FATTR4_WORD0_MAXNAME)) || 1788 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | 1789 FATTR4_WORD1_SPACE_TOTAL))) { 1790 err = vfs_statfs(dentry, &statfs); 1791 if (err) 1792 goto out_nfserr; 1793 } 1794 if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { 1795 fh_init(&tempfh, NFS4_FHSIZE); 1796 status = fh_compose(&tempfh, exp, dentry, NULL); 1797 if (status) 1798 goto out; 1799 fhp = &tempfh; 1800 } 1801 if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT 1802 | FATTR4_WORD0_SUPPORTED_ATTRS)) { 1803 err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); 1804 aclsupport = (err == 0); 1805 if (bmval0 & FATTR4_WORD0_ACL) { 1806 if (err == -EOPNOTSUPP) 1807 bmval0 &= ~FATTR4_WORD0_ACL; 1808 else if (err == -EINVAL) { 1809 status = nfserr_attrnotsupp; 1810 goto out; 1811 } else if (err != 0) 1812 goto out_nfserr; 1813 } 1814 } 1815 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) { 1816 if (exp->ex_fslocs.locations == NULL) { 1817 bmval0 &= ~FATTR4_WORD0_FS_LOCATIONS; 1818 } 1819 } 1820 if ((buflen -= 16) < 0) 1821 goto out_resource; 1822 1823 if (unlikely(bmval2)) { 1824 WRITE32(3); 1825 WRITE32(bmval0); 1826 WRITE32(bmval1); 1827 WRITE32(bmval2); 1828 } else if (likely(bmval1)) { 1829 WRITE32(2); 1830 WRITE32(bmval0); 1831 WRITE32(bmval1); 1832 } else { 1833 WRITE32(1); 1834 WRITE32(bmval0); 1835 } 1836 attrlenp = p++; /* to be backfilled later */ 1837 1838 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { 1839 u32 word0 = nfsd_suppattrs0(minorversion); 1840 u32 word1 = nfsd_suppattrs1(minorversion); 1841 u32 word2 = nfsd_suppattrs2(minorversion); 1842 1843 if ((buflen -= 12) < 0) 1844 goto out_resource; 1845 if (!aclsupport) 1846 word0 &= ~FATTR4_WORD0_ACL; 1847 if (!exp->ex_fslocs.locations) 1848 word0 &= ~FATTR4_WORD0_FS_LOCATIONS; 1849 if (!word2) { 1850 WRITE32(2); 1851 WRITE32(word0); 1852 WRITE32(word1); 1853 } else { 1854 WRITE32(3); 1855 WRITE32(word0); 1856 WRITE32(word1); 1857 WRITE32(word2); 1858 } 1859 } 1860 if (bmval0 & FATTR4_WORD0_TYPE) { 1861 if ((buflen -= 4) < 0) 1862 goto out_resource; 1863 dummy = nfs4_ftypes[(stat.mode & S_IFMT) >> 12]; 1864 if (dummy == NF4BAD) 1865 goto out_serverfault; 1866 WRITE32(dummy); 1867 } 1868 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) { 1869 if ((buflen -= 4) < 0) 1870 goto out_resource; 1871 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) 1872 WRITE32(NFS4_FH_PERSISTENT); 1873 else 1874 WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME); 1875 } 1876 if (bmval0 & FATTR4_WORD0_CHANGE) { 1877 /* 1878 * Note: This _must_ be consistent with the scheme for writing 1879 * change_info, so any changes made here must be reflected there 1880 * as well. (See xdr4.h:set_change_info() and the WRITECINFO() 1881 * macro above.) 1882 */ 1883 if ((buflen -= 8) < 0) 1884 goto out_resource; 1885 WRITE32(stat.ctime.tv_sec); 1886 WRITE32(stat.ctime.tv_nsec); 1887 } 1888 if (bmval0 & FATTR4_WORD0_SIZE) { 1889 if ((buflen -= 8) < 0) 1890 goto out_resource; 1891 WRITE64(stat.size); 1892 } 1893 if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) { 1894 if ((buflen -= 4) < 0) 1895 goto out_resource; 1896 WRITE32(1); 1897 } 1898 if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) { 1899 if ((buflen -= 4) < 0) 1900 goto out_resource; 1901 WRITE32(1); 1902 } 1903 if (bmval0 & FATTR4_WORD0_NAMED_ATTR) { 1904 if ((buflen -= 4) < 0) 1905 goto out_resource; 1906 WRITE32(0); 1907 } 1908 if (bmval0 & FATTR4_WORD0_FSID) { 1909 if ((buflen -= 16) < 0) 1910 goto out_resource; 1911 if (exp->ex_fslocs.migrated) { 1912 WRITE64(NFS4_REFERRAL_FSID_MAJOR); 1913 WRITE64(NFS4_REFERRAL_FSID_MINOR); 1914 } else switch(fsid_source(fhp)) { 1915 case FSIDSOURCE_FSID: 1916 WRITE64((u64)exp->ex_fsid); 1917 WRITE64((u64)0); 1918 break; 1919 case FSIDSOURCE_DEV: 1920 WRITE32(0); 1921 WRITE32(MAJOR(stat.dev)); 1922 WRITE32(0); 1923 WRITE32(MINOR(stat.dev)); 1924 break; 1925 case FSIDSOURCE_UUID: 1926 WRITEMEM(exp->ex_uuid, 16); 1927 break; 1928 } 1929 } 1930 if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) { 1931 if ((buflen -= 4) < 0) 1932 goto out_resource; 1933 WRITE32(0); 1934 } 1935 if (bmval0 & FATTR4_WORD0_LEASE_TIME) { 1936 if ((buflen -= 4) < 0) 1937 goto out_resource; 1938 WRITE32(NFSD_LEASE_TIME); 1939 } 1940 if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { 1941 if ((buflen -= 4) < 0) 1942 goto out_resource; 1943 WRITE32(rdattr_err); 1944 } 1945 if (bmval0 & FATTR4_WORD0_ACL) { 1946 struct nfs4_ace *ace; 1947 1948 if (acl == NULL) { 1949 if ((buflen -= 4) < 0) 1950 goto out_resource; 1951 1952 WRITE32(0); 1953 goto out_acl; 1954 } 1955 if ((buflen -= 4) < 0) 1956 goto out_resource; 1957 WRITE32(acl->naces); 1958 1959 for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { 1960 if ((buflen -= 4*3) < 0) 1961 goto out_resource; 1962 WRITE32(ace->type); 1963 WRITE32(ace->flag); 1964 WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL); 1965 status = nfsd4_encode_aclname(rqstp, ace->whotype, 1966 ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP, 1967 &p, &buflen); 1968 if (status == nfserr_resource) 1969 goto out_resource; 1970 if (status) 1971 goto out; 1972 } 1973 } 1974 out_acl: 1975 if (bmval0 & FATTR4_WORD0_ACLSUPPORT) { 1976 if ((buflen -= 4) < 0) 1977 goto out_resource; 1978 WRITE32(aclsupport ? 1979 ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0); 1980 } 1981 if (bmval0 & FATTR4_WORD0_CANSETTIME) { 1982 if ((buflen -= 4) < 0) 1983 goto out_resource; 1984 WRITE32(1); 1985 } 1986 if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) { 1987 if ((buflen -= 4) < 0) 1988 goto out_resource; 1989 WRITE32(1); 1990 } 1991 if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) { 1992 if ((buflen -= 4) < 0) 1993 goto out_resource; 1994 WRITE32(1); 1995 } 1996 if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) { 1997 if ((buflen -= 4) < 0) 1998 goto out_resource; 1999 WRITE32(1); 2000 } 2001 if (bmval0 & FATTR4_WORD0_FILEHANDLE) { 2002 buflen -= (XDR_QUADLEN(fhp->fh_handle.fh_size) << 2) + 4; 2003 if (buflen < 0) 2004 goto out_resource; 2005 WRITE32(fhp->fh_handle.fh_size); 2006 WRITEMEM(&fhp->fh_handle.fh_base, fhp->fh_handle.fh_size); 2007 } 2008 if (bmval0 & FATTR4_WORD0_FILEID) { 2009 if ((buflen -= 8) < 0) 2010 goto out_resource; 2011 WRITE64(stat.ino); 2012 } 2013 if (bmval0 & FATTR4_WORD0_FILES_AVAIL) { 2014 if ((buflen -= 8) < 0) 2015 goto out_resource; 2016 WRITE64((u64) statfs.f_ffree); 2017 } 2018 if (bmval0 & FATTR4_WORD0_FILES_FREE) { 2019 if ((buflen -= 8) < 0) 2020 goto out_resource; 2021 WRITE64((u64) statfs.f_ffree); 2022 } 2023 if (bmval0 & FATTR4_WORD0_FILES_TOTAL) { 2024 if ((buflen -= 8) < 0) 2025 goto out_resource; 2026 WRITE64((u64) statfs.f_files); 2027 } 2028 if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) { 2029 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen); 2030 if (status == nfserr_resource) 2031 goto out_resource; 2032 if (status) 2033 goto out; 2034 } 2035 if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) { 2036 if ((buflen -= 4) < 0) 2037 goto out_resource; 2038 WRITE32(1); 2039 } 2040 if (bmval0 & FATTR4_WORD0_MAXFILESIZE) { 2041 if ((buflen -= 8) < 0) 2042 goto out_resource; 2043 WRITE64(~(u64)0); 2044 } 2045 if (bmval0 & FATTR4_WORD0_MAXLINK) { 2046 if ((buflen -= 4) < 0) 2047 goto out_resource; 2048 WRITE32(255); 2049 } 2050 if (bmval0 & FATTR4_WORD0_MAXNAME) { 2051 if ((buflen -= 4) < 0) 2052 goto out_resource; 2053 WRITE32(statfs.f_namelen); 2054 } 2055 if (bmval0 & FATTR4_WORD0_MAXREAD) { 2056 if ((buflen -= 8) < 0) 2057 goto out_resource; 2058 WRITE64((u64) svc_max_payload(rqstp)); 2059 } 2060 if (bmval0 & FATTR4_WORD0_MAXWRITE) { 2061 if ((buflen -= 8) < 0) 2062 goto out_resource; 2063 WRITE64((u64) svc_max_payload(rqstp)); 2064 } 2065 if (bmval1 & FATTR4_WORD1_MODE) { 2066 if ((buflen -= 4) < 0) 2067 goto out_resource; 2068 WRITE32(stat.mode & S_IALLUGO); 2069 } 2070 if (bmval1 & FATTR4_WORD1_NO_TRUNC) { 2071 if ((buflen -= 4) < 0) 2072 goto out_resource; 2073 WRITE32(1); 2074 } 2075 if (bmval1 & FATTR4_WORD1_NUMLINKS) { 2076 if ((buflen -= 4) < 0) 2077 goto out_resource; 2078 WRITE32(stat.nlink); 2079 } 2080 if (bmval1 & FATTR4_WORD1_OWNER) { 2081 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen); 2082 if (status == nfserr_resource) 2083 goto out_resource; 2084 if (status) 2085 goto out; 2086 } 2087 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) { 2088 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen); 2089 if (status == nfserr_resource) 2090 goto out_resource; 2091 if (status) 2092 goto out; 2093 } 2094 if (bmval1 & FATTR4_WORD1_RAWDEV) { 2095 if ((buflen -= 8) < 0) 2096 goto out_resource; 2097 WRITE32((u32) MAJOR(stat.rdev)); 2098 WRITE32((u32) MINOR(stat.rdev)); 2099 } 2100 if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) { 2101 if ((buflen -= 8) < 0) 2102 goto out_resource; 2103 dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize; 2104 WRITE64(dummy64); 2105 } 2106 if (bmval1 & FATTR4_WORD1_SPACE_FREE) { 2107 if ((buflen -= 8) < 0) 2108 goto out_resource; 2109 dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize; 2110 WRITE64(dummy64); 2111 } 2112 if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) { 2113 if ((buflen -= 8) < 0) 2114 goto out_resource; 2115 dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize; 2116 WRITE64(dummy64); 2117 } 2118 if (bmval1 & FATTR4_WORD1_SPACE_USED) { 2119 if ((buflen -= 8) < 0) 2120 goto out_resource; 2121 dummy64 = (u64)stat.blocks << 9; 2122 WRITE64(dummy64); 2123 } 2124 if (bmval1 & FATTR4_WORD1_TIME_ACCESS) { 2125 if ((buflen -= 12) < 0) 2126 goto out_resource; 2127 WRITE32(0); 2128 WRITE32(stat.atime.tv_sec); 2129 WRITE32(stat.atime.tv_nsec); 2130 } 2131 if (bmval1 & FATTR4_WORD1_TIME_DELTA) { 2132 if ((buflen -= 12) < 0) 2133 goto out_resource; 2134 WRITE32(0); 2135 WRITE32(1); 2136 WRITE32(0); 2137 } 2138 if (bmval1 & FATTR4_WORD1_TIME_METADATA) { 2139 if ((buflen -= 12) < 0) 2140 goto out_resource; 2141 WRITE32(0); 2142 WRITE32(stat.ctime.tv_sec); 2143 WRITE32(stat.ctime.tv_nsec); 2144 } 2145 if (bmval1 & FATTR4_WORD1_TIME_MODIFY) { 2146 if ((buflen -= 12) < 0) 2147 goto out_resource; 2148 WRITE32(0); 2149 WRITE32(stat.mtime.tv_sec); 2150 WRITE32(stat.mtime.tv_nsec); 2151 } 2152 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { 2153 if ((buflen -= 8) < 0) 2154 goto out_resource; 2155 /* 2156 * Get parent's attributes if not ignoring crossmount 2157 * and this is the root of a cross-mounted filesystem. 2158 */ 2159 if (ignore_crossmnt == 0 && 2160 exp->ex_path.mnt->mnt_root->d_inode == dentry->d_inode) { 2161 err = vfs_getattr(exp->ex_path.mnt->mnt_parent, 2162 exp->ex_path.mnt->mnt_mountpoint, &stat); 2163 if (err) 2164 goto out_nfserr; 2165 } 2166 WRITE64(stat.ino); 2167 } 2168 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) { 2169 WRITE32(3); 2170 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0); 2171 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1); 2172 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD2); 2173 } 2174 2175 *attrlenp = htonl((char *)p - (char *)attrlenp - 4); 2176 *countp = p - buffer; 2177 status = nfs_ok; 2178 2179 out: 2180 kfree(acl); 2181 if (fhp == &tempfh) 2182 fh_put(&tempfh); 2183 return status; 2184 out_nfserr: 2185 status = nfserrno(err); 2186 goto out; 2187 out_resource: 2188 *countp = 0; 2189 status = nfserr_resource; 2190 goto out; 2191 out_serverfault: 2192 status = nfserr_serverfault; 2193 goto out; 2194 } 2195 2196 static inline int attributes_need_mount(u32 *bmval) 2197 { 2198 if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME)) 2199 return 1; 2200 if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID) 2201 return 1; 2202 return 0; 2203 } 2204 2205 static __be32 2206 nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, 2207 const char *name, int namlen, __be32 *p, int *buflen) 2208 { 2209 struct svc_export *exp = cd->rd_fhp->fh_export; 2210 struct dentry *dentry; 2211 __be32 nfserr; 2212 int ignore_crossmnt = 0; 2213 2214 dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); 2215 if (IS_ERR(dentry)) 2216 return nfserrno(PTR_ERR(dentry)); 2217 2218 exp_get(exp); 2219 /* 2220 * In the case of a mountpoint, the client may be asking for 2221 * attributes that are only properties of the underlying filesystem 2222 * as opposed to the cross-mounted file system. In such a case, 2223 * we will not follow the cross mount and will fill the attribtutes 2224 * directly from the mountpoint dentry. 2225 */ 2226 if (d_mountpoint(dentry) && !attributes_need_mount(cd->rd_bmval)) 2227 ignore_crossmnt = 1; 2228 else if (d_mountpoint(dentry)) { 2229 int err; 2230 2231 /* 2232 * Why the heck aren't we just using nfsd_lookup?? 2233 * Different "."/".." handling? Something else? 2234 * At least, add a comment here to explain.... 2235 */ 2236 err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp); 2237 if (err) { 2238 nfserr = nfserrno(err); 2239 goto out_put; 2240 } 2241 nfserr = check_nfsd_access(exp, cd->rd_rqstp); 2242 if (nfserr) 2243 goto out_put; 2244 2245 } 2246 nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, 2247 cd->rd_rqstp, ignore_crossmnt); 2248 out_put: 2249 dput(dentry); 2250 exp_put(exp); 2251 return nfserr; 2252 } 2253 2254 static __be32 * 2255 nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) 2256 { 2257 __be32 *attrlenp; 2258 2259 if (buflen < 6) 2260 return NULL; 2261 *p++ = htonl(2); 2262 *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */ 2263 *p++ = htonl(0); /* bmval1 */ 2264 2265 attrlenp = p++; 2266 *p++ = nfserr; /* no htonl */ 2267 *attrlenp = htonl((char *)p - (char *)attrlenp - 4); 2268 return p; 2269 } 2270 2271 static int 2272 nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, 2273 loff_t offset, u64 ino, unsigned int d_type) 2274 { 2275 struct readdir_cd *ccd = ccdv; 2276 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); 2277 int buflen; 2278 __be32 *p = cd->buffer; 2279 __be32 nfserr = nfserr_toosmall; 2280 2281 /* In nfsv4, "." and ".." never make it onto the wire.. */ 2282 if (name && isdotent(name, namlen)) { 2283 cd->common.err = nfs_ok; 2284 return 0; 2285 } 2286 2287 if (cd->offset) 2288 xdr_encode_hyper(cd->offset, (u64) offset); 2289 2290 buflen = cd->buflen - 4 - XDR_QUADLEN(namlen); 2291 if (buflen < 0) 2292 goto fail; 2293 2294 *p++ = xdr_one; /* mark entry present */ 2295 cd->offset = p; /* remember pointer */ 2296 p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ 2297 p = xdr_encode_array(p, name, namlen); /* name length & name */ 2298 2299 nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen); 2300 switch (nfserr) { 2301 case nfs_ok: 2302 p += buflen; 2303 break; 2304 case nfserr_resource: 2305 nfserr = nfserr_toosmall; 2306 goto fail; 2307 case nfserr_dropit: 2308 goto fail; 2309 default: 2310 /* 2311 * If the client requested the RDATTR_ERROR attribute, 2312 * we stuff the error code into this attribute 2313 * and continue. If this attribute was not requested, 2314 * then in accordance with the spec, we fail the 2315 * entire READDIR operation(!) 2316 */ 2317 if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR)) 2318 goto fail; 2319 p = nfsd4_encode_rdattr_error(p, buflen, nfserr); 2320 if (p == NULL) { 2321 nfserr = nfserr_toosmall; 2322 goto fail; 2323 } 2324 } 2325 cd->buflen -= (p - cd->buffer); 2326 cd->buffer = p; 2327 cd->common.err = nfs_ok; 2328 return 0; 2329 fail: 2330 cd->common.err = nfserr; 2331 return -EINVAL; 2332 } 2333 2334 static void 2335 nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid) 2336 { 2337 ENCODE_HEAD; 2338 2339 RESERVE_SPACE(sizeof(stateid_t)); 2340 WRITE32(sid->si_generation); 2341 WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t)); 2342 ADJUST_ARGS(); 2343 } 2344 2345 static __be32 2346 nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) 2347 { 2348 ENCODE_HEAD; 2349 2350 if (!nfserr) { 2351 RESERVE_SPACE(8); 2352 WRITE32(access->ac_supported); 2353 WRITE32(access->ac_resp_access); 2354 ADJUST_ARGS(); 2355 } 2356 return nfserr; 2357 } 2358 2359 static __be32 2360 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) 2361 { 2362 ENCODE_SEQID_OP_HEAD; 2363 2364 if (!nfserr) 2365 nfsd4_encode_stateid(resp, &close->cl_stateid); 2366 2367 ENCODE_SEQID_OP_TAIL(close->cl_stateowner); 2368 return nfserr; 2369 } 2370 2371 2372 static __be32 2373 nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit) 2374 { 2375 ENCODE_HEAD; 2376 2377 if (!nfserr) { 2378 RESERVE_SPACE(8); 2379 WRITEMEM(commit->co_verf.data, 8); 2380 ADJUST_ARGS(); 2381 } 2382 return nfserr; 2383 } 2384 2385 static __be32 2386 nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create) 2387 { 2388 ENCODE_HEAD; 2389 2390 if (!nfserr) { 2391 RESERVE_SPACE(32); 2392 WRITECINFO(create->cr_cinfo); 2393 WRITE32(2); 2394 WRITE32(create->cr_bmval[0]); 2395 WRITE32(create->cr_bmval[1]); 2396 ADJUST_ARGS(); 2397 } 2398 return nfserr; 2399 } 2400 2401 static __be32 2402 nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr) 2403 { 2404 struct svc_fh *fhp = getattr->ga_fhp; 2405 int buflen; 2406 2407 if (nfserr) 2408 return nfserr; 2409 2410 buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2); 2411 nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, 2412 resp->p, &buflen, getattr->ga_bmval, 2413 resp->rqstp, 0); 2414 if (!nfserr) 2415 resp->p += buflen; 2416 return nfserr; 2417 } 2418 2419 static __be32 2420 nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp) 2421 { 2422 struct svc_fh *fhp = *fhpp; 2423 unsigned int len; 2424 ENCODE_HEAD; 2425 2426 if (!nfserr) { 2427 len = fhp->fh_handle.fh_size; 2428 RESERVE_SPACE(len + 4); 2429 WRITE32(len); 2430 WRITEMEM(&fhp->fh_handle.fh_base, len); 2431 ADJUST_ARGS(); 2432 } 2433 return nfserr; 2434 } 2435 2436 /* 2437 * Including all fields other than the name, a LOCK4denied structure requires 2438 * 8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes. 2439 */ 2440 static void 2441 nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld) 2442 { 2443 ENCODE_HEAD; 2444 2445 RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop ? ld->ld_sop->so_owner.len : 0)); 2446 WRITE64(ld->ld_start); 2447 WRITE64(ld->ld_length); 2448 WRITE32(ld->ld_type); 2449 if (ld->ld_sop) { 2450 WRITEMEM(&ld->ld_clientid, 8); 2451 WRITE32(ld->ld_sop->so_owner.len); 2452 WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len); 2453 kref_put(&ld->ld_sop->so_ref, nfs4_free_stateowner); 2454 } else { /* non - nfsv4 lock in conflict, no clientid nor owner */ 2455 WRITE64((u64)0); /* clientid */ 2456 WRITE32(0); /* length of owner name */ 2457 } 2458 ADJUST_ARGS(); 2459 } 2460 2461 static __be32 2462 nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock) 2463 { 2464 ENCODE_SEQID_OP_HEAD; 2465 2466 if (!nfserr) 2467 nfsd4_encode_stateid(resp, &lock->lk_resp_stateid); 2468 else if (nfserr == nfserr_denied) 2469 nfsd4_encode_lock_denied(resp, &lock->lk_denied); 2470 2471 ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner); 2472 return nfserr; 2473 } 2474 2475 static __be32 2476 nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt) 2477 { 2478 if (nfserr == nfserr_denied) 2479 nfsd4_encode_lock_denied(resp, &lockt->lt_denied); 2480 return nfserr; 2481 } 2482 2483 static __be32 2484 nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku) 2485 { 2486 ENCODE_SEQID_OP_HEAD; 2487 2488 if (!nfserr) 2489 nfsd4_encode_stateid(resp, &locku->lu_stateid); 2490 2491 ENCODE_SEQID_OP_TAIL(locku->lu_stateowner); 2492 return nfserr; 2493 } 2494 2495 2496 static __be32 2497 nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link) 2498 { 2499 ENCODE_HEAD; 2500 2501 if (!nfserr) { 2502 RESERVE_SPACE(20); 2503 WRITECINFO(link->li_cinfo); 2504 ADJUST_ARGS(); 2505 } 2506 return nfserr; 2507 } 2508 2509 2510 static __be32 2511 nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) 2512 { 2513 ENCODE_HEAD; 2514 ENCODE_SEQID_OP_HEAD; 2515 2516 if (nfserr) 2517 goto out; 2518 2519 nfsd4_encode_stateid(resp, &open->op_stateid); 2520 RESERVE_SPACE(40); 2521 WRITECINFO(open->op_cinfo); 2522 WRITE32(open->op_rflags); 2523 WRITE32(2); 2524 WRITE32(open->op_bmval[0]); 2525 WRITE32(open->op_bmval[1]); 2526 WRITE32(open->op_delegate_type); 2527 ADJUST_ARGS(); 2528 2529 switch (open->op_delegate_type) { 2530 case NFS4_OPEN_DELEGATE_NONE: 2531 break; 2532 case NFS4_OPEN_DELEGATE_READ: 2533 nfsd4_encode_stateid(resp, &open->op_delegate_stateid); 2534 RESERVE_SPACE(20); 2535 WRITE32(open->op_recall); 2536 2537 /* 2538 * TODO: ACE's in delegations 2539 */ 2540 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE); 2541 WRITE32(0); 2542 WRITE32(0); 2543 WRITE32(0); /* XXX: is NULL principal ok? */ 2544 ADJUST_ARGS(); 2545 break; 2546 case NFS4_OPEN_DELEGATE_WRITE: 2547 nfsd4_encode_stateid(resp, &open->op_delegate_stateid); 2548 RESERVE_SPACE(32); 2549 WRITE32(0); 2550 2551 /* 2552 * TODO: space_limit's in delegations 2553 */ 2554 WRITE32(NFS4_LIMIT_SIZE); 2555 WRITE32(~(u32)0); 2556 WRITE32(~(u32)0); 2557 2558 /* 2559 * TODO: ACE's in delegations 2560 */ 2561 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE); 2562 WRITE32(0); 2563 WRITE32(0); 2564 WRITE32(0); /* XXX: is NULL principal ok? */ 2565 ADJUST_ARGS(); 2566 break; 2567 default: 2568 BUG(); 2569 } 2570 /* XXX save filehandle here */ 2571 out: 2572 ENCODE_SEQID_OP_TAIL(open->op_stateowner); 2573 return nfserr; 2574 } 2575 2576 static __be32 2577 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) 2578 { 2579 ENCODE_SEQID_OP_HEAD; 2580 2581 if (!nfserr) 2582 nfsd4_encode_stateid(resp, &oc->oc_resp_stateid); 2583 2584 ENCODE_SEQID_OP_TAIL(oc->oc_stateowner); 2585 return nfserr; 2586 } 2587 2588 static __be32 2589 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) 2590 { 2591 ENCODE_SEQID_OP_HEAD; 2592 2593 if (!nfserr) 2594 nfsd4_encode_stateid(resp, &od->od_stateid); 2595 2596 ENCODE_SEQID_OP_TAIL(od->od_stateowner); 2597 return nfserr; 2598 } 2599 2600 static __be32 2601 nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, 2602 struct nfsd4_read *read) 2603 { 2604 u32 eof; 2605 int v, pn; 2606 unsigned long maxcount; 2607 long len; 2608 ENCODE_HEAD; 2609 2610 if (nfserr) 2611 return nfserr; 2612 if (resp->xbuf->page_len) 2613 return nfserr_resource; 2614 2615 RESERVE_SPACE(8); /* eof flag and byte count */ 2616 2617 maxcount = svc_max_payload(resp->rqstp); 2618 if (maxcount > read->rd_length) 2619 maxcount = read->rd_length; 2620 2621 len = maxcount; 2622 v = 0; 2623 while (len > 0) { 2624 pn = resp->rqstp->rq_resused++; 2625 resp->rqstp->rq_vec[v].iov_base = 2626 page_address(resp->rqstp->rq_respages[pn]); 2627 resp->rqstp->rq_vec[v].iov_len = 2628 len < PAGE_SIZE ? len : PAGE_SIZE; 2629 v++; 2630 len -= PAGE_SIZE; 2631 } 2632 read->rd_vlen = v; 2633 2634 nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp, 2635 read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen, 2636 &maxcount); 2637 2638 if (nfserr == nfserr_symlink) 2639 nfserr = nfserr_inval; 2640 if (nfserr) 2641 return nfserr; 2642 eof = (read->rd_offset + maxcount >= 2643 read->rd_fhp->fh_dentry->d_inode->i_size); 2644 2645 WRITE32(eof); 2646 WRITE32(maxcount); 2647 ADJUST_ARGS(); 2648 resp->xbuf->head[0].iov_len = (char*)p 2649 - (char*)resp->xbuf->head[0].iov_base; 2650 resp->xbuf->page_len = maxcount; 2651 2652 /* Use rest of head for padding and remaining ops: */ 2653 resp->xbuf->tail[0].iov_base = p; 2654 resp->xbuf->tail[0].iov_len = 0; 2655 if (maxcount&3) { 2656 RESERVE_SPACE(4); 2657 WRITE32(0); 2658 resp->xbuf->tail[0].iov_base += maxcount&3; 2659 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3); 2660 ADJUST_ARGS(); 2661 } 2662 return 0; 2663 } 2664 2665 static __be32 2666 nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink) 2667 { 2668 int maxcount; 2669 char *page; 2670 ENCODE_HEAD; 2671 2672 if (nfserr) 2673 return nfserr; 2674 if (resp->xbuf->page_len) 2675 return nfserr_resource; 2676 2677 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); 2678 2679 maxcount = PAGE_SIZE; 2680 RESERVE_SPACE(4); 2681 2682 /* 2683 * XXX: By default, the ->readlink() VFS op will truncate symlinks 2684 * if they would overflow the buffer. Is this kosher in NFSv4? If 2685 * not, one easy fix is: if ->readlink() precisely fills the buffer, 2686 * assume that truncation occurred, and return NFS4ERR_RESOURCE. 2687 */ 2688 nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount); 2689 if (nfserr == nfserr_isdir) 2690 return nfserr_inval; 2691 if (nfserr) 2692 return nfserr; 2693 2694 WRITE32(maxcount); 2695 ADJUST_ARGS(); 2696 resp->xbuf->head[0].iov_len = (char*)p 2697 - (char*)resp->xbuf->head[0].iov_base; 2698 resp->xbuf->page_len = maxcount; 2699 2700 /* Use rest of head for padding and remaining ops: */ 2701 resp->xbuf->tail[0].iov_base = p; 2702 resp->xbuf->tail[0].iov_len = 0; 2703 if (maxcount&3) { 2704 RESERVE_SPACE(4); 2705 WRITE32(0); 2706 resp->xbuf->tail[0].iov_base += maxcount&3; 2707 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3); 2708 ADJUST_ARGS(); 2709 } 2710 return 0; 2711 } 2712 2713 static __be32 2714 nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir) 2715 { 2716 int maxcount; 2717 loff_t offset; 2718 __be32 *page, *savep, *tailbase; 2719 ENCODE_HEAD; 2720 2721 if (nfserr) 2722 return nfserr; 2723 if (resp->xbuf->page_len) 2724 return nfserr_resource; 2725 2726 RESERVE_SPACE(8); /* verifier */ 2727 savep = p; 2728 2729 /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */ 2730 WRITE32(0); 2731 WRITE32(0); 2732 ADJUST_ARGS(); 2733 resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base; 2734 tailbase = p; 2735 2736 maxcount = PAGE_SIZE; 2737 if (maxcount > readdir->rd_maxcount) 2738 maxcount = readdir->rd_maxcount; 2739 2740 /* 2741 * Convert from bytes to words, account for the two words already 2742 * written, make sure to leave two words at the end for the next 2743 * pointer and eof field. 2744 */ 2745 maxcount = (maxcount >> 2) - 4; 2746 if (maxcount < 0) { 2747 nfserr = nfserr_toosmall; 2748 goto err_no_verf; 2749 } 2750 2751 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); 2752 readdir->common.err = 0; 2753 readdir->buflen = maxcount; 2754 readdir->buffer = page; 2755 readdir->offset = NULL; 2756 2757 offset = readdir->rd_cookie; 2758 nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp, 2759 &offset, 2760 &readdir->common, nfsd4_encode_dirent); 2761 if (nfserr == nfs_ok && 2762 readdir->common.err == nfserr_toosmall && 2763 readdir->buffer == page) 2764 nfserr = nfserr_toosmall; 2765 if (nfserr == nfserr_symlink) 2766 nfserr = nfserr_notdir; 2767 if (nfserr) 2768 goto err_no_verf; 2769 2770 if (readdir->offset) 2771 xdr_encode_hyper(readdir->offset, offset); 2772 2773 p = readdir->buffer; 2774 *p++ = 0; /* no more entries */ 2775 *p++ = htonl(readdir->common.err == nfserr_eof); 2776 resp->xbuf->page_len = ((char*)p) - (char*)page_address( 2777 resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); 2778 2779 /* Use rest of head for padding and remaining ops: */ 2780 resp->xbuf->tail[0].iov_base = tailbase; 2781 resp->xbuf->tail[0].iov_len = 0; 2782 resp->p = resp->xbuf->tail[0].iov_base; 2783 resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4; 2784 2785 return 0; 2786 err_no_verf: 2787 p = savep; 2788 ADJUST_ARGS(); 2789 return nfserr; 2790 } 2791 2792 static __be32 2793 nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove) 2794 { 2795 ENCODE_HEAD; 2796 2797 if (!nfserr) { 2798 RESERVE_SPACE(20); 2799 WRITECINFO(remove->rm_cinfo); 2800 ADJUST_ARGS(); 2801 } 2802 return nfserr; 2803 } 2804 2805 static __be32 2806 nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename) 2807 { 2808 ENCODE_HEAD; 2809 2810 if (!nfserr) { 2811 RESERVE_SPACE(40); 2812 WRITECINFO(rename->rn_sinfo); 2813 WRITECINFO(rename->rn_tinfo); 2814 ADJUST_ARGS(); 2815 } 2816 return nfserr; 2817 } 2818 2819 static __be32 2820 nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, 2821 struct nfsd4_secinfo *secinfo) 2822 { 2823 int i = 0; 2824 struct svc_export *exp = secinfo->si_exp; 2825 u32 nflavs; 2826 struct exp_flavor_info *flavs; 2827 struct exp_flavor_info def_flavs[2]; 2828 ENCODE_HEAD; 2829 2830 if (nfserr) 2831 goto out; 2832 if (exp->ex_nflavors) { 2833 flavs = exp->ex_flavors; 2834 nflavs = exp->ex_nflavors; 2835 } else { /* Handling of some defaults in absence of real secinfo: */ 2836 flavs = def_flavs; 2837 if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) { 2838 nflavs = 2; 2839 flavs[0].pseudoflavor = RPC_AUTH_UNIX; 2840 flavs[1].pseudoflavor = RPC_AUTH_NULL; 2841 } else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) { 2842 nflavs = 1; 2843 flavs[0].pseudoflavor 2844 = svcauth_gss_flavor(exp->ex_client); 2845 } else { 2846 nflavs = 1; 2847 flavs[0].pseudoflavor 2848 = exp->ex_client->flavour->flavour; 2849 } 2850 } 2851 2852 RESERVE_SPACE(4); 2853 WRITE32(nflavs); 2854 ADJUST_ARGS(); 2855 for (i = 0; i < nflavs; i++) { 2856 u32 flav = flavs[i].pseudoflavor; 2857 struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav); 2858 2859 if (gm) { 2860 RESERVE_SPACE(4); 2861 WRITE32(RPC_AUTH_GSS); 2862 ADJUST_ARGS(); 2863 RESERVE_SPACE(4 + gm->gm_oid.len); 2864 WRITE32(gm->gm_oid.len); 2865 WRITEMEM(gm->gm_oid.data, gm->gm_oid.len); 2866 ADJUST_ARGS(); 2867 RESERVE_SPACE(4); 2868 WRITE32(0); /* qop */ 2869 ADJUST_ARGS(); 2870 RESERVE_SPACE(4); 2871 WRITE32(gss_pseudoflavor_to_service(gm, flav)); 2872 ADJUST_ARGS(); 2873 gss_mech_put(gm); 2874 } else { 2875 RESERVE_SPACE(4); 2876 WRITE32(flav); 2877 ADJUST_ARGS(); 2878 } 2879 } 2880 out: 2881 if (exp) 2882 exp_put(exp); 2883 return nfserr; 2884 } 2885 2886 /* 2887 * The SETATTR encode routine is special -- it always encodes a bitmap, 2888 * regardless of the error status. 2889 */ 2890 static __be32 2891 nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr) 2892 { 2893 ENCODE_HEAD; 2894 2895 RESERVE_SPACE(12); 2896 if (nfserr) { 2897 WRITE32(2); 2898 WRITE32(0); 2899 WRITE32(0); 2900 } 2901 else { 2902 WRITE32(2); 2903 WRITE32(setattr->sa_bmval[0]); 2904 WRITE32(setattr->sa_bmval[1]); 2905 } 2906 ADJUST_ARGS(); 2907 return nfserr; 2908 } 2909 2910 static __be32 2911 nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd) 2912 { 2913 ENCODE_HEAD; 2914 2915 if (!nfserr) { 2916 RESERVE_SPACE(8 + sizeof(nfs4_verifier)); 2917 WRITEMEM(&scd->se_clientid, 8); 2918 WRITEMEM(&scd->se_confirm, sizeof(nfs4_verifier)); 2919 ADJUST_ARGS(); 2920 } 2921 else if (nfserr == nfserr_clid_inuse) { 2922 RESERVE_SPACE(8); 2923 WRITE32(0); 2924 WRITE32(0); 2925 ADJUST_ARGS(); 2926 } 2927 return nfserr; 2928 } 2929 2930 static __be32 2931 nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write) 2932 { 2933 ENCODE_HEAD; 2934 2935 if (!nfserr) { 2936 RESERVE_SPACE(16); 2937 WRITE32(write->wr_bytes_written); 2938 WRITE32(write->wr_how_written); 2939 WRITEMEM(write->wr_verifier.data, 8); 2940 ADJUST_ARGS(); 2941 } 2942 return nfserr; 2943 } 2944 2945 static __be32 2946 nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr, 2947 struct nfsd4_exchange_id *exid) 2948 { 2949 ENCODE_HEAD; 2950 char *major_id; 2951 char *server_scope; 2952 int major_id_sz; 2953 int server_scope_sz; 2954 uint64_t minor_id = 0; 2955 2956 if (nfserr) 2957 return nfserr; 2958 2959 major_id = utsname()->nodename; 2960 major_id_sz = strlen(major_id); 2961 server_scope = utsname()->nodename; 2962 server_scope_sz = strlen(server_scope); 2963 2964 RESERVE_SPACE( 2965 8 /* eir_clientid */ + 2966 4 /* eir_sequenceid */ + 2967 4 /* eir_flags */ + 2968 4 /* spr_how (SP4_NONE) */ + 2969 8 /* so_minor_id */ + 2970 4 /* so_major_id.len */ + 2971 (XDR_QUADLEN(major_id_sz) * 4) + 2972 4 /* eir_server_scope.len */ + 2973 (XDR_QUADLEN(server_scope_sz) * 4) + 2974 4 /* eir_server_impl_id.count (0) */); 2975 2976 WRITEMEM(&exid->clientid, 8); 2977 WRITE32(exid->seqid); 2978 WRITE32(exid->flags); 2979 2980 /* state_protect4_r. Currently only support SP4_NONE */ 2981 BUG_ON(exid->spa_how != SP4_NONE); 2982 WRITE32(exid->spa_how); 2983 2984 /* The server_owner struct */ 2985 WRITE64(minor_id); /* Minor id */ 2986 /* major id */ 2987 WRITE32(major_id_sz); 2988 WRITEMEM(major_id, major_id_sz); 2989 2990 /* Server scope */ 2991 WRITE32(server_scope_sz); 2992 WRITEMEM(server_scope, server_scope_sz); 2993 2994 /* Implementation id */ 2995 WRITE32(0); /* zero length nfs_impl_id4 array */ 2996 ADJUST_ARGS(); 2997 return 0; 2998 } 2999 3000 static __be32 3001 nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, 3002 struct nfsd4_create_session *sess) 3003 { 3004 ENCODE_HEAD; 3005 3006 if (nfserr) 3007 return nfserr; 3008 3009 RESERVE_SPACE(24); 3010 WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN); 3011 WRITE32(sess->seqid); 3012 WRITE32(sess->flags); 3013 ADJUST_ARGS(); 3014 3015 RESERVE_SPACE(28); 3016 WRITE32(0); /* headerpadsz */ 3017 WRITE32(sess->fore_channel.maxreq_sz); 3018 WRITE32(sess->fore_channel.maxresp_sz); 3019 WRITE32(sess->fore_channel.maxresp_cached); 3020 WRITE32(sess->fore_channel.maxops); 3021 WRITE32(sess->fore_channel.maxreqs); 3022 WRITE32(sess->fore_channel.nr_rdma_attrs); 3023 ADJUST_ARGS(); 3024 3025 if (sess->fore_channel.nr_rdma_attrs) { 3026 RESERVE_SPACE(4); 3027 WRITE32(sess->fore_channel.rdma_attrs); 3028 ADJUST_ARGS(); 3029 } 3030 3031 RESERVE_SPACE(28); 3032 WRITE32(0); /* headerpadsz */ 3033 WRITE32(sess->back_channel.maxreq_sz); 3034 WRITE32(sess->back_channel.maxresp_sz); 3035 WRITE32(sess->back_channel.maxresp_cached); 3036 WRITE32(sess->back_channel.maxops); 3037 WRITE32(sess->back_channel.maxreqs); 3038 WRITE32(sess->back_channel.nr_rdma_attrs); 3039 ADJUST_ARGS(); 3040 3041 if (sess->back_channel.nr_rdma_attrs) { 3042 RESERVE_SPACE(4); 3043 WRITE32(sess->back_channel.rdma_attrs); 3044 ADJUST_ARGS(); 3045 } 3046 return 0; 3047 } 3048 3049 static __be32 3050 nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr, 3051 struct nfsd4_destroy_session *destroy_session) 3052 { 3053 return nfserr; 3054 } 3055 3056 __be32 3057 nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, 3058 struct nfsd4_sequence *seq) 3059 { 3060 ENCODE_HEAD; 3061 3062 if (nfserr) 3063 return nfserr; 3064 3065 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20); 3066 WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN); 3067 WRITE32(seq->seqid); 3068 WRITE32(seq->slotid); 3069 WRITE32(seq->maxslots); 3070 /* 3071 * FIXME: for now: 3072 * target_maxslots = maxslots 3073 * status_flags = 0 3074 */ 3075 WRITE32(seq->maxslots); 3076 WRITE32(0); 3077 3078 ADJUST_ARGS(); 3079 return 0; 3080 } 3081 3082 static __be32 3083 nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p) 3084 { 3085 return nfserr; 3086 } 3087 3088 typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *); 3089 3090 /* 3091 * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1 3092 * since we don't need to filter out obsolete ops as this is 3093 * done in the decoding phase. 3094 */ 3095 static nfsd4_enc nfsd4_enc_ops[] = { 3096 [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access, 3097 [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close, 3098 [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit, 3099 [OP_CREATE] = (nfsd4_enc)nfsd4_encode_create, 3100 [OP_DELEGPURGE] = (nfsd4_enc)nfsd4_encode_noop, 3101 [OP_DELEGRETURN] = (nfsd4_enc)nfsd4_encode_noop, 3102 [OP_GETATTR] = (nfsd4_enc)nfsd4_encode_getattr, 3103 [OP_GETFH] = (nfsd4_enc)nfsd4_encode_getfh, 3104 [OP_LINK] = (nfsd4_enc)nfsd4_encode_link, 3105 [OP_LOCK] = (nfsd4_enc)nfsd4_encode_lock, 3106 [OP_LOCKT] = (nfsd4_enc)nfsd4_encode_lockt, 3107 [OP_LOCKU] = (nfsd4_enc)nfsd4_encode_locku, 3108 [OP_LOOKUP] = (nfsd4_enc)nfsd4_encode_noop, 3109 [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, 3110 [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, 3111 [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, 3112 [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop, 3113 [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, 3114 [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, 3115 [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, 3116 [OP_PUTPUBFH] = (nfsd4_enc)nfsd4_encode_noop, 3117 [OP_PUTROOTFH] = (nfsd4_enc)nfsd4_encode_noop, 3118 [OP_READ] = (nfsd4_enc)nfsd4_encode_read, 3119 [OP_READDIR] = (nfsd4_enc)nfsd4_encode_readdir, 3120 [OP_READLINK] = (nfsd4_enc)nfsd4_encode_readlink, 3121 [OP_REMOVE] = (nfsd4_enc)nfsd4_encode_remove, 3122 [OP_RENAME] = (nfsd4_enc)nfsd4_encode_rename, 3123 [OP_RENEW] = (nfsd4_enc)nfsd4_encode_noop, 3124 [OP_RESTOREFH] = (nfsd4_enc)nfsd4_encode_noop, 3125 [OP_SAVEFH] = (nfsd4_enc)nfsd4_encode_noop, 3126 [OP_SECINFO] = (nfsd4_enc)nfsd4_encode_secinfo, 3127 [OP_SETATTR] = (nfsd4_enc)nfsd4_encode_setattr, 3128 [OP_SETCLIENTID] = (nfsd4_enc)nfsd4_encode_setclientid, 3129 [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop, 3130 [OP_VERIFY] = (nfsd4_enc)nfsd4_encode_noop, 3131 [OP_WRITE] = (nfsd4_enc)nfsd4_encode_write, 3132 [OP_RELEASE_LOCKOWNER] = (nfsd4_enc)nfsd4_encode_noop, 3133 3134 /* NFSv4.1 operations */ 3135 [OP_BACKCHANNEL_CTL] = (nfsd4_enc)nfsd4_encode_noop, 3136 [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_noop, 3137 [OP_EXCHANGE_ID] = (nfsd4_enc)nfsd4_encode_exchange_id, 3138 [OP_CREATE_SESSION] = (nfsd4_enc)nfsd4_encode_create_session, 3139 [OP_DESTROY_SESSION] = (nfsd4_enc)nfsd4_encode_destroy_session, 3140 [OP_FREE_STATEID] = (nfsd4_enc)nfsd4_encode_noop, 3141 [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, 3142 [OP_GETDEVICEINFO] = (nfsd4_enc)nfsd4_encode_noop, 3143 [OP_GETDEVICELIST] = (nfsd4_enc)nfsd4_encode_noop, 3144 [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, 3145 [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, 3146 [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, 3147 [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_noop, 3148 [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, 3149 [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, 3150 [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop, 3151 [OP_WANT_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop, 3152 [OP_DESTROY_CLIENTID] = (nfsd4_enc)nfsd4_encode_noop, 3153 [OP_RECLAIM_COMPLETE] = (nfsd4_enc)nfsd4_encode_noop, 3154 }; 3155 3156 /* 3157 * Calculate the total amount of memory that the compound response has taken 3158 * after encoding the current operation. 3159 * 3160 * pad: add on 8 bytes for the next operation's op_code and status so that 3161 * there is room to cache a failure on the next operation. 3162 * 3163 * Compare this length to the session se_fmaxresp_cached. 3164 * 3165 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so 3166 * will be at least a page and will therefore hold the xdr_buf head. 3167 */ 3168 static int nfsd4_check_drc_limit(struct nfsd4_compoundres *resp) 3169 { 3170 int status = 0; 3171 struct xdr_buf *xb = &resp->rqstp->rq_res; 3172 struct nfsd4_compoundargs *args = resp->rqstp->rq_argp; 3173 struct nfsd4_session *session = NULL; 3174 struct nfsd4_slot *slot = resp->cstate.slot; 3175 u32 length, tlen = 0, pad = 8; 3176 3177 if (!nfsd4_has_session(&resp->cstate)) 3178 return status; 3179 3180 session = resp->cstate.session; 3181 if (session == NULL || slot->sl_cache_entry.ce_cachethis == 0) 3182 return status; 3183 3184 if (resp->opcnt >= args->opcnt) 3185 pad = 0; /* this is the last operation */ 3186 3187 if (xb->page_len == 0) { 3188 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad; 3189 } else { 3190 if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0) 3191 tlen = (char *)resp->p - (char *)xb->tail[0].iov_base; 3192 3193 length = xb->head[0].iov_len + xb->page_len + tlen + pad; 3194 } 3195 dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__, 3196 length, xb->page_len, tlen, pad); 3197 3198 if (length <= session->se_fmaxresp_cached) 3199 return status; 3200 else 3201 return nfserr_rep_too_big_to_cache; 3202 } 3203 3204 void 3205 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) 3206 { 3207 __be32 *statp; 3208 ENCODE_HEAD; 3209 3210 RESERVE_SPACE(8); 3211 WRITE32(op->opnum); 3212 statp = p++; /* to be backfilled at the end */ 3213 ADJUST_ARGS(); 3214 3215 if (op->opnum == OP_ILLEGAL) 3216 goto status; 3217 BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) || 3218 !nfsd4_enc_ops[op->opnum]); 3219 op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u); 3220 /* nfsd4_check_drc_limit guarantees enough room for error status */ 3221 if (!op->status && nfsd4_check_drc_limit(resp)) 3222 op->status = nfserr_rep_too_big_to_cache; 3223 status: 3224 /* 3225 * Note: We write the status directly, instead of using WRITE32(), 3226 * since it is already in network byte order. 3227 */ 3228 *statp = op->status; 3229 } 3230 3231 /* 3232 * Encode the reply stored in the stateowner reply cache 3233 * 3234 * XDR note: do not encode rp->rp_buflen: the buffer contains the 3235 * previously sent already encoded operation. 3236 * 3237 * called with nfs4_lock_state() held 3238 */ 3239 void 3240 nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op) 3241 { 3242 ENCODE_HEAD; 3243 struct nfs4_replay *rp = op->replay; 3244 3245 BUG_ON(!rp); 3246 3247 RESERVE_SPACE(8); 3248 WRITE32(op->opnum); 3249 *p++ = rp->rp_status; /* already xdr'ed */ 3250 ADJUST_ARGS(); 3251 3252 RESERVE_SPACE(rp->rp_buflen); 3253 WRITEMEM(rp->rp_buf, rp->rp_buflen); 3254 ADJUST_ARGS(); 3255 } 3256 3257 /* 3258 * END OF "GENERIC" ENCODE ROUTINES. 3259 */ 3260 3261 int 3262 nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) 3263 { 3264 return xdr_ressize_check(rqstp, p); 3265 } 3266 3267 void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args) 3268 { 3269 if (args->ops != args->iops) { 3270 kfree(args->ops); 3271 args->ops = args->iops; 3272 } 3273 kfree(args->tmpp); 3274 args->tmpp = NULL; 3275 while (args->to_free) { 3276 struct tmpbuf *tb = args->to_free; 3277 args->to_free = tb->next; 3278 tb->release(tb->buf); 3279 kfree(tb); 3280 } 3281 } 3282 3283 int 3284 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args) 3285 { 3286 __be32 status; 3287 3288 args->p = p; 3289 args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; 3290 args->pagelist = rqstp->rq_arg.pages; 3291 args->pagelen = rqstp->rq_arg.page_len; 3292 args->tmpp = NULL; 3293 args->to_free = NULL; 3294 args->ops = args->iops; 3295 args->rqstp = rqstp; 3296 3297 status = nfsd4_decode_compound(args); 3298 if (status) { 3299 nfsd4_release_compoundargs(args); 3300 } 3301 return !status; 3302 } 3303 3304 int 3305 nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp) 3306 { 3307 /* 3308 * All that remains is to write the tag and operation count... 3309 */ 3310 struct kvec *iov; 3311 p = resp->tagp; 3312 *p++ = htonl(resp->taglen); 3313 memcpy(p, resp->tag, resp->taglen); 3314 p += XDR_QUADLEN(resp->taglen); 3315 *p++ = htonl(resp->opcnt); 3316 3317 if (rqstp->rq_res.page_len) 3318 iov = &rqstp->rq_res.tail[0]; 3319 else 3320 iov = &rqstp->rq_res.head[0]; 3321 iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base; 3322 BUG_ON(iov->iov_len > PAGE_SIZE); 3323 if (nfsd4_has_session(&resp->cstate)) { 3324 if (resp->cstate.status == nfserr_replay_cache && 3325 !nfsd4_not_cached(resp)) { 3326 iov->iov_len = resp->cstate.iovlen; 3327 } else { 3328 nfsd4_store_cache_entry(resp); 3329 dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__); 3330 resp->cstate.slot->sl_inuse = 0; 3331 } 3332 if (resp->cstate.session) 3333 nfsd4_put_session(resp->cstate.session); 3334 } 3335 return 1; 3336 } 3337 3338 /* 3339 * Local variables: 3340 * c-basic-offset: 8 3341 * End: 3342 */ 3343