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