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