nfs_vnops.c revision 111463
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. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 37 */ 38 39#include <sys/cdefs.h> 40__FBSDID("$FreeBSD: head/sys/nfsclient/nfs_vnops.c 111463 2003-02-25 03:37:48Z jeff $"); 41 42/* 43 * vnode op calls for Sun NFS version 2 and 3 44 */ 45 46#include "opt_inet.h" 47 48#include <sys/param.h> 49#include <sys/kernel.h> 50#include <sys/systm.h> 51#include <sys/resourcevar.h> 52#include <sys/proc.h> 53#include <sys/mount.h> 54#include <sys/bio.h> 55#include <sys/buf.h> 56#include <sys/malloc.h> 57#include <sys/mbuf.h> 58#include <sys/namei.h> 59#include <sys/socket.h> 60#include <sys/vnode.h> 61#include <sys/dirent.h> 62#include <sys/fcntl.h> 63#include <sys/lockf.h> 64#include <sys/stat.h> 65#include <sys/sysctl.h> 66 67#include <vm/vm.h> 68#include <vm/vm_extern.h> 69 70#include <fs/fifofs/fifo.h> 71 72#include <nfs/rpcv2.h> 73#include <nfs/nfsproto.h> 74#include <nfsclient/nfs.h> 75#include <nfsclient/nfsnode.h> 76#include <nfsclient/nfsmount.h> 77#include <nfsclient/nfs_lock.h> 78#include <nfs/xdr_subs.h> 79#include <nfsclient/nfsm_subs.h> 80 81#include <net/if.h> 82#include <netinet/in.h> 83#include <netinet/in_var.h> 84 85/* Defs */ 86#define TRUE 1 87#define FALSE 0 88 89/* 90 * Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these 91 * calls are not in getblk() and brelse() so that they would not be necessary 92 * here. 93 */ 94#ifndef B_VMIO 95#define vfs_busy_pages(bp, f) 96#endif 97 98static int nfsspec_read(struct vop_read_args *); 99static int nfsspec_write(struct vop_write_args *); 100static int nfsfifo_read(struct vop_read_args *); 101static int nfsfifo_write(struct vop_write_args *); 102static int nfsspec_close(struct vop_close_args *); 103static int nfsfifo_close(struct vop_close_args *); 104static int nfs_flush(struct vnode *, struct ucred *, int, struct thread *, 105 int); 106static int nfs_setattrrpc(struct vnode *, struct vattr *, struct ucred *, 107 struct thread *); 108static int nfs_lookup(struct vop_lookup_args *); 109static int nfs_create(struct vop_create_args *); 110static int nfs_mknod(struct vop_mknod_args *); 111static int nfs_open(struct vop_open_args *); 112static int nfs_close(struct vop_close_args *); 113static int nfs_access(struct vop_access_args *); 114static int nfs_getattr(struct vop_getattr_args *); 115static int nfs_setattr(struct vop_setattr_args *); 116static int nfs_read(struct vop_read_args *); 117static int nfs_fsync(struct vop_fsync_args *); 118static int nfs_remove(struct vop_remove_args *); 119static int nfs_link(struct vop_link_args *); 120static int nfs_rename(struct vop_rename_args *); 121static int nfs_mkdir(struct vop_mkdir_args *); 122static int nfs_rmdir(struct vop_rmdir_args *); 123static int nfs_symlink(struct vop_symlink_args *); 124static int nfs_readdir(struct vop_readdir_args *); 125static int nfs_strategy(struct vop_strategy_args *); 126static int nfs_lookitup(struct vnode *, const char *, int, 127 struct ucred *, struct thread *, struct nfsnode **); 128static int nfs_sillyrename(struct vnode *, struct vnode *, 129 struct componentname *); 130static int nfsspec_access(struct vop_access_args *); 131static int nfs_readlink(struct vop_readlink_args *); 132static int nfs_print(struct vop_print_args *); 133static int nfs_advlock(struct vop_advlock_args *); 134 135/* 136 * Global vfs data structures for nfs 137 */ 138vop_t **nfsv2_vnodeop_p; 139static struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = { 140 { &vop_default_desc, (vop_t *) vop_defaultop }, 141 { &vop_access_desc, (vop_t *) nfs_access }, 142 { &vop_advlock_desc, (vop_t *) nfs_advlock }, 143 { &vop_close_desc, (vop_t *) nfs_close }, 144 { &vop_create_desc, (vop_t *) nfs_create }, 145 { &vop_fsync_desc, (vop_t *) nfs_fsync }, 146 { &vop_getattr_desc, (vop_t *) nfs_getattr }, 147 { &vop_getpages_desc, (vop_t *) nfs_getpages }, 148 { &vop_putpages_desc, (vop_t *) nfs_putpages }, 149 { &vop_inactive_desc, (vop_t *) nfs_inactive }, 150 { &vop_lease_desc, (vop_t *) vop_null }, 151 { &vop_link_desc, (vop_t *) nfs_link }, 152 { &vop_lock_desc, (vop_t *) vop_sharedlock }, 153 { &vop_lookup_desc, (vop_t *) nfs_lookup }, 154 { &vop_mkdir_desc, (vop_t *) nfs_mkdir }, 155 { &vop_mknod_desc, (vop_t *) nfs_mknod }, 156 { &vop_open_desc, (vop_t *) nfs_open }, 157 { &vop_print_desc, (vop_t *) nfs_print }, 158 { &vop_read_desc, (vop_t *) nfs_read }, 159 { &vop_readdir_desc, (vop_t *) nfs_readdir }, 160 { &vop_readlink_desc, (vop_t *) nfs_readlink }, 161 { &vop_reclaim_desc, (vop_t *) nfs_reclaim }, 162 { &vop_remove_desc, (vop_t *) nfs_remove }, 163 { &vop_rename_desc, (vop_t *) nfs_rename }, 164 { &vop_rmdir_desc, (vop_t *) nfs_rmdir }, 165 { &vop_setattr_desc, (vop_t *) nfs_setattr }, 166 { &vop_strategy_desc, (vop_t *) nfs_strategy }, 167 { &vop_symlink_desc, (vop_t *) nfs_symlink }, 168 { &vop_write_desc, (vop_t *) nfs_write }, 169 { NULL, NULL } 170}; 171static struct vnodeopv_desc nfsv2_vnodeop_opv_desc = 172 { &nfsv2_vnodeop_p, nfsv2_vnodeop_entries }; 173VNODEOP_SET(nfsv2_vnodeop_opv_desc); 174 175/* 176 * Special device vnode ops 177 */ 178vop_t **spec_nfsv2nodeop_p; 179static struct vnodeopv_entry_desc nfsv2_specop_entries[] = { 180 { &vop_default_desc, (vop_t *) spec_vnoperate }, 181 { &vop_access_desc, (vop_t *) nfsspec_access }, 182 { &vop_close_desc, (vop_t *) nfsspec_close }, 183 { &vop_fsync_desc, (vop_t *) nfs_fsync }, 184 { &vop_getattr_desc, (vop_t *) nfs_getattr }, 185 { &vop_inactive_desc, (vop_t *) nfs_inactive }, 186 { &vop_lock_desc, (vop_t *) vop_sharedlock }, 187 { &vop_print_desc, (vop_t *) nfs_print }, 188 { &vop_read_desc, (vop_t *) nfsspec_read }, 189 { &vop_reclaim_desc, (vop_t *) nfs_reclaim }, 190 { &vop_setattr_desc, (vop_t *) nfs_setattr }, 191 { &vop_write_desc, (vop_t *) nfsspec_write }, 192 { NULL, NULL } 193}; 194static struct vnodeopv_desc spec_nfsv2nodeop_opv_desc = 195 { &spec_nfsv2nodeop_p, nfsv2_specop_entries }; 196VNODEOP_SET(spec_nfsv2nodeop_opv_desc); 197 198vop_t **fifo_nfsv2nodeop_p; 199static struct vnodeopv_entry_desc nfsv2_fifoop_entries[] = { 200 { &vop_default_desc, (vop_t *) fifo_vnoperate }, 201 { &vop_access_desc, (vop_t *) nfsspec_access }, 202 { &vop_close_desc, (vop_t *) nfsfifo_close }, 203 { &vop_fsync_desc, (vop_t *) nfs_fsync }, 204 { &vop_getattr_desc, (vop_t *) nfs_getattr }, 205 { &vop_inactive_desc, (vop_t *) nfs_inactive }, 206 { &vop_lock_desc, (vop_t *) vop_sharedlock }, 207 { &vop_print_desc, (vop_t *) nfs_print }, 208 { &vop_read_desc, (vop_t *) nfsfifo_read }, 209 { &vop_reclaim_desc, (vop_t *) nfs_reclaim }, 210 { &vop_setattr_desc, (vop_t *) nfs_setattr }, 211 { &vop_write_desc, (vop_t *) nfsfifo_write }, 212 { NULL, NULL } 213}; 214static struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc = 215 { &fifo_nfsv2nodeop_p, nfsv2_fifoop_entries }; 216VNODEOP_SET(fifo_nfsv2nodeop_opv_desc); 217 218static int nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, 219 struct componentname *cnp, struct vattr *vap); 220static int nfs_removerpc(struct vnode *dvp, const char *name, int namelen, 221 struct ucred *cred, struct thread *td); 222static int nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, 223 int fnamelen, struct vnode *tdvp, 224 const char *tnameptr, int tnamelen, 225 struct ucred *cred, struct thread *td); 226static int nfs_renameit(struct vnode *sdvp, struct componentname *scnp, 227 struct sillyrename *sp); 228 229/* 230 * Global variables 231 */ 232struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; 233struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON]; 234int nfs_numasync = 0; 235#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1)) 236 237SYSCTL_DECL(_vfs_nfs); 238 239static int nfsaccess_cache_timeout = NFS_MAXATTRTIMO; 240SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW, 241 &nfsaccess_cache_timeout, 0, "NFS ACCESS cache timeout"); 242 243static int nfsv3_commit_on_close = 0; 244SYSCTL_INT(_vfs_nfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW, 245 &nfsv3_commit_on_close, 0, "write+commit on close, else only write"); 246#if 0 247SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_hits, CTLFLAG_RD, 248 &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count"); 249 250SYSCTL_INT(_vfs_nfs, OID_AUTO, access_cache_misses, CTLFLAG_RD, 251 &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count"); 252#endif 253 254#define NFSV3ACCESS_ALL (NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY \ 255 | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE \ 256 | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP) 257static int 258nfs3_access_otw(struct vnode *vp, int wmode, struct thread *td, 259 struct ucred *cred) 260{ 261 const int v3 = 1; 262 u_int32_t *tl; 263 int error = 0, attrflag; 264 265 struct mbuf *mreq, *mrep, *md, *mb; 266 caddr_t bpos, dpos; 267 u_int32_t rmode; 268 struct nfsnode *np = VTONFS(vp); 269 270 nfsstats.rpccnt[NFSPROC_ACCESS]++; 271 mreq = nfsm_reqhead(vp, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED); 272 mb = mreq; 273 bpos = mtod(mb, caddr_t); 274 nfsm_fhtom(vp, v3); 275 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); 276 *tl = txdr_unsigned(wmode); 277 nfsm_request(vp, NFSPROC_ACCESS, td, cred); 278 nfsm_postop_attr(vp, attrflag); 279 if (!error) { 280 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); 281 rmode = fxdr_unsigned(u_int32_t, *tl); 282 np->n_mode = rmode; 283 np->n_modeuid = cred->cr_uid; 284 np->n_modestamp = time_second; 285 } 286 m_freem(mrep); 287nfsmout: 288 return error; 289} 290 291/* 292 * nfs access vnode op. 293 * For nfs version 2, just return ok. File accesses may fail later. 294 * For nfs version 3, use the access rpc to check accessibility. If file modes 295 * are changed on the server, accesses might still fail later. 296 */ 297static int 298nfs_access(struct vop_access_args *ap) 299{ 300 struct vnode *vp = ap->a_vp; 301 int error = 0; 302 u_int32_t mode, wmode; 303 int v3 = NFS_ISV3(vp); 304 struct nfsnode *np = VTONFS(vp); 305 306 /* 307 * Disallow write attempts on filesystems mounted read-only; 308 * unless the file is a socket, fifo, or a block or character 309 * device resident on the filesystem. 310 */ 311 if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { 312 switch (vp->v_type) { 313 case VREG: 314 case VDIR: 315 case VLNK: 316 return (EROFS); 317 default: 318 break; 319 } 320 } 321 /* 322 * For nfs v3, check to see if we have done this recently, and if 323 * so return our cached result instead of making an ACCESS call. 324 * If not, do an access rpc, otherwise you are stuck emulating 325 * ufs_access() locally using the vattr. This may not be correct, 326 * since the server may apply other access criteria such as 327 * client uid-->server uid mapping that we do not know about. 328 */ 329 if (v3) { 330 if (ap->a_mode & VREAD) 331 mode = NFSV3ACCESS_READ; 332 else 333 mode = 0; 334 if (vp->v_type != VDIR) { 335 if (ap->a_mode & VWRITE) 336 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND); 337 if (ap->a_mode & VEXEC) 338 mode |= NFSV3ACCESS_EXECUTE; 339 } else { 340 if (ap->a_mode & VWRITE) 341 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND | 342 NFSV3ACCESS_DELETE); 343 if (ap->a_mode & VEXEC) 344 mode |= NFSV3ACCESS_LOOKUP; 345 } 346 /* XXX safety belt, only make blanket request if caching */ 347 if (nfsaccess_cache_timeout > 0) { 348 wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY | 349 NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE | 350 NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP; 351 } else { 352 wmode = mode; 353 } 354 355 /* 356 * Does our cached result allow us to give a definite yes to 357 * this request? 358 */ 359 if ((time_second < (np->n_modestamp + nfsaccess_cache_timeout)) && 360 (ap->a_cred->cr_uid == np->n_modeuid) && 361 ((np->n_mode & mode) == mode)) { 362 nfsstats.accesscache_hits++; 363 } else { 364 /* 365 * Either a no, or a don't know. Go to the wire. 366 */ 367 nfsstats.accesscache_misses++; 368 error = nfs3_access_otw(vp, wmode, ap->a_td,ap->a_cred); 369 if (!error) { 370 if ((np->n_mode & mode) != mode) { 371 error = EACCES; 372 } 373 } 374 } 375 return (error); 376 } else { 377 if ((error = nfsspec_access(ap)) != 0) 378 return (error); 379 380 /* 381 * Attempt to prevent a mapped root from accessing a file 382 * which it shouldn't. We try to read a byte from the file 383 * if the user is root and the file is not zero length. 384 * After calling nfsspec_access, we should have the correct 385 * file size cached. 386 */ 387 if (ap->a_cred->cr_uid == 0 && (ap->a_mode & VREAD) 388 && VTONFS(vp)->n_size > 0) { 389 struct iovec aiov; 390 struct uio auio; 391 char buf[1]; 392 393 aiov.iov_base = buf; 394 aiov.iov_len = 1; 395 auio.uio_iov = &aiov; 396 auio.uio_iovcnt = 1; 397 auio.uio_offset = 0; 398 auio.uio_resid = 1; 399 auio.uio_segflg = UIO_SYSSPACE; 400 auio.uio_rw = UIO_READ; 401 auio.uio_td = ap->a_td; 402 403 if (vp->v_type == VREG) 404 error = nfs_readrpc(vp, &auio, ap->a_cred); 405 else if (vp->v_type == VDIR) { 406 char* bp; 407 bp = malloc(NFS_DIRBLKSIZ, M_TEMP, M_WAITOK); 408 aiov.iov_base = bp; 409 aiov.iov_len = auio.uio_resid = NFS_DIRBLKSIZ; 410 error = nfs_readdirrpc(vp, &auio, ap->a_cred); 411 free(bp, M_TEMP); 412 } else if (vp->v_type == VLNK) 413 error = nfs_readlinkrpc(vp, &auio, ap->a_cred); 414 else 415 error = EACCES; 416 } 417 return (error); 418 } 419} 420 421/* 422 * nfs open vnode op 423 * Check to see if the type is ok 424 * and that deletion is not in progress. 425 * For paged in text files, you will need to flush the page cache 426 * if consistency is lost. 427 */ 428/* ARGSUSED */ 429static int 430nfs_open(struct vop_open_args *ap) 431{ 432 struct vnode *vp = ap->a_vp; 433 struct nfsnode *np = VTONFS(vp); 434 struct vattr vattr; 435 int error; 436 437 if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) { 438#ifdef DIAGNOSTIC 439 printf("open eacces vtyp=%d\n", vp->v_type); 440#endif 441 return (EACCES); 442 } 443 /* 444 * Get a valid lease. If cached data is stale, flush it. 445 */ 446 if (np->n_flag & NMODIFIED) { 447 if ((error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, 448 ap->a_td, 1)) == EINTR) 449 return (error); 450 np->n_attrstamp = 0; 451 if (vp->v_type == VDIR) 452 np->n_direofoffset = 0; 453 error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td); 454 if (error) 455 return (error); 456 np->n_mtime = vattr.va_mtime.tv_sec; 457 } else { 458 error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_td); 459 if (error) 460 return (error); 461 if (np->n_mtime != vattr.va_mtime.tv_sec) { 462 if (vp->v_type == VDIR) 463 np->n_direofoffset = 0; 464 if ((error = nfs_vinvalbuf(vp, V_SAVE, 465 ap->a_cred, ap->a_td, 1)) == EINTR) 466 return (error); 467 np->n_mtime = vattr.va_mtime.tv_sec; 468 } 469 } 470 np->n_attrstamp = 0; /* For Open/Close consistency */ 471 return (0); 472} 473 474/* 475 * nfs close vnode op 476 * What an NFS client should do upon close after writing is a debatable issue. 477 * Most NFS clients push delayed writes to the server upon close, basically for 478 * two reasons: 479 * 1 - So that any write errors may be reported back to the client process 480 * doing the close system call. By far the two most likely errors are 481 * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure. 482 * 2 - To put a worst case upper bound on cache inconsistency between 483 * multiple clients for the file. 484 * There is also a consistency problem for Version 2 of the protocol w.r.t. 485 * not being able to tell if other clients are writing a file concurrently, 486 * since there is no way of knowing if the changed modify time in the reply 487 * is only due to the write for this client. 488 * (NFS Version 3 provides weak cache consistency data in the reply that 489 * should be sufficient to detect and handle this case.) 490 * 491 * The current code does the following: 492 * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers 493 * for NFS Version 3 - flush dirty buffers to the server but don't invalidate 494 * or commit them (this satisfies 1 and 2 except for the 495 * case where the server crashes after this close but 496 * before the commit RPC, which is felt to be "good 497 * enough". Changing the last argument to nfs_flush() to 498 * a 1 would force a commit operation, if it is felt a 499 * commit is necessary now. 500 */ 501/* ARGSUSED */ 502static int 503nfs_close(struct vop_close_args *ap) 504{ 505 struct vnode *vp = ap->a_vp; 506 struct nfsnode *np = VTONFS(vp); 507 int error = 0; 508 509 if (vp->v_type == VREG) { 510 if (np->n_flag & NMODIFIED) { 511 if (NFS_ISV3(vp)) { 512 /* 513 * Under NFSv3 we have dirty buffers to dispose of. We 514 * must flush them to the NFS server. We have the option 515 * of waiting all the way through the commit rpc or just 516 * waiting for the initial write. The default is to only 517 * wait through the initial write so the data is in the 518 * server's cache, which is roughly similar to the state 519 * a standard disk subsystem leaves the file in on close(). 520 * 521 * We cannot clear the NMODIFIED bit in np->n_flag due to 522 * potential races with other processes, and certainly 523 * cannot clear it if we don't commit. 524 */ 525 int cm = nfsv3_commit_on_close ? 1 : 0; 526 error = nfs_flush(vp, ap->a_cred, MNT_WAIT, ap->a_td, cm); 527 /* np->n_flag &= ~NMODIFIED; */ 528 } else { 529 error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_td, 1); 530 } 531 np->n_attrstamp = 0; 532 } 533 if (np->n_flag & NWRITEERR) { 534 np->n_flag &= ~NWRITEERR; 535 error = np->n_error; 536 } 537 } 538 return (error); 539} 540 541/* 542 * nfs getattr call from vfs. 543 */ 544static int 545nfs_getattr(struct vop_getattr_args *ap) 546{ 547 struct vnode *vp = ap->a_vp; 548 struct nfsnode *np = VTONFS(vp); 549 caddr_t bpos, dpos; 550 int error = 0; 551 struct mbuf *mreq, *mrep, *md, *mb; 552 int v3 = NFS_ISV3(vp); 553 554 /* 555 * Update local times for special files. 556 */ 557 if (np->n_flag & (NACC | NUPD)) 558 np->n_flag |= NCHG; 559 /* 560 * First look in the cache. 561 */ 562 if (nfs_getattrcache(vp, ap->a_vap) == 0) 563 return (0); 564 565 if (v3 && nfsaccess_cache_timeout > 0) { 566 nfsstats.accesscache_misses++; 567 nfs3_access_otw(vp, NFSV3ACCESS_ALL, ap->a_td, ap->a_cred); 568 if (nfs_getattrcache(vp, ap->a_vap) == 0) 569 return (0); 570 } 571 572 nfsstats.rpccnt[NFSPROC_GETATTR]++; 573 mreq = nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH(v3)); 574 mb = mreq; 575 bpos = mtod(mb, caddr_t); 576 nfsm_fhtom(vp, v3); 577 nfsm_request(vp, NFSPROC_GETATTR, ap->a_td, ap->a_cred); 578 if (!error) { 579 nfsm_loadattr(vp, ap->a_vap); 580 } 581 m_freem(mrep); 582nfsmout: 583 return (error); 584} 585 586/* 587 * nfs setattr call. 588 */ 589static int 590nfs_setattr(struct vop_setattr_args *ap) 591{ 592 struct vnode *vp = ap->a_vp; 593 struct nfsnode *np = VTONFS(vp); 594 struct vattr *vap = ap->a_vap; 595 int error = 0; 596 u_quad_t tsize; 597 598#ifndef nolint 599 tsize = (u_quad_t)0; 600#endif 601 602 /* 603 * Setting of flags is not supported. 604 */ 605 if (vap->va_flags != VNOVAL) 606 return (EOPNOTSUPP); 607 608 /* 609 * Disallow write attempts if the filesystem is mounted read-only. 610 */ 611 if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL || 612 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || 613 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) && 614 (vp->v_mount->mnt_flag & MNT_RDONLY)) 615 return (EROFS); 616 if (vap->va_size != VNOVAL) { 617 switch (vp->v_type) { 618 case VDIR: 619 return (EISDIR); 620 case VCHR: 621 case VBLK: 622 case VSOCK: 623 case VFIFO: 624 if (vap->va_mtime.tv_sec == VNOVAL && 625 vap->va_atime.tv_sec == VNOVAL && 626 vap->va_mode == (mode_t)VNOVAL && 627 vap->va_uid == (uid_t)VNOVAL && 628 vap->va_gid == (gid_t)VNOVAL) 629 return (0); 630 vap->va_size = VNOVAL; 631 break; 632 default: 633 /* 634 * Disallow write attempts if the filesystem is 635 * mounted read-only. 636 */ 637 if (vp->v_mount->mnt_flag & MNT_RDONLY) 638 return (EROFS); 639 640 /* 641 * We run vnode_pager_setsize() early (why?), 642 * we must set np->n_size now to avoid vinvalbuf 643 * V_SAVE races that might setsize a lower 644 * value. 645 */ 646 647 tsize = np->n_size; 648 error = nfs_meta_setsize(vp, ap->a_cred, 649 ap->a_td, vap->va_size); 650 651 if (np->n_flag & NMODIFIED) { 652 if (vap->va_size == 0) 653 error = nfs_vinvalbuf(vp, 0, 654 ap->a_cred, ap->a_td, 1); 655 else 656 error = nfs_vinvalbuf(vp, V_SAVE, 657 ap->a_cred, ap->a_td, 1); 658 if (error) { 659 vnode_pager_setsize(vp, np->n_size); 660 return (error); 661 } 662 } 663 np->n_vattr.va_size = vap->va_size; 664 }; 665 } else if ((vap->va_mtime.tv_sec != VNOVAL || 666 vap->va_atime.tv_sec != VNOVAL) && (np->n_flag & NMODIFIED) && 667 vp->v_type == VREG && 668 (error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, 669 ap->a_td, 1)) == EINTR) 670 return (error); 671 error = nfs_setattrrpc(vp, vap, ap->a_cred, ap->a_td); 672 if (error && vap->va_size != VNOVAL) { 673 np->n_size = np->n_vattr.va_size = tsize; 674 vnode_pager_setsize(vp, np->n_size); 675 } 676 return (error); 677} 678 679/* 680 * Do an nfs setattr rpc. 681 */ 682static int 683nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred, 684 struct thread *td) 685{ 686 struct nfsv2_sattr *sp; 687 caddr_t bpos, dpos; 688 u_int32_t *tl; 689 int error = 0, wccflag = NFSV3_WCCRATTR; 690 struct mbuf *mreq, *mrep, *md, *mb; 691 int v3 = NFS_ISV3(vp); 692 693 nfsstats.rpccnt[NFSPROC_SETATTR]++; 694 mreq = nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3)); 695 mb = mreq; 696 bpos = mtod(mb, caddr_t); 697 nfsm_fhtom(vp, v3); 698 if (v3) { 699 nfsm_v3attrbuild(vap, TRUE); 700 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); 701 *tl = nfs_false; 702 } else { 703 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); 704 if (vap->va_mode == (mode_t)VNOVAL) 705 sp->sa_mode = nfs_xdrneg1; 706 else 707 sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode); 708 if (vap->va_uid == (uid_t)VNOVAL) 709 sp->sa_uid = nfs_xdrneg1; 710 else 711 sp->sa_uid = txdr_unsigned(vap->va_uid); 712 if (vap->va_gid == (gid_t)VNOVAL) 713 sp->sa_gid = nfs_xdrneg1; 714 else 715 sp->sa_gid = txdr_unsigned(vap->va_gid); 716 sp->sa_size = txdr_unsigned(vap->va_size); 717 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 718 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 719 } 720 nfsm_request(vp, NFSPROC_SETATTR, td, cred); 721 if (v3) { 722 nfsm_wcc_data(vp, wccflag); 723 } else 724 nfsm_loadattr(vp, NULL); 725 m_freem(mrep); 726nfsmout: 727 return (error); 728} 729 730/* 731 * nfs lookup call, one step at a time... 732 * First look in cache 733 * If not found, unlock the directory nfsnode and do the rpc 734 */ 735static int 736nfs_lookup(struct vop_lookup_args *ap) 737{ 738 struct componentname *cnp = ap->a_cnp; 739 struct vnode *dvp = ap->a_dvp; 740 struct vnode **vpp = ap->a_vpp; 741 int flags = cnp->cn_flags; 742 struct vnode *newvp; 743 struct nfsmount *nmp; 744 caddr_t bpos, dpos; 745 struct mbuf *mreq, *mrep, *md, *mb; 746 long len; 747 nfsfh_t *fhp; 748 struct nfsnode *np; 749 int lockparent, wantparent, error = 0, attrflag, fhsize; 750 int v3 = NFS_ISV3(dvp); 751 struct thread *td = cnp->cn_thread; 752 753 *vpp = NULLVP; 754 cnp->cn_flags &= ~PDIRUNLOCK; 755 if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && 756 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) 757 return (EROFS); 758 if (dvp->v_type != VDIR) 759 return (ENOTDIR); 760 lockparent = flags & LOCKPARENT; 761 wantparent = flags & (LOCKPARENT|WANTPARENT); 762 nmp = VFSTONFS(dvp->v_mount); 763 np = VTONFS(dvp); 764 if ((error = cache_lookup(dvp, vpp, cnp)) && error != ENOENT) { 765 struct vattr vattr; 766 int vpid; 767 768 if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td)) != 0) { 769 *vpp = NULLVP; 770 return (error); 771 } 772 773 vhold(*vpp); 774 newvp = *vpp; 775 vpid = newvp->v_id; 776 /* 777 * See the comment starting `Step through' in ufs/ufs_lookup.c 778 * for an explanation of the locking protocol 779 */ 780 if (dvp == newvp) { 781 VREF(newvp); 782 error = 0; 783 } else if (flags & ISDOTDOT) { 784 VOP_UNLOCK(dvp, 0, td); 785 cnp->cn_flags |= PDIRUNLOCK; 786 error = vget(newvp, LK_EXCLUSIVE, td); 787 if (!error && lockparent && (flags & ISLASTCN)) { 788 error = vn_lock(dvp, LK_EXCLUSIVE, td); 789 if (error == 0) 790 cnp->cn_flags &= ~PDIRUNLOCK; 791 } 792 } else { 793 error = vget(newvp, LK_EXCLUSIVE, td); 794 if (!lockparent || error || !(flags & ISLASTCN)) { 795 VOP_UNLOCK(dvp, 0, td); 796 cnp->cn_flags |= PDIRUNLOCK; 797 } 798 } 799 if (!error) { 800 if (vpid == newvp->v_id) { 801 if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred, td) 802 && vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime) { 803 nfsstats.lookupcache_hits++; 804 if (cnp->cn_nameiop != LOOKUP && 805 (flags & ISLASTCN)) 806 cnp->cn_flags |= SAVENAME; 807 vdrop(newvp); 808 return (0); 809 } 810 cache_purge(newvp); 811 } 812 vput(newvp); 813 if (lockparent && dvp != newvp && (flags & ISLASTCN)) 814 VOP_UNLOCK(dvp, 0, td); 815 } 816 vdrop(newvp); 817 error = vn_lock(dvp, LK_EXCLUSIVE, td); 818 *vpp = NULLVP; 819 if (error) { 820 cnp->cn_flags |= PDIRUNLOCK; 821 return (error); 822 } 823 cnp->cn_flags &= ~PDIRUNLOCK; 824 } 825 error = 0; 826 newvp = NULLVP; 827 nfsstats.lookupcache_misses++; 828 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 829 len = cnp->cn_namelen; 830 mreq = nfsm_reqhead(dvp, NFSPROC_LOOKUP, 831 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); 832 mb = mreq; 833 bpos = mtod(mb, caddr_t); 834 nfsm_fhtom(dvp, v3); 835 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 836 nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_thread, cnp->cn_cred); 837 if (error) { 838 nfsm_postop_attr(dvp, attrflag); 839 m_freem(mrep); 840 goto nfsmout; 841 } 842 nfsm_getfh(fhp, fhsize, v3); 843 844 /* 845 * Handle RENAME case... 846 */ 847 if (cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN)) { 848 if (NFS_CMPFH(np, fhp, fhsize)) { 849 m_freem(mrep); 850 return (EISDIR); 851 } 852 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); 853 if (error) { 854 m_freem(mrep); 855 return (error); 856 } 857 newvp = NFSTOV(np); 858 if (v3) { 859 nfsm_postop_attr(newvp, attrflag); 860 nfsm_postop_attr(dvp, attrflag); 861 } else 862 nfsm_loadattr(newvp, NULL); 863 *vpp = newvp; 864 m_freem(mrep); 865 cnp->cn_flags |= SAVENAME; 866 if (!lockparent) { 867 VOP_UNLOCK(dvp, 0, td); 868 cnp->cn_flags |= PDIRUNLOCK; 869 } 870 return (0); 871 } 872 873 if (flags & ISDOTDOT) { 874 VOP_UNLOCK(dvp, 0, td); 875 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); 876 if (error) { 877 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td); 878 return (error); 879 } 880 newvp = NFSTOV(np); 881 if (lockparent && (flags & ISLASTCN)) { 882 error = vn_lock(dvp, LK_EXCLUSIVE, td); 883 if (error) { 884 cnp->cn_flags |= PDIRUNLOCK; 885 vput(newvp); 886 return (error); 887 } 888 } else 889 cnp->cn_flags |= PDIRUNLOCK; 890 } else if (NFS_CMPFH(np, fhp, fhsize)) { 891 VREF(dvp); 892 newvp = dvp; 893 } else { 894 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); 895 if (error) { 896 m_freem(mrep); 897 return (error); 898 } 899 if (!lockparent || !(flags & ISLASTCN)) { 900 cnp->cn_flags |= PDIRUNLOCK; 901 VOP_UNLOCK(dvp, 0, td); 902 } 903 newvp = NFSTOV(np); 904 } 905 if (v3) { 906 nfsm_postop_attr(newvp, attrflag); 907 nfsm_postop_attr(dvp, attrflag); 908 } else 909 nfsm_loadattr(newvp, NULL); 910 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) 911 cnp->cn_flags |= SAVENAME; 912 if ((cnp->cn_flags & MAKEENTRY) && 913 (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) { 914 np->n_ctime = np->n_vattr.va_ctime.tv_sec; 915 cache_enter(dvp, newvp, cnp); 916 } 917 *vpp = newvp; 918 m_freem(mrep); 919nfsmout: 920 if (error) { 921 if (newvp != NULLVP) { 922 vrele(newvp); 923 *vpp = NULLVP; 924 } 925 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && 926 (flags & ISLASTCN) && error == ENOENT) { 927 if (!lockparent) { 928 VOP_UNLOCK(dvp, 0, td); 929 cnp->cn_flags |= PDIRUNLOCK; 930 } 931 if (dvp->v_mount->mnt_flag & MNT_RDONLY) 932 error = EROFS; 933 else 934 error = EJUSTRETURN; 935 } 936 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) 937 cnp->cn_flags |= SAVENAME; 938 } 939 return (error); 940} 941 942/* 943 * nfs read call. 944 * Just call nfs_bioread() to do the work. 945 */ 946static int 947nfs_read(struct vop_read_args *ap) 948{ 949 struct vnode *vp = ap->a_vp; 950 951 if (vp->v_type != VREG) 952 return (EPERM); 953 return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred)); 954} 955 956/* 957 * nfs readlink call 958 */ 959static int 960nfs_readlink(struct vop_readlink_args *ap) 961{ 962 struct vnode *vp = ap->a_vp; 963 964 if (vp->v_type != VLNK) 965 return (EINVAL); 966 return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred)); 967} 968 969/* 970 * Do a readlink rpc. 971 * Called by nfs_doio() from below the buffer cache. 972 */ 973int 974nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) 975{ 976 caddr_t bpos, dpos; 977 int error = 0, len, attrflag; 978 struct mbuf *mreq, *mrep, *md, *mb; 979 int v3 = NFS_ISV3(vp); 980 981 nfsstats.rpccnt[NFSPROC_READLINK]++; 982 mreq = nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH(v3)); 983 mb = mreq; 984 bpos = mtod(mb, caddr_t); 985 nfsm_fhtom(vp, v3); 986 nfsm_request(vp, NFSPROC_READLINK, uiop->uio_td, cred); 987 if (v3) 988 nfsm_postop_attr(vp, attrflag); 989 if (!error) { 990 nfsm_strsiz(len, NFS_MAXPATHLEN); 991 if (len == NFS_MAXPATHLEN) { 992 struct nfsnode *np = VTONFS(vp); 993 if (np->n_size && np->n_size < NFS_MAXPATHLEN) 994 len = np->n_size; 995 } 996 nfsm_mtouio(uiop, len); 997 } 998 m_freem(mrep); 999nfsmout: 1000 return (error); 1001} 1002 1003/* 1004 * nfs read rpc call 1005 * Ditto above 1006 */ 1007int 1008nfs_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) 1009{ 1010 u_int32_t *tl; 1011 caddr_t bpos, dpos; 1012 struct mbuf *mreq, *mrep, *md, *mb; 1013 struct nfsmount *nmp; 1014 int error = 0, len, retlen, tsiz, eof, attrflag; 1015 int v3 = NFS_ISV3(vp); 1016 1017#ifndef nolint 1018 eof = 0; 1019#endif 1020 nmp = VFSTONFS(vp->v_mount); 1021 tsiz = uiop->uio_resid; 1022 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) 1023 return (EFBIG); 1024 while (tsiz > 0) { 1025 nfsstats.rpccnt[NFSPROC_READ]++; 1026 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; 1027 mreq = nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3); 1028 mb = mreq; 1029 bpos = mtod(mb, caddr_t); 1030 nfsm_fhtom(vp, v3); 1031 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED * 3); 1032 if (v3) { 1033 txdr_hyper(uiop->uio_offset, tl); 1034 *(tl + 2) = txdr_unsigned(len); 1035 } else { 1036 *tl++ = txdr_unsigned(uiop->uio_offset); 1037 *tl++ = txdr_unsigned(len); 1038 *tl = 0; 1039 } 1040 nfsm_request(vp, NFSPROC_READ, uiop->uio_td, cred); 1041 if (v3) { 1042 nfsm_postop_attr(vp, attrflag); 1043 if (error) { 1044 m_freem(mrep); 1045 goto nfsmout; 1046 } 1047 tl = nfsm_dissect(u_int32_t *, 2 * NFSX_UNSIGNED); 1048 eof = fxdr_unsigned(int, *(tl + 1)); 1049 } else 1050 nfsm_loadattr(vp, NULL); 1051 nfsm_strsiz(retlen, nmp->nm_rsize); 1052 nfsm_mtouio(uiop, retlen); 1053 m_freem(mrep); 1054 tsiz -= retlen; 1055 if (v3) { 1056 if (eof || retlen == 0) { 1057 tsiz = 0; 1058 } 1059 } else if (retlen < len) { 1060 tsiz = 0; 1061 } 1062 } 1063nfsmout: 1064 return (error); 1065} 1066 1067/* 1068 * nfs write call 1069 */ 1070int 1071nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, 1072 int *iomode, int *must_commit) 1073{ 1074 u_int32_t *tl; 1075 int32_t backup; 1076 caddr_t bpos, dpos; 1077 struct mbuf *mreq, *mrep, *md, *mb; 1078 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 1079 int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit; 1080 int v3 = NFS_ISV3(vp), committed = NFSV3WRITE_FILESYNC; 1081 1082#ifndef DIAGNOSTIC 1083 if (uiop->uio_iovcnt != 1) 1084 panic("nfs: writerpc iovcnt > 1"); 1085#endif 1086 *must_commit = 0; 1087 tsiz = uiop->uio_resid; 1088 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) 1089 return (EFBIG); 1090 while (tsiz > 0) { 1091 nfsstats.rpccnt[NFSPROC_WRITE]++; 1092 len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; 1093 mreq = nfsm_reqhead(vp, NFSPROC_WRITE, 1094 NFSX_FH(v3) + 5 * NFSX_UNSIGNED + nfsm_rndup(len)); 1095 mb = mreq; 1096 bpos = mtod(mb, caddr_t); 1097 nfsm_fhtom(vp, v3); 1098 if (v3) { 1099 tl = nfsm_build(u_int32_t *, 5 * NFSX_UNSIGNED); 1100 txdr_hyper(uiop->uio_offset, tl); 1101 tl += 2; 1102 *tl++ = txdr_unsigned(len); 1103 *tl++ = txdr_unsigned(*iomode); 1104 *tl = txdr_unsigned(len); 1105 } else { 1106 u_int32_t x; 1107 1108 tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED); 1109 /* Set both "begin" and "current" to non-garbage. */ 1110 x = txdr_unsigned((u_int32_t)uiop->uio_offset); 1111 *tl++ = x; /* "begin offset" */ 1112 *tl++ = x; /* "current offset" */ 1113 x = txdr_unsigned(len); 1114 *tl++ = x; /* total to this offset */ 1115 *tl = x; /* size of this write */ 1116 } 1117 nfsm_uiotom(uiop, len); 1118 nfsm_request(vp, NFSPROC_WRITE, uiop->uio_td, cred); 1119 if (v3) { 1120 wccflag = NFSV3_WCCCHK; 1121 nfsm_wcc_data(vp, wccflag); 1122 if (!error) { 1123 tl = nfsm_dissect(u_int32_t *, 2 * NFSX_UNSIGNED 1124 + NFSX_V3WRITEVERF); 1125 rlen = fxdr_unsigned(int, *tl++); 1126 if (rlen == 0) { 1127 error = NFSERR_IO; 1128 m_freem(mrep); 1129 break; 1130 } else if (rlen < len) { 1131 backup = len - rlen; 1132 uiop->uio_iov->iov_base = 1133 (char *)uiop->uio_iov->iov_base - 1134 backup; 1135 uiop->uio_iov->iov_len += backup; 1136 uiop->uio_offset -= backup; 1137 uiop->uio_resid += backup; 1138 len = rlen; 1139 } 1140 commit = fxdr_unsigned(int, *tl++); 1141 1142 /* 1143 * Return the lowest committment level 1144 * obtained by any of the RPCs. 1145 */ 1146 if (committed == NFSV3WRITE_FILESYNC) 1147 committed = commit; 1148 else if (committed == NFSV3WRITE_DATASYNC && 1149 commit == NFSV3WRITE_UNSTABLE) 1150 committed = commit; 1151 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){ 1152 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 1153 NFSX_V3WRITEVERF); 1154 nmp->nm_state |= NFSSTA_HASWRITEVERF; 1155 } else if (bcmp((caddr_t)tl, 1156 (caddr_t)nmp->nm_verf, NFSX_V3WRITEVERF)) { 1157 *must_commit = 1; 1158 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 1159 NFSX_V3WRITEVERF); 1160 } 1161 } 1162 } else 1163 nfsm_loadattr(vp, NULL); 1164 if (wccflag) 1165 VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.tv_sec; 1166 m_freem(mrep); 1167 if (error) 1168 break; 1169 tsiz -= len; 1170 } 1171nfsmout: 1172 if (vp->v_mount->mnt_flag & MNT_ASYNC) 1173 committed = NFSV3WRITE_FILESYNC; 1174 *iomode = committed; 1175 if (error) 1176 uiop->uio_resid = tsiz; 1177 return (error); 1178} 1179 1180/* 1181 * nfs mknod rpc 1182 * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the 1183 * mode set to specify the file type and the size field for rdev. 1184 */ 1185static int 1186nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, 1187 struct vattr *vap) 1188{ 1189 struct nfsv2_sattr *sp; 1190 u_int32_t *tl; 1191 struct vnode *newvp = NULL; 1192 struct nfsnode *np = NULL; 1193 struct vattr vattr; 1194 caddr_t bpos, dpos; 1195 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0; 1196 struct mbuf *mreq, *mrep, *md, *mb; 1197 u_int32_t rdev; 1198 int v3 = NFS_ISV3(dvp); 1199 1200 if (vap->va_type == VCHR || vap->va_type == VBLK) 1201 rdev = txdr_unsigned(vap->va_rdev); 1202 else if (vap->va_type == VFIFO || vap->va_type == VSOCK) 1203 rdev = nfs_xdrneg1; 1204 else { 1205 return (EOPNOTSUPP); 1206 } 1207 if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred, cnp->cn_thread)) != 0) { 1208 return (error); 1209 } 1210 nfsstats.rpccnt[NFSPROC_MKNOD]++; 1211 mreq = nfsm_reqhead(dvp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED + 1212 + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); 1213 mb = mreq; 1214 bpos = mtod(mb, caddr_t); 1215 nfsm_fhtom(dvp, v3); 1216 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1217 if (v3) { 1218 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); 1219 *tl++ = vtonfsv3_type(vap->va_type); 1220 nfsm_v3attrbuild(vap, FALSE); 1221 if (vap->va_type == VCHR || vap->va_type == VBLK) { 1222 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED); 1223 *tl++ = txdr_unsigned(umajor(vap->va_rdev)); 1224 *tl = txdr_unsigned(uminor(vap->va_rdev)); 1225 } 1226 } else { 1227 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); 1228 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); 1229 sp->sa_uid = nfs_xdrneg1; 1230 sp->sa_gid = nfs_xdrneg1; 1231 sp->sa_size = rdev; 1232 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1233 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1234 } 1235 nfsm_request(dvp, NFSPROC_MKNOD, cnp->cn_thread, cnp->cn_cred); 1236 if (!error) { 1237 nfsm_mtofh(dvp, newvp, v3, gotvp); 1238 if (!gotvp) { 1239 if (newvp) { 1240 vput(newvp); 1241 newvp = NULL; 1242 } 1243 error = nfs_lookitup(dvp, cnp->cn_nameptr, 1244 cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread, &np); 1245 if (!error) 1246 newvp = NFSTOV(np); 1247 } 1248 } 1249 if (v3) 1250 nfsm_wcc_data(dvp, wccflag); 1251 m_freem(mrep); 1252nfsmout: 1253 if (error) { 1254 if (newvp) 1255 vput(newvp); 1256 } else { 1257 if (cnp->cn_flags & MAKEENTRY) 1258 cache_enter(dvp, newvp, cnp); 1259 *vpp = newvp; 1260 } 1261 VTONFS(dvp)->n_flag |= NMODIFIED; 1262 if (!wccflag) 1263 VTONFS(dvp)->n_attrstamp = 0; 1264 return (error); 1265} 1266 1267/* 1268 * nfs mknod vop 1269 * just call nfs_mknodrpc() to do the work. 1270 */ 1271/* ARGSUSED */ 1272static int 1273nfs_mknod(struct vop_mknod_args *ap) 1274{ 1275 1276 return nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap); 1277} 1278 1279static u_long create_verf; 1280/* 1281 * nfs file create call 1282 */ 1283static int 1284nfs_create(struct vop_create_args *ap) 1285{ 1286 struct vnode *dvp = ap->a_dvp; 1287 struct vattr *vap = ap->a_vap; 1288 struct componentname *cnp = ap->a_cnp; 1289 struct nfsv2_sattr *sp; 1290 u_int32_t *tl; 1291 struct nfsnode *np = NULL; 1292 struct vnode *newvp = NULL; 1293 caddr_t bpos, dpos; 1294 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0; 1295 struct mbuf *mreq, *mrep, *md, *mb; 1296 struct vattr vattr; 1297 int v3 = NFS_ISV3(dvp); 1298 1299 /* 1300 * Oops, not for me.. 1301 */ 1302 if (vap->va_type == VSOCK) 1303 return (nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap)); 1304 1305 if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred, cnp->cn_thread)) != 0) { 1306 return (error); 1307 } 1308 if (vap->va_vaflags & VA_EXCLUSIVE) 1309 fmode |= O_EXCL; 1310again: 1311 nfsstats.rpccnt[NFSPROC_CREATE]++; 1312 mreq = nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED + 1313 nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); 1314 mb = mreq; 1315 bpos = mtod(mb, caddr_t); 1316 nfsm_fhtom(dvp, v3); 1317 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1318 if (v3) { 1319 tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); 1320 if (fmode & O_EXCL) { 1321 *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); 1322 tl = nfsm_build(u_int32_t *, NFSX_V3CREATEVERF); 1323#ifdef INET 1324 if (!TAILQ_EMPTY(&in_ifaddrhead)) 1325 *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr.s_addr; 1326 else 1327#endif 1328 *tl++ = create_verf; 1329 *tl = ++create_verf; 1330 } else { 1331 *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED); 1332 nfsm_v3attrbuild(vap, FALSE); 1333 } 1334 } else { 1335 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); 1336 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); 1337 sp->sa_uid = nfs_xdrneg1; 1338 sp->sa_gid = nfs_xdrneg1; 1339 sp->sa_size = 0; 1340 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1341 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1342 } 1343 nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_thread, cnp->cn_cred); 1344 if (!error) { 1345 nfsm_mtofh(dvp, newvp, v3, gotvp); 1346 if (!gotvp) { 1347 if (newvp) { 1348 vput(newvp); 1349 newvp = NULL; 1350 } 1351 error = nfs_lookitup(dvp, cnp->cn_nameptr, 1352 cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread, &np); 1353 if (!error) 1354 newvp = NFSTOV(np); 1355 } 1356 } 1357 if (v3) 1358 nfsm_wcc_data(dvp, wccflag); 1359 m_freem(mrep); 1360nfsmout: 1361 if (error) { 1362 if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) { 1363 fmode &= ~O_EXCL; 1364 goto again; 1365 } 1366 if (newvp) 1367 vput(newvp); 1368 } else if (v3 && (fmode & O_EXCL)) { 1369 /* 1370 * We are normally called with only a partially initialized 1371 * VAP. Since the NFSv3 spec says that server may use the 1372 * file attributes to store the verifier, the spec requires 1373 * us to do a SETATTR RPC. FreeBSD servers store the verifier 1374 * in atime, but we can't really assume that all servers will 1375 * so we ensure that our SETATTR sets both atime and mtime. 1376 */ 1377 if (vap->va_mtime.tv_sec == VNOVAL) 1378 vfs_timestamp(&vap->va_mtime); 1379 if (vap->va_atime.tv_sec == VNOVAL) 1380 vap->va_atime = vap->va_mtime; 1381 error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_thread); 1382 } 1383 if (!error) { 1384 if (cnp->cn_flags & MAKEENTRY) 1385 cache_enter(dvp, newvp, cnp); 1386 *ap->a_vpp = newvp; 1387 } 1388 VTONFS(dvp)->n_flag |= NMODIFIED; 1389 if (!wccflag) 1390 VTONFS(dvp)->n_attrstamp = 0; 1391 return (error); 1392} 1393 1394/* 1395 * nfs file remove call 1396 * To try and make nfs semantics closer to ufs semantics, a file that has 1397 * other processes using the vnode is renamed instead of removed and then 1398 * removed later on the last close. 1399 * - If v_usecount > 1 1400 * If a rename is not already in the works 1401 * call nfs_sillyrename() to set it up 1402 * else 1403 * do the remove rpc 1404 */ 1405static int 1406nfs_remove(struct vop_remove_args *ap) 1407{ 1408 struct vnode *vp = ap->a_vp; 1409 struct vnode *dvp = ap->a_dvp; 1410 struct componentname *cnp = ap->a_cnp; 1411 struct nfsnode *np = VTONFS(vp); 1412 int error = 0; 1413 struct vattr vattr; 1414 1415#ifndef DIAGNOSTIC 1416 if ((cnp->cn_flags & HASBUF) == 0) 1417 panic("nfs_remove: no name"); 1418 if (vrefcnt(vp) < 1) 1419 panic("nfs_remove: bad v_usecount"); 1420#endif 1421 if (vp->v_type == VDIR) 1422 error = EPERM; 1423 else if (vrefcnt(vp) == 1 || (np->n_sillyrename && 1424 VOP_GETATTR(vp, &vattr, cnp->cn_cred, cnp->cn_thread) == 0 && 1425 vattr.va_nlink > 1)) { 1426 /* 1427 * Purge the name cache so that the chance of a lookup for 1428 * the name succeeding while the remove is in progress is 1429 * minimized. Without node locking it can still happen, such 1430 * that an I/O op returns ESTALE, but since you get this if 1431 * another host removes the file.. 1432 */ 1433 cache_purge(vp); 1434 /* 1435 * throw away biocache buffers, mainly to avoid 1436 * unnecessary delayed writes later. 1437 */ 1438 error = nfs_vinvalbuf(vp, 0, cnp->cn_cred, cnp->cn_thread, 1); 1439 /* Do the rpc */ 1440 if (error != EINTR) 1441 error = nfs_removerpc(dvp, cnp->cn_nameptr, 1442 cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread); 1443 /* 1444 * Kludge City: If the first reply to the remove rpc is lost.. 1445 * the reply to the retransmitted request will be ENOENT 1446 * since the file was in fact removed 1447 * Therefore, we cheat and return success. 1448 */ 1449 if (error == ENOENT) 1450 error = 0; 1451 } else if (!np->n_sillyrename) 1452 error = nfs_sillyrename(dvp, vp, cnp); 1453 np->n_attrstamp = 0; 1454 return (error); 1455} 1456 1457/* 1458 * nfs file remove rpc called from nfs_inactive 1459 */ 1460int 1461nfs_removeit(struct sillyrename *sp) 1462{ 1463 1464 return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred, 1465 NULL)); 1466} 1467 1468/* 1469 * Nfs remove rpc, called from nfs_remove() and nfs_removeit(). 1470 */ 1471static int 1472nfs_removerpc(struct vnode *dvp, const char *name, int namelen, 1473 struct ucred *cred, struct thread *td) 1474{ 1475 caddr_t bpos, dpos; 1476 int error = 0, wccflag = NFSV3_WCCRATTR; 1477 struct mbuf *mreq, *mrep, *md, *mb; 1478 int v3 = NFS_ISV3(dvp); 1479 1480 nfsstats.rpccnt[NFSPROC_REMOVE]++; 1481 mreq = nfsm_reqhead(dvp, NFSPROC_REMOVE, 1482 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen)); 1483 mb = mreq; 1484 bpos = mtod(mb, caddr_t); 1485 nfsm_fhtom(dvp, v3); 1486 nfsm_strtom(name, namelen, NFS_MAXNAMLEN); 1487 nfsm_request(dvp, NFSPROC_REMOVE, td, cred); 1488 if (v3) 1489 nfsm_wcc_data(dvp, wccflag); 1490 m_freem(mrep); 1491nfsmout: 1492 VTONFS(dvp)->n_flag |= NMODIFIED; 1493 if (!wccflag) 1494 VTONFS(dvp)->n_attrstamp = 0; 1495 return (error); 1496} 1497 1498/* 1499 * nfs file rename call 1500 */ 1501static int 1502nfs_rename(struct vop_rename_args *ap) 1503{ 1504 struct vnode *fvp = ap->a_fvp; 1505 struct vnode *tvp = ap->a_tvp; 1506 struct vnode *fdvp = ap->a_fdvp; 1507 struct vnode *tdvp = ap->a_tdvp; 1508 struct componentname *tcnp = ap->a_tcnp; 1509 struct componentname *fcnp = ap->a_fcnp; 1510 int error; 1511 1512#ifndef DIAGNOSTIC 1513 if ((tcnp->cn_flags & HASBUF) == 0 || 1514 (fcnp->cn_flags & HASBUF) == 0) 1515 panic("nfs_rename: no name"); 1516#endif 1517 /* Check for cross-device rename */ 1518 if ((fvp->v_mount != tdvp->v_mount) || 1519 (tvp && (fvp->v_mount != tvp->v_mount))) { 1520 error = EXDEV; 1521 goto out; 1522 } 1523 1524 /* 1525 * We have to flush B_DELWRI data prior to renaming 1526 * the file. If we don't, the delayed-write buffers 1527 * can be flushed out later after the file has gone stale 1528 * under NFSV3. NFSV2 does not have this problem because 1529 * ( as far as I can tell ) it flushes dirty buffers more 1530 * often. 1531 */ 1532 1533 VOP_FSYNC(fvp, fcnp->cn_cred, MNT_WAIT, fcnp->cn_thread); 1534 if (tvp) 1535 VOP_FSYNC(tvp, tcnp->cn_cred, MNT_WAIT, tcnp->cn_thread); 1536 1537 /* 1538 * If the tvp exists and is in use, sillyrename it before doing the 1539 * rename of the new file over it. 1540 * XXX Can't sillyrename a directory. 1541 */ 1542 if (tvp && vrefcnt(tvp) > 1 && !VTONFS(tvp)->n_sillyrename && 1543 tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) { 1544 vput(tvp); 1545 tvp = NULL; 1546 } 1547 1548 error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen, 1549 tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred, 1550 tcnp->cn_thread); 1551 1552 if (fvp->v_type == VDIR) { 1553 if (tvp != NULL && tvp->v_type == VDIR) 1554 cache_purge(tdvp); 1555 cache_purge(fdvp); 1556 } 1557 1558out: 1559 if (tdvp == tvp) 1560 vrele(tdvp); 1561 else 1562 vput(tdvp); 1563 if (tvp) 1564 vput(tvp); 1565 vrele(fdvp); 1566 vrele(fvp); 1567 /* 1568 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. 1569 */ 1570 if (error == ENOENT) 1571 error = 0; 1572 return (error); 1573} 1574 1575/* 1576 * nfs file rename rpc called from nfs_remove() above 1577 */ 1578static int 1579nfs_renameit(struct vnode *sdvp, struct componentname *scnp, 1580 struct sillyrename *sp) 1581{ 1582 1583 return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, sdvp, 1584 sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_thread)); 1585} 1586 1587/* 1588 * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit(). 1589 */ 1590static int 1591nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen, 1592 struct vnode *tdvp, const char *tnameptr, int tnamelen, struct ucred *cred, 1593 struct thread *td) 1594{ 1595 caddr_t bpos, dpos; 1596 int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR; 1597 struct mbuf *mreq, *mrep, *md, *mb; 1598 int v3 = NFS_ISV3(fdvp); 1599 1600 nfsstats.rpccnt[NFSPROC_RENAME]++; 1601 mreq = nfsm_reqhead(fdvp, NFSPROC_RENAME, 1602 (NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) + 1603 nfsm_rndup(tnamelen)); 1604 mb = mreq; 1605 bpos = mtod(mb, caddr_t); 1606 nfsm_fhtom(fdvp, v3); 1607 nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN); 1608 nfsm_fhtom(tdvp, v3); 1609 nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN); 1610 nfsm_request(fdvp, NFSPROC_RENAME, td, cred); 1611 if (v3) { 1612 nfsm_wcc_data(fdvp, fwccflag); 1613 nfsm_wcc_data(tdvp, twccflag); 1614 } 1615 m_freem(mrep); 1616nfsmout: 1617 VTONFS(fdvp)->n_flag |= NMODIFIED; 1618 VTONFS(tdvp)->n_flag |= NMODIFIED; 1619 if (!fwccflag) 1620 VTONFS(fdvp)->n_attrstamp = 0; 1621 if (!twccflag) 1622 VTONFS(tdvp)->n_attrstamp = 0; 1623 return (error); 1624} 1625 1626/* 1627 * nfs hard link create call 1628 */ 1629static int 1630nfs_link(struct vop_link_args *ap) 1631{ 1632 struct vnode *vp = ap->a_vp; 1633 struct vnode *tdvp = ap->a_tdvp; 1634 struct componentname *cnp = ap->a_cnp; 1635 caddr_t bpos, dpos; 1636 int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0; 1637 struct mbuf *mreq, *mrep, *md, *mb; 1638 int v3; 1639 1640 if (vp->v_mount != tdvp->v_mount) { 1641 return (EXDEV); 1642 } 1643 1644 /* 1645 * Push all writes to the server, so that the attribute cache 1646 * doesn't get "out of sync" with the server. 1647 * XXX There should be a better way! 1648 */ 1649 VOP_FSYNC(vp, cnp->cn_cred, MNT_WAIT, cnp->cn_thread); 1650 1651 v3 = NFS_ISV3(vp); 1652 nfsstats.rpccnt[NFSPROC_LINK]++; 1653 mreq = nfsm_reqhead(vp, NFSPROC_LINK, 1654 NFSX_FH(v3)*2 + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); 1655 mb = mreq; 1656 bpos = mtod(mb, caddr_t); 1657 nfsm_fhtom(vp, v3); 1658 nfsm_fhtom(tdvp, v3); 1659 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1660 nfsm_request(vp, NFSPROC_LINK, cnp->cn_thread, cnp->cn_cred); 1661 if (v3) { 1662 nfsm_postop_attr(vp, attrflag); 1663 nfsm_wcc_data(tdvp, wccflag); 1664 } 1665 m_freem(mrep); 1666nfsmout: 1667 VTONFS(tdvp)->n_flag |= NMODIFIED; 1668 if (!attrflag) 1669 VTONFS(vp)->n_attrstamp = 0; 1670 if (!wccflag) 1671 VTONFS(tdvp)->n_attrstamp = 0; 1672 /* 1673 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. 1674 */ 1675 if (error == EEXIST) 1676 error = 0; 1677 return (error); 1678} 1679 1680/* 1681 * nfs symbolic link create call 1682 */ 1683static int 1684nfs_symlink(struct vop_symlink_args *ap) 1685{ 1686 struct vnode *dvp = ap->a_dvp; 1687 struct vattr *vap = ap->a_vap; 1688 struct componentname *cnp = ap->a_cnp; 1689 struct nfsv2_sattr *sp; 1690 caddr_t bpos, dpos; 1691 int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp; 1692 struct mbuf *mreq, *mrep, *md, *mb; 1693 struct vnode *newvp = NULL; 1694 int v3 = NFS_ISV3(dvp); 1695 1696 nfsstats.rpccnt[NFSPROC_SYMLINK]++; 1697 slen = strlen(ap->a_target); 1698 mreq = nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED + 1699 nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3)); 1700 mb = mreq; 1701 bpos = mtod(mb, caddr_t); 1702 nfsm_fhtom(dvp, v3); 1703 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1704 if (v3) { 1705 nfsm_v3attrbuild(vap, FALSE); 1706 } 1707 nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN); 1708 if (!v3) { 1709 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); 1710 sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode); 1711 sp->sa_uid = nfs_xdrneg1; 1712 sp->sa_gid = nfs_xdrneg1; 1713 sp->sa_size = nfs_xdrneg1; 1714 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1715 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1716 } 1717 1718 /* 1719 * Issue the NFS request and get the rpc response. 1720 * 1721 * Only NFSv3 responses returning an error of 0 actually return 1722 * a file handle that can be converted into newvp without having 1723 * to do an extra lookup rpc. 1724 */ 1725 nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_thread, cnp->cn_cred); 1726 if (v3) { 1727 if (error == 0) 1728 nfsm_mtofh(dvp, newvp, v3, gotvp); 1729 nfsm_wcc_data(dvp, wccflag); 1730 } 1731 1732 /* 1733 * out code jumps -> here, mrep is also freed. 1734 */ 1735 1736 m_freem(mrep); 1737nfsmout: 1738 1739 /* 1740 * If we get an EEXIST error, silently convert it to no-error 1741 * in case of an NFS retry. 1742 */ 1743 if (error == EEXIST) 1744 error = 0; 1745 1746 /* 1747 * If we do not have (or no longer have) an error, and we could 1748 * not extract the newvp from the response due to the request being 1749 * NFSv2 or the error being EEXIST. We have to do a lookup in order 1750 * to obtain a newvp to return. 1751 */ 1752 if (error == 0 && newvp == NULL) { 1753 struct nfsnode *np = NULL; 1754 1755 error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen, 1756 cnp->cn_cred, cnp->cn_thread, &np); 1757 if (!error) 1758 newvp = NFSTOV(np); 1759 } 1760 if (error) { 1761 if (newvp) 1762 vput(newvp); 1763 } else { 1764 *ap->a_vpp = newvp; 1765 } 1766 VTONFS(dvp)->n_flag |= NMODIFIED; 1767 if (!wccflag) 1768 VTONFS(dvp)->n_attrstamp = 0; 1769 return (error); 1770} 1771 1772/* 1773 * nfs make dir call 1774 */ 1775static int 1776nfs_mkdir(struct vop_mkdir_args *ap) 1777{ 1778 struct vnode *dvp = ap->a_dvp; 1779 struct vattr *vap = ap->a_vap; 1780 struct componentname *cnp = ap->a_cnp; 1781 struct nfsv2_sattr *sp; 1782 int len; 1783 struct nfsnode *np = NULL; 1784 struct vnode *newvp = NULL; 1785 caddr_t bpos, dpos; 1786 int error = 0, wccflag = NFSV3_WCCRATTR; 1787 int gotvp = 0; 1788 struct mbuf *mreq, *mrep, *md, *mb; 1789 struct vattr vattr; 1790 int v3 = NFS_ISV3(dvp); 1791 1792 if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred, cnp->cn_thread)) != 0) { 1793 return (error); 1794 } 1795 len = cnp->cn_namelen; 1796 nfsstats.rpccnt[NFSPROC_MKDIR]++; 1797 mreq = nfsm_reqhead(dvp, NFSPROC_MKDIR, 1798 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(v3)); 1799 mb = mreq; 1800 bpos = mtod(mb, caddr_t); 1801 nfsm_fhtom(dvp, v3); 1802 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 1803 if (v3) { 1804 nfsm_v3attrbuild(vap, FALSE); 1805 } else { 1806 sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); 1807 sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode); 1808 sp->sa_uid = nfs_xdrneg1; 1809 sp->sa_gid = nfs_xdrneg1; 1810 sp->sa_size = nfs_xdrneg1; 1811 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1812 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1813 } 1814 nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_thread, cnp->cn_cred); 1815 if (!error) 1816 nfsm_mtofh(dvp, newvp, v3, gotvp); 1817 if (v3) 1818 nfsm_wcc_data(dvp, wccflag); 1819 m_freem(mrep); 1820nfsmout: 1821 VTONFS(dvp)->n_flag |= NMODIFIED; 1822 if (!wccflag) 1823 VTONFS(dvp)->n_attrstamp = 0; 1824 /* 1825 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry 1826 * if we can succeed in looking up the directory. 1827 */ 1828 if (error == EEXIST || (!error && !gotvp)) { 1829 if (newvp) { 1830 vrele(newvp); 1831 newvp = NULL; 1832 } 1833 error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred, 1834 cnp->cn_thread, &np); 1835 if (!error) { 1836 newvp = NFSTOV(np); 1837 if (newvp->v_type != VDIR) 1838 error = EEXIST; 1839 } 1840 } 1841 if (error) { 1842 if (newvp) 1843 vrele(newvp); 1844 } else 1845 *ap->a_vpp = newvp; 1846 return (error); 1847} 1848 1849/* 1850 * nfs remove directory call 1851 */ 1852static int 1853nfs_rmdir(struct vop_rmdir_args *ap) 1854{ 1855 struct vnode *vp = ap->a_vp; 1856 struct vnode *dvp = ap->a_dvp; 1857 struct componentname *cnp = ap->a_cnp; 1858 caddr_t bpos, dpos; 1859 int error = 0, wccflag = NFSV3_WCCRATTR; 1860 struct mbuf *mreq, *mrep, *md, *mb; 1861 int v3 = NFS_ISV3(dvp); 1862 1863 if (dvp == vp) 1864 return (EINVAL); 1865 nfsstats.rpccnt[NFSPROC_RMDIR]++; 1866 mreq = nfsm_reqhead(dvp, NFSPROC_RMDIR, 1867 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); 1868 mb = mreq; 1869 bpos = mtod(mb, caddr_t); 1870 nfsm_fhtom(dvp, v3); 1871 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1872 nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_thread, cnp->cn_cred); 1873 if (v3) 1874 nfsm_wcc_data(dvp, wccflag); 1875 m_freem(mrep); 1876nfsmout: 1877 VTONFS(dvp)->n_flag |= NMODIFIED; 1878 if (!wccflag) 1879 VTONFS(dvp)->n_attrstamp = 0; 1880 cache_purge(dvp); 1881 cache_purge(vp); 1882 /* 1883 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. 1884 */ 1885 if (error == ENOENT) 1886 error = 0; 1887 return (error); 1888} 1889 1890/* 1891 * nfs readdir call 1892 */ 1893static int 1894nfs_readdir(struct vop_readdir_args *ap) 1895{ 1896 struct vnode *vp = ap->a_vp; 1897 struct nfsnode *np = VTONFS(vp); 1898 struct uio *uio = ap->a_uio; 1899 int tresid, error; 1900 struct vattr vattr; 1901 1902 if (vp->v_type != VDIR) 1903 return (EPERM); 1904 /* 1905 * First, check for hit on the EOF offset cache 1906 */ 1907 if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset && 1908 (np->n_flag & NMODIFIED) == 0) { 1909 if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_td) == 0 && 1910 np->n_mtime == vattr.va_mtime.tv_sec) { 1911 nfsstats.direofcache_hits++; 1912 return (0); 1913 } 1914 } 1915 1916 /* 1917 * Call nfs_bioread() to do the real work. 1918 */ 1919 tresid = uio->uio_resid; 1920 error = nfs_bioread(vp, uio, 0, ap->a_cred); 1921 1922 if (!error && uio->uio_resid == tresid) 1923 nfsstats.direofcache_misses++; 1924 return (error); 1925} 1926 1927/* 1928 * Readdir rpc call. 1929 * Called from below the buffer cache by nfs_doio(). 1930 */ 1931int 1932nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) 1933{ 1934 int len, left; 1935 struct dirent *dp = NULL; 1936 u_int32_t *tl; 1937 caddr_t cp; 1938 nfsuint64 *cookiep; 1939 caddr_t bpos, dpos; 1940 struct mbuf *mreq, *mrep, *md, *mb; 1941 nfsuint64 cookie; 1942 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 1943 struct nfsnode *dnp = VTONFS(vp); 1944 u_quad_t fileno; 1945 int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1; 1946 int attrflag; 1947 int v3 = NFS_ISV3(vp); 1948 1949#ifndef DIAGNOSTIC 1950 if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) || 1951 (uiop->uio_resid & (DIRBLKSIZ - 1))) 1952 panic("nfs readdirrpc bad uio"); 1953#endif 1954 1955 /* 1956 * If there is no cookie, assume directory was stale. 1957 */ 1958 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0); 1959 if (cookiep) 1960 cookie = *cookiep; 1961 else 1962 return (NFSERR_BAD_COOKIE); 1963 /* 1964 * Loop around doing readdir rpc's of size nm_readdirsize 1965 * truncated to a multiple of DIRBLKSIZ. 1966 * The stopping criteria is EOF or buffer full. 1967 */ 1968 while (more_dirs && bigenough) { 1969 nfsstats.rpccnt[NFSPROC_READDIR]++; 1970 mreq = nfsm_reqhead(vp, NFSPROC_READDIR, NFSX_FH(v3) + 1971 NFSX_READDIR(v3)); 1972 mb = mreq; 1973 bpos = mtod(mb, caddr_t); 1974 nfsm_fhtom(vp, v3); 1975 if (v3) { 1976 tl = nfsm_build(u_int32_t *, 5 * NFSX_UNSIGNED); 1977 *tl++ = cookie.nfsuquad[0]; 1978 *tl++ = cookie.nfsuquad[1]; 1979 *tl++ = dnp->n_cookieverf.nfsuquad[0]; 1980 *tl++ = dnp->n_cookieverf.nfsuquad[1]; 1981 } else { 1982 tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED); 1983 *tl++ = cookie.nfsuquad[0]; 1984 } 1985 *tl = txdr_unsigned(nmp->nm_readdirsize); 1986 nfsm_request(vp, NFSPROC_READDIR, uiop->uio_td, cred); 1987 if (v3) { 1988 nfsm_postop_attr(vp, attrflag); 1989 if (!error) { 1990 tl = nfsm_dissect(u_int32_t *, 1991 2 * NFSX_UNSIGNED); 1992 dnp->n_cookieverf.nfsuquad[0] = *tl++; 1993 dnp->n_cookieverf.nfsuquad[1] = *tl; 1994 } else { 1995 m_freem(mrep); 1996 goto nfsmout; 1997 } 1998 } 1999 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); 2000 more_dirs = fxdr_unsigned(int, *tl); 2001 2002 /* loop thru the dir entries, doctoring them to 4bsd form */ 2003 while (more_dirs && bigenough) { 2004 if (v3) { 2005 tl = nfsm_dissect(u_int32_t *, 2006 3 * NFSX_UNSIGNED); 2007 fileno = fxdr_hyper(tl); 2008 len = fxdr_unsigned(int, *(tl + 2)); 2009 } else { 2010 tl = nfsm_dissect(u_int32_t *, 2011 2 * NFSX_UNSIGNED); 2012 fileno = fxdr_unsigned(u_quad_t, *tl++); 2013 len = fxdr_unsigned(int, *tl); 2014 } 2015 if (len <= 0 || len > NFS_MAXNAMLEN) { 2016 error = EBADRPC; 2017 m_freem(mrep); 2018 goto nfsmout; 2019 } 2020 tlen = nfsm_rndup(len); 2021 if (tlen == len) 2022 tlen += 4; /* To ensure null termination */ 2023 left = DIRBLKSIZ - blksiz; 2024 if ((tlen + DIRHDSIZ) > left) { 2025 dp->d_reclen += left; 2026 uiop->uio_iov->iov_base = 2027 (char *)uiop->uio_iov->iov_base + left; 2028 uiop->uio_iov->iov_len -= left; 2029 uiop->uio_offset += left; 2030 uiop->uio_resid -= left; 2031 blksiz = 0; 2032 } 2033 if ((tlen + DIRHDSIZ) > uiop->uio_resid) 2034 bigenough = 0; 2035 if (bigenough) { 2036 dp = (struct dirent *)uiop->uio_iov->iov_base; 2037 dp->d_fileno = (int)fileno; 2038 dp->d_namlen = len; 2039 dp->d_reclen = tlen + DIRHDSIZ; 2040 dp->d_type = DT_UNKNOWN; 2041 blksiz += dp->d_reclen; 2042 if (blksiz == DIRBLKSIZ) 2043 blksiz = 0; 2044 uiop->uio_offset += DIRHDSIZ; 2045 uiop->uio_resid -= DIRHDSIZ; 2046 uiop->uio_iov->iov_base = 2047 (char *)uiop->uio_iov->iov_base + DIRHDSIZ; 2048 uiop->uio_iov->iov_len -= DIRHDSIZ; 2049 nfsm_mtouio(uiop, len); 2050 cp = uiop->uio_iov->iov_base; 2051 tlen -= len; 2052 *cp = '\0'; /* null terminate */ 2053 uiop->uio_iov->iov_base = 2054 (char *)uiop->uio_iov->iov_base + tlen; 2055 uiop->uio_iov->iov_len -= tlen; 2056 uiop->uio_offset += tlen; 2057 uiop->uio_resid -= tlen; 2058 } else 2059 nfsm_adv(nfsm_rndup(len)); 2060 if (v3) { 2061 tl = nfsm_dissect(u_int32_t *, 2062 3 * NFSX_UNSIGNED); 2063 } else { 2064 tl = nfsm_dissect(u_int32_t *, 2065 2 * NFSX_UNSIGNED); 2066 } 2067 if (bigenough) { 2068 cookie.nfsuquad[0] = *tl++; 2069 if (v3) 2070 cookie.nfsuquad[1] = *tl++; 2071 } else if (v3) 2072 tl += 2; 2073 else 2074 tl++; 2075 more_dirs = fxdr_unsigned(int, *tl); 2076 } 2077 /* 2078 * If at end of rpc data, get the eof boolean 2079 */ 2080 if (!more_dirs) { 2081 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); 2082 more_dirs = (fxdr_unsigned(int, *tl) == 0); 2083 } 2084 m_freem(mrep); 2085 } 2086 /* 2087 * Fill last record, iff any, out to a multiple of DIRBLKSIZ 2088 * by increasing d_reclen for the last record. 2089 */ 2090 if (blksiz > 0) { 2091 left = DIRBLKSIZ - blksiz; 2092 dp->d_reclen += left; 2093 uiop->uio_iov->iov_base = 2094 (char *)uiop->uio_iov->iov_base + left; 2095 uiop->uio_iov->iov_len -= left; 2096 uiop->uio_offset += left; 2097 uiop->uio_resid -= left; 2098 } 2099 2100 /* 2101 * We are now either at the end of the directory or have filled the 2102 * block. 2103 */ 2104 if (bigenough) 2105 dnp->n_direofoffset = uiop->uio_offset; 2106 else { 2107 if (uiop->uio_resid > 0) 2108 printf("EEK! readdirrpc resid > 0\n"); 2109 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1); 2110 *cookiep = cookie; 2111 } 2112nfsmout: 2113 return (error); 2114} 2115 2116/* 2117 * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc(). 2118 */ 2119int 2120nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) 2121{ 2122 int len, left; 2123 struct dirent *dp; 2124 u_int32_t *tl; 2125 caddr_t cp; 2126 struct vnode *newvp; 2127 nfsuint64 *cookiep; 2128 caddr_t bpos, dpos, dpossav1, dpossav2; 2129 struct mbuf *mreq, *mrep, *md, *mb, *mdsav1, *mdsav2; 2130 struct nameidata nami, *ndp = &nami; 2131 struct componentname *cnp = &ndp->ni_cnd; 2132 nfsuint64 cookie; 2133 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2134 struct nfsnode *dnp = VTONFS(vp), *np; 2135 nfsfh_t *fhp; 2136 u_quad_t fileno; 2137 int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i; 2138 int attrflag, fhsize; 2139 2140#ifndef nolint 2141 dp = NULL; 2142#endif 2143#ifndef DIAGNOSTIC 2144 if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) || 2145 (uiop->uio_resid & (DIRBLKSIZ - 1))) 2146 panic("nfs readdirplusrpc bad uio"); 2147#endif 2148 ndp->ni_dvp = vp; 2149 newvp = NULLVP; 2150 2151 /* 2152 * If there is no cookie, assume directory was stale. 2153 */ 2154 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0); 2155 if (cookiep) 2156 cookie = *cookiep; 2157 else 2158 return (NFSERR_BAD_COOKIE); 2159 /* 2160 * Loop around doing readdir rpc's of size nm_readdirsize 2161 * truncated to a multiple of DIRBLKSIZ. 2162 * The stopping criteria is EOF or buffer full. 2163 */ 2164 while (more_dirs && bigenough) { 2165 nfsstats.rpccnt[NFSPROC_READDIRPLUS]++; 2166 mreq = nfsm_reqhead(vp, NFSPROC_READDIRPLUS, 2167 NFSX_FH(1) + 6 * NFSX_UNSIGNED); 2168 mb = mreq; 2169 bpos = mtod(mb, caddr_t); 2170 nfsm_fhtom(vp, 1); 2171 tl = nfsm_build(u_int32_t *, 6 * NFSX_UNSIGNED); 2172 *tl++ = cookie.nfsuquad[0]; 2173 *tl++ = cookie.nfsuquad[1]; 2174 *tl++ = dnp->n_cookieverf.nfsuquad[0]; 2175 *tl++ = dnp->n_cookieverf.nfsuquad[1]; 2176 *tl++ = txdr_unsigned(nmp->nm_readdirsize); 2177 *tl = txdr_unsigned(nmp->nm_rsize); 2178 nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_td, cred); 2179 nfsm_postop_attr(vp, attrflag); 2180 if (error) { 2181 m_freem(mrep); 2182 goto nfsmout; 2183 } 2184 tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED); 2185 dnp->n_cookieverf.nfsuquad[0] = *tl++; 2186 dnp->n_cookieverf.nfsuquad[1] = *tl++; 2187 more_dirs = fxdr_unsigned(int, *tl); 2188 2189 /* loop thru the dir entries, doctoring them to 4bsd form */ 2190 while (more_dirs && bigenough) { 2191 tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED); 2192 fileno = fxdr_hyper(tl); 2193 len = fxdr_unsigned(int, *(tl + 2)); 2194 if (len <= 0 || len > NFS_MAXNAMLEN) { 2195 error = EBADRPC; 2196 m_freem(mrep); 2197 goto nfsmout; 2198 } 2199 tlen = nfsm_rndup(len); 2200 if (tlen == len) 2201 tlen += 4; /* To ensure null termination*/ 2202 left = DIRBLKSIZ - blksiz; 2203 if ((tlen + DIRHDSIZ) > left) { 2204 dp->d_reclen += left; 2205 uiop->uio_iov->iov_base = 2206 (char *)uiop->uio_iov->iov_base + left; 2207 uiop->uio_iov->iov_len -= left; 2208 uiop->uio_offset += left; 2209 uiop->uio_resid -= left; 2210 blksiz = 0; 2211 } 2212 if ((tlen + DIRHDSIZ) > uiop->uio_resid) 2213 bigenough = 0; 2214 if (bigenough) { 2215 dp = (struct dirent *)uiop->uio_iov->iov_base; 2216 dp->d_fileno = (int)fileno; 2217 dp->d_namlen = len; 2218 dp->d_reclen = tlen + DIRHDSIZ; 2219 dp->d_type = DT_UNKNOWN; 2220 blksiz += dp->d_reclen; 2221 if (blksiz == DIRBLKSIZ) 2222 blksiz = 0; 2223 uiop->uio_offset += DIRHDSIZ; 2224 uiop->uio_resid -= DIRHDSIZ; 2225 uiop->uio_iov->iov_base = 2226 (char *)uiop->uio_iov->iov_base + DIRHDSIZ; 2227 uiop->uio_iov->iov_len -= DIRHDSIZ; 2228 cnp->cn_nameptr = uiop->uio_iov->iov_base; 2229 cnp->cn_namelen = len; 2230 nfsm_mtouio(uiop, len); 2231 cp = uiop->uio_iov->iov_base; 2232 tlen -= len; 2233 *cp = '\0'; 2234 uiop->uio_iov->iov_base = 2235 (char *)uiop->uio_iov->iov_base + tlen; 2236 uiop->uio_iov->iov_len -= tlen; 2237 uiop->uio_offset += tlen; 2238 uiop->uio_resid -= tlen; 2239 } else 2240 nfsm_adv(nfsm_rndup(len)); 2241 tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED); 2242 if (bigenough) { 2243 cookie.nfsuquad[0] = *tl++; 2244 cookie.nfsuquad[1] = *tl++; 2245 } else 2246 tl += 2; 2247 2248 /* 2249 * Since the attributes are before the file handle 2250 * (sigh), we must skip over the attributes and then 2251 * come back and get them. 2252 */ 2253 attrflag = fxdr_unsigned(int, *tl); 2254 if (attrflag) { 2255 dpossav1 = dpos; 2256 mdsav1 = md; 2257 nfsm_adv(NFSX_V3FATTR); 2258 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); 2259 doit = fxdr_unsigned(int, *tl); 2260 if (doit) { 2261 nfsm_getfh(fhp, fhsize, 1); 2262 if (NFS_CMPFH(dnp, fhp, fhsize)) { 2263 VREF(vp); 2264 newvp = vp; 2265 np = dnp; 2266 } else { 2267 error = nfs_nget(vp->v_mount, fhp, 2268 fhsize, &np); 2269 if (error) 2270 doit = 0; 2271 else 2272 newvp = NFSTOV(np); 2273 } 2274 } 2275 if (doit && bigenough) { 2276 dpossav2 = dpos; 2277 dpos = dpossav1; 2278 mdsav2 = md; 2279 md = mdsav1; 2280 nfsm_loadattr(newvp, NULL); 2281 dpos = dpossav2; 2282 md = mdsav2; 2283 dp->d_type = 2284 IFTODT(VTTOIF(np->n_vattr.va_type)); 2285 ndp->ni_vp = newvp; 2286 cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp); 2287 } 2288 } else { 2289 /* Just skip over the file handle */ 2290 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); 2291 i = fxdr_unsigned(int, *tl); 2292 nfsm_adv(nfsm_rndup(i)); 2293 } 2294 if (newvp != NULLVP) { 2295 if (newvp == vp) 2296 vrele(newvp); 2297 else 2298 vput(newvp); 2299 newvp = NULLVP; 2300 } 2301 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); 2302 more_dirs = fxdr_unsigned(int, *tl); 2303 } 2304 /* 2305 * If at end of rpc data, get the eof boolean 2306 */ 2307 if (!more_dirs) { 2308 tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); 2309 more_dirs = (fxdr_unsigned(int, *tl) == 0); 2310 } 2311 m_freem(mrep); 2312 } 2313 /* 2314 * Fill last record, iff any, out to a multiple of DIRBLKSIZ 2315 * by increasing d_reclen for the last record. 2316 */ 2317 if (blksiz > 0) { 2318 left = DIRBLKSIZ - blksiz; 2319 dp->d_reclen += left; 2320 uiop->uio_iov->iov_base = 2321 (char *)uiop->uio_iov->iov_base + left; 2322 uiop->uio_iov->iov_len -= left; 2323 uiop->uio_offset += left; 2324 uiop->uio_resid -= left; 2325 } 2326 2327 /* 2328 * We are now either at the end of the directory or have filled the 2329 * block. 2330 */ 2331 if (bigenough) 2332 dnp->n_direofoffset = uiop->uio_offset; 2333 else { 2334 if (uiop->uio_resid > 0) 2335 printf("EEK! readdirplusrpc resid > 0\n"); 2336 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1); 2337 *cookiep = cookie; 2338 } 2339nfsmout: 2340 if (newvp != NULLVP) { 2341 if (newvp == vp) 2342 vrele(newvp); 2343 else 2344 vput(newvp); 2345 newvp = NULLVP; 2346 } 2347 return (error); 2348} 2349 2350/* 2351 * Silly rename. To make the NFS filesystem that is stateless look a little 2352 * more like the "ufs" a remove of an active vnode is translated to a rename 2353 * to a funny looking filename that is removed by nfs_inactive on the 2354 * nfsnode. There is the potential for another process on a different client 2355 * to create the same funny name between the nfs_lookitup() fails and the 2356 * nfs_rename() completes, but... 2357 */ 2358static int 2359nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 2360{ 2361 struct sillyrename *sp; 2362 struct nfsnode *np; 2363 int error; 2364 short pid; 2365 2366 cache_purge(dvp); 2367 np = VTONFS(vp); 2368#ifndef DIAGNOSTIC 2369 if (vp->v_type == VDIR) 2370 panic("nfs: sillyrename dir"); 2371#endif 2372 MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename), 2373 M_NFSREQ, M_WAITOK); 2374 sp->s_cred = crhold(cnp->cn_cred); 2375 sp->s_dvp = dvp; 2376 VREF(dvp); 2377 2378 /* Fudge together a funny name */ 2379 pid = cnp->cn_thread->td_proc->p_pid; 2380 sp->s_namlen = sprintf(sp->s_name, ".nfsA%04x4.4", pid); 2381 2382 /* Try lookitups until we get one that isn't there */ 2383 while (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2384 cnp->cn_thread, NULL) == 0) { 2385 sp->s_name[4]++; 2386 if (sp->s_name[4] > 'z') { 2387 error = EINVAL; 2388 goto bad; 2389 } 2390 } 2391 error = nfs_renameit(dvp, cnp, sp); 2392 if (error) 2393 goto bad; 2394 error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2395 cnp->cn_thread, &np); 2396 np->n_sillyrename = sp; 2397 return (0); 2398bad: 2399 vrele(sp->s_dvp); 2400 crfree(sp->s_cred); 2401 free((caddr_t)sp, M_NFSREQ); 2402 return (error); 2403} 2404 2405/* 2406 * Look up a file name and optionally either update the file handle or 2407 * allocate an nfsnode, depending on the value of npp. 2408 * npp == NULL --> just do the lookup 2409 * *npp == NULL --> allocate a new nfsnode and make sure attributes are 2410 * handled too 2411 * *npp != NULL --> update the file handle in the vnode 2412 */ 2413static int 2414nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred, 2415 struct thread *td, struct nfsnode **npp) 2416{ 2417 struct vnode *newvp = NULL; 2418 struct nfsnode *np, *dnp = VTONFS(dvp); 2419 caddr_t bpos, dpos; 2420 int error = 0, fhlen, attrflag; 2421 struct mbuf *mreq, *mrep, *md, *mb; 2422 nfsfh_t *nfhp; 2423 int v3 = NFS_ISV3(dvp); 2424 2425 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 2426 mreq = nfsm_reqhead(dvp, NFSPROC_LOOKUP, 2427 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); 2428 mb = mreq; 2429 bpos = mtod(mb, caddr_t); 2430 nfsm_fhtom(dvp, v3); 2431 nfsm_strtom(name, len, NFS_MAXNAMLEN); 2432 nfsm_request(dvp, NFSPROC_LOOKUP, td, cred); 2433 if (npp && !error) { 2434 nfsm_getfh(nfhp, fhlen, v3); 2435 if (*npp) { 2436 np = *npp; 2437 if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) { 2438 free((caddr_t)np->n_fhp, M_NFSBIGFH); 2439 np->n_fhp = &np->n_fh; 2440 } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH) 2441 np->n_fhp =(nfsfh_t *)malloc(fhlen, M_NFSBIGFH, M_WAITOK); 2442 bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen); 2443 np->n_fhsize = fhlen; 2444 newvp = NFSTOV(np); 2445 } else if (NFS_CMPFH(dnp, nfhp, fhlen)) { 2446 VREF(dvp); 2447 newvp = dvp; 2448 } else { 2449 error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np); 2450 if (error) { 2451 m_freem(mrep); 2452 return (error); 2453 } 2454 newvp = NFSTOV(np); 2455 } 2456 if (v3) { 2457 nfsm_postop_attr(newvp, attrflag); 2458 if (!attrflag && *npp == NULL) { 2459 m_freem(mrep); 2460 if (newvp == dvp) 2461 vrele(newvp); 2462 else 2463 vput(newvp); 2464 return (ENOENT); 2465 } 2466 } else 2467 nfsm_loadattr(newvp, NULL); 2468 } 2469 m_freem(mrep); 2470nfsmout: 2471 if (npp && *npp == NULL) { 2472 if (error) { 2473 if (newvp) { 2474 if (newvp == dvp) 2475 vrele(newvp); 2476 else 2477 vput(newvp); 2478 } 2479 } else 2480 *npp = np; 2481 } 2482 return (error); 2483} 2484 2485/* 2486 * Nfs Version 3 commit rpc 2487 */ 2488int 2489nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred, 2490 struct thread *td) 2491{ 2492 u_int32_t *tl; 2493 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2494 caddr_t bpos, dpos; 2495 int error = 0, wccflag = NFSV3_WCCRATTR; 2496 struct mbuf *mreq, *mrep, *md, *mb; 2497 2498 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) 2499 return (0); 2500 nfsstats.rpccnt[NFSPROC_COMMIT]++; 2501 mreq = nfsm_reqhead(vp, NFSPROC_COMMIT, NFSX_FH(1)); 2502 mb = mreq; 2503 bpos = mtod(mb, caddr_t); 2504 nfsm_fhtom(vp, 1); 2505 tl = nfsm_build(u_int32_t *, 3 * NFSX_UNSIGNED); 2506 txdr_hyper(offset, tl); 2507 tl += 2; 2508 *tl = txdr_unsigned(cnt); 2509 nfsm_request(vp, NFSPROC_COMMIT, td, cred); 2510 nfsm_wcc_data(vp, wccflag); 2511 if (!error) { 2512 tl = nfsm_dissect(u_int32_t *, NFSX_V3WRITEVERF); 2513 if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl, 2514 NFSX_V3WRITEVERF)) { 2515 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 2516 NFSX_V3WRITEVERF); 2517 error = NFSERR_STALEWRITEVERF; 2518 } 2519 } 2520 m_freem(mrep); 2521nfsmout: 2522 return (error); 2523} 2524 2525/* 2526 * Strategy routine. 2527 * For async requests when nfsiod(s) are running, queue the request by 2528 * calling nfs_asyncio(), otherwise just all nfs_doio() to do the 2529 * request. 2530 */ 2531static int 2532nfs_strategy(struct vop_strategy_args *ap) 2533{ 2534 struct buf *bp = ap->a_bp; 2535 struct ucred *cr; 2536 struct thread *td; 2537 int error = 0; 2538 2539 KASSERT(!(bp->b_flags & B_DONE), ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp)); 2540 KASSERT(BUF_REFCNT(bp) > 0, ("nfs_strategy: buffer %p not locked", bp)); 2541 2542 if (bp->b_flags & B_PHYS) 2543 panic("nfs physio"); 2544 2545 if (bp->b_flags & B_ASYNC) 2546 td = NULL; 2547 else 2548 td = curthread; /* XXX */ 2549 2550 if (bp->b_iocmd == BIO_READ) 2551 cr = bp->b_rcred; 2552 else 2553 cr = bp->b_wcred; 2554 2555 /* 2556 * If the op is asynchronous and an i/o daemon is waiting 2557 * queue the request, wake it up and wait for completion 2558 * otherwise just do it ourselves. 2559 */ 2560 if ((bp->b_flags & B_ASYNC) == 0 || 2561 nfs_asyncio(bp, NOCRED, td)) 2562 error = nfs_doio(bp, cr, td); 2563 return (error); 2564} 2565 2566/* 2567 * fsync vnode op. Just call nfs_flush() with commit == 1. 2568 */ 2569/* ARGSUSED */ 2570static int 2571nfs_fsync(struct vop_fsync_args *ap) 2572{ 2573 2574 return (nfs_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_td, 1)); 2575} 2576 2577/* 2578 * Flush all the blocks associated with a vnode. 2579 * Walk through the buffer pool and push any dirty pages 2580 * associated with the vnode. 2581 */ 2582static int 2583nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td, 2584 int commit) 2585{ 2586 struct nfsnode *np = VTONFS(vp); 2587 struct buf *bp; 2588 int i; 2589 struct buf *nbp; 2590 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2591 int s, error = 0, slptimeo = 0, slpflag = 0, retv, bvecpos; 2592 int passone = 1; 2593 u_quad_t off, endoff, toff; 2594 struct ucred* wcred = NULL; 2595 struct buf **bvec = NULL; 2596#ifndef NFS_COMMITBVECSIZ 2597#define NFS_COMMITBVECSIZ 20 2598#endif 2599 struct buf *bvec_on_stack[NFS_COMMITBVECSIZ]; 2600 int bvecsize = 0, bveccount; 2601 2602 if (nmp->nm_flag & NFSMNT_INT) 2603 slpflag = PCATCH; 2604 if (!commit) 2605 passone = 0; 2606 /* 2607 * A b_flags == (B_DELWRI | B_NEEDCOMMIT) block has been written to the 2608 * server, but nas not been committed to stable storage on the server 2609 * yet. On the first pass, the byte range is worked out and the commit 2610 * rpc is done. On the second pass, nfs_writebp() is called to do the 2611 * job. 2612 */ 2613again: 2614 off = (u_quad_t)-1; 2615 endoff = 0; 2616 bvecpos = 0; 2617 if (NFS_ISV3(vp) && commit) { 2618 s = splbio(); 2619 if (bvec != NULL && bvec != bvec_on_stack) 2620 free(bvec, M_TEMP); 2621 /* 2622 * Count up how many buffers waiting for a commit. 2623 */ 2624 bveccount = 0; 2625 VI_LOCK(vp); 2626 for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { 2627 nbp = TAILQ_NEXT(bp, b_vnbufs); 2628 if (BUF_REFCNT(bp) == 0 && 2629 (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) 2630 == (B_DELWRI | B_NEEDCOMMIT)) 2631 bveccount++; 2632 } 2633 /* 2634 * Allocate space to remember the list of bufs to commit. It is 2635 * important to use M_NOWAIT here to avoid a race with nfs_write. 2636 * If we can't get memory (for whatever reason), we will end up 2637 * committing the buffers one-by-one in the loop below. 2638 */ 2639 if (bveccount > NFS_COMMITBVECSIZ) { 2640 /* 2641 * Release the vnode interlock to avoid a lock 2642 * order reversal. 2643 */ 2644 VI_UNLOCK(vp); 2645 bvec = (struct buf **) 2646 malloc(bveccount * sizeof(struct buf *), 2647 M_TEMP, M_NOWAIT); 2648 VI_LOCK(vp); 2649 if (bvec == NULL) { 2650 bvec = bvec_on_stack; 2651 bvecsize = NFS_COMMITBVECSIZ; 2652 } else 2653 bvecsize = bveccount; 2654 } else { 2655 bvec = bvec_on_stack; 2656 bvecsize = NFS_COMMITBVECSIZ; 2657 } 2658 for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { 2659 if (bvecpos >= bvecsize) 2660 break; 2661 if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != 2662 (B_DELWRI | B_NEEDCOMMIT) || 2663 BUF_LOCK(bp, 2664 LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, 2665 VI_MTX(vp))) { 2666 VI_LOCK(vp); 2667 nbp = TAILQ_NEXT(bp, b_vnbufs); 2668 continue; 2669 } 2670 bremfree(bp); 2671 /* 2672 * Work out if all buffers are using the same cred 2673 * so we can deal with them all with one commit. 2674 * 2675 * NOTE: we are not clearing B_DONE here, so we have 2676 * to do it later on in this routine if we intend to 2677 * initiate I/O on the bp. 2678 * 2679 * Note: to avoid loopback deadlocks, we do not 2680 * assign b_runningbufspace. 2681 */ 2682 if (wcred == NULL) 2683 wcred = bp->b_wcred; 2684 else if (wcred != bp->b_wcred) 2685 wcred = NOCRED; 2686 bp->b_flags |= B_WRITEINPROG; 2687 vfs_busy_pages(bp, 1); 2688 2689 VI_LOCK(vp); 2690 /* 2691 * bp is protected by being locked, but nbp is not 2692 * and vfs_busy_pages() may sleep. We have to 2693 * recalculate nbp. 2694 */ 2695 nbp = TAILQ_NEXT(bp, b_vnbufs); 2696 2697 /* 2698 * A list of these buffers is kept so that the 2699 * second loop knows which buffers have actually 2700 * been committed. This is necessary, since there 2701 * may be a race between the commit rpc and new 2702 * uncommitted writes on the file. 2703 */ 2704 bvec[bvecpos++] = bp; 2705 toff = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + 2706 bp->b_dirtyoff; 2707 if (toff < off) 2708 off = toff; 2709 toff += (u_quad_t)(bp->b_dirtyend - bp->b_dirtyoff); 2710 if (toff > endoff) 2711 endoff = toff; 2712 } 2713 splx(s); 2714 VI_UNLOCK(vp); 2715 } 2716 if (bvecpos > 0) { 2717 /* 2718 * Commit data on the server, as required. 2719 * If all bufs are using the same wcred, then use that with 2720 * one call for all of them, otherwise commit each one 2721 * separately. 2722 */ 2723 if (wcred != NOCRED) 2724 retv = nfs_commit(vp, off, (int)(endoff - off), 2725 wcred, td); 2726 else { 2727 retv = 0; 2728 for (i = 0; i < bvecpos; i++) { 2729 off_t off, size; 2730 bp = bvec[i]; 2731 off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + 2732 bp->b_dirtyoff; 2733 size = (u_quad_t)(bp->b_dirtyend 2734 - bp->b_dirtyoff); 2735 retv = nfs_commit(vp, off, (int)size, 2736 bp->b_wcred, td); 2737 if (retv) break; 2738 } 2739 } 2740 2741 if (retv == NFSERR_STALEWRITEVERF) 2742 nfs_clearcommit(vp->v_mount); 2743 2744 /* 2745 * Now, either mark the blocks I/O done or mark the 2746 * blocks dirty, depending on whether the commit 2747 * succeeded. 2748 */ 2749 for (i = 0; i < bvecpos; i++) { 2750 bp = bvec[i]; 2751 bp->b_flags &= ~(B_NEEDCOMMIT | B_WRITEINPROG | B_CLUSTEROK); 2752 if (retv) { 2753 /* 2754 * Error, leave B_DELWRI intact 2755 */ 2756 vfs_unbusy_pages(bp); 2757 brelse(bp); 2758 } else { 2759 /* 2760 * Success, remove B_DELWRI ( bundirty() ). 2761 * 2762 * b_dirtyoff/b_dirtyend seem to be NFS 2763 * specific. We should probably move that 2764 * into bundirty(). XXX 2765 */ 2766 s = splbio(); 2767 VI_LOCK(vp); 2768 vp->v_numoutput++; 2769 VI_UNLOCK(vp); 2770 bp->b_flags |= B_ASYNC; 2771 bundirty(bp); 2772 bp->b_flags &= ~B_DONE; 2773 bp->b_ioflags &= ~BIO_ERROR; 2774 bp->b_dirtyoff = bp->b_dirtyend = 0; 2775 splx(s); 2776 bufdone(bp); 2777 } 2778 } 2779 } 2780 2781 /* 2782 * Start/do any write(s) that are required. 2783 */ 2784loop: 2785 s = splbio(); 2786 VI_LOCK(vp); 2787 for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { 2788 nbp = TAILQ_NEXT(bp, b_vnbufs); 2789 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) { 2790 if (waitfor != MNT_WAIT || passone) 2791 continue; 2792 2793 error = BUF_TIMELOCK(bp, 2794 LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, 2795 VI_MTX(vp), "nfsfsync", slpflag, slptimeo); 2796 splx(s); 2797 if (error == 0) 2798 panic("nfs_fsync: inconsistent lock"); 2799 if (error == ENOLCK) 2800 goto loop; 2801 if (nfs_sigintr(nmp, NULL, td)) { 2802 error = EINTR; 2803 goto done; 2804 } 2805 if (slpflag == PCATCH) { 2806 slpflag = 0; 2807 slptimeo = 2 * hz; 2808 } 2809 goto loop; 2810 } 2811 if ((bp->b_flags & B_DELWRI) == 0) 2812 panic("nfs_fsync: not dirty"); 2813 if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) { 2814 BUF_UNLOCK(bp); 2815 VI_LOCK(vp); 2816 continue; 2817 } 2818 bremfree(bp); 2819 if (passone || !commit) 2820 bp->b_flags |= B_ASYNC; 2821 else 2822 bp->b_flags |= B_ASYNC | B_WRITEINPROG; 2823 splx(s); 2824 BUF_WRITE(bp); 2825 goto loop; 2826 } 2827 splx(s); 2828 if (passone) { 2829 passone = 0; 2830 VI_UNLOCK(vp); 2831 goto again; 2832 } 2833 if (waitfor == MNT_WAIT) { 2834 while (vp->v_numoutput) { 2835 vp->v_iflag |= VI_BWAIT; 2836 error = msleep((caddr_t)&vp->v_numoutput, VI_MTX(vp), 2837 slpflag | (PRIBIO + 1), "nfsfsync", slptimeo); 2838 if (error) { 2839 if (nfs_sigintr(nmp, NULL, td)) { 2840 VI_UNLOCK(vp); 2841 error = EINTR; 2842 goto done; 2843 } 2844 if (slpflag == PCATCH) { 2845 slpflag = 0; 2846 slptimeo = 2 * hz; 2847 } 2848 } 2849 } 2850 if (!TAILQ_EMPTY(&vp->v_dirtyblkhd) && commit) { 2851 VI_UNLOCK(vp); 2852 goto loop; 2853 } 2854 } 2855 VI_UNLOCK(vp); 2856 if (np->n_flag & NWRITEERR) { 2857 error = np->n_error; 2858 np->n_flag &= ~NWRITEERR; 2859 } 2860done: 2861 if (bvec != NULL && bvec != bvec_on_stack) 2862 free(bvec, M_TEMP); 2863 return (error); 2864} 2865 2866/* 2867 * NFS advisory byte-level locks. 2868 */ 2869static int 2870nfs_advlock(struct vop_advlock_args *ap) 2871{ 2872 2873 if ((VFSTONFS(ap->a_vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { 2874 struct nfsnode *np = VTONFS(ap->a_vp); 2875 2876 return (lf_advlock(ap, &(np->n_lockf), np->n_size)); 2877 } 2878 return (nfs_dolock(ap)); 2879} 2880 2881/* 2882 * Print out the contents of an nfsnode. 2883 */ 2884static int 2885nfs_print(struct vop_print_args *ap) 2886{ 2887 struct vnode *vp = ap->a_vp; 2888 struct nfsnode *np = VTONFS(vp); 2889 2890 printf("tag %s fileid %ld fsid 0x%x", 2891 vp->v_tag, np->n_vattr.va_fileid, np->n_vattr.va_fsid); 2892 if (vp->v_type == VFIFO) 2893 fifo_printinfo(vp); 2894 printf("\n"); 2895 return (0); 2896} 2897 2898/* 2899 * This is the "real" nfs::bwrite(struct buf*). 2900 * B_WRITEINPROG isn't set unless the force flag is one and it 2901 * handles the B_NEEDCOMMIT flag. 2902 * We set B_CACHE if this is a VMIO buffer. 2903 */ 2904int 2905nfs_writebp(struct buf *bp, int force, struct thread *td) 2906{ 2907 int s; 2908 int oldflags = bp->b_flags; 2909#if 0 2910 int retv = 1; 2911 off_t off; 2912#endif 2913 2914 if (BUF_REFCNT(bp) == 0) 2915 panic("bwrite: buffer is not locked???"); 2916 2917 if (bp->b_flags & B_INVAL) { 2918 brelse(bp); 2919 return(0); 2920 } 2921 2922 bp->b_flags |= B_CACHE; 2923 2924 /* 2925 * Undirty the bp. We will redirty it later if the I/O fails. 2926 */ 2927 2928 s = splbio(); 2929 bundirty(bp); 2930 bp->b_flags &= ~B_DONE; 2931 bp->b_ioflags &= ~BIO_ERROR; 2932 bp->b_iocmd = BIO_WRITE; 2933 2934 VI_LOCK(bp->b_vp); 2935 bp->b_vp->v_numoutput++; 2936 VI_UNLOCK(bp->b_vp); 2937 curthread->td_proc->p_stats->p_ru.ru_oublock++; 2938 splx(s); 2939 2940 /* 2941 * Note: to avoid loopback deadlocks, we do not 2942 * assign b_runningbufspace. 2943 */ 2944 vfs_busy_pages(bp, 1); 2945 2946 if (force) 2947 bp->b_flags |= B_WRITEINPROG; 2948 BUF_KERNPROC(bp); 2949 VOP_STRATEGY(bp->b_vp, bp); 2950 2951 if( (oldflags & B_ASYNC) == 0) { 2952 int rtval = bufwait(bp); 2953 2954 if (oldflags & B_DELWRI) { 2955 s = splbio(); 2956 reassignbuf(bp, bp->b_vp); 2957 splx(s); 2958 } 2959 2960 brelse(bp); 2961 return (rtval); 2962 } 2963 2964 return (0); 2965} 2966 2967/* 2968 * nfs special file access vnode op. 2969 * Essentially just get vattr and then imitate iaccess() since the device is 2970 * local to the client. 2971 */ 2972static int 2973nfsspec_access(struct vop_access_args *ap) 2974{ 2975 struct vattr *vap; 2976 gid_t *gp; 2977 struct ucred *cred = ap->a_cred; 2978 struct vnode *vp = ap->a_vp; 2979 mode_t mode = ap->a_mode; 2980 struct vattr vattr; 2981 int i; 2982 int error; 2983 2984 /* 2985 * Disallow write attempts on filesystems mounted read-only; 2986 * unless the file is a socket, fifo, or a block or character 2987 * device resident on the filesystem. 2988 */ 2989 if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { 2990 switch (vp->v_type) { 2991 case VREG: 2992 case VDIR: 2993 case VLNK: 2994 return (EROFS); 2995 default: 2996 break; 2997 } 2998 } 2999 /* 3000 * If you're the super-user, 3001 * you always get access. 3002 */ 3003 if (cred->cr_uid == 0) 3004 return (0); 3005 vap = &vattr; 3006 error = VOP_GETATTR(vp, vap, cred, ap->a_td); 3007 if (error) 3008 return (error); 3009 /* 3010 * Access check is based on only one of owner, group, public. 3011 * If not owner, then check group. If not a member of the 3012 * group, then check public access. 3013 */ 3014 if (cred->cr_uid != vap->va_uid) { 3015 mode >>= 3; 3016 gp = cred->cr_groups; 3017 for (i = 0; i < cred->cr_ngroups; i++, gp++) 3018 if (vap->va_gid == *gp) 3019 goto found; 3020 mode >>= 3; 3021found: 3022 ; 3023 } 3024 error = (vap->va_mode & mode) == mode ? 0 : EACCES; 3025 return (error); 3026} 3027 3028/* 3029 * Read wrapper for special devices. 3030 */ 3031static int 3032nfsspec_read(struct vop_read_args *ap) 3033{ 3034 struct nfsnode *np = VTONFS(ap->a_vp); 3035 3036 /* 3037 * Set access flag. 3038 */ 3039 np->n_flag |= NACC; 3040 getnanotime(&np->n_atim); 3041 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap)); 3042} 3043 3044/* 3045 * Write wrapper for special devices. 3046 */ 3047static int 3048nfsspec_write(struct vop_write_args *ap) 3049{ 3050 struct nfsnode *np = VTONFS(ap->a_vp); 3051 3052 /* 3053 * Set update flag. 3054 */ 3055 np->n_flag |= NUPD; 3056 getnanotime(&np->n_mtim); 3057 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap)); 3058} 3059 3060/* 3061 * Close wrapper for special devices. 3062 * 3063 * Update the times on the nfsnode then do device close. 3064 */ 3065static int 3066nfsspec_close(struct vop_close_args *ap) 3067{ 3068 struct vnode *vp = ap->a_vp; 3069 struct nfsnode *np = VTONFS(vp); 3070 struct vattr vattr; 3071 3072 if (np->n_flag & (NACC | NUPD)) { 3073 np->n_flag |= NCHG; 3074 if (vrefcnt(vp) == 1 && 3075 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 3076 VATTR_NULL(&vattr); 3077 if (np->n_flag & NACC) 3078 vattr.va_atime = np->n_atim; 3079 if (np->n_flag & NUPD) 3080 vattr.va_mtime = np->n_mtim; 3081 (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_td); 3082 } 3083 } 3084 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap)); 3085} 3086 3087/* 3088 * Read wrapper for fifos. 3089 */ 3090static int 3091nfsfifo_read(struct vop_read_args *ap) 3092{ 3093 struct nfsnode *np = VTONFS(ap->a_vp); 3094 3095 /* 3096 * Set access flag. 3097 */ 3098 np->n_flag |= NACC; 3099 getnanotime(&np->n_atim); 3100 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap)); 3101} 3102 3103/* 3104 * Write wrapper for fifos. 3105 */ 3106static int 3107nfsfifo_write(struct vop_write_args *ap) 3108{ 3109 struct nfsnode *np = VTONFS(ap->a_vp); 3110 3111 /* 3112 * Set update flag. 3113 */ 3114 np->n_flag |= NUPD; 3115 getnanotime(&np->n_mtim); 3116 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap)); 3117} 3118 3119/* 3120 * Close wrapper for fifos. 3121 * 3122 * Update the times on the nfsnode then do fifo close. 3123 */ 3124static int 3125nfsfifo_close(struct vop_close_args *ap) 3126{ 3127 struct vnode *vp = ap->a_vp; 3128 struct nfsnode *np = VTONFS(vp); 3129 struct vattr vattr; 3130 struct timespec ts; 3131 3132 if (np->n_flag & (NACC | NUPD)) { 3133 getnanotime(&ts); 3134 if (np->n_flag & NACC) 3135 np->n_atim = ts; 3136 if (np->n_flag & NUPD) 3137 np->n_mtim = ts; 3138 np->n_flag |= NCHG; 3139 if (vrefcnt(vp) == 1 && 3140 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 3141 VATTR_NULL(&vattr); 3142 if (np->n_flag & NACC) 3143 vattr.va_atime = np->n_atim; 3144 if (np->n_flag & NUPD) 3145 vattr.va_mtime = np->n_mtim; 3146 (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_td); 3147 } 3148 } 3149 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap)); 3150} 3151 3152