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.16 2004/01/23 23:00:52 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 = time_second; 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 ((time_second < (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 (EACCES); 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, 0, td); 892 error = vget(newvp, LK_EXCLUSIVE, td); 893 if (!error && lockparent && (flags & CNP_ISLASTCN)) 894 error = vn_lock(dvp, LK_EXCLUSIVE, td); 895 } else { 896 error = vget(newvp, LK_EXCLUSIVE, td); 897 if (!lockparent || error || !(flags & CNP_ISLASTCN)) 898 VOP_UNLOCK(dvp, 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, 0, td); 915 } 916 error = vn_lock(dvp, 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, 0, td); 962 return (0); 963 } 964 965 if (flags & CNP_ISDOTDOT) { 966 VOP_UNLOCK(dvp, 0, td); 967 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); 968 if (error) { 969 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td); 970 return (error); 971 } 972 newvp = NFSTOV(np); 973 if (lockparent && (flags & CNP_ISLASTCN) && 974 (error = vn_lock(dvp, 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, 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, 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 if (vp->v_type != VREG) 1042 return (EPERM); 1043 return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag)); 1044 } 1045 1046 /* 1047 * nfs readlink call 1048 */ 1049 static int 1050 nfs_readlink(ap) 1051 struct vop_readlink_args /* { 1052 struct vnode *a_vp; 1053 struct uio *a_uio; 1054 struct ucred *a_cred; 1055 } */ *ap; 1056 { 1057 struct vnode *vp = ap->a_vp; 1058 1059 if (vp->v_type != VLNK) 1060 return (EINVAL); 1061 return (nfs_bioread(vp, ap->a_uio, 0)); 1062 } 1063 1064 /* 1065 * Do a readlink rpc. 1066 * Called by nfs_doio() from below the buffer cache. 1067 */ 1068 int 1069 nfs_readlinkrpc(struct vnode *vp, struct uio *uiop) 1070 { 1071 u_int32_t *tl; 1072 caddr_t cp; 1073 int32_t t1, t2; 1074 caddr_t bpos, dpos, cp2; 1075 int error = 0, len, attrflag; 1076 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1077 int v3 = NFS_ISV3(vp); 1078 1079 nfsstats.rpccnt[NFSPROC_READLINK]++; 1080 nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH(v3)); 1081 nfsm_fhtom(vp, v3); 1082 nfsm_request(vp, NFSPROC_READLINK, uiop->uio_td, nfs_vpcred(vp, ND_CHECK)); 1083 if (v3) 1084 nfsm_postop_attr(vp, attrflag); 1085 if (!error) { 1086 nfsm_strsiz(len, NFS_MAXPATHLEN); 1087 if (len == NFS_MAXPATHLEN) { 1088 struct nfsnode *np = VTONFS(vp); 1089 if (np->n_size && np->n_size < NFS_MAXPATHLEN) 1090 len = np->n_size; 1091 } 1092 nfsm_mtouio(uiop, len); 1093 } 1094 m_freem(mrep); 1095 nfsmout: 1096 return (error); 1097 } 1098 1099 /* 1100 * nfs read rpc call 1101 * Ditto above 1102 */ 1103 int 1104 nfs_readrpc(struct vnode *vp, struct uio *uiop) 1105 { 1106 u_int32_t *tl; 1107 caddr_t cp; 1108 int32_t t1, t2; 1109 caddr_t bpos, dpos, cp2; 1110 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1111 struct nfsmount *nmp; 1112 int error = 0, len, retlen, tsiz, eof, attrflag; 1113 int v3 = NFS_ISV3(vp); 1114 1115 #ifndef nolint 1116 eof = 0; 1117 #endif 1118 nmp = VFSTONFS(vp->v_mount); 1119 tsiz = uiop->uio_resid; 1120 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) 1121 return (EFBIG); 1122 while (tsiz > 0) { 1123 nfsstats.rpccnt[NFSPROC_READ]++; 1124 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; 1125 nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3); 1126 nfsm_fhtom(vp, v3); 1127 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED * 3); 1128 if (v3) { 1129 txdr_hyper(uiop->uio_offset, tl); 1130 *(tl + 2) = txdr_unsigned(len); 1131 } else { 1132 *tl++ = txdr_unsigned(uiop->uio_offset); 1133 *tl++ = txdr_unsigned(len); 1134 *tl = 0; 1135 } 1136 nfsm_request(vp, NFSPROC_READ, uiop->uio_td, nfs_vpcred(vp, ND_READ)); 1137 if (v3) { 1138 nfsm_postop_attr(vp, attrflag); 1139 if (error) { 1140 m_freem(mrep); 1141 goto nfsmout; 1142 } 1143 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 1144 eof = fxdr_unsigned(int, *(tl + 1)); 1145 } else 1146 nfsm_loadattr(vp, (struct vattr *)0); 1147 nfsm_strsiz(retlen, nmp->nm_rsize); 1148 nfsm_mtouio(uiop, retlen); 1149 m_freem(mrep); 1150 tsiz -= retlen; 1151 if (v3) { 1152 if (eof || retlen == 0) { 1153 tsiz = 0; 1154 } 1155 } else if (retlen < len) { 1156 tsiz = 0; 1157 } 1158 } 1159 nfsmout: 1160 return (error); 1161 } 1162 1163 /* 1164 * nfs write call 1165 */ 1166 int 1167 nfs_writerpc(vp, uiop, iomode, must_commit) 1168 struct vnode *vp; 1169 struct uio *uiop; 1170 int *iomode, *must_commit; 1171 { 1172 u_int32_t *tl; 1173 caddr_t cp; 1174 int32_t t1, t2, backup; 1175 caddr_t bpos, dpos, cp2; 1176 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1177 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 1178 int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit; 1179 int v3 = NFS_ISV3(vp), committed = NFSV3WRITE_FILESYNC; 1180 1181 #ifndef DIAGNOSTIC 1182 if (uiop->uio_iovcnt != 1) 1183 panic("nfs: writerpc iovcnt > 1"); 1184 #endif 1185 *must_commit = 0; 1186 tsiz = uiop->uio_resid; 1187 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) 1188 return (EFBIG); 1189 while (tsiz > 0) { 1190 nfsstats.rpccnt[NFSPROC_WRITE]++; 1191 len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; 1192 nfsm_reqhead(vp, NFSPROC_WRITE, 1193 NFSX_FH(v3) + 5 * NFSX_UNSIGNED + nfsm_rndup(len)); 1194 nfsm_fhtom(vp, v3); 1195 if (v3) { 1196 nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED); 1197 txdr_hyper(uiop->uio_offset, tl); 1198 tl += 2; 1199 *tl++ = txdr_unsigned(len); 1200 *tl++ = txdr_unsigned(*iomode); 1201 *tl = txdr_unsigned(len); 1202 } else { 1203 u_int32_t x; 1204 1205 nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED); 1206 /* Set both "begin" and "current" to non-garbage. */ 1207 x = txdr_unsigned((u_int32_t)uiop->uio_offset); 1208 *tl++ = x; /* "begin offset" */ 1209 *tl++ = x; /* "current offset" */ 1210 x = txdr_unsigned(len); 1211 *tl++ = x; /* total to this offset */ 1212 *tl = x; /* size of this write */ 1213 } 1214 nfsm_uiotom(uiop, len); 1215 nfsm_request(vp, NFSPROC_WRITE, uiop->uio_td, nfs_vpcred(vp, ND_WRITE)); 1216 if (v3) { 1217 wccflag = NFSV3_WCCCHK; 1218 nfsm_wcc_data(vp, wccflag); 1219 if (!error) { 1220 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED 1221 + NFSX_V3WRITEVERF); 1222 rlen = fxdr_unsigned(int, *tl++); 1223 if (rlen == 0) { 1224 error = NFSERR_IO; 1225 m_freem(mrep); 1226 break; 1227 } else if (rlen < len) { 1228 backup = len - rlen; 1229 uiop->uio_iov->iov_base -= backup; 1230 uiop->uio_iov->iov_len += backup; 1231 uiop->uio_offset -= backup; 1232 uiop->uio_resid += backup; 1233 len = rlen; 1234 } 1235 commit = fxdr_unsigned(int, *tl++); 1236 1237 /* 1238 * Return the lowest committment level 1239 * obtained by any of the RPCs. 1240 */ 1241 if (committed == NFSV3WRITE_FILESYNC) 1242 committed = commit; 1243 else if (committed == NFSV3WRITE_DATASYNC && 1244 commit == NFSV3WRITE_UNSTABLE) 1245 committed = commit; 1246 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){ 1247 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 1248 NFSX_V3WRITEVERF); 1249 nmp->nm_state |= NFSSTA_HASWRITEVERF; 1250 } else if (bcmp((caddr_t)tl, 1251 (caddr_t)nmp->nm_verf, NFSX_V3WRITEVERF)) { 1252 *must_commit = 1; 1253 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 1254 NFSX_V3WRITEVERF); 1255 } 1256 } 1257 } else 1258 nfsm_loadattr(vp, (struct vattr *)0); 1259 if (wccflag) 1260 VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.tv_sec; 1261 m_freem(mrep); 1262 if (error) 1263 break; 1264 tsiz -= len; 1265 } 1266 nfsmout: 1267 if (vp->v_mount->mnt_flag & MNT_ASYNC) 1268 committed = NFSV3WRITE_FILESYNC; 1269 *iomode = committed; 1270 if (error) 1271 uiop->uio_resid = tsiz; 1272 return (error); 1273 } 1274 1275 /* 1276 * nfs mknod rpc 1277 * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the 1278 * mode set to specify the file type and the size field for rdev. 1279 */ 1280 static int 1281 nfs_mknodrpc(dvp, vpp, cnp, vap) 1282 struct vnode *dvp; 1283 struct vnode **vpp; 1284 struct componentname *cnp; 1285 struct vattr *vap; 1286 { 1287 struct nfsv2_sattr *sp; 1288 u_int32_t *tl; 1289 caddr_t cp; 1290 int32_t t1, t2; 1291 struct vnode *newvp = (struct vnode *)0; 1292 struct nfsnode *np = (struct nfsnode *)0; 1293 struct vattr vattr; 1294 char *cp2; 1295 caddr_t bpos, dpos; 1296 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0; 1297 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1298 u_int32_t rdev; 1299 int v3 = NFS_ISV3(dvp); 1300 1301 if (vap->va_type == VCHR || vap->va_type == VBLK) 1302 rdev = txdr_unsigned(vap->va_rdev); 1303 else if (vap->va_type == VFIFO || vap->va_type == VSOCK) 1304 rdev = nfs_xdrneg1; 1305 else { 1306 return (EOPNOTSUPP); 1307 } 1308 if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_td)) != 0) { 1309 return (error); 1310 } 1311 nfsstats.rpccnt[NFSPROC_MKNOD]++; 1312 nfsm_reqhead(dvp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED + 1313 + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); 1314 nfsm_fhtom(dvp, v3); 1315 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1316 if (v3) { 1317 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); 1318 *tl++ = vtonfsv3_type(vap->va_type); 1319 nfsm_v3attrbuild(vap, FALSE); 1320 if (vap->va_type == VCHR || vap->va_type == VBLK) { 1321 nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 1322 *tl++ = txdr_unsigned(umajor(vap->va_rdev)); 1323 *tl = txdr_unsigned(uminor(vap->va_rdev)); 1324 } 1325 } else { 1326 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); 1327 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); 1328 sp->sa_uid = nfs_xdrneg1; 1329 sp->sa_gid = nfs_xdrneg1; 1330 sp->sa_size = rdev; 1331 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1332 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1333 } 1334 nfsm_request(dvp, NFSPROC_MKNOD, cnp->cn_td, cnp->cn_cred); 1335 if (!error) { 1336 nfsm_mtofh(dvp, newvp, v3, gotvp); 1337 if (!gotvp) { 1338 if (newvp) { 1339 vput(newvp); 1340 newvp = (struct vnode *)0; 1341 } 1342 error = nfs_lookitup(dvp, cnp->cn_nameptr, 1343 cnp->cn_namelen, cnp->cn_cred, cnp->cn_td, &np); 1344 if (!error) 1345 newvp = NFSTOV(np); 1346 } 1347 } 1348 if (v3) 1349 nfsm_wcc_data(dvp, wccflag); 1350 m_freem(mrep); 1351 nfsmout: 1352 if (error) { 1353 if (newvp) 1354 vput(newvp); 1355 } else { 1356 if (cnp->cn_flags & CNP_MAKEENTRY) 1357 cache_enter(dvp, NCPNULL, newvp, cnp); 1358 *vpp = newvp; 1359 } 1360 VTONFS(dvp)->n_flag |= NMODIFIED; 1361 if (!wccflag) 1362 VTONFS(dvp)->n_attrstamp = 0; 1363 return (error); 1364 } 1365 1366 /* 1367 * nfs mknod vop 1368 * just call nfs_mknodrpc() to do the work. 1369 */ 1370 /* ARGSUSED */ 1371 static int 1372 nfs_mknod(ap) 1373 struct vop_mknod_args /* { 1374 struct vnode *a_dvp; 1375 struct vnode **a_vpp; 1376 struct componentname *a_cnp; 1377 struct vattr *a_vap; 1378 } */ *ap; 1379 { 1380 return nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap); 1381 } 1382 1383 static u_long create_verf; 1384 /* 1385 * nfs file create call 1386 */ 1387 static int 1388 nfs_create(ap) 1389 struct vop_create_args /* { 1390 struct vnode *a_dvp; 1391 struct vnode **a_vpp; 1392 struct componentname *a_cnp; 1393 struct vattr *a_vap; 1394 } */ *ap; 1395 { 1396 struct vnode *dvp = ap->a_dvp; 1397 struct vattr *vap = ap->a_vap; 1398 struct componentname *cnp = ap->a_cnp; 1399 struct nfsv2_sattr *sp; 1400 u_int32_t *tl; 1401 caddr_t cp; 1402 int32_t t1, t2; 1403 struct nfsnode *np = (struct nfsnode *)0; 1404 struct vnode *newvp = (struct vnode *)0; 1405 caddr_t bpos, dpos, cp2; 1406 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0; 1407 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1408 struct vattr vattr; 1409 int v3 = NFS_ISV3(dvp); 1410 1411 /* 1412 * Oops, not for me.. 1413 */ 1414 if (vap->va_type == VSOCK) 1415 return (nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap)); 1416 1417 if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_td)) != 0) { 1418 return (error); 1419 } 1420 if (vap->va_vaflags & VA_EXCLUSIVE) 1421 fmode |= O_EXCL; 1422 again: 1423 nfsstats.rpccnt[NFSPROC_CREATE]++; 1424 nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED + 1425 nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); 1426 nfsm_fhtom(dvp, v3); 1427 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1428 if (v3) { 1429 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); 1430 if (fmode & O_EXCL) { 1431 *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); 1432 nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF); 1433 #ifdef INET 1434 if (!TAILQ_EMPTY(&in_ifaddrhead)) 1435 *tl++ = IA_SIN(in_ifaddrhead.tqh_first)->sin_addr.s_addr; 1436 else 1437 #endif 1438 *tl++ = create_verf; 1439 *tl = ++create_verf; 1440 } else { 1441 *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED); 1442 nfsm_v3attrbuild(vap, FALSE); 1443 } 1444 } else { 1445 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); 1446 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); 1447 sp->sa_uid = nfs_xdrneg1; 1448 sp->sa_gid = nfs_xdrneg1; 1449 sp->sa_size = 0; 1450 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1451 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1452 } 1453 nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_td, cnp->cn_cred); 1454 if (!error) { 1455 nfsm_mtofh(dvp, newvp, v3, gotvp); 1456 if (!gotvp) { 1457 if (newvp) { 1458 vput(newvp); 1459 newvp = (struct vnode *)0; 1460 } 1461 error = nfs_lookitup(dvp, cnp->cn_nameptr, 1462 cnp->cn_namelen, cnp->cn_cred, cnp->cn_td, &np); 1463 if (!error) 1464 newvp = NFSTOV(np); 1465 } 1466 } 1467 if (v3) 1468 nfsm_wcc_data(dvp, wccflag); 1469 m_freem(mrep); 1470 nfsmout: 1471 if (error) { 1472 if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) { 1473 fmode &= ~O_EXCL; 1474 goto again; 1475 } 1476 if (newvp) 1477 vput(newvp); 1478 } else if (v3 && (fmode & O_EXCL)) { 1479 /* 1480 * We are normally called with only a partially initialized 1481 * VAP. Since the NFSv3 spec says that server may use the 1482 * file attributes to store the verifier, the spec requires 1483 * us to do a SETATTR RPC. FreeBSD servers store the verifier 1484 * in atime, but we can't really assume that all servers will 1485 * so we ensure that our SETATTR sets both atime and mtime. 1486 */ 1487 if (vap->va_mtime.tv_sec == VNOVAL) 1488 vfs_timestamp(&vap->va_mtime); 1489 if (vap->va_atime.tv_sec == VNOVAL) 1490 vap->va_atime = vap->va_mtime; 1491 error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_td); 1492 } 1493 if (!error) { 1494 if (cnp->cn_flags & CNP_MAKEENTRY) 1495 cache_enter(dvp, NCPNULL, newvp, cnp); 1496 /* 1497 * The new np may have enough info for access 1498 * checks, make sure rucred and wucred are 1499 * initialized for read and write rpc's. 1500 */ 1501 np = VTONFS(newvp); 1502 if (np->n_rucred == NULL) 1503 np->n_rucred = crhold(cnp->cn_cred); 1504 if (np->n_wucred == NULL) 1505 np->n_wucred = crhold(cnp->cn_cred); 1506 *ap->a_vpp = newvp; 1507 } 1508 VTONFS(dvp)->n_flag |= NMODIFIED; 1509 if (!wccflag) 1510 VTONFS(dvp)->n_attrstamp = 0; 1511 return (error); 1512 } 1513 1514 /* 1515 * nfs file remove call 1516 * To try and make nfs semantics closer to ufs semantics, a file that has 1517 * other processes using the vnode is renamed instead of removed and then 1518 * removed later on the last close. 1519 * - If v_usecount > 1 1520 * If a rename is not already in the works 1521 * call nfs_sillyrename() to set it up 1522 * else 1523 * do the remove rpc 1524 */ 1525 static int 1526 nfs_remove(ap) 1527 struct vop_remove_args /* { 1528 struct vnodeop_desc *a_desc; 1529 struct vnode * a_dvp; 1530 struct vnode * a_vp; 1531 struct componentname * a_cnp; 1532 } */ *ap; 1533 { 1534 struct vnode *vp = ap->a_vp; 1535 struct vnode *dvp = ap->a_dvp; 1536 struct componentname *cnp = ap->a_cnp; 1537 struct nfsnode *np = VTONFS(vp); 1538 int error = 0; 1539 struct vattr vattr; 1540 1541 #ifndef DIAGNOSTIC 1542 if ((cnp->cn_flags & CNP_HASBUF) == 0) 1543 panic("nfs_remove: no name"); 1544 if (vp->v_usecount < 1) 1545 panic("nfs_remove: bad v_usecount"); 1546 #endif 1547 if (vp->v_type == VDIR) 1548 error = EPERM; 1549 else if (vp->v_usecount == 1 || (np->n_sillyrename && 1550 VOP_GETATTR(vp, &vattr, cnp->cn_td) == 0 && 1551 vattr.va_nlink > 1)) { 1552 /* 1553 * Purge the name cache so that the chance of a lookup for 1554 * the name succeeding while the remove is in progress is 1555 * minimized. Without node locking it can still happen, such 1556 * that an I/O op returns ESTALE, but since you get this if 1557 * another host removes the file.. 1558 */ 1559 cache_purge(vp); 1560 /* 1561 * throw away biocache buffers, mainly to avoid 1562 * unnecessary delayed writes later. 1563 */ 1564 error = nfs_vinvalbuf(vp, 0, cnp->cn_td, 1); 1565 /* Do the rpc */ 1566 if (error != EINTR) 1567 error = nfs_removerpc(dvp, cnp->cn_nameptr, 1568 cnp->cn_namelen, cnp->cn_cred, cnp->cn_td); 1569 /* 1570 * Kludge City: If the first reply to the remove rpc is lost.. 1571 * the reply to the retransmitted request will be ENOENT 1572 * since the file was in fact removed 1573 * Therefore, we cheat and return success. 1574 */ 1575 if (error == ENOENT) 1576 error = 0; 1577 } else if (!np->n_sillyrename) 1578 error = nfs_sillyrename(dvp, vp, cnp); 1579 np->n_attrstamp = 0; 1580 return (error); 1581 } 1582 1583 /* 1584 * nfs file remove rpc called from nfs_inactive 1585 */ 1586 int 1587 nfs_removeit(struct sillyrename *sp) 1588 { 1589 1590 return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, 1591 sp->s_cred, NULL)); 1592 } 1593 1594 /* 1595 * Nfs remove rpc, called from nfs_remove() and nfs_removeit(). 1596 */ 1597 static int 1598 nfs_removerpc(dvp, name, namelen, cred, td) 1599 struct vnode *dvp; 1600 const char *name; 1601 int namelen; 1602 struct ucred *cred; 1603 struct thread *td; 1604 { 1605 u_int32_t *tl; 1606 caddr_t cp; 1607 int32_t t1, t2; 1608 caddr_t bpos, dpos, cp2; 1609 int error = 0, wccflag = NFSV3_WCCRATTR; 1610 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1611 int v3 = NFS_ISV3(dvp); 1612 1613 nfsstats.rpccnt[NFSPROC_REMOVE]++; 1614 nfsm_reqhead(dvp, NFSPROC_REMOVE, 1615 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen)); 1616 nfsm_fhtom(dvp, v3); 1617 nfsm_strtom(name, namelen, NFS_MAXNAMLEN); 1618 nfsm_request(dvp, NFSPROC_REMOVE, td, cred); 1619 if (v3) 1620 nfsm_wcc_data(dvp, wccflag); 1621 m_freem(mrep); 1622 nfsmout: 1623 VTONFS(dvp)->n_flag |= NMODIFIED; 1624 if (!wccflag) 1625 VTONFS(dvp)->n_attrstamp = 0; 1626 return (error); 1627 } 1628 1629 /* 1630 * nfs file rename call 1631 */ 1632 static int 1633 nfs_rename(ap) 1634 struct vop_rename_args /* { 1635 struct vnode *a_fdvp; 1636 struct vnode *a_fvp; 1637 struct componentname *a_fcnp; 1638 struct vnode *a_tdvp; 1639 struct vnode *a_tvp; 1640 struct componentname *a_tcnp; 1641 } */ *ap; 1642 { 1643 struct vnode *fvp = ap->a_fvp; 1644 struct vnode *tvp = ap->a_tvp; 1645 struct vnode *fdvp = ap->a_fdvp; 1646 struct vnode *tdvp = ap->a_tdvp; 1647 struct componentname *tcnp = ap->a_tcnp; 1648 struct componentname *fcnp = ap->a_fcnp; 1649 int error; 1650 1651 #ifndef DIAGNOSTIC 1652 if ((tcnp->cn_flags & CNP_HASBUF) == 0 || 1653 (fcnp->cn_flags & CNP_HASBUF) == 0) 1654 panic("nfs_rename: no name"); 1655 #endif 1656 /* Check for cross-device rename */ 1657 if ((fvp->v_mount != tdvp->v_mount) || 1658 (tvp && (fvp->v_mount != tvp->v_mount))) { 1659 error = EXDEV; 1660 goto out; 1661 } 1662 1663 /* 1664 * We have to flush B_DELWRI data prior to renaming 1665 * the file. If we don't, the delayed-write buffers 1666 * can be flushed out later after the file has gone stale 1667 * under NFSV3. NFSV2 does not have this problem because 1668 * ( as far as I can tell ) it flushes dirty buffers more 1669 * often. 1670 */ 1671 1672 VOP_FSYNC(fvp, MNT_WAIT, fcnp->cn_td); 1673 if (tvp) 1674 VOP_FSYNC(tvp, MNT_WAIT, tcnp->cn_td); 1675 1676 /* 1677 * If the tvp exists and is in use, sillyrename it before doing the 1678 * rename of the new file over it. 1679 * XXX Can't sillyrename a directory. 1680 */ 1681 if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)->n_sillyrename && 1682 tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) { 1683 vput(tvp); 1684 tvp = NULL; 1685 } 1686 1687 error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen, 1688 tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred, 1689 tcnp->cn_td); 1690 1691 if (fvp->v_type == VDIR) { 1692 if (tvp != NULL && tvp->v_type == VDIR) 1693 cache_purge(tdvp); 1694 cache_purge(fdvp); 1695 } 1696 1697 out: 1698 if (tdvp == tvp) 1699 vrele(tdvp); 1700 else 1701 vput(tdvp); 1702 if (tvp) 1703 vput(tvp); 1704 vrele(fdvp); 1705 vrele(fvp); 1706 /* 1707 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. 1708 */ 1709 if (error == ENOENT) 1710 error = 0; 1711 return (error); 1712 } 1713 1714 /* 1715 * nfs file rename rpc called from nfs_remove() above 1716 */ 1717 static int 1718 nfs_renameit(sdvp, scnp, sp) 1719 struct vnode *sdvp; 1720 struct componentname *scnp; 1721 struct sillyrename *sp; 1722 { 1723 return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, 1724 sdvp, sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_td)); 1725 } 1726 1727 /* 1728 * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit(). 1729 */ 1730 static int 1731 nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, td) 1732 struct vnode *fdvp; 1733 const char *fnameptr; 1734 int fnamelen; 1735 struct vnode *tdvp; 1736 const char *tnameptr; 1737 int tnamelen; 1738 struct ucred *cred; 1739 struct thread *td; 1740 { 1741 u_int32_t *tl; 1742 caddr_t cp; 1743 int32_t t1, t2; 1744 caddr_t bpos, dpos, cp2; 1745 int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR; 1746 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1747 int v3 = NFS_ISV3(fdvp); 1748 1749 nfsstats.rpccnt[NFSPROC_RENAME]++; 1750 nfsm_reqhead(fdvp, NFSPROC_RENAME, 1751 (NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) + 1752 nfsm_rndup(tnamelen)); 1753 nfsm_fhtom(fdvp, v3); 1754 nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN); 1755 nfsm_fhtom(tdvp, v3); 1756 nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN); 1757 nfsm_request(fdvp, NFSPROC_RENAME, td, cred); 1758 if (v3) { 1759 nfsm_wcc_data(fdvp, fwccflag); 1760 nfsm_wcc_data(tdvp, twccflag); 1761 } 1762 m_freem(mrep); 1763 nfsmout: 1764 VTONFS(fdvp)->n_flag |= NMODIFIED; 1765 VTONFS(tdvp)->n_flag |= NMODIFIED; 1766 if (!fwccflag) 1767 VTONFS(fdvp)->n_attrstamp = 0; 1768 if (!twccflag) 1769 VTONFS(tdvp)->n_attrstamp = 0; 1770 return (error); 1771 } 1772 1773 /* 1774 * nfs hard link create call 1775 */ 1776 static int 1777 nfs_link(ap) 1778 struct vop_link_args /* { 1779 struct vnode *a_tdvp; 1780 struct vnode *a_vp; 1781 struct componentname *a_cnp; 1782 } */ *ap; 1783 { 1784 struct vnode *vp = ap->a_vp; 1785 struct vnode *tdvp = ap->a_tdvp; 1786 struct componentname *cnp = ap->a_cnp; 1787 u_int32_t *tl; 1788 caddr_t cp; 1789 int32_t t1, t2; 1790 caddr_t bpos, dpos, cp2; 1791 int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0; 1792 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1793 int v3; 1794 1795 if (vp->v_mount != tdvp->v_mount) { 1796 return (EXDEV); 1797 } 1798 1799 /* 1800 * Push all writes to the server, so that the attribute cache 1801 * doesn't get "out of sync" with the server. 1802 * XXX There should be a better way! 1803 */ 1804 VOP_FSYNC(vp, MNT_WAIT, cnp->cn_td); 1805 1806 v3 = NFS_ISV3(vp); 1807 nfsstats.rpccnt[NFSPROC_LINK]++; 1808 nfsm_reqhead(vp, NFSPROC_LINK, 1809 NFSX_FH(v3)*2 + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); 1810 nfsm_fhtom(vp, v3); 1811 nfsm_fhtom(tdvp, v3); 1812 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1813 nfsm_request(vp, NFSPROC_LINK, cnp->cn_td, cnp->cn_cred); 1814 if (v3) { 1815 nfsm_postop_attr(vp, attrflag); 1816 nfsm_wcc_data(tdvp, wccflag); 1817 } 1818 m_freem(mrep); 1819 nfsmout: 1820 VTONFS(tdvp)->n_flag |= NMODIFIED; 1821 if (!attrflag) 1822 VTONFS(vp)->n_attrstamp = 0; 1823 if (!wccflag) 1824 VTONFS(tdvp)->n_attrstamp = 0; 1825 /* 1826 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. 1827 */ 1828 if (error == EEXIST) 1829 error = 0; 1830 return (error); 1831 } 1832 1833 /* 1834 * nfs symbolic link create call 1835 */ 1836 static int 1837 nfs_symlink(ap) 1838 struct vop_symlink_args /* { 1839 struct vnode *a_dvp; 1840 struct vnode **a_vpp; 1841 struct componentname *a_cnp; 1842 struct vattr *a_vap; 1843 char *a_target; 1844 } */ *ap; 1845 { 1846 struct vnode *dvp = ap->a_dvp; 1847 struct vattr *vap = ap->a_vap; 1848 struct componentname *cnp = ap->a_cnp; 1849 struct nfsv2_sattr *sp; 1850 u_int32_t *tl; 1851 caddr_t cp; 1852 int32_t t1, t2; 1853 caddr_t bpos, dpos, cp2; 1854 int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp; 1855 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1856 struct vnode *newvp = (struct vnode *)0; 1857 int v3 = NFS_ISV3(dvp); 1858 1859 nfsstats.rpccnt[NFSPROC_SYMLINK]++; 1860 slen = strlen(ap->a_target); 1861 nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED + 1862 nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3)); 1863 nfsm_fhtom(dvp, v3); 1864 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1865 if (v3) { 1866 nfsm_v3attrbuild(vap, FALSE); 1867 } 1868 nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN); 1869 if (!v3) { 1870 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); 1871 sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode); 1872 sp->sa_uid = nfs_xdrneg1; 1873 sp->sa_gid = nfs_xdrneg1; 1874 sp->sa_size = nfs_xdrneg1; 1875 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1876 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1877 } 1878 1879 /* 1880 * Issue the NFS request and get the rpc response. 1881 * 1882 * Only NFSv3 responses returning an error of 0 actually return 1883 * a file handle that can be converted into newvp without having 1884 * to do an extra lookup rpc. 1885 */ 1886 nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_td, cnp->cn_cred); 1887 if (v3) { 1888 if (error == 0) 1889 nfsm_mtofh(dvp, newvp, v3, gotvp); 1890 nfsm_wcc_data(dvp, wccflag); 1891 } 1892 1893 /* 1894 * out code jumps -> here, mrep is also freed. 1895 */ 1896 1897 m_freem(mrep); 1898 nfsmout: 1899 1900 /* 1901 * If we get an EEXIST error, silently convert it to no-error 1902 * in case of an NFS retry. 1903 */ 1904 if (error == EEXIST) 1905 error = 0; 1906 1907 /* 1908 * If we do not have (or no longer have) an error, and we could 1909 * not extract the newvp from the response due to the request being 1910 * NFSv2 or the error being EEXIST. We have to do a lookup in order 1911 * to obtain a newvp to return. 1912 */ 1913 if (error == 0 && newvp == NULL) { 1914 struct nfsnode *np = NULL; 1915 1916 error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen, 1917 cnp->cn_cred, cnp->cn_td, &np); 1918 if (!error) 1919 newvp = NFSTOV(np); 1920 } 1921 if (error) { 1922 if (newvp) 1923 vput(newvp); 1924 } else { 1925 *ap->a_vpp = newvp; 1926 } 1927 VTONFS(dvp)->n_flag |= NMODIFIED; 1928 if (!wccflag) 1929 VTONFS(dvp)->n_attrstamp = 0; 1930 return (error); 1931 } 1932 1933 /* 1934 * nfs make dir call 1935 */ 1936 static int 1937 nfs_mkdir(ap) 1938 struct vop_mkdir_args /* { 1939 struct vnode *a_dvp; 1940 struct vnode **a_vpp; 1941 struct componentname *a_cnp; 1942 struct vattr *a_vap; 1943 } */ *ap; 1944 { 1945 struct vnode *dvp = ap->a_dvp; 1946 struct vattr *vap = ap->a_vap; 1947 struct componentname *cnp = ap->a_cnp; 1948 struct nfsv2_sattr *sp; 1949 u_int32_t *tl; 1950 caddr_t cp; 1951 int32_t t1, t2; 1952 int len; 1953 struct nfsnode *np = (struct nfsnode *)0; 1954 struct vnode *newvp = (struct vnode *)0; 1955 caddr_t bpos, dpos, cp2; 1956 int error = 0, wccflag = NFSV3_WCCRATTR; 1957 int gotvp = 0; 1958 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1959 struct vattr vattr; 1960 int v3 = NFS_ISV3(dvp); 1961 1962 if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_td)) != 0) { 1963 return (error); 1964 } 1965 len = cnp->cn_namelen; 1966 nfsstats.rpccnt[NFSPROC_MKDIR]++; 1967 nfsm_reqhead(dvp, NFSPROC_MKDIR, 1968 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(v3)); 1969 nfsm_fhtom(dvp, v3); 1970 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 1971 if (v3) { 1972 nfsm_v3attrbuild(vap, FALSE); 1973 } else { 1974 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); 1975 sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode); 1976 sp->sa_uid = nfs_xdrneg1; 1977 sp->sa_gid = nfs_xdrneg1; 1978 sp->sa_size = nfs_xdrneg1; 1979 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1980 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1981 } 1982 nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_td, cnp->cn_cred); 1983 if (!error) 1984 nfsm_mtofh(dvp, newvp, v3, gotvp); 1985 if (v3) 1986 nfsm_wcc_data(dvp, wccflag); 1987 m_freem(mrep); 1988 nfsmout: 1989 VTONFS(dvp)->n_flag |= NMODIFIED; 1990 if (!wccflag) 1991 VTONFS(dvp)->n_attrstamp = 0; 1992 /* 1993 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry 1994 * if we can succeed in looking up the directory. 1995 */ 1996 if (error == EEXIST || (!error && !gotvp)) { 1997 if (newvp) { 1998 vrele(newvp); 1999 newvp = (struct vnode *)0; 2000 } 2001 error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred, 2002 cnp->cn_td, &np); 2003 if (!error) { 2004 newvp = NFSTOV(np); 2005 if (newvp->v_type != VDIR) 2006 error = EEXIST; 2007 } 2008 } 2009 if (error) { 2010 if (newvp) 2011 vrele(newvp); 2012 } else 2013 *ap->a_vpp = newvp; 2014 return (error); 2015 } 2016 2017 /* 2018 * nfs remove directory call 2019 */ 2020 static int 2021 nfs_rmdir(ap) 2022 struct vop_rmdir_args /* { 2023 struct vnode *a_dvp; 2024 struct vnode *a_vp; 2025 struct componentname *a_cnp; 2026 } */ *ap; 2027 { 2028 struct vnode *vp = ap->a_vp; 2029 struct vnode *dvp = ap->a_dvp; 2030 struct componentname *cnp = ap->a_cnp; 2031 u_int32_t *tl; 2032 caddr_t cp; 2033 int32_t t1, t2; 2034 caddr_t bpos, dpos, cp2; 2035 int error = 0, wccflag = NFSV3_WCCRATTR; 2036 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 2037 int v3 = NFS_ISV3(dvp); 2038 2039 if (dvp == vp) 2040 return (EINVAL); 2041 nfsstats.rpccnt[NFSPROC_RMDIR]++; 2042 nfsm_reqhead(dvp, NFSPROC_RMDIR, 2043 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); 2044 nfsm_fhtom(dvp, v3); 2045 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 2046 nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_td, cnp->cn_cred); 2047 if (v3) 2048 nfsm_wcc_data(dvp, wccflag); 2049 m_freem(mrep); 2050 nfsmout: 2051 VTONFS(dvp)->n_flag |= NMODIFIED; 2052 if (!wccflag) 2053 VTONFS(dvp)->n_attrstamp = 0; 2054 cache_purge(dvp); 2055 cache_purge(vp); 2056 /* 2057 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. 2058 */ 2059 if (error == ENOENT) 2060 error = 0; 2061 return (error); 2062 } 2063 2064 /* 2065 * nfs readdir call 2066 */ 2067 static int 2068 nfs_readdir(ap) 2069 struct vop_readdir_args /* { 2070 struct vnode *a_vp; 2071 struct uio *a_uio; 2072 struct ucred *a_cred; 2073 } */ *ap; 2074 { 2075 struct vnode *vp = ap->a_vp; 2076 struct nfsnode *np = VTONFS(vp); 2077 struct uio *uio = ap->a_uio; 2078 int tresid, error; 2079 struct vattr vattr; 2080 2081 if (vp->v_type != VDIR) 2082 return (EPERM); 2083 /* 2084 * First, check for hit on the EOF offset cache 2085 */ 2086 if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset && 2087 (np->n_flag & NMODIFIED) == 0) { 2088 if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) { 2089 if (NQNFS_CKCACHABLE(vp, ND_READ)) { 2090 nfsstats.direofcache_hits++; 2091 return (0); 2092 } 2093 } else if (VOP_GETATTR(vp, &vattr, uio->uio_td) == 0 && 2094 np->n_mtime == vattr.va_mtime.tv_sec) { 2095 nfsstats.direofcache_hits++; 2096 return (0); 2097 } 2098 } 2099 2100 /* 2101 * Call nfs_bioread() to do the real work. 2102 */ 2103 tresid = uio->uio_resid; 2104 error = nfs_bioread(vp, uio, 0); 2105 2106 if (!error && uio->uio_resid == tresid) 2107 nfsstats.direofcache_misses++; 2108 return (error); 2109 } 2110 2111 /* 2112 * Readdir rpc call. 2113 * Called from below the buffer cache by nfs_doio(). 2114 */ 2115 int 2116 nfs_readdirrpc(struct vnode *vp, struct uio *uiop) 2117 { 2118 int len, left; 2119 struct dirent *dp = NULL; 2120 u_int32_t *tl; 2121 caddr_t cp; 2122 int32_t t1, t2; 2123 nfsuint64 *cookiep; 2124 caddr_t bpos, dpos, cp2; 2125 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 2126 nfsuint64 cookie; 2127 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2128 struct nfsnode *dnp = VTONFS(vp); 2129 u_quad_t fileno; 2130 int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1; 2131 int attrflag; 2132 int v3 = NFS_ISV3(vp); 2133 2134 #ifndef DIAGNOSTIC 2135 if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) || 2136 (uiop->uio_resid & (DIRBLKSIZ - 1))) 2137 panic("nfs readdirrpc bad uio"); 2138 #endif 2139 2140 /* 2141 * If there is no cookie, assume directory was stale. 2142 */ 2143 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0); 2144 if (cookiep) 2145 cookie = *cookiep; 2146 else 2147 return (NFSERR_BAD_COOKIE); 2148 /* 2149 * Loop around doing readdir rpc's of size nm_readdirsize 2150 * truncated to a multiple of DIRBLKSIZ. 2151 * The stopping criteria is EOF or buffer full. 2152 */ 2153 while (more_dirs && bigenough) { 2154 nfsstats.rpccnt[NFSPROC_READDIR]++; 2155 nfsm_reqhead(vp, NFSPROC_READDIR, NFSX_FH(v3) + 2156 NFSX_READDIR(v3)); 2157 nfsm_fhtom(vp, v3); 2158 if (v3) { 2159 nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED); 2160 *tl++ = cookie.nfsuquad[0]; 2161 *tl++ = cookie.nfsuquad[1]; 2162 *tl++ = dnp->n_cookieverf.nfsuquad[0]; 2163 *tl++ = dnp->n_cookieverf.nfsuquad[1]; 2164 } else { 2165 nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 2166 *tl++ = cookie.nfsuquad[0]; 2167 } 2168 *tl = txdr_unsigned(nmp->nm_readdirsize); 2169 nfsm_request(vp, NFSPROC_READDIR, uiop->uio_td, nfs_vpcred(vp, ND_READ)); 2170 if (v3) { 2171 nfsm_postop_attr(vp, attrflag); 2172 if (!error) { 2173 nfsm_dissect(tl, u_int32_t *, 2174 2 * NFSX_UNSIGNED); 2175 dnp->n_cookieverf.nfsuquad[0] = *tl++; 2176 dnp->n_cookieverf.nfsuquad[1] = *tl; 2177 } else { 2178 m_freem(mrep); 2179 goto nfsmout; 2180 } 2181 } 2182 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2183 more_dirs = fxdr_unsigned(int, *tl); 2184 2185 /* loop thru the dir entries, doctoring them to 4bsd form */ 2186 while (more_dirs && bigenough) { 2187 if (v3) { 2188 nfsm_dissect(tl, u_int32_t *, 2189 3 * NFSX_UNSIGNED); 2190 fileno = fxdr_hyper(tl); 2191 len = fxdr_unsigned(int, *(tl + 2)); 2192 } else { 2193 nfsm_dissect(tl, u_int32_t *, 2194 2 * NFSX_UNSIGNED); 2195 fileno = fxdr_unsigned(u_quad_t, *tl++); 2196 len = fxdr_unsigned(int, *tl); 2197 } 2198 if (len <= 0 || len > NFS_MAXNAMLEN) { 2199 error = EBADRPC; 2200 m_freem(mrep); 2201 goto nfsmout; 2202 } 2203 tlen = nfsm_rndup(len); 2204 if (tlen == len) 2205 tlen += 4; /* To ensure null termination */ 2206 left = DIRBLKSIZ - blksiz; 2207 if ((tlen + DIRHDSIZ) > left) { 2208 dp->d_reclen += left; 2209 uiop->uio_iov->iov_base += left; 2210 uiop->uio_iov->iov_len -= left; 2211 uiop->uio_offset += left; 2212 uiop->uio_resid -= left; 2213 blksiz = 0; 2214 } 2215 if ((tlen + DIRHDSIZ) > uiop->uio_resid) 2216 bigenough = 0; 2217 if (bigenough) { 2218 dp = (struct dirent *)uiop->uio_iov->iov_base; 2219 dp->d_fileno = (int)fileno; 2220 dp->d_namlen = len; 2221 dp->d_reclen = tlen + DIRHDSIZ; 2222 dp->d_type = DT_UNKNOWN; 2223 blksiz += dp->d_reclen; 2224 if (blksiz == DIRBLKSIZ) 2225 blksiz = 0; 2226 uiop->uio_offset += DIRHDSIZ; 2227 uiop->uio_resid -= DIRHDSIZ; 2228 uiop->uio_iov->iov_base += DIRHDSIZ; 2229 uiop->uio_iov->iov_len -= DIRHDSIZ; 2230 nfsm_mtouio(uiop, len); 2231 cp = uiop->uio_iov->iov_base; 2232 tlen -= len; 2233 *cp = '\0'; /* null terminate */ 2234 uiop->uio_iov->iov_base += tlen; 2235 uiop->uio_iov->iov_len -= tlen; 2236 uiop->uio_offset += tlen; 2237 uiop->uio_resid -= tlen; 2238 } else 2239 nfsm_adv(nfsm_rndup(len)); 2240 if (v3) { 2241 nfsm_dissect(tl, u_int32_t *, 2242 3 * NFSX_UNSIGNED); 2243 } else { 2244 nfsm_dissect(tl, u_int32_t *, 2245 2 * NFSX_UNSIGNED); 2246 } 2247 if (bigenough) { 2248 cookie.nfsuquad[0] = *tl++; 2249 if (v3) 2250 cookie.nfsuquad[1] = *tl++; 2251 } else if (v3) 2252 tl += 2; 2253 else 2254 tl++; 2255 more_dirs = fxdr_unsigned(int, *tl); 2256 } 2257 /* 2258 * If at end of rpc data, get the eof boolean 2259 */ 2260 if (!more_dirs) { 2261 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2262 more_dirs = (fxdr_unsigned(int, *tl) == 0); 2263 } 2264 m_freem(mrep); 2265 } 2266 /* 2267 * Fill last record, iff any, out to a multiple of DIRBLKSIZ 2268 * by increasing d_reclen for the last record. 2269 */ 2270 if (blksiz > 0) { 2271 left = DIRBLKSIZ - blksiz; 2272 dp->d_reclen += left; 2273 uiop->uio_iov->iov_base += left; 2274 uiop->uio_iov->iov_len -= left; 2275 uiop->uio_offset += left; 2276 uiop->uio_resid -= left; 2277 } 2278 2279 /* 2280 * We are now either at the end of the directory or have filled the 2281 * block. 2282 */ 2283 if (bigenough) 2284 dnp->n_direofoffset = uiop->uio_offset; 2285 else { 2286 if (uiop->uio_resid > 0) 2287 printf("EEK! readdirrpc resid > 0\n"); 2288 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1); 2289 *cookiep = cookie; 2290 } 2291 nfsmout: 2292 return (error); 2293 } 2294 2295 /* 2296 * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc(). 2297 */ 2298 int 2299 nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) 2300 { 2301 int len, left; 2302 struct dirent *dp; 2303 u_int32_t *tl; 2304 caddr_t cp; 2305 int32_t t1, t2; 2306 struct vnode *newvp; 2307 nfsuint64 *cookiep; 2308 caddr_t bpos, dpos, cp2, dpossav1, dpossav2; 2309 struct mbuf *mreq, *mrep, *md, *mb, *mb2, *mdsav1, *mdsav2; 2310 struct nameidata nami, *ndp = &nami; 2311 struct componentname *cnp = &ndp->ni_cnd; 2312 nfsuint64 cookie; 2313 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2314 struct nfsnode *dnp = VTONFS(vp), *np; 2315 nfsfh_t *fhp; 2316 u_quad_t fileno; 2317 int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i; 2318 int attrflag, fhsize; 2319 2320 #ifndef nolint 2321 dp = (struct dirent *)0; 2322 #endif 2323 #ifndef DIAGNOSTIC 2324 if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) || 2325 (uiop->uio_resid & (DIRBLKSIZ - 1))) 2326 panic("nfs readdirplusrpc bad uio"); 2327 #endif 2328 ndp->ni_dvp = vp; 2329 newvp = NULLVP; 2330 2331 /* 2332 * If there is no cookie, assume directory was stale. 2333 */ 2334 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0); 2335 if (cookiep) 2336 cookie = *cookiep; 2337 else 2338 return (NFSERR_BAD_COOKIE); 2339 /* 2340 * Loop around doing readdir rpc's of size nm_readdirsize 2341 * truncated to a multiple of DIRBLKSIZ. 2342 * The stopping criteria is EOF or buffer full. 2343 */ 2344 while (more_dirs && bigenough) { 2345 nfsstats.rpccnt[NFSPROC_READDIRPLUS]++; 2346 nfsm_reqhead(vp, NFSPROC_READDIRPLUS, 2347 NFSX_FH(1) + 6 * NFSX_UNSIGNED); 2348 nfsm_fhtom(vp, 1); 2349 nfsm_build(tl, u_int32_t *, 6 * NFSX_UNSIGNED); 2350 *tl++ = cookie.nfsuquad[0]; 2351 *tl++ = cookie.nfsuquad[1]; 2352 *tl++ = dnp->n_cookieverf.nfsuquad[0]; 2353 *tl++ = dnp->n_cookieverf.nfsuquad[1]; 2354 *tl++ = txdr_unsigned(nmp->nm_readdirsize); 2355 *tl = txdr_unsigned(nmp->nm_rsize); 2356 nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_td, nfs_vpcred(vp, ND_READ)); 2357 nfsm_postop_attr(vp, attrflag); 2358 if (error) { 2359 m_freem(mrep); 2360 goto nfsmout; 2361 } 2362 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); 2363 dnp->n_cookieverf.nfsuquad[0] = *tl++; 2364 dnp->n_cookieverf.nfsuquad[1] = *tl++; 2365 more_dirs = fxdr_unsigned(int, *tl); 2366 2367 /* loop thru the dir entries, doctoring them to 4bsd form */ 2368 while (more_dirs && bigenough) { 2369 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); 2370 fileno = fxdr_hyper(tl); 2371 len = fxdr_unsigned(int, *(tl + 2)); 2372 if (len <= 0 || len > NFS_MAXNAMLEN) { 2373 error = EBADRPC; 2374 m_freem(mrep); 2375 goto nfsmout; 2376 } 2377 tlen = nfsm_rndup(len); 2378 if (tlen == len) 2379 tlen += 4; /* To ensure null termination*/ 2380 left = DIRBLKSIZ - blksiz; 2381 if ((tlen + DIRHDSIZ) > left) { 2382 dp->d_reclen += left; 2383 uiop->uio_iov->iov_base += left; 2384 uiop->uio_iov->iov_len -= left; 2385 uiop->uio_offset += left; 2386 uiop->uio_resid -= left; 2387 blksiz = 0; 2388 } 2389 if ((tlen + DIRHDSIZ) > uiop->uio_resid) 2390 bigenough = 0; 2391 if (bigenough) { 2392 dp = (struct dirent *)uiop->uio_iov->iov_base; 2393 dp->d_fileno = (int)fileno; 2394 dp->d_namlen = len; 2395 dp->d_reclen = tlen + DIRHDSIZ; 2396 dp->d_type = DT_UNKNOWN; 2397 blksiz += dp->d_reclen; 2398 if (blksiz == DIRBLKSIZ) 2399 blksiz = 0; 2400 uiop->uio_offset += DIRHDSIZ; 2401 uiop->uio_resid -= DIRHDSIZ; 2402 uiop->uio_iov->iov_base += DIRHDSIZ; 2403 uiop->uio_iov->iov_len -= DIRHDSIZ; 2404 cnp->cn_nameptr = uiop->uio_iov->iov_base; 2405 cnp->cn_namelen = len; 2406 nfsm_mtouio(uiop, len); 2407 cp = uiop->uio_iov->iov_base; 2408 tlen -= len; 2409 *cp = '\0'; 2410 uiop->uio_iov->iov_base += tlen; 2411 uiop->uio_iov->iov_len -= tlen; 2412 uiop->uio_offset += tlen; 2413 uiop->uio_resid -= tlen; 2414 } else 2415 nfsm_adv(nfsm_rndup(len)); 2416 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); 2417 if (bigenough) { 2418 cookie.nfsuquad[0] = *tl++; 2419 cookie.nfsuquad[1] = *tl++; 2420 } else 2421 tl += 2; 2422 2423 /* 2424 * Since the attributes are before the file handle 2425 * (sigh), we must skip over the attributes and then 2426 * come back and get them. 2427 */ 2428 attrflag = fxdr_unsigned(int, *tl); 2429 if (attrflag) { 2430 dpossav1 = dpos; 2431 mdsav1 = md; 2432 nfsm_adv(NFSX_V3FATTR); 2433 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2434 doit = fxdr_unsigned(int, *tl); 2435 if (doit) { 2436 nfsm_getfh(fhp, fhsize, 1); 2437 if (NFS_CMPFH(dnp, fhp, fhsize)) { 2438 VREF(vp); 2439 newvp = vp; 2440 np = dnp; 2441 } else { 2442 error = nfs_nget(vp->v_mount, fhp, 2443 fhsize, &np); 2444 if (error) 2445 doit = 0; 2446 else 2447 newvp = NFSTOV(np); 2448 } 2449 } 2450 if (doit && bigenough) { 2451 dpossav2 = dpos; 2452 dpos = dpossav1; 2453 mdsav2 = md; 2454 md = mdsav1; 2455 nfsm_loadattr(newvp, (struct vattr *)0); 2456 dpos = dpossav2; 2457 md = mdsav2; 2458 dp->d_type = 2459 IFTODT(VTTOIF(np->n_vattr.va_type)); 2460 ndp->ni_vp = newvp; 2461 cache_enter(ndp->ni_dvp, NCPNULL, ndp->ni_vp, cnp); 2462 } 2463 } else { 2464 /* Just skip over the file handle */ 2465 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2466 i = fxdr_unsigned(int, *tl); 2467 nfsm_adv(nfsm_rndup(i)); 2468 } 2469 if (newvp != NULLVP) { 2470 if (newvp == vp) 2471 vrele(newvp); 2472 else 2473 vput(newvp); 2474 newvp = NULLVP; 2475 } 2476 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2477 more_dirs = fxdr_unsigned(int, *tl); 2478 } 2479 /* 2480 * If at end of rpc data, get the eof boolean 2481 */ 2482 if (!more_dirs) { 2483 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2484 more_dirs = (fxdr_unsigned(int, *tl) == 0); 2485 } 2486 m_freem(mrep); 2487 } 2488 /* 2489 * Fill last record, iff any, out to a multiple of DIRBLKSIZ 2490 * by increasing d_reclen for the last record. 2491 */ 2492 if (blksiz > 0) { 2493 left = DIRBLKSIZ - blksiz; 2494 dp->d_reclen += left; 2495 uiop->uio_iov->iov_base += left; 2496 uiop->uio_iov->iov_len -= left; 2497 uiop->uio_offset += left; 2498 uiop->uio_resid -= left; 2499 } 2500 2501 /* 2502 * We are now either at the end of the directory or have filled the 2503 * block. 2504 */ 2505 if (bigenough) 2506 dnp->n_direofoffset = uiop->uio_offset; 2507 else { 2508 if (uiop->uio_resid > 0) 2509 printf("EEK! readdirplusrpc resid > 0\n"); 2510 cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1); 2511 *cookiep = cookie; 2512 } 2513 nfsmout: 2514 if (newvp != NULLVP) { 2515 if (newvp == vp) 2516 vrele(newvp); 2517 else 2518 vput(newvp); 2519 newvp = NULLVP; 2520 } 2521 return (error); 2522 } 2523 2524 /* 2525 * Silly rename. To make the NFS filesystem that is stateless look a little 2526 * more like the "ufs" a remove of an active vnode is translated to a rename 2527 * to a funny looking filename that is removed by nfs_inactive on the 2528 * nfsnode. There is the potential for another process on a different client 2529 * to create the same funny name between the nfs_lookitup() fails and the 2530 * nfs_rename() completes, but... 2531 */ 2532 static int 2533 nfs_sillyrename(dvp, vp, cnp) 2534 struct vnode *dvp, *vp; 2535 struct componentname *cnp; 2536 { 2537 struct sillyrename *sp; 2538 struct nfsnode *np; 2539 int error; 2540 2541 cache_purge(dvp); 2542 np = VTONFS(vp); 2543 #ifndef DIAGNOSTIC 2544 if (vp->v_type == VDIR) 2545 panic("nfs: sillyrename dir"); 2546 #endif 2547 MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename), 2548 M_NFSREQ, M_WAITOK); 2549 sp->s_cred = crdup(cnp->cn_cred); 2550 sp->s_dvp = dvp; 2551 VREF(dvp); 2552 2553 /* Fudge together a funny name */ 2554 sp->s_namlen = sprintf(sp->s_name, ".nfsA%08x4.4", (int)cnp->cn_td); 2555 2556 /* Try lookitups until we get one that isn't there */ 2557 while (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2558 cnp->cn_td, (struct nfsnode **)0) == 0) { 2559 sp->s_name[4]++; 2560 if (sp->s_name[4] > 'z') { 2561 error = EINVAL; 2562 goto bad; 2563 } 2564 } 2565 error = nfs_renameit(dvp, cnp, sp); 2566 if (error) 2567 goto bad; 2568 error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2569 cnp->cn_td, &np); 2570 np->n_sillyrename = sp; 2571 return (0); 2572 bad: 2573 vrele(sp->s_dvp); 2574 crfree(sp->s_cred); 2575 free((caddr_t)sp, M_NFSREQ); 2576 return (error); 2577 } 2578 2579 /* 2580 * Look up a file name and optionally either update the file handle or 2581 * allocate an nfsnode, depending on the value of npp. 2582 * npp == NULL --> just do the lookup 2583 * *npp == NULL --> allocate a new nfsnode and make sure attributes are 2584 * handled too 2585 * *npp != NULL --> update the file handle in the vnode 2586 */ 2587 static int 2588 nfs_lookitup(dvp, name, len, cred, td, npp) 2589 struct vnode *dvp; 2590 const char *name; 2591 int len; 2592 struct ucred *cred; 2593 struct thread *td; 2594 struct nfsnode **npp; 2595 { 2596 u_int32_t *tl; 2597 caddr_t cp; 2598 int32_t t1, t2; 2599 struct vnode *newvp = (struct vnode *)0; 2600 struct nfsnode *np, *dnp = VTONFS(dvp); 2601 caddr_t bpos, dpos, cp2; 2602 int error = 0, fhlen, attrflag; 2603 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 2604 nfsfh_t *nfhp; 2605 int v3 = NFS_ISV3(dvp); 2606 2607 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 2608 nfsm_reqhead(dvp, NFSPROC_LOOKUP, 2609 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); 2610 nfsm_fhtom(dvp, v3); 2611 nfsm_strtom(name, len, NFS_MAXNAMLEN); 2612 nfsm_request(dvp, NFSPROC_LOOKUP, td, cred); 2613 if (npp && !error) { 2614 nfsm_getfh(nfhp, fhlen, v3); 2615 if (*npp) { 2616 np = *npp; 2617 if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) { 2618 free((caddr_t)np->n_fhp, M_NFSBIGFH); 2619 np->n_fhp = &np->n_fh; 2620 } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH) 2621 np->n_fhp =(nfsfh_t *)malloc(fhlen,M_NFSBIGFH,M_WAITOK); 2622 bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen); 2623 np->n_fhsize = fhlen; 2624 newvp = NFSTOV(np); 2625 } else if (NFS_CMPFH(dnp, nfhp, fhlen)) { 2626 VREF(dvp); 2627 newvp = dvp; 2628 } else { 2629 error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np); 2630 if (error) { 2631 m_freem(mrep); 2632 return (error); 2633 } 2634 newvp = NFSTOV(np); 2635 } 2636 if (v3) { 2637 nfsm_postop_attr(newvp, attrflag); 2638 if (!attrflag && *npp == NULL) { 2639 m_freem(mrep); 2640 if (newvp == dvp) 2641 vrele(newvp); 2642 else 2643 vput(newvp); 2644 return (ENOENT); 2645 } 2646 } else 2647 nfsm_loadattr(newvp, (struct vattr *)0); 2648 } 2649 m_freem(mrep); 2650 nfsmout: 2651 if (npp && *npp == NULL) { 2652 if (error) { 2653 if (newvp) { 2654 if (newvp == dvp) 2655 vrele(newvp); 2656 else 2657 vput(newvp); 2658 } 2659 } else 2660 *npp = np; 2661 } 2662 return (error); 2663 } 2664 2665 /* 2666 * Nfs Version 3 commit rpc 2667 */ 2668 int 2669 nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct thread *td) 2670 { 2671 caddr_t cp; 2672 u_int32_t *tl; 2673 int32_t t1, t2; 2674 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2675 caddr_t bpos, dpos, cp2; 2676 int error = 0, wccflag = NFSV3_WCCRATTR; 2677 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 2678 2679 if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) 2680 return (0); 2681 nfsstats.rpccnt[NFSPROC_COMMIT]++; 2682 nfsm_reqhead(vp, NFSPROC_COMMIT, NFSX_FH(1)); 2683 nfsm_fhtom(vp, 1); 2684 nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); 2685 txdr_hyper(offset, tl); 2686 tl += 2; 2687 *tl = txdr_unsigned(cnt); 2688 nfsm_request(vp, NFSPROC_COMMIT, td, nfs_vpcred(vp, ND_WRITE)); 2689 nfsm_wcc_data(vp, wccflag); 2690 if (!error) { 2691 nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF); 2692 if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl, 2693 NFSX_V3WRITEVERF)) { 2694 bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, 2695 NFSX_V3WRITEVERF); 2696 error = NFSERR_STALEWRITEVERF; 2697 } 2698 } 2699 m_freem(mrep); 2700 nfsmout: 2701 return (error); 2702 } 2703 2704 /* 2705 * Kludge City.. 2706 * - make nfs_bmap() essentially a no-op that does no translation 2707 * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc 2708 * (Maybe I could use the process's page mapping, but I was concerned that 2709 * Kernel Write might not be enabled and also figured copyout() would do 2710 * a lot more work than bcopy() and also it currently happens in the 2711 * context of the swapper process (2). 2712 */ 2713 static int 2714 nfs_bmap(ap) 2715 struct vop_bmap_args /* { 2716 struct vnode *a_vp; 2717 daddr_t a_bn; 2718 struct vnode **a_vpp; 2719 daddr_t *a_bnp; 2720 int *a_runp; 2721 int *a_runb; 2722 } */ *ap; 2723 { 2724 struct vnode *vp = ap->a_vp; 2725 2726 if (ap->a_vpp != NULL) 2727 *ap->a_vpp = vp; 2728 if (ap->a_bnp != NULL) 2729 *ap->a_bnp = ap->a_bn * btodb(vp->v_mount->mnt_stat.f_iosize); 2730 if (ap->a_runp != NULL) 2731 *ap->a_runp = 0; 2732 if (ap->a_runb != NULL) 2733 *ap->a_runb = 0; 2734 return (0); 2735 } 2736 2737 /* 2738 * Strategy routine. 2739 * For async requests when nfsiod(s) are running, queue the request by 2740 * calling nfs_asyncio(), otherwise just all nfs_doio() to do the 2741 * request. 2742 */ 2743 static int 2744 nfs_strategy(ap) 2745 struct vop_strategy_args *ap; 2746 { 2747 struct buf *bp = ap->a_bp; 2748 struct thread *td; 2749 int error = 0; 2750 2751 KASSERT(!(bp->b_flags & B_DONE), ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp)); 2752 KASSERT(BUF_REFCNT(bp) > 0, ("nfs_strategy: buffer %p not locked", bp)); 2753 2754 if (bp->b_flags & B_PHYS) 2755 panic("nfs physio"); 2756 2757 if (bp->b_flags & B_ASYNC) 2758 td = NULL; 2759 else 2760 td = curthread; /* XXX */ 2761 2762 /* 2763 * If the op is asynchronous and an i/o daemon is waiting 2764 * queue the request, wake it up and wait for completion 2765 * otherwise just do it ourselves. 2766 */ 2767 if ((bp->b_flags & B_ASYNC) == 0 || 2768 nfs_asyncio(bp, td)) 2769 error = nfs_doio(bp, td); 2770 return (error); 2771 } 2772 2773 /* 2774 * Mmap a file 2775 * 2776 * NB Currently unsupported. 2777 */ 2778 /* ARGSUSED */ 2779 static int 2780 nfs_mmap(ap) 2781 struct vop_mmap_args /* { 2782 struct vnode *a_vp; 2783 int a_fflags; 2784 struct ucred *a_cred; 2785 struct thread *a_td; 2786 } */ *ap; 2787 { 2788 2789 return (EINVAL); 2790 } 2791 2792 /* 2793 * fsync vnode op. Just call nfs_flush() with commit == 1. 2794 */ 2795 /* ARGSUSED */ 2796 static int 2797 nfs_fsync(ap) 2798 struct vop_fsync_args /* { 2799 struct vnodeop_desc *a_desc; 2800 struct vnode * a_vp; 2801 struct ucred * a_cred; 2802 int a_waitfor; 2803 struct thread * a_td; 2804 } */ *ap; 2805 { 2806 2807 return (nfs_flush(ap->a_vp, ap->a_waitfor, ap->a_td, 1)); 2808 } 2809 2810 /* 2811 * Flush all the blocks associated with a vnode. 2812 * Walk through the buffer pool and push any dirty pages 2813 * associated with the vnode. 2814 */ 2815 static int 2816 nfs_flush(vp, waitfor, td, commit) 2817 struct vnode *vp; 2818 int waitfor; 2819 struct thread *td; 2820 int commit; 2821 { 2822 struct nfsnode *np = VTONFS(vp); 2823 struct buf *bp; 2824 int i; 2825 struct buf *nbp; 2826 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2827 int s, error = 0, slptimeo = 0, slpflag = 0, retv, bvecpos; 2828 int passone = 1; 2829 u_quad_t off, endoff, toff; 2830 struct buf **bvec = NULL; 2831 #ifndef NFS_COMMITBVECSIZ 2832 #define NFS_COMMITBVECSIZ 20 2833 #endif 2834 struct buf *bvec_on_stack[NFS_COMMITBVECSIZ]; 2835 int bvecsize = 0, bveccount; 2836 2837 if (nmp->nm_flag & NFSMNT_INT) 2838 slpflag = PCATCH; 2839 if (!commit) 2840 passone = 0; 2841 /* 2842 * A b_flags == (B_DELWRI | B_NEEDCOMMIT) block has been written to the 2843 * server, but nas not been committed to stable storage on the server 2844 * yet. On the first pass, the byte range is worked out and the commit 2845 * rpc is done. On the second pass, nfs_writebp() is called to do the 2846 * job. 2847 */ 2848 again: 2849 off = (u_quad_t)-1; 2850 endoff = 0; 2851 bvecpos = 0; 2852 if (NFS_ISV3(vp) && commit) { 2853 s = splbio(); 2854 /* 2855 * Count up how many buffers waiting for a commit. 2856 */ 2857 bveccount = 0; 2858 for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { 2859 nbp = TAILQ_NEXT(bp, b_vnbufs); 2860 if (BUF_REFCNT(bp) == 0 && 2861 (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) 2862 == (B_DELWRI | B_NEEDCOMMIT)) 2863 bveccount++; 2864 } 2865 /* 2866 * Allocate space to remember the list of bufs to commit. It is 2867 * important to use M_NOWAIT here to avoid a race with nfs_write. 2868 * If we can't get memory (for whatever reason), we will end up 2869 * committing the buffers one-by-one in the loop below. 2870 */ 2871 if (bvec != NULL && bvec != bvec_on_stack) 2872 free(bvec, M_TEMP); 2873 if (bveccount > NFS_COMMITBVECSIZ) { 2874 bvec = (struct buf **) 2875 malloc(bveccount * sizeof(struct buf *), 2876 M_TEMP, M_NOWAIT); 2877 if (bvec == NULL) { 2878 bvec = bvec_on_stack; 2879 bvecsize = NFS_COMMITBVECSIZ; 2880 } else 2881 bvecsize = bveccount; 2882 } else { 2883 bvec = bvec_on_stack; 2884 bvecsize = NFS_COMMITBVECSIZ; 2885 } 2886 for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { 2887 nbp = TAILQ_NEXT(bp, b_vnbufs); 2888 if (bvecpos >= bvecsize) 2889 break; 2890 if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != 2891 (B_DELWRI | B_NEEDCOMMIT) || 2892 BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) 2893 continue; 2894 bremfree(bp); 2895 /* 2896 * NOTE: we are not clearing B_DONE here, so we have 2897 * to do it later on in this routine if we intend to 2898 * initiate I/O on the bp. 2899 * 2900 * Note: to avoid loopback deadlocks, we do not 2901 * assign b_runningbufspace. 2902 */ 2903 bp->b_flags |= B_WRITEINPROG; 2904 vfs_busy_pages(bp, 1); 2905 2906 /* 2907 * bp is protected by being locked, but nbp is not 2908 * and vfs_busy_pages() may sleep. We have to 2909 * recalculate nbp. 2910 */ 2911 nbp = TAILQ_NEXT(bp, b_vnbufs); 2912 2913 /* 2914 * A list of these buffers is kept so that the 2915 * second loop knows which buffers have actually 2916 * been committed. This is necessary, since there 2917 * may be a race between the commit rpc and new 2918 * uncommitted writes on the file. 2919 */ 2920 bvec[bvecpos++] = bp; 2921 toff = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + 2922 bp->b_dirtyoff; 2923 if (toff < off) 2924 off = toff; 2925 toff += (u_quad_t)(bp->b_dirtyend - bp->b_dirtyoff); 2926 if (toff > endoff) 2927 endoff = toff; 2928 } 2929 splx(s); 2930 } 2931 if (bvecpos > 0) { 2932 /* 2933 * Commit data on the server, as required. Note that 2934 * nfs_commit will use the vnode's cred for the commit. 2935 */ 2936 retv = nfs_commit(vp, off, (int)(endoff - off), td); 2937 2938 if (retv == NFSERR_STALEWRITEVERF) 2939 nfs_clearcommit(vp->v_mount); 2940 2941 /* 2942 * Now, either mark the blocks I/O done or mark the 2943 * blocks dirty, depending on whether the commit 2944 * succeeded. 2945 */ 2946 for (i = 0; i < bvecpos; i++) { 2947 bp = bvec[i]; 2948 bp->b_flags &= ~(B_NEEDCOMMIT | B_WRITEINPROG | B_CLUSTEROK); 2949 if (retv) { 2950 /* 2951 * Error, leave B_DELWRI intact 2952 */ 2953 vfs_unbusy_pages(bp); 2954 brelse(bp); 2955 } else { 2956 /* 2957 * Success, remove B_DELWRI ( bundirty() ). 2958 * 2959 * b_dirtyoff/b_dirtyend seem to be NFS 2960 * specific. We should probably move that 2961 * into bundirty(). XXX 2962 */ 2963 s = splbio(); 2964 vp->v_numoutput++; 2965 bp->b_flags |= B_ASYNC; 2966 bundirty(bp); 2967 bp->b_flags &= ~(B_READ|B_DONE|B_ERROR); 2968 bp->b_dirtyoff = bp->b_dirtyend = 0; 2969 splx(s); 2970 biodone(bp); 2971 } 2972 } 2973 } 2974 2975 /* 2976 * Start/do any write(s) that are required. 2977 */ 2978 loop: 2979 s = splbio(); 2980 for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { 2981 nbp = TAILQ_NEXT(bp, b_vnbufs); 2982 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) { 2983 if (waitfor != MNT_WAIT || passone) 2984 continue; 2985 error = BUF_TIMELOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL, 2986 "nfsfsync", slpflag, slptimeo); 2987 splx(s); 2988 if (error == 0) 2989 panic("nfs_fsync: inconsistent lock"); 2990 if (error == ENOLCK) 2991 goto loop; 2992 if (nfs_sigintr(nmp, (struct nfsreq *)0, td)) { 2993 error = EINTR; 2994 goto done; 2995 } 2996 if (slpflag == PCATCH) { 2997 slpflag = 0; 2998 slptimeo = 2 * hz; 2999 } 3000 goto loop; 3001 } 3002 if ((bp->b_flags & B_DELWRI) == 0) 3003 panic("nfs_fsync: not dirty"); 3004 if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) { 3005 BUF_UNLOCK(bp); 3006 continue; 3007 } 3008 bremfree(bp); 3009 if (passone || !commit) 3010 bp->b_flags |= B_ASYNC; 3011 else 3012 bp->b_flags |= B_ASYNC | B_WRITEINPROG; 3013 splx(s); 3014 VOP_BWRITE(bp->b_vp, bp); 3015 goto loop; 3016 } 3017 splx(s); 3018 if (passone) { 3019 passone = 0; 3020 goto again; 3021 } 3022 if (waitfor == MNT_WAIT) { 3023 while (vp->v_numoutput) { 3024 vp->v_flag |= VBWAIT; 3025 error = tsleep((caddr_t)&vp->v_numoutput, 3026 slpflag, "nfsfsync", slptimeo); 3027 if (error) { 3028 if (nfs_sigintr(nmp, (struct nfsreq *)0, td)) { 3029 error = EINTR; 3030 goto done; 3031 } 3032 if (slpflag == PCATCH) { 3033 slpflag = 0; 3034 slptimeo = 2 * hz; 3035 } 3036 } 3037 } 3038 if (!TAILQ_EMPTY(&vp->v_dirtyblkhd) && commit) { 3039 goto loop; 3040 } 3041 } 3042 if (np->n_flag & NWRITEERR) { 3043 error = np->n_error; 3044 np->n_flag &= ~NWRITEERR; 3045 } 3046 done: 3047 if (bvec != NULL && bvec != bvec_on_stack) 3048 free(bvec, M_TEMP); 3049 return (error); 3050 } 3051 3052 /* 3053 * NFS advisory byte-level locks. 3054 * Currently unsupported. 3055 */ 3056 static int 3057 nfs_advlock(ap) 3058 struct vop_advlock_args /* { 3059 struct vnode *a_vp; 3060 caddr_t a_id; 3061 int a_op; 3062 struct flock *a_fl; 3063 int a_flags; 3064 } */ *ap; 3065 { 3066 struct nfsnode *np = VTONFS(ap->a_vp); 3067 3068 /* 3069 * The following kludge is to allow diskless support to work 3070 * until a real NFS lockd is implemented. Basically, just pretend 3071 * that this is a local lock. 3072 */ 3073 return (lf_advlock(ap, &(np->n_lockf), np->n_size)); 3074 } 3075 3076 /* 3077 * Print out the contents of an nfsnode. 3078 */ 3079 static int 3080 nfs_print(ap) 3081 struct vop_print_args /* { 3082 struct vnode *a_vp; 3083 } */ *ap; 3084 { 3085 struct vnode *vp = ap->a_vp; 3086 struct nfsnode *np = VTONFS(vp); 3087 3088 printf("tag VT_NFS, fileid %ld fsid 0x%x", 3089 np->n_vattr.va_fileid, np->n_vattr.va_fsid); 3090 if (vp->v_type == VFIFO) 3091 fifo_printinfo(vp); 3092 printf("\n"); 3093 return (0); 3094 } 3095 3096 /* 3097 * Just call nfs_writebp() with the force argument set to 1. 3098 * 3099 * NOTE: B_DONE may or may not be set in a_bp on call. 3100 */ 3101 static int 3102 nfs_bwrite(ap) 3103 struct vop_bwrite_args /* { 3104 struct vnode *a_bp; 3105 } */ *ap; 3106 { 3107 return (nfs_writebp(ap->a_bp, 1, curthread)); 3108 } 3109 3110 /* 3111 * This is a clone of vn_bwrite(), except that B_WRITEINPROG isn't set unless 3112 * the force flag is one and it also handles the B_NEEDCOMMIT flag. We set 3113 * B_CACHE if this is a VMIO buffer. 3114 */ 3115 int 3116 nfs_writebp(bp, force, td) 3117 struct buf *bp; 3118 int force; 3119 struct thread *td; 3120 { 3121 int s; 3122 int oldflags = bp->b_flags; 3123 #if 0 3124 int retv = 1; 3125 off_t off; 3126 #endif 3127 3128 if (BUF_REFCNT(bp) == 0) 3129 panic("bwrite: buffer is not locked???"); 3130 3131 if (bp->b_flags & B_INVAL) { 3132 brelse(bp); 3133 return(0); 3134 } 3135 3136 bp->b_flags |= B_CACHE; 3137 3138 /* 3139 * Undirty the bp. We will redirty it later if the I/O fails. 3140 */ 3141 3142 s = splbio(); 3143 bundirty(bp); 3144 bp->b_flags &= ~(B_READ|B_DONE|B_ERROR); 3145 3146 bp->b_vp->v_numoutput++; 3147 splx(s); 3148 3149 /* 3150 * Note: to avoid loopback deadlocks, we do not 3151 * assign b_runningbufspace. 3152 */ 3153 vfs_busy_pages(bp, 1); 3154 3155 if (force) 3156 bp->b_flags |= B_WRITEINPROG; 3157 BUF_KERNPROC(bp); 3158 VOP_STRATEGY(bp->b_vp, bp); 3159 3160 if( (oldflags & B_ASYNC) == 0) { 3161 int rtval = biowait(bp); 3162 3163 if (oldflags & B_DELWRI) { 3164 s = splbio(); 3165 reassignbuf(bp, bp->b_vp); 3166 splx(s); 3167 } 3168 3169 brelse(bp); 3170 return (rtval); 3171 } 3172 3173 return (0); 3174 } 3175 3176 /* 3177 * nfs special file access vnode op. 3178 * Essentially just get vattr and then imitate iaccess() since the device is 3179 * local to the client. 3180 */ 3181 static int 3182 nfsspec_access(ap) 3183 struct vop_access_args /* { 3184 struct vnode *a_vp; 3185 int a_mode; 3186 struct ucred *a_cred; 3187 struct thread *a_td; 3188 } */ *ap; 3189 { 3190 struct vattr *vap; 3191 gid_t *gp; 3192 struct ucred *cred = ap->a_cred; 3193 struct vnode *vp = ap->a_vp; 3194 mode_t mode = ap->a_mode; 3195 struct vattr vattr; 3196 int i; 3197 int error; 3198 3199 /* 3200 * Disallow write attempts on filesystems mounted read-only; 3201 * unless the file is a socket, fifo, or a block or character 3202 * device resident on the filesystem. 3203 */ 3204 if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { 3205 switch (vp->v_type) { 3206 case VREG: 3207 case VDIR: 3208 case VLNK: 3209 return (EROFS); 3210 default: 3211 break; 3212 } 3213 } 3214 /* 3215 * If you're the super-user, 3216 * you always get access. 3217 */ 3218 if (cred->cr_uid == 0) 3219 return (0); 3220 vap = &vattr; 3221 error = VOP_GETATTR(vp, vap, ap->a_td); 3222 if (error) 3223 return (error); 3224 /* 3225 * Access check is based on only one of owner, group, public. 3226 * If not owner, then check group. If not a member of the 3227 * group, then check public access. 3228 */ 3229 if (cred->cr_uid != vap->va_uid) { 3230 mode >>= 3; 3231 gp = cred->cr_groups; 3232 for (i = 0; i < cred->cr_ngroups; i++, gp++) 3233 if (vap->va_gid == *gp) 3234 goto found; 3235 mode >>= 3; 3236 found: 3237 ; 3238 } 3239 error = (vap->va_mode & mode) == mode ? 0 : EACCES; 3240 return (error); 3241 } 3242 3243 /* 3244 * Read wrapper for special devices. 3245 */ 3246 static int 3247 nfsspec_read(ap) 3248 struct vop_read_args /* { 3249 struct vnode *a_vp; 3250 struct uio *a_uio; 3251 int a_ioflag; 3252 struct ucred *a_cred; 3253 } */ *ap; 3254 { 3255 struct nfsnode *np = VTONFS(ap->a_vp); 3256 3257 /* 3258 * Set access flag. 3259 */ 3260 np->n_flag |= NACC; 3261 getnanotime(&np->n_atim); 3262 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap)); 3263 } 3264 3265 /* 3266 * Write wrapper for special devices. 3267 */ 3268 static int 3269 nfsspec_write(ap) 3270 struct vop_write_args /* { 3271 struct vnode *a_vp; 3272 struct uio *a_uio; 3273 int a_ioflag; 3274 struct ucred *a_cred; 3275 } */ *ap; 3276 { 3277 struct nfsnode *np = VTONFS(ap->a_vp); 3278 3279 /* 3280 * Set update flag. 3281 */ 3282 np->n_flag |= NUPD; 3283 getnanotime(&np->n_mtim); 3284 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap)); 3285 } 3286 3287 /* 3288 * Close wrapper for special devices. 3289 * 3290 * Update the times on the nfsnode then do device close. 3291 */ 3292 static int 3293 nfsspec_close(ap) 3294 struct vop_close_args /* { 3295 struct vnode *a_vp; 3296 int a_fflag; 3297 struct ucred *a_cred; 3298 struct thread *a_td; 3299 } */ *ap; 3300 { 3301 struct vnode *vp = ap->a_vp; 3302 struct nfsnode *np = VTONFS(vp); 3303 struct vattr vattr; 3304 3305 if (np->n_flag & (NACC | NUPD)) { 3306 np->n_flag |= NCHG; 3307 if (vp->v_usecount == 1 && 3308 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 3309 VATTR_NULL(&vattr); 3310 if (np->n_flag & NACC) 3311 vattr.va_atime = np->n_atim; 3312 if (np->n_flag & NUPD) 3313 vattr.va_mtime = np->n_mtim; 3314 (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE), ap->a_td); 3315 } 3316 } 3317 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap)); 3318 } 3319 3320 /* 3321 * Read wrapper for fifos. 3322 */ 3323 static int 3324 nfsfifo_read(ap) 3325 struct vop_read_args /* { 3326 struct vnode *a_vp; 3327 struct uio *a_uio; 3328 int a_ioflag; 3329 struct ucred *a_cred; 3330 } */ *ap; 3331 { 3332 struct nfsnode *np = VTONFS(ap->a_vp); 3333 3334 /* 3335 * Set access flag. 3336 */ 3337 np->n_flag |= NACC; 3338 getnanotime(&np->n_atim); 3339 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap)); 3340 } 3341 3342 /* 3343 * Write wrapper for fifos. 3344 */ 3345 static int 3346 nfsfifo_write(ap) 3347 struct vop_write_args /* { 3348 struct vnode *a_vp; 3349 struct uio *a_uio; 3350 int a_ioflag; 3351 struct ucred *a_cred; 3352 } */ *ap; 3353 { 3354 struct nfsnode *np = VTONFS(ap->a_vp); 3355 3356 /* 3357 * Set update flag. 3358 */ 3359 np->n_flag |= NUPD; 3360 getnanotime(&np->n_mtim); 3361 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap)); 3362 } 3363 3364 /* 3365 * Close wrapper for fifos. 3366 * 3367 * Update the times on the nfsnode then do fifo close. 3368 */ 3369 static int 3370 nfsfifo_close(ap) 3371 struct vop_close_args /* { 3372 struct vnode *a_vp; 3373 int a_fflag; 3374 struct thread *a_td; 3375 } */ *ap; 3376 { 3377 struct vnode *vp = ap->a_vp; 3378 struct nfsnode *np = VTONFS(vp); 3379 struct vattr vattr; 3380 struct timespec ts; 3381 3382 if (np->n_flag & (NACC | NUPD)) { 3383 getnanotime(&ts); 3384 if (np->n_flag & NACC) 3385 np->n_atim = ts; 3386 if (np->n_flag & NUPD) 3387 np->n_mtim = ts; 3388 np->n_flag |= NCHG; 3389 if (vp->v_usecount == 1 && 3390 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 3391 VATTR_NULL(&vattr); 3392 if (np->n_flag & NACC) 3393 vattr.va_atime = np->n_atim; 3394 if (np->n_flag & NUPD) 3395 vattr.va_mtime = np->n_mtim; 3396 (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE), ap->a_td); 3397 } 3398 } 3399 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap)); 3400 } 3401 3402