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