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