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