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 * Force finalization so the VOP_INACTIVE() call is not delayed. 2943 */ 2944 atomic_set_int(&vp->v_refcnt, VREF_FINALIZE); 2945 2946 /* 2947 * We previously purged dvp instead of vp. I don't know why, it 2948 * completely destroys performance. We can't do it anyway with the 2949 * new VFS API since we would be breaking the namecache topology. 2950 */ 2951 cache_purge(vp); /* XXX */ 2952 np = VTONFS(vp); 2953 #ifndef DIAGNOSTIC 2954 if (vp->v_type == VDIR) 2955 panic("nfs: sillyrename dir"); 2956 #endif 2957 sp = kmalloc(sizeof(struct sillyrename), M_NFSREQ, M_WAITOK); 2958 sp->s_cred = crdup(cnp->cn_cred); 2959 sp->s_dvp = dvp; 2960 vref(dvp); 2961 2962 /* Fudge together a funny name */ 2963 sp->s_namlen = ksprintf(sp->s_name, ".nfsA%08x4.4", 2964 (int)(intptr_t)cnp->cn_td); 2965 2966 /* Try lookitups until we get one that isn't there */ 2967 while (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2968 cnp->cn_td, NULL) == 0) { 2969 sp->s_name[4]++; 2970 if (sp->s_name[4] > 'z') { 2971 error = EINVAL; 2972 goto bad; 2973 } 2974 } 2975 error = nfs_renameit(dvp, cnp, sp); 2976 if (error) 2977 goto bad; 2978 error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2979 cnp->cn_td, &np); 2980 np->n_sillyrename = sp; 2981 return (0); 2982 bad: 2983 vrele(sp->s_dvp); 2984 crfree(sp->s_cred); 2985 kfree((caddr_t)sp, M_NFSREQ); 2986 return (error); 2987 } 2988 2989 /* 2990 * Look up a file name and optionally either update the file handle or 2991 * allocate an nfsnode, depending on the value of npp. 2992 * npp == NULL --> just do the lookup 2993 * *npp == NULL --> allocate a new nfsnode and make sure attributes are 2994 * handled too 2995 * *npp != NULL --> update the file handle in the vnode 2996 */ 2997 static int 2998 nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred, 2999 struct thread *td, struct nfsnode **npp) 3000 { 3001 struct vnode *newvp = NULL; 3002 struct nfsnode *np, *dnp = VTONFS(dvp); 3003 int error = 0, fhlen, attrflag; 3004 nfsfh_t *nfhp; 3005 struct nfsm_info info; 3006 3007 info.mrep = NULL; 3008 info.v3 = NFS_ISV3(dvp); 3009 3010 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 3011 nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP, 3012 NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len)); 3013 ERROROUT(nfsm_fhtom(&info, dvp)); 3014 ERROROUT(nfsm_strtom(&info, name, len, NFS_MAXNAMLEN)); 3015 NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, td, cred, &error)); 3016 if (npp && !error) { 3017 NEGATIVEOUT(fhlen = nfsm_getfh(&info, &nfhp)); 3018 if (*npp) { 3019 np = *npp; 3020 if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) { 3021 kfree((caddr_t)np->n_fhp, M_NFSBIGFH); 3022 np->n_fhp = &np->n_fh; 3023 } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH) 3024 np->n_fhp =(nfsfh_t *)kmalloc(fhlen,M_NFSBIGFH,M_WAITOK); 3025 bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen); 3026 np->n_fhsize = fhlen; 3027 newvp = NFSTOV(np); 3028 } else if (NFS_CMPFH(dnp, nfhp, fhlen)) { 3029 vref(dvp); 3030 newvp = dvp; 3031 } else { 3032 error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np, NULL); 3033 if (error) { 3034 m_freem(info.mrep); 3035 info.mrep = NULL; 3036 return (error); 3037 } 3038 newvp = NFSTOV(np); 3039 } 3040 if (info.v3) { 3041 ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag, 3042 NFS_LATTR_NOSHRINK)); 3043 if (!attrflag && *npp == NULL) { 3044 m_freem(info.mrep); 3045 info.mrep = NULL; 3046 if (newvp == dvp) 3047 vrele(newvp); 3048 else 3049 vput(newvp); 3050 return (ENOENT); 3051 } 3052 } else { 3053 ERROROUT(nfsm_loadattr(&info, newvp, NULL)); 3054 } 3055 } 3056 m_freem(info.mrep); 3057 info.mrep = NULL; 3058 nfsmout: 3059 if (npp && *npp == NULL) { 3060 if (error) { 3061 if (newvp) { 3062 if (newvp == dvp) 3063 vrele(newvp); 3064 else 3065 vput(newvp); 3066 } 3067 } else 3068 *npp = np; 3069 } 3070 return (error); 3071 } 3072 3073 /* 3074 * Nfs Version 3 commit rpc 3075 * 3076 * We call it 'uio' to distinguish it from 'bio' but there is no real uio 3077 * involved. 3078 */ 3079 int 3080 nfs_commitrpc_uio(struct vnode *vp, u_quad_t offset, int cnt, struct thread *td) 3081 { 3082 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 3083 int error = 0, wccflag = NFSV3_WCCRATTR; 3084 struct nfsm_info info; 3085 u_int32_t *tl; 3086 3087 info.mrep = NULL; 3088 info.v3 = 1; 3089 3090 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) 3091 return (0); 3092 nfsstats.rpccnt[NFSPROC_COMMIT]++; 3093 nfsm_reqhead(&info, vp, NFSPROC_COMMIT, NFSX_FH(1)); 3094 ERROROUT(nfsm_fhtom(&info, vp)); 3095 tl = nfsm_build(&info, 3 * NFSX_UNSIGNED); 3096 txdr_hyper(offset, tl); 3097 tl += 2; 3098 *tl = txdr_unsigned(cnt); 3099 NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_COMMIT, td, 3100 nfs_vpcred(vp, ND_WRITE), &error)); 3101 ERROROUT(nfsm_wcc_data(&info, vp, &wccflag)); 3102 if (!error) { 3103 NULLOUT(tl = nfsm_dissect(&info, NFSX_V3WRITEVERF)); 3104 if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl, 3105 NFSX_V3WRITEVERF)) { 3106 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 3107 NFSX_V3WRITEVERF); 3108 error = NFSERR_STALEWRITEVERF; 3109 } 3110 } 3111 m_freem(info.mrep); 3112 info.mrep = NULL; 3113 nfsmout: 3114 return (error); 3115 } 3116 3117 /* 3118 * Kludge City.. 3119 * - make nfs_bmap() essentially a no-op that does no translation 3120 * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc 3121 * (Maybe I could use the process's page mapping, but I was concerned that 3122 * Kernel Write might not be enabled and also figured copyout() would do 3123 * a lot more work than bcopy() and also it currently happens in the 3124 * context of the swapper process (2). 3125 * 3126 * nfs_bmap(struct vnode *a_vp, off_t a_loffset, 3127 * off_t *a_doffsetp, int *a_runp, int *a_runb) 3128 */ 3129 static int 3130 nfs_bmap(struct vop_bmap_args *ap) 3131 { 3132 /* no token lock required */ 3133 if (ap->a_doffsetp != NULL) 3134 *ap->a_doffsetp = ap->a_loffset; 3135 if (ap->a_runp != NULL) 3136 *ap->a_runp = 0; 3137 if (ap->a_runb != NULL) 3138 *ap->a_runb = 0; 3139 return (0); 3140 } 3141 3142 /* 3143 * Strategy routine. 3144 */ 3145 static int 3146 nfs_strategy(struct vop_strategy_args *ap) 3147 { 3148 struct bio *bio = ap->a_bio; 3149 struct bio *nbio; 3150 struct buf *bp __debugvar = bio->bio_buf; 3151 struct nfsmount *nmp = VFSTONFS(ap->a_vp->v_mount); 3152 struct thread *td; 3153 int error; 3154 3155 KASSERT(bp->b_cmd != BUF_CMD_DONE, 3156 ("nfs_strategy: buffer %p unexpectedly marked done", bp)); 3157 KASSERT(BUF_REFCNT(bp) > 0, 3158 ("nfs_strategy: buffer %p not locked", bp)); 3159 3160 if (bio->bio_flags & BIO_SYNC) 3161 td = curthread; /* XXX */ 3162 else 3163 td = NULL; 3164 3165 lwkt_gettoken(&nmp->nm_token); 3166 3167 /* 3168 * We probably don't need to push an nbio any more since no 3169 * block conversion is required due to the use of 64 bit byte 3170 * offsets, but do it anyway. 3171 * 3172 * NOTE: When NFS callers itself via this strategy routines and 3173 * sets up a synchronous I/O, it expects the I/O to run 3174 * synchronously (its bio_done routine just assumes it), 3175 * so for now we have to honor the bit. 3176 */ 3177 nbio = push_bio(bio); 3178 nbio->bio_offset = bio->bio_offset; 3179 nbio->bio_flags = bio->bio_flags & BIO_SYNC; 3180 3181 /* 3182 * If the op is asynchronous and an i/o daemon is waiting 3183 * queue the request, wake it up and wait for completion 3184 * otherwise just do it ourselves. 3185 */ 3186 if (bio->bio_flags & BIO_SYNC) { 3187 error = nfs_doio(ap->a_vp, nbio, td); 3188 } else { 3189 nfs_asyncio(ap->a_vp, nbio); 3190 error = 0; 3191 } 3192 lwkt_reltoken(&nmp->nm_token); 3193 3194 return (error); 3195 } 3196 3197 /* 3198 * Mmap a file 3199 * 3200 * NB Currently unsupported. 3201 * 3202 * nfs_mmap(struct vnode *a_vp, int a_fflags, struct ucred *a_cred) 3203 */ 3204 /* ARGSUSED */ 3205 static int 3206 nfs_mmap(struct vop_mmap_args *ap) 3207 { 3208 /* no token lock required */ 3209 return (EINVAL); 3210 } 3211 3212 /* 3213 * fsync vnode op. Just call nfs_flush() with commit == 1. 3214 * 3215 * nfs_fsync(struct vnode *a_vp, int a_waitfor) 3216 */ 3217 /* ARGSUSED */ 3218 static int 3219 nfs_fsync(struct vop_fsync_args *ap) 3220 { 3221 struct nfsmount *nmp = VFSTONFS(ap->a_vp->v_mount); 3222 int error; 3223 3224 lwkt_gettoken(&nmp->nm_token); 3225 3226 /* 3227 * NOTE: Because attributes are set synchronously we currently 3228 * do not have to implement vsetisdirty()/vclrisdirty(). 3229 */ 3230 error = nfs_flush(ap->a_vp, ap->a_waitfor, curthread, 1); 3231 3232 lwkt_reltoken(&nmp->nm_token); 3233 3234 return error; 3235 } 3236 3237 /* 3238 * Flush all the blocks associated with a vnode. Dirty NFS buffers may be 3239 * in one of two states: If B_NEEDCOMMIT is clear then the buffer contains 3240 * new NFS data which needs to be written to the server. If B_NEEDCOMMIT is 3241 * set the buffer contains data that has already been written to the server 3242 * and which now needs a commit RPC. 3243 * 3244 * If commit is 0 we only take one pass and only flush buffers containing new 3245 * dirty data. 3246 * 3247 * If commit is 1 we take two passes, issuing a commit RPC in the second 3248 * pass. 3249 * 3250 * If waitfor is MNT_WAIT and commit is 1, we loop as many times as required 3251 * to completely flush all pending data. 3252 * 3253 * Note that the RB_SCAN code properly handles the case where the 3254 * callback might block and directly or indirectly (another thread) cause 3255 * the RB tree to change. 3256 */ 3257 3258 #ifndef NFS_COMMITBVECSIZ 3259 #define NFS_COMMITBVECSIZ 16 3260 #endif 3261 3262 struct nfs_flush_info { 3263 enum { NFI_FLUSHNEW, NFI_COMMIT } mode; 3264 struct thread *td; 3265 struct vnode *vp; 3266 int waitfor; 3267 int slpflag; 3268 int slptimeo; 3269 int loops; 3270 struct buf *bvary[NFS_COMMITBVECSIZ]; 3271 int bvsize; 3272 off_t beg_off; 3273 off_t end_off; 3274 }; 3275 3276 static int nfs_flush_bp(struct buf *bp, void *data); 3277 static int nfs_flush_docommit(struct nfs_flush_info *info, int error); 3278 3279 int 3280 nfs_flush(struct vnode *vp, int waitfor, struct thread *td, int commit) 3281 { 3282 struct nfsnode *np = VTONFS(vp); 3283 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 3284 struct nfs_flush_info info; 3285 int error; 3286 3287 bzero(&info, sizeof(info)); 3288 info.td = td; 3289 info.vp = vp; 3290 info.waitfor = waitfor; 3291 info.slpflag = (nmp->nm_flag & NFSMNT_INT) ? PCATCH : 0; 3292 info.loops = 0; 3293 lwkt_gettoken(&vp->v_token); 3294 3295 do { 3296 /* 3297 * Flush mode 3298 */ 3299 info.mode = NFI_FLUSHNEW; 3300 error = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL, 3301 nfs_flush_bp, &info); 3302 3303 /* 3304 * Take a second pass if committing and no error occured. 3305 * Clean up any left over collection (whether an error 3306 * occurs or not). 3307 */ 3308 if (commit && error == 0) { 3309 info.mode = NFI_COMMIT; 3310 error = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL, 3311 nfs_flush_bp, &info); 3312 if (info.bvsize) 3313 error = nfs_flush_docommit(&info, error); 3314 } 3315 3316 /* 3317 * Wait for pending I/O to complete before checking whether 3318 * any further dirty buffers exist. 3319 */ 3320 while (waitfor == MNT_WAIT && 3321 bio_track_active(&vp->v_track_write)) { 3322 error = bio_track_wait(&vp->v_track_write, 3323 info.slpflag, info.slptimeo); 3324 if (error) { 3325 /* 3326 * We have to be able to break out if this 3327 * is an 'intr' mount. 3328 */ 3329 if (nfs_sigintr(nmp, NULL, td)) { 3330 error = -EINTR; 3331 break; 3332 } 3333 3334 /* 3335 * Since we do not process pending signals, 3336 * once we get a PCATCH our tsleep() will no 3337 * longer sleep, switch to a fixed timeout 3338 * instead. 3339 */ 3340 if (info.slpflag == PCATCH) { 3341 info.slpflag = 0; 3342 info.slptimeo = 2 * hz; 3343 } 3344 error = 0; 3345 } 3346 } 3347 ++info.loops; 3348 /* 3349 * Loop if we are flushing synchronous as well as committing, 3350 * and dirty buffers are still present. Otherwise we might livelock. 3351 */ 3352 } while (waitfor == MNT_WAIT && commit && 3353 error == 0 && !RB_EMPTY(&vp->v_rbdirty_tree)); 3354 3355 /* 3356 * The callbacks have to return a negative error to terminate the 3357 * RB scan. 3358 */ 3359 if (error < 0) 3360 error = -error; 3361 3362 /* 3363 * Deal with any error collection 3364 */ 3365 if (np->n_flag & NWRITEERR) { 3366 error = np->n_error; 3367 np->n_flag &= ~NWRITEERR; 3368 } 3369 lwkt_reltoken(&vp->v_token); 3370 return (error); 3371 } 3372 3373 static 3374 int 3375 nfs_flush_bp(struct buf *bp, void *data) 3376 { 3377 struct nfs_flush_info *info = data; 3378 int lkflags; 3379 int error; 3380 off_t toff; 3381 3382 error = 0; 3383 switch(info->mode) { 3384 case NFI_FLUSHNEW: 3385 error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT); 3386 if (error && info->loops && info->waitfor == MNT_WAIT) { 3387 error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT); 3388 if (error) { 3389 lkflags = LK_EXCLUSIVE | LK_SLEEPFAIL; 3390 if (info->slpflag & PCATCH) 3391 lkflags |= LK_PCATCH; 3392 error = BUF_TIMELOCK(bp, lkflags, "nfsfsync", 3393 info->slptimeo); 3394 } 3395 } 3396 3397 /* 3398 * Ignore locking errors 3399 */ 3400 if (error) { 3401 error = 0; 3402 break; 3403 } 3404 3405 /* 3406 * The buffer may have changed out from under us, even if 3407 * we did not block (MPSAFE). Check again now that it is 3408 * locked. 3409 */ 3410 if (bp->b_vp == info->vp && 3411 (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) == B_DELWRI) { 3412 bremfree(bp); 3413 bawrite(bp); 3414 } else { 3415 BUF_UNLOCK(bp); 3416 } 3417 break; 3418 case NFI_COMMIT: 3419 /* 3420 * Only process buffers in need of a commit which we can 3421 * immediately lock. This may prevent a buffer from being 3422 * committed, but the normal flush loop will block on the 3423 * same buffer so we shouldn't get into an endless loop. 3424 */ 3425 if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != 3426 (B_DELWRI | B_NEEDCOMMIT)) { 3427 break; 3428 } 3429 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) 3430 break; 3431 3432 /* 3433 * We must recheck after successfully locking the buffer. 3434 */ 3435 if (bp->b_vp != info->vp || 3436 (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != 3437 (B_DELWRI | B_NEEDCOMMIT)) { 3438 BUF_UNLOCK(bp); 3439 break; 3440 } 3441 3442 /* 3443 * NOTE: storing the bp in the bvary[] basically sets 3444 * it up for a commit operation. 3445 * 3446 * We must call vfs_busy_pages() now so the commit operation 3447 * is interlocked with user modifications to memory mapped 3448 * pages. The b_dirtyoff/b_dirtyend range is not correct 3449 * until after the pages have been busied. 3450 * 3451 * Note: to avoid loopback deadlocks, we do not 3452 * assign b_runningbufspace. 3453 */ 3454 bremfree(bp); 3455 bp->b_cmd = BUF_CMD_WRITE; 3456 vfs_busy_pages(bp->b_vp, bp); 3457 info->bvary[info->bvsize] = bp; 3458 toff = bp->b_bio2.bio_offset + bp->b_dirtyoff; 3459 if (info->bvsize == 0 || toff < info->beg_off) 3460 info->beg_off = toff; 3461 toff += (off_t)(bp->b_dirtyend - bp->b_dirtyoff); 3462 if (info->bvsize == 0 || toff > info->end_off) 3463 info->end_off = toff; 3464 ++info->bvsize; 3465 if (info->bvsize == NFS_COMMITBVECSIZ) { 3466 error = nfs_flush_docommit(info, 0); 3467 KKASSERT(info->bvsize == 0); 3468 } 3469 } 3470 return (error); 3471 } 3472 3473 static 3474 int 3475 nfs_flush_docommit(struct nfs_flush_info *info, int error) 3476 { 3477 struct vnode *vp; 3478 struct buf *bp; 3479 off_t bytes; 3480 int retv; 3481 int i; 3482 3483 vp = info->vp; 3484 3485 if (info->bvsize > 0) { 3486 /* 3487 * Commit data on the server, as required. Note that 3488 * nfs_commit will use the vnode's cred for the commit. 3489 * The NFSv3 commit RPC is limited to a 32 bit byte count. 3490 */ 3491 bytes = info->end_off - info->beg_off; 3492 if (bytes > 0x40000000) 3493 bytes = 0x40000000; 3494 if (error) { 3495 retv = -error; 3496 } else { 3497 retv = nfs_commitrpc_uio(vp, info->beg_off, 3498 (int)bytes, info->td); 3499 if (retv == NFSERR_STALEWRITEVERF) 3500 nfs_clearcommit(vp->v_mount); 3501 } 3502 3503 /* 3504 * Now, either mark the blocks I/O done or mark the 3505 * blocks dirty, depending on whether the commit 3506 * succeeded. 3507 */ 3508 for (i = 0; i < info->bvsize; ++i) { 3509 bp = info->bvary[i]; 3510 if (retv || (bp->b_flags & B_NEEDCOMMIT) == 0) { 3511 /* 3512 * Either an error or the original 3513 * vfs_busy_pages() cleared B_NEEDCOMMIT 3514 * due to finding new dirty VM pages in 3515 * the buffer. 3516 * 3517 * Leave B_DELWRI intact. 3518 */ 3519 bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); 3520 vfs_unbusy_pages(bp); 3521 bp->b_cmd = BUF_CMD_DONE; 3522 bqrelse(bp); 3523 } else { 3524 /* 3525 * Success, remove B_DELWRI ( bundirty() ). 3526 * 3527 * b_dirtyoff/b_dirtyend seem to be NFS 3528 * specific. We should probably move that 3529 * into bundirty(). XXX 3530 * 3531 * We are faking an I/O write, we have to 3532 * start the transaction in order to 3533 * immediately biodone() it. 3534 */ 3535 bundirty(bp); 3536 bp->b_flags &= ~B_ERROR; 3537 bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); 3538 bp->b_dirtyoff = bp->b_dirtyend = 0; 3539 biodone(&bp->b_bio1); 3540 } 3541 } 3542 info->bvsize = 0; 3543 } 3544 return (error); 3545 } 3546 3547 /* 3548 * NFS advisory byte-level locks. 3549 * Currently unsupported. 3550 * 3551 * nfs_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl, 3552 * int a_flags) 3553 */ 3554 static int 3555 nfs_advlock(struct vop_advlock_args *ap) 3556 { 3557 struct nfsnode *np = VTONFS(ap->a_vp); 3558 3559 /* no token lock currently required */ 3560 /* 3561 * The following kludge is to allow diskless support to work 3562 * until a real NFS lockd is implemented. Basically, just pretend 3563 * that this is a local lock. 3564 */ 3565 return (lf_advlock(ap, &(np->n_lockf), np->n_size)); 3566 } 3567 3568 /* 3569 * Print out the contents of an nfsnode. 3570 * 3571 * nfs_print(struct vnode *a_vp) 3572 */ 3573 static int 3574 nfs_print(struct vop_print_args *ap) 3575 { 3576 struct vnode *vp = ap->a_vp; 3577 struct nfsnode *np = VTONFS(vp); 3578 3579 kprintf("tag VT_NFS, fileid %lld fsid 0x%x", 3580 (long long)np->n_vattr.va_fileid, np->n_vattr.va_fsid); 3581 if (vp->v_type == VFIFO) 3582 fifo_printinfo(vp); 3583 kprintf("\n"); 3584 return (0); 3585 } 3586 3587 /* 3588 * nfs special file access vnode op. 3589 * 3590 * nfs_laccess(struct vnode *a_vp, int a_mode, struct ucred *a_cred) 3591 */ 3592 static int 3593 nfs_laccess(struct vop_access_args *ap) 3594 { 3595 struct nfsmount *nmp = VFSTONFS(ap->a_vp->v_mount); 3596 struct vattr vattr; 3597 int error; 3598 3599 lwkt_gettoken(&nmp->nm_token); 3600 error = VOP_GETATTR(ap->a_vp, &vattr); 3601 if (error == 0) { 3602 error = vop_helper_access(ap, vattr.va_uid, vattr.va_gid, 3603 vattr.va_mode, 0); 3604 } 3605 lwkt_reltoken(&nmp->nm_token); 3606 3607 return (error); 3608 } 3609 3610 /* 3611 * Read wrapper for fifos. 3612 * 3613 * nfsfifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 3614 * struct ucred *a_cred) 3615 */ 3616 static int 3617 nfsfifo_read(struct vop_read_args *ap) 3618 { 3619 struct nfsnode *np = VTONFS(ap->a_vp); 3620 3621 /* no token access required */ 3622 /* 3623 * Set access flag. 3624 */ 3625 np->n_flag |= NACC; 3626 getnanotime(&np->n_atim); 3627 return (VOCALL(&fifo_vnode_vops, &ap->a_head)); 3628 } 3629 3630 /* 3631 * Write wrapper for fifos. 3632 * 3633 * nfsfifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 3634 * struct ucred *a_cred) 3635 */ 3636 static int 3637 nfsfifo_write(struct vop_write_args *ap) 3638 { 3639 struct nfsnode *np = VTONFS(ap->a_vp); 3640 3641 /* no token access required */ 3642 /* 3643 * Set update flag. 3644 */ 3645 np->n_flag |= NUPD; 3646 getnanotime(&np->n_mtim); 3647 return (VOCALL(&fifo_vnode_vops, &ap->a_head)); 3648 } 3649 3650 /* 3651 * Close wrapper for fifos. 3652 * 3653 * Update the times on the nfsnode then do fifo close. 3654 * 3655 * nfsfifo_close(struct vnode *a_vp, int a_fflag) 3656 */ 3657 static int 3658 nfsfifo_close(struct vop_close_args *ap) 3659 { 3660 struct vnode *vp = ap->a_vp; 3661 struct nfsnode *np = VTONFS(vp); 3662 struct vattr vattr; 3663 struct timespec ts; 3664 3665 /* no token access required */ 3666 3667 vn_lock(vp, LK_UPGRADE | LK_RETRY); /* XXX */ 3668 if (np->n_flag & (NACC | NUPD)) { 3669 getnanotime(&ts); 3670 if (np->n_flag & NACC) 3671 np->n_atim = ts; 3672 if (np->n_flag & NUPD) 3673 np->n_mtim = ts; 3674 np->n_flag |= NCHG; 3675 if (VREFCNT(vp) == 1 && 3676 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 3677 VATTR_NULL(&vattr); 3678 if (np->n_flag & NACC) 3679 vattr.va_atime = np->n_atim; 3680 if (np->n_flag & NUPD) 3681 vattr.va_mtime = np->n_mtim; 3682 (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE)); 3683 } 3684 } 3685 return (VOCALL(&fifo_vnode_vops, &ap->a_head)); 3686 } 3687 3688 /************************************************************************ 3689 * KQFILTER OPS * 3690 ************************************************************************/ 3691 3692 static void filt_nfsdetach(struct knote *kn); 3693 static int filt_nfsread(struct knote *kn, long hint); 3694 static int filt_nfswrite(struct knote *kn, long hint); 3695 static int filt_nfsvnode(struct knote *kn, long hint); 3696 3697 static struct filterops nfsread_filtops = 3698 { FILTEROP_ISFD | FILTEROP_MPSAFE, 3699 NULL, filt_nfsdetach, filt_nfsread }; 3700 static struct filterops nfswrite_filtops = 3701 { FILTEROP_ISFD | FILTEROP_MPSAFE, 3702 NULL, filt_nfsdetach, filt_nfswrite }; 3703 static struct filterops nfsvnode_filtops = 3704 { FILTEROP_ISFD | FILTEROP_MPSAFE, 3705 NULL, filt_nfsdetach, filt_nfsvnode }; 3706 3707 static int 3708 nfs_kqfilter (struct vop_kqfilter_args *ap) 3709 { 3710 struct vnode *vp = ap->a_vp; 3711 struct knote *kn = ap->a_kn; 3712 3713 switch (kn->kn_filter) { 3714 case EVFILT_READ: 3715 kn->kn_fop = &nfsread_filtops; 3716 break; 3717 case EVFILT_WRITE: 3718 kn->kn_fop = &nfswrite_filtops; 3719 break; 3720 case EVFILT_VNODE: 3721 kn->kn_fop = &nfsvnode_filtops; 3722 break; 3723 default: 3724 return (EOPNOTSUPP); 3725 } 3726 3727 kn->kn_hook = (caddr_t)vp; 3728 3729 knote_insert(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn); 3730 3731 return(0); 3732 } 3733 3734 static void 3735 filt_nfsdetach(struct knote *kn) 3736 { 3737 struct vnode *vp = (void *)kn->kn_hook; 3738 3739 knote_remove(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn); 3740 } 3741 3742 static int 3743 filt_nfsread(struct knote *kn, long hint) 3744 { 3745 struct vnode *vp = (void *)kn->kn_hook; 3746 struct nfsnode *node = VTONFS(vp); 3747 off_t off; 3748 3749 if (hint == NOTE_REVOKE) { 3750 kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT); 3751 return(1); 3752 } 3753 3754 /* 3755 * Interlock against MP races when performing this function. XXX 3756 */ 3757 /* TMPFS_NODE_LOCK_SH(node); */ 3758 off = node->n_size - kn->kn_fp->f_offset; 3759 kn->kn_data = (off < INTPTR_MAX) ? off : INTPTR_MAX; 3760 if (kn->kn_sfflags & NOTE_OLDAPI) { 3761 /* TMPFS_NODE_UNLOCK(node); */ 3762 return(1); 3763 } 3764 if (kn->kn_data == 0) { 3765 kn->kn_data = (off < INTPTR_MAX) ? off : INTPTR_MAX; 3766 } 3767 /* TMPFS_NODE_UNLOCK(node); */ 3768 return (kn->kn_data != 0); 3769 } 3770 3771 static int 3772 filt_nfswrite(struct knote *kn, long hint) 3773 { 3774 if (hint == NOTE_REVOKE) 3775 kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT); 3776 kn->kn_data = 0; 3777 return (1); 3778 } 3779 3780 static int 3781 filt_nfsvnode(struct knote *kn, long hint) 3782 { 3783 if (kn->kn_sfflags & hint) 3784 kn->kn_fflags |= hint; 3785 if (hint == NOTE_REVOKE) { 3786 kn->kn_flags |= (EV_EOF | EV_NODATA); 3787 return (1); 3788 } 3789 return (kn->kn_fflags != 0); 3790 } 3791