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