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