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