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