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