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 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the University of California, Berkeley. The name of the 14 * University may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * @(#)nfs_vnops.c 7.25 (Berkeley) 02/08/90 21 */ 22 23 /* 24 * vnode op calls for sun nfs version 2 25 */ 26 27 #include "machine/pte.h" 28 #include "machine/mtpr.h" 29 #include "strings.h" 30 #include "param.h" 31 #include "user.h" 32 #include "proc.h" 33 #include "mount.h" 34 #include "buf.h" 35 #include "vm.h" 36 #include "../ufs/dir.h" 37 #include "malloc.h" 38 #include "mbuf.h" 39 #include "uio.h" 40 #include "ucred.h" 41 #include "namei.h" 42 #include "errno.h" 43 #include "file.h" 44 #include "conf.h" 45 #include "vnode.h" 46 #include "../ufs/inode.h" 47 #include "map.h" 48 #include "nfsv2.h" 49 #include "nfs.h" 50 #include "nfsnode.h" 51 #include "nfsmount.h" 52 #include "xdr_subs.h" 53 #include "nfsm_subs.h" 54 #include "nfsiom.h" 55 56 /* Defs */ 57 #define TRUE 1 58 #define FALSE 0 59 60 /* Global vars */ 61 int nfs_lookup(), 62 nfs_create(), 63 nfs_mknod(), 64 nfs_open(), 65 nfs_close(), 66 nfs_access(), 67 nfs_getattr(), 68 nfs_setattr(), 69 nfs_read(), 70 nfs_write(), 71 vfs_noop(), 72 vfs_nullop(), 73 nfs_remove(), 74 nfs_link(), 75 nfs_rename(), 76 nfs_mkdir(), 77 nfs_rmdir(), 78 nfs_symlink(), 79 nfs_readdir(), 80 nfs_readlink(), 81 nfs_abortop(), 82 nfs_lock(), 83 nfs_unlock(), 84 nfs_bmap(), 85 nfs_strategy(), 86 nfs_fsync(), 87 nfs_inactive(), 88 nfs_reclaim(), 89 nfs_print(), 90 nfs_islocked(); 91 92 struct vnodeops nfsv2_vnodeops = { 93 nfs_lookup, /* lookup */ 94 nfs_create, /* create */ 95 nfs_mknod, /* mknod */ 96 nfs_open, /* open */ 97 nfs_close, /* close */ 98 nfs_access, /* access */ 99 nfs_getattr, /* getattr */ 100 nfs_setattr, /* setattr */ 101 nfs_read, /* read */ 102 nfs_write, /* write */ 103 vfs_noop, /* ioctl */ 104 vfs_noop, /* select */ 105 vfs_noop, /* mmap */ 106 nfs_fsync, /* fsync */ 107 vfs_nullop, /* seek */ 108 nfs_remove, /* remove */ 109 nfs_link, /* link */ 110 nfs_rename, /* rename */ 111 nfs_mkdir, /* mkdir */ 112 nfs_rmdir, /* rmdir */ 113 nfs_symlink, /* symlink */ 114 nfs_readdir, /* readdir */ 115 nfs_readlink, /* readlink */ 116 nfs_abortop, /* abortop */ 117 nfs_inactive, /* inactive */ 118 nfs_reclaim, /* reclaim */ 119 nfs_lock, /* lock */ 120 nfs_unlock, /* unlock */ 121 nfs_bmap, /* bmap */ 122 nfs_strategy, /* strategy */ 123 nfs_print, /* print */ 124 nfs_islocked, /* islocked */ 125 }; 126 127 /* Special device vnode ops */ 128 int spec_lookup(), 129 spec_open(), 130 spec_read(), 131 spec_write(), 132 spec_strategy(), 133 spec_bmap(), 134 spec_ioctl(), 135 spec_select(), 136 spec_close(), 137 spec_badop(), 138 spec_nullop(); 139 140 struct vnodeops spec_nfsv2nodeops = { 141 spec_lookup, /* lookup */ 142 spec_badop, /* create */ 143 spec_badop, /* mknod */ 144 spec_open, /* open */ 145 spec_close, /* close */ 146 nfs_access, /* access */ 147 nfs_getattr, /* getattr */ 148 nfs_setattr, /* setattr */ 149 spec_read, /* read */ 150 spec_write, /* write */ 151 spec_ioctl, /* ioctl */ 152 spec_select, /* select */ 153 spec_badop, /* mmap */ 154 spec_nullop, /* fsync */ 155 spec_badop, /* seek */ 156 spec_badop, /* remove */ 157 spec_badop, /* link */ 158 spec_badop, /* rename */ 159 spec_badop, /* mkdir */ 160 spec_badop, /* rmdir */ 161 spec_badop, /* symlink */ 162 spec_badop, /* readdir */ 163 spec_badop, /* readlink */ 164 spec_badop, /* abortop */ 165 nfs_inactive, /* inactive */ 166 nfs_reclaim, /* reclaim */ 167 nfs_lock, /* lock */ 168 nfs_unlock, /* unlock */ 169 spec_bmap, /* bmap */ 170 spec_strategy, /* strategy */ 171 nfs_print, /* print */ 172 nfs_islocked, /* islocked */ 173 }; 174 175 extern u_long nfs_procids[NFS_NPROCS]; 176 extern u_long nfs_prog, nfs_vers; 177 extern char nfsiobuf[MAXPHYS+NBPG]; 178 struct map nfsmap[NFS_MSIZ]; 179 enum vtype v_type[NFLNK+1]; 180 struct buf nfs_bqueue; /* Queue head for nfsiod's */ 181 int nfs_asyncdaemons = 0; 182 struct proc *nfs_iodwant[MAX_ASYNCDAEMON]; 183 static int nfsmap_want = 0; 184 185 /* 186 * nfs null call from vfs. 187 */ 188 nfs_null(vp, cred) 189 struct vnode *vp; 190 struct ucred *cred; 191 { 192 caddr_t bpos, dpos; 193 u_long xid; 194 int error = 0; 195 struct mbuf *mreq, *mrep, *md, *mb; 196 197 nfsm_reqhead(nfs_procids[NFSPROC_NULL], cred, 0); 198 nfsm_request(vp); 199 nfsm_reqdone; 200 return (error); 201 } 202 203 /* 204 * nfs access vnode op. 205 * Essentially just get vattr and then imitate iaccess() 206 */ 207 nfs_access(vp, mode, cred) 208 struct vnode *vp; 209 int mode; 210 register struct ucred *cred; 211 { 212 register struct vattr *vap; 213 register gid_t *gp; 214 struct vattr vattr; 215 register int i; 216 int error; 217 218 /* 219 * If you're the super-user, 220 * you always get access. 221 */ 222 if (cred->cr_uid == 0) 223 return (0); 224 vap = &vattr; 225 if (error = nfs_getattr(vp, vap, cred)) 226 return (error); 227 /* 228 * Access check is based on only one of owner, group, public. 229 * If not owner, then check group. If not a member of the 230 * group, then check public access. 231 */ 232 if (cred->cr_uid != vap->va_uid) { 233 mode >>= 3; 234 gp = cred->cr_groups; 235 for (i = 0; i < cred->cr_ngroups; i++, gp++) 236 if (vap->va_gid == *gp) 237 goto found; 238 mode >>= 3; 239 found: 240 ; 241 } 242 if ((vap->va_mode & mode) != 0) 243 return (0); 244 return (EACCES); 245 } 246 247 /* 248 * nfs open vnode op 249 * Just check to see if the type is ok 250 */ 251 /* ARGSUSED */ 252 nfs_open(vp, mode, cred) 253 struct vnode *vp; 254 int mode; 255 struct ucred *cred; 256 { 257 register enum vtype vtyp; 258 259 vtyp = vp->v_type; 260 if (vtyp == VREG || vtyp == VDIR || vtyp == VLNK) 261 return (0); 262 else 263 return (EACCES); 264 } 265 266 /* 267 * nfs close vnode op 268 * For reg files, invalidate any buffer cache entries. 269 */ 270 /* ARGSUSED */ 271 nfs_close(vp, fflags, cred) 272 register struct vnode *vp; 273 int fflags; 274 struct ucred *cred; 275 { 276 register struct nfsnode *np = VTONFS(vp); 277 int error = 0; 278 279 if (vp->v_type == VREG && ((np->n_flag & NMODIFIED) || 280 ((np->n_flag & NBUFFERED) && np->n_sillyrename))) { 281 nfs_lock(vp); 282 np->n_flag &= ~(NMODIFIED|NBUFFERED); 283 vinvalbuf(vp, TRUE); 284 if (np->n_flag & NWRITEERR) { 285 np->n_flag &= ~NWRITEERR; 286 error = np->n_error; 287 } 288 nfs_unlock(vp); 289 } 290 return (error); 291 } 292 293 /* 294 * nfs getattr call from vfs. 295 */ 296 nfs_getattr(vp, vap, cred) 297 register struct vnode *vp; 298 struct vattr *vap; 299 struct ucred *cred; 300 { 301 register caddr_t cp; 302 register long t1; 303 caddr_t bpos, dpos; 304 u_long xid; 305 int error = 0; 306 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 307 308 /* First look in the cache.. */ 309 if (nfs_getattrcache(vp, vap) == 0) 310 return (0); 311 nfsstats.rpccnt[NFSPROC_GETATTR]++; 312 nfsm_reqhead(nfs_procids[NFSPROC_GETATTR], cred, NFSX_FH); 313 nfsm_fhtom(vp); 314 nfsm_request(vp); 315 nfsm_loadattr(vp, vap); 316 nfsm_reqdone; 317 return (error); 318 } 319 320 /* 321 * nfs setattr call. 322 */ 323 nfs_setattr(vp, vap, cred) 324 register struct vnode *vp; 325 register struct vattr *vap; 326 struct ucred *cred; 327 { 328 register struct nfsv2_sattr *sp; 329 register caddr_t cp; 330 register long t1; 331 caddr_t bpos, dpos; 332 u_long xid; 333 int error = 0; 334 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 335 struct nfsnode *np; 336 337 nfsstats.rpccnt[NFSPROC_SETATTR]++; 338 nfsm_reqhead(nfs_procids[NFSPROC_SETATTR], cred, NFSX_FH+NFSX_SATTR); 339 nfsm_fhtom(vp); 340 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 341 if (vap->va_mode == 0xffff) 342 sp->sa_mode = VNOVAL; 343 else 344 sp->sa_mode = vtonfs_mode(vp->v_type, vap->va_mode); 345 if (vap->va_uid == 0xffff) 346 sp->sa_uid = VNOVAL; 347 else 348 sp->sa_uid = txdr_unsigned(vap->va_uid); 349 if (vap->va_gid == 0xffff) 350 sp->sa_gid = VNOVAL; 351 else 352 sp->sa_gid = txdr_unsigned(vap->va_gid); 353 sp->sa_size = txdr_unsigned(vap->va_size); 354 if (vap->va_size != VNOVAL) { 355 np = VTONFS(vp); 356 if (np->n_flag & NMODIFIED) { 357 np->n_flag &= ~NMODIFIED; 358 vinvalbuf(vp, TRUE); 359 } 360 } 361 sp->sa_atime.tv_sec = txdr_unsigned(vap->va_atime.tv_sec); 362 sp->sa_atime.tv_usec = txdr_unsigned(vap->va_flags); 363 txdr_time(&vap->va_mtime, &sp->sa_mtime); 364 nfsm_request(vp); 365 nfsm_loadattr(vp, (struct vattr *)0); 366 /* should we fill in any vap fields ?? */ 367 nfsm_reqdone; 368 return (error); 369 } 370 371 /* 372 * nfs lookup call, one step at a time... 373 * First look in cache 374 * If not found, unlock the directory nfsnode and do the rpc 375 */ 376 nfs_lookup(vp, ndp) 377 register struct vnode *vp; 378 register struct nameidata *ndp; 379 { 380 register struct vnode *vdp; 381 register u_long *p; 382 register caddr_t cp; 383 register long t1, t2; 384 caddr_t bpos, dpos, cp2; 385 u_long xid; 386 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 387 struct vnode *newvp; 388 long len; 389 nfsv2fh_t *fhp; 390 struct nfsnode *np; 391 int lockparent, wantparent, flag, error = 0; 392 393 ndp->ni_dvp = vp; 394 ndp->ni_vp = NULL; 395 if (vp->v_type != VDIR) 396 return (ENOTDIR); 397 lockparent = ndp->ni_nameiop & LOCKPARENT; 398 flag = ndp->ni_nameiop & OPFLAG; 399 wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT); 400 if ((error = cache_lookup(ndp)) && error != ENOENT) { 401 struct vattr vattr; 402 int vpid; 403 404 if (vp == ndp->ni_rdir && ndp->ni_isdotdot) 405 panic("nfs_lookup: .. through root"); 406 vdp = ndp->ni_vp; 407 vpid = vdp->v_id; 408 /* 409 * See the comment starting `Step through' in ufs/ufs_lookup.c 410 * for an explanation of the locking protocol 411 */ 412 if (vp == vdp) { 413 VREF(vdp); 414 error = 0; 415 } else if (ndp->ni_isdotdot) { 416 nfs_unlock(vp); 417 error = vget(vdp); 418 } else { 419 error = vget(vdp); 420 nfs_unlock(vp); 421 } 422 if (!error) { 423 if (vpid == vdp->v_id && 424 !nfs_getattr(vdp, &vattr, ndp->ni_cred)) { 425 nfsstats.lookupcache_hits++; 426 return (0); 427 } else { 428 nfs_nput(vdp); 429 } 430 } 431 ndp->ni_vp = (struct vnode *)0; 432 } else 433 nfs_unlock(vp); 434 error = 0; 435 nfsstats.lookupcache_misses++; 436 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 437 len = ndp->ni_namelen; 438 nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], ndp->ni_cred, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)); 439 nfsm_fhtom(vp); 440 nfsm_strtom(ndp->ni_ptr, len, NFS_MAXNAMLEN); 441 nfsm_request(vp); 442 nfsmout: 443 if (error) { 444 if (lockparent || (flag != CREATE && flag != RENAME) || 445 *ndp->ni_next != 0) 446 nfs_lock(vp); 447 return (ENOENT); 448 } 449 nfsm_disect(fhp,nfsv2fh_t *,NFSX_FH); 450 451 /* 452 * Handle DELETE and RENAME cases... 453 */ 454 if (flag == DELETE && *ndp->ni_next == 0) { 455 if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) { 456 VREF(vp); 457 newvp = vp; 458 np = VTONFS(vp); 459 } else { 460 if (error = nfs_nget(vp->v_mount, fhp, &np)) { 461 nfs_lock(vp); 462 m_freem(mrep); 463 return (error); 464 } 465 newvp = NFSTOV(np); 466 } 467 if (error = 468 nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) { 469 nfs_lock(vp); 470 if (newvp != vp) 471 nfs_nput(newvp); 472 else 473 vrele(vp); 474 m_freem(mrep); 475 return (error); 476 } 477 ndp->ni_vp = newvp; 478 if (lockparent || vp == newvp) 479 nfs_lock(vp); 480 m_freem(mrep); 481 return (0); 482 } 483 484 if (flag == RENAME && wantparent && *ndp->ni_next == 0) { 485 if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) { 486 nfs_lock(vp); 487 m_freem(mrep); 488 return (EISDIR); 489 } 490 if (error = nfs_nget(vp->v_mount, fhp, &np)) { 491 nfs_lock(vp); 492 m_freem(mrep); 493 return (error); 494 } 495 newvp = NFSTOV(np); 496 if (error = 497 nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) { 498 nfs_lock(vp); 499 nfs_nput(newvp); 500 m_freem(mrep); 501 return (error); 502 } 503 ndp->ni_vp = newvp; 504 if (lockparent) 505 nfs_lock(vp); 506 return (0); 507 } 508 509 if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) { 510 VREF(vp); 511 newvp = vp; 512 np = VTONFS(vp); 513 } else if (ndp->ni_isdotdot) { 514 if (error = nfs_nget(vp->v_mount, fhp, &np)) { 515 nfs_lock(vp); 516 m_freem(mrep); 517 return (error); 518 } 519 newvp = NFSTOV(np); 520 } else { 521 if (error = nfs_nget(vp->v_mount, fhp, &np)) { 522 nfs_lock(vp); 523 m_freem(mrep); 524 return (error); 525 } 526 newvp = NFSTOV(np); 527 } 528 if (error = nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) { 529 nfs_lock(vp); 530 if (newvp != vp) 531 nfs_nput(newvp); 532 else 533 vrele(vp); 534 m_freem(mrep); 535 return (error); 536 } 537 m_freem(mrep); 538 539 if (vp == newvp || (lockparent && *ndp->ni_next == '\0')) 540 nfs_lock(vp); 541 ndp->ni_vp = newvp; 542 if (error == 0 && ndp->ni_makeentry) 543 cache_enter(ndp); 544 return (error); 545 } 546 547 /* 548 * nfs readlink call 549 */ 550 nfs_readlink(vp, uiop, cred) 551 register struct vnode *vp; 552 struct uio *uiop; 553 struct ucred *cred; 554 { 555 register u_long *p; 556 register caddr_t cp; 557 register long t1; 558 caddr_t bpos, dpos, cp2; 559 u_long xid; 560 int error = 0; 561 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 562 long len; 563 564 nfsstats.rpccnt[NFSPROC_READLINK]++; 565 nfsm_reqhead(nfs_procids[NFSPROC_READLINK], cred, NFSX_FH); 566 nfsm_fhtom(vp); 567 nfsm_request(vp); 568 nfsm_strsiz(len, NFS_MAXPATHLEN); 569 nfsm_mtouio(uiop, len); 570 nfsm_reqdone; 571 return (error); 572 } 573 574 /* 575 * nfs read call 576 */ 577 nfs_readrpc(vp, uiop, cred) 578 register struct vnode *vp; 579 struct uio *uiop; 580 struct ucred *cred; 581 { 582 register u_long *p; 583 register caddr_t cp; 584 register long t1; 585 caddr_t bpos, dpos, cp2; 586 u_long xid; 587 int error = 0; 588 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 589 struct nfsmount *nmp; 590 long len, retlen, tsiz; 591 592 nmp = vfs_to_nfs(vp->v_mount); 593 tsiz = uiop->uio_resid; 594 while (tsiz > 0) { 595 nfsstats.rpccnt[NFSPROC_READ]++; 596 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; 597 nfsm_reqhead(nfs_procids[NFSPROC_READ], cred, NFSX_FH+NFSX_UNSIGNED*3); 598 nfsm_fhtom(vp); 599 nfsm_build(p, u_long *, NFSX_UNSIGNED*3); 600 *p++ = txdr_unsigned(uiop->uio_offset); 601 *p++ = txdr_unsigned(len); 602 *p = 0; 603 nfsm_request(vp); 604 nfsm_loadattr(vp, (struct vattr *)0); 605 nfsm_strsiz(retlen, nmp->nm_rsize); 606 nfsm_mtouio(uiop, retlen); 607 m_freem(mrep); 608 if (retlen < len) 609 tsiz = 0; 610 else 611 tsiz -= len; 612 } 613 nfsmout: 614 return (error); 615 } 616 617 /* 618 * nfs write call 619 */ 620 nfs_writerpc(vp, uiop, cred) 621 register struct vnode *vp; 622 struct uio *uiop; 623 struct ucred *cred; 624 { 625 register u_long *p; 626 register caddr_t cp; 627 register long t1; 628 caddr_t bpos, dpos; 629 u_long xid; 630 int error = 0; 631 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 632 struct nfsmount *nmp; 633 long len, tsiz; 634 635 nmp = vfs_to_nfs(vp->v_mount); 636 tsiz = uiop->uio_resid; 637 while (tsiz > 0) { 638 nfsstats.rpccnt[NFSPROC_WRITE]++; 639 len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; 640 nfsm_reqhead(nfs_procids[NFSPROC_WRITE], cred, 641 NFSX_FH+NFSX_UNSIGNED*4); 642 nfsm_fhtom(vp); 643 nfsm_build(p, u_long *, NFSX_UNSIGNED*4); 644 *(p+1) = txdr_unsigned(uiop->uio_offset); 645 *(p+3) = txdr_unsigned(len); 646 nfsm_uiotom(uiop, len); 647 nfsm_request(vp); 648 nfsm_loadattr(vp, (struct vattr *)0); 649 m_freem(mrep); 650 tsiz -= len; 651 } 652 nfsmout: 653 return (error); 654 } 655 656 /* 657 * nfs mknod call 658 * This call is currently not supported. 659 */ 660 /* ARGSUSED */ 661 nfs_mknod(ndp, vap, cred) 662 struct nameidata *ndp; 663 struct ucred *cred; 664 struct vattr *vap; 665 { 666 667 nfs_abortop(ndp); 668 return (EOPNOTSUPP); 669 } 670 671 /* 672 * nfs file create call 673 */ 674 nfs_create(ndp, vap) 675 register struct nameidata *ndp; 676 register struct vattr *vap; 677 { 678 register struct nfsv2_sattr *sp; 679 register u_long *p; 680 register caddr_t cp; 681 register long t1, t2; 682 caddr_t bpos, dpos, cp2; 683 u_long xid; 684 int error = 0; 685 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 686 687 nfsstats.rpccnt[NFSPROC_CREATE]++; 688 nfsm_reqhead(nfs_procids[NFSPROC_CREATE], ndp->ni_cred, 689 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)+NFSX_SATTR); 690 nfsm_fhtom(ndp->ni_dvp); 691 nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN); 692 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 693 sp->sa_mode = vtonfs_mode(VREG, vap->va_mode); 694 sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid); 695 sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid); 696 sp->sa_size = txdr_unsigned(0); 697 /* or should these be VNOVAL ?? */ 698 txdr_time(&vap->va_atime, &sp->sa_atime); 699 txdr_time(&vap->va_mtime, &sp->sa_mtime); 700 nfsm_request(ndp->ni_dvp); 701 nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp); 702 nfsm_reqdone; 703 nfs_nput(ndp->ni_dvp); 704 return (error); 705 } 706 707 /* 708 * nfs file remove call 709 * To try and make nfs semantics closer to vfs semantics, a file that has 710 * other references to the vnode is renamed instead of removed and then 711 * removed later on the last close. 712 * Unfortunately you must flush the buffer cache and cmap to get rid of 713 * all extraneous vnode references before you check the reference cnt. 714 * 1 - If the file could have blocks in the buffer cache 715 * flush them out and invalidate them 716 * mpurge the vnode to flush out cmap references 717 * (This is necessary to update the vnode ref cnt as well as sensible 718 * for actual removes, to free up the buffers) 719 * 2 - If v_usecount > 1 720 * If a rename is not already in the works 721 * call nfs_sillyrename() to set it up 722 * else 723 * do the remove rpc 724 */ 725 nfs_remove(ndp) 726 register struct nameidata *ndp; 727 { 728 register struct vnode *vp = ndp->ni_vp; 729 register struct nfsnode *np = VTONFS(ndp->ni_vp); 730 register u_long *p; 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 738 if (vp->v_type == VREG) { 739 if (np->n_flag & (NMODIFIED|NBUFFERED)) { 740 np->n_flag &= ~(NMODIFIED|NBUFFERED); 741 vinvalbuf(vp, TRUE); 742 } 743 if (np->n_flag & NPAGEDON) { 744 np->n_flag &= ~NPAGEDON; 745 mpurge(vp); /* In case cmap entries still ref it */ 746 } 747 } 748 if (vp->v_usecount > 1) { 749 if (!np->n_sillyrename) 750 error = nfs_sillyrename(ndp, REMOVE); 751 } else { 752 nfsstats.rpccnt[NFSPROC_REMOVE]++; 753 nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], ndp->ni_cred, 754 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)); 755 nfsm_fhtom(ndp->ni_dvp); 756 nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN); 757 nfsm_request(ndp->ni_dvp); 758 nfsm_reqdone; 759 /* 760 * Kludge City: If the first reply to the remove rpc is lost.. 761 * the reply to the retransmitted request will be ENOENT 762 * since the file was in fact removed 763 * Therefore, we cheat and return success. 764 */ 765 if (error == ENOENT) 766 error = 0; 767 } 768 np->n_attrstamp = 0; 769 if (ndp->ni_dvp == ndp->ni_vp) 770 vrele(ndp->ni_vp); 771 else 772 nfs_nput(ndp->ni_vp); 773 nfs_nput(ndp->ni_dvp); 774 return (error); 775 } 776 777 /* 778 * nfs file remove rpc called from nfs_inactive 779 */ 780 nfs_removeit(ndp) 781 register struct nameidata *ndp; 782 { 783 register u_long *p; 784 register caddr_t cp; 785 register long t1, t2; 786 caddr_t bpos, dpos; 787 u_long xid; 788 int error = 0; 789 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 790 791 nfsstats.rpccnt[NFSPROC_REMOVE]++; 792 nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], ndp->ni_cred, 793 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)); 794 nfsm_fhtom(ndp->ni_dvp); 795 nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN); 796 nfsm_request(ndp->ni_dvp); 797 nfsm_reqdone; 798 return (error); 799 } 800 801 /* 802 * nfs file rename call 803 */ 804 nfs_rename(sndp, tndp) 805 register struct nameidata *sndp, *tndp; 806 { 807 register u_long *p; 808 register caddr_t cp; 809 register long t1, t2; 810 caddr_t bpos, dpos; 811 u_long xid; 812 int error = 0; 813 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 814 815 nfsstats.rpccnt[NFSPROC_RENAME]++; 816 nfsm_reqhead(nfs_procids[NFSPROC_RENAME], tndp->ni_cred, 817 (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_dent.d_namlen)+ 818 nfsm_rndup(tndp->ni_dent.d_namlen)); /* or sndp->ni_cred?*/ 819 nfsm_fhtom(sndp->ni_dvp); 820 nfsm_strtom(sndp->ni_dent.d_name,sndp->ni_dent.d_namlen,NFS_MAXNAMLEN); 821 nfsm_fhtom(tndp->ni_dvp); 822 nfsm_strtom(tndp->ni_dent.d_name,tndp->ni_dent.d_namlen,NFS_MAXNAMLEN); 823 nfsm_request(sndp->ni_dvp); 824 nfsm_reqdone; 825 if (sndp->ni_vp->v_type == VDIR) { 826 if (tndp->ni_vp != NULL && tndp->ni_vp->v_type == VDIR) 827 cache_purge(tndp->ni_dvp); 828 cache_purge(sndp->ni_dvp); 829 } 830 nfs_abortop(sndp); 831 nfs_abortop(tndp); 832 return (error); 833 } 834 835 /* 836 * nfs file rename rpc called from above 837 */ 838 nfs_renameit(sndp, tndp) 839 register struct nameidata *sndp, *tndp; 840 { 841 register u_long *p; 842 register caddr_t cp; 843 register long t1, t2; 844 caddr_t bpos, dpos; 845 u_long xid; 846 int error = 0; 847 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 848 849 nfsstats.rpccnt[NFSPROC_RENAME]++; 850 nfsm_reqhead(nfs_procids[NFSPROC_RENAME], tndp->ni_cred, 851 (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_dent.d_namlen)+ 852 nfsm_rndup(tndp->ni_dent.d_namlen)); /* or sndp->ni_cred?*/ 853 nfsm_fhtom(sndp->ni_dvp); 854 nfsm_strtom(sndp->ni_dent.d_name,sndp->ni_dent.d_namlen,NFS_MAXNAMLEN); 855 nfsm_fhtom(tndp->ni_dvp); 856 nfsm_strtom(tndp->ni_dent.d_name,tndp->ni_dent.d_namlen,NFS_MAXNAMLEN); 857 nfsm_request(sndp->ni_dvp); 858 nfsm_reqdone; 859 return (error); 860 } 861 862 /* 863 * nfs hard link create call 864 */ 865 nfs_link(vp, ndp) 866 register struct vnode *vp; 867 register struct nameidata *ndp; 868 { 869 register u_long *p; 870 register caddr_t cp; 871 register long t1, t2; 872 caddr_t bpos, dpos; 873 u_long xid; 874 int error = 0; 875 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 876 877 if (ndp->ni_dvp != vp) 878 nfs_lock(vp); 879 nfsstats.rpccnt[NFSPROC_LINK]++; 880 nfsm_reqhead(nfs_procids[NFSPROC_LINK], ndp->ni_cred, 881 NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)); 882 nfsm_fhtom(vp); 883 nfsm_fhtom(ndp->ni_dvp); 884 nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN); 885 nfsm_request(vp); 886 nfsm_reqdone; 887 VTONFS(vp)->n_attrstamp = 0; 888 if (ndp->ni_dvp != vp) 889 nfs_unlock(vp); 890 nfs_nput(ndp->ni_dvp); 891 return (error); 892 } 893 894 /* 895 * nfs symbolic link create call 896 */ 897 nfs_symlink(ndp, vap, nm) 898 struct nameidata *ndp; 899 struct vattr *vap; 900 char *nm; /* is this the path ?? */ 901 { 902 register struct nfsv2_sattr *sp; 903 register u_long *p; 904 register caddr_t cp; 905 register long t1, t2; 906 caddr_t bpos, dpos; 907 u_long xid; 908 int error = 0; 909 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 910 911 nfsstats.rpccnt[NFSPROC_SYMLINK]++; 912 nfsm_reqhead(nfs_procids[NFSPROC_SYMLINK], ndp->ni_cred, 913 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)+NFSX_UNSIGNED); 914 nfsm_fhtom(ndp->ni_dvp); 915 nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN); 916 nfsm_strtom(nm, strlen(nm), NFS_MAXPATHLEN); 917 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 918 sp->sa_mode = vtonfs_mode(VLNK, vap->va_mode); 919 sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid); 920 sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid); 921 sp->sa_size = txdr_unsigned(VNOVAL); 922 txdr_time(&vap->va_atime, &sp->sa_atime); /* or VNOVAL ?? */ 923 txdr_time(&vap->va_mtime, &sp->sa_mtime); /* or VNOVAL ?? */ 924 nfsm_request(ndp->ni_dvp); 925 nfsm_reqdone; 926 nfs_nput(ndp->ni_dvp); 927 return (error); 928 } 929 930 /* 931 * nfs make dir call 932 */ 933 nfs_mkdir(ndp, vap) 934 register struct nameidata *ndp; 935 struct vattr *vap; 936 { 937 register struct nfsv2_sattr *sp; 938 register u_long *p; 939 register caddr_t cp; 940 register long t1, t2; 941 caddr_t bpos, dpos, cp2; 942 u_long xid; 943 int error = 0; 944 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 945 946 nfsstats.rpccnt[NFSPROC_MKDIR]++; 947 nfsm_reqhead(nfs_procids[NFSPROC_MKDIR], ndp->ni_cred, 948 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)+NFSX_SATTR); 949 nfsm_fhtom(ndp->ni_dvp); 950 nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN); 951 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 952 sp->sa_mode = vtonfs_mode(VDIR, vap->va_mode); 953 sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid); 954 sp->sa_gid = txdr_unsigned(ndp->ni_cred->cr_gid); 955 sp->sa_size = txdr_unsigned(VNOVAL); 956 txdr_time(&vap->va_atime, &sp->sa_atime); /* or VNOVAL ?? */ 957 txdr_time(&vap->va_mtime, &sp->sa_mtime); /* or VNOVAL ?? */ 958 nfsm_request(ndp->ni_dvp); 959 nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp); 960 nfsm_reqdone; 961 nfs_nput(ndp->ni_dvp); 962 return (error); 963 } 964 965 /* 966 * nfs remove directory call 967 */ 968 nfs_rmdir(ndp) 969 register struct nameidata *ndp; 970 { 971 register u_long *p; 972 register caddr_t cp; 973 register long t1, t2; 974 caddr_t bpos, dpos; 975 u_long xid; 976 int error = 0; 977 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 978 979 if (ndp->ni_dvp == ndp->ni_vp) { 980 vrele(ndp->ni_dvp); 981 nfs_nput(ndp->ni_dvp); 982 return (EINVAL); 983 } 984 nfsstats.rpccnt[NFSPROC_RMDIR]++; 985 nfsm_reqhead(nfs_procids[NFSPROC_RMDIR], ndp->ni_cred, 986 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)); 987 nfsm_fhtom(ndp->ni_dvp); 988 nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN); 989 nfsm_request(ndp->ni_dvp); 990 nfsm_reqdone; 991 cache_purge(ndp->ni_dvp); 992 cache_purge(ndp->ni_vp); 993 nfs_nput(ndp->ni_vp); 994 nfs_nput(ndp->ni_dvp); 995 return (error); 996 } 997 998 /* 999 * nfs readdir call 1000 * Although cookie is defined as opaque, I translate it to/from net byte 1001 * order so that it looks more sensible. This appears consistent with the 1002 * Ultrix implementation of NFS. 1003 */ 1004 nfs_readdir(vp, uiop, cred) 1005 register struct vnode *vp; 1006 struct uio *uiop; 1007 struct ucred *cred; 1008 { 1009 register long len; 1010 register struct direct *dp; 1011 register u_long *p; 1012 register caddr_t cp; 1013 register long t1; 1014 caddr_t bpos, dpos, cp2; 1015 u_long xid; 1016 int error = 0; 1017 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1018 struct mbuf *md2; 1019 caddr_t dpos2; 1020 int siz; 1021 int more_dirs; 1022 off_t off, savoff; 1023 struct direct *savdp; 1024 1025 nfsstats.rpccnt[NFSPROC_READDIR]++; 1026 nfsm_reqhead(nfs_procids[NFSPROC_READDIR], cred, xid); 1027 nfsm_fhtom(vp); 1028 nfsm_build(p, u_long *, 2*NFSX_UNSIGNED); 1029 *p++ = txdr_unsigned(uiop->uio_offset); 1030 *p = txdr_unsigned(uiop->uio_resid); 1031 nfsm_request(vp); 1032 siz = 0; 1033 nfsm_disect(p, u_long *, NFSX_UNSIGNED); 1034 more_dirs = fxdr_unsigned(int, *p); 1035 1036 /* Save the position so that we can do nfsm_mtouio() later */ 1037 dpos2 = dpos; 1038 md2 = md; 1039 1040 /* loop thru the dir entries, doctoring them to 4bsd form */ 1041 savoff = off = 0; 1042 savdp = dp = NULL; 1043 while (more_dirs && siz < uiop->uio_resid) { 1044 savoff = off; /* Hold onto offset and dp */ 1045 savdp = dp; 1046 nfsm_disecton(p, u_long *, 2*NFSX_UNSIGNED); 1047 dp = (struct direct *)p; 1048 dp->d_ino = fxdr_unsigned(u_long, *p++); 1049 len = fxdr_unsigned(int, *p); 1050 if (len <= 0 || len > NFS_MAXNAMLEN) { 1051 error = EBADRPC; 1052 m_freem(mrep); 1053 goto nfsmout; 1054 } 1055 dp->d_namlen = (u_short)len; 1056 len = nfsm_rndup(len); 1057 nfsm_adv(len); 1058 nfsm_disecton(p, u_long *, 2*NFSX_UNSIGNED); 1059 off = fxdr_unsigned(off_t, *p); 1060 *p++ = 0; /* Ensures null termination of name */ 1061 more_dirs = fxdr_unsigned(int, *p); 1062 dp->d_reclen = len+4*NFSX_UNSIGNED; 1063 siz += dp->d_reclen; 1064 } 1065 /* 1066 * If at end of rpc data, get the eof boolean 1067 */ 1068 if (!more_dirs) 1069 nfsm_disecton(p, u_long *, NFSX_UNSIGNED); 1070 /* 1071 * If there is too much to fit in the data buffer, use savoff and 1072 * savdp to trim off the last record. 1073 * --> we are not at eof 1074 */ 1075 if (siz > uiop->uio_resid) { 1076 off = savoff; 1077 siz -= dp->d_reclen; 1078 dp = savdp; 1079 } 1080 if (siz > 0) { 1081 md = md2; 1082 dpos = dpos2; 1083 nfsm_mtouio(uiop, siz); 1084 uiop->uio_offset = off; 1085 } 1086 nfsm_reqdone; 1087 return (error); 1088 } 1089 1090 /* 1091 * nfs statfs call 1092 * (Actually a vfsop, not a vnode op) 1093 */ 1094 nfs_statfs(mp, sbp) 1095 struct mount *mp; 1096 register struct statfs *sbp; 1097 { 1098 register struct vnode *vp; 1099 register struct nfsv2_statfs *sfp; 1100 register caddr_t cp; 1101 register long t1; 1102 caddr_t bpos, dpos, cp2; 1103 u_long xid; 1104 int error = 0; 1105 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1106 struct nfsmount *nmp; 1107 struct ucred *cred; 1108 struct nfsnode *np; 1109 1110 nmp = vfs_to_nfs(mp); 1111 if (error = nfs_nget(mp, &nmp->nm_fh, &np)) 1112 return (error); 1113 vp = NFSTOV(np); 1114 nfsstats.rpccnt[NFSPROC_STATFS]++; 1115 cred = crget(); 1116 cred->cr_ngroups = 1; 1117 nfsm_reqhead(nfs_procids[NFSPROC_STATFS], cred, NFSX_FH); 1118 nfsm_fhtom(vp); 1119 nfsm_request(vp); 1120 nfsm_disect(sfp, struct nfsv2_statfs *, NFSX_STATFS); 1121 sbp->f_type = MOUNT_NFS; 1122 sbp->f_flags = nmp->nm_flag; 1123 sbp->f_bsize = fxdr_unsigned(long, sfp->sf_tsize); 1124 sbp->f_fsize = fxdr_unsigned(long, sfp->sf_bsize); 1125 sbp->f_blocks = fxdr_unsigned(long, sfp->sf_blocks); 1126 sbp->f_bfree = fxdr_unsigned(long, sfp->sf_bfree); 1127 sbp->f_bavail = fxdr_unsigned(long, sfp->sf_bavail); 1128 sbp->f_files = 0; 1129 sbp->f_ffree = 0; 1130 sbp->f_fsid.val[0] = mp->m_fsid.val[0]; 1131 sbp->f_fsid.val[1] = mp->m_fsid.val[1]; 1132 bcopy(nmp->nm_path, sbp->f_mntonname, MNAMELEN); 1133 bcopy(nmp->nm_host, sbp->f_mntfromname, MNAMELEN); 1134 nfsm_reqdone; 1135 nfs_nput(vp); 1136 crfree(cred); 1137 return (error); 1138 } 1139 1140 static char hextoasc[] = "0123456789abcdef"; 1141 1142 /* 1143 * Silly rename. To make the NFS filesystem that is stateless look a little 1144 * more like the "ufs" a remove of an active vnode is translated to a rename 1145 * to a funny looking filename that is removed by nfs_inactive on the 1146 * nfsnode. There is the potential for another process on a different client 1147 * to create the same funny name between the nfs_lookitup() fails and the 1148 * nfs_rename() completes, but... 1149 */ 1150 nfs_sillyrename(ndp, flag) 1151 register struct nameidata *ndp; 1152 int flag; 1153 { 1154 register struct nfsnode *np; 1155 register struct sillyrename *sp; 1156 register struct nameidata *tndp; 1157 int error; 1158 short pid; 1159 1160 np = VTONFS(ndp->ni_dvp); 1161 cache_purge(ndp->ni_dvp); 1162 MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename), 1163 M_TEMP, M_WAITOK); 1164 sp->s_flag = flag; 1165 bcopy((caddr_t)&np->n_fh, (caddr_t)&sp->s_fh, NFSX_FH); 1166 np = VTONFS(ndp->ni_vp); 1167 tndp = &sp->s_namei; 1168 tndp->ni_cred = crdup(ndp->ni_cred); 1169 1170 /* Fudge together a funny name */ 1171 pid = u.u_procp->p_pid; 1172 bcopy(".nfsAxxxx4.4", tndp->ni_dent.d_name, 13); 1173 tndp->ni_dent.d_namlen = 12; 1174 tndp->ni_dent.d_name[8] = hextoasc[pid & 0xf]; 1175 tndp->ni_dent.d_name[7] = hextoasc[(pid >> 4) & 0xf]; 1176 tndp->ni_dent.d_name[6] = hextoasc[(pid >> 8) & 0xf]; 1177 tndp->ni_dent.d_name[5] = hextoasc[(pid >> 12) & 0xf]; 1178 1179 /* Try lookitups until we get one that isn't there */ 1180 while (nfs_lookitup(ndp->ni_dvp, tndp, (nfsv2fh_t *)0) == 0) { 1181 tndp->ni_dent.d_name[4]++; 1182 if (tndp->ni_dent.d_name[4] > 'z') { 1183 error = EINVAL; 1184 goto bad; 1185 } 1186 } 1187 if (error = nfs_renameit(ndp, tndp)) 1188 goto bad; 1189 nfs_lookitup(ndp->ni_dvp, tndp, &np->n_fh); 1190 np->n_sillyrename = sp; 1191 return (0); 1192 bad: 1193 crfree(tndp->ni_cred); 1194 free((caddr_t)sp, M_TEMP); 1195 return (error); 1196 } 1197 1198 /* 1199 * Look up a file name for silly rename stuff. 1200 * Just like nfs_lookup() except that it doesn't load returned values 1201 * into the nfsnode table. 1202 * If fhp != NULL it copies the returned file handle out 1203 */ 1204 nfs_lookitup(vp, ndp, fhp) 1205 register struct vnode *vp; 1206 register struct nameidata *ndp; 1207 nfsv2fh_t *fhp; 1208 { 1209 register u_long *p; 1210 register caddr_t cp; 1211 register long t1, t2; 1212 caddr_t bpos, dpos, cp2; 1213 u_long xid; 1214 int error = 0; 1215 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1216 long len; 1217 1218 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 1219 ndp->ni_dvp = vp; 1220 ndp->ni_vp = NULL; 1221 len = ndp->ni_dent.d_namlen; 1222 nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], ndp->ni_cred, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)); 1223 nfsm_fhtom(vp); 1224 nfsm_strtom(ndp->ni_dent.d_name, len, NFS_MAXNAMLEN); 1225 nfsm_request(vp); 1226 if (fhp != NULL) { 1227 nfsm_disect(cp, caddr_t, NFSX_FH); 1228 bcopy(cp, (caddr_t)fhp, NFSX_FH); 1229 } 1230 nfsm_reqdone; 1231 return (error); 1232 } 1233 1234 /* 1235 * Kludge City.. 1236 * - make nfs_bmap() essentially a no-op that does no translation 1237 * - do nfs_strategy() by faking physical I/O with nfs_readit/nfs_writeit 1238 * after mapping the physical addresses into Kernel Virtual space in the 1239 * nfsiobuf area. 1240 * (Maybe I could use the process's page mapping, but I was concerned that 1241 * Kernel Write might not be enabled and also figured copyout() would do 1242 * a lot more work than bcopy() and also it currently happens in the 1243 * context of the swapper process (2). 1244 */ 1245 nfs_bmap(vp, bn, vpp, bnp) 1246 struct vnode *vp; 1247 daddr_t bn; 1248 struct vnode **vpp; 1249 daddr_t *bnp; 1250 { 1251 if (vpp != NULL) 1252 *vpp = vp; 1253 if (bnp != NULL) 1254 *bnp = bn * btodb(vp->v_mount->m_bsize); 1255 return (0); 1256 } 1257 1258 /* 1259 * Strategy routine for phys. i/o 1260 * If the biod's are running, queue a request 1261 * otherwise just call nfs_doio() to get it done 1262 */ 1263 nfs_strategy(bp) 1264 register struct buf *bp; 1265 { 1266 register struct buf *dp; 1267 register int i; 1268 struct proc *rp; 1269 int error = 0; 1270 int fnd = 0; 1271 1272 /* 1273 * If an i/o daemon is waiting 1274 * queue the request, wake it up and wait for completion 1275 * otherwise just do it ourselves 1276 */ 1277 for (i = 0; i < nfs_asyncdaemons; i++) { 1278 if (rp = nfs_iodwant[i]) { 1279 /* 1280 * Ensure that the async_daemon is still waiting here 1281 */ 1282 if (rp->p_stat != SSLEEP || 1283 rp->p_wchan != ((caddr_t)&nfs_iodwant[i])) { 1284 nfs_iodwant[i] = (struct proc *)0; 1285 continue; 1286 } 1287 dp = &nfs_bqueue; 1288 if (dp->b_actf == NULL) { 1289 dp->b_actl = bp; 1290 bp->b_actf = dp; 1291 } else { 1292 dp->b_actf->b_actl = bp; 1293 bp->b_actf = dp->b_actf; 1294 } 1295 dp->b_actf = bp; 1296 bp->b_actl = dp; 1297 fnd++; 1298 nfs_iodwant[i] = (struct proc *)0; 1299 wakeup((caddr_t)&nfs_iodwant[i]); 1300 break; 1301 } 1302 } 1303 if (!fnd) 1304 error = nfs_doio(bp); 1305 return (error); 1306 } 1307 1308 /* 1309 * Fun and games with i/o 1310 * Essentially play ubasetup() and disk interrupt service routine by 1311 * mapping the data buffer into kernel virtual space and doing the 1312 * nfs read or write rpc's from it. 1313 * If the biod's are not running, this is just called from nfs_strategy(), 1314 * otherwise it is called by the biod's to do what would normally be 1315 * partially disk interrupt driven. 1316 */ 1317 nfs_doio(bp) 1318 register struct buf *bp; 1319 { 1320 register struct pte *pte, *ppte; 1321 register caddr_t vaddr; 1322 register struct uio *uiop; 1323 register struct vnode *vp; 1324 struct nfsnode *np; 1325 struct ucred *cr; 1326 int npf, npf2; 1327 int reg; 1328 caddr_t vbase; 1329 unsigned v; 1330 struct proc *rp; 1331 int o, error; 1332 struct uio uio; 1333 struct iovec io; 1334 1335 vp = bp->b_vp; 1336 uiop = &uio; 1337 uiop->uio_iov = &io; 1338 uiop->uio_iovcnt = 1; 1339 uiop->uio_segflg = UIO_SYSSPACE; 1340 1341 /* 1342 * For phys i/o, map the b_addr into kernel virtual space using 1343 * the Nfsiomap pte's 1344 * Also, add a temporary b_rcred for reading using the process's uid 1345 * and a guess at a group 1346 */ 1347 if (bp->b_flags & B_PHYS) { 1348 VTONFS(vp)->n_flag |= NPAGEDON; 1349 bp->b_rcred = cr = crget(); 1350 rp = (bp->b_flags & B_DIRTY) ? &proc[2] : bp->b_proc; 1351 cr->cr_uid = rp->p_uid; 1352 cr->cr_gid = 0; /* Anything ?? */ 1353 cr->cr_ngroups = 1; 1354 o = (int)bp->b_un.b_addr & PGOFSET; 1355 npf2 = npf = btoc(bp->b_bcount + o); 1356 1357 /* 1358 * Get some mapping page table entries 1359 */ 1360 while ((reg = rmalloc(nfsmap, (long)npf)) == 0) { 1361 nfsmap_want++; 1362 sleep((caddr_t)&nfsmap_want, PZERO-1); 1363 } 1364 reg--; 1365 if (bp->b_flags & B_PAGET) 1366 pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; 1367 else { 1368 v = btop(bp->b_un.b_addr); 1369 if (bp->b_flags & B_UAREA) 1370 pte = &rp->p_addr[v]; 1371 else 1372 pte = vtopte(rp, v); 1373 } 1374 1375 /* 1376 * Play vmaccess() but with the Nfsiomap page table 1377 */ 1378 ppte = &Nfsiomap[reg]; 1379 vbase = vaddr = &nfsiobuf[reg*NBPG]; 1380 while (npf != 0) { 1381 mapin(ppte, (u_int)vaddr, pte->pg_pfnum, (int)(PG_V|PG_KW)); 1382 #if defined(tahoe) 1383 mtpr(P1DC, vaddr); 1384 #endif 1385 ppte++; 1386 pte++; 1387 vaddr += NBPG; 1388 --npf; 1389 } 1390 1391 /* 1392 * And do the i/o rpc 1393 */ 1394 io.iov_base = vbase+o; 1395 io.iov_len = uiop->uio_resid = bp->b_bcount; 1396 uiop->uio_offset = bp->b_blkno * DEV_BSIZE; 1397 if (bp->b_flags & B_READ) { 1398 uiop->uio_rw = UIO_READ; 1399 nfsstats.read_physios++; 1400 bp->b_error = error = nfs_readrpc(vp, uiop, bp->b_rcred); 1401 } else { 1402 uiop->uio_rw = UIO_WRITE; 1403 nfsstats.write_physios++; 1404 bp->b_error = error = nfs_writerpc(vp, uiop, bp->b_wcred); 1405 } 1406 1407 /* 1408 * Finally, release pte's used by physical i/o 1409 */ 1410 crfree(cr); 1411 rmfree(nfsmap, (long)npf2, (long)++reg); 1412 if (nfsmap_want) { 1413 nfsmap_want = 0; 1414 wakeup((caddr_t)&nfsmap_want); 1415 } 1416 } else { 1417 if (bp->b_flags & B_READ) { 1418 io.iov_len = uiop->uio_resid = bp->b_bcount; 1419 uiop->uio_offset = bp->b_blkno * DEV_BSIZE; 1420 io.iov_base = bp->b_un.b_addr; 1421 uiop->uio_rw = UIO_READ; 1422 nfsstats.read_bios++; 1423 bp->b_error = error = nfs_readrpc(vp, uiop, bp->b_rcred); 1424 } else { 1425 io.iov_len = uiop->uio_resid = bp->b_dirtyend 1426 - bp->b_dirtyoff; 1427 uiop->uio_offset = (bp->b_blkno * DEV_BSIZE) 1428 + bp->b_dirtyoff; 1429 io.iov_base = bp->b_un.b_addr + bp->b_dirtyoff; 1430 uiop->uio_rw = UIO_WRITE; 1431 nfsstats.write_bios++; 1432 bp->b_error = error = nfs_writerpc(vp, uiop, bp->b_wcred); 1433 if (error) { 1434 np = VTONFS(vp); 1435 np->n_error = error; 1436 np->n_flag |= NWRITEERR; 1437 } 1438 bp->b_dirtyoff = bp->b_dirtyend = 0; 1439 } 1440 } 1441 if (error) 1442 bp->b_flags |= B_ERROR; 1443 bp->b_resid = uiop->uio_resid; 1444 biodone(bp); 1445 return (error); 1446 } 1447 1448 /* 1449 * Flush all the blocks associated with a vnode. 1450 * Walk through the buffer pool and push any dirty pages 1451 * associated with the vnode. 1452 */ 1453 /* ARGSUSED */ 1454 nfs_fsync(vp, fflags, cred, waitfor) 1455 register struct vnode *vp; 1456 int fflags; 1457 struct ucred *cred; 1458 int waitfor; 1459 { 1460 register struct nfsnode *np = VTONFS(vp); 1461 int error = 0; 1462 1463 if (np->n_flag & NMODIFIED) { 1464 np->n_flag &= ~NMODIFIED; 1465 vflushbuf(vp, waitfor == MNT_WAIT ? B_SYNC : 0); 1466 } 1467 if (!error && (np->n_flag & NWRITEERR)) 1468 error = np->n_error; 1469 return (error); 1470 } 1471 1472 /* 1473 * Print out the contents of an nfsnode. 1474 */ 1475 nfs_print(vp) 1476 struct vnode *vp; 1477 { 1478 register struct nfsnode *np = VTONFS(vp); 1479 1480 printf("tag VT_NFS, fileid %d fsid 0x%x%s\n", 1481 np->n_vattr.va_fileid, np->n_vattr.va_fsid, 1482 (np->n_flag & NLOCKED) ? " (LOCKED)" : ""); 1483 if (np->n_lockholder == 0) 1484 return; 1485 printf("\towner pid %d", np->n_lockholder); 1486 if (np->n_lockwaiter) 1487 printf(" waiting pid %d", np->n_lockwaiter); 1488 printf("\n"); 1489 } 1490