1 /* 2 * fs/nfsd/nfs4proc.c 3 * 4 * Server-side procedures 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 38 #include <linux/param.h> 39 #include <linux/major.h> 40 #include <linux/slab.h> 41 #include <linux/file.h> 42 43 #include <linux/sunrpc/svc.h> 44 #include <linux/nfsd/nfsd.h> 45 #include <linux/nfsd/cache.h> 46 #include <linux/nfs4.h> 47 #include <linux/nfsd/state.h> 48 #include <linux/nfsd/xdr4.h> 49 #include <linux/nfs4_acl.h> 50 #include <linux/sunrpc/gss_api.h> 51 52 #define NFSDDBG_FACILITY NFSDDBG_PROC 53 54 static inline void 55 fh_dup2(struct svc_fh *dst, struct svc_fh *src) 56 { 57 fh_put(dst); 58 dget(src->fh_dentry); 59 if (src->fh_export) 60 cache_get(&src->fh_export->h); 61 *dst = *src; 62 } 63 64 static __be32 65 do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode) 66 { 67 __be32 status; 68 69 if (open->op_truncate && 70 !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) 71 return nfserr_inval; 72 73 if (open->op_share_access & NFS4_SHARE_ACCESS_READ) 74 accmode |= MAY_READ; 75 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 76 accmode |= (MAY_WRITE | MAY_TRUNC); 77 if (open->op_share_deny & NFS4_SHARE_DENY_WRITE) 78 accmode |= MAY_WRITE; 79 80 status = fh_verify(rqstp, current_fh, S_IFREG, accmode); 81 82 return status; 83 } 84 85 static __be32 86 do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 87 { 88 struct svc_fh resfh; 89 __be32 status; 90 int created = 0; 91 92 fh_init(&resfh, NFS4_FHSIZE); 93 open->op_truncate = 0; 94 95 if (open->op_create) { 96 /* 97 * Note: create modes (UNCHECKED,GUARDED...) are the same 98 * in NFSv4 as in v3. 99 */ 100 status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, 101 open->op_fname.len, &open->op_iattr, 102 &resfh, open->op_createmode, 103 (u32 *)open->op_verf.data, &open->op_truncate, &created); 104 } else { 105 status = nfsd_lookup(rqstp, current_fh, 106 open->op_fname.data, open->op_fname.len, &resfh); 107 fh_unlock(current_fh); 108 } 109 if (status) 110 goto out; 111 112 set_change_info(&open->op_cinfo, current_fh); 113 114 /* set reply cache */ 115 fh_dup2(current_fh, &resfh); 116 open->op_stateowner->so_replay.rp_openfh_len = resfh.fh_handle.fh_size; 117 memcpy(open->op_stateowner->so_replay.rp_openfh, 118 &resfh.fh_handle.fh_base, resfh.fh_handle.fh_size); 119 120 if (!created) 121 status = do_open_permission(rqstp, current_fh, open, MAY_NOP); 122 123 out: 124 fh_put(&resfh); 125 return status; 126 } 127 128 static __be32 129 do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 130 { 131 __be32 status; 132 133 /* Only reclaims from previously confirmed clients are valid */ 134 if ((status = nfs4_check_open_reclaim(&open->op_clientid))) 135 return status; 136 137 /* We don't know the target directory, and therefore can not 138 * set the change info 139 */ 140 141 memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info)); 142 143 /* set replay cache */ 144 open->op_stateowner->so_replay.rp_openfh_len = current_fh->fh_handle.fh_size; 145 memcpy(open->op_stateowner->so_replay.rp_openfh, 146 ¤t_fh->fh_handle.fh_base, 147 current_fh->fh_handle.fh_size); 148 149 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && 150 (open->op_iattr.ia_size == 0); 151 152 status = do_open_permission(rqstp, current_fh, open, MAY_OWNER_OVERRIDE); 153 154 return status; 155 } 156 157 158 static __be32 159 nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 160 struct nfsd4_open *open) 161 { 162 __be32 status; 163 dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", 164 (int)open->op_fname.len, open->op_fname.data, 165 open->op_stateowner); 166 167 /* This check required by spec. */ 168 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) 169 return nfserr_inval; 170 171 nfs4_lock_state(); 172 173 /* check seqid for replay. set nfs4_owner */ 174 status = nfsd4_process_open1(open); 175 if (status == nfserr_replay_me) { 176 struct nfs4_replay *rp = &open->op_stateowner->so_replay; 177 fh_put(&cstate->current_fh); 178 cstate->current_fh.fh_handle.fh_size = rp->rp_openfh_len; 179 memcpy(&cstate->current_fh.fh_handle.fh_base, rp->rp_openfh, 180 rp->rp_openfh_len); 181 status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); 182 if (status) 183 dprintk("nfsd4_open: replay failed" 184 " restoring previous filehandle\n"); 185 else 186 status = nfserr_replay_me; 187 } 188 if (status) 189 goto out; 190 191 /* Openowner is now set, so sequence id will get bumped. Now we need 192 * these checks before we do any creates: */ 193 status = nfserr_grace; 194 if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 195 goto out; 196 status = nfserr_no_grace; 197 if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) 198 goto out; 199 200 switch (open->op_claim_type) { 201 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 202 status = nfserr_inval; 203 if (open->op_create) 204 goto out; 205 /* fall through */ 206 case NFS4_OPEN_CLAIM_NULL: 207 /* 208 * (1) set CURRENT_FH to the file being opened, 209 * creating it if necessary, (2) set open->op_cinfo, 210 * (3) set open->op_truncate if the file is to be 211 * truncated after opening, (4) do permission checking. 212 */ 213 status = do_open_lookup(rqstp, &cstate->current_fh, 214 open); 215 if (status) 216 goto out; 217 break; 218 case NFS4_OPEN_CLAIM_PREVIOUS: 219 open->op_stateowner->so_confirmed = 1; 220 /* 221 * The CURRENT_FH is already set to the file being 222 * opened. (1) set open->op_cinfo, (2) set 223 * open->op_truncate if the file is to be truncated 224 * after opening, (3) do permission checking. 225 */ 226 status = do_open_fhandle(rqstp, &cstate->current_fh, 227 open); 228 if (status) 229 goto out; 230 break; 231 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 232 open->op_stateowner->so_confirmed = 1; 233 printk("NFSD: unsupported OPEN claim type %d\n", 234 open->op_claim_type); 235 status = nfserr_notsupp; 236 goto out; 237 default: 238 printk("NFSD: Invalid OPEN claim type %d\n", 239 open->op_claim_type); 240 status = nfserr_inval; 241 goto out; 242 } 243 /* 244 * nfsd4_process_open2() does the actual opening of the file. If 245 * successful, it (1) truncates the file if open->op_truncate was 246 * set, (2) sets open->op_stateid, (3) sets open->op_delegation. 247 */ 248 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); 249 out: 250 if (open->op_stateowner) { 251 nfs4_get_stateowner(open->op_stateowner); 252 cstate->replay_owner = open->op_stateowner; 253 } 254 nfs4_unlock_state(); 255 return status; 256 } 257 258 /* 259 * filehandle-manipulating ops. 260 */ 261 static __be32 262 nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 263 struct svc_fh **getfh) 264 { 265 if (!cstate->current_fh.fh_dentry) 266 return nfserr_nofilehandle; 267 268 *getfh = &cstate->current_fh; 269 return nfs_ok; 270 } 271 272 static __be32 273 nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 274 struct nfsd4_putfh *putfh) 275 { 276 fh_put(&cstate->current_fh); 277 cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; 278 memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, 279 putfh->pf_fhlen); 280 return fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); 281 } 282 283 static __be32 284 nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 285 void *arg) 286 { 287 __be32 status; 288 289 fh_put(&cstate->current_fh); 290 status = exp_pseudoroot(rqstp, &cstate->current_fh); 291 return status; 292 } 293 294 static __be32 295 nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 296 void *arg) 297 { 298 if (!cstate->save_fh.fh_dentry) 299 return nfserr_restorefh; 300 301 fh_dup2(&cstate->current_fh, &cstate->save_fh); 302 return nfs_ok; 303 } 304 305 static __be32 306 nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 307 void *arg) 308 { 309 if (!cstate->current_fh.fh_dentry) 310 return nfserr_nofilehandle; 311 312 fh_dup2(&cstate->save_fh, &cstate->current_fh); 313 return nfs_ok; 314 } 315 316 /* 317 * misc nfsv4 ops 318 */ 319 static __be32 320 nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 321 struct nfsd4_access *access) 322 { 323 if (access->ac_req_access & ~NFS3_ACCESS_FULL) 324 return nfserr_inval; 325 326 access->ac_resp_access = access->ac_req_access; 327 return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access, 328 &access->ac_supported); 329 } 330 331 static __be32 332 nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 333 struct nfsd4_commit *commit) 334 { 335 __be32 status; 336 337 u32 *p = (u32 *)commit->co_verf.data; 338 *p++ = nfssvc_boot.tv_sec; 339 *p++ = nfssvc_boot.tv_usec; 340 341 status = nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, 342 commit->co_count); 343 if (status == nfserr_symlink) 344 status = nfserr_inval; 345 return status; 346 } 347 348 static __be32 349 nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 350 struct nfsd4_create *create) 351 { 352 struct svc_fh resfh; 353 __be32 status; 354 dev_t rdev; 355 356 fh_init(&resfh, NFS4_FHSIZE); 357 358 status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, MAY_CREATE); 359 if (status == nfserr_symlink) 360 status = nfserr_notdir; 361 if (status) 362 return status; 363 364 switch (create->cr_type) { 365 case NF4LNK: 366 /* ugh! we have to null-terminate the linktext, or 367 * vfs_symlink() will choke. it is always safe to 368 * null-terminate by brute force, since at worst we 369 * will overwrite the first byte of the create namelen 370 * in the XDR buffer, which has already been extracted 371 * during XDR decode. 372 */ 373 create->cr_linkname[create->cr_linklen] = 0; 374 375 status = nfsd_symlink(rqstp, &cstate->current_fh, 376 create->cr_name, create->cr_namelen, 377 create->cr_linkname, create->cr_linklen, 378 &resfh, &create->cr_iattr); 379 break; 380 381 case NF4BLK: 382 rdev = MKDEV(create->cr_specdata1, create->cr_specdata2); 383 if (MAJOR(rdev) != create->cr_specdata1 || 384 MINOR(rdev) != create->cr_specdata2) 385 return nfserr_inval; 386 status = nfsd_create(rqstp, &cstate->current_fh, 387 create->cr_name, create->cr_namelen, 388 &create->cr_iattr, S_IFBLK, rdev, &resfh); 389 break; 390 391 case NF4CHR: 392 rdev = MKDEV(create->cr_specdata1, create->cr_specdata2); 393 if (MAJOR(rdev) != create->cr_specdata1 || 394 MINOR(rdev) != create->cr_specdata2) 395 return nfserr_inval; 396 status = nfsd_create(rqstp, &cstate->current_fh, 397 create->cr_name, create->cr_namelen, 398 &create->cr_iattr,S_IFCHR, rdev, &resfh); 399 break; 400 401 case NF4SOCK: 402 status = nfsd_create(rqstp, &cstate->current_fh, 403 create->cr_name, create->cr_namelen, 404 &create->cr_iattr, S_IFSOCK, 0, &resfh); 405 break; 406 407 case NF4FIFO: 408 status = nfsd_create(rqstp, &cstate->current_fh, 409 create->cr_name, create->cr_namelen, 410 &create->cr_iattr, S_IFIFO, 0, &resfh); 411 break; 412 413 case NF4DIR: 414 create->cr_iattr.ia_valid &= ~ATTR_SIZE; 415 status = nfsd_create(rqstp, &cstate->current_fh, 416 create->cr_name, create->cr_namelen, 417 &create->cr_iattr, S_IFDIR, 0, &resfh); 418 break; 419 420 default: 421 status = nfserr_badtype; 422 } 423 424 if (!status) { 425 fh_unlock(&cstate->current_fh); 426 set_change_info(&create->cr_cinfo, &cstate->current_fh); 427 fh_dup2(&cstate->current_fh, &resfh); 428 } 429 430 fh_put(&resfh); 431 return status; 432 } 433 434 static __be32 435 nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 436 struct nfsd4_getattr *getattr) 437 { 438 __be32 status; 439 440 status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); 441 if (status) 442 return status; 443 444 if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) 445 return nfserr_inval; 446 447 getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; 448 getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; 449 450 getattr->ga_fhp = &cstate->current_fh; 451 return nfs_ok; 452 } 453 454 static __be32 455 nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 456 struct nfsd4_link *link) 457 { 458 __be32 status = nfserr_nofilehandle; 459 460 if (!cstate->save_fh.fh_dentry) 461 return status; 462 status = nfsd_link(rqstp, &cstate->current_fh, 463 link->li_name, link->li_namelen, &cstate->save_fh); 464 if (!status) 465 set_change_info(&link->li_cinfo, &cstate->current_fh); 466 return status; 467 } 468 469 static __be32 470 nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 471 void *arg) 472 { 473 struct svc_fh tmp_fh; 474 __be32 ret; 475 476 fh_init(&tmp_fh, NFS4_FHSIZE); 477 ret = exp_pseudoroot(rqstp, &tmp_fh); 478 if (ret) 479 return ret; 480 if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) { 481 fh_put(&tmp_fh); 482 return nfserr_noent; 483 } 484 fh_put(&tmp_fh); 485 return nfsd_lookup(rqstp, &cstate->current_fh, 486 "..", 2, &cstate->current_fh); 487 } 488 489 static __be32 490 nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 491 struct nfsd4_lookup *lookup) 492 { 493 return nfsd_lookup(rqstp, &cstate->current_fh, 494 lookup->lo_name, lookup->lo_len, 495 &cstate->current_fh); 496 } 497 498 static __be32 499 nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 500 struct nfsd4_read *read) 501 { 502 __be32 status; 503 504 /* no need to check permission - this will be done in nfsd_read() */ 505 506 read->rd_filp = NULL; 507 if (read->rd_offset >= OFFSET_MAX) 508 return nfserr_inval; 509 510 nfs4_lock_state(); 511 /* check stateid */ 512 if ((status = nfs4_preprocess_stateid_op(&cstate->current_fh, 513 &read->rd_stateid, 514 CHECK_FH | RD_STATE, &read->rd_filp))) { 515 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); 516 goto out; 517 } 518 if (read->rd_filp) 519 get_file(read->rd_filp); 520 status = nfs_ok; 521 out: 522 nfs4_unlock_state(); 523 read->rd_rqstp = rqstp; 524 read->rd_fhp = &cstate->current_fh; 525 return status; 526 } 527 528 static __be32 529 nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 530 struct nfsd4_readdir *readdir) 531 { 532 u64 cookie = readdir->rd_cookie; 533 static const nfs4_verifier zeroverf; 534 535 /* no need to check permission - this will be done in nfsd_readdir() */ 536 537 if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) 538 return nfserr_inval; 539 540 readdir->rd_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; 541 readdir->rd_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; 542 543 if ((cookie > ~(u32)0) || (cookie == 1) || (cookie == 2) || 544 (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE))) 545 return nfserr_bad_cookie; 546 547 readdir->rd_rqstp = rqstp; 548 readdir->rd_fhp = &cstate->current_fh; 549 return nfs_ok; 550 } 551 552 static __be32 553 nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 554 struct nfsd4_readlink *readlink) 555 { 556 readlink->rl_rqstp = rqstp; 557 readlink->rl_fhp = &cstate->current_fh; 558 return nfs_ok; 559 } 560 561 static __be32 562 nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 563 struct nfsd4_remove *remove) 564 { 565 __be32 status; 566 567 if (nfs4_in_grace()) 568 return nfserr_grace; 569 status = nfsd_unlink(rqstp, &cstate->current_fh, 0, 570 remove->rm_name, remove->rm_namelen); 571 if (status == nfserr_symlink) 572 return nfserr_notdir; 573 if (!status) { 574 fh_unlock(&cstate->current_fh); 575 set_change_info(&remove->rm_cinfo, &cstate->current_fh); 576 } 577 return status; 578 } 579 580 static __be32 581 nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 582 struct nfsd4_rename *rename) 583 { 584 __be32 status = nfserr_nofilehandle; 585 586 if (!cstate->save_fh.fh_dentry) 587 return status; 588 if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags 589 & NFSEXP_NOSUBTREECHECK)) 590 return nfserr_grace; 591 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, 592 rename->rn_snamelen, &cstate->current_fh, 593 rename->rn_tname, rename->rn_tnamelen); 594 595 /* the underlying filesystem returns different error's than required 596 * by NFSv4. both save_fh and current_fh have been verified.. */ 597 if (status == nfserr_isdir) 598 status = nfserr_exist; 599 else if ((status == nfserr_notdir) && 600 (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) && 601 S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode))) 602 status = nfserr_exist; 603 else if (status == nfserr_symlink) 604 status = nfserr_notdir; 605 606 if (!status) { 607 set_change_info(&rename->rn_sinfo, &cstate->current_fh); 608 set_change_info(&rename->rn_tinfo, &cstate->save_fh); 609 } 610 return status; 611 } 612 613 static __be32 614 nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 615 struct nfsd4_secinfo *secinfo) 616 { 617 struct svc_fh resfh; 618 struct svc_export *exp; 619 struct dentry *dentry; 620 __be32 err; 621 622 fh_init(&resfh, NFS4_FHSIZE); 623 err = nfsd_lookup_dentry(rqstp, &cstate->current_fh, 624 secinfo->si_name, secinfo->si_namelen, 625 &exp, &dentry); 626 if (err) 627 return err; 628 if (dentry->d_inode == NULL) { 629 exp_put(exp); 630 err = nfserr_noent; 631 } else 632 secinfo->si_exp = exp; 633 dput(dentry); 634 return err; 635 } 636 637 static __be32 638 nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 639 struct nfsd4_setattr *setattr) 640 { 641 __be32 status = nfs_ok; 642 643 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { 644 nfs4_lock_state(); 645 status = nfs4_preprocess_stateid_op(&cstate->current_fh, 646 &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL); 647 nfs4_unlock_state(); 648 if (status) { 649 dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); 650 return status; 651 } 652 } 653 status = nfs_ok; 654 if (setattr->sa_acl != NULL) 655 status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, 656 setattr->sa_acl); 657 if (status) 658 return status; 659 status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, 660 0, (time_t)0); 661 return status; 662 } 663 664 static __be32 665 nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 666 struct nfsd4_write *write) 667 { 668 stateid_t *stateid = &write->wr_stateid; 669 struct file *filp = NULL; 670 u32 *p; 671 __be32 status = nfs_ok; 672 673 /* no need to check permission - this will be done in nfsd_write() */ 674 675 if (write->wr_offset >= OFFSET_MAX) 676 return nfserr_inval; 677 678 nfs4_lock_state(); 679 status = nfs4_preprocess_stateid_op(&cstate->current_fh, stateid, 680 CHECK_FH | WR_STATE, &filp); 681 if (filp) 682 get_file(filp); 683 nfs4_unlock_state(); 684 685 if (status) { 686 dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); 687 return status; 688 } 689 690 write->wr_bytes_written = write->wr_buflen; 691 write->wr_how_written = write->wr_stable_how; 692 p = (u32 *)write->wr_verifier.data; 693 *p++ = nfssvc_boot.tv_sec; 694 *p++ = nfssvc_boot.tv_usec; 695 696 status = nfsd_write(rqstp, &cstate->current_fh, filp, 697 write->wr_offset, rqstp->rq_vec, write->wr_vlen, 698 write->wr_buflen, &write->wr_how_written); 699 if (filp) 700 fput(filp); 701 702 if (status == nfserr_symlink) 703 status = nfserr_inval; 704 return status; 705 } 706 707 /* This routine never returns NFS_OK! If there are no other errors, it 708 * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the 709 * attributes matched. VERIFY is implemented by mapping NFSERR_SAME 710 * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. 711 */ 712 static __be32 713 _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 714 struct nfsd4_verify *verify) 715 { 716 __be32 *buf, *p; 717 int count; 718 __be32 status; 719 720 status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); 721 if (status) 722 return status; 723 724 if ((verify->ve_bmval[0] & ~NFSD_SUPPORTED_ATTRS_WORD0) 725 || (verify->ve_bmval[1] & ~NFSD_SUPPORTED_ATTRS_WORD1)) 726 return nfserr_attrnotsupp; 727 if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR) 728 || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)) 729 return nfserr_inval; 730 if (verify->ve_attrlen & 3) 731 return nfserr_inval; 732 733 /* count in words: 734 * bitmap_len(1) + bitmap(2) + attr_len(1) = 4 735 */ 736 count = 4 + (verify->ve_attrlen >> 2); 737 buf = kmalloc(count << 2, GFP_KERNEL); 738 if (!buf) 739 return nfserr_resource; 740 741 status = nfsd4_encode_fattr(&cstate->current_fh, 742 cstate->current_fh.fh_export, 743 cstate->current_fh.fh_dentry, buf, 744 &count, verify->ve_bmval, 745 rqstp); 746 747 /* this means that nfsd4_encode_fattr() ran out of space */ 748 if (status == nfserr_resource && count == 0) 749 status = nfserr_not_same; 750 if (status) 751 goto out_kfree; 752 753 p = buf + 3; 754 status = nfserr_not_same; 755 if (ntohl(*p++) != verify->ve_attrlen) 756 goto out_kfree; 757 if (!memcmp(p, verify->ve_attrval, verify->ve_attrlen)) 758 status = nfserr_same; 759 760 out_kfree: 761 kfree(buf); 762 return status; 763 } 764 765 static __be32 766 nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 767 struct nfsd4_verify *verify) 768 { 769 __be32 status; 770 771 status = _nfsd4_verify(rqstp, cstate, verify); 772 return status == nfserr_not_same ? nfs_ok : status; 773 } 774 775 static __be32 776 nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 777 struct nfsd4_verify *verify) 778 { 779 __be32 status; 780 781 status = _nfsd4_verify(rqstp, cstate, verify); 782 return status == nfserr_same ? nfs_ok : status; 783 } 784 785 /* 786 * NULL call. 787 */ 788 static __be32 789 nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) 790 { 791 return nfs_ok; 792 } 793 794 static inline void nfsd4_increment_op_stats(u32 opnum) 795 { 796 if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP) 797 nfsdstats.nfs4_opcount[opnum]++; 798 } 799 800 static void cstate_free(struct nfsd4_compound_state *cstate) 801 { 802 if (cstate == NULL) 803 return; 804 fh_put(&cstate->current_fh); 805 fh_put(&cstate->save_fh); 806 BUG_ON(cstate->replay_owner); 807 kfree(cstate); 808 } 809 810 static struct nfsd4_compound_state *cstate_alloc(void) 811 { 812 struct nfsd4_compound_state *cstate; 813 814 cstate = kmalloc(sizeof(struct nfsd4_compound_state), GFP_KERNEL); 815 if (cstate == NULL) 816 return NULL; 817 fh_init(&cstate->current_fh, NFS4_FHSIZE); 818 fh_init(&cstate->save_fh, NFS4_FHSIZE); 819 cstate->replay_owner = NULL; 820 return cstate; 821 } 822 823 typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 824 void *); 825 826 struct nfsd4_operation { 827 nfsd4op_func op_func; 828 u32 op_flags; 829 /* Most ops require a valid current filehandle; a few don't: */ 830 #define ALLOWED_WITHOUT_FH 1 831 /* GETATTR and ops not listed as returning NFS4ERR_MOVED: */ 832 #define ALLOWED_ON_ABSENT_FS 2 833 }; 834 835 static struct nfsd4_operation nfsd4_ops[]; 836 837 /* 838 * COMPOUND call. 839 */ 840 static __be32 841 nfsd4_proc_compound(struct svc_rqst *rqstp, 842 struct nfsd4_compoundargs *args, 843 struct nfsd4_compoundres *resp) 844 { 845 struct nfsd4_op *op; 846 struct nfsd4_operation *opdesc; 847 struct nfsd4_compound_state *cstate = NULL; 848 int slack_bytes; 849 __be32 status; 850 851 status = nfserr_resource; 852 cstate = cstate_alloc(); 853 if (cstate == NULL) 854 goto out; 855 856 resp->xbuf = &rqstp->rq_res; 857 resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; 858 resp->tagp = resp->p; 859 /* reserve space for: taglen, tag, and opcnt */ 860 resp->p += 2 + XDR_QUADLEN(args->taglen); 861 resp->end = rqstp->rq_res.head[0].iov_base + PAGE_SIZE; 862 resp->taglen = args->taglen; 863 resp->tag = args->tag; 864 resp->opcnt = 0; 865 resp->rqstp = rqstp; 866 867 /* 868 * According to RFC3010, this takes precedence over all other errors. 869 */ 870 status = nfserr_minor_vers_mismatch; 871 if (args->minorversion > NFSD_SUPPORTED_MINOR_VERSION) 872 goto out; 873 874 status = nfs_ok; 875 while (!status && resp->opcnt < args->opcnt) { 876 op = &args->ops[resp->opcnt++]; 877 878 dprintk("nfsv4 compound op #%d: %d\n", resp->opcnt, op->opnum); 879 880 /* 881 * The XDR decode routines may have pre-set op->status; 882 * for example, if there is a miscellaneous XDR error 883 * it will be set to nfserr_bad_xdr. 884 */ 885 if (op->status) 886 goto encode_op; 887 888 /* We must be able to encode a successful response to 889 * this operation, with enough room left over to encode a 890 * failed response to the next operation. If we don't 891 * have enough room, fail with ERR_RESOURCE. 892 */ 893 slack_bytes = (char *)resp->end - (char *)resp->p; 894 if (slack_bytes < COMPOUND_SLACK_SPACE 895 + COMPOUND_ERR_SLACK_SPACE) { 896 BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE); 897 op->status = nfserr_resource; 898 goto encode_op; 899 } 900 901 opdesc = &nfsd4_ops[op->opnum]; 902 903 if (!cstate->current_fh.fh_dentry) { 904 if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { 905 op->status = nfserr_nofilehandle; 906 goto encode_op; 907 } 908 } else if (cstate->current_fh.fh_export->ex_fslocs.migrated && 909 !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { 910 op->status = nfserr_moved; 911 goto encode_op; 912 } 913 914 if (opdesc->op_func) 915 op->status = opdesc->op_func(rqstp, cstate, &op->u); 916 else 917 BUG_ON(op->status == nfs_ok); 918 919 encode_op: 920 if (op->status == nfserr_replay_me) { 921 op->replay = &cstate->replay_owner->so_replay; 922 nfsd4_encode_replay(resp, op); 923 status = op->status = op->replay->rp_status; 924 } else { 925 nfsd4_encode_operation(resp, op); 926 status = op->status; 927 } 928 if (cstate->replay_owner) { 929 nfs4_put_stateowner(cstate->replay_owner); 930 cstate->replay_owner = NULL; 931 } 932 /* XXX Ugh, we need to get rid of this kind of special case: */ 933 if (op->opnum == OP_READ && op->u.read.rd_filp) 934 fput(op->u.read.rd_filp); 935 936 nfsd4_increment_op_stats(op->opnum); 937 } 938 939 out: 940 nfsd4_release_compoundargs(args); 941 cstate_free(cstate); 942 return status; 943 } 944 945 static struct nfsd4_operation nfsd4_ops[OP_RELEASE_LOCKOWNER+1] = { 946 [OP_ACCESS] = { 947 .op_func = (nfsd4op_func)nfsd4_access, 948 }, 949 [OP_CLOSE] = { 950 .op_func = (nfsd4op_func)nfsd4_close, 951 }, 952 [OP_COMMIT] = { 953 .op_func = (nfsd4op_func)nfsd4_commit, 954 }, 955 [OP_CREATE] = { 956 .op_func = (nfsd4op_func)nfsd4_create, 957 }, 958 [OP_DELEGRETURN] = { 959 .op_func = (nfsd4op_func)nfsd4_delegreturn, 960 }, 961 [OP_GETATTR] = { 962 .op_func = (nfsd4op_func)nfsd4_getattr, 963 .op_flags = ALLOWED_ON_ABSENT_FS, 964 }, 965 [OP_GETFH] = { 966 .op_func = (nfsd4op_func)nfsd4_getfh, 967 }, 968 [OP_LINK] = { 969 .op_func = (nfsd4op_func)nfsd4_link, 970 }, 971 [OP_LOCK] = { 972 .op_func = (nfsd4op_func)nfsd4_lock, 973 }, 974 [OP_LOCKT] = { 975 .op_func = (nfsd4op_func)nfsd4_lockt, 976 }, 977 [OP_LOCKU] = { 978 .op_func = (nfsd4op_func)nfsd4_locku, 979 }, 980 [OP_LOOKUP] = { 981 .op_func = (nfsd4op_func)nfsd4_lookup, 982 }, 983 [OP_LOOKUPP] = { 984 .op_func = (nfsd4op_func)nfsd4_lookupp, 985 }, 986 [OP_NVERIFY] = { 987 .op_func = (nfsd4op_func)nfsd4_nverify, 988 }, 989 [OP_OPEN] = { 990 .op_func = (nfsd4op_func)nfsd4_open, 991 }, 992 [OP_OPEN_CONFIRM] = { 993 .op_func = (nfsd4op_func)nfsd4_open_confirm, 994 }, 995 [OP_OPEN_DOWNGRADE] = { 996 .op_func = (nfsd4op_func)nfsd4_open_downgrade, 997 }, 998 [OP_PUTFH] = { 999 .op_func = (nfsd4op_func)nfsd4_putfh, 1000 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1001 }, 1002 [OP_PUTPUBFH] = { 1003 /* unsupported; just for future reference: */ 1004 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1005 }, 1006 [OP_PUTROOTFH] = { 1007 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1008 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1009 }, 1010 [OP_READ] = { 1011 .op_func = (nfsd4op_func)nfsd4_read, 1012 }, 1013 [OP_READDIR] = { 1014 .op_func = (nfsd4op_func)nfsd4_readdir, 1015 }, 1016 [OP_READLINK] = { 1017 .op_func = (nfsd4op_func)nfsd4_readlink, 1018 }, 1019 [OP_REMOVE] = { 1020 .op_func = (nfsd4op_func)nfsd4_remove, 1021 }, 1022 [OP_RENAME] = { 1023 .op_func = (nfsd4op_func)nfsd4_rename, 1024 }, 1025 [OP_RENEW] = { 1026 .op_func = (nfsd4op_func)nfsd4_renew, 1027 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1028 }, 1029 [OP_RESTOREFH] = { 1030 .op_func = (nfsd4op_func)nfsd4_restorefh, 1031 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1032 }, 1033 [OP_SAVEFH] = { 1034 .op_func = (nfsd4op_func)nfsd4_savefh, 1035 }, 1036 [OP_SECINFO] = { 1037 .op_func = (nfsd4op_func)nfsd4_secinfo, 1038 }, 1039 [OP_SETATTR] = { 1040 .op_func = (nfsd4op_func)nfsd4_setattr, 1041 }, 1042 [OP_SETCLIENTID] = { 1043 .op_func = (nfsd4op_func)nfsd4_setclientid, 1044 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1045 }, 1046 [OP_SETCLIENTID_CONFIRM] = { 1047 .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, 1048 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1049 }, 1050 [OP_VERIFY] = { 1051 .op_func = (nfsd4op_func)nfsd4_verify, 1052 }, 1053 [OP_WRITE] = { 1054 .op_func = (nfsd4op_func)nfsd4_write, 1055 }, 1056 [OP_RELEASE_LOCKOWNER] = { 1057 .op_func = (nfsd4op_func)nfsd4_release_lockowner, 1058 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, 1059 }, 1060 }; 1061 1062 #define nfs4svc_decode_voidargs NULL 1063 #define nfs4svc_release_void NULL 1064 #define nfsd4_voidres nfsd4_voidargs 1065 #define nfs4svc_release_compound NULL 1066 struct nfsd4_voidargs { int dummy; }; 1067 1068 #define PROC(name, argt, rest, relt, cache, respsize) \ 1069 { (svc_procfunc) nfsd4_proc_##name, \ 1070 (kxdrproc_t) nfs4svc_decode_##argt##args, \ 1071 (kxdrproc_t) nfs4svc_encode_##rest##res, \ 1072 (kxdrproc_t) nfs4svc_release_##relt, \ 1073 sizeof(struct nfsd4_##argt##args), \ 1074 sizeof(struct nfsd4_##rest##res), \ 1075 0, \ 1076 cache, \ 1077 respsize, \ 1078 } 1079 1080 /* 1081 * TODO: At the present time, the NFSv4 server does not do XID caching 1082 * of requests. Implementing XID caching would not be a serious problem, 1083 * although it would require a mild change in interfaces since one 1084 * doesn't know whether an NFSv4 request is idempotent until after the 1085 * XDR decode. However, XID caching totally confuses pynfs (Peter 1086 * Astrand's regression testsuite for NFSv4 servers), which reuses 1087 * XID's liberally, so I've left it unimplemented until pynfs generates 1088 * better XID's. 1089 */ 1090 static struct svc_procedure nfsd_procedures4[2] = { 1091 PROC(null, void, void, void, RC_NOCACHE, 1), 1092 PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE/4) 1093 }; 1094 1095 struct svc_version nfsd_version4 = { 1096 .vs_vers = 4, 1097 .vs_nproc = 2, 1098 .vs_proc = nfsd_procedures4, 1099 .vs_dispatch = nfsd_dispatch, 1100 .vs_xdrsize = NFS4_SVC_XDRSIZE, 1101 }; 1102 1103 /* 1104 * Local variables: 1105 * c-basic-offset: 8 1106 * End: 1107 */ 1108