1 /* 2 * Server-side procedures for NFSv4. 3 * 4 * Copyright (c) 2002 The Regents of the University of Michigan. 5 * All rights reserved. 6 * 7 * Kendrick Smith <kmsmith@umich.edu> 8 * Andy Adamson <andros@umich.edu> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 #include <linux/file.h> 36 #include <linux/slab.h> 37 38 #include "idmap.h" 39 #include "cache.h" 40 #include "xdr4.h" 41 #include "vfs.h" 42 43 #define NFSDDBG_FACILITY NFSDDBG_PROC 44 45 static u32 nfsd_attrmask[] = { 46 NFSD_WRITEABLE_ATTRS_WORD0, 47 NFSD_WRITEABLE_ATTRS_WORD1, 48 NFSD_WRITEABLE_ATTRS_WORD2 49 }; 50 51 static u32 nfsd41_ex_attrmask[] = { 52 NFSD_SUPPATTR_EXCLCREAT_WORD0, 53 NFSD_SUPPATTR_EXCLCREAT_WORD1, 54 NFSD_SUPPATTR_EXCLCREAT_WORD2 55 }; 56 57 static __be32 58 check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 59 u32 *bmval, u32 *writable) 60 { 61 struct dentry *dentry = cstate->current_fh.fh_dentry; 62 63 /* 64 * Check about attributes are supported by the NFSv4 server or not. 65 * According to spec, unsupported attributes return ERR_ATTRNOTSUPP. 66 */ 67 if ((bmval[0] & ~nfsd_suppattrs0(cstate->minorversion)) || 68 (bmval[1] & ~nfsd_suppattrs1(cstate->minorversion)) || 69 (bmval[2] & ~nfsd_suppattrs2(cstate->minorversion))) 70 return nfserr_attrnotsupp; 71 72 /* 73 * Check FATTR4_WORD0_ACL can be supported 74 * in current environment or not. 75 */ 76 if (bmval[0] & FATTR4_WORD0_ACL) { 77 if (!IS_POSIXACL(dentry->d_inode)) 78 return nfserr_attrnotsupp; 79 } 80 81 /* 82 * According to spec, read-only attributes return ERR_INVAL. 83 */ 84 if (writable) { 85 if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) || 86 (bmval[2] & ~writable[2])) 87 return nfserr_inval; 88 } 89 90 return nfs_ok; 91 } 92 93 static __be32 94 nfsd4_check_open_attributes(struct svc_rqst *rqstp, 95 struct nfsd4_compound_state *cstate, struct nfsd4_open *open) 96 { 97 __be32 status = nfs_ok; 98 99 if (open->op_create == NFS4_OPEN_CREATE) { 100 if (open->op_createmode == NFS4_CREATE_UNCHECKED 101 || open->op_createmode == NFS4_CREATE_GUARDED) 102 status = check_attr_support(rqstp, cstate, 103 open->op_bmval, nfsd_attrmask); 104 else if (open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1) 105 status = check_attr_support(rqstp, cstate, 106 open->op_bmval, nfsd41_ex_attrmask); 107 } 108 109 return status; 110 } 111 112 static int 113 is_create_with_attrs(struct nfsd4_open *open) 114 { 115 return open->op_create == NFS4_OPEN_CREATE 116 && (open->op_createmode == NFS4_CREATE_UNCHECKED 117 || open->op_createmode == NFS4_CREATE_GUARDED 118 || open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1); 119 } 120 121 /* 122 * if error occurs when setting the acl, just clear the acl bit 123 * in the returned attr bitmap. 124 */ 125 static void 126 do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, 127 struct nfs4_acl *acl, u32 *bmval) 128 { 129 __be32 status; 130 131 status = nfsd4_set_nfs4_acl(rqstp, fhp, acl); 132 if (status) 133 /* 134 * We should probably fail the whole open at this point, 135 * but we've already created the file, so it's too late; 136 * So this seems the least of evils: 137 */ 138 bmval[0] &= ~FATTR4_WORD0_ACL; 139 } 140 141 static inline void 142 fh_dup2(struct svc_fh *dst, struct svc_fh *src) 143 { 144 fh_put(dst); 145 dget(src->fh_dentry); 146 if (src->fh_export) 147 cache_get(&src->fh_export->h); 148 *dst = *src; 149 } 150 151 static __be32 152 do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode) 153 { 154 __be32 status; 155 156 if (open->op_truncate && 157 !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) 158 return nfserr_inval; 159 160 accmode |= NFSD_MAY_READ_IF_EXEC; 161 162 if (open->op_share_access & NFS4_SHARE_ACCESS_READ) 163 accmode |= NFSD_MAY_READ; 164 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 165 accmode |= (NFSD_MAY_WRITE | NFSD_MAY_TRUNC); 166 if (open->op_share_deny & NFS4_SHARE_DENY_READ) 167 accmode |= NFSD_MAY_WRITE; 168 169 status = fh_verify(rqstp, current_fh, S_IFREG, accmode); 170 171 return status; 172 } 173 174 static __be32 nfsd_check_obj_isreg(struct svc_fh *fh) 175 { 176 umode_t mode = fh->fh_dentry->d_inode->i_mode; 177 178 if (S_ISREG(mode)) 179 return nfs_ok; 180 if (S_ISDIR(mode)) 181 return nfserr_isdir; 182 /* 183 * Using err_symlink as our catch-all case may look odd; but 184 * there's no other obvious error for this case in 4.0, and we 185 * happen to know that it will cause the linux v4 client to do 186 * the right thing on attempts to open something other than a 187 * regular file. 188 */ 189 return nfserr_symlink; 190 } 191 192 static __be32 193 do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 194 { 195 struct svc_fh resfh; 196 __be32 status; 197 198 fh_init(&resfh, NFS4_FHSIZE); 199 open->op_truncate = 0; 200 201 if (open->op_create) { 202 /* FIXME: check session persistence and pnfs flags. 203 * The nfsv4.1 spec requires the following semantics: 204 * 205 * Persistent | pNFS | Server REQUIRED | Client Allowed 206 * Reply Cache | server | | 207 * -------------+--------+-----------------+-------------------- 208 * no | no | EXCLUSIVE4_1 | EXCLUSIVE4_1 209 * | | | (SHOULD) 210 * | | and EXCLUSIVE4 | or EXCLUSIVE4 211 * | | | (SHOULD NOT) 212 * no | yes | EXCLUSIVE4_1 | EXCLUSIVE4_1 213 * yes | no | GUARDED4 | GUARDED4 214 * yes | yes | GUARDED4 | GUARDED4 215 */ 216 217 /* 218 * Note: create modes (UNCHECKED,GUARDED...) are the same 219 * in NFSv4 as in v3 except EXCLUSIVE4_1. 220 */ 221 status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, 222 open->op_fname.len, &open->op_iattr, 223 &resfh, open->op_createmode, 224 (u32 *)open->op_verf.data, 225 &open->op_truncate, &open->op_created); 226 227 /* 228 * Following rfc 3530 14.2.16, use the returned bitmask 229 * to indicate which attributes we used to store the 230 * verifier: 231 */ 232 if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) 233 open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | 234 FATTR4_WORD1_TIME_MODIFY); 235 } else { 236 status = nfsd_lookup(rqstp, current_fh, 237 open->op_fname.data, open->op_fname.len, &resfh); 238 fh_unlock(current_fh); 239 if (status) 240 goto out; 241 status = nfsd_check_obj_isreg(&resfh); 242 } 243 if (status) 244 goto out; 245 246 if (is_create_with_attrs(open) && open->op_acl != NULL) 247 do_set_nfs4_acl(rqstp, &resfh, open->op_acl, open->op_bmval); 248 249 set_change_info(&open->op_cinfo, current_fh); 250 fh_dup2(current_fh, &resfh); 251 252 /* set reply cache */ 253 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh, 254 &resfh.fh_handle); 255 if (!open->op_created) 256 status = do_open_permission(rqstp, current_fh, open, 257 NFSD_MAY_NOP); 258 259 out: 260 fh_put(&resfh); 261 return status; 262 } 263 264 static __be32 265 do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) 266 { 267 __be32 status; 268 269 /* We don't know the target directory, and therefore can not 270 * set the change info 271 */ 272 273 memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info)); 274 275 /* set replay cache */ 276 fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh, 277 ¤t_fh->fh_handle); 278 279 open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && 280 (open->op_iattr.ia_size == 0); 281 282 status = do_open_permission(rqstp, current_fh, open, 283 NFSD_MAY_OWNER_OVERRIDE); 284 285 return status; 286 } 287 288 static void 289 copy_clientid(clientid_t *clid, struct nfsd4_session *session) 290 { 291 struct nfsd4_sessionid *sid = 292 (struct nfsd4_sessionid *)session->se_sessionid.data; 293 294 clid->cl_boot = sid->clientid.cl_boot; 295 clid->cl_id = sid->clientid.cl_id; 296 } 297 298 static __be32 299 nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 300 struct nfsd4_open *open) 301 { 302 __be32 status; 303 struct nfsd4_compoundres *resp; 304 305 dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n", 306 (int)open->op_fname.len, open->op_fname.data, 307 open->op_openowner); 308 309 /* This check required by spec. */ 310 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) 311 return nfserr_inval; 312 313 /* We don't yet support WANT bits: */ 314 open->op_share_access &= NFS4_SHARE_ACCESS_MASK; 315 316 open->op_created = 0; 317 /* 318 * RFC5661 18.51.3 319 * Before RECLAIM_COMPLETE done, server should deny new lock 320 */ 321 if (nfsd4_has_session(cstate) && 322 !cstate->session->se_client->cl_firststate && 323 open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 324 return nfserr_grace; 325 326 if (nfsd4_has_session(cstate)) 327 copy_clientid(&open->op_clientid, cstate->session); 328 329 nfs4_lock_state(); 330 331 /* check seqid for replay. set nfs4_owner */ 332 resp = rqstp->rq_resp; 333 status = nfsd4_process_open1(&resp->cstate, open); 334 if (status == nfserr_replay_me) { 335 struct nfs4_replay *rp = &open->op_openowner->oo_owner.so_replay; 336 fh_put(&cstate->current_fh); 337 fh_copy_shallow(&cstate->current_fh.fh_handle, 338 &rp->rp_openfh); 339 status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); 340 if (status) 341 dprintk("nfsd4_open: replay failed" 342 " restoring previous filehandle\n"); 343 else 344 status = nfserr_replay_me; 345 } 346 if (status) 347 goto out; 348 349 status = nfsd4_check_open_attributes(rqstp, cstate, open); 350 if (status) 351 goto out; 352 353 /* Openowner is now set, so sequence id will get bumped. Now we need 354 * these checks before we do any creates: */ 355 status = nfserr_grace; 356 if (locks_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 357 goto out; 358 status = nfserr_no_grace; 359 if (!locks_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) 360 goto out; 361 362 switch (open->op_claim_type) { 363 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 364 case NFS4_OPEN_CLAIM_NULL: 365 status = do_open_lookup(rqstp, &cstate->current_fh, 366 open); 367 if (status) 368 goto out; 369 break; 370 case NFS4_OPEN_CLAIM_PREVIOUS: 371 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 372 status = nfs4_check_open_reclaim(&open->op_clientid); 373 if (status) 374 goto out; 375 case NFS4_OPEN_CLAIM_FH: 376 case NFS4_OPEN_CLAIM_DELEG_CUR_FH: 377 status = do_open_fhandle(rqstp, &cstate->current_fh, 378 open); 379 if (status) 380 goto out; 381 break; 382 case NFS4_OPEN_CLAIM_DELEG_PREV_FH: 383 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 384 open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; 385 dprintk("NFSD: unsupported OPEN claim type %d\n", 386 open->op_claim_type); 387 status = nfserr_notsupp; 388 goto out; 389 default: 390 dprintk("NFSD: Invalid OPEN claim type %d\n", 391 open->op_claim_type); 392 status = nfserr_inval; 393 goto out; 394 } 395 /* 396 * nfsd4_process_open2() does the actual opening of the file. If 397 * successful, it (1) truncates the file if open->op_truncate was 398 * set, (2) sets open->op_stateid, (3) sets open->op_delegation. 399 */ 400 status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); 401 WARN_ON(status && open->op_created); 402 out: 403 nfsd4_cleanup_open_state(open, status); 404 if (open->op_openowner) 405 cstate->replay_owner = &open->op_openowner->oo_owner; 406 else 407 nfs4_unlock_state(); 408 return status; 409 } 410 411 /* 412 * filehandle-manipulating ops. 413 */ 414 static __be32 415 nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 416 struct svc_fh **getfh) 417 { 418 if (!cstate->current_fh.fh_dentry) 419 return nfserr_nofilehandle; 420 421 *getfh = &cstate->current_fh; 422 return nfs_ok; 423 } 424 425 static __be32 426 nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 427 struct nfsd4_putfh *putfh) 428 { 429 fh_put(&cstate->current_fh); 430 cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; 431 memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, 432 putfh->pf_fhlen); 433 return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); 434 } 435 436 static __be32 437 nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 438 void *arg) 439 { 440 __be32 status; 441 442 fh_put(&cstate->current_fh); 443 status = exp_pseudoroot(rqstp, &cstate->current_fh); 444 return status; 445 } 446 447 static __be32 448 nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 449 void *arg) 450 { 451 if (!cstate->save_fh.fh_dentry) 452 return nfserr_restorefh; 453 454 fh_dup2(&cstate->current_fh, &cstate->save_fh); 455 return nfs_ok; 456 } 457 458 static __be32 459 nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 460 void *arg) 461 { 462 if (!cstate->current_fh.fh_dentry) 463 return nfserr_nofilehandle; 464 465 fh_dup2(&cstate->save_fh, &cstate->current_fh); 466 return nfs_ok; 467 } 468 469 /* 470 * misc nfsv4 ops 471 */ 472 static __be32 473 nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 474 struct nfsd4_access *access) 475 { 476 if (access->ac_req_access & ~NFS3_ACCESS_FULL) 477 return nfserr_inval; 478 479 access->ac_resp_access = access->ac_req_access; 480 return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access, 481 &access->ac_supported); 482 } 483 484 static __be32 485 nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 486 struct nfsd4_commit *commit) 487 { 488 u32 *p = (u32 *)commit->co_verf.data; 489 *p++ = nfssvc_boot.tv_sec; 490 *p++ = nfssvc_boot.tv_usec; 491 492 return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, 493 commit->co_count); 494 } 495 496 static __be32 497 nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 498 struct nfsd4_create *create) 499 { 500 struct svc_fh resfh; 501 __be32 status; 502 dev_t rdev; 503 504 fh_init(&resfh, NFS4_FHSIZE); 505 506 status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, 507 NFSD_MAY_CREATE); 508 if (status) 509 return status; 510 511 status = check_attr_support(rqstp, cstate, create->cr_bmval, 512 nfsd_attrmask); 513 if (status) 514 return status; 515 516 switch (create->cr_type) { 517 case NF4LNK: 518 /* ugh! we have to null-terminate the linktext, or 519 * vfs_symlink() will choke. it is always safe to 520 * null-terminate by brute force, since at worst we 521 * will overwrite the first byte of the create namelen 522 * in the XDR buffer, which has already been extracted 523 * during XDR decode. 524 */ 525 create->cr_linkname[create->cr_linklen] = 0; 526 527 status = nfsd_symlink(rqstp, &cstate->current_fh, 528 create->cr_name, create->cr_namelen, 529 create->cr_linkname, create->cr_linklen, 530 &resfh, &create->cr_iattr); 531 break; 532 533 case NF4BLK: 534 rdev = MKDEV(create->cr_specdata1, create->cr_specdata2); 535 if (MAJOR(rdev) != create->cr_specdata1 || 536 MINOR(rdev) != create->cr_specdata2) 537 return nfserr_inval; 538 status = nfsd_create(rqstp, &cstate->current_fh, 539 create->cr_name, create->cr_namelen, 540 &create->cr_iattr, S_IFBLK, rdev, &resfh); 541 break; 542 543 case NF4CHR: 544 rdev = MKDEV(create->cr_specdata1, create->cr_specdata2); 545 if (MAJOR(rdev) != create->cr_specdata1 || 546 MINOR(rdev) != create->cr_specdata2) 547 return nfserr_inval; 548 status = nfsd_create(rqstp, &cstate->current_fh, 549 create->cr_name, create->cr_namelen, 550 &create->cr_iattr,S_IFCHR, rdev, &resfh); 551 break; 552 553 case NF4SOCK: 554 status = nfsd_create(rqstp, &cstate->current_fh, 555 create->cr_name, create->cr_namelen, 556 &create->cr_iattr, S_IFSOCK, 0, &resfh); 557 break; 558 559 case NF4FIFO: 560 status = nfsd_create(rqstp, &cstate->current_fh, 561 create->cr_name, create->cr_namelen, 562 &create->cr_iattr, S_IFIFO, 0, &resfh); 563 break; 564 565 case NF4DIR: 566 create->cr_iattr.ia_valid &= ~ATTR_SIZE; 567 status = nfsd_create(rqstp, &cstate->current_fh, 568 create->cr_name, create->cr_namelen, 569 &create->cr_iattr, S_IFDIR, 0, &resfh); 570 break; 571 572 default: 573 status = nfserr_badtype; 574 } 575 576 if (status) 577 goto out; 578 579 if (create->cr_acl != NULL) 580 do_set_nfs4_acl(rqstp, &resfh, create->cr_acl, 581 create->cr_bmval); 582 583 fh_unlock(&cstate->current_fh); 584 set_change_info(&create->cr_cinfo, &cstate->current_fh); 585 fh_dup2(&cstate->current_fh, &resfh); 586 out: 587 fh_put(&resfh); 588 return status; 589 } 590 591 static __be32 592 nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 593 struct nfsd4_getattr *getattr) 594 { 595 __be32 status; 596 597 status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); 598 if (status) 599 return status; 600 601 if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) 602 return nfserr_inval; 603 604 getattr->ga_bmval[0] &= nfsd_suppattrs0(cstate->minorversion); 605 getattr->ga_bmval[1] &= nfsd_suppattrs1(cstate->minorversion); 606 getattr->ga_bmval[2] &= nfsd_suppattrs2(cstate->minorversion); 607 608 getattr->ga_fhp = &cstate->current_fh; 609 return nfs_ok; 610 } 611 612 static __be32 613 nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 614 struct nfsd4_link *link) 615 { 616 __be32 status = nfserr_nofilehandle; 617 618 if (!cstate->save_fh.fh_dentry) 619 return status; 620 status = nfsd_link(rqstp, &cstate->current_fh, 621 link->li_name, link->li_namelen, &cstate->save_fh); 622 if (!status) 623 set_change_info(&link->li_cinfo, &cstate->current_fh); 624 return status; 625 } 626 627 static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) 628 { 629 struct svc_fh tmp_fh; 630 __be32 ret; 631 632 fh_init(&tmp_fh, NFS4_FHSIZE); 633 ret = exp_pseudoroot(rqstp, &tmp_fh); 634 if (ret) 635 return ret; 636 if (tmp_fh.fh_dentry == fh->fh_dentry) { 637 fh_put(&tmp_fh); 638 return nfserr_noent; 639 } 640 fh_put(&tmp_fh); 641 return nfsd_lookup(rqstp, fh, "..", 2, fh); 642 } 643 644 static __be32 645 nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 646 void *arg) 647 { 648 return nfsd4_do_lookupp(rqstp, &cstate->current_fh); 649 } 650 651 static __be32 652 nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 653 struct nfsd4_lookup *lookup) 654 { 655 return nfsd_lookup(rqstp, &cstate->current_fh, 656 lookup->lo_name, lookup->lo_len, 657 &cstate->current_fh); 658 } 659 660 static __be32 661 nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 662 struct nfsd4_read *read) 663 { 664 __be32 status; 665 666 /* no need to check permission - this will be done in nfsd_read() */ 667 668 read->rd_filp = NULL; 669 if (read->rd_offset >= OFFSET_MAX) 670 return nfserr_inval; 671 672 nfs4_lock_state(); 673 /* check stateid */ 674 if ((status = nfs4_preprocess_stateid_op(cstate, &read->rd_stateid, 675 RD_STATE, &read->rd_filp))) { 676 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); 677 goto out; 678 } 679 if (read->rd_filp) 680 get_file(read->rd_filp); 681 status = nfs_ok; 682 out: 683 nfs4_unlock_state(); 684 read->rd_rqstp = rqstp; 685 read->rd_fhp = &cstate->current_fh; 686 return status; 687 } 688 689 static __be32 690 nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 691 struct nfsd4_readdir *readdir) 692 { 693 u64 cookie = readdir->rd_cookie; 694 static const nfs4_verifier zeroverf; 695 696 /* no need to check permission - this will be done in nfsd_readdir() */ 697 698 if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) 699 return nfserr_inval; 700 701 readdir->rd_bmval[0] &= nfsd_suppattrs0(cstate->minorversion); 702 readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion); 703 readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion); 704 705 if ((cookie == 1) || (cookie == 2) || 706 (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE))) 707 return nfserr_bad_cookie; 708 709 readdir->rd_rqstp = rqstp; 710 readdir->rd_fhp = &cstate->current_fh; 711 return nfs_ok; 712 } 713 714 static __be32 715 nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 716 struct nfsd4_readlink *readlink) 717 { 718 readlink->rl_rqstp = rqstp; 719 readlink->rl_fhp = &cstate->current_fh; 720 return nfs_ok; 721 } 722 723 static __be32 724 nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 725 struct nfsd4_remove *remove) 726 { 727 __be32 status; 728 729 if (locks_in_grace()) 730 return nfserr_grace; 731 status = nfsd_unlink(rqstp, &cstate->current_fh, 0, 732 remove->rm_name, remove->rm_namelen); 733 if (!status) { 734 fh_unlock(&cstate->current_fh); 735 set_change_info(&remove->rm_cinfo, &cstate->current_fh); 736 } 737 return status; 738 } 739 740 static __be32 741 nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 742 struct nfsd4_rename *rename) 743 { 744 __be32 status = nfserr_nofilehandle; 745 746 if (!cstate->save_fh.fh_dentry) 747 return status; 748 if (locks_in_grace() && !(cstate->save_fh.fh_export->ex_flags 749 & NFSEXP_NOSUBTREECHECK)) 750 return nfserr_grace; 751 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, 752 rename->rn_snamelen, &cstate->current_fh, 753 rename->rn_tname, rename->rn_tnamelen); 754 755 /* the underlying filesystem returns different error's than required 756 * by NFSv4. both save_fh and current_fh have been verified.. */ 757 if (status == nfserr_isdir) 758 status = nfserr_exist; 759 else if ((status == nfserr_notdir) && 760 (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) && 761 S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode))) 762 status = nfserr_exist; 763 764 if (!status) { 765 set_change_info(&rename->rn_sinfo, &cstate->current_fh); 766 set_change_info(&rename->rn_tinfo, &cstate->save_fh); 767 } 768 return status; 769 } 770 771 static __be32 772 nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 773 struct nfsd4_secinfo *secinfo) 774 { 775 struct svc_fh resfh; 776 struct svc_export *exp; 777 struct dentry *dentry; 778 __be32 err; 779 780 fh_init(&resfh, NFS4_FHSIZE); 781 err = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_EXEC); 782 if (err) 783 return err; 784 err = nfsd_lookup_dentry(rqstp, &cstate->current_fh, 785 secinfo->si_name, secinfo->si_namelen, 786 &exp, &dentry); 787 if (err) 788 return err; 789 if (dentry->d_inode == NULL) { 790 exp_put(exp); 791 err = nfserr_noent; 792 } else 793 secinfo->si_exp = exp; 794 dput(dentry); 795 if (cstate->minorversion) 796 /* See rfc 5661 section 2.6.3.1.1.8 */ 797 fh_put(&cstate->current_fh); 798 return err; 799 } 800 801 static __be32 802 nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 803 struct nfsd4_secinfo_no_name *sin) 804 { 805 __be32 err; 806 807 switch (sin->sin_style) { 808 case NFS4_SECINFO_STYLE4_CURRENT_FH: 809 break; 810 case NFS4_SECINFO_STYLE4_PARENT: 811 err = nfsd4_do_lookupp(rqstp, &cstate->current_fh); 812 if (err) 813 return err; 814 break; 815 default: 816 return nfserr_inval; 817 } 818 exp_get(cstate->current_fh.fh_export); 819 sin->sin_exp = cstate->current_fh.fh_export; 820 fh_put(&cstate->current_fh); 821 return nfs_ok; 822 } 823 824 static __be32 825 nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 826 struct nfsd4_setattr *setattr) 827 { 828 __be32 status = nfs_ok; 829 830 if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { 831 nfs4_lock_state(); 832 status = nfs4_preprocess_stateid_op(cstate, 833 &setattr->sa_stateid, WR_STATE, NULL); 834 nfs4_unlock_state(); 835 if (status) { 836 dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); 837 return status; 838 } 839 } 840 status = fh_want_write(&cstate->current_fh); 841 if (status) 842 return status; 843 status = nfs_ok; 844 845 status = check_attr_support(rqstp, cstate, setattr->sa_bmval, 846 nfsd_attrmask); 847 if (status) 848 goto out; 849 850 if (setattr->sa_acl != NULL) 851 status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, 852 setattr->sa_acl); 853 if (status) 854 goto out; 855 status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, 856 0, (time_t)0); 857 out: 858 fh_drop_write(&cstate->current_fh); 859 return status; 860 } 861 862 static __be32 863 nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 864 struct nfsd4_write *write) 865 { 866 stateid_t *stateid = &write->wr_stateid; 867 struct file *filp = NULL; 868 u32 *p; 869 __be32 status = nfs_ok; 870 unsigned long cnt; 871 872 /* no need to check permission - this will be done in nfsd_write() */ 873 874 if (write->wr_offset >= OFFSET_MAX) 875 return nfserr_inval; 876 877 nfs4_lock_state(); 878 status = nfs4_preprocess_stateid_op(cstate, stateid, WR_STATE, &filp); 879 if (filp) 880 get_file(filp); 881 nfs4_unlock_state(); 882 883 if (status) { 884 dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); 885 return status; 886 } 887 888 cnt = write->wr_buflen; 889 write->wr_how_written = write->wr_stable_how; 890 p = (u32 *)write->wr_verifier.data; 891 *p++ = nfssvc_boot.tv_sec; 892 *p++ = nfssvc_boot.tv_usec; 893 894 status = nfsd_write(rqstp, &cstate->current_fh, filp, 895 write->wr_offset, rqstp->rq_vec, write->wr_vlen, 896 &cnt, &write->wr_how_written); 897 if (filp) 898 fput(filp); 899 900 write->wr_bytes_written = cnt; 901 902 return status; 903 } 904 905 /* This routine never returns NFS_OK! If there are no other errors, it 906 * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the 907 * attributes matched. VERIFY is implemented by mapping NFSERR_SAME 908 * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. 909 */ 910 static __be32 911 _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 912 struct nfsd4_verify *verify) 913 { 914 __be32 *buf, *p; 915 int count; 916 __be32 status; 917 918 status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); 919 if (status) 920 return status; 921 922 status = check_attr_support(rqstp, cstate, verify->ve_bmval, NULL); 923 if (status) 924 return status; 925 926 if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR) 927 || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)) 928 return nfserr_inval; 929 if (verify->ve_attrlen & 3) 930 return nfserr_inval; 931 932 /* count in words: 933 * bitmap_len(1) + bitmap(2) + attr_len(1) = 4 934 */ 935 count = 4 + (verify->ve_attrlen >> 2); 936 buf = kmalloc(count << 2, GFP_KERNEL); 937 if (!buf) 938 return nfserr_jukebox; 939 940 status = nfsd4_encode_fattr(&cstate->current_fh, 941 cstate->current_fh.fh_export, 942 cstate->current_fh.fh_dentry, buf, 943 &count, verify->ve_bmval, 944 rqstp, 0); 945 946 /* this means that nfsd4_encode_fattr() ran out of space */ 947 if (status == nfserr_resource && count == 0) 948 status = nfserr_not_same; 949 if (status) 950 goto out_kfree; 951 952 /* skip bitmap */ 953 p = buf + 1 + ntohl(buf[0]); 954 status = nfserr_not_same; 955 if (ntohl(*p++) != verify->ve_attrlen) 956 goto out_kfree; 957 if (!memcmp(p, verify->ve_attrval, verify->ve_attrlen)) 958 status = nfserr_same; 959 960 out_kfree: 961 kfree(buf); 962 return status; 963 } 964 965 static __be32 966 nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 967 struct nfsd4_verify *verify) 968 { 969 __be32 status; 970 971 status = _nfsd4_verify(rqstp, cstate, verify); 972 return status == nfserr_not_same ? nfs_ok : status; 973 } 974 975 static __be32 976 nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 977 struct nfsd4_verify *verify) 978 { 979 __be32 status; 980 981 status = _nfsd4_verify(rqstp, cstate, verify); 982 return status == nfserr_same ? nfs_ok : status; 983 } 984 985 /* 986 * NULL call. 987 */ 988 static __be32 989 nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) 990 { 991 return nfs_ok; 992 } 993 994 static inline void nfsd4_increment_op_stats(u32 opnum) 995 { 996 if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP) 997 nfsdstats.nfs4_opcount[opnum]++; 998 } 999 1000 typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, 1001 void *); 1002 typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op); 1003 1004 enum nfsd4_op_flags { 1005 ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ 1006 ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ 1007 ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ 1008 /* For rfc 5661 section 2.6.3.1.1: */ 1009 OP_HANDLES_WRONGSEC = 1 << 3, 1010 OP_IS_PUTFH_LIKE = 1 << 4, 1011 /* 1012 * These are the ops whose result size we estimate before 1013 * encoding, to avoid performing an op then not being able to 1014 * respond or cache a response. This includes writes and setattrs 1015 * as well as the operations usually called "nonidempotent": 1016 */ 1017 OP_MODIFIES_SOMETHING = 1 << 5, 1018 /* 1019 * Cache compounds containing these ops in the xid-based drc: 1020 * We use the DRC for compounds containing non-idempotent 1021 * operations, *except* those that are 4.1-specific (since 1022 * sessions provide their own EOS), and except for stateful 1023 * operations other than setclientid and setclientid_confirm 1024 * (since sequence numbers provide EOS for open, lock, etc in 1025 * the v4.0 case). 1026 */ 1027 OP_CACHEME = 1 << 6, 1028 }; 1029 1030 struct nfsd4_operation { 1031 nfsd4op_func op_func; 1032 u32 op_flags; 1033 char *op_name; 1034 /* Try to get response size before operation */ 1035 nfsd4op_rsize op_rsize_bop; 1036 }; 1037 1038 static struct nfsd4_operation nfsd4_ops[]; 1039 1040 static const char *nfsd4_op_name(unsigned opnum); 1041 1042 /* 1043 * Enforce NFSv4.1 COMPOUND ordering rules: 1044 * 1045 * Also note, enforced elsewhere: 1046 * - SEQUENCE other than as first op results in 1047 * NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().) 1048 * - BIND_CONN_TO_SESSION must be the only op in its compound. 1049 * (Enforced in nfsd4_bind_conn_to_session().) 1050 * - DESTROY_SESSION must be the final operation in a compound, if 1051 * sessionid's in SEQUENCE and DESTROY_SESSION are the same. 1052 * (Enforced in nfsd4_destroy_session().) 1053 */ 1054 static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args) 1055 { 1056 struct nfsd4_op *op = &args->ops[0]; 1057 1058 /* These ordering requirements don't apply to NFSv4.0: */ 1059 if (args->minorversion == 0) 1060 return nfs_ok; 1061 /* This is weird, but OK, not our problem: */ 1062 if (args->opcnt == 0) 1063 return nfs_ok; 1064 if (op->status == nfserr_op_illegal) 1065 return nfs_ok; 1066 if (!(nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP)) 1067 return nfserr_op_not_in_session; 1068 if (op->opnum == OP_SEQUENCE) 1069 return nfs_ok; 1070 if (args->opcnt != 1) 1071 return nfserr_not_only_op; 1072 return nfs_ok; 1073 } 1074 1075 static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op) 1076 { 1077 return &nfsd4_ops[op->opnum]; 1078 } 1079 1080 bool nfsd4_cache_this_op(struct nfsd4_op *op) 1081 { 1082 return OPDESC(op)->op_flags & OP_CACHEME; 1083 } 1084 1085 static bool need_wrongsec_check(struct svc_rqst *rqstp) 1086 { 1087 struct nfsd4_compoundres *resp = rqstp->rq_resp; 1088 struct nfsd4_compoundargs *argp = rqstp->rq_argp; 1089 struct nfsd4_op *this = &argp->ops[resp->opcnt - 1]; 1090 struct nfsd4_op *next = &argp->ops[resp->opcnt]; 1091 struct nfsd4_operation *thisd; 1092 struct nfsd4_operation *nextd; 1093 1094 thisd = OPDESC(this); 1095 /* 1096 * Most ops check wronsec on our own; only the putfh-like ops 1097 * have special rules. 1098 */ 1099 if (!(thisd->op_flags & OP_IS_PUTFH_LIKE)) 1100 return false; 1101 /* 1102 * rfc 5661 2.6.3.1.1.6: don't bother erroring out a 1103 * put-filehandle operation if we're not going to use the 1104 * result: 1105 */ 1106 if (argp->opcnt == resp->opcnt) 1107 return false; 1108 1109 nextd = OPDESC(next); 1110 /* 1111 * Rest of 2.6.3.1.1: certain operations will return WRONGSEC 1112 * errors themselves as necessary; others should check for them 1113 * now: 1114 */ 1115 return !(nextd->op_flags & OP_HANDLES_WRONGSEC); 1116 } 1117 1118 /* 1119 * COMPOUND call. 1120 */ 1121 static __be32 1122 nfsd4_proc_compound(struct svc_rqst *rqstp, 1123 struct nfsd4_compoundargs *args, 1124 struct nfsd4_compoundres *resp) 1125 { 1126 struct nfsd4_op *op; 1127 struct nfsd4_operation *opdesc; 1128 struct nfsd4_compound_state *cstate = &resp->cstate; 1129 int slack_bytes; 1130 u32 plen = 0; 1131 __be32 status; 1132 1133 resp->xbuf = &rqstp->rq_res; 1134 resp->p = rqstp->rq_res.head[0].iov_base + 1135 rqstp->rq_res.head[0].iov_len; 1136 resp->tagp = resp->p; 1137 /* reserve space for: taglen, tag, and opcnt */ 1138 resp->p += 2 + XDR_QUADLEN(args->taglen); 1139 resp->end = rqstp->rq_res.head[0].iov_base + PAGE_SIZE; 1140 resp->taglen = args->taglen; 1141 resp->tag = args->tag; 1142 resp->opcnt = 0; 1143 resp->rqstp = rqstp; 1144 resp->cstate.minorversion = args->minorversion; 1145 resp->cstate.replay_owner = NULL; 1146 resp->cstate.session = NULL; 1147 fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); 1148 fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); 1149 /* 1150 * Don't use the deferral mechanism for NFSv4; compounds make it 1151 * too hard to avoid non-idempotency problems. 1152 */ 1153 rqstp->rq_usedeferral = 0; 1154 1155 /* 1156 * According to RFC3010, this takes precedence over all other errors. 1157 */ 1158 status = nfserr_minor_vers_mismatch; 1159 if (args->minorversion > nfsd_supported_minorversion) 1160 goto out; 1161 1162 status = nfs41_check_op_ordering(args); 1163 if (status) { 1164 op = &args->ops[0]; 1165 op->status = status; 1166 goto encode_op; 1167 } 1168 1169 while (!status && resp->opcnt < args->opcnt) { 1170 op = &args->ops[resp->opcnt++]; 1171 1172 dprintk("nfsv4 compound op #%d/%d: %d (%s)\n", 1173 resp->opcnt, args->opcnt, op->opnum, 1174 nfsd4_op_name(op->opnum)); 1175 /* 1176 * The XDR decode routines may have pre-set op->status; 1177 * for example, if there is a miscellaneous XDR error 1178 * it will be set to nfserr_bad_xdr. 1179 */ 1180 if (op->status) 1181 goto encode_op; 1182 1183 /* We must be able to encode a successful response to 1184 * this operation, with enough room left over to encode a 1185 * failed response to the next operation. If we don't 1186 * have enough room, fail with ERR_RESOURCE. 1187 */ 1188 slack_bytes = (char *)resp->end - (char *)resp->p; 1189 if (slack_bytes < COMPOUND_SLACK_SPACE 1190 + COMPOUND_ERR_SLACK_SPACE) { 1191 BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE); 1192 op->status = nfserr_resource; 1193 goto encode_op; 1194 } 1195 1196 opdesc = OPDESC(op); 1197 1198 if (!cstate->current_fh.fh_dentry) { 1199 if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { 1200 op->status = nfserr_nofilehandle; 1201 goto encode_op; 1202 } 1203 } else if (cstate->current_fh.fh_export->ex_fslocs.migrated && 1204 !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { 1205 op->status = nfserr_moved; 1206 goto encode_op; 1207 } 1208 1209 /* If op is non-idempotent */ 1210 if (opdesc->op_flags & OP_MODIFIES_SOMETHING) { 1211 plen = opdesc->op_rsize_bop(rqstp, op); 1212 op->status = nfsd4_check_resp_size(resp, plen); 1213 } 1214 1215 if (op->status) 1216 goto encode_op; 1217 1218 if (opdesc->op_func) 1219 op->status = opdesc->op_func(rqstp, cstate, &op->u); 1220 else 1221 BUG_ON(op->status == nfs_ok); 1222 1223 if (!op->status && need_wrongsec_check(rqstp)) 1224 op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); 1225 1226 encode_op: 1227 /* Only from SEQUENCE */ 1228 if (resp->cstate.status == nfserr_replay_cache) { 1229 dprintk("%s NFS4.1 replay from cache\n", __func__); 1230 status = op->status; 1231 goto out; 1232 } 1233 if (op->status == nfserr_replay_me) { 1234 op->replay = &cstate->replay_owner->so_replay; 1235 nfsd4_encode_replay(resp, op); 1236 status = op->status = op->replay->rp_status; 1237 } else { 1238 nfsd4_encode_operation(resp, op); 1239 status = op->status; 1240 } 1241 1242 dprintk("nfsv4 compound op %p opcnt %d #%d: %d: status %d\n", 1243 args->ops, args->opcnt, resp->opcnt, op->opnum, 1244 be32_to_cpu(status)); 1245 1246 if (cstate->replay_owner) { 1247 nfs4_unlock_state(); 1248 cstate->replay_owner = NULL; 1249 } 1250 /* XXX Ugh, we need to get rid of this kind of special case: */ 1251 if (op->opnum == OP_READ && op->u.read.rd_filp) 1252 fput(op->u.read.rd_filp); 1253 1254 nfsd4_increment_op_stats(op->opnum); 1255 } 1256 1257 resp->cstate.status = status; 1258 fh_put(&resp->cstate.current_fh); 1259 fh_put(&resp->cstate.save_fh); 1260 BUG_ON(resp->cstate.replay_owner); 1261 out: 1262 /* Reset deferral mechanism for RPC deferrals */ 1263 rqstp->rq_usedeferral = 1; 1264 dprintk("nfsv4 compound returned %d\n", ntohl(status)); 1265 return status; 1266 } 1267 1268 #define op_encode_hdr_size (2) 1269 #define op_encode_stateid_maxsz (XDR_QUADLEN(NFS4_STATEID_SIZE)) 1270 #define op_encode_verifier_maxsz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) 1271 #define op_encode_change_info_maxsz (5) 1272 #define nfs4_fattr_bitmap_maxsz (4) 1273 1274 #define op_encode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 1275 #define op_encode_lock_denied_maxsz (8 + op_encode_lockowner_maxsz) 1276 1277 #define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 1278 1279 #define op_encode_ace_maxsz (3 + nfs4_owner_maxsz) 1280 #define op_encode_delegation_maxsz (1 + op_encode_stateid_maxsz + 1 + \ 1281 op_encode_ace_maxsz) 1282 1283 #define op_encode_channel_attrs_maxsz (6 + 1 + 1) 1284 1285 static inline u32 nfsd4_only_status_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1286 { 1287 return (op_encode_hdr_size) * sizeof(__be32); 1288 } 1289 1290 static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1291 { 1292 return (op_encode_hdr_size + op_encode_stateid_maxsz)* sizeof(__be32); 1293 } 1294 1295 static inline u32 nfsd4_commit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1296 { 1297 return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32); 1298 } 1299 1300 static inline u32 nfsd4_create_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1301 { 1302 return (op_encode_hdr_size + op_encode_change_info_maxsz 1303 + nfs4_fattr_bitmap_maxsz) * sizeof(__be32); 1304 } 1305 1306 static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1307 { 1308 return (op_encode_hdr_size + op_encode_change_info_maxsz) 1309 * sizeof(__be32); 1310 } 1311 1312 static inline u32 nfsd4_lock_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1313 { 1314 return (op_encode_hdr_size + op_encode_lock_denied_maxsz) 1315 * sizeof(__be32); 1316 } 1317 1318 static inline u32 nfsd4_open_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1319 { 1320 return (op_encode_hdr_size + op_encode_stateid_maxsz 1321 + op_encode_change_info_maxsz + 1 1322 + nfs4_fattr_bitmap_maxsz 1323 + op_encode_delegation_maxsz) * sizeof(__be32); 1324 } 1325 1326 static inline u32 nfsd4_read_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1327 { 1328 u32 maxcount = 0, rlen = 0; 1329 1330 maxcount = svc_max_payload(rqstp); 1331 rlen = op->u.read.rd_length; 1332 1333 if (rlen > maxcount) 1334 rlen = maxcount; 1335 1336 return (op_encode_hdr_size + 2) * sizeof(__be32) + rlen; 1337 } 1338 1339 static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1340 { 1341 u32 rlen = op->u.readdir.rd_maxcount; 1342 1343 if (rlen > PAGE_SIZE) 1344 rlen = PAGE_SIZE; 1345 1346 return (op_encode_hdr_size + op_encode_verifier_maxsz) 1347 * sizeof(__be32) + rlen; 1348 } 1349 1350 static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1351 { 1352 return (op_encode_hdr_size + op_encode_change_info_maxsz) 1353 * sizeof(__be32); 1354 } 1355 1356 static inline u32 nfsd4_rename_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1357 { 1358 return (op_encode_hdr_size + op_encode_change_info_maxsz 1359 + op_encode_change_info_maxsz) * sizeof(__be32); 1360 } 1361 1362 static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1363 { 1364 return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32); 1365 } 1366 1367 static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1368 { 1369 return (op_encode_hdr_size + 2 + 1024) * sizeof(__be32); 1370 } 1371 1372 static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1373 { 1374 return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32); 1375 } 1376 1377 static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1378 { 1379 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\ 1380 1 + 1 + 0 + /* eir_flags, spr_how, SP4_NONE (for now) */\ 1381 2 + /*eir_server_owner.so_minor_id */\ 1382 /* eir_server_owner.so_major_id<> */\ 1383 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ 1384 /* eir_server_scope<> */\ 1385 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ 1386 1 + /* eir_server_impl_id array length */\ 1387 0 /* ignored eir_server_impl_id contents */) * sizeof(__be32); 1388 } 1389 1390 static inline u32 nfsd4_bind_conn_to_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1391 { 1392 return (op_encode_hdr_size + \ 1393 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* bctsr_sessid */\ 1394 2 /* bctsr_dir, use_conn_in_rdma_mode */) * sizeof(__be32); 1395 } 1396 1397 static inline u32 nfsd4_create_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1398 { 1399 return (op_encode_hdr_size + \ 1400 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* sessionid */\ 1401 2 + /* csr_sequence, csr_flags */\ 1402 op_encode_channel_attrs_maxsz + \ 1403 op_encode_channel_attrs_maxsz) * sizeof(__be32); 1404 } 1405 1406 static struct nfsd4_operation nfsd4_ops[] = { 1407 [OP_ACCESS] = { 1408 .op_func = (nfsd4op_func)nfsd4_access, 1409 .op_name = "OP_ACCESS", 1410 }, 1411 [OP_CLOSE] = { 1412 .op_func = (nfsd4op_func)nfsd4_close, 1413 .op_flags = OP_MODIFIES_SOMETHING, 1414 .op_name = "OP_CLOSE", 1415 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1416 }, 1417 [OP_COMMIT] = { 1418 .op_func = (nfsd4op_func)nfsd4_commit, 1419 .op_flags = OP_MODIFIES_SOMETHING, 1420 .op_name = "OP_COMMIT", 1421 .op_rsize_bop = (nfsd4op_rsize)nfsd4_commit_rsize, 1422 }, 1423 [OP_CREATE] = { 1424 .op_func = (nfsd4op_func)nfsd4_create, 1425 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1426 .op_name = "OP_CREATE", 1427 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize, 1428 }, 1429 [OP_DELEGRETURN] = { 1430 .op_func = (nfsd4op_func)nfsd4_delegreturn, 1431 .op_flags = OP_MODIFIES_SOMETHING, 1432 .op_name = "OP_DELEGRETURN", 1433 .op_rsize_bop = nfsd4_only_status_rsize, 1434 }, 1435 [OP_GETATTR] = { 1436 .op_func = (nfsd4op_func)nfsd4_getattr, 1437 .op_flags = ALLOWED_ON_ABSENT_FS, 1438 .op_name = "OP_GETATTR", 1439 }, 1440 [OP_GETFH] = { 1441 .op_func = (nfsd4op_func)nfsd4_getfh, 1442 .op_name = "OP_GETFH", 1443 }, 1444 [OP_LINK] = { 1445 .op_func = (nfsd4op_func)nfsd4_link, 1446 .op_flags = ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING 1447 | OP_CACHEME, 1448 .op_name = "OP_LINK", 1449 .op_rsize_bop = (nfsd4op_rsize)nfsd4_link_rsize, 1450 }, 1451 [OP_LOCK] = { 1452 .op_func = (nfsd4op_func)nfsd4_lock, 1453 .op_flags = OP_MODIFIES_SOMETHING, 1454 .op_name = "OP_LOCK", 1455 .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize, 1456 }, 1457 [OP_LOCKT] = { 1458 .op_func = (nfsd4op_func)nfsd4_lockt, 1459 .op_name = "OP_LOCKT", 1460 }, 1461 [OP_LOCKU] = { 1462 .op_func = (nfsd4op_func)nfsd4_locku, 1463 .op_flags = OP_MODIFIES_SOMETHING, 1464 .op_name = "OP_LOCKU", 1465 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1466 }, 1467 [OP_LOOKUP] = { 1468 .op_func = (nfsd4op_func)nfsd4_lookup, 1469 .op_flags = OP_HANDLES_WRONGSEC, 1470 .op_name = "OP_LOOKUP", 1471 }, 1472 [OP_LOOKUPP] = { 1473 .op_func = (nfsd4op_func)nfsd4_lookupp, 1474 .op_flags = OP_HANDLES_WRONGSEC, 1475 .op_name = "OP_LOOKUPP", 1476 }, 1477 [OP_NVERIFY] = { 1478 .op_func = (nfsd4op_func)nfsd4_nverify, 1479 .op_name = "OP_NVERIFY", 1480 }, 1481 [OP_OPEN] = { 1482 .op_func = (nfsd4op_func)nfsd4_open, 1483 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, 1484 .op_name = "OP_OPEN", 1485 .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize, 1486 }, 1487 [OP_OPEN_CONFIRM] = { 1488 .op_func = (nfsd4op_func)nfsd4_open_confirm, 1489 .op_flags = OP_MODIFIES_SOMETHING, 1490 .op_name = "OP_OPEN_CONFIRM", 1491 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1492 }, 1493 [OP_OPEN_DOWNGRADE] = { 1494 .op_func = (nfsd4op_func)nfsd4_open_downgrade, 1495 .op_flags = OP_MODIFIES_SOMETHING, 1496 .op_name = "OP_OPEN_DOWNGRADE", 1497 .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, 1498 }, 1499 [OP_PUTFH] = { 1500 .op_func = (nfsd4op_func)nfsd4_putfh, 1501 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1502 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, 1503 .op_name = "OP_PUTFH", 1504 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1505 }, 1506 [OP_PUTPUBFH] = { 1507 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1508 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1509 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, 1510 .op_name = "OP_PUTPUBFH", 1511 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1512 }, 1513 [OP_PUTROOTFH] = { 1514 .op_func = (nfsd4op_func)nfsd4_putrootfh, 1515 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1516 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, 1517 .op_name = "OP_PUTROOTFH", 1518 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1519 }, 1520 [OP_READ] = { 1521 .op_func = (nfsd4op_func)nfsd4_read, 1522 .op_flags = OP_MODIFIES_SOMETHING, 1523 .op_name = "OP_READ", 1524 .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize, 1525 }, 1526 [OP_READDIR] = { 1527 .op_func = (nfsd4op_func)nfsd4_readdir, 1528 .op_flags = OP_MODIFIES_SOMETHING, 1529 .op_name = "OP_READDIR", 1530 .op_rsize_bop = (nfsd4op_rsize)nfsd4_readdir_rsize, 1531 }, 1532 [OP_READLINK] = { 1533 .op_func = (nfsd4op_func)nfsd4_readlink, 1534 .op_name = "OP_READLINK", 1535 }, 1536 [OP_REMOVE] = { 1537 .op_func = (nfsd4op_func)nfsd4_remove, 1538 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1539 .op_name = "OP_REMOVE", 1540 .op_rsize_bop = (nfsd4op_rsize)nfsd4_remove_rsize, 1541 }, 1542 [OP_RENAME] = { 1543 .op_func = (nfsd4op_func)nfsd4_rename, 1544 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1545 .op_name = "OP_RENAME", 1546 .op_rsize_bop = (nfsd4op_rsize)nfsd4_rename_rsize, 1547 }, 1548 [OP_RENEW] = { 1549 .op_func = (nfsd4op_func)nfsd4_renew, 1550 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1551 | OP_MODIFIES_SOMETHING, 1552 .op_name = "OP_RENEW", 1553 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1554 1555 }, 1556 [OP_RESTOREFH] = { 1557 .op_func = (nfsd4op_func)nfsd4_restorefh, 1558 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1559 | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, 1560 .op_name = "OP_RESTOREFH", 1561 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1562 }, 1563 [OP_SAVEFH] = { 1564 .op_func = (nfsd4op_func)nfsd4_savefh, 1565 .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, 1566 .op_name = "OP_SAVEFH", 1567 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1568 }, 1569 [OP_SECINFO] = { 1570 .op_func = (nfsd4op_func)nfsd4_secinfo, 1571 .op_flags = OP_HANDLES_WRONGSEC, 1572 .op_name = "OP_SECINFO", 1573 }, 1574 [OP_SETATTR] = { 1575 .op_func = (nfsd4op_func)nfsd4_setattr, 1576 .op_name = "OP_SETATTR", 1577 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1578 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize, 1579 }, 1580 [OP_SETCLIENTID] = { 1581 .op_func = (nfsd4op_func)nfsd4_setclientid, 1582 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1583 | OP_MODIFIES_SOMETHING | OP_CACHEME, 1584 .op_name = "OP_SETCLIENTID", 1585 .op_rsize_bop = (nfsd4op_rsize)nfsd4_setclientid_rsize, 1586 }, 1587 [OP_SETCLIENTID_CONFIRM] = { 1588 .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, 1589 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1590 | OP_MODIFIES_SOMETHING | OP_CACHEME, 1591 .op_name = "OP_SETCLIENTID_CONFIRM", 1592 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1593 }, 1594 [OP_VERIFY] = { 1595 .op_func = (nfsd4op_func)nfsd4_verify, 1596 .op_name = "OP_VERIFY", 1597 }, 1598 [OP_WRITE] = { 1599 .op_func = (nfsd4op_func)nfsd4_write, 1600 .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, 1601 .op_name = "OP_WRITE", 1602 .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, 1603 }, 1604 [OP_RELEASE_LOCKOWNER] = { 1605 .op_func = (nfsd4op_func)nfsd4_release_lockowner, 1606 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS 1607 | OP_MODIFIES_SOMETHING, 1608 .op_name = "OP_RELEASE_LOCKOWNER", 1609 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1610 }, 1611 1612 /* NFSv4.1 operations */ 1613 [OP_EXCHANGE_ID] = { 1614 .op_func = (nfsd4op_func)nfsd4_exchange_id, 1615 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1616 | OP_MODIFIES_SOMETHING, 1617 .op_name = "OP_EXCHANGE_ID", 1618 .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize, 1619 }, 1620 [OP_BIND_CONN_TO_SESSION] = { 1621 .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session, 1622 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1623 | OP_MODIFIES_SOMETHING, 1624 .op_name = "OP_BIND_CONN_TO_SESSION", 1625 .op_rsize_bop = (nfsd4op_rsize)nfsd4_bind_conn_to_session_rsize, 1626 }, 1627 [OP_CREATE_SESSION] = { 1628 .op_func = (nfsd4op_func)nfsd4_create_session, 1629 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1630 | OP_MODIFIES_SOMETHING, 1631 .op_name = "OP_CREATE_SESSION", 1632 .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_session_rsize, 1633 }, 1634 [OP_DESTROY_SESSION] = { 1635 .op_func = (nfsd4op_func)nfsd4_destroy_session, 1636 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1637 | OP_MODIFIES_SOMETHING, 1638 .op_name = "OP_DESTROY_SESSION", 1639 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1640 }, 1641 [OP_SEQUENCE] = { 1642 .op_func = (nfsd4op_func)nfsd4_sequence, 1643 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, 1644 .op_name = "OP_SEQUENCE", 1645 }, 1646 [OP_DESTROY_CLIENTID] = { 1647 .op_func = (nfsd4op_func)nfsd4_destroy_clientid, 1648 .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP 1649 | OP_MODIFIES_SOMETHING, 1650 .op_name = "OP_DESTROY_CLIENTID", 1651 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1652 }, 1653 [OP_RECLAIM_COMPLETE] = { 1654 .op_func = (nfsd4op_func)nfsd4_reclaim_complete, 1655 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, 1656 .op_name = "OP_RECLAIM_COMPLETE", 1657 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1658 }, 1659 [OP_SECINFO_NO_NAME] = { 1660 .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, 1661 .op_flags = OP_HANDLES_WRONGSEC, 1662 .op_name = "OP_SECINFO_NO_NAME", 1663 }, 1664 [OP_TEST_STATEID] = { 1665 .op_func = (nfsd4op_func)nfsd4_test_stateid, 1666 .op_flags = ALLOWED_WITHOUT_FH, 1667 .op_name = "OP_TEST_STATEID", 1668 }, 1669 [OP_FREE_STATEID] = { 1670 .op_func = (nfsd4op_func)nfsd4_free_stateid, 1671 .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, 1672 .op_name = "OP_FREE_STATEID", 1673 .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, 1674 }, 1675 }; 1676 1677 static const char *nfsd4_op_name(unsigned opnum) 1678 { 1679 if (opnum < ARRAY_SIZE(nfsd4_ops)) 1680 return nfsd4_ops[opnum].op_name; 1681 return "unknown_operation"; 1682 } 1683 1684 #define nfsd4_voidres nfsd4_voidargs 1685 struct nfsd4_voidargs { int dummy; }; 1686 1687 static struct svc_procedure nfsd_procedures4[2] = { 1688 [NFSPROC4_NULL] = { 1689 .pc_func = (svc_procfunc) nfsd4_proc_null, 1690 .pc_encode = (kxdrproc_t) nfs4svc_encode_voidres, 1691 .pc_argsize = sizeof(struct nfsd4_voidargs), 1692 .pc_ressize = sizeof(struct nfsd4_voidres), 1693 .pc_cachetype = RC_NOCACHE, 1694 .pc_xdrressize = 1, 1695 }, 1696 [NFSPROC4_COMPOUND] = { 1697 .pc_func = (svc_procfunc) nfsd4_proc_compound, 1698 .pc_decode = (kxdrproc_t) nfs4svc_decode_compoundargs, 1699 .pc_encode = (kxdrproc_t) nfs4svc_encode_compoundres, 1700 .pc_argsize = sizeof(struct nfsd4_compoundargs), 1701 .pc_ressize = sizeof(struct nfsd4_compoundres), 1702 .pc_release = nfsd4_release_compoundargs, 1703 .pc_cachetype = RC_NOCACHE, 1704 .pc_xdrressize = NFSD_BUFSIZE/4, 1705 }, 1706 }; 1707 1708 struct svc_version nfsd_version4 = { 1709 .vs_vers = 4, 1710 .vs_nproc = 2, 1711 .vs_proc = nfsd_procedures4, 1712 .vs_dispatch = nfsd_dispatch, 1713 .vs_xdrsize = NFS4_SVC_XDRSIZE, 1714 }; 1715 1716 /* 1717 * Local variables: 1718 * c-basic-offset: 8 1719 * End: 1720 */ 1721