1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * 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 * %sccs.include.redist.c% 9 * 10 * @(#)nfs_vnops.c 7.85 (Berkeley) 07/03/92 11 */ 12 13 /* 14 * vnode op calls for sun nfs version 2 15 */ 16 17 #include <sys/param.h> 18 #include <sys/proc.h> 19 #include <sys/kernel.h> 20 #include <sys/systm.h> 21 #include <sys/mount.h> 22 #include <sys/buf.h> 23 #include <sys/malloc.h> 24 #include <sys/mbuf.h> 25 #include <sys/conf.h> 26 #include <sys/namei.h> 27 #include <sys/vnode.h> 28 #include <sys/specdev.h> 29 #include <sys/fifo.h> 30 #include <sys/map.h> 31 32 #include <vm/vm.h> 33 34 #include <nfs/rpcv2.h> 35 #include <nfs/nfsv2.h> 36 #include <nfs/nfs.h> 37 #include <nfs/nfsnode.h> 38 #include <nfs/nfsmount.h> 39 #include <nfs/xdr_subs.h> 40 #include <nfs/nfsm_subs.h> 41 #include <nfs/nqnfs.h> 42 43 /* Defs */ 44 #define TRUE 1 45 #define FALSE 0 46 47 /* 48 * Global vfs data structures for nfs 49 */ 50 int (**nfsv2_vnodeop_p)(); 51 struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = { 52 { &vop_default_desc, vn_default_error }, 53 { &vop_lookup_desc, nfs_lookup }, /* lookup */ 54 { &vop_create_desc, nfs_create }, /* create */ 55 { &vop_mknod_desc, nfs_mknod }, /* mknod */ 56 { &vop_open_desc, nfs_open }, /* open */ 57 { &vop_close_desc, nfs_close }, /* close */ 58 { &vop_access_desc, nfs_access }, /* access */ 59 { &vop_getattr_desc, nfs_getattr }, /* getattr */ 60 { &vop_setattr_desc, nfs_setattr }, /* setattr */ 61 { &vop_read_desc, nfs_read }, /* read */ 62 { &vop_write_desc, nfs_write }, /* write */ 63 { &vop_ioctl_desc, nfs_ioctl }, /* ioctl */ 64 { &vop_select_desc, nfs_select }, /* select */ 65 { &vop_mmap_desc, nfs_mmap }, /* mmap */ 66 { &vop_fsync_desc, nfs_fsync }, /* fsync */ 67 { &vop_seek_desc, nfs_seek }, /* seek */ 68 { &vop_remove_desc, nfs_remove }, /* remove */ 69 { &vop_link_desc, nfs_link }, /* link */ 70 { &vop_rename_desc, nfs_rename }, /* rename */ 71 { &vop_mkdir_desc, nfs_mkdir }, /* mkdir */ 72 { &vop_rmdir_desc, nfs_rmdir }, /* rmdir */ 73 { &vop_symlink_desc, nfs_symlink }, /* symlink */ 74 { &vop_readdir_desc, nfs_readdir }, /* readdir */ 75 { &vop_readlink_desc, nfs_readlink }, /* readlink */ 76 { &vop_abortop_desc, nfs_abortop }, /* abortop */ 77 { &vop_inactive_desc, nfs_inactive }, /* inactive */ 78 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */ 79 { &vop_lock_desc, nfs_lock }, /* lock */ 80 { &vop_unlock_desc, nfs_unlock }, /* unlock */ 81 { &vop_bmap_desc, nfs_bmap }, /* bmap */ 82 { &vop_strategy_desc, nfs_strategy }, /* strategy */ 83 { &vop_print_desc, nfs_print }, /* print */ 84 { &vop_islocked_desc, nfs_islocked }, /* islocked */ 85 { &vop_advlock_desc, nfs_advlock }, /* advlock */ 86 { &vop_blkatoff_desc, nfs_blkatoff }, /* blkatoff */ 87 { &vop_valloc_desc, nfs_valloc }, /* valloc */ 88 { &vop_vfree_desc, nfs_vfree }, /* vfree */ 89 { &vop_truncate_desc, nfs_truncate }, /* truncate */ 90 { &vop_update_desc, nfs_update }, /* update */ 91 { &vop_bwrite_desc, vn_bwrite }, 92 { (struct vnodeop_desc*)NULL, (int(*)())NULL } 93 }; 94 struct vnodeopv_desc nfsv2_vnodeop_opv_desc = 95 { &nfsv2_vnodeop_p, nfsv2_vnodeop_entries }; 96 97 /* 98 * Special device vnode ops 99 */ 100 int (**spec_nfsv2nodeop_p)(); 101 struct vnodeopv_entry_desc spec_nfsv2nodeop_entries[] = { 102 { &vop_default_desc, vn_default_error }, 103 { &vop_lookup_desc, spec_lookup }, /* lookup */ 104 { &vop_create_desc, spec_create }, /* create */ 105 { &vop_mknod_desc, spec_mknod }, /* mknod */ 106 { &vop_open_desc, spec_open }, /* open */ 107 { &vop_close_desc, nfsspec_close }, /* close */ 108 { &vop_access_desc, nfs_access }, /* access */ 109 { &vop_getattr_desc, nfs_getattr }, /* getattr */ 110 { &vop_setattr_desc, nfs_setattr }, /* setattr */ 111 { &vop_read_desc, nfsspec_read }, /* read */ 112 { &vop_write_desc, nfsspec_write }, /* write */ 113 { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 114 { &vop_select_desc, spec_select }, /* select */ 115 { &vop_mmap_desc, spec_mmap }, /* mmap */ 116 { &vop_fsync_desc, nfs_fsync }, /* fsync */ 117 { &vop_seek_desc, spec_seek }, /* seek */ 118 { &vop_remove_desc, spec_remove }, /* remove */ 119 { &vop_link_desc, spec_link }, /* link */ 120 { &vop_rename_desc, spec_rename }, /* rename */ 121 { &vop_mkdir_desc, spec_mkdir }, /* mkdir */ 122 { &vop_rmdir_desc, spec_rmdir }, /* rmdir */ 123 { &vop_symlink_desc, spec_symlink }, /* symlink */ 124 { &vop_readdir_desc, spec_readdir }, /* readdir */ 125 { &vop_readlink_desc, spec_readlink }, /* readlink */ 126 { &vop_abortop_desc, spec_abortop }, /* abortop */ 127 { &vop_inactive_desc, nfs_inactive }, /* inactive */ 128 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */ 129 { &vop_lock_desc, nfs_lock }, /* lock */ 130 { &vop_unlock_desc, nfs_unlock }, /* unlock */ 131 { &vop_bmap_desc, spec_bmap }, /* bmap */ 132 { &vop_strategy_desc, spec_strategy }, /* strategy */ 133 { &vop_print_desc, nfs_print }, /* print */ 134 { &vop_islocked_desc, nfs_islocked }, /* islocked */ 135 { &vop_advlock_desc, spec_advlock }, /* advlock */ 136 { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ 137 { &vop_valloc_desc, spec_valloc }, /* valloc */ 138 { &vop_vfree_desc, spec_vfree }, /* vfree */ 139 { &vop_truncate_desc, spec_truncate }, /* truncate */ 140 { &vop_update_desc, nfs_update }, /* update */ 141 { &vop_bwrite_desc, vn_bwrite }, 142 { (struct vnodeop_desc*)NULL, (int(*)())NULL } 143 }; 144 struct vnodeopv_desc spec_nfsv2nodeop_opv_desc = 145 { &spec_nfsv2nodeop_p, spec_nfsv2nodeop_entries }; 146 147 #ifdef FIFO 148 int (**fifo_nfsv2nodeop_p)(); 149 struct vnodeopv_entry_desc fifo_nfsv2nodeop_entries[] = { 150 { &vop_default_desc, vn_default_error }, 151 { &vop_lookup_desc, fifo_lookup }, /* lookup */ 152 { &vop_create_desc, fifo_create }, /* create */ 153 { &vop_mknod_desc, fifo_mknod }, /* mknod */ 154 { &vop_open_desc, fifo_open }, /* open */ 155 { &vop_close_desc, nfsfifo_close }, /* close */ 156 { &vop_access_desc, nfs_access }, /* access */ 157 { &vop_getattr_desc, nfs_getattr }, /* getattr */ 158 { &vop_setattr_desc, nfs_setattr }, /* setattr */ 159 { &vop_read_desc, nfsfifo_read }, /* read */ 160 { &vop_write_desc, nfsfifo_write }, /* write */ 161 { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ 162 { &vop_select_desc, fifo_select }, /* select */ 163 { &vop_mmap_desc, fifo_mmap }, /* mmap */ 164 { &vop_fsync_desc, nfs_fsync }, /* fsync */ 165 { &vop_seek_desc, fifo_seek }, /* seek */ 166 { &vop_remove_desc, fifo_remove }, /* remove */ 167 { &vop_link_desc, fifo_link }, /* link */ 168 { &vop_rename_desc, fifo_rename }, /* rename */ 169 { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */ 170 { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */ 171 { &vop_symlink_desc, fifo_symlink }, /* symlink */ 172 { &vop_readdir_desc, fifo_readdir }, /* readdir */ 173 { &vop_readlink_desc, fifo_readlink }, /* readlink */ 174 { &vop_abortop_desc, fifo_abortop }, /* abortop */ 175 { &vop_inactive_desc, nfs_inactive }, /* inactive */ 176 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */ 177 { &vop_lock_desc, nfs_lock }, /* lock */ 178 { &vop_unlock_desc, nfs_unlock }, /* unlock */ 179 { &vop_bmap_desc, fifo_bmap }, /* bmap */ 180 { &vop_strategy_desc, fifo_badop }, /* strategy */ 181 { &vop_print_desc, nfs_print }, /* print */ 182 { &vop_islocked_desc, nfs_islocked }, /* islocked */ 183 { &vop_advlock_desc, fifo_advlock }, /* advlock */ 184 { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ 185 { &vop_valloc_desc, fifo_valloc }, /* valloc */ 186 { &vop_vfree_desc, fifo_vfree }, /* vfree */ 187 { &vop_truncate_desc, fifo_truncate }, /* truncate */ 188 { &vop_update_desc, nfs_update }, /* update */ 189 { &vop_bwrite_desc, vn_bwrite }, 190 { (struct vnodeop_desc*)NULL, (int(*)())NULL } 191 }; 192 struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc = 193 { &fifo_nfsv2nodeop_p, fifo_nfsv2nodeop_entries }; 194 #endif /* FIFO */ 195 196 /* 197 * Global variables 198 */ 199 extern u_long nfs_procids[NFS_NPROCS]; 200 extern u_long nfs_prog, nfs_vers; 201 extern char nfsiobuf[MAXPHYS+NBPG]; 202 struct buf nfs_bqueue; /* Queue head for nfsiod's */ 203 struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; 204 int nfs_numasync = 0; 205 #define DIRHDSIZ (sizeof (struct readdir) - (MAXNAMLEN + 1)) 206 207 /* 208 * nfs null call from vfs. 209 */ 210 int 211 nfs_null(vp, cred, procp) 212 struct vnode *vp; 213 struct ucred *cred; 214 struct proc *procp; 215 { 216 caddr_t bpos, dpos; 217 int error = 0; 218 struct mbuf *mreq, *mrep, *md, *mb; 219 220 nfsm_reqhead(vp, NFSPROC_NULL, 0); 221 nfsm_request(vp, NFSPROC_NULL, procp, cred); 222 nfsm_reqdone; 223 return (error); 224 } 225 226 /* 227 * nfs access vnode op. 228 * Essentially just get vattr and then imitate iaccess() 229 */ 230 int 231 nfs_access(ap) 232 struct vop_access_args /* { 233 struct vnode *a_vp; 234 int a_mode; 235 struct ucred *a_cred; 236 struct proc *a_p; 237 } */ *ap; 238 { 239 register struct vattr *vap; 240 register gid_t *gp; 241 register struct ucred *cred = ap->a_cred; 242 mode_t mode = ap->a_mode; 243 struct vattr vattr; 244 register int i; 245 int error; 246 247 /* 248 * If you're the super-user, 249 * you always get access. 250 */ 251 if (cred->cr_uid == 0) 252 return (0); 253 vap = &vattr; 254 if (error = VOP_GETATTR(ap->a_vp, vap, cred, ap->a_p)) 255 return (error); 256 /* 257 * Access check is based on only one of owner, group, public. 258 * If not owner, then check group. If not a member of the 259 * group, then check public access. 260 */ 261 if (cred->cr_uid != vap->va_uid) { 262 mode >>= 3; 263 gp = cred->cr_groups; 264 for (i = 0; i < cred->cr_ngroups; i++, gp++) 265 if (vap->va_gid == *gp) 266 goto found; 267 mode >>= 3; 268 found: 269 ; 270 } 271 if ((vap->va_mode & mode) != 0) 272 return (0); 273 return (EACCES); 274 } 275 276 /* 277 * nfs open vnode op 278 * Just check to see if the type is ok 279 * and that deletion is not in progress. 280 */ 281 /* ARGSUSED */ 282 int 283 nfs_open(ap) 284 struct vop_open_args /* { 285 struct vnode *a_vp; 286 int a_mode; 287 struct ucred *a_cred; 288 struct proc *a_p; 289 } */ *ap; 290 { 291 register struct vnode *vp = ap->a_vp; 292 293 if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) 294 return (EACCES); 295 if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) == 0) 296 VTONFS(vp)->n_attrstamp = 0; /* For Open/Close consistency */ 297 return (0); 298 } 299 300 /* 301 * nfs close vnode op 302 * For reg files, invalidate any buffer cache entries. 303 */ 304 /* ARGSUSED */ 305 int 306 nfs_close(ap) 307 struct vop_close_args /* { 308 struct vnodeop_desc *a_desc; 309 struct vnode *a_vp; 310 int a_fflag; 311 struct ucred *a_cred; 312 struct proc *a_p; 313 } */ *ap; 314 { 315 register struct vnode *vp = ap->a_vp; 316 register struct nfsnode *np = VTONFS(vp); 317 int error = 0; 318 319 if (vp->v_type == VREG) { 320 if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) == 0 && 321 (np->n_flag & NMODIFIED)) { 322 error = vinvalbuf(vp, TRUE, ap->a_cred, ap->a_p); 323 np->n_flag &= ~NMODIFIED; 324 np->n_attrstamp = 0; 325 } 326 if (np->n_flag & NWRITEERR) { 327 np->n_flag &= ~NWRITEERR; 328 error = np->n_error; 329 } 330 } 331 return (error); 332 } 333 334 /* 335 * nfs getattr call from vfs. 336 */ 337 int 338 nfs_getattr(ap) 339 struct vop_getattr_args /* { 340 struct vnode *a_vp; 341 struct vattr *a_vap; 342 struct ucred *a_cred; 343 struct proc *a_p; 344 } */ *ap; 345 { 346 register struct vnode *vp = ap->a_vp; 347 register struct nfsnode *np = VTONFS(vp); 348 register caddr_t cp; 349 caddr_t bpos, dpos; 350 int error = 0; 351 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 352 353 /* 354 * Update local times for special files. 355 */ 356 if (np->n_flag & (NACC | NUPD)) { 357 if (np->n_flag & NACC) 358 np->n_atim = time; 359 if (np->n_flag & NUPD) 360 np->n_mtim = time; 361 np->n_flag |= NCHG; 362 } 363 /* 364 * First look in the cache. 365 */ 366 if (nfs_getattrcache(vp, ap->a_vap) == 0) 367 return (0); 368 nfsstats.rpccnt[NFSPROC_GETATTR]++; 369 nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH); 370 nfsm_fhtom(vp); 371 nfsm_request(vp, NFSPROC_GETATTR, ap->a_p, ap->a_cred); 372 nfsm_loadattr(vp, ap->a_vap); 373 nfsm_reqdone; 374 return (error); 375 } 376 377 /* 378 * nfs setattr call. 379 */ 380 int 381 nfs_setattr(ap) 382 struct vop_setattr_args /* { 383 struct vnodeop_desc *a_desc; 384 struct vnode *a_vp; 385 struct vattr *a_vap; 386 struct ucred *a_cred; 387 struct proc *a_p; 388 } */ *ap; 389 { 390 register struct nfsv2_sattr *sp; 391 register caddr_t cp; 392 register long t1; 393 caddr_t bpos, dpos, cp2; 394 u_long *tl; 395 int error = 0; 396 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 397 register struct vnode *vp = ap->a_vp; 398 register struct nfsnode *np = VTONFS(vp); 399 register struct vattr *vap = ap->a_vap; 400 u_quad_t frev; 401 402 nfsstats.rpccnt[NFSPROC_SETATTR]++; 403 nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH+NFSX_SATTR); 404 nfsm_fhtom(vp); 405 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 406 if (vap->va_mode == 0xffff) 407 sp->sa_mode = VNOVAL; 408 else 409 sp->sa_mode = vtonfs_mode(vp->v_type, vap->va_mode); 410 if (vap->va_uid == 0xffff) 411 sp->sa_uid = VNOVAL; 412 else 413 sp->sa_uid = txdr_unsigned(vap->va_uid); 414 if (vap->va_gid == 0xffff) 415 sp->sa_gid = VNOVAL; 416 else 417 sp->sa_gid = txdr_unsigned(vap->va_gid); 418 sp->sa_size = txdr_unsigned(vap->va_size); 419 sp->sa_atime.tv_sec = txdr_unsigned(vap->va_atime.ts_sec); 420 sp->sa_atime.tv_usec = txdr_unsigned(vap->va_flags); 421 txdr_time(&vap->va_mtime, &sp->sa_mtime); 422 if (vap->va_size != VNOVAL || vap->va_mtime.ts_sec != VNOVAL || 423 vap->va_atime.ts_sec != VNOVAL) { 424 if (np->n_flag & NMODIFIED) { 425 if (vap->va_size == 0) 426 error = 427 vinvalbuf(vp, FALSE, ap->a_cred, ap->a_p); 428 else 429 error = 430 vinvalbuf(vp, TRUE, ap->a_cred, ap->a_p); 431 np->n_flag &= ~NMODIFIED; 432 } 433 } 434 nfsm_request(vp, NFSPROC_SETATTR, ap->a_p, ap->a_cred); 435 nfsm_loadattr(vp, (struct vattr *)0); 436 if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) && 437 NQNFS_CKCACHABLE(vp, NQL_WRITE)) { 438 nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); 439 fxdr_hyper(tl, &frev); 440 if (frev > np->n_brev) 441 np->n_brev = frev; 442 } 443 nfsm_reqdone; 444 return (error); 445 } 446 447 /* 448 * nfs lookup call, one step at a time... 449 * First look in cache 450 * If not found, unlock the directory nfsnode and do the rpc 451 */ 452 int 453 nfs_lookup(ap) 454 struct vop_lookup_args /* { 455 struct vnodeop_desc *a_desc; 456 struct vnode *a_dvp; 457 struct vnode **a_vpp; 458 struct componentname *a_cnp; 459 } */ *ap; 460 { 461 register struct componentname *cnp = ap->a_cnp; 462 register struct vnode *dvp = ap->a_dvp; 463 register struct vnode **vpp = ap->a_vpp; 464 register struct vnode *vdp; 465 register u_long *tl; 466 register caddr_t cp; 467 register long t1, t2; 468 struct nfsmount *nmp; 469 struct nfsnode *tp; 470 caddr_t bpos, dpos, cp2; 471 time_t reqtime; 472 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 473 struct vnode *newvp; 474 long len; 475 nfsv2fh_t *fhp; 476 struct nfsnode *np; 477 int lockparent, wantparent, error = 0; 478 int nqlflag, cachable; 479 u_quad_t frev; 480 481 *vpp = NULL; 482 if (dvp->v_type != VDIR) 483 return (ENOTDIR); 484 lockparent = cnp->cn_flags & LOCKPARENT; 485 wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT); 486 nmp = VFSTONFS(dvp->v_mount); 487 np = VTONFS(dvp); 488 if ((error = cache_lookup(dvp, vpp, cnp)) && error != ENOENT) { 489 struct vattr vattr; 490 int vpid; 491 492 vdp = *vpp; 493 vpid = vdp->v_id; 494 /* 495 * See the comment starting `Step through' in ufs/ufs_lookup.c 496 * for an explanation of the locking protocol 497 */ 498 if (dvp == vdp) { 499 VREF(vdp); 500 error = 0; 501 } else 502 error = vget(vdp); 503 if (!error) { 504 if (vpid == vdp->v_id) { 505 if (nmp->nm_flag & NFSMNT_NQNFS) { 506 if (NQNFS_CKCACHABLE(dvp, NQL_READ)) { 507 if (np->n_lrev != np->n_brev || 508 (np->n_flag & NMODIFIED)) { 509 np->n_direofoffset = 0; 510 cache_purge(dvp); 511 error = vinvalbuf(dvp, FALSE, 512 cnp->cn_cred, cnp->cn_proc); 513 np->n_flag &= ~NMODIFIED; 514 np->n_brev = np->n_lrev; 515 } else { 516 nfsstats.lookupcache_hits++; 517 if (cnp->cn_nameiop != LOOKUP && 518 (cnp->cn_flags&ISLASTCN)) 519 cnp->cn_flags |= SAVENAME; 520 return (0); 521 } 522 } 523 } else if (!VOP_GETATTR(vdp, &vattr, cnp->cn_cred, cnp->cn_proc) && 524 vattr.va_ctime.ts_sec == VTONFS(vdp)->n_ctime) { 525 nfsstats.lookupcache_hits++; 526 if (cnp->cn_nameiop != LOOKUP && 527 (cnp->cn_flags&ISLASTCN)) 528 cnp->cn_flags |= SAVENAME; 529 return (0); 530 } 531 cache_purge(vdp); 532 } 533 vrele(vdp); 534 } 535 *vpp = NULLVP; 536 } 537 error = 0; 538 nfsstats.lookupcache_misses++; 539 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 540 len = cnp->cn_namelen; 541 nfsm_reqhead(dvp, NFSPROC_LOOKUP, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)); 542 543 /* 544 * For nqnfs optionally piggyback a getlease request for the name 545 * being looked up. 546 */ 547 if (nmp->nm_flag & NFSMNT_NQNFS) { 548 if ((nmp->nm_flag & NFSMNT_NQLOOKLEASE) && 549 ((cnp->cn_flags&MAKEENTRY) && 550 (cnp->cn_nameiop != DELETE || !(cnp->cn_flags&ISLASTCN)))) { 551 nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED); 552 *tl++ = txdr_unsigned(NQL_READ); 553 *tl = txdr_unsigned(nmp->nm_leaseterm); 554 } else { 555 nfsm_build(tl, u_long *, NFSX_UNSIGNED); 556 *tl = 0; 557 } 558 } 559 nfsm_fhtom(dvp); 560 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 561 reqtime = time.tv_sec; 562 nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_proc, cnp->cn_cred); 563 nfsmout: 564 if (error) { 565 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && 566 (cnp->cn_flags & ISLASTCN) && error == ENOENT) 567 error = EJUSTRETURN; 568 if (cnp->cn_nameiop != LOOKUP && (cnp->cn_flags&ISLASTCN)) 569 cnp->cn_flags |= SAVENAME; 570 return (error); 571 } 572 if (nmp->nm_flag & NFSMNT_NQNFS) { 573 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); 574 if (*tl) { 575 nqlflag = fxdr_unsigned(int, *tl); 576 nfsm_dissect(tl, u_long *, 4*NFSX_UNSIGNED); 577 cachable = fxdr_unsigned(int, *tl++); 578 reqtime += fxdr_unsigned(int, *tl++); 579 fxdr_hyper(tl, &frev); 580 } else 581 nqlflag = 0; 582 } 583 nfsm_dissect(fhp, nfsv2fh_t *, NFSX_FH); 584 585 /* 586 * Handle RENAME case... 587 */ 588 if (cnp->cn_nameiop == RENAME && wantparent && (cnp->cn_flags&ISLASTCN)) { 589 if (!bcmp(np->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) { 590 m_freem(mrep); 591 return (EISDIR); 592 } 593 if (error = nfs_nget(dvp->v_mount, fhp, &np)) { 594 m_freem(mrep); 595 return (error); 596 } 597 newvp = NFSTOV(np); 598 if (error = 599 nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) { 600 vrele(newvp); 601 m_freem(mrep); 602 return (error); 603 } 604 *vpp = newvp; 605 m_freem(mrep); 606 cnp->cn_flags |= SAVENAME; 607 return (0); 608 } 609 610 if (!bcmp(np->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) { 611 VREF(dvp); 612 newvp = dvp; 613 } else { 614 if (error = nfs_nget(dvp->v_mount, fhp, &np)) { 615 m_freem(mrep); 616 return (error); 617 } 618 newvp = NFSTOV(np); 619 } 620 if (error = nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) { 621 vrele(newvp); 622 m_freem(mrep); 623 return (error); 624 } 625 m_freem(mrep); 626 *vpp = newvp; 627 if (cnp->cn_nameiop != LOOKUP && (cnp->cn_flags&ISLASTCN)) 628 cnp->cn_flags |= SAVENAME; 629 if ((cnp->cn_flags&MAKEENTRY) && 630 (cnp->cn_nameiop != DELETE || !(cnp->cn_flags&ISLASTCN))) { 631 if ((nmp->nm_flag & NFSMNT_NQNFS) == 0) 632 np->n_ctime = np->n_vattr.va_ctime.ts_sec; 633 else if (nqlflag && reqtime > time.tv_sec) { 634 if (np->n_tnext) { 635 if (np->n_tnext == (struct nfsnode *)nmp) 636 nmp->nm_tprev = np->n_tprev; 637 else 638 np->n_tnext->n_tprev = np->n_tprev; 639 if (np->n_tprev == (struct nfsnode *)nmp) 640 nmp->nm_tnext = np->n_tnext; 641 else 642 np->n_tprev->n_tnext = np->n_tnext; 643 if (nqlflag == NQL_WRITE) 644 np->n_flag |= NQNFSWRITE; 645 } else if (nqlflag == NQL_READ) 646 np->n_flag &= ~NQNFSWRITE; 647 else 648 np->n_flag |= NQNFSWRITE; 649 if (cachable) 650 np->n_flag &= ~NQNFSNONCACHE; 651 else 652 np->n_flag |= NQNFSNONCACHE; 653 np->n_expiry = reqtime; 654 np->n_lrev = frev; 655 tp = nmp->nm_tprev; 656 while (tp != (struct nfsnode *)nmp && tp->n_expiry > np->n_expiry) 657 tp = tp->n_tprev; 658 if (tp == (struct nfsnode *)nmp) { 659 np->n_tnext = nmp->nm_tnext; 660 nmp->nm_tnext = np; 661 } else { 662 np->n_tnext = tp->n_tnext; 663 tp->n_tnext = np; 664 } 665 np->n_tprev = tp; 666 if (np->n_tnext == (struct nfsnode *)nmp) 667 nmp->nm_tprev = np; 668 else 669 np->n_tnext->n_tprev = np; 670 } 671 cache_enter(dvp, *vpp, cnp); 672 } 673 return (0); 674 } 675 676 /* 677 * nfs read call. 678 * Just call nfs_bioread() to do the work. 679 */ 680 int 681 nfs_read(ap) 682 struct vop_read_args /* { 683 struct vnode *a_vp; 684 struct uio *a_uio; 685 int a_ioflag; 686 struct ucred *a_cred; 687 } */ *ap; 688 { 689 register struct vnode *vp = ap->a_vp; 690 691 if (vp->v_type != VREG) 692 return (EPERM); 693 return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred)); 694 } 695 696 /* 697 * nfs readlink call 698 */ 699 int 700 nfs_readlink(ap) 701 struct vop_readlink_args /* { 702 struct vnode *a_vp; 703 struct uio *a_uio; 704 struct ucred *a_cred; 705 } */ *ap; 706 { 707 register struct vnode *vp = ap->a_vp; 708 709 if (vp->v_type != VLNK) 710 return (EPERM); 711 return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred)); 712 } 713 714 /* 715 * Do a readlink rpc. 716 * Called by nfs_doio() from below the buffer cache. 717 */ 718 int 719 nfs_readlinkrpc(vp, uiop, cred) 720 register struct vnode *vp; 721 struct uio *uiop; 722 struct ucred *cred; 723 { 724 register u_long *tl; 725 register caddr_t cp; 726 register long t1; 727 caddr_t bpos, dpos, cp2; 728 int error = 0; 729 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 730 long len; 731 732 nfsstats.rpccnt[NFSPROC_READLINK]++; 733 nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH); 734 nfsm_fhtom(vp); 735 nfsm_request(vp, NFSPROC_READLINK, uiop->uio_procp, cred); 736 nfsm_strsiz(len, NFS_MAXPATHLEN); 737 nfsm_mtouio(uiop, len); 738 nfsm_reqdone; 739 return (error); 740 } 741 742 /* 743 * nfs read rpc call 744 * Ditto above 745 */ 746 int 747 nfs_readrpc(vp, uiop, cred) 748 register struct vnode *vp; 749 struct uio *uiop; 750 struct ucred *cred; 751 { 752 register u_long *tl; 753 register caddr_t cp; 754 register long t1; 755 caddr_t bpos, dpos, cp2; 756 int error = 0; 757 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 758 struct nfsmount *nmp; 759 long len, retlen, tsiz; 760 761 nmp = VFSTONFS(vp->v_mount); 762 tsiz = uiop->uio_resid; 763 while (tsiz > 0) { 764 nfsstats.rpccnt[NFSPROC_READ]++; 765 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; 766 nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH+NFSX_UNSIGNED*3); 767 nfsm_fhtom(vp); 768 nfsm_build(tl, u_long *, NFSX_UNSIGNED*3); 769 *tl++ = txdr_unsigned(uiop->uio_offset); 770 *tl++ = txdr_unsigned(len); 771 *tl = 0; 772 nfsm_request(vp, NFSPROC_READ, uiop->uio_procp, cred); 773 nfsm_loadattr(vp, (struct vattr *)0); 774 nfsm_strsiz(retlen, nmp->nm_rsize); 775 nfsm_mtouio(uiop, retlen); 776 m_freem(mrep); 777 if (retlen < len) 778 tsiz = 0; 779 else 780 tsiz -= len; 781 } 782 nfsmout: 783 return (error); 784 } 785 786 /* 787 * nfs write call 788 */ 789 int 790 nfs_writerpc(vp, uiop, cred) 791 register struct vnode *vp; 792 struct uio *uiop; 793 struct ucred *cred; 794 { 795 register u_long *tl; 796 register caddr_t cp; 797 register long t1; 798 caddr_t bpos, dpos, cp2; 799 int error = 0; 800 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 801 struct nfsmount *nmp; 802 struct nfsnode *np = VTONFS(vp); 803 u_quad_t frev; 804 long len, tsiz; 805 806 nmp = VFSTONFS(vp->v_mount); 807 tsiz = uiop->uio_resid; 808 while (tsiz > 0) { 809 nfsstats.rpccnt[NFSPROC_WRITE]++; 810 len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; 811 nfsm_reqhead(vp, NFSPROC_WRITE, 812 NFSX_FH+NFSX_UNSIGNED*4+nfsm_rndup(len)); 813 nfsm_fhtom(vp); 814 nfsm_build(tl, u_long *, NFSX_UNSIGNED*4); 815 *(tl+1) = txdr_unsigned(uiop->uio_offset); 816 *(tl+3) = txdr_unsigned(len); 817 nfsm_uiotom(uiop, len); 818 nfsm_request(vp, NFSPROC_WRITE, uiop->uio_procp, cred); 819 nfsm_loadattr(vp, (struct vattr *)0); 820 if (nmp->nm_flag & NFSMNT_MYWRITE) 821 VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.ts_sec; 822 else if ((nmp->nm_flag & NFSMNT_NQNFS) && 823 NQNFS_CKCACHABLE(vp, NQL_WRITE)) { 824 nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); 825 fxdr_hyper(tl, &frev); 826 if (frev > np->n_brev) 827 np->n_brev = frev; 828 } 829 m_freem(mrep); 830 tsiz -= len; 831 } 832 nfsmout: 833 if (error) 834 uiop->uio_resid = tsiz; 835 return (error); 836 } 837 838 /* 839 * nfs mknod call 840 * This is a kludge. Use a create rpc but with the IFMT bits of the mode 841 * set to specify the file type and the size field for rdev. 842 */ 843 /* ARGSUSED */ 844 int 845 nfs_mknod(ap) 846 struct vop_mknod_args /* { 847 struct vnode *a_dvp; 848 struct vnode **a_vpp; 849 struct componentname *a_cnp; 850 struct vattr *a_vap; 851 } */ *ap; 852 { 853 register struct vnode *dvp = ap->a_dvp; 854 register struct vattr *vap = ap->a_vap; 855 register struct componentname *cnp = ap->a_cnp; 856 register struct nfsv2_sattr *sp; 857 register u_long *tl; 858 register caddr_t cp; 859 register long t2; 860 caddr_t bpos, dpos; 861 int error = 0; 862 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 863 u_long rdev; 864 865 if (vap->va_type == VCHR || vap->va_type == VBLK) 866 rdev = txdr_unsigned(vap->va_rdev); 867 #ifdef FIFO 868 else if (vap->va_type == VFIFO) 869 rdev = 0xffffffff; 870 #endif /* FIFO */ 871 else { 872 VOP_ABORTOP(dvp, cnp); 873 vput(dvp); 874 return (EOPNOTSUPP); 875 } 876 nfsstats.rpccnt[NFSPROC_CREATE]++; 877 nfsm_reqhead(dvp, NFSPROC_CREATE, 878 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)+NFSX_SATTR); 879 nfsm_fhtom(dvp); 880 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 881 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 882 sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode); 883 sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid); 884 sp->sa_gid = txdr_unsigned(cnp->cn_cred->cr_gid); 885 sp->sa_size = rdev; 886 /* or should these be VNOVAL ?? */ 887 txdr_time(&vap->va_atime, &sp->sa_atime); 888 txdr_time(&vap->va_mtime, &sp->sa_mtime); 889 nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_proc, cnp->cn_cred); 890 nfsm_reqdone; 891 FREE(cnp->cn_pnbuf, M_NAMEI); 892 VTONFS(dvp)->n_flag |= NMODIFIED; 893 vrele(dvp); 894 return (error); 895 } 896 897 /* 898 * nfs file create call 899 */ 900 int 901 nfs_create(ap) 902 struct vop_create_args /* { 903 struct vnode *a_dvp; 904 struct vnode **a_vpp; 905 struct componentname *a_cnp; 906 struct vattr *a_vap; 907 } */ *ap; 908 { 909 register struct vnode *dvp = ap->a_dvp; 910 register struct vattr *vap = ap->a_vap; 911 register struct componentname *cnp = ap->a_cnp; 912 register struct nfsv2_sattr *sp; 913 register u_long *tl; 914 register caddr_t cp; 915 register long t1, t2; 916 caddr_t bpos, dpos, cp2; 917 int error = 0; 918 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 919 920 nfsstats.rpccnt[NFSPROC_CREATE]++; 921 nfsm_reqhead(dvp, NFSPROC_CREATE, 922 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)+NFSX_SATTR); 923 nfsm_fhtom(dvp); 924 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 925 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 926 sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode); 927 sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid); 928 sp->sa_gid = txdr_unsigned(cnp->cn_cred->cr_gid); 929 sp->sa_size = txdr_unsigned(0); 930 /* or should these be VNOVAL ?? */ 931 txdr_time(&vap->va_atime, &sp->sa_atime); 932 txdr_time(&vap->va_mtime, &sp->sa_mtime); 933 nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_proc, cnp->cn_cred); 934 nfsm_mtofh(dvp, *ap->a_vpp); 935 nfsm_reqdone; 936 FREE(cnp->cn_pnbuf, M_NAMEI); 937 VTONFS(dvp)->n_flag |= NMODIFIED; 938 vrele(dvp); 939 return (error); 940 } 941 942 /* 943 * nfs file remove call 944 * To try and make nfs semantics closer to ufs semantics, a file that has 945 * other processes using the vnode is renamed instead of removed and then 946 * removed later on the last close. 947 * - If v_usecount > 1 948 * If a rename is not already in the works 949 * call nfs_sillyrename() to set it up 950 * else 951 * do the remove rpc 952 */ 953 int 954 nfs_remove(ap) 955 struct vop_remove_args /* { 956 struct vnodeop_desc *a_desc; 957 struct vnode * a_dvp; 958 struct vnode * a_vp; 959 struct componentname * a_cnp; 960 } */ *ap; 961 { 962 register struct vnode *vp = ap->a_vp; 963 register struct vnode *dvp = ap->a_dvp; 964 register struct componentname *cnp = ap->a_cnp; 965 register struct nfsnode *np = VTONFS(vp); 966 register u_long *tl; 967 register caddr_t cp; 968 register long t2; 969 caddr_t bpos, dpos; 970 int error = 0; 971 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 972 973 if (vp->v_usecount > 1) { 974 if (!np->n_sillyrename) 975 error = nfs_sillyrename(dvp, vp, cnp); 976 } else { 977 /* 978 * Purge the name cache so that the chance of a lookup for 979 * the name succeeding while the remove is in progress is 980 * minimized. Without node locking it can still happen, such 981 * that an I/O op returns ESTALE, but since you get this if 982 * another host removes the file.. 983 */ 984 cache_purge(vp); 985 /* 986 * Throw away biocache buffers. Mainly to avoid 987 * unnecessary delayed writes. 988 */ 989 error = vinvalbuf(vp, FALSE, cnp->cn_cred, cnp->cn_proc); 990 /* Do the rpc */ 991 nfsstats.rpccnt[NFSPROC_REMOVE]++; 992 nfsm_reqhead(dvp, NFSPROC_REMOVE, 993 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)); 994 nfsm_fhtom(dvp); 995 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 996 nfsm_request(dvp, NFSPROC_REMOVE, cnp->cn_proc, cnp->cn_cred); 997 nfsm_reqdone; 998 FREE(cnp->cn_pnbuf, M_NAMEI); 999 VTONFS(dvp)->n_flag |= NMODIFIED; 1000 /* 1001 * Kludge City: If the first reply to the remove rpc is lost.. 1002 * the reply to the retransmitted request will be ENOENT 1003 * since the file was in fact removed 1004 * Therefore, we cheat and return success. 1005 */ 1006 if (error == ENOENT) 1007 error = 0; 1008 } 1009 np->n_attrstamp = 0; 1010 vrele(dvp); 1011 vrele(vp); 1012 return (error); 1013 } 1014 1015 /* 1016 * nfs file remove rpc called from nfs_inactive 1017 */ 1018 int 1019 nfs_removeit(sp) 1020 register struct sillyrename *sp; 1021 { 1022 register u_long *tl; 1023 register caddr_t cp; 1024 register long t2; 1025 caddr_t bpos, dpos; 1026 int error = 0; 1027 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1028 1029 nfsstats.rpccnt[NFSPROC_REMOVE]++; 1030 nfsm_reqhead(sp->s_dvp, NFSPROC_REMOVE, 1031 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(sp->s_namlen)); 1032 nfsm_fhtom(sp->s_dvp); 1033 nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN); 1034 nfsm_request(sp->s_dvp, NFSPROC_REMOVE, NULL, sp->s_cred); 1035 nfsm_reqdone; 1036 VTONFS(sp->s_dvp)->n_flag |= NMODIFIED; 1037 return (error); 1038 } 1039 1040 /* 1041 * nfs file rename call 1042 */ 1043 int 1044 nfs_rename(ap) 1045 struct vop_rename_args /* { 1046 struct vnode *a_fdvp; 1047 struct vnode *a_fvp; 1048 struct componentname *a_fcnp; 1049 struct vnode *a_tdvp; 1050 struct vnode *a_tvp; 1051 struct componentname *a_tcnp; 1052 } */ *ap; 1053 { 1054 register struct vnode *fvp = ap->a_fvp; 1055 register struct vnode *tvp = ap->a_tvp; 1056 register struct vnode *fdvp = ap->a_fdvp; 1057 register struct vnode *tdvp = ap->a_tdvp; 1058 register struct componentname *tcnp = ap->a_tcnp; 1059 register struct componentname *fcnp = ap->a_fcnp; 1060 register u_long *tl; 1061 register caddr_t cp; 1062 register long t2; 1063 caddr_t bpos, dpos; 1064 int error = 0; 1065 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1066 1067 /* Check for cross-device rename */ 1068 if ((fvp->v_mount != tdvp->v_mount) || 1069 (tvp && (fvp->v_mount != tvp->v_mount))) { 1070 error = EXDEV; 1071 goto out; 1072 } 1073 1074 1075 nfsstats.rpccnt[NFSPROC_RENAME]++; 1076 nfsm_reqhead(fdvp, NFSPROC_RENAME, 1077 (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(fcnp->cn_namelen)+ 1078 nfsm_rndup(fcnp->cn_namelen)); /* or fcnp->cn_cred?*/ 1079 nfsm_fhtom(fdvp); 1080 nfsm_strtom(fcnp->cn_nameptr, fcnp->cn_namelen, NFS_MAXNAMLEN); 1081 nfsm_fhtom(tdvp); 1082 nfsm_strtom(tcnp->cn_nameptr, tcnp->cn_namelen, NFS_MAXNAMLEN); 1083 nfsm_request(fdvp, NFSPROC_RENAME, tcnp->cn_proc, tcnp->cn_cred); 1084 nfsm_reqdone; 1085 VTONFS(fdvp)->n_flag |= NMODIFIED; 1086 VTONFS(tdvp)->n_flag |= NMODIFIED; 1087 if (fvp->v_type == VDIR) { 1088 if (tvp != NULL && tvp->v_type == VDIR) 1089 cache_purge(tdvp); 1090 cache_purge(fdvp); 1091 } 1092 out: 1093 if (tdvp == tvp) 1094 vrele(tdvp); 1095 else 1096 vput(tdvp); 1097 if (tvp) 1098 vput(tvp); 1099 vrele(fdvp); 1100 vrele(fvp); 1101 /* 1102 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. 1103 */ 1104 if (error == ENOENT) 1105 error = 0; 1106 return (error); 1107 } 1108 1109 /* 1110 * nfs file rename rpc called from nfs_remove() above 1111 */ 1112 int 1113 nfs_renameit(sdvp, scnp, sp) 1114 struct vnode *sdvp; 1115 struct componentname *scnp; 1116 register struct sillyrename *sp; 1117 { 1118 register u_long *tl; 1119 register caddr_t cp; 1120 register long t2; 1121 caddr_t bpos, dpos; 1122 int error = 0; 1123 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1124 1125 nfsstats.rpccnt[NFSPROC_RENAME]++; 1126 nfsm_reqhead(sdvp, NFSPROC_RENAME, 1127 (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(scnp->cn_namelen)+ 1128 nfsm_rndup(sp->s_namlen)); 1129 nfsm_fhtom(sdvp); 1130 nfsm_strtom(scnp->cn_nameptr, scnp->cn_namelen, NFS_MAXNAMLEN); 1131 nfsm_fhtom(sdvp); 1132 nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN); 1133 nfsm_request(sdvp, NFSPROC_RENAME, scnp->cn_proc, scnp->cn_cred); 1134 nfsm_reqdone; 1135 FREE(scnp->cn_pnbuf, M_NAMEI); 1136 VTONFS(sdvp)->n_flag |= NMODIFIED; 1137 return (error); 1138 } 1139 1140 /* 1141 * nfs hard link create call 1142 */ 1143 int 1144 nfs_link(ap) 1145 struct vop_link_args /* { 1146 struct vnode *a_vp; 1147 struct vnode *a_tdvp; 1148 struct componentname *a_cnp; 1149 } */ *ap; 1150 { 1151 register struct vnode *vp = ap->a_vp; 1152 register struct vnode *tdvp = ap->a_tdvp; 1153 register struct componentname *cnp = ap->a_cnp; 1154 register u_long *tl; 1155 register caddr_t cp; 1156 register long t2; 1157 caddr_t bpos, dpos; 1158 int error = 0; 1159 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1160 1161 if (vp->v_mount != tdvp->v_mount) { 1162 /*VOP_ABORTOP(vp, cnp);*/ 1163 if (tdvp == vp) 1164 vrele(vp); 1165 else 1166 vput(vp); 1167 return (EXDEV); 1168 } 1169 1170 nfsstats.rpccnt[NFSPROC_LINK]++; 1171 nfsm_reqhead(tdvp, NFSPROC_LINK, 1172 NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)); 1173 nfsm_fhtom(tdvp); 1174 nfsm_fhtom(vp); 1175 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1176 nfsm_request(tdvp, NFSPROC_LINK, cnp->cn_proc, cnp->cn_cred); 1177 nfsm_reqdone; 1178 FREE(cnp->cn_pnbuf, M_NAMEI); 1179 VTONFS(tdvp)->n_attrstamp = 0; 1180 VTONFS(vp)->n_flag |= NMODIFIED; 1181 vrele(vp); 1182 /* 1183 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. 1184 */ 1185 if (error == EEXIST) 1186 error = 0; 1187 return (error); 1188 } 1189 1190 /* 1191 * nfs symbolic link create call 1192 */ 1193 /* start here */ 1194 int 1195 nfs_symlink(ap) 1196 struct vop_symlink_args /* { 1197 struct vnode *a_dvp; 1198 struct vnode **a_vpp; 1199 struct componentname *a_cnp; 1200 struct vattr *a_vap; 1201 char *a_target; 1202 } */ *ap; 1203 { 1204 register struct vnode *dvp = ap->a_dvp; 1205 register struct vattr *vap = ap->a_vap; 1206 register struct componentname *cnp = ap->a_cnp; 1207 register struct nfsv2_sattr *sp; 1208 register u_long *tl; 1209 register caddr_t cp; 1210 register long t2; 1211 caddr_t bpos, dpos; 1212 int slen, error = 0; 1213 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1214 1215 nfsstats.rpccnt[NFSPROC_SYMLINK]++; 1216 slen = strlen(ap->a_target); 1217 nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH+2*NFSX_UNSIGNED+ 1218 nfsm_rndup(cnp->cn_namelen)+nfsm_rndup(slen)+NFSX_SATTR); 1219 nfsm_fhtom(dvp); 1220 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1221 nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN); 1222 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 1223 sp->sa_mode = vtonfs_mode(VLNK, vap->va_mode); 1224 sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid); 1225 sp->sa_gid = txdr_unsigned(cnp->cn_cred->cr_gid); 1226 sp->sa_size = txdr_unsigned(VNOVAL); 1227 txdr_time(&vap->va_atime, &sp->sa_atime); /* or VNOVAL ?? */ 1228 txdr_time(&vap->va_mtime, &sp->sa_mtime); /* or VNOVAL ?? */ 1229 nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_proc, cnp->cn_cred); 1230 nfsm_reqdone; 1231 FREE(cnp->cn_pnbuf, M_NAMEI); 1232 VTONFS(dvp)->n_flag |= NMODIFIED; 1233 vrele(dvp); 1234 /* 1235 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. 1236 */ 1237 if (error == EEXIST) 1238 error = 0; 1239 return (error); 1240 } 1241 1242 /* 1243 * nfs make dir call 1244 */ 1245 int 1246 nfs_mkdir(ap) 1247 struct vop_mkdir_args /* { 1248 struct vnode *a_dvp; 1249 struct vnode **a_vpp; 1250 struct componentname *a_cnp; 1251 struct vattr *a_vap; 1252 } */ *ap; 1253 { 1254 register struct vnode *dvp = ap->a_dvp; 1255 register struct vattr *vap = ap->a_vap; 1256 register struct componentname *cnp = ap->a_cnp; 1257 register struct vnode **vpp = ap->a_vpp; 1258 register struct nfsv2_sattr *sp; 1259 register u_long *tl; 1260 register caddr_t cp; 1261 register long t1, t2; 1262 register int len; 1263 caddr_t bpos, dpos, cp2; 1264 int error = 0, firsttry = 1; 1265 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1266 1267 len = cnp->cn_namelen; 1268 nfsstats.rpccnt[NFSPROC_MKDIR]++; 1269 nfsm_reqhead(dvp, NFSPROC_MKDIR, 1270 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)+NFSX_SATTR); 1271 nfsm_fhtom(dvp); 1272 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 1273 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 1274 sp->sa_mode = vtonfs_mode(VDIR, vap->va_mode); 1275 sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid); 1276 sp->sa_gid = txdr_unsigned(cnp->cn_cred->cr_gid); 1277 sp->sa_size = txdr_unsigned(VNOVAL); 1278 txdr_time(&vap->va_atime, &sp->sa_atime); /* or VNOVAL ?? */ 1279 txdr_time(&vap->va_mtime, &sp->sa_mtime); /* or VNOVAL ?? */ 1280 nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_proc, cnp->cn_cred); 1281 nfsm_mtofh(dvp, *vpp); 1282 nfsm_reqdone; 1283 VTONFS(dvp)->n_flag |= NMODIFIED; 1284 /* 1285 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry 1286 * if we can succeed in looking up the directory. 1287 * "firsttry" is necessary since the macros may "goto nfsmout" which 1288 * is above the if on errors. (Ugh) 1289 */ 1290 if (error == EEXIST && firsttry) { 1291 firsttry = 0; 1292 error = 0; 1293 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 1294 *vpp = NULL; 1295 nfsm_reqhead(dvp, NFSPROC_LOOKUP, 1296 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)); 1297 nfsm_fhtom(dvp); 1298 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 1299 nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_proc, cnp->cn_cred); 1300 nfsm_mtofh(dvp, *vpp); 1301 if ((*vpp)->v_type != VDIR) { 1302 vput(*vpp); 1303 error = EEXIST; 1304 } 1305 m_freem(mrep); 1306 } 1307 FREE(cnp->cn_pnbuf, M_NAMEI); 1308 vrele(dvp); 1309 return (error); 1310 } 1311 1312 /* 1313 * nfs remove directory call 1314 */ 1315 int 1316 nfs_rmdir(ap) 1317 struct vop_rmdir_args /* { 1318 struct vnode *a_dvp; 1319 struct vnode *a_vp; 1320 struct componentname *a_cnp; 1321 } */ *ap; 1322 { 1323 register struct vnode *vp = ap->a_vp; 1324 register struct vnode *dvp = ap->a_dvp; 1325 register struct componentname *cnp = ap->a_cnp; 1326 register u_long *tl; 1327 register caddr_t cp; 1328 register long t2; 1329 caddr_t bpos, dpos; 1330 int error = 0; 1331 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1332 1333 if (dvp == vp) { 1334 vrele(dvp); 1335 vrele(dvp); 1336 FREE(cnp->cn_pnbuf, M_NAMEI); 1337 return (EINVAL); 1338 } 1339 nfsstats.rpccnt[NFSPROC_RMDIR]++; 1340 nfsm_reqhead(dvp, NFSPROC_RMDIR, 1341 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)); 1342 nfsm_fhtom(dvp); 1343 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1344 nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_proc, cnp->cn_cred); 1345 nfsm_reqdone; 1346 FREE(cnp->cn_pnbuf, M_NAMEI); 1347 VTONFS(dvp)->n_flag |= NMODIFIED; 1348 cache_purge(dvp); 1349 cache_purge(vp); 1350 vrele(vp); 1351 vrele(dvp); 1352 /* 1353 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. 1354 */ 1355 if (error == ENOENT) 1356 error = 0; 1357 return (error); 1358 } 1359 1360 /* 1361 * nfs readdir call 1362 * Although cookie is defined as opaque, I translate it to/from net byte 1363 * order so that it looks more sensible. This appears consistent with the 1364 * Ultrix implementation of NFS. 1365 */ 1366 int 1367 nfs_readdir(ap) 1368 struct vop_readdir_args /* { 1369 struct vnode *a_vp; 1370 struct uio *a_uio; 1371 struct ucred *a_cred; 1372 } */ *ap; 1373 { 1374 register struct vnode *vp = ap->a_vp; 1375 register struct nfsnode *np = VTONFS(vp); 1376 register struct uio *uio = ap->a_uio; 1377 int tresid, error; 1378 struct vattr vattr; 1379 1380 if (vp->v_type != VDIR) 1381 return (EPERM); 1382 /* 1383 * First, check for hit on the EOF offset cache 1384 */ 1385 if (uio->uio_offset != 0 && uio->uio_offset == np->n_direofoffset && 1386 (np->n_flag & NMODIFIED) == 0) { 1387 if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) { 1388 if (NQNFS_CKCACHABLE(vp, NQL_READ)) { 1389 nfsstats.direofcache_hits++; 1390 return (0); 1391 } 1392 } else if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_procp) == 0 && 1393 np->n_mtime == vattr.va_mtime.ts_sec) { 1394 nfsstats.direofcache_hits++; 1395 return (0); 1396 } 1397 } 1398 1399 /* 1400 * Call nfs_bioread() to do the real work. 1401 */ 1402 tresid = uio->uio_resid; 1403 error = nfs_bioread(vp, uio, 0, ap->a_cred); 1404 1405 if (!error && uio->uio_resid == tresid) 1406 nfsstats.direofcache_misses++; 1407 return (error); 1408 } 1409 1410 /* 1411 * Readdir rpc call. 1412 * Called from below the buffer cache by nfs_doio(). 1413 */ 1414 int 1415 nfs_readdirrpc(vp, uiop, cred) 1416 register struct vnode *vp; 1417 struct uio *uiop; 1418 struct ucred *cred; 1419 { 1420 register long len; 1421 register struct readdir *dp; 1422 register u_long *tl; 1423 register caddr_t cp; 1424 register long t1; 1425 long tlen, lastlen; 1426 caddr_t bpos, dpos, cp2; 1427 int error = 0; 1428 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1429 struct mbuf *md2; 1430 caddr_t dpos2; 1431 int siz; 1432 int more_dirs = 1; 1433 off_t off, savoff; 1434 struct readdir *savdp; 1435 struct nfsmount *nmp; 1436 struct nfsnode *np = VTONFS(vp); 1437 long tresid; 1438 1439 nmp = VFSTONFS(vp->v_mount); 1440 tresid = uiop->uio_resid; 1441 /* 1442 * Loop around doing readdir rpc's of size uio_resid or nm_rsize, 1443 * whichever is smaller, truncated to a multiple of NFS_DIRBLKSIZ. 1444 * The stopping criteria is EOF or buffer full. 1445 */ 1446 while (more_dirs && uiop->uio_resid >= NFS_DIRBLKSIZ) { 1447 nfsstats.rpccnt[NFSPROC_READDIR]++; 1448 nfsm_reqhead(vp, NFSPROC_READDIR, 1449 NFSX_FH+2*NFSX_UNSIGNED); 1450 nfsm_fhtom(vp); 1451 nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED); 1452 *tl++ = txdr_unsigned(uiop->uio_offset); 1453 *tl = txdr_unsigned(((uiop->uio_resid > nmp->nm_rsize) ? 1454 nmp->nm_rsize : uiop->uio_resid) & ~(NFS_DIRBLKSIZ-1)); 1455 nfsm_request(vp, NFSPROC_READDIR, uiop->uio_procp, cred); 1456 siz = 0; 1457 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); 1458 more_dirs = fxdr_unsigned(int, *tl); 1459 1460 /* Save the position so that we can do nfsm_mtouio() later */ 1461 dpos2 = dpos; 1462 md2 = md; 1463 1464 /* loop thru the dir entries, doctoring them to 4bsd form */ 1465 off = uiop->uio_offset; 1466 #ifdef lint 1467 dp = (struct readdir *)0; 1468 #endif /* lint */ 1469 while (more_dirs && siz < uiop->uio_resid) { 1470 savoff = off; /* Hold onto offset and dp */ 1471 savdp = dp; 1472 nfsm_dissecton(tl, u_long *, 2*NFSX_UNSIGNED); 1473 dp = (struct readdir *)tl; 1474 dp->d_ino = fxdr_unsigned(u_long, *tl++); 1475 len = fxdr_unsigned(int, *tl); 1476 if (len <= 0 || len > NFS_MAXNAMLEN) { 1477 error = EBADRPC; 1478 m_freem(mrep); 1479 goto nfsmout; 1480 } 1481 dp->d_namlen = (u_short)len; 1482 nfsm_adv(len); /* Point past name */ 1483 tlen = nfsm_rndup(len); 1484 /* 1485 * This should not be necessary, but some servers have 1486 * broken XDR such that these bytes are not null filled. 1487 */ 1488 if (tlen != len) { 1489 *dpos = '\0'; /* Null-terminate */ 1490 nfsm_adv(tlen - len); 1491 len = tlen; 1492 } 1493 nfsm_dissecton(tl, u_long *, 2*NFSX_UNSIGNED); 1494 off = fxdr_unsigned(off_t, *tl); 1495 *tl++ = 0; /* Ensures null termination of name */ 1496 more_dirs = fxdr_unsigned(int, *tl); 1497 dp->d_reclen = len+4*NFSX_UNSIGNED; 1498 siz += dp->d_reclen; 1499 } 1500 /* 1501 * If at end of rpc data, get the eof boolean 1502 */ 1503 if (!more_dirs) { 1504 nfsm_dissecton(tl, u_long *, NFSX_UNSIGNED); 1505 more_dirs = (fxdr_unsigned(int, *tl) == 0); 1506 1507 /* 1508 * If at EOF, cache directory offset 1509 */ 1510 if (!more_dirs) 1511 np->n_direofoffset = off; 1512 } 1513 /* 1514 * If there is too much to fit in the data buffer, use savoff and 1515 * savdp to trim off the last record. 1516 * --> we are not at eof 1517 */ 1518 if (siz > uiop->uio_resid) { 1519 off = savoff; 1520 siz -= dp->d_reclen; 1521 dp = savdp; 1522 more_dirs = 0; /* Paranoia */ 1523 } 1524 if (siz > 0) { 1525 lastlen = dp->d_reclen; 1526 md = md2; 1527 dpos = dpos2; 1528 nfsm_mtouio(uiop, siz); 1529 uiop->uio_offset = off; 1530 } else 1531 more_dirs = 0; /* Ugh, never happens, but in case.. */ 1532 m_freem(mrep); 1533 } 1534 /* 1535 * Fill last record, iff any, out to a multiple of NFS_DIRBLKSIZ 1536 * by increasing d_reclen for the last record. 1537 */ 1538 if (uiop->uio_resid < tresid) { 1539 len = uiop->uio_resid & (NFS_DIRBLKSIZ - 1); 1540 if (len > 0) { 1541 dp = (struct readdir *) 1542 (uiop->uio_iov->iov_base - lastlen); 1543 dp->d_reclen += len; 1544 uiop->uio_iov->iov_base += len; 1545 uiop->uio_iov->iov_len -= len; 1546 uiop->uio_resid -= len; 1547 } 1548 } 1549 nfsmout: 1550 return (error); 1551 } 1552 1553 /* 1554 * Nqnfs readdir_and_lookup RPC. Used in place of nfs_readdirrpc() when 1555 * the "rdirlook" mount option is specified. 1556 */ 1557 int 1558 nfs_readdirlookrpc(vp, uiop, cred) 1559 struct vnode *vp; 1560 register struct uio *uiop; 1561 struct ucred *cred; 1562 { 1563 register int len; 1564 register struct readdir *dp; 1565 register u_long *tl; 1566 register caddr_t cp; 1567 register long t1; 1568 caddr_t bpos, dpos, cp2; 1569 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1570 struct nameidata nami, *ndp = &nami; 1571 struct componentname *cnp = &ndp->ni_cnd; 1572 off_t off, endoff; 1573 time_t reqtime, ltime; 1574 struct nfsmount *nmp; 1575 struct nfsnode *np, *tp; 1576 struct vnode *newvp; 1577 nfsv2fh_t *fhp; 1578 u_long fileno; 1579 u_quad_t frev; 1580 int error = 0, tlen, more_dirs = 1, tresid, doit, bigenough, i; 1581 int cachable; 1582 1583 if (uiop->uio_iovcnt != 1) 1584 panic("nfs rdirlook"); 1585 nmp = VFSTONFS(vp->v_mount); 1586 tresid = uiop->uio_resid; 1587 ndp->ni_dvp = vp; 1588 newvp = NULLVP; 1589 /* 1590 * Loop around doing readdir rpc's of size uio_resid or nm_rsize, 1591 * whichever is smaller, truncated to a multiple of NFS_DIRBLKSIZ. 1592 * The stopping criteria is EOF or buffer full. 1593 */ 1594 while (more_dirs && uiop->uio_resid >= NFS_DIRBLKSIZ) { 1595 nfsstats.rpccnt[NQNFSPROC_READDIRLOOK]++; 1596 nfsm_reqhead(vp, NQNFSPROC_READDIRLOOK, 1597 NFSX_FH+3*NFSX_UNSIGNED); 1598 nfsm_fhtom(vp); 1599 nfsm_build(tl, u_long *, 3*NFSX_UNSIGNED); 1600 *tl++ = txdr_unsigned(uiop->uio_offset); 1601 *tl++ = txdr_unsigned(((uiop->uio_resid > nmp->nm_rsize) ? 1602 nmp->nm_rsize : uiop->uio_resid) & ~(NFS_DIRBLKSIZ-1)); 1603 *tl = txdr_unsigned(nmp->nm_leaseterm); 1604 reqtime = time.tv_sec; 1605 nfsm_request(vp, NQNFSPROC_READDIRLOOK, uiop->uio_procp, cred); 1606 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); 1607 more_dirs = fxdr_unsigned(int, *tl); 1608 1609 /* loop thru the dir entries, doctoring them to 4bsd form */ 1610 off = uiop->uio_offset; 1611 bigenough = 1; 1612 while (more_dirs && bigenough) { 1613 doit = 1; 1614 nfsm_dissect(tl, u_long *, 4*NFSX_UNSIGNED); 1615 cachable = fxdr_unsigned(int, *tl++); 1616 ltime = reqtime + fxdr_unsigned(int, *tl++); 1617 fxdr_hyper(tl, &frev); 1618 nfsm_dissect(fhp, nfsv2fh_t *, NFSX_FH); 1619 if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) { 1620 VREF(vp); 1621 newvp = vp; 1622 np = VTONFS(vp); 1623 } else { 1624 if (error = nfs_nget(vp->v_mount, fhp, &np)) 1625 doit = 0; 1626 newvp = NFSTOV(np); 1627 } 1628 if (error = nfs_loadattrcache(&newvp, &md, &dpos, 1629 (struct vattr *)0)) 1630 doit = 0; 1631 nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); 1632 fileno = fxdr_unsigned(u_long, *tl++); 1633 len = fxdr_unsigned(int, *tl); 1634 if (len <= 0 || len > NFS_MAXNAMLEN) { 1635 error = EBADRPC; 1636 m_freem(mrep); 1637 goto nfsmout; 1638 } 1639 tlen = (len + 4) & ~0x3; 1640 if ((tlen + DIRHDSIZ) > uiop->uio_resid) 1641 bigenough = 0; 1642 if (bigenough && doit) { 1643 dp = (struct readdir *)uiop->uio_iov->iov_base; 1644 dp->d_ino = fileno; 1645 dp->d_namlen = len; 1646 dp->d_reclen = tlen + DIRHDSIZ; 1647 uiop->uio_resid -= DIRHDSIZ; 1648 uiop->uio_iov->iov_base += DIRHDSIZ; 1649 uiop->uio_iov->iov_len -= DIRHDSIZ; 1650 cnp->cn_nameptr = uiop->uio_iov->iov_base; 1651 cnp->cn_namelen = len; 1652 ndp->ni_vp = newvp; 1653 nfsm_mtouio(uiop, len); 1654 cp = uiop->uio_iov->iov_base; 1655 tlen -= len; 1656 for (i = 0; i < tlen; i++) 1657 *cp++ = '\0'; 1658 uiop->uio_iov->iov_base += tlen; 1659 uiop->uio_iov->iov_len -= tlen; 1660 uiop->uio_resid -= tlen; 1661 cnp->cn_hash = 0; 1662 for (cp = cnp->cn_nameptr, i = 1; i <= len; i++, cp++) 1663 cnp->cn_hash += (unsigned char)*cp * i; 1664 if (ltime > time.tv_sec) { 1665 if (np->n_tnext) { 1666 if (np->n_tnext == (struct nfsnode *)nmp) 1667 nmp->nm_tprev = np->n_tprev; 1668 else 1669 np->n_tnext->n_tprev = np->n_tprev; 1670 if (np->n_tprev == (struct nfsnode *)nmp) 1671 nmp->nm_tnext = np->n_tnext; 1672 else 1673 np->n_tprev->n_tnext = np->n_tnext; 1674 } else 1675 np->n_flag &= ~NQNFSWRITE; 1676 if (cachable) 1677 np->n_flag &= ~NQNFSNONCACHE; 1678 else 1679 np->n_flag |= NQNFSNONCACHE; 1680 np->n_expiry = ltime; 1681 np->n_lrev = frev; 1682 tp = nmp->nm_tprev; 1683 while (tp != (struct nfsnode *)nmp && tp->n_expiry > np->n_expiry) 1684 tp = tp->n_tprev; 1685 if (tp == (struct nfsnode *)nmp) { 1686 np->n_tnext = nmp->nm_tnext; 1687 nmp->nm_tnext = np; 1688 } else { 1689 np->n_tnext = tp->n_tnext; 1690 tp->n_tnext = np; 1691 } 1692 np->n_tprev = tp; 1693 if (np->n_tnext == (struct nfsnode *)nmp) 1694 nmp->nm_tprev = np; 1695 else 1696 np->n_tnext->n_tprev = np; 1697 cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp); 1698 } 1699 } else { 1700 nfsm_adv(nfsm_rndup(len)); 1701 } 1702 if (newvp != NULLVP) { 1703 vrele(newvp); 1704 newvp = NULLVP; 1705 } 1706 nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); 1707 if (bigenough) 1708 endoff = off = fxdr_unsigned(off_t, *tl++); 1709 else 1710 endoff = fxdr_unsigned(off_t, *tl++); 1711 more_dirs = fxdr_unsigned(int, *tl); 1712 } 1713 /* 1714 * If at end of rpc data, get the eof boolean 1715 */ 1716 if (!more_dirs) { 1717 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); 1718 more_dirs = (fxdr_unsigned(int, *tl) == 0); 1719 1720 /* 1721 * If at EOF, cache directory offset 1722 */ 1723 if (!more_dirs) 1724 VTONFS(vp)->n_direofoffset = endoff; 1725 } 1726 if (uiop->uio_resid < tresid) 1727 uiop->uio_offset = off; 1728 else 1729 more_dirs = 0; 1730 m_freem(mrep); 1731 } 1732 /* 1733 * Fill last record, iff any, out to a multiple of NFS_DIRBLKSIZ 1734 * by increasing d_reclen for the last record. 1735 */ 1736 if (uiop->uio_resid < tresid) { 1737 len = uiop->uio_resid & (NFS_DIRBLKSIZ - 1); 1738 if (len > 0) { 1739 dp->d_reclen += len; 1740 uiop->uio_iov->iov_base += len; 1741 uiop->uio_iov->iov_len -= len; 1742 uiop->uio_resid -= len; 1743 } 1744 } 1745 nfsmout: 1746 if (newvp != NULLVP) 1747 vrele(newvp); 1748 return (error); 1749 } 1750 static char hextoasc[] = "0123456789abcdef"; 1751 1752 /* 1753 * Silly rename. To make the NFS filesystem that is stateless look a little 1754 * more like the "ufs" a remove of an active vnode is translated to a rename 1755 * to a funny looking filename that is removed by nfs_inactive on the 1756 * nfsnode. There is the potential for another process on a different client 1757 * to create the same funny name between the nfs_lookitup() fails and the 1758 * nfs_rename() completes, but... 1759 */ 1760 int 1761 nfs_sillyrename(dvp, vp, cnp) 1762 struct vnode *dvp, *vp; 1763 struct componentname *cnp; 1764 { 1765 register struct nfsnode *np; 1766 register struct sillyrename *sp; 1767 int error; 1768 short pid; 1769 1770 cache_purge(dvp); 1771 np = VTONFS(vp); 1772 #ifdef SILLYSEPARATE 1773 MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename), 1774 M_NFSREQ, M_WAITOK); 1775 #else 1776 sp = &np->n_silly; 1777 #endif 1778 sp->s_cred = crdup(cnp->cn_cred); 1779 sp->s_dvp = dvp; 1780 VREF(dvp); 1781 1782 /* Fudge together a funny name */ 1783 pid = cnp->cn_proc->p_pid; 1784 bcopy(".nfsAxxxx4.4", sp->s_name, 13); 1785 sp->s_namlen = 12; 1786 sp->s_name[8] = hextoasc[pid & 0xf]; 1787 sp->s_name[7] = hextoasc[(pid >> 4) & 0xf]; 1788 sp->s_name[6] = hextoasc[(pid >> 8) & 0xf]; 1789 sp->s_name[5] = hextoasc[(pid >> 12) & 0xf]; 1790 1791 /* Try lookitups until we get one that isn't there */ 1792 while (nfs_lookitup(sp, (nfsv2fh_t *)0, cnp->cn_proc) == 0) { 1793 sp->s_name[4]++; 1794 if (sp->s_name[4] > 'z') { 1795 error = EINVAL; 1796 goto bad; 1797 } 1798 } 1799 if (error = nfs_renameit(dvp, cnp, sp)) 1800 goto bad; 1801 nfs_lookitup(sp, &np->n_fh, cnp->cn_proc); 1802 np->n_sillyrename = sp; 1803 return (0); 1804 bad: 1805 vrele(sp->s_dvp); 1806 crfree(sp->s_cred); 1807 #ifdef SILLYSEPARATE 1808 free((caddr_t)sp, M_NFSREQ); 1809 #endif 1810 return (error); 1811 } 1812 1813 /* 1814 * Look up a file name for silly rename stuff. 1815 * Just like nfs_lookup() except that it doesn't load returned values 1816 * into the nfsnode table. 1817 * If fhp != NULL it copies the returned file handle out 1818 */ 1819 int 1820 nfs_lookitup(sp, fhp, procp) 1821 register struct sillyrename *sp; 1822 nfsv2fh_t *fhp; 1823 struct proc *procp; 1824 { 1825 register struct vnode *vp = sp->s_dvp; 1826 register u_long *tl; 1827 register caddr_t cp; 1828 register long t1, t2; 1829 caddr_t bpos, dpos, cp2; 1830 u_long xid; 1831 int error = 0; 1832 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1833 long len; 1834 1835 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 1836 len = sp->s_namlen; 1837 nfsm_reqhead(vp, NFSPROC_LOOKUP, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)); 1838 nfsm_fhtom(vp); 1839 nfsm_strtom(sp->s_name, len, NFS_MAXNAMLEN); 1840 nfsm_request(vp, NFSPROC_LOOKUP, procp, sp->s_cred); 1841 if (fhp != NULL) { 1842 nfsm_dissect(cp, caddr_t, NFSX_FH); 1843 bcopy(cp, (caddr_t)fhp, NFSX_FH); 1844 } 1845 nfsm_reqdone; 1846 return (error); 1847 } 1848 1849 /* 1850 * Kludge City.. 1851 * - make nfs_bmap() essentially a no-op that does no translation 1852 * - do nfs_strategy() by faking physical I/O with nfs_readrpc/nfs_writerpc 1853 * after mapping the physical addresses into Kernel Virtual space in the 1854 * nfsiobuf area. 1855 * (Maybe I could use the process's page mapping, but I was concerned that 1856 * Kernel Write might not be enabled and also figured copyout() would do 1857 * a lot more work than bcopy() and also it currently happens in the 1858 * context of the swapper process (2). 1859 */ 1860 int 1861 nfs_bmap(ap) 1862 struct vop_bmap_args /* { 1863 struct vnode *a_vp; 1864 daddr_t a_bn; 1865 struct vnode **a_vpp; 1866 daddr_t *a_bnp; 1867 } */ *ap; 1868 { 1869 register struct vnode *vp = ap->a_vp; 1870 1871 if (ap->a_vpp != NULL) 1872 *ap->a_vpp = vp; 1873 if (ap->a_bnp != NULL) 1874 *ap->a_bnp = ap->a_bn * btodb(vp->v_mount->mnt_stat.f_iosize); 1875 return (0); 1876 } 1877 1878 /* 1879 * Strategy routine for phys. i/o 1880 * If the biod's are running, queue a request 1881 * otherwise just call nfs_doio() to get it done 1882 */ 1883 int 1884 nfs_strategy(ap) 1885 struct vop_strategy_args /* { 1886 struct buf *a_bp; 1887 } */ *ap; 1888 { 1889 register struct buf *bp = ap->a_bp; 1890 register struct buf *dp; 1891 register int i; 1892 int error = 0; 1893 int fnd = 0; 1894 1895 /* 1896 * Set b_proc. It seems a bit silly to do it here, but since bread() 1897 * doesn't set it, I will. 1898 * Set b_proc == NULL for asynchronous ops, since these may still 1899 * be hanging about after the process terminates. 1900 */ 1901 if ((bp->b_flags & B_PHYS) == 0) { 1902 if (bp->b_flags & B_ASYNC) 1903 bp->b_proc = (struct proc *)0; 1904 else 1905 bp->b_proc = curproc; 1906 } 1907 /* 1908 * If the op is asynchronous and an i/o daemon is waiting 1909 * queue the request, wake it up and wait for completion 1910 * otherwise just do it ourselves. 1911 */ 1912 if ((bp->b_flags & B_ASYNC) == 0 || nfs_numasync == 0) 1913 return (nfs_doio(bp)); 1914 for (i = 0; i < NFS_MAXASYNCDAEMON; i++) { 1915 if (nfs_iodwant[i]) { 1916 dp = &nfs_bqueue; 1917 if (dp->b_actf == NULL) { 1918 dp->b_actl = bp; 1919 bp->b_actf = dp; 1920 } else { 1921 dp->b_actf->b_actl = bp; 1922 bp->b_actf = dp->b_actf; 1923 } 1924 dp->b_actf = bp; 1925 bp->b_actl = dp; 1926 fnd++; 1927 wakeup((caddr_t)&nfs_iodwant[i]); 1928 break; 1929 } 1930 } 1931 if (!fnd) 1932 error = nfs_doio(bp); 1933 return (error); 1934 } 1935 1936 /* 1937 * Fun and games with i/o 1938 * Essentially play ubasetup() and disk interrupt service routine by 1939 * mapping the data buffer into kernel virtual space and doing the 1940 * nfs read or write rpc's from it. 1941 * If the nfsiod's are not running, this is just called from nfs_strategy(), 1942 * otherwise it is called by the nfsiods to do what would normally be 1943 * partially disk interrupt driven. 1944 */ 1945 int 1946 nfs_doio(bp) 1947 register struct buf *bp; 1948 { 1949 register struct uio *uiop; 1950 register struct vnode *vp; 1951 struct nfsnode *np; 1952 struct ucred *cr; 1953 int error; 1954 struct uio uio; 1955 struct iovec io; 1956 1957 vp = bp->b_vp; 1958 np = VTONFS(vp); 1959 uiop = &uio; 1960 uiop->uio_iov = &io; 1961 uiop->uio_iovcnt = 1; 1962 uiop->uio_segflg = UIO_SYSSPACE; 1963 uiop->uio_procp = bp->b_proc; 1964 1965 /* 1966 * For phys i/o, map the b_addr into kernel virtual space using 1967 * the Nfsiomap pte's 1968 * Also, add a temporary b_rcred for reading using the process's uid 1969 * and a guess at a group 1970 */ 1971 if (bp->b_flags & B_PHYS) { 1972 if (bp->b_flags & B_DIRTY) 1973 uiop->uio_procp = pageproc; 1974 cr = crcopy(uiop->uio_procp->p_ucred); 1975 /* mapping was already done by vmapbuf */ 1976 io.iov_base = bp->b_un.b_addr; 1977 1978 /* 1979 * And do the i/o rpc 1980 */ 1981 io.iov_len = uiop->uio_resid = bp->b_bcount; 1982 uiop->uio_offset = bp->b_blkno * DEV_BSIZE; 1983 if (bp->b_flags & B_READ) { 1984 uiop->uio_rw = UIO_READ; 1985 nfsstats.read_physios++; 1986 bp->b_error = error = nfs_readrpc(vp, uiop, cr); 1987 (void) vnode_pager_uncache(vp); 1988 } else { 1989 uiop->uio_rw = UIO_WRITE; 1990 nfsstats.write_physios++; 1991 bp->b_error = error = nfs_writerpc(vp, uiop, cr); 1992 } 1993 1994 /* 1995 * Finally, release pte's used by physical i/o 1996 */ 1997 crfree(cr); 1998 } else { 1999 if (bp->b_flags & B_READ) { 2000 io.iov_len = uiop->uio_resid = bp->b_bcount; 2001 io.iov_base = bp->b_un.b_addr; 2002 uiop->uio_rw = UIO_READ; 2003 switch (vp->v_type) { 2004 case VREG: 2005 uiop->uio_offset = bp->b_blkno * DEV_BSIZE; 2006 nfsstats.read_bios++; 2007 error = nfs_readrpc(vp, uiop, bp->b_rcred); 2008 break; 2009 case VLNK: 2010 uiop->uio_offset = 0; 2011 nfsstats.readlink_bios++; 2012 error = nfs_readlinkrpc(vp, uiop, bp->b_rcred); 2013 break; 2014 case VDIR: 2015 uiop->uio_offset = bp->b_lblkno; 2016 nfsstats.readdir_bios++; 2017 if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_RDIRALOOK) 2018 error = nfs_readdirlookrpc(vp, uiop, bp->b_rcred); 2019 else 2020 error = nfs_readdirrpc(vp, uiop, bp->b_rcred); 2021 /* 2022 * Save offset cookie in b_blkno. 2023 */ 2024 bp->b_blkno = uiop->uio_offset; 2025 break; 2026 }; 2027 bp->b_error = error; 2028 } else { 2029 io.iov_len = uiop->uio_resid = bp->b_dirtyend 2030 - bp->b_dirtyoff; 2031 uiop->uio_offset = (bp->b_blkno * DEV_BSIZE) 2032 + bp->b_dirtyoff; 2033 io.iov_base = bp->b_un.b_addr + bp->b_dirtyoff; 2034 uiop->uio_rw = UIO_WRITE; 2035 nfsstats.write_bios++; 2036 bp->b_error = error = nfs_writerpc(vp, uiop, 2037 bp->b_wcred); 2038 if (error) { 2039 np->n_error = error; 2040 np->n_flag |= NWRITEERR; 2041 } 2042 bp->b_dirtyoff = bp->b_dirtyend = 0; 2043 } 2044 } 2045 if (error) 2046 bp->b_flags |= B_ERROR; 2047 bp->b_resid = uiop->uio_resid; 2048 biodone(bp); 2049 return (error); 2050 } 2051 2052 /* 2053 * Mmap a file 2054 * 2055 * NB Currently unsupported. 2056 */ 2057 /* ARGSUSED */ 2058 int 2059 nfs_mmap(ap) 2060 struct vop_mmap_args /* { 2061 struct vnode *a_vp; 2062 int a_fflags; 2063 struct ucred *a_cred; 2064 struct proc *a_p; 2065 } */ *ap; 2066 { 2067 2068 return (EINVAL); 2069 } 2070 2071 /* 2072 * Flush all the blocks associated with a vnode. 2073 * Walk through the buffer pool and push any dirty pages 2074 * associated with the vnode. 2075 */ 2076 /* ARGSUSED */ 2077 int 2078 nfs_fsync(ap) 2079 struct vop_fsync_args /* { 2080 struct vnodeop_desc *a_desc; 2081 struct vnode * a_vp; 2082 struct ucred * a_cred; 2083 int a_waitfor; 2084 struct proc * a_p; 2085 } */ *ap; 2086 { 2087 register struct vnode *vp = ap->a_vp; 2088 register struct nfsnode *np = VTONFS(vp); 2089 register struct buf *bp; 2090 struct buf *nbp; 2091 int s, error = 0; 2092 2093 loop: 2094 s = splbio(); 2095 for (bp = vp->v_dirtyblkhd; bp; bp = nbp) { 2096 nbp = bp->b_blockf; 2097 if ((bp->b_flags & B_BUSY)) 2098 continue; 2099 if ((bp->b_flags & B_DELWRI) == 0) 2100 panic("nfs_fsync: not dirty"); 2101 bremfree(bp); 2102 bp->b_flags |= B_BUSY; 2103 splx(s); 2104 error = bawrite(bp); 2105 goto loop; 2106 } 2107 if (ap->a_waitfor == MNT_WAIT) { 2108 while (vp->v_numoutput) { 2109 vp->v_flag |= VBWAIT; 2110 sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1); 2111 } 2112 #ifdef DIAGNOSTIC 2113 if (vp->v_dirtyblkhd) { 2114 vprint("nfs_fsync: dirty", vp); 2115 goto loop; 2116 } 2117 #endif 2118 } 2119 splx(s); 2120 np->n_flag &= ~NMODIFIED; 2121 if (np->n_flag & NWRITEERR) { 2122 error = np->n_error; 2123 np->n_flag &= ~NWRITEERR; 2124 } 2125 return (error); 2126 } 2127 2128 /* 2129 * NFS advisory byte-level locks. 2130 * Currently unsupported. 2131 */ 2132 int 2133 nfs_advlock(ap) 2134 struct vop_advlock_args /* { 2135 struct vnode *a_vp; 2136 caddr_t a_id; 2137 int a_op; 2138 struct flock *a_fl; 2139 int a_flags; 2140 } */ *ap; 2141 { 2142 2143 return (EOPNOTSUPP); 2144 } 2145 2146 /* 2147 * Print out the contents of an nfsnode. 2148 */ 2149 int 2150 nfs_print(ap) 2151 struct vop_print_args /* { 2152 struct vnode *a_vp; 2153 } */ *ap; 2154 { 2155 register struct vnode *vp = ap->a_vp; 2156 register struct nfsnode *np = VTONFS(vp); 2157 2158 printf("tag VT_NFS, fileid %d fsid 0x%x", 2159 np->n_vattr.va_fileid, np->n_vattr.va_fsid); 2160 #ifdef FIFO 2161 if (vp->v_type == VFIFO) 2162 fifo_printinfo(vp); 2163 #endif /* FIFO */ 2164 printf("\n"); 2165 } 2166 2167 /* 2168 * NFS directory offset lookup. 2169 * Currently unsupported. 2170 */ 2171 int 2172 nfs_blkatoff(ap) 2173 struct vop_blkatoff_args /* { 2174 struct vnode *a_vp; 2175 off_t a_offset; 2176 char **a_res; 2177 struct buf **a_bpp; 2178 } */ *ap; 2179 { 2180 2181 return (EOPNOTSUPP); 2182 } 2183 2184 /* 2185 * NFS flat namespace allocation. 2186 * Currently unsupported. 2187 */ 2188 int 2189 nfs_valloc(ap) 2190 struct vop_valloc_args /* { 2191 struct vnode *a_pvp; 2192 int a_mode; 2193 struct ucred *a_cred; 2194 struct vnode **a_vpp; 2195 } */ *ap; 2196 { 2197 2198 return (EOPNOTSUPP); 2199 } 2200 2201 /* 2202 * NFS flat namespace free. 2203 * Currently unsupported. 2204 */ 2205 int 2206 nfs_vfree(ap) 2207 struct vop_vfree_args /* { 2208 struct vnode *a_pvp; 2209 ino_t a_ino; 2210 int a_mode; 2211 } */ *ap; 2212 { 2213 2214 return (EOPNOTSUPP); 2215 } 2216 2217 /* 2218 * NFS file truncation. 2219 */ 2220 int 2221 nfs_truncate(ap) 2222 struct vop_truncate_args /* { 2223 struct vnode *a_vp; 2224 off_t a_length; 2225 int a_flags; 2226 struct ucred *a_cred; 2227 struct proc *a_p; 2228 } */ *ap; 2229 { 2230 2231 /* Use nfs_setattr */ 2232 printf("nfs_truncate: need to implement!!"); 2233 return (EOPNOTSUPP); 2234 } 2235 2236 /* 2237 * NFS update. 2238 */ 2239 int 2240 nfs_update(ap) 2241 struct vop_update_args /* { 2242 struct vnode *a_vp; 2243 struct timeval *a_ta; 2244 struct timeval *a_tm; 2245 int a_waitfor; 2246 } */ *ap; 2247 { 2248 2249 /* Use nfs_setattr */ 2250 printf("nfs_update: need to implement!!"); 2251 return (EOPNOTSUPP); 2252 } 2253 2254 /* 2255 * Read wrapper for special devices. 2256 */ 2257 int 2258 nfsspec_read(ap) 2259 struct vop_read_args /* { 2260 struct vnode *a_vp; 2261 struct uio *a_uio; 2262 int a_ioflag; 2263 struct ucred *a_cred; 2264 } */ *ap; 2265 { 2266 extern int (**spec_vnodeop_p)(); 2267 register struct nfsnode *np = VTONFS(ap->a_vp); 2268 2269 /* 2270 * Set access flag. 2271 */ 2272 np->n_flag |= NACC; 2273 np->n_atim = time; 2274 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap)); 2275 } 2276 2277 /* 2278 * Write wrapper for special devices. 2279 */ 2280 int 2281 nfsspec_write(ap) 2282 struct vop_write_args /* { 2283 struct vnode *a_vp; 2284 struct uio *a_uio; 2285 int a_ioflag; 2286 struct ucred *a_cred; 2287 } */ *ap; 2288 { 2289 extern int (**spec_vnodeop_p)(); 2290 register struct nfsnode *np = VTONFS(ap->a_vp); 2291 2292 /* 2293 * Set update flag. 2294 */ 2295 np->n_flag |= NUPD; 2296 np->n_mtim = time; 2297 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap)); 2298 } 2299 2300 /* 2301 * Close wrapper for special devices. 2302 * 2303 * Update the times on the nfsnode then do device close. 2304 */ 2305 int 2306 nfsspec_close(ap) 2307 struct vop_close_args /* { 2308 struct vnode *a_vp; 2309 int a_fflag; 2310 struct ucred *a_cred; 2311 struct proc *a_p; 2312 } */ *ap; 2313 { 2314 register struct vnode *vp = ap->a_vp; 2315 register struct nfsnode *np = VTONFS(vp); 2316 struct vattr vattr; 2317 extern int (**spec_vnodeop_p)(); 2318 2319 if (np->n_flag & (NACC | NUPD)) { 2320 if (np->n_flag & NACC) 2321 np->n_atim = time; 2322 if (np->n_flag & NUPD) 2323 np->n_mtim = time; 2324 np->n_flag |= NCHG; 2325 if (vp->v_usecount == 1 && 2326 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 2327 VATTR_NULL(&vattr); 2328 if (np->n_flag & NACC) { 2329 vattr.va_atime.ts_sec = np->n_atim.tv_sec; 2330 vattr.va_atime.ts_nsec = 2331 np->n_atim.tv_usec * 1000; 2332 } 2333 if (np->n_flag & NUPD) { 2334 vattr.va_mtime.ts_sec = np->n_mtim.tv_sec; 2335 vattr.va_mtime.ts_nsec = 2336 np->n_mtim.tv_usec * 1000; 2337 } 2338 (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_p); 2339 } 2340 } 2341 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap)); 2342 } 2343 2344 #ifdef FIFO 2345 /* 2346 * Read wrapper for fifos. 2347 */ 2348 int 2349 nfsfifo_read(ap) 2350 struct vop_read_args /* { 2351 struct vnode *a_vp; 2352 struct uio *a_uio; 2353 int a_ioflag; 2354 struct ucred *a_cred; 2355 } */ *ap; 2356 { 2357 extern int (**fifo_vnodeop_p)(); 2358 register struct nfsnode *np = VTONFS(ap->a_vp); 2359 2360 /* 2361 * Set access flag. 2362 */ 2363 np->n_flag |= NACC; 2364 np->n_atim = time; 2365 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap)); 2366 } 2367 2368 /* 2369 * Write wrapper for fifos. 2370 */ 2371 int 2372 nfsfifo_write(ap) 2373 struct vop_write_args /* { 2374 struct vnode *a_vp; 2375 struct uio *a_uio; 2376 int a_ioflag; 2377 struct ucred *a_cred; 2378 } */ *ap; 2379 { 2380 extern int (**fifo_vnodeop_p)(); 2381 register struct nfsnode *np = VTONFS(ap->a_vp); 2382 2383 /* 2384 * Set update flag. 2385 */ 2386 np->n_flag |= NUPD; 2387 np->n_mtim = time; 2388 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap)); 2389 } 2390 2391 /* 2392 * Close wrapper for fifos. 2393 * 2394 * Update the times on the nfsnode then do fifo close. 2395 */ 2396 int 2397 nfsfifo_close(ap) 2398 struct vop_close_args /* { 2399 struct vnode *a_vp; 2400 int a_fflag; 2401 struct ucred *a_cred; 2402 struct proc *a_p; 2403 } */ *ap; 2404 { 2405 register struct vnode *vp = ap->a_vp; 2406 register struct nfsnode *np = VTONFS(vp); 2407 struct vattr vattr; 2408 extern int (**fifo_vnodeop_p)(); 2409 2410 if (np->n_flag & (NACC | NUPD)) { 2411 if (np->n_flag & NACC) 2412 np->n_atim = time; 2413 if (np->n_flag & NUPD) 2414 np->n_mtim = time; 2415 np->n_flag |= NCHG; 2416 if (vp->v_usecount == 1 && 2417 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 2418 VATTR_NULL(&vattr); 2419 if (np->n_flag & NACC) { 2420 vattr.va_atime.ts_sec = np->n_atim.tv_sec; 2421 vattr.va_atime.ts_nsec = 2422 np->n_atim.tv_usec * 1000; 2423 } 2424 if (np->n_flag & NUPD) { 2425 vattr.va_mtime.ts_sec = np->n_mtim.tv_sec; 2426 vattr.va_mtime.ts_nsec = 2427 np->n_mtim.tv_usec * 1000; 2428 } 2429 (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_p); 2430 } 2431 } 2432 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap)); 2433 } 2434 #endif /* FIFO */ 2435