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