1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rick Macklem at The University of Guelph. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 33 * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $ 34 */ 35 36 37 /* 38 * vnode op calls for Sun NFS version 2 and 3 39 */ 40 41 #include "opt_inet.h" 42 43 #include <sys/param.h> 44 #include <sys/kernel.h> 45 #include <sys/systm.h> 46 #include <sys/resourcevar.h> 47 #include <sys/proc.h> 48 #include <sys/mount.h> 49 #include <sys/buf.h> 50 #include <sys/malloc.h> 51 #include <sys/mbuf.h> 52 #include <sys/namei.h> 53 #include <sys/nlookup.h> 54 #include <sys/socket.h> 55 #include <sys/vnode.h> 56 #include <sys/dirent.h> 57 #include <sys/fcntl.h> 58 #include <sys/lockf.h> 59 #include <sys/stat.h> 60 #include <sys/sysctl.h> 61 #include <sys/conf.h> 62 63 #include <vm/vm.h> 64 #include <vm/vm_extern.h> 65 66 #include <sys/buf2.h> 67 68 #include <vfs/fifofs/fifo.h> 69 #include <vfs/ufs/dir.h> 70 71 #undef DIRBLKSIZ 72 73 #include "rpcv2.h" 74 #include "nfsproto.h" 75 #include "nfs.h" 76 #include "nfsmount.h" 77 #include "nfsnode.h" 78 #include "xdr_subs.h" 79 #include "nfsm_subs.h" 80 81 #include <net/if.h> 82 #include <netinet/in.h> 83 #include <netinet/in_var.h> 84 85 #include <sys/thread2.h> 86 87 /* Defs */ 88 #define TRUE 1 89 #define FALSE 0 90 91 static int nfsfifo_read (struct vop_read_args *); 92 static int nfsfifo_write (struct vop_write_args *); 93 static int nfsfifo_close (struct vop_close_args *); 94 static int nfs_setattrrpc (struct vnode *,struct vattr *,struct ucred *,struct thread *); 95 static int nfs_lookup (struct vop_old_lookup_args *); 96 static int nfs_create (struct vop_old_create_args *); 97 static int nfs_mknod (struct vop_old_mknod_args *); 98 static int nfs_open (struct vop_open_args *); 99 static int nfs_close (struct vop_close_args *); 100 static int nfs_access (struct vop_access_args *); 101 static int nfs_getattr (struct vop_getattr_args *); 102 static int nfs_setattr (struct vop_setattr_args *); 103 static int nfs_read (struct vop_read_args *); 104 static int nfs_mmap (struct vop_mmap_args *); 105 static int nfs_fsync (struct vop_fsync_args *); 106 static int nfs_remove (struct vop_old_remove_args *); 107 static int nfs_link (struct vop_old_link_args *); 108 static int nfs_rename (struct vop_old_rename_args *); 109 static int nfs_mkdir (struct vop_old_mkdir_args *); 110 static int nfs_rmdir (struct vop_old_rmdir_args *); 111 static int nfs_symlink (struct vop_old_symlink_args *); 112 static int nfs_readdir (struct vop_readdir_args *); 113 static int nfs_bmap (struct vop_bmap_args *); 114 static int nfs_strategy (struct vop_strategy_args *); 115 static int nfs_lookitup (struct vnode *, const char *, int, 116 struct ucred *, struct thread *, struct nfsnode **); 117 static int nfs_sillyrename (struct vnode *,struct vnode *,struct componentname *); 118 static int nfs_laccess (struct vop_access_args *); 119 static int nfs_readlink (struct vop_readlink_args *); 120 static int nfs_print (struct vop_print_args *); 121 static int nfs_advlock (struct vop_advlock_args *); 122 static int nfs_kqfilter (struct vop_kqfilter_args *ap); 123 124 static int nfs_nresolve (struct vop_nresolve_args *); 125 /* 126 * Global vfs data structures for nfs 127 */ 128 struct vop_ops nfsv2_vnode_vops = { 129 .vop_default = vop_defaultop, 130 .vop_access = nfs_access, 131 .vop_advlock = nfs_advlock, 132 .vop_bmap = nfs_bmap, 133 .vop_close = nfs_close, 134 .vop_old_create = nfs_create, 135 .vop_fsync = nfs_fsync, 136 .vop_getattr = nfs_getattr, 137 .vop_getpages = vop_stdgetpages, 138 .vop_putpages = vop_stdputpages, 139 .vop_inactive = nfs_inactive, 140 .vop_old_link = nfs_link, 141 .vop_old_lookup = nfs_lookup, 142 .vop_old_mkdir = nfs_mkdir, 143 .vop_old_mknod = nfs_mknod, 144 .vop_mmap = nfs_mmap, 145 .vop_open = nfs_open, 146 .vop_print = nfs_print, 147 .vop_read = nfs_read, 148 .vop_readdir = nfs_readdir, 149 .vop_readlink = nfs_readlink, 150 .vop_reclaim = nfs_reclaim, 151 .vop_old_remove = nfs_remove, 152 .vop_old_rename = nfs_rename, 153 .vop_old_rmdir = nfs_rmdir, 154 .vop_setattr = nfs_setattr, 155 .vop_strategy = nfs_strategy, 156 .vop_old_symlink = nfs_symlink, 157 .vop_write = nfs_write, 158 .vop_nresolve = nfs_nresolve, 159 .vop_kqfilter = nfs_kqfilter 160 }; 161 162 /* 163 * Special device vnode ops 164 */ 165 struct vop_ops nfsv2_spec_vops = { 166 .vop_default = vop_defaultop, 167 .vop_access = nfs_laccess, 168 .vop_close = nfs_close, 169 .vop_fsync = nfs_fsync, 170 .vop_getattr = nfs_getattr, 171 .vop_inactive = nfs_inactive, 172 .vop_print = nfs_print, 173 .vop_read = vop_stdnoread, 174 .vop_reclaim = nfs_reclaim, 175 .vop_setattr = nfs_setattr, 176 .vop_write = vop_stdnowrite 177 }; 178 179 struct vop_ops nfsv2_fifo_vops = { 180 .vop_default = fifo_vnoperate, 181 .vop_access = nfs_laccess, 182 .vop_close = nfsfifo_close, 183 .vop_fsync = nfs_fsync, 184 .vop_getattr = nfs_getattr, 185 .vop_inactive = nfs_inactive, 186 .vop_print = nfs_print, 187 .vop_read = nfsfifo_read, 188 .vop_reclaim = nfs_reclaim, 189 .vop_setattr = nfs_setattr, 190 .vop_write = nfsfifo_write 191 }; 192 193 static int nfs_mknodrpc (struct vnode *dvp, struct vnode **vpp, 194 struct componentname *cnp, 195 struct vattr *vap); 196 static int nfs_removerpc (struct vnode *dvp, const char *name, 197 int namelen, 198 struct ucred *cred, struct thread *td); 199 static int nfs_renamerpc (struct vnode *fdvp, const char *fnameptr, 200 int fnamelen, struct vnode *tdvp, 201 const char *tnameptr, int tnamelen, 202 struct ucred *cred, struct thread *td); 203 static int nfs_renameit (struct vnode *sdvp, 204 struct componentname *scnp, 205 struct sillyrename *sp); 206 207 SYSCTL_DECL(_vfs_nfs); 208 209 static int nfs_flush_on_rename = 1; 210 SYSCTL_INT(_vfs_nfs, OID_AUTO, flush_on_rename, CTLFLAG_RW, 211 &nfs_flush_on_rename, 0, "flush fvp prior to rename"); 212 static int nfs_flush_on_hlink = 0; 213 SYSCTL_INT(_vfs_nfs, OID_AUTO, flush_on_hlink, CTLFLAG_RW, 214 &nfs_flush_on_hlink, 0, "flush fvp prior to hard link"); 215 216 static int nfsaccess_cache_timeout = NFS_DEFATTRTIMO; 217 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW, 218 &nfsaccess_cache_timeout, 0, "NFS ACCESS cache timeout"); 219 220 static int nfsneg_cache_timeout = NFS_MINATTRTIMO; 221 SYSCTL_INT(_vfs_nfs, OID_AUTO, neg_cache_timeout, CTLFLAG_RW, 222 &nfsneg_cache_timeout, 0, "NFS NEGATIVE NAMECACHE timeout"); 223 224 static int nfspos_cache_timeout = NFS_MINATTRTIMO; 225 SYSCTL_INT(_vfs_nfs, OID_AUTO, pos_cache_timeout, CTLFLAG_RW, 226 &nfspos_cache_timeout, 0, "NFS POSITIVE NAMECACHE timeout"); 227 228 static int nfsv3_commit_on_close = 0; 229 SYSCTL_INT(_vfs_nfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW, 230 &nfsv3_commit_on_close, 0, "write+commit on close, else only write"); 231 #if 0 232 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD, 233 &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count"); 234 235 SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD, 236 &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count"); 237 #endif 238 239 #define NFSV3ACCESS_ALL (NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY \ 240 | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE \ 241 | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP) 242 243 static __inline 244 void 245 nfs_knote(struct vnode *vp, int flags) 246 { 247 if (flags) 248 KNOTE(&vp->v_pollinfo.vpi_kqinfo.ki_note, flags); 249 } 250 251 /* 252 * Returns whether a name component is a degenerate '.' or '..'. 253 */ 254 static __inline 255 int 256 nlcdegenerate(struct nlcomponent *nlc) 257 { 258 if (nlc->nlc_namelen == 1 && nlc->nlc_nameptr[0] == '.') 259 return(1); 260 if (nlc->nlc_namelen == 2 && 261 nlc->nlc_nameptr[0] == '.' && nlc->nlc_nameptr[1] == '.') 262 return(1); 263 return(0); 264 } 265 266 static int 267 nfs3_access_otw(struct vnode *vp, int wmode, 268 struct thread *td, struct ucred *cred) 269 { 270 struct nfsnode *np = VTONFS(vp); 271 int attrflag; 272 int error = 0; 273 u_int32_t *tl; 274 u_int32_t rmode; 275 struct nfsm_info info; 276 277 info.mrep = NULL; 278 info.v3 = 1; 279 280 nfsstats.rpccnt[NFSPROC_ACCESS]++; 281 nfsm_reqhead(&info, vp, NFSPROC_ACCESS, 282 NFSX_FH(info.v3) + NFSX_UNSIGNED); 283 ERROROUT(nfsm_fhtom(&info, vp)); 284 tl = nfsm_build(&info, NFSX_UNSIGNED); 285 *tl = txdr_unsigned(wmode); 286 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_ACCESS, td, cred, &error)); 287 ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, NFS_LATTR_NOSHRINK)); 288 if (error == 0) { 289 NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); 290 rmode = fxdr_unsigned(u_int32_t, *tl); 291 np->n_mode = rmode; 292 np->n_modeuid = cred->cr_uid; 293 np->n_modestamp = mycpu->gd_time_seconds; 294 } 295 m_freem(info.mrep); 296 info.mrep = NULL; 297 nfsmout: 298 return error; 299 } 300 301 /* 302 * nfs access vnode op. 303 * For nfs version 2, just return ok. File accesses may fail later. 304 * For nfs version 3, use the access rpc to check accessibility. If file modes 305 * are changed on the server, accesses might still fail later. 306 * 307 * nfs_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred) 308 */ 309 static int 310 nfs_access(struct vop_access_args *ap) 311 { 312 struct ucred *cred; 313 struct vnode *vp = ap->a_vp; 314 thread_t td = curthread; 315 int error = 0; 316 u_int32_t mode, wmode; 317 struct nfsnode *np = VTONFS(vp); 318 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 319 int v3 = NFS_ISV3(vp); 320 321 lwkt_gettoken(&nmp->nm_token); 322 323 /* 324 * Disallow write attempts on filesystems mounted read-only; 325 * unless the file is a socket, fifo, or a block or character 326 * device resident on the filesystem. 327 */ 328 if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { 329 switch (vp->v_type) { 330 case VREG: 331 case VDIR: 332 case VLNK: 333 lwkt_reltoken(&nmp->nm_token); 334 return (EROFS); 335 default: 336 break; 337 } 338 } 339 340 /* 341 * The NFS protocol passes only the effective uid/gid over the wire but 342 * we need to check access against real ids if AT_EACCESS not set. 343 * Handle this case by cloning the credentials and setting the 344 * effective ids to the real ones. 345 */ 346 if (ap->a_flags & AT_EACCESS) { 347 cred = crhold(ap->a_cred); 348 } else { 349 cred = crdup(ap->a_cred); 350 cred->cr_uid = cred->cr_ruid; 351 cred->cr_gid = cred->cr_rgid; 352 } 353 354 /* 355 * For nfs v3, check to see if we have done this recently, and if 356 * so return our cached result instead of making an ACCESS call. 357 * If not, do an access rpc, otherwise you are stuck emulating 358 * ufs_access() locally using the vattr. This may not be correct, 359 * since the server may apply other access criteria such as 360 * client uid-->server uid mapping that we do not know about. 361 */ 362 if (v3) { 363 if (ap->a_mode & VREAD) 364 mode = NFSV3ACCESS_READ; 365 else 366 mode = 0; 367 if (vp->v_type != VDIR) { 368 if (ap->a_mode & VWRITE) 369 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND); 370 if (ap->a_mode & VEXEC) 371 mode |= NFSV3ACCESS_EXECUTE; 372 } else { 373 if (ap->a_mode & VWRITE) 374 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND | 375 NFSV3ACCESS_DELETE); 376 if (ap->a_mode & VEXEC) 377 mode |= NFSV3ACCESS_LOOKUP; 378 } 379 /* XXX safety belt, only make blanket request if caching */ 380 if (nfsaccess_cache_timeout > 0) { 381 wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY | 382 NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE | 383 NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP; 384 } else { 385 wmode = mode; 386 } 387 388 /* 389 * Does our cached result allow us to give a definite yes to 390 * this request? 391 */ 392 if (np->n_modestamp && 393 (mycpu->gd_time_seconds < (np->n_modestamp + nfsaccess_cache_timeout)) && 394 (cred->cr_uid == np->n_modeuid) && 395 ((np->n_mode & mode) == mode)) { 396 nfsstats.accesscache_hits++; 397 } else { 398 /* 399 * Either a no, or a don't know. Go to the wire. 400 */ 401 nfsstats.accesscache_misses++; 402 error = nfs3_access_otw(vp, wmode, td, cred); 403 if (!error) { 404 if ((np->n_mode & mode) != mode) { 405 error = EACCES; 406 } 407 } 408 } 409 } else { 410 if ((error = nfs_laccess(ap)) != 0) { 411 crfree(cred); 412 lwkt_reltoken(&nmp->nm_token); 413 return (error); 414 } 415 416 /* 417 * Attempt to prevent a mapped root from accessing a file 418 * which it shouldn't. We try to read a byte from the file 419 * if the user is root and the file is not zero length. 420 * After calling nfs_laccess, we should have the correct 421 * file size cached. 422 */ 423 if (cred->cr_uid == 0 && (ap->a_mode & VREAD) 424 && VTONFS(vp)->n_size > 0) { 425 struct iovec aiov; 426 struct uio auio; 427 char buf[1]; 428 429 aiov.iov_base = buf; 430 aiov.iov_len = 1; 431 auio.uio_iov = &aiov; 432 auio.uio_iovcnt = 1; 433 auio.uio_offset = 0; 434 auio.uio_resid = 1; 435 auio.uio_segflg = UIO_SYSSPACE; 436 auio.uio_rw = UIO_READ; 437 auio.uio_td = td; 438 439 if (vp->v_type == VREG) { 440 error = nfs_readrpc_uio(vp, &auio); 441 } else if (vp->v_type == VDIR) { 442 char* bp; 443 bp = kmalloc(NFS_DIRBLKSIZ, M_TEMP, M_WAITOK); 444 aiov.iov_base = bp; 445 aiov.iov_len = auio.uio_resid = NFS_DIRBLKSIZ; 446 error = nfs_readdirrpc_uio(vp, &auio); 447 kfree(bp, M_TEMP); 448 } else if (vp->v_type == VLNK) { 449 error = nfs_readlinkrpc_uio(vp, &auio); 450 } else { 451 error = EACCES; 452 } 453 } 454 } 455 /* 456 * [re]record creds for reading and/or writing if access 457 * was granted. Assume the NFS server will grant read access 458 * for execute requests. 459 */ 460 if (error == 0) { 461 if ((ap->a_mode & (VREAD|VEXEC)) && cred != np->n_rucred) { 462 crhold(cred); 463 if (np->n_rucred) 464 crfree(np->n_rucred); 465 np->n_rucred = cred; 466 } 467 if ((ap->a_mode & VWRITE) && cred != np->n_wucred) { 468 crhold(cred); 469 if (np->n_wucred) 470 crfree(np->n_wucred); 471 np->n_wucred = cred; 472 } 473 } 474 lwkt_reltoken(&nmp->nm_token); 475 crfree(cred); 476 return(error); 477 } 478 479 /* 480 * nfs open vnode op 481 * Check to see if the type is ok 482 * and that deletion is not in progress. 483 * For paged in text files, you will need to flush the page cache 484 * if consistency is lost. 485 * 486 * nfs_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred, 487 * struct file *a_fp) 488 */ 489 /* ARGSUSED */ 490 static int 491 nfs_open(struct vop_open_args *ap) 492 { 493 struct vnode *vp = ap->a_vp; 494 struct nfsnode *np = VTONFS(vp); 495 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 496 struct vattr vattr; 497 int error; 498 499 lwkt_gettoken(&nmp->nm_token); 500 501 if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) { 502 #ifdef DIAGNOSTIC 503 kprintf("open eacces vtyp=%d\n",vp->v_type); 504 #endif 505 lwkt_reltoken(&nmp->nm_token); 506 return (EOPNOTSUPP); 507 } 508 509 /* 510 * Save valid creds for reading and writing for later RPCs. 511 */ 512 if ((ap->a_mode & FREAD) && ap->a_cred != np->n_rucred) { 513 crhold(ap->a_cred); 514 if (np->n_rucred) 515 crfree(np->n_rucred); 516 np->n_rucred = ap->a_cred; 517 } 518 if ((ap->a_mode & FWRITE) && ap->a_cred != np->n_wucred) { 519 crhold(ap->a_cred); 520 if (np->n_wucred) 521 crfree(np->n_wucred); 522 np->n_wucred = ap->a_cred; 523 } 524 525 /* 526 * Clear the attribute cache only if opening with write access. It 527 * is unclear if we should do this at all here, but we certainly 528 * should not clear the cache unconditionally simply because a file 529 * is being opened. 530 */ 531 if (ap->a_mode & FWRITE) 532 np->n_attrstamp = 0; 533 534 /* 535 * For normal NFS, reconcile changes made locally verses 536 * changes made remotely. Note that VOP_GETATTR only goes 537 * to the wire if the cached attribute has timed out or been 538 * cleared. 539 * 540 * If local modifications have been made clear the attribute 541 * cache to force an attribute and modified time check. If 542 * GETATTR detects that the file has been changed by someone 543 * other then us it will set NRMODIFIED. 544 * 545 * If we are opening a directory and local changes have been 546 * made we have to invalidate the cache in order to ensure 547 * that we get the most up-to-date information from the 548 * server. XXX 549 */ 550 if (np->n_flag & NLMODIFIED) { 551 np->n_attrstamp = 0; 552 if (vp->v_type == VDIR) { 553 error = nfs_vinvalbuf(vp, V_SAVE, 1); 554 if (error == EINTR) { 555 lwkt_reltoken(&nmp->nm_token); 556 return (error); 557 } 558 nfs_invaldir(vp); 559 } 560 } 561 error = VOP_GETATTR(vp, &vattr); 562 if (error) { 563 lwkt_reltoken(&nmp->nm_token); 564 return (error); 565 } 566 if (np->n_flag & NRMODIFIED) { 567 if (vp->v_type == VDIR) 568 nfs_invaldir(vp); 569 error = nfs_vinvalbuf(vp, V_SAVE, 1); 570 if (error == EINTR) { 571 lwkt_reltoken(&nmp->nm_token); 572 return (error); 573 } 574 np->n_flag &= ~NRMODIFIED; 575 } 576 error = vop_stdopen(ap); 577 lwkt_reltoken(&nmp->nm_token); 578 579 return error; 580 } 581 582 /* 583 * nfs close vnode op 584 * What an NFS client should do upon close after writing is a debatable issue. 585 * Most NFS clients push delayed writes to the server upon close, basically for 586 * two reasons: 587 * 1 - So that any write errors may be reported back to the client process 588 * doing the close system call. By far the two most likely errors are 589 * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure. 590 * 2 - To put a worst case upper bound on cache inconsistency between 591 * multiple clients for the file. 592 * There is also a consistency problem for Version 2 of the protocol w.r.t. 593 * not being able to tell if other clients are writing a file concurrently, 594 * since there is no way of knowing if the changed modify time in the reply 595 * is only due to the write for this client. 596 * (NFS Version 3 provides weak cache consistency data in the reply that 597 * should be sufficient to detect and handle this case.) 598 * 599 * The current code does the following: 600 * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers 601 * for NFS Version 3 - flush dirty buffers to the server but don't invalidate 602 * or commit them (this satisfies 1 and 2 except for the 603 * case where the server crashes after this close but 604 * before the commit RPC, which is felt to be "good 605 * enough". Changing the last argument to nfs_flush() to 606 * a 1 would force a commit operation, if it is felt a 607 * commit is necessary now. 608 * for NQNFS - do nothing now, since 2 is dealt with via leases and 609 * 1 should be dealt with via an fsync() system call for 610 * cases where write errors are important. 611 * 612 * nfs_close(struct vnode *a_vp, int a_fflag) 613 */ 614 /* ARGSUSED */ 615 static int 616 nfs_close(struct vop_close_args *ap) 617 { 618 struct vnode *vp = ap->a_vp; 619 struct nfsnode *np = VTONFS(vp); 620 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 621 int error = 0; 622 thread_t td = curthread; 623 624 vn_lock(vp, LK_UPGRADE | LK_RETRY); /* XXX */ 625 lwkt_gettoken(&nmp->nm_token); 626 627 if (vp->v_type == VREG) { 628 if (np->n_flag & NLMODIFIED) { 629 if (NFS_ISV3(vp)) { 630 /* 631 * Under NFSv3 we have dirty buffers to dispose of. We 632 * must flush them to the NFS server. We have the option 633 * of waiting all the way through the commit rpc or just 634 * waiting for the initial write. The default is to only 635 * wait through the initial write so the data is in the 636 * server's cache, which is roughly similar to the state 637 * a standard disk subsystem leaves the file in on close(). 638 * 639 * We cannot clear the NLMODIFIED bit in np->n_flag due to 640 * potential races with other processes, and certainly 641 * cannot clear it if we don't commit. 642 */ 643 int cm = nfsv3_commit_on_close ? 1 : 0; 644 error = nfs_flush(vp, MNT_WAIT, td, cm); 645 /* np->n_flag &= ~NLMODIFIED; */ 646 } else { 647 error = nfs_vinvalbuf(vp, V_SAVE, 1); 648 } 649 np->n_attrstamp = 0; 650 } 651 if (np->n_flag & NWRITEERR) { 652 np->n_flag &= ~NWRITEERR; 653 error = np->n_error; 654 } 655 } 656 vop_stdclose(ap); 657 lwkt_reltoken(&nmp->nm_token); 658 659 return (error); 660 } 661 662 /* 663 * nfs getattr call from vfs. 664 * 665 * nfs_getattr(struct vnode *a_vp, struct vattr *a_vap) 666 */ 667 static int 668 nfs_getattr(struct vop_getattr_args *ap) 669 { 670 struct vnode *vp = ap->a_vp; 671 struct nfsnode *np = VTONFS(vp); 672 struct nfsmount *nmp; 673 int error = 0; 674 thread_t td = curthread; 675 struct nfsm_info info; 676 677 info.mrep = NULL; 678 info.v3 = NFS_ISV3(vp); 679 nmp = VFSTONFS(vp->v_mount); 680 681 lwkt_gettoken(&nmp->nm_token); 682 683 /* 684 * Update local times for special files. 685 */ 686 if (np->n_flag & (NACC | NUPD)) 687 np->n_flag |= NCHG; 688 /* 689 * First look in the cache. 690 */ 691 if (nfs_getattrcache(vp, ap->a_vap) == 0) 692 goto done; 693 694 if (info.v3 && nfsaccess_cache_timeout > 0) { 695 nfsstats.accesscache_misses++; 696 nfs3_access_otw(vp, NFSV3ACCESS_ALL, td, nfs_vpcred(vp, ND_CHECK)); 697 if (nfs_getattrcache(vp, ap->a_vap) == 0) 698 goto done; 699 } 700 701 nfsstats.rpccnt[NFSPROC_GETATTR]++; 702 nfsm_reqhead(&info, vp, NFSPROC_GETATTR, NFSX_FH(info.v3)); 703 ERROROUT(nfsm_fhtom(&info, vp)); 704 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_GETATTR, td, 705 nfs_vpcred(vp, ND_CHECK), &error)); 706 if (error == 0) { 707 ERROROUT(nfsm_loadattr(&info, vp, ap->a_vap)); 708 } 709 m_freem(info.mrep); 710 info.mrep = NULL; 711 done: 712 /* 713 * NFS doesn't support chflags flags. If the nfs mount was 714 * made -o cache set the UF_CACHE bit for swapcache. 715 */ 716 if ((nmp->nm_flag & NFSMNT_CACHE) && (vp->v_flag & VROOT)) 717 ap->a_vap->va_flags |= UF_CACHE; 718 nfsmout: 719 lwkt_reltoken(&nmp->nm_token); 720 return (error); 721 } 722 723 /* 724 * nfs setattr call. 725 * 726 * nfs_setattr(struct vnode *a_vp, struct vattr *a_vap, struct ucred *a_cred) 727 */ 728 static int 729 nfs_setattr(struct vop_setattr_args *ap) 730 { 731 struct vnode *vp = ap->a_vp; 732 struct nfsnode *np = VTONFS(vp); 733 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 734 struct vattr *vap = ap->a_vap; 735 int error = 0; 736 int kflags = 0; 737 off_t tsize; 738 thread_t td = curthread; 739 740 #ifndef nolint 741 tsize = (off_t)0; 742 #endif 743 /* 744 * Setting of flags is not supported. 745 */ 746 if (vap->va_flags != VNOVAL) 747 return (EOPNOTSUPP); 748 749 /* 750 * Disallow write attempts if the filesystem is mounted read-only. 751 */ 752 if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL || 753 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || 754 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) && 755 (vp->v_mount->mnt_flag & MNT_RDONLY)) 756 return (EROFS); 757 758 lwkt_gettoken(&nmp->nm_token); 759 760 if (vap->va_size != VNOVAL) { 761 /* 762 * truncation requested 763 */ 764 switch (vp->v_type) { 765 case VDIR: 766 lwkt_reltoken(&nmp->nm_token); 767 return (EISDIR); 768 case VCHR: 769 case VBLK: 770 case VSOCK: 771 case VFIFO: 772 if (vap->va_mtime.tv_sec == VNOVAL && 773 vap->va_atime.tv_sec == VNOVAL && 774 vap->va_mode == (mode_t)VNOVAL && 775 vap->va_uid == (uid_t)VNOVAL && 776 vap->va_gid == (gid_t)VNOVAL) { 777 lwkt_reltoken(&nmp->nm_token); 778 return (0); 779 } 780 vap->va_size = VNOVAL; 781 break; 782 default: 783 /* 784 * Disallow write attempts if the filesystem is 785 * mounted read-only. 786 */ 787 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 788 lwkt_reltoken(&nmp->nm_token); 789 return (EROFS); 790 } 791 792 tsize = np->n_size; 793 again: 794 error = nfs_meta_setsize(vp, td, vap->va_size, 0); 795 796 #if 0 797 if (np->n_flag & NLMODIFIED) { 798 if (vap->va_size == 0) 799 error = nfs_vinvalbuf(vp, 0, 1); 800 else 801 error = nfs_vinvalbuf(vp, V_SAVE, 1); 802 } 803 #endif 804 /* 805 * note: this loop case almost always happens at 806 * least once per truncation. 807 */ 808 if (error == 0 && np->n_size != vap->va_size) 809 goto again; 810 np->n_vattr.va_size = vap->va_size; 811 kflags |= NOTE_WRITE; 812 if (tsize < vap->va_size) 813 kflags |= NOTE_EXTEND; 814 break; 815 } 816 } else if ((np->n_flag & NLMODIFIED) && vp->v_type == VREG) { 817 /* 818 * What to do. If we are modifying the mtime we lose 819 * mtime detection of changes made by the server or other 820 * clients. But programs like rsync/rdist/cpdup are going 821 * to call utimes a lot. We don't want to piecemeal sync. 822 * 823 * For now sync if any prior remote changes were detected, 824 * but allow us to lose track of remote changes made during 825 * the utimes operation. 826 */ 827 if (np->n_flag & NRMODIFIED) 828 error = nfs_vinvalbuf(vp, V_SAVE, 1); 829 if (error == EINTR) { 830 lwkt_reltoken(&nmp->nm_token); 831 return (error); 832 } 833 if (error == 0) { 834 if (vap->va_mtime.tv_sec != VNOVAL) { 835 np->n_mtime = vap->va_mtime.tv_sec; 836 } 837 } 838 } 839 error = nfs_setattrrpc(vp, vap, ap->a_cred, td); 840 if (error == 0) 841 kflags |= NOTE_EXTEND; 842 843 /* 844 * Sanity check if a truncation was issued. This should only occur 845 * if multiple processes are racing on the same file. 846 */ 847 if (error == 0 && vap->va_size != VNOVAL && 848 np->n_size != vap->va_size) { 849 kprintf("NFS ftruncate: server disagrees on the file size: " 850 "%jd/%jd/%jd\n", 851 (intmax_t)tsize, 852 (intmax_t)vap->va_size, 853 (intmax_t)np->n_size); 854 goto again; 855 } 856 if (error && vap->va_size != VNOVAL) { 857 np->n_size = np->n_vattr.va_size = tsize; 858 nfs_meta_setsize(vp, td, np->n_size, 0); 859 } 860 lwkt_reltoken(&nmp->nm_token); 861 nfs_knote(vp, kflags); 862 863 return (error); 864 } 865 866 /* 867 * Do an nfs setattr rpc. 868 */ 869 static int 870 nfs_setattrrpc(struct vnode *vp, struct vattr *vap, 871 struct ucred *cred, struct thread *td) 872 { 873 struct nfsv2_sattr *sp; 874 struct nfsnode *np = VTONFS(vp); 875 u_int32_t *tl; 876 int error = 0, wccflag = NFSV3_WCCRATTR; 877 struct nfsm_info info; 878 879 info.mrep = NULL; 880 info.v3 = NFS_ISV3(vp); 881 882 nfsstats.rpccnt[NFSPROC_SETATTR]++; 883 nfsm_reqhead(&info, vp, NFSPROC_SETATTR, 884 NFSX_FH(info.v3) + NFSX_SATTR(info.v3)); 885 ERROROUT(nfsm_fhtom(&info, vp)); 886 if (info.v3) { 887 nfsm_v3attrbuild(&info, vap, TRUE); 888 tl = nfsm_build(&info, NFSX_UNSIGNED); 889 *tl = nfs_false; 890 } else { 891 sp = nfsm_build(&info, NFSX_V2SATTR); 892 if (vap->va_mode == (mode_t)VNOVAL) 893 sp->sa_mode = nfs_xdrneg1; 894 else 895 sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode); 896 if (vap->va_uid == (uid_t)VNOVAL) 897 sp->sa_uid = nfs_xdrneg1; 898 else 899 sp->sa_uid = txdr_unsigned(vap->va_uid); 900 if (vap->va_gid == (gid_t)VNOVAL) 901 sp->sa_gid = nfs_xdrneg1; 902 else 903 sp->sa_gid = txdr_unsigned(vap->va_gid); 904 sp->sa_size = txdr_unsigned(vap->va_size); 905 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 906 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 907 } 908 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_SETATTR, td, cred, &error)); 909 if (info.v3) { 910 np->n_modestamp = 0; 911 ERROROUT(nfsm_wcc_data(&info, vp, &wccflag)); 912 } else { 913 ERROROUT(nfsm_loadattr(&info, vp, NULL)); 914 } 915 m_freem(info.mrep); 916 info.mrep = NULL; 917 nfsmout: 918 return (error); 919 } 920 921 static 922 void 923 nfs_cache_setvp(struct nchandle *nch, struct vnode *vp, int nctimeout) 924 { 925 if (nctimeout == 0) 926 nctimeout = 1; 927 else 928 nctimeout *= hz; 929 cache_setvp(nch, vp); 930 cache_settimeout(nch, nctimeout); 931 } 932 933 /* 934 * NEW API CALL - replaces nfs_lookup(). However, we cannot remove 935 * nfs_lookup() until all remaining new api calls are implemented. 936 * 937 * Resolve a namecache entry. This function is passed a locked ncp and 938 * must call nfs_cache_setvp() on it as appropriate to resolve the entry. 939 */ 940 static int 941 nfs_nresolve(struct vop_nresolve_args *ap) 942 { 943 struct thread *td = curthread; 944 struct namecache *ncp; 945 struct nfsmount *nmp; 946 struct nfsnode *np; 947 struct vnode *dvp; 948 struct vnode *nvp; 949 nfsfh_t *fhp; 950 int attrflag; 951 int fhsize; 952 int error; 953 int tmp_error; 954 int len; 955 struct nfsm_info info; 956 957 dvp = ap->a_dvp; 958 nmp = VFSTONFS(dvp->v_mount); 959 960 lwkt_gettoken(&nmp->nm_token); 961 962 if ((error = vget(dvp, LK_SHARED)) != 0) { 963 lwkt_reltoken(&nmp->nm_token); 964 return (error); 965 } 966 967 info.mrep = NULL; 968 info.v3 = NFS_ISV3(dvp); 969 970 nvp = NULL; 971 nfsstats.lookupcache_misses++; 972 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 973 ncp = ap->a_nch->ncp; 974 len = ncp->nc_nlen; 975 nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP, 976 NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len)); 977 ERROROUT(nfsm_fhtom(&info, dvp)); 978 ERROROUT(nfsm_strtom(&info, ncp->nc_name, len, NFS_MAXNAMLEN)); 979 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, td, 980 ap->a_cred, &error)); 981 if (error) { 982 /* 983 * Cache negatve lookups to reduce NFS traffic, but use 984 * a fast timeout. Otherwise use a timeout of 1 tick. 985 * XXX we should add a namecache flag for no-caching 986 * to uncache the negative hit as soon as possible, but 987 * we cannot simply destroy the entry because it is used 988 * as a placeholder by the caller. 989 * 990 * The refactored nfs code will overwrite a non-zero error 991 * with 0 when we use ERROROUT(), so don't here. 992 */ 993 if (error == ENOENT) 994 nfs_cache_setvp(ap->a_nch, NULL, nfsneg_cache_timeout); 995 tmp_error = nfsm_postop_attr(&info, dvp, &attrflag, 996 NFS_LATTR_NOSHRINK); 997 if (tmp_error) { 998 error = tmp_error; 999 goto nfsmout; 1000 } 1001 m_freem(info.mrep); 1002 info.mrep = NULL; 1003 goto nfsmout; 1004 } 1005 1006 /* 1007 * Success, get the file handle, do various checks, and load 1008 * post-operation data from the reply packet. Theoretically 1009 * we should never be looking up "." so, theoretically, we 1010 * should never get the same file handle as our directory. But 1011 * we check anyway. XXX 1012 * 1013 * Note that no timeout is set for the positive cache hit. We 1014 * assume, theoretically, that ESTALE returns will be dealt with 1015 * properly to handle NFS races and in anycase we cannot depend 1016 * on a timeout to deal with NFS open/create/excl issues so instead 1017 * of a bad hack here the rest of the NFS client code needs to do 1018 * the right thing. 1019 */ 1020 NEGATIVEOUT(fhsize = nfsm_getfh(&info, &fhp)); 1021 1022 np = VTONFS(dvp); 1023 if (NFS_CMPFH(np, fhp, fhsize)) { 1024 vref(dvp); 1025 nvp = dvp; 1026 } else { 1027 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, NULL); 1028 if (error) { 1029 m_freem(info.mrep); 1030 info.mrep = NULL; 1031 vput(dvp); 1032 lwkt_reltoken(&nmp->nm_token); 1033 return (error); 1034 } 1035 nvp = NFSTOV(np); 1036 } 1037 if (info.v3) { 1038 ERROROUT(nfsm_postop_attr(&info, nvp, &attrflag, 1039 NFS_LATTR_NOSHRINK)); 1040 ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag, 1041 NFS_LATTR_NOSHRINK)); 1042 } else { 1043 ERROROUT(nfsm_loadattr(&info, nvp, NULL)); 1044 } 1045 nfs_cache_setvp(ap->a_nch, nvp, nfspos_cache_timeout); 1046 m_freem(info.mrep); 1047 info.mrep = NULL; 1048 nfsmout: 1049 lwkt_reltoken(&nmp->nm_token); 1050 vput(dvp); 1051 if (nvp) { 1052 if (nvp == dvp) 1053 vrele(nvp); 1054 else 1055 vput(nvp); 1056 } 1057 return (error); 1058 } 1059 1060 /* 1061 * 'cached' nfs directory lookup 1062 * 1063 * NOTE: cannot be removed until NFS implements all the new n*() API calls. 1064 * 1065 * nfs_lookup(struct vnode *a_dvp, struct vnode **a_vpp, 1066 * struct componentname *a_cnp) 1067 */ 1068 static int 1069 nfs_lookup(struct vop_old_lookup_args *ap) 1070 { 1071 struct componentname *cnp = ap->a_cnp; 1072 struct vnode *dvp = ap->a_dvp; 1073 struct vnode **vpp = ap->a_vpp; 1074 int flags = cnp->cn_flags; 1075 struct vnode *newvp; 1076 struct vnode *notvp; 1077 struct nfsmount *nmp; 1078 long len; 1079 nfsfh_t *fhp; 1080 struct nfsnode *np; 1081 int lockparent, wantparent, attrflag, fhsize; 1082 int error; 1083 int tmp_error; 1084 struct nfsm_info info; 1085 1086 info.mrep = NULL; 1087 info.v3 = NFS_ISV3(dvp); 1088 error = 0; 1089 1090 notvp = (cnp->cn_flags & CNP_NOTVP) ? cnp->cn_notvp : NULL; 1091 1092 /* 1093 * Read-only mount check and directory check. 1094 */ 1095 *vpp = NULLVP; 1096 if ((dvp->v_mount->mnt_flag & MNT_RDONLY) && 1097 (cnp->cn_nameiop == NAMEI_DELETE || cnp->cn_nameiop == NAMEI_RENAME)) 1098 return (EROFS); 1099 1100 if (dvp->v_type != VDIR) 1101 return (ENOTDIR); 1102 1103 /* 1104 * Look it up in the cache. Note that ENOENT is only returned if we 1105 * previously entered a negative hit (see later on). The additional 1106 * nfsneg_cache_timeout check causes previously cached results to 1107 * be instantly ignored if the negative caching is turned off. 1108 */ 1109 lockparent = flags & CNP_LOCKPARENT; 1110 wantparent = flags & (CNP_LOCKPARENT|CNP_WANTPARENT); 1111 nmp = VFSTONFS(dvp->v_mount); 1112 np = VTONFS(dvp); 1113 1114 lwkt_gettoken(&nmp->nm_token); 1115 1116 /* 1117 * Go to the wire. 1118 */ 1119 error = 0; 1120 newvp = NULLVP; 1121 nfsstats.lookupcache_misses++; 1122 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 1123 len = cnp->cn_namelen; 1124 nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP, 1125 NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len)); 1126 ERROROUT(nfsm_fhtom(&info, dvp)); 1127 ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN)); 1128 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, cnp->cn_td, 1129 cnp->cn_cred, &error)); 1130 if (error) { 1131 tmp_error = nfsm_postop_attr(&info, dvp, &attrflag, 1132 NFS_LATTR_NOSHRINK); 1133 if (tmp_error) { 1134 error = tmp_error; 1135 goto nfsmout; 1136 } 1137 1138 m_freem(info.mrep); 1139 info.mrep = NULL; 1140 goto nfsmout; 1141 } 1142 NEGATIVEOUT(fhsize = nfsm_getfh(&info, &fhp)); 1143 1144 /* 1145 * Handle RENAME case... 1146 */ 1147 if (cnp->cn_nameiop == NAMEI_RENAME && wantparent) { 1148 if (NFS_CMPFH(np, fhp, fhsize)) { 1149 m_freem(info.mrep); 1150 info.mrep = NULL; 1151 lwkt_reltoken(&nmp->nm_token); 1152 return (EISDIR); 1153 } 1154 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, notvp); 1155 if (error) { 1156 m_freem(info.mrep); 1157 info.mrep = NULL; 1158 lwkt_reltoken(&nmp->nm_token); 1159 return (error); 1160 } 1161 newvp = NFSTOV(np); 1162 if (info.v3) { 1163 ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag, 1164 NFS_LATTR_NOSHRINK)); 1165 ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag, 1166 NFS_LATTR_NOSHRINK)); 1167 } else { 1168 ERROROUT(nfsm_loadattr(&info, newvp, NULL)); 1169 } 1170 *vpp = newvp; 1171 m_freem(info.mrep); 1172 info.mrep = NULL; 1173 if (!lockparent) { 1174 vn_unlock(dvp); 1175 cnp->cn_flags |= CNP_PDIRUNLOCK; 1176 } 1177 lwkt_reltoken(&nmp->nm_token); 1178 return (0); 1179 } 1180 1181 if (flags & CNP_ISDOTDOT) { 1182 vn_unlock(dvp); 1183 cnp->cn_flags |= CNP_PDIRUNLOCK; 1184 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, notvp); 1185 if (error) { 1186 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 1187 cnp->cn_flags &= ~CNP_PDIRUNLOCK; 1188 lwkt_reltoken(&nmp->nm_token); 1189 return (error); /* NOTE: return error from nget */ 1190 } 1191 newvp = NFSTOV(np); 1192 if (lockparent) { 1193 error = vn_lock(dvp, LK_EXCLUSIVE | LK_FAILRECLAIM); 1194 if (error) { 1195 vput(newvp); 1196 lwkt_reltoken(&nmp->nm_token); 1197 return (error); 1198 } 1199 cnp->cn_flags |= CNP_PDIRUNLOCK; 1200 } 1201 } else if (NFS_CMPFH(np, fhp, fhsize)) { 1202 vref(dvp); 1203 newvp = dvp; 1204 } else { 1205 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, notvp); 1206 if (error) { 1207 m_freem(info.mrep); 1208 info.mrep = NULL; 1209 lwkt_reltoken(&nmp->nm_token); 1210 return (error); 1211 } 1212 if (!lockparent) { 1213 vn_unlock(dvp); 1214 cnp->cn_flags |= CNP_PDIRUNLOCK; 1215 } 1216 newvp = NFSTOV(np); 1217 } 1218 if (info.v3) { 1219 ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag, 1220 NFS_LATTR_NOSHRINK)); 1221 ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag, 1222 NFS_LATTR_NOSHRINK)); 1223 } else { 1224 ERROROUT(nfsm_loadattr(&info, newvp, NULL)); 1225 } 1226 #if 0 1227 /* XXX MOVE TO nfs_nremove() */ 1228 if ((cnp->cn_flags & CNP_MAKEENTRY) && 1229 cnp->cn_nameiop != NAMEI_DELETE) { 1230 np->n_ctime = np->n_vattr.va_ctime.tv_sec; /* XXX */ 1231 } 1232 #endif 1233 *vpp = newvp; 1234 m_freem(info.mrep); 1235 info.mrep = NULL; 1236 nfsmout: 1237 if (error) { 1238 if (newvp != NULLVP) { 1239 vrele(newvp); 1240 *vpp = NULLVP; 1241 } 1242 if ((cnp->cn_nameiop == NAMEI_CREATE || 1243 cnp->cn_nameiop == NAMEI_RENAME) && 1244 error == ENOENT) { 1245 if (!lockparent) { 1246 vn_unlock(dvp); 1247 cnp->cn_flags |= CNP_PDIRUNLOCK; 1248 } 1249 if (dvp->v_mount->mnt_flag & MNT_RDONLY) 1250 error = EROFS; 1251 else 1252 error = EJUSTRETURN; 1253 } 1254 } 1255 lwkt_reltoken(&nmp->nm_token); 1256 return (error); 1257 } 1258 1259 /* 1260 * nfs read call. 1261 * Just call nfs_bioread() to do the work. 1262 * 1263 * nfs_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 1264 * struct ucred *a_cred) 1265 */ 1266 static int 1267 nfs_read(struct vop_read_args *ap) 1268 { 1269 struct vnode *vp = ap->a_vp; 1270 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 1271 int error; 1272 1273 lwkt_gettoken(&nmp->nm_token); 1274 error = nfs_bioread(vp, ap->a_uio, ap->a_ioflag); 1275 lwkt_reltoken(&nmp->nm_token); 1276 1277 return error; 1278 } 1279 1280 /* 1281 * nfs readlink call 1282 * 1283 * nfs_readlink(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred) 1284 */ 1285 static int 1286 nfs_readlink(struct vop_readlink_args *ap) 1287 { 1288 struct vnode *vp = ap->a_vp; 1289 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 1290 int error; 1291 1292 if (vp->v_type != VLNK) 1293 return (EINVAL); 1294 1295 lwkt_gettoken(&nmp->nm_token); 1296 error = nfs_bioread(vp, ap->a_uio, 0); 1297 lwkt_reltoken(&nmp->nm_token); 1298 1299 return error; 1300 } 1301 1302 /* 1303 * Do a readlink rpc. 1304 * Called by nfs_doio() from below the buffer cache. 1305 */ 1306 int 1307 nfs_readlinkrpc_uio(struct vnode *vp, struct uio *uiop) 1308 { 1309 int error = 0, len, attrflag; 1310 struct nfsm_info info; 1311 1312 info.mrep = NULL; 1313 info.v3 = NFS_ISV3(vp); 1314 1315 nfsstats.rpccnt[NFSPROC_READLINK]++; 1316 nfsm_reqhead(&info, vp, NFSPROC_READLINK, NFSX_FH(info.v3)); 1317 ERROROUT(nfsm_fhtom(&info, vp)); 1318 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READLINK, uiop->uio_td, 1319 nfs_vpcred(vp, ND_CHECK), &error)); 1320 if (info.v3) { 1321 ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, 1322 NFS_LATTR_NOSHRINK)); 1323 } 1324 if (!error) { 1325 NEGATIVEOUT(len = nfsm_strsiz(&info, NFS_MAXPATHLEN)); 1326 if (len == NFS_MAXPATHLEN) { 1327 struct nfsnode *np = VTONFS(vp); 1328 if (np->n_size && np->n_size < NFS_MAXPATHLEN) 1329 len = np->n_size; 1330 } 1331 ERROROUT(nfsm_mtouio(&info, uiop, len)); 1332 } 1333 m_freem(info.mrep); 1334 info.mrep = NULL; 1335 nfsmout: 1336 return (error); 1337 } 1338 1339 /* 1340 * nfs synchronous read rpc using UIO 1341 */ 1342 int 1343 nfs_readrpc_uio(struct vnode *vp, struct uio *uiop) 1344 { 1345 u_int32_t *tl; 1346 struct nfsmount *nmp; 1347 int error = 0, len, retlen, tsiz, eof, attrflag; 1348 struct nfsm_info info; 1349 off_t tmp_off; 1350 1351 info.mrep = NULL; 1352 info.v3 = NFS_ISV3(vp); 1353 1354 #ifndef nolint 1355 eof = 0; 1356 #endif 1357 nmp = VFSTONFS(vp->v_mount); 1358 1359 tsiz = uiop->uio_resid; 1360 tmp_off = uiop->uio_offset + tsiz; 1361 if (tmp_off > nmp->nm_maxfilesize || tmp_off < uiop->uio_offset) 1362 return (EFBIG); 1363 tmp_off = uiop->uio_offset; 1364 while (tsiz > 0) { 1365 nfsstats.rpccnt[NFSPROC_READ]++; 1366 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; 1367 nfsm_reqhead(&info, vp, NFSPROC_READ, 1368 NFSX_FH(info.v3) + NFSX_UNSIGNED * 3); 1369 ERROROUT(nfsm_fhtom(&info, vp)); 1370 tl = nfsm_build(&info, NFSX_UNSIGNED * 3); 1371 if (info.v3) { 1372 txdr_hyper(uiop->uio_offset, tl); 1373 *(tl + 2) = txdr_unsigned(len); 1374 } else { 1375 *tl++ = txdr_unsigned(uiop->uio_offset); 1376 *tl++ = txdr_unsigned(len); 1377 *tl = 0; 1378 } 1379 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READ, uiop->uio_td, 1380 nfs_vpcred(vp, ND_READ), &error)); 1381 if (info.v3) { 1382 ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, 1383 NFS_LATTR_NOSHRINK)); 1384 NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); 1385 eof = fxdr_unsigned(int, *(tl + 1)); 1386 } else { 1387 ERROROUT(nfsm_loadattr(&info, vp, NULL)); 1388 } 1389 NEGATIVEOUT(retlen = nfsm_strsiz(&info, len)); 1390 ERROROUT(nfsm_mtouio(&info, uiop, retlen)); 1391 m_freem(info.mrep); 1392 info.mrep = NULL; 1393 1394 /* 1395 * Handle short-read from server (NFSv3). If EOF is not 1396 * flagged (and no error occurred), but retlen is less 1397 * then the request size, we must zero-fill the remainder. 1398 */ 1399 if (retlen < len && info.v3 && eof == 0) { 1400 ERROROUT(uiomovez(len - retlen, uiop)); 1401 retlen = len; 1402 } 1403 tsiz -= retlen; 1404 1405 /* 1406 * Terminate loop on EOF or zero-length read. 1407 * 1408 * For NFSv2 a short-read indicates EOF, not zero-fill, 1409 * and also terminates the loop. 1410 */ 1411 if (info.v3) { 1412 if (eof || retlen == 0) 1413 tsiz = 0; 1414 } else if (retlen < len) { 1415 tsiz = 0; 1416 } 1417 } 1418 nfsmout: 1419 return (error); 1420 } 1421 1422 /* 1423 * nfs write call 1424 */ 1425 int 1426 nfs_writerpc_uio(struct vnode *vp, struct uio *uiop, 1427 int *iomode, int *must_commit) 1428 { 1429 u_int32_t *tl; 1430 int32_t backup; 1431 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 1432 int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit; 1433 int committed = NFSV3WRITE_FILESYNC; 1434 struct nfsm_info info; 1435 1436 info.mrep = NULL; 1437 info.v3 = NFS_ISV3(vp); 1438 1439 #ifndef DIAGNOSTIC 1440 if (uiop->uio_iovcnt != 1) 1441 panic("nfs: writerpc iovcnt > 1"); 1442 #endif 1443 *must_commit = 0; 1444 tsiz = uiop->uio_resid; 1445 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) 1446 return (EFBIG); 1447 while (tsiz > 0) { 1448 nfsstats.rpccnt[NFSPROC_WRITE]++; 1449 len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; 1450 nfsm_reqhead(&info, vp, NFSPROC_WRITE, 1451 NFSX_FH(info.v3) + 5 * NFSX_UNSIGNED + 1452 nfsm_rndup(len)); 1453 ERROROUT(nfsm_fhtom(&info, vp)); 1454 if (info.v3) { 1455 tl = nfsm_build(&info, 5 * NFSX_UNSIGNED); 1456 txdr_hyper(uiop->uio_offset, tl); 1457 tl += 2; 1458 *tl++ = txdr_unsigned(len); 1459 *tl++ = txdr_unsigned(*iomode); 1460 *tl = txdr_unsigned(len); 1461 } else { 1462 u_int32_t x; 1463 1464 tl = nfsm_build(&info, 4 * NFSX_UNSIGNED); 1465 /* Set both "begin" and "current" to non-garbage. */ 1466 x = txdr_unsigned((u_int32_t)uiop->uio_offset); 1467 *tl++ = x; /* "begin offset" */ 1468 *tl++ = x; /* "current offset" */ 1469 x = txdr_unsigned(len); 1470 *tl++ = x; /* total to this offset */ 1471 *tl = x; /* size of this write */ 1472 } 1473 ERROROUT(nfsm_uiotom(&info, uiop, len)); 1474 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_WRITE, uiop->uio_td, 1475 nfs_vpcred(vp, ND_WRITE), &error)); 1476 if (info.v3) { 1477 /* 1478 * The write RPC returns a before and after mtime. The 1479 * nfsm_wcc_data() macro checks the before n_mtime 1480 * against the before time and stores the after time 1481 * in the nfsnode's cached vattr and n_mtime field. 1482 * The NRMODIFIED bit will be set if the before 1483 * time did not match the original mtime. 1484 */ 1485 wccflag = NFSV3_WCCCHK; 1486 ERROROUT(nfsm_wcc_data(&info, vp, &wccflag)); 1487 if (error == 0) { 1488 NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED + NFSX_V3WRITEVERF)); 1489 rlen = fxdr_unsigned(int, *tl++); 1490 if (rlen == 0) { 1491 error = NFSERR_IO; 1492 m_freem(info.mrep); 1493 info.mrep = NULL; 1494 break; 1495 } else if (rlen < len) { 1496 backup = len - rlen; 1497 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base - backup; 1498 uiop->uio_iov->iov_len += backup; 1499 uiop->uio_offset -= backup; 1500 uiop->uio_resid += backup; 1501 len = rlen; 1502 } 1503 commit = fxdr_unsigned(int, *tl++); 1504 1505 /* 1506 * Return the lowest committment level 1507 * obtained by any of the RPCs. 1508 */ 1509 if (committed == NFSV3WRITE_FILESYNC) 1510 committed = commit; 1511 else if (committed == NFSV3WRITE_DATASYNC && 1512 commit == NFSV3WRITE_UNSTABLE) 1513 committed = commit; 1514 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){ 1515 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 1516 NFSX_V3WRITEVERF); 1517 nmp->nm_state |= NFSSTA_HASWRITEVERF; 1518 } else if (bcmp((caddr_t)tl, 1519 (caddr_t)nmp->nm_verf, NFSX_V3WRITEVERF)) { 1520 *must_commit = 1; 1521 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 1522 NFSX_V3WRITEVERF); 1523 } 1524 } 1525 } else { 1526 ERROROUT(nfsm_loadattr(&info, vp, NULL)); 1527 } 1528 m_freem(info.mrep); 1529 info.mrep = NULL; 1530 if (error) 1531 break; 1532 tsiz -= len; 1533 } 1534 nfsmout: 1535 if (vp->v_mount->mnt_flag & MNT_ASYNC) 1536 committed = NFSV3WRITE_FILESYNC; 1537 *iomode = committed; 1538 if (error) 1539 uiop->uio_resid = tsiz; 1540 return (error); 1541 } 1542 1543 /* 1544 * nfs mknod rpc 1545 * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the 1546 * mode set to specify the file type and the size field for rdev. 1547 */ 1548 static int 1549 nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, 1550 struct vattr *vap) 1551 { 1552 struct nfsv2_sattr *sp; 1553 u_int32_t *tl; 1554 struct vnode *newvp = NULL; 1555 struct nfsnode *np = NULL; 1556 struct vattr vattr; 1557 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0; 1558 int rmajor, rminor; 1559 struct nfsm_info info; 1560 1561 info.mrep = NULL; 1562 info.v3 = NFS_ISV3(dvp); 1563 1564 if (vap->va_type == VCHR || vap->va_type == VBLK) { 1565 rmajor = txdr_unsigned(vap->va_rmajor); 1566 rminor = txdr_unsigned(vap->va_rminor); 1567 } else if (vap->va_type == VFIFO || vap->va_type == VSOCK) { 1568 rmajor = nfs_xdrneg1; 1569 rminor = nfs_xdrneg1; 1570 } else { 1571 return (EOPNOTSUPP); 1572 } 1573 if ((error = VOP_GETATTR(dvp, &vattr)) != 0) { 1574 return (error); 1575 } 1576 nfsstats.rpccnt[NFSPROC_MKNOD]++; 1577 nfsm_reqhead(&info, dvp, NFSPROC_MKNOD, 1578 NFSX_FH(info.v3) + 4 * NFSX_UNSIGNED + 1579 nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(info.v3)); 1580 ERROROUT(nfsm_fhtom(&info, dvp)); 1581 ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, 1582 NFS_MAXNAMLEN)); 1583 if (info.v3) { 1584 tl = nfsm_build(&info, NFSX_UNSIGNED); 1585 *tl++ = vtonfsv3_type(vap->va_type); 1586 nfsm_v3attrbuild(&info, vap, FALSE); 1587 if (vap->va_type == VCHR || vap->va_type == VBLK) { 1588 tl = nfsm_build(&info, 2 * NFSX_UNSIGNED); 1589 *tl++ = txdr_unsigned(vap->va_rmajor); 1590 *tl = txdr_unsigned(vap->va_rminor); 1591 } 1592 } else { 1593 sp = nfsm_build(&info, NFSX_V2SATTR); 1594 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); 1595 sp->sa_uid = nfs_xdrneg1; 1596 sp->sa_gid = nfs_xdrneg1; 1597 sp->sa_size = makeudev(rmajor, rminor); 1598 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1599 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1600 } 1601 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_MKNOD, cnp->cn_td, 1602 cnp->cn_cred, &error)); 1603 if (!error) { 1604 ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp)); 1605 if (!gotvp) { 1606 if (newvp) { 1607 vput(newvp); 1608 newvp = NULL; 1609 } 1610 error = nfs_lookitup(dvp, cnp->cn_nameptr, 1611 cnp->cn_namelen, cnp->cn_cred, cnp->cn_td, &np); 1612 if (!error) 1613 newvp = NFSTOV(np); 1614 } 1615 } 1616 if (info.v3) { 1617 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); 1618 } 1619 m_freem(info.mrep); 1620 info.mrep = NULL; 1621 nfsmout: 1622 if (error) { 1623 if (newvp) 1624 vput(newvp); 1625 } else { 1626 *vpp = newvp; 1627 } 1628 VTONFS(dvp)->n_flag |= NLMODIFIED; 1629 if (!wccflag) 1630 VTONFS(dvp)->n_attrstamp = 0; 1631 return (error); 1632 } 1633 1634 /* 1635 * nfs mknod vop 1636 * just call nfs_mknodrpc() to do the work. 1637 * 1638 * nfs_mknod(struct vnode *a_dvp, struct vnode **a_vpp, 1639 * struct componentname *a_cnp, struct vattr *a_vap) 1640 */ 1641 /* ARGSUSED */ 1642 static int 1643 nfs_mknod(struct vop_old_mknod_args *ap) 1644 { 1645 struct nfsmount *nmp = VFSTONFS(ap->a_dvp->v_mount); 1646 int error; 1647 1648 lwkt_gettoken(&nmp->nm_token); 1649 error = nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap); 1650 lwkt_reltoken(&nmp->nm_token); 1651 if (error == 0) 1652 nfs_knote(ap->a_dvp, NOTE_WRITE); 1653 1654 return error; 1655 } 1656 1657 static u_long create_verf; 1658 /* 1659 * nfs file create call 1660 * 1661 * nfs_create(struct vnode *a_dvp, struct vnode **a_vpp, 1662 * struct componentname *a_cnp, struct vattr *a_vap) 1663 */ 1664 static int 1665 nfs_create(struct vop_old_create_args *ap) 1666 { 1667 struct vnode *dvp = ap->a_dvp; 1668 struct vattr *vap = ap->a_vap; 1669 struct nfsmount *nmp = VFSTONFS(dvp->v_mount); 1670 struct componentname *cnp = ap->a_cnp; 1671 struct nfsv2_sattr *sp; 1672 u_int32_t *tl; 1673 struct nfsnode *np = NULL; 1674 struct vnode *newvp = NULL; 1675 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0; 1676 struct vattr vattr; 1677 struct nfsm_info info; 1678 1679 info.mrep = NULL; 1680 info.v3 = NFS_ISV3(dvp); 1681 lwkt_gettoken(&nmp->nm_token); 1682 1683 /* 1684 * Oops, not for me.. 1685 */ 1686 if (vap->va_type == VSOCK) { 1687 error = nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap); 1688 lwkt_reltoken(&nmp->nm_token); 1689 return error; 1690 } 1691 1692 if ((error = VOP_GETATTR(dvp, &vattr)) != 0) { 1693 lwkt_reltoken(&nmp->nm_token); 1694 return (error); 1695 } 1696 if (vap->va_vaflags & VA_EXCLUSIVE) 1697 fmode |= O_EXCL; 1698 again: 1699 nfsstats.rpccnt[NFSPROC_CREATE]++; 1700 nfsm_reqhead(&info, dvp, NFSPROC_CREATE, 1701 NFSX_FH(info.v3) + 2 * NFSX_UNSIGNED + 1702 nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(info.v3)); 1703 ERROROUT(nfsm_fhtom(&info, dvp)); 1704 ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, 1705 NFS_MAXNAMLEN)); 1706 if (info.v3) { 1707 tl = nfsm_build(&info, NFSX_UNSIGNED); 1708 if (fmode & O_EXCL) { 1709 *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); 1710 tl = nfsm_build(&info, NFSX_V3CREATEVERF); 1711 #ifdef INET 1712 if (!TAILQ_EMPTY(&in_ifaddrheads[mycpuid])) 1713 *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrheads[mycpuid])->ia)->sin_addr.s_addr; 1714 else 1715 #endif 1716 *tl++ = create_verf; 1717 *tl = ++create_verf; 1718 } else { 1719 *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED); 1720 nfsm_v3attrbuild(&info, vap, FALSE); 1721 } 1722 } else { 1723 sp = nfsm_build(&info, NFSX_V2SATTR); 1724 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); 1725 sp->sa_uid = nfs_xdrneg1; 1726 sp->sa_gid = nfs_xdrneg1; 1727 sp->sa_size = 0; 1728 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1729 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1730 } 1731 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_CREATE, cnp->cn_td, 1732 cnp->cn_cred, &error)); 1733 if (error == 0) { 1734 ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp)); 1735 if (!gotvp) { 1736 if (newvp) { 1737 vput(newvp); 1738 newvp = NULL; 1739 } 1740 error = nfs_lookitup(dvp, cnp->cn_nameptr, 1741 cnp->cn_namelen, cnp->cn_cred, cnp->cn_td, &np); 1742 if (!error) 1743 newvp = NFSTOV(np); 1744 } 1745 } 1746 if (info.v3) { 1747 if (error == 0) 1748 error = nfsm_wcc_data(&info, dvp, &wccflag); 1749 else 1750 (void)nfsm_wcc_data(&info, dvp, &wccflag); 1751 } 1752 m_freem(info.mrep); 1753 info.mrep = NULL; 1754 nfsmout: 1755 if (error) { 1756 if (info.v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) { 1757 KKASSERT(newvp == NULL); 1758 fmode &= ~O_EXCL; 1759 goto again; 1760 } 1761 } else if (info.v3 && (fmode & O_EXCL)) { 1762 /* 1763 * We are normally called with only a partially initialized 1764 * VAP. Since the NFSv3 spec says that server may use the 1765 * file attributes to store the verifier, the spec requires 1766 * us to do a SETATTR RPC. FreeBSD servers store the verifier 1767 * in atime, but we can't really assume that all servers will 1768 * so we ensure that our SETATTR sets both atime and mtime. 1769 */ 1770 if (vap->va_mtime.tv_sec == VNOVAL) 1771 vfs_timestamp(&vap->va_mtime); 1772 if (vap->va_atime.tv_sec == VNOVAL) 1773 vap->va_atime = vap->va_mtime; 1774 error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_td); 1775 } 1776 if (error == 0) { 1777 /* 1778 * The new np may have enough info for access 1779 * checks, make sure rucred and wucred are 1780 * initialized for read and write rpc's. 1781 */ 1782 np = VTONFS(newvp); 1783 if (np->n_rucred == NULL) 1784 np->n_rucred = crhold(cnp->cn_cred); 1785 if (np->n_wucred == NULL) 1786 np->n_wucred = crhold(cnp->cn_cred); 1787 *ap->a_vpp = newvp; 1788 nfs_knote(dvp, NOTE_WRITE); 1789 } else if (newvp) { 1790 vput(newvp); 1791 } 1792 VTONFS(dvp)->n_flag |= NLMODIFIED; 1793 if (!wccflag) 1794 VTONFS(dvp)->n_attrstamp = 0; 1795 lwkt_reltoken(&nmp->nm_token); 1796 return (error); 1797 } 1798 1799 /* 1800 * nfs file remove call 1801 * To try and make nfs semantics closer to ufs semantics, a file that has 1802 * other processes using the vnode is renamed instead of removed and then 1803 * removed later on the last close. 1804 * - If v_refcnt > 1 1805 * If a rename is not already in the works 1806 * call nfs_sillyrename() to set it up 1807 * else 1808 * do the remove rpc 1809 * 1810 * nfs_remove(struct vnode *a_dvp, struct vnode *a_vp, 1811 * struct componentname *a_cnp) 1812 */ 1813 static int 1814 nfs_remove(struct vop_old_remove_args *ap) 1815 { 1816 struct vnode *vp = ap->a_vp; 1817 struct vnode *dvp = ap->a_dvp; 1818 struct nfsmount *nmp = VFSTONFS(dvp->v_mount); 1819 struct componentname *cnp = ap->a_cnp; 1820 struct nfsnode *np = VTONFS(vp); 1821 int error = 0; 1822 struct vattr vattr; 1823 1824 lwkt_gettoken(&nmp->nm_token); 1825 #ifndef DIAGNOSTIC 1826 if (VREFCNT(vp) < 1) 1827 panic("nfs_remove: bad v_refcnt"); 1828 #endif 1829 if (vp->v_type == VDIR) { 1830 error = EPERM; 1831 } else if (VREFCNT(vp) == 1 || (np->n_sillyrename && 1832 VOP_GETATTR(vp, &vattr) == 0 && vattr.va_nlink > 1)) { 1833 /* 1834 * throw away biocache buffers, mainly to avoid 1835 * unnecessary delayed writes later. 1836 */ 1837 error = nfs_vinvalbuf(vp, 0, 1); 1838 /* Do the rpc */ 1839 if (error != EINTR) 1840 error = nfs_removerpc(dvp, cnp->cn_nameptr, 1841 cnp->cn_namelen, cnp->cn_cred, cnp->cn_td); 1842 /* 1843 * Kludge City: If the first reply to the remove rpc is lost.. 1844 * the reply to the retransmitted request will be ENOENT 1845 * since the file was in fact removed 1846 * Therefore, we cheat and return success. 1847 */ 1848 if (error == ENOENT) 1849 error = 0; 1850 } else if (!np->n_sillyrename) { 1851 error = nfs_sillyrename(dvp, vp, cnp); 1852 } 1853 np->n_attrstamp = 0; 1854 lwkt_reltoken(&nmp->nm_token); 1855 if (error == 0) { 1856 nfs_knote(vp, NOTE_DELETE); 1857 nfs_knote(dvp, NOTE_WRITE); 1858 } 1859 1860 return (error); 1861 } 1862 1863 /* 1864 * nfs file remove rpc called from nfs_inactive 1865 * 1866 * NOTE: s_dvp can be VBAD during a forced unmount. 1867 */ 1868 int 1869 nfs_removeit(struct sillyrename *sp) 1870 { 1871 if (sp->s_dvp->v_type == VBAD) 1872 return(0); 1873 return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, 1874 sp->s_cred, NULL)); 1875 } 1876 1877 /* 1878 * Nfs remove rpc, called from nfs_remove() and nfs_removeit(). 1879 */ 1880 static int 1881 nfs_removerpc(struct vnode *dvp, const char *name, int namelen, 1882 struct ucred *cred, struct thread *td) 1883 { 1884 int error = 0, wccflag = NFSV3_WCCRATTR; 1885 struct nfsm_info info; 1886 1887 info.mrep = NULL; 1888 info.v3 = NFS_ISV3(dvp); 1889 1890 nfsstats.rpccnt[NFSPROC_REMOVE]++; 1891 nfsm_reqhead(&info, dvp, NFSPROC_REMOVE, 1892 NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(namelen)); 1893 ERROROUT(nfsm_fhtom(&info, dvp)); 1894 ERROROUT(nfsm_strtom(&info, name, namelen, NFS_MAXNAMLEN)); 1895 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_REMOVE, td, cred, &error)); 1896 if (info.v3) { 1897 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); 1898 } 1899 m_freem(info.mrep); 1900 info.mrep = NULL; 1901 nfsmout: 1902 VTONFS(dvp)->n_flag |= NLMODIFIED; 1903 if (!wccflag) 1904 VTONFS(dvp)->n_attrstamp = 0; 1905 return (error); 1906 } 1907 1908 /* 1909 * nfs file rename call 1910 * 1911 * nfs_rename(struct vnode *a_fdvp, struct vnode *a_fvp, 1912 * struct componentname *a_fcnp, struct vnode *a_tdvp, 1913 * struct vnode *a_tvp, struct componentname *a_tcnp) 1914 */ 1915 static int 1916 nfs_rename(struct vop_old_rename_args *ap) 1917 { 1918 struct vnode *fvp = ap->a_fvp; 1919 struct vnode *tvp = ap->a_tvp; 1920 struct vnode *fdvp = ap->a_fdvp; 1921 struct vnode *tdvp = ap->a_tdvp; 1922 struct componentname *tcnp = ap->a_tcnp; 1923 struct componentname *fcnp = ap->a_fcnp; 1924 struct nfsmount *nmp = VFSTONFS(fdvp->v_mount); 1925 int error; 1926 1927 lwkt_gettoken(&nmp->nm_token); 1928 1929 /* Check for cross-device rename */ 1930 if ((fvp->v_mount != tdvp->v_mount) || 1931 (tvp && (fvp->v_mount != tvp->v_mount))) { 1932 error = EXDEV; 1933 goto out; 1934 } 1935 1936 /* 1937 * We shouldn't have to flush fvp on rename for most server-side 1938 * filesystems as the file handle should not change. Unfortunately 1939 * the inode for some filesystems (msdosfs) might be tied to the 1940 * file name or directory position so to be completely safe 1941 * vfs.nfs.flush_on_rename is set by default. Clear to improve 1942 * performance. 1943 * 1944 * We must flush tvp on rename because it might become stale on the 1945 * server after the rename. 1946 */ 1947 if (nfs_flush_on_rename) 1948 VOP_FSYNC(fvp, MNT_WAIT, 0); 1949 if (tvp) 1950 VOP_FSYNC(tvp, MNT_WAIT, 0); 1951 1952 /* 1953 * If the tvp exists and is in use, sillyrename it before doing the 1954 * rename of the new file over it. 1955 * 1956 * XXX Can't sillyrename a directory. 1957 * 1958 * We do not attempt to do any namecache purges in this old API 1959 * routine. The new API compat functions have access to the actual 1960 * namecache structures and will do it for us. 1961 */ 1962 if (tvp && VREFCNT(tvp) > 1 && !VTONFS(tvp)->n_sillyrename && 1963 tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) { 1964 nfs_knote(tvp, NOTE_DELETE); 1965 vput(tvp); 1966 tvp = NULL; 1967 } else if (tvp) { 1968 nfs_knote(tvp, NOTE_DELETE); 1969 } 1970 1971 error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen, 1972 tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred, 1973 tcnp->cn_td); 1974 1975 out: 1976 if (error == 0) { 1977 nfs_knote(fdvp, NOTE_WRITE); 1978 nfs_knote(tdvp, NOTE_WRITE); 1979 nfs_knote(fvp, NOTE_RENAME); 1980 } 1981 lwkt_reltoken(&nmp->nm_token); 1982 if (tdvp == tvp) 1983 vrele(tdvp); 1984 else 1985 vput(tdvp); 1986 if (tvp) 1987 vput(tvp); 1988 vrele(fdvp); 1989 vrele(fvp); 1990 /* 1991 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. 1992 */ 1993 if (error == ENOENT) 1994 error = 0; 1995 return (error); 1996 } 1997 1998 /* 1999 * nfs file rename rpc called from nfs_remove() above 2000 */ 2001 static int 2002 nfs_renameit(struct vnode *sdvp, struct componentname *scnp, 2003 struct sillyrename *sp) 2004 { 2005 return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, 2006 sdvp, sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_td)); 2007 } 2008 2009 /* 2010 * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit(). 2011 */ 2012 static int 2013 nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen, 2014 struct vnode *tdvp, const char *tnameptr, int tnamelen, 2015 struct ucred *cred, struct thread *td) 2016 { 2017 int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR; 2018 struct nfsm_info info; 2019 2020 info.mrep = NULL; 2021 info.v3 = NFS_ISV3(fdvp); 2022 2023 nfsstats.rpccnt[NFSPROC_RENAME]++; 2024 nfsm_reqhead(&info, fdvp, NFSPROC_RENAME, 2025 (NFSX_FH(info.v3) + NFSX_UNSIGNED)*2 + 2026 nfsm_rndup(fnamelen) + nfsm_rndup(tnamelen)); 2027 ERROROUT(nfsm_fhtom(&info, fdvp)); 2028 ERROROUT(nfsm_strtom(&info, fnameptr, fnamelen, NFS_MAXNAMLEN)); 2029 ERROROUT(nfsm_fhtom(&info, tdvp)); 2030 ERROROUT(nfsm_strtom(&info, tnameptr, tnamelen, NFS_MAXNAMLEN)); 2031 NEGKEEPOUT(nfsm_request(&info, fdvp, NFSPROC_RENAME, td, cred, &error)); 2032 if (info.v3) { 2033 ERROROUT(nfsm_wcc_data(&info, fdvp, &fwccflag)); 2034 ERROROUT(nfsm_wcc_data(&info, tdvp, &twccflag)); 2035 } 2036 m_freem(info.mrep); 2037 info.mrep = NULL; 2038 nfsmout: 2039 VTONFS(fdvp)->n_flag |= NLMODIFIED; 2040 VTONFS(tdvp)->n_flag |= NLMODIFIED; 2041 if (!fwccflag) 2042 VTONFS(fdvp)->n_attrstamp = 0; 2043 if (!twccflag) 2044 VTONFS(tdvp)->n_attrstamp = 0; 2045 return (error); 2046 } 2047 2048 /* 2049 * nfs hard link create call 2050 * 2051 * nfs_link(struct vnode *a_tdvp, struct vnode *a_vp, 2052 * struct componentname *a_cnp) 2053 */ 2054 static int 2055 nfs_link(struct vop_old_link_args *ap) 2056 { 2057 struct vnode *vp = ap->a_vp; 2058 struct vnode *tdvp = ap->a_tdvp; 2059 struct nfsmount *nmp = VFSTONFS(tdvp->v_mount); 2060 struct componentname *cnp = ap->a_cnp; 2061 int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0; 2062 struct nfsm_info info; 2063 2064 if (vp->v_mount != tdvp->v_mount) { 2065 return (EXDEV); 2066 } 2067 lwkt_gettoken(&nmp->nm_token); 2068 2069 /* 2070 * The attribute cache may get out of sync with the server on link. 2071 * Pushing writes to the server before handle was inherited from 2072 * long long ago and it is unclear if we still need to do this. 2073 * Defaults to off. 2074 */ 2075 if (nfs_flush_on_hlink) 2076 VOP_FSYNC(vp, MNT_WAIT, 0); 2077 2078 info.mrep = NULL; 2079 info.v3 = NFS_ISV3(vp); 2080 2081 nfsstats.rpccnt[NFSPROC_LINK]++; 2082 nfsm_reqhead(&info, vp, NFSPROC_LINK, 2083 NFSX_FH(info.v3) * 2 + NFSX_UNSIGNED + 2084 nfsm_rndup(cnp->cn_namelen)); 2085 ERROROUT(nfsm_fhtom(&info, vp)); 2086 ERROROUT(nfsm_fhtom(&info, tdvp)); 2087 ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, 2088 NFS_MAXNAMLEN)); 2089 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_LINK, cnp->cn_td, 2090 cnp->cn_cred, &error)); 2091 if (info.v3) { 2092 ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, 2093 NFS_LATTR_NOSHRINK)); 2094 ERROROUT(nfsm_wcc_data(&info, tdvp, &wccflag)); 2095 } 2096 m_freem(info.mrep); 2097 info.mrep = NULL; 2098 nfsmout: 2099 VTONFS(tdvp)->n_flag |= NLMODIFIED; 2100 if (!attrflag) 2101 VTONFS(vp)->n_attrstamp = 0; 2102 if (!wccflag) 2103 VTONFS(tdvp)->n_attrstamp = 0; 2104 /* 2105 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. 2106 */ 2107 if (error == EEXIST) 2108 error = 0; 2109 lwkt_reltoken(&nmp->nm_token); 2110 if (error == 0) { 2111 nfs_knote(vp, NOTE_LINK); 2112 nfs_knote(tdvp, NOTE_WRITE); 2113 } 2114 2115 return (error); 2116 } 2117 2118 /* 2119 * nfs symbolic link create call 2120 * 2121 * nfs_symlink(struct vnode *a_dvp, struct vnode **a_vpp, 2122 * struct componentname *a_cnp, struct vattr *a_vap, 2123 * char *a_target) 2124 */ 2125 static int 2126 nfs_symlink(struct vop_old_symlink_args *ap) 2127 { 2128 struct vnode *dvp = ap->a_dvp; 2129 struct vattr *vap = ap->a_vap; 2130 struct nfsmount *nmp = VFSTONFS(dvp->v_mount); 2131 struct componentname *cnp = ap->a_cnp; 2132 struct nfsv2_sattr *sp; 2133 int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp; 2134 struct vnode *newvp = NULL; 2135 struct nfsm_info info; 2136 2137 info.mrep = NULL; 2138 info.v3 = NFS_ISV3(dvp); 2139 lwkt_gettoken(&nmp->nm_token); 2140 2141 nfsstats.rpccnt[NFSPROC_SYMLINK]++; 2142 slen = strlen(ap->a_target); 2143 nfsm_reqhead(&info, dvp, NFSPROC_SYMLINK, 2144 NFSX_FH(info.v3) + 2*NFSX_UNSIGNED + 2145 nfsm_rndup(cnp->cn_namelen) + 2146 nfsm_rndup(slen) + NFSX_SATTR(info.v3)); 2147 ERROROUT(nfsm_fhtom(&info, dvp)); 2148 ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, 2149 NFS_MAXNAMLEN)); 2150 if (info.v3) { 2151 nfsm_v3attrbuild(&info, vap, FALSE); 2152 } 2153 ERROROUT(nfsm_strtom(&info, ap->a_target, slen, NFS_MAXPATHLEN)); 2154 if (info.v3 == 0) { 2155 sp = nfsm_build(&info, NFSX_V2SATTR); 2156 sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode); 2157 sp->sa_uid = nfs_xdrneg1; 2158 sp->sa_gid = nfs_xdrneg1; 2159 sp->sa_size = nfs_xdrneg1; 2160 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 2161 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 2162 } 2163 2164 /* 2165 * Issue the NFS request and get the rpc response. 2166 * 2167 * Only NFSv3 responses returning an error of 0 actually return 2168 * a file handle that can be converted into newvp without having 2169 * to do an extra lookup rpc. 2170 */ 2171 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_SYMLINK, cnp->cn_td, 2172 cnp->cn_cred, &error)); 2173 if (info.v3) { 2174 if (error == 0) { 2175 ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp)); 2176 } 2177 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); 2178 } 2179 2180 /* 2181 * out code jumps -> here, mrep is also freed. 2182 */ 2183 2184 m_freem(info.mrep); 2185 info.mrep = NULL; 2186 nfsmout: 2187 2188 /* 2189 * If we get an EEXIST error, silently convert it to no-error 2190 * in case of an NFS retry. 2191 */ 2192 if (error == EEXIST) 2193 error = 0; 2194 2195 /* 2196 * If we do not have (or no longer have) an error, and we could 2197 * not extract the newvp from the response due to the request being 2198 * NFSv2 or the error being EEXIST. We have to do a lookup in order 2199 * to obtain a newvp to return. 2200 */ 2201 if (error == 0 && newvp == NULL) { 2202 struct nfsnode *np = NULL; 2203 2204 error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen, 2205 cnp->cn_cred, cnp->cn_td, &np); 2206 if (!error) 2207 newvp = NFSTOV(np); 2208 } 2209 if (error) { 2210 if (newvp) 2211 vput(newvp); 2212 } else { 2213 *ap->a_vpp = newvp; 2214 } 2215 VTONFS(dvp)->n_flag |= NLMODIFIED; 2216 if (!wccflag) 2217 VTONFS(dvp)->n_attrstamp = 0; 2218 if (error == 0 && *ap->a_vpp) 2219 nfs_knote(*ap->a_vpp, NOTE_WRITE); 2220 lwkt_reltoken(&nmp->nm_token); 2221 2222 return (error); 2223 } 2224 2225 /* 2226 * nfs make dir call 2227 * 2228 * nfs_mkdir(struct vnode *a_dvp, struct vnode **a_vpp, 2229 * struct componentname *a_cnp, struct vattr *a_vap) 2230 */ 2231 static int 2232 nfs_mkdir(struct vop_old_mkdir_args *ap) 2233 { 2234 struct vnode *dvp = ap->a_dvp; 2235 struct vattr *vap = ap->a_vap; 2236 struct nfsmount *nmp = VFSTONFS(dvp->v_mount); 2237 struct componentname *cnp = ap->a_cnp; 2238 struct nfsv2_sattr *sp; 2239 struct nfsnode *np = NULL; 2240 struct vnode *newvp = NULL; 2241 struct vattr vattr; 2242 int error = 0, wccflag = NFSV3_WCCRATTR; 2243 int gotvp = 0; 2244 int len; 2245 struct nfsm_info info; 2246 2247 info.mrep = NULL; 2248 info.v3 = NFS_ISV3(dvp); 2249 lwkt_gettoken(&nmp->nm_token); 2250 2251 if ((error = VOP_GETATTR(dvp, &vattr)) != 0) { 2252 lwkt_reltoken(&nmp->nm_token); 2253 return (error); 2254 } 2255 len = cnp->cn_namelen; 2256 nfsstats.rpccnt[NFSPROC_MKDIR]++; 2257 nfsm_reqhead(&info, dvp, NFSPROC_MKDIR, 2258 NFSX_FH(info.v3) + NFSX_UNSIGNED + 2259 nfsm_rndup(len) + NFSX_SATTR(info.v3)); 2260 ERROROUT(nfsm_fhtom(&info, dvp)); 2261 ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN)); 2262 if (info.v3) { 2263 nfsm_v3attrbuild(&info, vap, FALSE); 2264 } else { 2265 sp = nfsm_build(&info, NFSX_V2SATTR); 2266 sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode); 2267 sp->sa_uid = nfs_xdrneg1; 2268 sp->sa_gid = nfs_xdrneg1; 2269 sp->sa_size = nfs_xdrneg1; 2270 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 2271 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 2272 } 2273 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_MKDIR, cnp->cn_td, 2274 cnp->cn_cred, &error)); 2275 if (error == 0) { 2276 ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp)); 2277 } 2278 if (info.v3) { 2279 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); 2280 } 2281 m_freem(info.mrep); 2282 info.mrep = NULL; 2283 nfsmout: 2284 VTONFS(dvp)->n_flag |= NLMODIFIED; 2285 if (!wccflag) 2286 VTONFS(dvp)->n_attrstamp = 0; 2287 /* 2288 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry 2289 * if we can succeed in looking up the directory. 2290 */ 2291 if (error == EEXIST || (!error && !gotvp)) { 2292 if (newvp) { 2293 vrele(newvp); 2294 newvp = NULL; 2295 } 2296 error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred, 2297 cnp->cn_td, &np); 2298 if (!error) { 2299 newvp = NFSTOV(np); 2300 if (newvp->v_type != VDIR) 2301 error = EEXIST; 2302 } 2303 } 2304 if (error) { 2305 if (newvp) 2306 vrele(newvp); 2307 } else { 2308 nfs_knote(dvp, NOTE_WRITE | NOTE_LINK); 2309 *ap->a_vpp = newvp; 2310 } 2311 lwkt_reltoken(&nmp->nm_token); 2312 return (error); 2313 } 2314 2315 /* 2316 * nfs remove directory call 2317 * 2318 * nfs_rmdir(struct vnode *a_dvp, struct vnode *a_vp, 2319 * struct componentname *a_cnp) 2320 */ 2321 static int 2322 nfs_rmdir(struct vop_old_rmdir_args *ap) 2323 { 2324 struct vnode *vp = ap->a_vp; 2325 struct vnode *dvp = ap->a_dvp; 2326 struct nfsmount *nmp = VFSTONFS(dvp->v_mount); 2327 struct componentname *cnp = ap->a_cnp; 2328 int error = 0, wccflag = NFSV3_WCCRATTR; 2329 struct nfsm_info info; 2330 2331 info.mrep = NULL; 2332 info.v3 = NFS_ISV3(dvp); 2333 2334 if (dvp == vp) 2335 return (EINVAL); 2336 2337 lwkt_gettoken(&nmp->nm_token); 2338 2339 nfsstats.rpccnt[NFSPROC_RMDIR]++; 2340 nfsm_reqhead(&info, dvp, NFSPROC_RMDIR, 2341 NFSX_FH(info.v3) + NFSX_UNSIGNED + 2342 nfsm_rndup(cnp->cn_namelen)); 2343 ERROROUT(nfsm_fhtom(&info, dvp)); 2344 ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, 2345 NFS_MAXNAMLEN)); 2346 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_RMDIR, cnp->cn_td, 2347 cnp->cn_cred, &error)); 2348 if (info.v3) { 2349 ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); 2350 } 2351 m_freem(info.mrep); 2352 info.mrep = NULL; 2353 nfsmout: 2354 VTONFS(dvp)->n_flag |= NLMODIFIED; 2355 if (!wccflag) 2356 VTONFS(dvp)->n_attrstamp = 0; 2357 /* 2358 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. 2359 */ 2360 if (error == ENOENT) 2361 error = 0; 2362 else 2363 nfs_knote(dvp, NOTE_WRITE | NOTE_LINK); 2364 lwkt_reltoken(&nmp->nm_token); 2365 2366 return (error); 2367 } 2368 2369 /* 2370 * nfs readdir call 2371 * 2372 * nfs_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred) 2373 */ 2374 static int 2375 nfs_readdir(struct vop_readdir_args *ap) 2376 { 2377 struct vnode *vp = ap->a_vp; 2378 struct nfsnode *np = VTONFS(vp); 2379 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2380 struct uio *uio = ap->a_uio; 2381 int tresid, error; 2382 struct vattr vattr; 2383 2384 if (vp->v_type != VDIR) 2385 return (EPERM); 2386 2387 error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_FAILRECLAIM); 2388 if (error) 2389 return (error); 2390 2391 lwkt_gettoken(&nmp->nm_token); 2392 2393 /* 2394 * If we have a valid EOF offset cache we must call VOP_GETATTR() 2395 * and then check that is still valid, or if this is an NQNFS mount 2396 * we call NQNFS_CKCACHEABLE() instead of VOP_GETATTR(). Note that 2397 * VOP_GETATTR() does not necessarily go to the wire. 2398 */ 2399 if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset && 2400 (np->n_flag & (NLMODIFIED|NRMODIFIED)) == 0) { 2401 if (VOP_GETATTR(vp, &vattr) == 0 && 2402 (np->n_flag & (NLMODIFIED|NRMODIFIED)) == 0 2403 ) { 2404 nfsstats.direofcache_hits++; 2405 goto done; 2406 } 2407 } 2408 2409 /* 2410 * Call nfs_bioread() to do the real work. nfs_bioread() does its 2411 * own cache coherency checks so we do not have to. 2412 */ 2413 tresid = uio->uio_resid; 2414 error = nfs_bioread(vp, uio, 0); 2415 2416 if (!error && uio->uio_resid == tresid) 2417 nfsstats.direofcache_misses++; 2418 done: 2419 lwkt_reltoken(&nmp->nm_token); 2420 vn_unlock(vp); 2421 2422 return (error); 2423 } 2424 2425 /* 2426 * Readdir rpc call. nfs_bioread->nfs_doio->nfs_readdirrpc. 2427 * 2428 * Note that for directories, nfs_bioread maintains the underlying nfs-centric 2429 * offset/block and converts the nfs formatted directory entries for userland 2430 * consumption as well as deals with offsets into the middle of blocks. 2431 * nfs_doio only deals with logical blocks. In particular, uio_offset will 2432 * be block-bounded. It must convert to cookies for the actual RPC. 2433 */ 2434 int 2435 nfs_readdirrpc_uio(struct vnode *vp, struct uio *uiop) 2436 { 2437 int len, left; 2438 struct nfs_dirent *dp = NULL; 2439 u_int32_t *tl; 2440 nfsuint64 *cookiep; 2441 caddr_t cp; 2442 nfsuint64 cookie; 2443 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2444 struct nfsnode *dnp = VTONFS(vp); 2445 u_quad_t fileno; 2446 int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1; 2447 int attrflag; 2448 struct nfsm_info info; 2449 2450 info.mrep = NULL; 2451 info.v3 = NFS_ISV3(vp); 2452 2453 #ifndef DIAGNOSTIC 2454 if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) || 2455 (uiop->uio_resid & (DIRBLKSIZ - 1))) 2456 panic("nfs readdirrpc bad uio"); 2457 #endif 2458 2459 /* 2460 * If there is no cookie, assume directory was stale. 2461 */ 2462 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0); 2463 if (cookiep) 2464 cookie = *cookiep; 2465 else 2466 return (NFSERR_BAD_COOKIE); 2467 /* 2468 * Loop around doing readdir rpc's of size nm_readdirsize 2469 * truncated to a multiple of DIRBLKSIZ. 2470 * The stopping criteria is EOF or buffer full. 2471 */ 2472 while (more_dirs && bigenough) { 2473 nfsstats.rpccnt[NFSPROC_READDIR]++; 2474 nfsm_reqhead(&info, vp, NFSPROC_READDIR, 2475 NFSX_FH(info.v3) + NFSX_READDIR(info.v3)); 2476 ERROROUT(nfsm_fhtom(&info, vp)); 2477 if (info.v3) { 2478 tl = nfsm_build(&info, 5 * NFSX_UNSIGNED); 2479 *tl++ = cookie.nfsuquad[0]; 2480 *tl++ = cookie.nfsuquad[1]; 2481 *tl++ = dnp->n_cookieverf.nfsuquad[0]; 2482 *tl++ = dnp->n_cookieverf.nfsuquad[1]; 2483 } else { 2484 /* 2485 * WARNING! HAMMER DIRECTORIES WILL NOT WORK WELL 2486 * WITH NFSv2!!! There's nothing I can really do 2487 * about it other than to hope the server supports 2488 * rdirplus w/NFSv2. 2489 */ 2490 tl = nfsm_build(&info, 2 * NFSX_UNSIGNED); 2491 *tl++ = cookie.nfsuquad[0]; 2492 } 2493 *tl = txdr_unsigned(nmp->nm_readdirsize); 2494 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READDIR, 2495 uiop->uio_td, 2496 nfs_vpcred(vp, ND_READ), &error)); 2497 if (info.v3) { 2498 ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, 2499 NFS_LATTR_NOSHRINK)); 2500 NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); 2501 dnp->n_cookieverf.nfsuquad[0] = *tl++; 2502 dnp->n_cookieverf.nfsuquad[1] = *tl; 2503 } 2504 NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); 2505 more_dirs = fxdr_unsigned(int, *tl); 2506 2507 /* loop thru the dir entries, converting them to std form */ 2508 while (more_dirs && bigenough) { 2509 if (info.v3) { 2510 NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); 2511 fileno = fxdr_hyper(tl); 2512 len = fxdr_unsigned(int, *(tl + 2)); 2513 } else { 2514 NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); 2515 fileno = fxdr_unsigned(u_quad_t, *tl++); 2516 len = fxdr_unsigned(int, *tl); 2517 } 2518 if (len <= 0 || len > NFS_MAXNAMLEN) { 2519 error = EBADRPC; 2520 m_freem(info.mrep); 2521 info.mrep = NULL; 2522 goto nfsmout; 2523 } 2524 2525 /* 2526 * len is the number of bytes in the path element 2527 * name, not including the \0 termination. 2528 * 2529 * tlen is the number of bytes w have to reserve for 2530 * the path element name. 2531 */ 2532 tlen = nfsm_rndup(len); 2533 if (tlen == len) 2534 tlen += 4; /* To ensure null termination */ 2535 2536 /* 2537 * If the entry would cross a DIRBLKSIZ boundary, 2538 * extend the previous nfs_dirent to cover the 2539 * remaining space. 2540 */ 2541 left = DIRBLKSIZ - blksiz; 2542 if ((tlen + sizeof(struct nfs_dirent)) > left) { 2543 dp->nfs_reclen += left; 2544 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + left; 2545 uiop->uio_iov->iov_len -= left; 2546 uiop->uio_offset += left; 2547 uiop->uio_resid -= left; 2548 blksiz = 0; 2549 } 2550 if ((tlen + sizeof(struct nfs_dirent)) > uiop->uio_resid) 2551 bigenough = 0; 2552 if (bigenough) { 2553 dp = (struct nfs_dirent *)uiop->uio_iov->iov_base; 2554 dp->nfs_ino = fileno; 2555 dp->nfs_namlen = len; 2556 dp->nfs_reclen = tlen + sizeof(struct nfs_dirent); 2557 dp->nfs_type = DT_UNKNOWN; 2558 blksiz += dp->nfs_reclen; 2559 if (blksiz == DIRBLKSIZ) 2560 blksiz = 0; 2561 uiop->uio_offset += sizeof(struct nfs_dirent); 2562 uiop->uio_resid -= sizeof(struct nfs_dirent); 2563 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + sizeof(struct nfs_dirent); 2564 uiop->uio_iov->iov_len -= sizeof(struct nfs_dirent); 2565 ERROROUT(nfsm_mtouio(&info, uiop, len)); 2566 2567 /* 2568 * The uiop has advanced by nfs_dirent + len 2569 * but really needs to advance by 2570 * nfs_dirent + tlen 2571 */ 2572 cp = uiop->uio_iov->iov_base; 2573 tlen -= len; 2574 *cp = '\0'; /* null terminate */ 2575 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + tlen; 2576 uiop->uio_iov->iov_len -= tlen; 2577 uiop->uio_offset += tlen; 2578 uiop->uio_resid -= tlen; 2579 } else { 2580 /* 2581 * NFS strings must be rounded up (nfsm_myouio 2582 * handled that in the bigenough case). 2583 */ 2584 ERROROUT(nfsm_adv(&info, nfsm_rndup(len))); 2585 } 2586 if (info.v3) { 2587 NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); 2588 } else { 2589 NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); 2590 } 2591 2592 /* 2593 * If we were able to accomodate the last entry, 2594 * get the cookie for the next one. Otherwise 2595 * hold-over the cookie for the one we were not 2596 * able to accomodate. 2597 */ 2598 if (bigenough) { 2599 cookie.nfsuquad[0] = *tl++; 2600 if (info.v3) 2601 cookie.nfsuquad[1] = *tl++; 2602 } else if (info.v3) { 2603 tl += 2; 2604 } else { 2605 tl++; 2606 } 2607 more_dirs = fxdr_unsigned(int, *tl); 2608 } 2609 /* 2610 * If at end of rpc data, get the eof boolean 2611 */ 2612 if (!more_dirs) { 2613 NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); 2614 more_dirs = (fxdr_unsigned(int, *tl) == 0); 2615 } 2616 m_freem(info.mrep); 2617 info.mrep = NULL; 2618 } 2619 /* 2620 * Fill last record, iff any, out to a multiple of DIRBLKSIZ 2621 * by increasing d_reclen for the last record. 2622 */ 2623 if (blksiz > 0) { 2624 left = DIRBLKSIZ - blksiz; 2625 dp->nfs_reclen += left; 2626 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + left; 2627 uiop->uio_iov->iov_len -= left; 2628 uiop->uio_offset += left; 2629 uiop->uio_resid -= left; 2630 } 2631 2632 if (bigenough) { 2633 /* 2634 * We hit the end of the directory, update direofoffset. 2635 */ 2636 dnp->n_direofoffset = uiop->uio_offset; 2637 } else { 2638 /* 2639 * There is more to go, insert the link cookie so the 2640 * next block can be read. 2641 */ 2642 if (uiop->uio_resid > 0) 2643 kprintf("EEK! readdirrpc resid > 0\n"); 2644 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1); 2645 *cookiep = cookie; 2646 } 2647 nfsmout: 2648 return (error); 2649 } 2650 2651 /* 2652 * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc(). 2653 */ 2654 int 2655 nfs_readdirplusrpc_uio(struct vnode *vp, struct uio *uiop) 2656 { 2657 int len, left; 2658 struct nfs_dirent *dp; 2659 u_int32_t *tl; 2660 struct vnode *newvp; 2661 nfsuint64 *cookiep; 2662 caddr_t dpossav1, dpossav2; 2663 caddr_t cp; 2664 struct mbuf *mdsav1, *mdsav2; 2665 nfsuint64 cookie; 2666 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2667 struct nfsnode *dnp = VTONFS(vp), *np; 2668 nfsfh_t *fhp; 2669 u_quad_t fileno; 2670 int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i; 2671 int attrflag, fhsize; 2672 struct nchandle nch; 2673 struct nchandle dnch; 2674 struct nlcomponent nlc; 2675 struct nfsm_info info; 2676 2677 info.mrep = NULL; 2678 info.v3 = 1; 2679 2680 #ifndef nolint 2681 dp = NULL; 2682 #endif 2683 #ifndef DIAGNOSTIC 2684 if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) || 2685 (uiop->uio_resid & (DIRBLKSIZ - 1))) 2686 panic("nfs readdirplusrpc bad uio"); 2687 #endif 2688 /* 2689 * Obtain the namecache record for the directory so we have something 2690 * to use as a basis for creating the entries. This function will 2691 * return a held (but not locked) ncp. The ncp may be disconnected 2692 * from the tree and cannot be used for upward traversals, and the 2693 * ncp may be unnamed. Note that other unrelated operations may 2694 * cause the ncp to be named at any time. 2695 * 2696 * We have to lock the ncp to prevent a lock order reversal when 2697 * rdirplus does nlookups of the children, because the vnode is 2698 * locked and has to stay that way. 2699 */ 2700 cache_fromdvp(vp, NULL, 0, &dnch); 2701 bzero(&nlc, sizeof(nlc)); 2702 newvp = NULLVP; 2703 2704 /* 2705 * If there is no cookie, assume directory was stale. 2706 */ 2707 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0); 2708 if (cookiep) { 2709 cookie = *cookiep; 2710 } else { 2711 if (dnch.ncp) 2712 cache_drop(&dnch); 2713 return (NFSERR_BAD_COOKIE); 2714 } 2715 2716 /* 2717 * Loop around doing readdir rpc's of size nm_readdirsize 2718 * truncated to a multiple of DIRBLKSIZ. 2719 * The stopping criteria is EOF or buffer full. 2720 */ 2721 while (more_dirs && bigenough) { 2722 nfsstats.rpccnt[NFSPROC_READDIRPLUS]++; 2723 nfsm_reqhead(&info, vp, NFSPROC_READDIRPLUS, 2724 NFSX_FH(info.v3) + 6 * NFSX_UNSIGNED); 2725 ERROROUT(nfsm_fhtom(&info, vp)); 2726 tl = nfsm_build(&info, 6 * NFSX_UNSIGNED); 2727 *tl++ = cookie.nfsuquad[0]; 2728 *tl++ = cookie.nfsuquad[1]; 2729 *tl++ = dnp->n_cookieverf.nfsuquad[0]; 2730 *tl++ = dnp->n_cookieverf.nfsuquad[1]; 2731 *tl++ = txdr_unsigned(nmp->nm_readdirsize); 2732 *tl = txdr_unsigned(nmp->nm_rsize); 2733 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READDIRPLUS, 2734 uiop->uio_td, 2735 nfs_vpcred(vp, ND_READ), &error)); 2736 ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, 2737 NFS_LATTR_NOSHRINK)); 2738 NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); 2739 dnp->n_cookieverf.nfsuquad[0] = *tl++; 2740 dnp->n_cookieverf.nfsuquad[1] = *tl++; 2741 more_dirs = fxdr_unsigned(int, *tl); 2742 2743 /* loop thru the dir entries, doctoring them to 4bsd form */ 2744 while (more_dirs && bigenough) { 2745 NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); 2746 fileno = fxdr_hyper(tl); 2747 len = fxdr_unsigned(int, *(tl + 2)); 2748 if (len <= 0 || len > NFS_MAXNAMLEN) { 2749 error = EBADRPC; 2750 m_freem(info.mrep); 2751 info.mrep = NULL; 2752 goto nfsmout; 2753 } 2754 tlen = nfsm_rndup(len); 2755 if (tlen == len) 2756 tlen += 4; /* To ensure null termination*/ 2757 left = DIRBLKSIZ - blksiz; 2758 if ((tlen + sizeof(struct nfs_dirent)) > left) { 2759 dp->nfs_reclen += left; 2760 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + left; 2761 uiop->uio_iov->iov_len -= left; 2762 uiop->uio_offset += left; 2763 uiop->uio_resid -= left; 2764 blksiz = 0; 2765 } 2766 if ((tlen + sizeof(struct nfs_dirent)) > uiop->uio_resid) 2767 bigenough = 0; 2768 if (bigenough) { 2769 dp = (struct nfs_dirent *)uiop->uio_iov->iov_base; 2770 dp->nfs_ino = fileno; 2771 dp->nfs_namlen = len; 2772 dp->nfs_reclen = tlen + sizeof(struct nfs_dirent); 2773 dp->nfs_type = DT_UNKNOWN; 2774 blksiz += dp->nfs_reclen; 2775 if (blksiz == DIRBLKSIZ) 2776 blksiz = 0; 2777 uiop->uio_offset += sizeof(struct nfs_dirent); 2778 uiop->uio_resid -= sizeof(struct nfs_dirent); 2779 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + sizeof(struct nfs_dirent); 2780 uiop->uio_iov->iov_len -= sizeof(struct nfs_dirent); 2781 nlc.nlc_nameptr = uiop->uio_iov->iov_base; 2782 nlc.nlc_namelen = len; 2783 ERROROUT(nfsm_mtouio(&info, uiop, len)); 2784 cp = uiop->uio_iov->iov_base; 2785 tlen -= len; 2786 *cp = '\0'; 2787 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + tlen; 2788 uiop->uio_iov->iov_len -= tlen; 2789 uiop->uio_offset += tlen; 2790 uiop->uio_resid -= tlen; 2791 } else { 2792 ERROROUT(nfsm_adv(&info, nfsm_rndup(len))); 2793 } 2794 NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); 2795 if (bigenough) { 2796 cookie.nfsuquad[0] = *tl++; 2797 cookie.nfsuquad[1] = *tl++; 2798 } else { 2799 tl += 2; 2800 } 2801 2802 /* 2803 * Since the attributes are before the file handle 2804 * (sigh), we must skip over the attributes and then 2805 * come back and get them. 2806 */ 2807 attrflag = fxdr_unsigned(int, *tl); 2808 if (attrflag) { 2809 dpossav1 = info.dpos; 2810 mdsav1 = info.md; 2811 ERROROUT(nfsm_adv(&info, NFSX_V3FATTR)); 2812 NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); 2813 doit = fxdr_unsigned(int, *tl); 2814 if (doit) { 2815 NEGATIVEOUT(fhsize = nfsm_getfh(&info, &fhp)); 2816 } 2817 if (doit && bigenough && !nlcdegenerate(&nlc) && 2818 !NFS_CMPFH(dnp, fhp, fhsize) 2819 ) { 2820 if (dnch.ncp) { 2821 #if 0 2822 kprintf("NFS/READDIRPLUS, ENTER %*.*s\n", 2823 nlc.nlc_namelen, nlc.nlc_namelen, 2824 nlc.nlc_nameptr); 2825 #endif 2826 /* 2827 * This is a bit hokey but there isn't 2828 * much we can do about it. We can't 2829 * hold the directory vp locked while 2830 * doing lookups and gets. 2831 */ 2832 nch = cache_nlookup_nonblock(&dnch, &nlc); 2833 if (nch.ncp == NULL) 2834 goto rdfail; 2835 cache_setunresolved(&nch); 2836 error = nfs_nget_nonblock(vp->v_mount, fhp, 2837 fhsize, &np, 2838 NULL); 2839 if (error) { 2840 cache_put(&nch); 2841 goto rdfail; 2842 } 2843 newvp = NFSTOV(np); 2844 dpossav2 = info.dpos; 2845 info.dpos = dpossav1; 2846 mdsav2 = info.md; 2847 info.md = mdsav1; 2848 ERROROUT(nfsm_loadattr(&info, newvp, NULL)); 2849 info.dpos = dpossav2; 2850 info.md = mdsav2; 2851 dp->nfs_type = 2852 IFTODT(VTTOIF(np->n_vattr.va_type)); 2853 nfs_cache_setvp(&nch, newvp, 2854 nfspos_cache_timeout); 2855 vput(newvp); 2856 newvp = NULLVP; 2857 cache_put(&nch); 2858 } else { 2859 rdfail: 2860 ; 2861 #if 0 2862 kprintf("Warning: NFS/rddirplus, " 2863 "UNABLE TO ENTER %*.*s\n", 2864 nlc.nlc_namelen, nlc.nlc_namelen, 2865 nlc.nlc_nameptr); 2866 #endif 2867 } 2868 } 2869 } else { 2870 /* Just skip over the file handle */ 2871 NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); 2872 i = fxdr_unsigned(int, *tl); 2873 ERROROUT(nfsm_adv(&info, nfsm_rndup(i))); 2874 } 2875 NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); 2876 more_dirs = fxdr_unsigned(int, *tl); 2877 } 2878 /* 2879 * If at end of rpc data, get the eof boolean 2880 */ 2881 if (!more_dirs) { 2882 NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); 2883 more_dirs = (fxdr_unsigned(int, *tl) == 0); 2884 } 2885 m_freem(info.mrep); 2886 info.mrep = NULL; 2887 } 2888 /* 2889 * Fill last record, iff any, out to a multiple of DIRBLKSIZ 2890 * by increasing d_reclen for the last record. 2891 */ 2892 if (blksiz > 0) { 2893 left = DIRBLKSIZ - blksiz; 2894 dp->nfs_reclen += left; 2895 uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + left; 2896 uiop->uio_iov->iov_len -= left; 2897 uiop->uio_offset += left; 2898 uiop->uio_resid -= left; 2899 } 2900 2901 /* 2902 * We are now either at the end of the directory or have filled the 2903 * block. 2904 */ 2905 if (bigenough) { 2906 dnp->n_direofoffset = uiop->uio_offset; 2907 } else { 2908 if (uiop->uio_resid > 0) 2909 kprintf("EEK! readdirplusrpc resid > 0\n"); 2910 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1); 2911 *cookiep = cookie; 2912 } 2913 nfsmout: 2914 if (newvp != NULLVP) { 2915 if (newvp == vp) 2916 vrele(newvp); 2917 else 2918 vput(newvp); 2919 newvp = NULLVP; 2920 } 2921 if (dnch.ncp) 2922 cache_drop(&dnch); 2923 return (error); 2924 } 2925 2926 /* 2927 * Silly rename. To make the NFS filesystem that is stateless look a little 2928 * more like the "ufs" a remove of an active vnode is translated to a rename 2929 * to a funny looking filename that is removed by nfs_inactive on the 2930 * nfsnode. There is the potential for another process on a different client 2931 * to create the same funny name between the nfs_lookitup() fails and the 2932 * nfs_rename() completes, but... 2933 */ 2934 static int 2935 nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 2936 { 2937 struct sillyrename *sp; 2938 struct nfsnode *np; 2939 int error; 2940 2941 /* 2942 * We previously purged dvp instead of vp. I don't know why, it 2943 * completely destroys performance. We can't do it anyway with the 2944 * new VFS API since we would be breaking the namecache topology. 2945 */ 2946 cache_purge(vp); /* XXX */ 2947 np = VTONFS(vp); 2948 #ifndef DIAGNOSTIC 2949 if (vp->v_type == VDIR) 2950 panic("nfs: sillyrename dir"); 2951 #endif 2952 sp = kmalloc(sizeof(struct sillyrename), M_NFSREQ, M_WAITOK); 2953 sp->s_cred = crdup(cnp->cn_cred); 2954 sp->s_dvp = dvp; 2955 vref(dvp); 2956 2957 /* Fudge together a funny name */ 2958 sp->s_namlen = ksprintf(sp->s_name, ".nfsA%08x4.4", 2959 (int)(intptr_t)cnp->cn_td); 2960 2961 /* Try lookitups until we get one that isn't there */ 2962 while (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2963 cnp->cn_td, NULL) == 0) { 2964 sp->s_name[4]++; 2965 if (sp->s_name[4] > 'z') { 2966 error = EINVAL; 2967 goto bad; 2968 } 2969 } 2970 error = nfs_renameit(dvp, cnp, sp); 2971 if (error) 2972 goto bad; 2973 error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2974 cnp->cn_td, &np); 2975 np->n_sillyrename = sp; 2976 return (0); 2977 bad: 2978 vrele(sp->s_dvp); 2979 crfree(sp->s_cred); 2980 kfree((caddr_t)sp, M_NFSREQ); 2981 return (error); 2982 } 2983 2984 /* 2985 * Look up a file name and optionally either update the file handle or 2986 * allocate an nfsnode, depending on the value of npp. 2987 * npp == NULL --> just do the lookup 2988 * *npp == NULL --> allocate a new nfsnode and make sure attributes are 2989 * handled too 2990 * *npp != NULL --> update the file handle in the vnode 2991 */ 2992 static int 2993 nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred, 2994 struct thread *td, struct nfsnode **npp) 2995 { 2996 struct vnode *newvp = NULL; 2997 struct nfsnode *np, *dnp = VTONFS(dvp); 2998 int error = 0, fhlen, attrflag; 2999 nfsfh_t *nfhp; 3000 struct nfsm_info info; 3001 3002 info.mrep = NULL; 3003 info.v3 = NFS_ISV3(dvp); 3004 3005 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 3006 nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP, 3007 NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len)); 3008 ERROROUT(nfsm_fhtom(&info, dvp)); 3009 ERROROUT(nfsm_strtom(&info, name, len, NFS_MAXNAMLEN)); 3010 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, td, cred, &error)); 3011 if (npp && !error) { 3012 NEGATIVEOUT(fhlen = nfsm_getfh(&info, &nfhp)); 3013 if (*npp) { 3014 np = *npp; 3015 if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) { 3016 kfree((caddr_t)np->n_fhp, M_NFSBIGFH); 3017 np->n_fhp = &np->n_fh; 3018 } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH) 3019 np->n_fhp =(nfsfh_t *)kmalloc(fhlen,M_NFSBIGFH,M_WAITOK); 3020 bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen); 3021 np->n_fhsize = fhlen; 3022 newvp = NFSTOV(np); 3023 } else if (NFS_CMPFH(dnp, nfhp, fhlen)) { 3024 vref(dvp); 3025 newvp = dvp; 3026 } else { 3027 error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np, NULL); 3028 if (error) { 3029 m_freem(info.mrep); 3030 info.mrep = NULL; 3031 return (error); 3032 } 3033 newvp = NFSTOV(np); 3034 } 3035 if (info.v3) { 3036 ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag, 3037 NFS_LATTR_NOSHRINK)); 3038 if (!attrflag && *npp == NULL) { 3039 m_freem(info.mrep); 3040 info.mrep = NULL; 3041 if (newvp == dvp) 3042 vrele(newvp); 3043 else 3044 vput(newvp); 3045 return (ENOENT); 3046 } 3047 } else { 3048 ERROROUT(nfsm_loadattr(&info, newvp, NULL)); 3049 } 3050 } 3051 m_freem(info.mrep); 3052 info.mrep = NULL; 3053 nfsmout: 3054 if (npp && *npp == NULL) { 3055 if (error) { 3056 if (newvp) { 3057 if (newvp == dvp) 3058 vrele(newvp); 3059 else 3060 vput(newvp); 3061 } 3062 } else 3063 *npp = np; 3064 } 3065 return (error); 3066 } 3067 3068 /* 3069 * Nfs Version 3 commit rpc 3070 * 3071 * We call it 'uio' to distinguish it from 'bio' but there is no real uio 3072 * involved. 3073 */ 3074 int 3075 nfs_commitrpc_uio(struct vnode *vp, u_quad_t offset, int cnt, struct thread *td) 3076 { 3077 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 3078 int error = 0, wccflag = NFSV3_WCCRATTR; 3079 struct nfsm_info info; 3080 u_int32_t *tl; 3081 3082 info.mrep = NULL; 3083 info.v3 = 1; 3084 3085 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) 3086 return (0); 3087 nfsstats.rpccnt[NFSPROC_COMMIT]++; 3088 nfsm_reqhead(&info, vp, NFSPROC_COMMIT, NFSX_FH(1)); 3089 ERROROUT(nfsm_fhtom(&info, vp)); 3090 tl = nfsm_build(&info, 3 * NFSX_UNSIGNED); 3091 txdr_hyper(offset, tl); 3092 tl += 2; 3093 *tl = txdr_unsigned(cnt); 3094 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_COMMIT, td, 3095 nfs_vpcred(vp, ND_WRITE), &error)); 3096 ERROROUT(nfsm_wcc_data(&info, vp, &wccflag)); 3097 if (!error) { 3098 NULLOUT(tl = nfsm_dissect(&info, NFSX_V3WRITEVERF)); 3099 if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl, 3100 NFSX_V3WRITEVERF)) { 3101 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 3102 NFSX_V3WRITEVERF); 3103 error = NFSERR_STALEWRITEVERF; 3104 } 3105 } 3106 m_freem(info.mrep); 3107 info.mrep = NULL; 3108 nfsmout: 3109 return (error); 3110 } 3111 3112 /* 3113 * Kludge City.. 3114 * - make nfs_bmap() essentially a no-op that does no translation 3115 * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc 3116 * (Maybe I could use the process's page mapping, but I was concerned that 3117 * Kernel Write might not be enabled and also figured copyout() would do 3118 * a lot more work than bcopy() and also it currently happens in the 3119 * context of the swapper process (2). 3120 * 3121 * nfs_bmap(struct vnode *a_vp, off_t a_loffset, 3122 * off_t *a_doffsetp, int *a_runp, int *a_runb) 3123 */ 3124 static int 3125 nfs_bmap(struct vop_bmap_args *ap) 3126 { 3127 /* no token lock required */ 3128 if (ap->a_doffsetp != NULL) 3129 *ap->a_doffsetp = ap->a_loffset; 3130 if (ap->a_runp != NULL) 3131 *ap->a_runp = 0; 3132 if (ap->a_runb != NULL) 3133 *ap->a_runb = 0; 3134 return (0); 3135 } 3136 3137 /* 3138 * Strategy routine. 3139 */ 3140 static int 3141 nfs_strategy(struct vop_strategy_args *ap) 3142 { 3143 struct bio *bio = ap->a_bio; 3144 struct bio *nbio; 3145 struct buf *bp __debugvar = bio->bio_buf; 3146 struct nfsmount *nmp = VFSTONFS(ap->a_vp->v_mount); 3147 struct thread *td; 3148 int error; 3149 3150 KASSERT(bp->b_cmd != BUF_CMD_DONE, 3151 ("nfs_strategy: buffer %p unexpectedly marked done", bp)); 3152 KASSERT(BUF_REFCNT(bp) > 0, 3153 ("nfs_strategy: buffer %p not locked", bp)); 3154 3155 if (bio->bio_flags & BIO_SYNC) 3156 td = curthread; /* XXX */ 3157 else 3158 td = NULL; 3159 3160 lwkt_gettoken(&nmp->nm_token); 3161 3162 /* 3163 * We probably don't need to push an nbio any more since no 3164 * block conversion is required due to the use of 64 bit byte 3165 * offsets, but do it anyway. 3166 * 3167 * NOTE: When NFS callers itself via this strategy routines and 3168 * sets up a synchronous I/O, it expects the I/O to run 3169 * synchronously (its bio_done routine just assumes it), 3170 * so for now we have to honor the bit. 3171 */ 3172 nbio = push_bio(bio); 3173 nbio->bio_offset = bio->bio_offset; 3174 nbio->bio_flags = bio->bio_flags & BIO_SYNC; 3175 3176 /* 3177 * If the op is asynchronous and an i/o daemon is waiting 3178 * queue the request, wake it up and wait for completion 3179 * otherwise just do it ourselves. 3180 */ 3181 if (bio->bio_flags & BIO_SYNC) { 3182 error = nfs_doio(ap->a_vp, nbio, td); 3183 } else { 3184 nfs_asyncio(ap->a_vp, nbio); 3185 error = 0; 3186 } 3187 lwkt_reltoken(&nmp->nm_token); 3188 3189 return (error); 3190 } 3191 3192 /* 3193 * Mmap a file 3194 * 3195 * NB Currently unsupported. 3196 * 3197 * nfs_mmap(struct vnode *a_vp, int a_fflags, struct ucred *a_cred) 3198 */ 3199 /* ARGSUSED */ 3200 static int 3201 nfs_mmap(struct vop_mmap_args *ap) 3202 { 3203 /* no token lock required */ 3204 return (EINVAL); 3205 } 3206 3207 /* 3208 * fsync vnode op. Just call nfs_flush() with commit == 1. 3209 * 3210 * nfs_fsync(struct vnode *a_vp, int a_waitfor) 3211 */ 3212 /* ARGSUSED */ 3213 static int 3214 nfs_fsync(struct vop_fsync_args *ap) 3215 { 3216 struct nfsmount *nmp = VFSTONFS(ap->a_vp->v_mount); 3217 int error; 3218 3219 lwkt_gettoken(&nmp->nm_token); 3220 3221 /* 3222 * NOTE: Because attributes are set synchronously we currently 3223 * do not have to implement vsetisdirty()/vclrisdirty(). 3224 */ 3225 error = nfs_flush(ap->a_vp, ap->a_waitfor, curthread, 1); 3226 3227 lwkt_reltoken(&nmp->nm_token); 3228 3229 return error; 3230 } 3231 3232 /* 3233 * Flush all the blocks associated with a vnode. Dirty NFS buffers may be 3234 * in one of two states: If B_NEEDCOMMIT is clear then the buffer contains 3235 * new NFS data which needs to be written to the server. If B_NEEDCOMMIT is 3236 * set the buffer contains data that has already been written to the server 3237 * and which now needs a commit RPC. 3238 * 3239 * If commit is 0 we only take one pass and only flush buffers containing new 3240 * dirty data. 3241 * 3242 * If commit is 1 we take two passes, issuing a commit RPC in the second 3243 * pass. 3244 * 3245 * If waitfor is MNT_WAIT and commit is 1, we loop as many times as required 3246 * to completely flush all pending data. 3247 * 3248 * Note that the RB_SCAN code properly handles the case where the 3249 * callback might block and directly or indirectly (another thread) cause 3250 * the RB tree to change. 3251 */ 3252 3253 #ifndef NFS_COMMITBVECSIZ 3254 #define NFS_COMMITBVECSIZ 16 3255 #endif 3256 3257 struct nfs_flush_info { 3258 enum { NFI_FLUSHNEW, NFI_COMMIT } mode; 3259 struct thread *td; 3260 struct vnode *vp; 3261 int waitfor; 3262 int slpflag; 3263 int slptimeo; 3264 int loops; 3265 struct buf *bvary[NFS_COMMITBVECSIZ]; 3266 int bvsize; 3267 off_t beg_off; 3268 off_t end_off; 3269 }; 3270 3271 static int nfs_flush_bp(struct buf *bp, void *data); 3272 static int nfs_flush_docommit(struct nfs_flush_info *info, int error); 3273 3274 int 3275 nfs_flush(struct vnode *vp, int waitfor, struct thread *td, int commit) 3276 { 3277 struct nfsnode *np = VTONFS(vp); 3278 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 3279 struct nfs_flush_info info; 3280 int error; 3281 3282 bzero(&info, sizeof(info)); 3283 info.td = td; 3284 info.vp = vp; 3285 info.waitfor = waitfor; 3286 info.slpflag = (nmp->nm_flag & NFSMNT_INT) ? PCATCH : 0; 3287 info.loops = 0; 3288 lwkt_gettoken(&vp->v_token); 3289 3290 do { 3291 /* 3292 * Flush mode 3293 */ 3294 info.mode = NFI_FLUSHNEW; 3295 error = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL, 3296 nfs_flush_bp, &info); 3297 3298 /* 3299 * Take a second pass if committing and no error occured. 3300 * Clean up any left over collection (whether an error 3301 * occurs or not). 3302 */ 3303 if (commit && error == 0) { 3304 info.mode = NFI_COMMIT; 3305 error = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL, 3306 nfs_flush_bp, &info); 3307 if (info.bvsize) 3308 error = nfs_flush_docommit(&info, error); 3309 } 3310 3311 /* 3312 * Wait for pending I/O to complete before checking whether 3313 * any further dirty buffers exist. 3314 */ 3315 while (waitfor == MNT_WAIT && 3316 bio_track_active(&vp->v_track_write)) { 3317 error = bio_track_wait(&vp->v_track_write, 3318 info.slpflag, info.slptimeo); 3319 if (error) { 3320 /* 3321 * We have to be able to break out if this 3322 * is an 'intr' mount. 3323 */ 3324 if (nfs_sigintr(nmp, NULL, td)) { 3325 error = -EINTR; 3326 break; 3327 } 3328 3329 /* 3330 * Since we do not process pending signals, 3331 * once we get a PCATCH our tsleep() will no 3332 * longer sleep, switch to a fixed timeout 3333 * instead. 3334 */ 3335 if (info.slpflag == PCATCH) { 3336 info.slpflag = 0; 3337 info.slptimeo = 2 * hz; 3338 } 3339 error = 0; 3340 } 3341 } 3342 ++info.loops; 3343 /* 3344 * Loop if we are flushing synchronous as well as committing, 3345 * and dirty buffers are still present. Otherwise we might livelock. 3346 */ 3347 } while (waitfor == MNT_WAIT && commit && 3348 error == 0 && !RB_EMPTY(&vp->v_rbdirty_tree)); 3349 3350 /* 3351 * The callbacks have to return a negative error to terminate the 3352 * RB scan. 3353 */ 3354 if (error < 0) 3355 error = -error; 3356 3357 /* 3358 * Deal with any error collection 3359 */ 3360 if (np->n_flag & NWRITEERR) { 3361 error = np->n_error; 3362 np->n_flag &= ~NWRITEERR; 3363 } 3364 lwkt_reltoken(&vp->v_token); 3365 return (error); 3366 } 3367 3368 static 3369 int 3370 nfs_flush_bp(struct buf *bp, void *data) 3371 { 3372 struct nfs_flush_info *info = data; 3373 int lkflags; 3374 int error; 3375 off_t toff; 3376 3377 error = 0; 3378 switch(info->mode) { 3379 case NFI_FLUSHNEW: 3380 error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT); 3381 if (error && info->loops && info->waitfor == MNT_WAIT) { 3382 error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT); 3383 if (error) { 3384 lkflags = LK_EXCLUSIVE | LK_SLEEPFAIL; 3385 if (info->slpflag & PCATCH) 3386 lkflags |= LK_PCATCH; 3387 error = BUF_TIMELOCK(bp, lkflags, "nfsfsync", 3388 info->slptimeo); 3389 } 3390 } 3391 3392 /* 3393 * Ignore locking errors 3394 */ 3395 if (error) { 3396 error = 0; 3397 break; 3398 } 3399 3400 /* 3401 * The buffer may have changed out from under us, even if 3402 * we did not block (MPSAFE). Check again now that it is 3403 * locked. 3404 */ 3405 if (bp->b_vp == info->vp && 3406 (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) == B_DELWRI) { 3407 bremfree(bp); 3408 bawrite(bp); 3409 } else { 3410 BUF_UNLOCK(bp); 3411 } 3412 break; 3413 case NFI_COMMIT: 3414 /* 3415 * Only process buffers in need of a commit which we can 3416 * immediately lock. This may prevent a buffer from being 3417 * committed, but the normal flush loop will block on the 3418 * same buffer so we shouldn't get into an endless loop. 3419 */ 3420 if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != 3421 (B_DELWRI | B_NEEDCOMMIT)) { 3422 break; 3423 } 3424 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) 3425 break; 3426 3427 /* 3428 * We must recheck after successfully locking the buffer. 3429 */ 3430 if (bp->b_vp != info->vp || 3431 (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != 3432 (B_DELWRI | B_NEEDCOMMIT)) { 3433 BUF_UNLOCK(bp); 3434 break; 3435 } 3436 3437 /* 3438 * NOTE: storing the bp in the bvary[] basically sets 3439 * it up for a commit operation. 3440 * 3441 * We must call vfs_busy_pages() now so the commit operation 3442 * is interlocked with user modifications to memory mapped 3443 * pages. The b_dirtyoff/b_dirtyend range is not correct 3444 * until after the pages have been busied. 3445 * 3446 * Note: to avoid loopback deadlocks, we do not 3447 * assign b_runningbufspace. 3448 */ 3449 bremfree(bp); 3450 bp->b_cmd = BUF_CMD_WRITE; 3451 vfs_busy_pages(bp->b_vp, bp); 3452 info->bvary[info->bvsize] = bp; 3453 toff = bp->b_bio2.bio_offset + bp->b_dirtyoff; 3454 if (info->bvsize == 0 || toff < info->beg_off) 3455 info->beg_off = toff; 3456 toff += (off_t)(bp->b_dirtyend - bp->b_dirtyoff); 3457 if (info->bvsize == 0 || toff > info->end_off) 3458 info->end_off = toff; 3459 ++info->bvsize; 3460 if (info->bvsize == NFS_COMMITBVECSIZ) { 3461 error = nfs_flush_docommit(info, 0); 3462 KKASSERT(info->bvsize == 0); 3463 } 3464 } 3465 return (error); 3466 } 3467 3468 static 3469 int 3470 nfs_flush_docommit(struct nfs_flush_info *info, int error) 3471 { 3472 struct vnode *vp; 3473 struct buf *bp; 3474 off_t bytes; 3475 int retv; 3476 int i; 3477 3478 vp = info->vp; 3479 3480 if (info->bvsize > 0) { 3481 /* 3482 * Commit data on the server, as required. Note that 3483 * nfs_commit will use the vnode's cred for the commit. 3484 * The NFSv3 commit RPC is limited to a 32 bit byte count. 3485 */ 3486 bytes = info->end_off - info->beg_off; 3487 if (bytes > 0x40000000) 3488 bytes = 0x40000000; 3489 if (error) { 3490 retv = -error; 3491 } else { 3492 retv = nfs_commitrpc_uio(vp, info->beg_off, 3493 (int)bytes, info->td); 3494 if (retv == NFSERR_STALEWRITEVERF) 3495 nfs_clearcommit(vp->v_mount); 3496 } 3497 3498 /* 3499 * Now, either mark the blocks I/O done or mark the 3500 * blocks dirty, depending on whether the commit 3501 * succeeded. 3502 */ 3503 for (i = 0; i < info->bvsize; ++i) { 3504 bp = info->bvary[i]; 3505 if (retv || (bp->b_flags & B_NEEDCOMMIT) == 0) { 3506 /* 3507 * Either an error or the original 3508 * vfs_busy_pages() cleared B_NEEDCOMMIT 3509 * due to finding new dirty VM pages in 3510 * the buffer. 3511 * 3512 * Leave B_DELWRI intact. 3513 */ 3514 bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); 3515 vfs_unbusy_pages(bp); 3516 bp->b_cmd = BUF_CMD_DONE; 3517 bqrelse(bp); 3518 } else { 3519 /* 3520 * Success, remove B_DELWRI ( bundirty() ). 3521 * 3522 * b_dirtyoff/b_dirtyend seem to be NFS 3523 * specific. We should probably move that 3524 * into bundirty(). XXX 3525 * 3526 * We are faking an I/O write, we have to 3527 * start the transaction in order to 3528 * immediately biodone() it. 3529 */ 3530 bundirty(bp); 3531 bp->b_flags &= ~B_ERROR; 3532 bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); 3533 bp->b_dirtyoff = bp->b_dirtyend = 0; 3534 biodone(&bp->b_bio1); 3535 } 3536 } 3537 info->bvsize = 0; 3538 } 3539 return (error); 3540 } 3541 3542 /* 3543 * NFS advisory byte-level locks. 3544 * Currently unsupported. 3545 * 3546 * nfs_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl, 3547 * int a_flags) 3548 */ 3549 static int 3550 nfs_advlock(struct vop_advlock_args *ap) 3551 { 3552 struct nfsnode *np = VTONFS(ap->a_vp); 3553 3554 /* no token lock currently required */ 3555 /* 3556 * The following kludge is to allow diskless support to work 3557 * until a real NFS lockd is implemented. Basically, just pretend 3558 * that this is a local lock. 3559 */ 3560 return (lf_advlock(ap, &(np->n_lockf), np->n_size)); 3561 } 3562 3563 /* 3564 * Print out the contents of an nfsnode. 3565 * 3566 * nfs_print(struct vnode *a_vp) 3567 */ 3568 static int 3569 nfs_print(struct vop_print_args *ap) 3570 { 3571 struct vnode *vp = ap->a_vp; 3572 struct nfsnode *np = VTONFS(vp); 3573 3574 kprintf("tag VT_NFS, fileid %lld fsid 0x%x", 3575 (long long)np->n_vattr.va_fileid, np->n_vattr.va_fsid); 3576 if (vp->v_type == VFIFO) 3577 fifo_printinfo(vp); 3578 kprintf("\n"); 3579 return (0); 3580 } 3581 3582 /* 3583 * nfs special file access vnode op. 3584 * 3585 * nfs_laccess(struct vnode *a_vp, int a_mode, struct ucred *a_cred) 3586 */ 3587 static int 3588 nfs_laccess(struct vop_access_args *ap) 3589 { 3590 struct nfsmount *nmp = VFSTONFS(ap->a_vp->v_mount); 3591 struct vattr vattr; 3592 int error; 3593 3594 lwkt_gettoken(&nmp->nm_token); 3595 error = VOP_GETATTR(ap->a_vp, &vattr); 3596 if (error == 0) { 3597 error = vop_helper_access(ap, vattr.va_uid, vattr.va_gid, 3598 vattr.va_mode, 0); 3599 } 3600 lwkt_reltoken(&nmp->nm_token); 3601 3602 return (error); 3603 } 3604 3605 /* 3606 * Read wrapper for fifos. 3607 * 3608 * nfsfifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 3609 * struct ucred *a_cred) 3610 */ 3611 static int 3612 nfsfifo_read(struct vop_read_args *ap) 3613 { 3614 struct nfsnode *np = VTONFS(ap->a_vp); 3615 3616 /* no token access required */ 3617 /* 3618 * Set access flag. 3619 */ 3620 np->n_flag |= NACC; 3621 getnanotime(&np->n_atim); 3622 return (VOCALL(&fifo_vnode_vops, &ap->a_head)); 3623 } 3624 3625 /* 3626 * Write wrapper for fifos. 3627 * 3628 * nfsfifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 3629 * struct ucred *a_cred) 3630 */ 3631 static int 3632 nfsfifo_write(struct vop_write_args *ap) 3633 { 3634 struct nfsnode *np = VTONFS(ap->a_vp); 3635 3636 /* no token access required */ 3637 /* 3638 * Set update flag. 3639 */ 3640 np->n_flag |= NUPD; 3641 getnanotime(&np->n_mtim); 3642 return (VOCALL(&fifo_vnode_vops, &ap->a_head)); 3643 } 3644 3645 /* 3646 * Close wrapper for fifos. 3647 * 3648 * Update the times on the nfsnode then do fifo close. 3649 * 3650 * nfsfifo_close(struct vnode *a_vp, int a_fflag) 3651 */ 3652 static int 3653 nfsfifo_close(struct vop_close_args *ap) 3654 { 3655 struct vnode *vp = ap->a_vp; 3656 struct nfsnode *np = VTONFS(vp); 3657 struct vattr vattr; 3658 struct timespec ts; 3659 3660 /* no token access required */ 3661 3662 vn_lock(vp, LK_UPGRADE | LK_RETRY); /* XXX */ 3663 if (np->n_flag & (NACC | NUPD)) { 3664 getnanotime(&ts); 3665 if (np->n_flag & NACC) 3666 np->n_atim = ts; 3667 if (np->n_flag & NUPD) 3668 np->n_mtim = ts; 3669 np->n_flag |= NCHG; 3670 if (VREFCNT(vp) == 1 && 3671 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 3672 VATTR_NULL(&vattr); 3673 if (np->n_flag & NACC) 3674 vattr.va_atime = np->n_atim; 3675 if (np->n_flag & NUPD) 3676 vattr.va_mtime = np->n_mtim; 3677 (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE)); 3678 } 3679 } 3680 return (VOCALL(&fifo_vnode_vops, &ap->a_head)); 3681 } 3682 3683 /************************************************************************ 3684 * KQFILTER OPS * 3685 ************************************************************************/ 3686 3687 static void filt_nfsdetach(struct knote *kn); 3688 static int filt_nfsread(struct knote *kn, long hint); 3689 static int filt_nfswrite(struct knote *kn, long hint); 3690 static int filt_nfsvnode(struct knote *kn, long hint); 3691 3692 static struct filterops nfsread_filtops = 3693 { FILTEROP_ISFD | FILTEROP_MPSAFE, 3694 NULL, filt_nfsdetach, filt_nfsread }; 3695 static struct filterops nfswrite_filtops = 3696 { FILTEROP_ISFD | FILTEROP_MPSAFE, 3697 NULL, filt_nfsdetach, filt_nfswrite }; 3698 static struct filterops nfsvnode_filtops = 3699 { FILTEROP_ISFD | FILTEROP_MPSAFE, 3700 NULL, filt_nfsdetach, filt_nfsvnode }; 3701 3702 static int 3703 nfs_kqfilter (struct vop_kqfilter_args *ap) 3704 { 3705 struct vnode *vp = ap->a_vp; 3706 struct knote *kn = ap->a_kn; 3707 3708 switch (kn->kn_filter) { 3709 case EVFILT_READ: 3710 kn->kn_fop = &nfsread_filtops; 3711 break; 3712 case EVFILT_WRITE: 3713 kn->kn_fop = &nfswrite_filtops; 3714 break; 3715 case EVFILT_VNODE: 3716 kn->kn_fop = &nfsvnode_filtops; 3717 break; 3718 default: 3719 return (EOPNOTSUPP); 3720 } 3721 3722 kn->kn_hook = (caddr_t)vp; 3723 3724 knote_insert(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn); 3725 3726 return(0); 3727 } 3728 3729 static void 3730 filt_nfsdetach(struct knote *kn) 3731 { 3732 struct vnode *vp = (void *)kn->kn_hook; 3733 3734 knote_remove(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn); 3735 } 3736 3737 static int 3738 filt_nfsread(struct knote *kn, long hint) 3739 { 3740 struct vnode *vp = (void *)kn->kn_hook; 3741 struct nfsnode *node = VTONFS(vp); 3742 off_t off; 3743 3744 if (hint == NOTE_REVOKE) { 3745 kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT); 3746 return(1); 3747 } 3748 3749 /* 3750 * Interlock against MP races when performing this function. XXX 3751 */ 3752 /* TMPFS_NODE_LOCK_SH(node); */ 3753 off = node->n_size - kn->kn_fp->f_offset; 3754 kn->kn_data = (off < INTPTR_MAX) ? off : INTPTR_MAX; 3755 if (kn->kn_sfflags & NOTE_OLDAPI) { 3756 /* TMPFS_NODE_UNLOCK(node); */ 3757 return(1); 3758 } 3759 if (kn->kn_data == 0) { 3760 kn->kn_data = (off < INTPTR_MAX) ? off : INTPTR_MAX; 3761 } 3762 /* TMPFS_NODE_UNLOCK(node); */ 3763 return (kn->kn_data != 0); 3764 } 3765 3766 static int 3767 filt_nfswrite(struct knote *kn, long hint) 3768 { 3769 if (hint == NOTE_REVOKE) 3770 kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT); 3771 kn->kn_data = 0; 3772 return (1); 3773 } 3774 3775 static int 3776 filt_nfsvnode(struct knote *kn, long hint) 3777 { 3778 if (kn->kn_sfflags & hint) 3779 kn->kn_fflags |= hint; 3780 if (hint == NOTE_REVOKE) { 3781 kn->kn_flags |= (EV_EOF | EV_NODATA); 3782 return (1); 3783 } 3784 return (kn->kn_fflags != 0); 3785 } 3786