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.83 (Berkeley) 06/19/92 11 */ 12 13 /* 14 * vnode op calls for sun nfs version 2 15 */ 16 17 #include <sys/param.h> 18 #include <sys/proc.h> 19 #include <sys/kernel.h> 20 #include <sys/systm.h> 21 #include <sys/mount.h> 22 #include <sys/buf.h> 23 #include <sys/malloc.h> 24 #include <sys/mbuf.h> 25 #include <sys/conf.h> 26 #include <sys/namei.h> 27 #include <sys/vnode.h> 28 #include <sys/specdev.h> 29 #include <sys/fifo.h> 30 #include <sys/map.h> 31 32 #include <vm/vm.h> 33 34 #include <nfs/rpcv2.h> 35 #include <nfs/nfsv2.h> 36 #include <nfs/nfs.h> 37 #include <nfs/nfsnode.h> 38 #include <nfs/nfsmount.h> 39 #include <nfs/xdr_subs.h> 40 #include <nfs/nfsm_subs.h> 41 #include <nfs/nqnfs.h> 42 43 /* Defs */ 44 #define TRUE 1 45 #define FALSE 0 46 47 /* 48 * Global vfs data structures for nfs 49 */ 50 int (**nfsv2_vnodeop_p)(); 51 struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = { 52 { &vop_default_desc, vn_default_error }, 53 { &vop_lookup_desc, nfs_lookup }, /* lookup */ 54 { &vop_create_desc, nfs_create }, /* create */ 55 { &vop_mknod_desc, nfs_mknod }, /* mknod */ 56 { &vop_open_desc, nfs_open }, /* open */ 57 { &vop_close_desc, nfs_close }, /* close */ 58 { &vop_access_desc, nfs_access }, /* access */ 59 { &vop_getattr_desc, nfs_getattr }, /* getattr */ 60 { &vop_setattr_desc, nfs_setattr }, /* setattr */ 61 { &vop_read_desc, nfs_read }, /* read */ 62 { &vop_write_desc, nfs_write }, /* write */ 63 { &vop_ioctl_desc, nfs_ioctl }, /* ioctl */ 64 { &vop_select_desc, nfs_select }, /* select */ 65 { &vop_mmap_desc, nfs_mmap }, /* mmap */ 66 { &vop_fsync_desc, nfs_fsync }, /* fsync */ 67 { &vop_seek_desc, nfs_seek }, /* seek */ 68 { &vop_remove_desc, nfs_remove }, /* remove */ 69 { &vop_link_desc, nfs_link }, /* link */ 70 { &vop_rename_desc, nfs_rename }, /* rename */ 71 { &vop_mkdir_desc, nfs_mkdir }, /* mkdir */ 72 { &vop_rmdir_desc, nfs_rmdir }, /* rmdir */ 73 { &vop_symlink_desc, nfs_symlink }, /* symlink */ 74 { &vop_readdir_desc, nfs_readdir }, /* readdir */ 75 { &vop_readlink_desc, nfs_readlink }, /* readlink */ 76 { &vop_abortop_desc, nfs_abortop }, /* abortop */ 77 { &vop_inactive_desc, nfs_inactive }, /* inactive */ 78 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */ 79 { &vop_lock_desc, nfs_lock }, /* lock */ 80 { &vop_unlock_desc, nfs_unlock }, /* unlock */ 81 { &vop_bmap_desc, nfs_bmap }, /* bmap */ 82 { &vop_strategy_desc, nfs_strategy }, /* strategy */ 83 { &vop_print_desc, nfs_print }, /* print */ 84 { &vop_islocked_desc, nfs_islocked }, /* islocked */ 85 { &vop_advlock_desc, nfs_advlock }, /* advlock */ 86 { &vop_blkatoff_desc, nfs_blkatoff }, /* blkatoff */ 87 { &vop_vget_desc, nfs_vget }, /* vget */ 88 { &vop_valloc_desc, nfs_valloc }, /* valloc */ 89 { &vop_vfree_desc, nfs_vfree }, /* vfree */ 90 { &vop_truncate_desc, nfs_truncate }, /* truncate */ 91 { &vop_update_desc, nfs_update }, /* update */ 92 { &vop_bwrite_desc, vn_bwrite }, 93 { (struct vnodeop_desc*)NULL, (int(*)())NULL } 94 }; 95 struct vnodeopv_desc nfsv2_vnodeop_opv_desc = 96 { &nfsv2_vnodeop_p, nfsv2_vnodeop_entries }; 97 98 /* 99 * Special device vnode ops 100 */ 101 int (**spec_nfsv2nodeop_p)(); 102 struct vnodeopv_entry_desc spec_nfsv2nodeop_entries[] = { 103 { &vop_default_desc, vn_default_error }, 104 { &vop_lookup_desc, spec_lookup }, /* lookup */ 105 { &vop_create_desc, spec_create }, /* create */ 106 { &vop_mknod_desc, spec_mknod }, /* mknod */ 107 { &vop_open_desc, spec_open }, /* open */ 108 { &vop_close_desc, nfsspec_close }, /* close */ 109 { &vop_access_desc, nfs_access }, /* access */ 110 { &vop_getattr_desc, nfs_getattr }, /* getattr */ 111 { &vop_setattr_desc, nfs_setattr }, /* setattr */ 112 { &vop_read_desc, nfsspec_read }, /* read */ 113 { &vop_write_desc, nfsspec_write }, /* write */ 114 { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 115 { &vop_select_desc, spec_select }, /* select */ 116 { &vop_mmap_desc, spec_mmap }, /* mmap */ 117 { &vop_fsync_desc, spec_fsync }, /* fsync */ 118 { &vop_seek_desc, spec_seek }, /* seek */ 119 { &vop_remove_desc, spec_remove }, /* remove */ 120 { &vop_link_desc, spec_link }, /* link */ 121 { &vop_rename_desc, spec_rename }, /* rename */ 122 { &vop_mkdir_desc, spec_mkdir }, /* mkdir */ 123 { &vop_rmdir_desc, spec_rmdir }, /* rmdir */ 124 { &vop_symlink_desc, spec_symlink }, /* symlink */ 125 { &vop_readdir_desc, spec_readdir }, /* readdir */ 126 { &vop_readlink_desc, spec_readlink }, /* readlink */ 127 { &vop_abortop_desc, spec_abortop }, /* abortop */ 128 { &vop_inactive_desc, nfs_inactive }, /* inactive */ 129 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */ 130 { &vop_lock_desc, nfs_lock }, /* lock */ 131 { &vop_unlock_desc, nfs_unlock }, /* unlock */ 132 { &vop_bmap_desc, spec_bmap }, /* bmap */ 133 { &vop_strategy_desc, spec_strategy }, /* strategy */ 134 { &vop_print_desc, nfs_print }, /* print */ 135 { &vop_islocked_desc, nfs_islocked }, /* islocked */ 136 { &vop_advlock_desc, spec_advlock }, /* advlock */ 137 { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ 138 { &vop_vget_desc, spec_vget }, /* vget */ 139 { &vop_valloc_desc, spec_valloc }, /* valloc */ 140 { &vop_vfree_desc, spec_vfree }, /* vfree */ 141 { &vop_truncate_desc, spec_truncate }, /* truncate */ 142 { &vop_update_desc, nfs_update }, /* update */ 143 { &vop_bwrite_desc, vn_bwrite }, 144 { (struct vnodeop_desc*)NULL, (int(*)())NULL } 145 }; 146 struct vnodeopv_desc spec_nfsv2nodeop_opv_desc = 147 { &spec_nfsv2nodeop_p, spec_nfsv2nodeop_entries }; 148 149 #ifdef FIFO 150 int (**fifo_nfsv2nodeop_p)(); 151 struct vnodeopv_entry_desc fifo_nfsv2nodeop_entries[] = { 152 { &vop_default_desc, vn_default_error }, 153 { &vop_lookup_desc, fifo_lookup }, /* lookup */ 154 { &vop_create_desc, fifo_create }, /* create */ 155 { &vop_mknod_desc, fifo_mknod }, /* mknod */ 156 { &vop_open_desc, fifo_open }, /* open */ 157 { &vop_close_desc, nfsfifo_close }, /* close */ 158 { &vop_access_desc, nfs_access }, /* access */ 159 { &vop_getattr_desc, nfs_getattr }, /* getattr */ 160 { &vop_setattr_desc, nfs_setattr }, /* setattr */ 161 { &vop_read_desc, nfsfifo_read }, /* read */ 162 { &vop_write_desc, nfsfifo_write }, /* write */ 163 { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ 164 { &vop_select_desc, fifo_select }, /* select */ 165 { &vop_mmap_desc, fifo_mmap }, /* mmap */ 166 { &vop_fsync_desc, fifo_fsync }, /* fsync */ 167 { &vop_seek_desc, fifo_seek }, /* seek */ 168 { &vop_remove_desc, fifo_remove }, /* remove */ 169 { &vop_link_desc, fifo_link }, /* link */ 170 { &vop_rename_desc, fifo_rename }, /* rename */ 171 { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */ 172 { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */ 173 { &vop_symlink_desc, fifo_symlink }, /* symlink */ 174 { &vop_readdir_desc, fifo_readdir }, /* readdir */ 175 { &vop_readlink_desc, fifo_readlink }, /* readlink */ 176 { &vop_abortop_desc, fifo_abortop }, /* abortop */ 177 { &vop_inactive_desc, nfs_inactive }, /* inactive */ 178 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */ 179 { &vop_lock_desc, nfs_lock }, /* lock */ 180 { &vop_unlock_desc, nfs_unlock }, /* unlock */ 181 { &vop_bmap_desc, fifo_bmap }, /* bmap */ 182 { &vop_strategy_desc, fifo_badop }, /* strategy */ 183 { &vop_print_desc, nfs_print }, /* print */ 184 { &vop_islocked_desc, nfs_islocked }, /* islocked */ 185 { &vop_advlock_desc, fifo_advlock }, /* advlock */ 186 { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ 187 { &vop_vget_desc, fifo_vget }, /* vget */ 188 { &vop_valloc_desc, fifo_valloc }, /* valloc */ 189 { &vop_vfree_desc, fifo_vfree }, /* vfree */ 190 { &vop_truncate_desc, fifo_truncate }, /* truncate */ 191 { &vop_update_desc, nfs_update }, /* update */ 192 { &vop_bwrite_desc, vn_bwrite }, 193 { (struct vnodeop_desc*)NULL, (int(*)())NULL } 194 }; 195 struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc = 196 { &fifo_nfsv2nodeop_p, fifo_nfsv2nodeop_entries }; 197 #endif /* FIFO */ 198 199 /* 200 * Global variables 201 */ 202 extern u_long nfs_procids[NFS_NPROCS]; 203 extern u_long nfs_prog, nfs_vers; 204 extern char nfsiobuf[MAXPHYS+NBPG]; 205 struct buf nfs_bqueue; /* Queue head for nfsiod's */ 206 struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; 207 int nfs_numasync = 0; 208 #define DIRHDSIZ (sizeof (struct readdir) - (MAXNAMLEN + 1)) 209 210 /* 211 * nfs null call from vfs. 212 */ 213 int 214 nfs_null(vp, cred, procp) 215 struct vnode *vp; 216 struct ucred *cred; 217 struct proc *procp; 218 { 219 caddr_t bpos, dpos; 220 int error = 0; 221 struct mbuf *mreq, *mrep, *md, *mb; 222 223 nfsm_reqhead(vp, NFSPROC_NULL, 0); 224 nfsm_request(vp, NFSPROC_NULL, procp, cred); 225 nfsm_reqdone; 226 return (error); 227 } 228 229 /* 230 * nfs access vnode op. 231 * Essentially just get vattr and then imitate iaccess() 232 */ 233 int 234 nfs_access(ap) 235 struct vop_access_args *ap; 236 { 237 USES_VOP_GETATTR; 238 register struct vattr *vap; 239 register gid_t *gp; 240 register struct ucred *cred = ap->a_cred; 241 mode_t mode = ap->a_mode; 242 struct vattr vattr; 243 register int i; 244 int error; 245 246 /* 247 * If you're the super-user, 248 * you always get access. 249 */ 250 if (cred->cr_uid == 0) 251 return (0); 252 vap = &vattr; 253 if (error = VOP_GETATTR(ap->a_vp, vap, cred, ap->a_p)) 254 return (error); 255 /* 256 * Access check is based on only one of owner, group, public. 257 * If not owner, then check group. If not a member of the 258 * group, then check public access. 259 */ 260 if (cred->cr_uid != vap->va_uid) { 261 mode >>= 3; 262 gp = cred->cr_groups; 263 for (i = 0; i < cred->cr_ngroups; i++, gp++) 264 if (vap->va_gid == *gp) 265 goto found; 266 mode >>= 3; 267 found: 268 ; 269 } 270 if ((vap->va_mode & mode) != 0) 271 return (0); 272 return (EACCES); 273 } 274 275 /* 276 * nfs open vnode op 277 * Just check to see if the type is ok 278 * and that deletion is not in progress. 279 */ 280 /* ARGSUSED */ 281 int 282 nfs_open(ap) 283 struct vop_open_args *ap; 284 { 285 register struct vnode *vp = ap->a_vp; 286 287 if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) 288 return (EACCES); 289 if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) == 0) 290 VTONFS(vp)->n_attrstamp = 0; /* For Open/Close consistency */ 291 return (0); 292 } 293 294 /* 295 * nfs close vnode op 296 * For reg files, invalidate any buffer cache entries. 297 */ 298 /* ARGSUSED */ 299 int 300 nfs_close(ap) 301 struct vop_close_args *ap; 302 { 303 register struct vnode *vp = ap->a_vp; 304 register struct nfsnode *np = VTONFS(vp); 305 int error = 0; 306 307 if (vp->v_type == VREG) { 308 if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) == 0 && 309 (np->n_flag & NMODIFIED)) { 310 np->n_flag &= ~NMODIFIED; 311 vinvalbuf(vp, TRUE); 312 np->n_attrstamp = 0; 313 } 314 if (np->n_flag & NWRITEERR) { 315 np->n_flag &= ~NWRITEERR; 316 error = np->n_error; 317 } 318 } 319 return (error); 320 } 321 322 /* 323 * nfs getattr call from vfs. 324 */ 325 int 326 nfs_getattr(ap) 327 struct vop_getattr_args *ap; 328 { 329 register struct vnode *vp = ap->a_vp; 330 register struct nfsnode *np = VTONFS(vp); 331 register caddr_t cp; 332 caddr_t bpos, dpos; 333 int error = 0; 334 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 335 336 /* 337 * Update local times for special files. 338 */ 339 if (np->n_flag & (NACC | NUPD)) { 340 if (np->n_flag & NACC) 341 np->n_atim = time; 342 if (np->n_flag & NUPD) 343 np->n_mtim = time; 344 np->n_flag |= NCHG; 345 } 346 /* 347 * First look in the cache. 348 */ 349 if (nfs_getattrcache(vp, ap->a_vap) == 0) 350 return (0); 351 nfsstats.rpccnt[NFSPROC_GETATTR]++; 352 nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH); 353 nfsm_fhtom(vp); 354 nfsm_request(vp, NFSPROC_GETATTR, ap->a_p, ap->a_cred); 355 nfsm_loadattr(vp, ap->a_vap); 356 nfsm_reqdone; 357 return (error); 358 } 359 360 /* 361 * nfs setattr call. 362 */ 363 int 364 nfs_setattr(ap) 365 struct vop_setattr_args *ap; 366 { 367 register struct nfsv2_sattr *sp; 368 register caddr_t cp; 369 register long t1; 370 caddr_t bpos, dpos, cp2; 371 u_long *tl; 372 int error = 0; 373 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 374 register struct vnode *vp = ap->a_vp; 375 register struct nfsnode *np = VTONFS(vp); 376 register struct vattr *vap = ap->a_vap; 377 u_quad_t frev; 378 379 nfsstats.rpccnt[NFSPROC_SETATTR]++; 380 nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH+NFSX_SATTR); 381 nfsm_fhtom(vp); 382 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 383 if (vap->va_mode == 0xffff) 384 sp->sa_mode = VNOVAL; 385 else 386 sp->sa_mode = vtonfs_mode(vp->v_type, vap->va_mode); 387 if (vap->va_uid == 0xffff) 388 sp->sa_uid = VNOVAL; 389 else 390 sp->sa_uid = txdr_unsigned(vap->va_uid); 391 if (vap->va_gid == 0xffff) 392 sp->sa_gid = VNOVAL; 393 else 394 sp->sa_gid = txdr_unsigned(vap->va_gid); 395 sp->sa_size = txdr_unsigned(vap->va_size); 396 sp->sa_atime.tv_sec = txdr_unsigned(vap->va_atime.ts_sec); 397 sp->sa_atime.tv_usec = txdr_unsigned(vap->va_flags); 398 txdr_time(&vap->va_mtime, &sp->sa_mtime); 399 if (vap->va_size != VNOVAL || vap->va_mtime.ts_sec != VNOVAL || 400 vap->va_atime.ts_sec != VNOVAL) { 401 if (np->n_flag & NMODIFIED) { 402 np->n_flag &= ~NMODIFIED; 403 if (vap->va_size == 0) 404 vinvalbuf(vp, FALSE); 405 else 406 vinvalbuf(vp, TRUE); 407 } 408 } 409 nfsm_request(vp, NFSPROC_SETATTR, ap->a_p, ap->a_cred); 410 nfsm_loadattr(vp, (struct vattr *)0); 411 if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) && 412 NQNFS_CKCACHABLE(vp, NQL_WRITE)) { 413 nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); 414 fxdr_hyper(tl, &frev); 415 if (QUADGT(frev, np->n_brev)) 416 np->n_brev = frev; 417 } 418 nfsm_reqdone; 419 return (error); 420 } 421 422 /* 423 * nfs lookup call, one step at a time... 424 * First look in cache 425 * If not found, unlock the directory nfsnode and do the rpc 426 */ 427 int 428 nfs_lookup(ap) 429 struct vop_lookup_args *ap; 430 { 431 USES_VOP_GETATTR; 432 register struct componentname *cnp = ap->a_cnp; 433 register struct vnode *dvp = ap->a_dvp; 434 register struct vnode *vdp; 435 register u_long *tl; 436 register caddr_t cp; 437 register long t1, t2; 438 struct nfsmount *nmp; 439 struct nfsnode *tp; 440 caddr_t bpos, dpos, cp2; 441 time_t reqtime; 442 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 443 struct vnode *newvp; 444 long len; 445 nfsv2fh_t *fhp; 446 struct nfsnode *np; 447 int lockparent, wantparent, error = 0; 448 int nqlflag, cachable; 449 u_quad_t frev; 450 451 *ap->a_vpp = NULL; 452 if (dvp->v_type != VDIR) 453 return (ENOTDIR); 454 lockparent = cnp->cn_flags & LOCKPARENT; 455 wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT); 456 nmp = VFSTONFS(dvp->v_mount); 457 np = VTONFS(dvp); 458 if ((error = cache_lookup(dvp, ap->a_vpp, cnp)) && error != ENOENT) { 459 struct vattr vattr; 460 int vpid; 461 462 vdp = *ap->a_vpp; 463 vpid = vdp->v_id; 464 /* 465 * See the comment starting `Step through' in ufs/ufs_lookup.c 466 * for an explanation of the locking protocol 467 */ 468 if (dvp == vdp) { 469 VREF(vdp); 470 error = 0; 471 } else 472 error = vget(vdp); 473 if (!error) { 474 if (vpid == vdp->v_id) { 475 if (nmp->nm_flag & NFSMNT_NQNFS) { 476 if (NQNFS_CKCACHABLE(dvp, NQL_READ)) { 477 if (QUADNE(np->n_lrev, np->n_brev) || 478 (np->n_flag & NMODIFIED)) { 479 np->n_direofoffset = 0; 480 cache_purge(dvp); 481 np->n_flag &= ~NMODIFIED; 482 vinvalbuf(dvp, FALSE); 483 np->n_brev = np->n_lrev; 484 } else { 485 nfsstats.lookupcache_hits++; 486 if (cnp->cn_nameiop != LOOKUP && 487 (cnp->cn_flags&ISLASTCN)) 488 cnp->cn_flags |= SAVENAME; 489 return (0); 490 } 491 } 492 } else if (!VOP_GETATTR(vdp, &vattr, cnp->cn_cred, cnp->cn_proc) && 493 vattr.va_ctime.ts_sec == VTONFS(vdp)->n_ctime) { 494 nfsstats.lookupcache_hits++; 495 if (cnp->cn_nameiop != LOOKUP && 496 (cnp->cn_flags&ISLASTCN)) 497 cnp->cn_flags |= SAVENAME; 498 return (0); 499 } 500 cache_purge(vdp); 501 } 502 vrele(vdp); 503 } 504 *ap->a_vpp = NULLVP; 505 } 506 error = 0; 507 nfsstats.lookupcache_misses++; 508 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 509 len = cnp->cn_namelen; 510 nfsm_reqhead(dvp, NFSPROC_LOOKUP, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)); 511 512 /* 513 * For nqnfs optionally piggyback a getlease request for the name 514 * being looked up. 515 */ 516 if (nmp->nm_flag & NFSMNT_NQNFS) { 517 if ((nmp->nm_flag & NFSMNT_NQLOOKLEASE) && 518 ((cnp->cn_flags&MAKEENTRY) && 519 (cnp->cn_nameiop != DELETE || !(cnp->cn_flags&ISLASTCN)))) { 520 nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED); 521 *tl++ = txdr_unsigned(NQL_READ); 522 *tl = txdr_unsigned(nmp->nm_leaseterm); 523 } else { 524 nfsm_build(tl, u_long *, NFSX_UNSIGNED); 525 *tl = 0; 526 } 527 } 528 nfsm_fhtom(dvp); 529 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 530 reqtime = time.tv_sec; 531 nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_proc, cnp->cn_cred); 532 nfsmout: 533 if (error) { 534 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && 535 (cnp->cn_flags & ISLASTCN) && error == ENOENT) 536 error = EJUSTRETURN; 537 if (cnp->cn_nameiop != LOOKUP && (cnp->cn_flags&ISLASTCN)) 538 cnp->cn_flags |= SAVENAME; 539 return (error); 540 } 541 if (nmp->nm_flag & NFSMNT_NQNFS) { 542 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); 543 if (*tl) { 544 nqlflag = fxdr_unsigned(int, *tl); 545 nfsm_dissect(tl, u_long *, 4*NFSX_UNSIGNED); 546 cachable = fxdr_unsigned(int, *tl++); 547 reqtime += fxdr_unsigned(int, *tl++); 548 fxdr_hyper(tl, &frev); 549 } else 550 nqlflag = 0; 551 } 552 nfsm_dissect(fhp, nfsv2fh_t *, NFSX_FH); 553 554 /* 555 * Handle RENAME case... 556 */ 557 if (cnp->cn_nameiop == RENAME && wantparent && (cnp->cn_flags&ISLASTCN)) { 558 if (!bcmp(np->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) { 559 m_freem(mrep); 560 return (EISDIR); 561 } 562 if (error = nfs_nget(dvp->v_mount, fhp, &np)) { 563 m_freem(mrep); 564 return (error); 565 } 566 newvp = NFSTOV(np); 567 if (error = 568 nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) { 569 vrele(newvp); 570 m_freem(mrep); 571 return (error); 572 } 573 *ap->a_vpp = newvp; 574 m_freem(mrep); 575 cnp->cn_flags |= SAVENAME; 576 return (0); 577 } 578 579 if (!bcmp(np->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) { 580 VREF(dvp); 581 newvp = dvp; 582 } else { 583 if (error = nfs_nget(dvp->v_mount, fhp, &np)) { 584 m_freem(mrep); 585 return (error); 586 } 587 newvp = NFSTOV(np); 588 } 589 if (error = nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0)) { 590 vrele(newvp); 591 m_freem(mrep); 592 return (error); 593 } 594 m_freem(mrep); 595 *ap->a_vpp = newvp; 596 if (cnp->cn_nameiop != LOOKUP && (cnp->cn_flags&ISLASTCN)) 597 cnp->cn_flags |= SAVENAME; 598 if ((cnp->cn_flags&MAKEENTRY) && 599 (cnp->cn_nameiop != DELETE || !(cnp->cn_flags&ISLASTCN))) { 600 if ((nmp->nm_flag & NFSMNT_NQNFS) == 0) 601 np->n_ctime = np->n_vattr.va_ctime.ts_sec; 602 else if (nqlflag && reqtime > time.tv_sec) { 603 if (np->n_tnext) { 604 if (np->n_tnext == (struct nfsnode *)nmp) 605 nmp->nm_tprev = np->n_tprev; 606 else 607 np->n_tnext->n_tprev = np->n_tprev; 608 if (np->n_tprev == (struct nfsnode *)nmp) 609 nmp->nm_tnext = np->n_tnext; 610 else 611 np->n_tprev->n_tnext = np->n_tnext; 612 if (nqlflag == NQL_WRITE) 613 np->n_flag |= NQNFSWRITE; 614 } else if (nqlflag == NQL_READ) 615 np->n_flag &= ~NQNFSWRITE; 616 else 617 np->n_flag |= NQNFSWRITE; 618 if (cachable) 619 np->n_flag &= ~NQNFSNONCACHE; 620 else 621 np->n_flag |= NQNFSNONCACHE; 622 np->n_expiry = reqtime; 623 np->n_lrev = frev; 624 tp = nmp->nm_tprev; 625 while (tp != (struct nfsnode *)nmp && tp->n_expiry > np->n_expiry) 626 tp = tp->n_tprev; 627 if (tp == (struct nfsnode *)nmp) { 628 np->n_tnext = nmp->nm_tnext; 629 nmp->nm_tnext = np; 630 } else { 631 np->n_tnext = tp->n_tnext; 632 tp->n_tnext = np; 633 } 634 np->n_tprev = tp; 635 if (np->n_tnext == (struct nfsnode *)nmp) 636 nmp->nm_tprev = np; 637 else 638 np->n_tnext->n_tprev = np; 639 } 640 cache_enter(dvp, *ap->a_vpp, cnp); 641 } 642 return (0); 643 } 644 645 /* 646 * nfs read call. 647 * Just call nfs_bioread() to do the work. 648 */ 649 int 650 nfs_read(ap) 651 struct vop_read_args *ap; 652 { 653 register struct vnode *vp = ap->a_vp; 654 655 if (vp->v_type != VREG) 656 return (EPERM); 657 return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred)); 658 } 659 660 /* 661 * nfs readlink call 662 */ 663 int 664 nfs_readlink(ap) 665 struct vop_readlink_args *ap; 666 { 667 register struct vnode *vp = ap->a_vp; 668 669 if (vp->v_type != VLNK) 670 return (EPERM); 671 return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred)); 672 } 673 674 /* 675 * Do a readlink rpc. 676 * Called by nfs_doio() from below the buffer cache. 677 */ 678 int 679 nfs_readlinkrpc(vp, uiop, cred) 680 register struct vnode *vp; 681 struct uio *uiop; 682 struct ucred *cred; 683 { 684 register u_long *tl; 685 register caddr_t cp; 686 register long t1; 687 caddr_t bpos, dpos, cp2; 688 int error = 0; 689 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 690 long len; 691 692 nfsstats.rpccnt[NFSPROC_READLINK]++; 693 nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH); 694 nfsm_fhtom(vp); 695 nfsm_request(vp, NFSPROC_READLINK, uiop->uio_procp, cred); 696 nfsm_strsiz(len, NFS_MAXPATHLEN); 697 nfsm_mtouio(uiop, len); 698 nfsm_reqdone; 699 return (error); 700 } 701 702 /* 703 * nfs read rpc call 704 * Ditto above 705 */ 706 int 707 nfs_readrpc(vp, uiop, cred) 708 register struct vnode *vp; 709 struct uio *uiop; 710 struct ucred *cred; 711 { 712 register u_long *tl; 713 register caddr_t cp; 714 register long t1; 715 caddr_t bpos, dpos, cp2; 716 int error = 0; 717 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 718 struct nfsmount *nmp; 719 long len, retlen, tsiz; 720 721 nmp = VFSTONFS(vp->v_mount); 722 tsiz = uiop->uio_resid; 723 while (tsiz > 0) { 724 nfsstats.rpccnt[NFSPROC_READ]++; 725 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; 726 nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH+NFSX_UNSIGNED*3); 727 nfsm_fhtom(vp); 728 nfsm_build(tl, u_long *, NFSX_UNSIGNED*3); 729 *tl++ = txdr_unsigned(uiop->uio_offset); 730 *tl++ = txdr_unsigned(len); 731 *tl = 0; 732 nfsm_request(vp, NFSPROC_READ, uiop->uio_procp, cred); 733 nfsm_loadattr(vp, (struct vattr *)0); 734 nfsm_strsiz(retlen, nmp->nm_rsize); 735 nfsm_mtouio(uiop, retlen); 736 m_freem(mrep); 737 if (retlen < len) 738 tsiz = 0; 739 else 740 tsiz -= len; 741 } 742 nfsmout: 743 return (error); 744 } 745 746 /* 747 * nfs write call 748 */ 749 int 750 nfs_writerpc(vp, uiop, cred) 751 register struct vnode *vp; 752 struct uio *uiop; 753 struct ucred *cred; 754 { 755 register u_long *tl; 756 register caddr_t cp; 757 register long t1; 758 caddr_t bpos, dpos, cp2; 759 int error = 0; 760 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 761 struct nfsmount *nmp; 762 struct nfsnode *np = VTONFS(vp); 763 u_quad_t frev; 764 long len, tsiz; 765 766 nmp = VFSTONFS(vp->v_mount); 767 tsiz = uiop->uio_resid; 768 while (tsiz > 0) { 769 nfsstats.rpccnt[NFSPROC_WRITE]++; 770 len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; 771 nfsm_reqhead(vp, NFSPROC_WRITE, 772 NFSX_FH+NFSX_UNSIGNED*4+nfsm_rndup(len)); 773 nfsm_fhtom(vp); 774 nfsm_build(tl, u_long *, NFSX_UNSIGNED*4); 775 *(tl+1) = txdr_unsigned(uiop->uio_offset); 776 *(tl+3) = txdr_unsigned(len); 777 nfsm_uiotom(uiop, len); 778 nfsm_request(vp, NFSPROC_WRITE, uiop->uio_procp, cred); 779 nfsm_loadattr(vp, (struct vattr *)0); 780 if (nmp->nm_flag & NFSMNT_MYWRITE) 781 VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime.ts_sec; 782 else if ((nmp->nm_flag & NFSMNT_NQNFS) && 783 NQNFS_CKCACHABLE(vp, NQL_WRITE)) { 784 nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); 785 fxdr_hyper(tl, &frev); 786 if (QUADGT(frev, np->n_brev)) 787 np->n_brev = frev; 788 } 789 m_freem(mrep); 790 tsiz -= len; 791 } 792 nfsmout: 793 if (error) 794 uiop->uio_resid = tsiz; 795 return (error); 796 } 797 798 /* 799 * nfs mknod call 800 * This is a kludge. Use a create rpc but with the IFMT bits of the mode 801 * set to specify the file type and the size field for rdev. 802 */ 803 /* ARGSUSED */ 804 int 805 nfs_mknod(ap) 806 struct vop_mknod_args *ap; 807 { 808 USES_VOP_ABORTOP; 809 register struct vnode *dvp = ap->a_dvp; 810 register struct vattr *vap = ap->a_vap; 811 register struct componentname *cnp = ap->a_cnp; 812 register struct nfsv2_sattr *sp; 813 register u_long *tl; 814 register caddr_t cp; 815 register long t2; 816 caddr_t bpos, dpos; 817 int error = 0; 818 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 819 u_long rdev; 820 821 if (vap->va_type == VCHR || vap->va_type == VBLK) 822 rdev = txdr_unsigned(vap->va_rdev); 823 #ifdef FIFO 824 else if (vap->va_type == VFIFO) 825 rdev = 0xffffffff; 826 #endif /* FIFO */ 827 else { 828 VOP_ABORTOP(dvp, cnp); 829 vput(dvp); 830 return (EOPNOTSUPP); 831 } 832 nfsstats.rpccnt[NFSPROC_CREATE]++; 833 nfsm_reqhead(dvp, NFSPROC_CREATE, 834 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)+NFSX_SATTR); 835 nfsm_fhtom(dvp); 836 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 837 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 838 sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode); 839 sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid); 840 sp->sa_gid = txdr_unsigned(cnp->cn_cred->cr_gid); 841 sp->sa_size = rdev; 842 /* or should these be VNOVAL ?? */ 843 txdr_time(&vap->va_atime, &sp->sa_atime); 844 txdr_time(&vap->va_mtime, &sp->sa_mtime); 845 nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_proc, cnp->cn_cred); 846 nfsm_reqdone; 847 FREE(cnp->cn_pnbuf, M_NAMEI); 848 VTONFS(dvp)->n_flag |= NMODIFIED; 849 vrele(dvp); 850 return (error); 851 } 852 853 /* 854 * nfs file create call 855 */ 856 int 857 nfs_create(ap) 858 struct vop_create_args *ap; 859 { 860 register struct vnode *dvp = ap->a_dvp; 861 register struct vattr *vap = ap->a_vap; 862 register struct componentname *cnp = ap->a_cnp; 863 register struct nfsv2_sattr *sp; 864 register u_long *tl; 865 register caddr_t cp; 866 register long t1, t2; 867 caddr_t bpos, dpos, cp2; 868 int error = 0; 869 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 870 871 nfsstats.rpccnt[NFSPROC_CREATE]++; 872 nfsm_reqhead(dvp, NFSPROC_CREATE, 873 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)+NFSX_SATTR); 874 nfsm_fhtom(dvp); 875 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 876 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 877 sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode); 878 sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid); 879 sp->sa_gid = txdr_unsigned(cnp->cn_cred->cr_gid); 880 sp->sa_size = txdr_unsigned(0); 881 /* or should these be VNOVAL ?? */ 882 txdr_time(&vap->va_atime, &sp->sa_atime); 883 txdr_time(&vap->va_mtime, &sp->sa_mtime); 884 nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_proc, cnp->cn_cred); 885 nfsm_mtofh(dvp, *ap->a_vpp); 886 nfsm_reqdone; 887 FREE(cnp->cn_pnbuf, M_NAMEI); 888 VTONFS(dvp)->n_flag |= NMODIFIED; 889 vrele(dvp); 890 return (error); 891 } 892 893 /* 894 * nfs file remove call 895 * To try and make nfs semantics closer to ufs semantics, a file that has 896 * other processes using the vnode is renamed instead of removed and then 897 * removed later on the last close. 898 * - If v_usecount > 1 899 * If a rename is not already in the works 900 * call nfs_sillyrename() to set it up 901 * else 902 * do the remove rpc 903 */ 904 int 905 nfs_remove(ap) 906 struct vop_remove_args *ap; 907 { 908 register struct vnode *vp = ap->a_vp; 909 register struct vnode *dvp = ap->a_dvp; 910 register struct componentname *cnp = ap->a_cnp; 911 register struct nfsnode *np = VTONFS(vp); 912 register u_long *tl; 913 register caddr_t cp; 914 register long t2; 915 caddr_t bpos, dpos; 916 int error = 0; 917 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 918 919 if (vp->v_usecount > 1) { 920 if (!np->n_sillyrename) 921 error = nfs_sillyrename(dvp, vp, cnp); 922 } else { 923 /* 924 * Purge the name cache so that the chance of a lookup for 925 * the name succeeding while the remove is in progress is 926 * minimized. Without node locking it can still happen, such 927 * that an I/O op returns ESTALE, but since you get this if 928 * another host removes the file.. 929 */ 930 cache_purge(vp); 931 /* 932 * Throw away biocache buffers. Mainly to avoid 933 * unnecessary delayed writes. 934 */ 935 vinvalbuf(vp, FALSE); 936 /* Do the rpc */ 937 nfsstats.rpccnt[NFSPROC_REMOVE]++; 938 nfsm_reqhead(dvp, NFSPROC_REMOVE, 939 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)); 940 nfsm_fhtom(dvp); 941 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 942 nfsm_request(dvp, NFSPROC_REMOVE, cnp->cn_proc, cnp->cn_cred); 943 nfsm_reqdone; 944 FREE(cnp->cn_pnbuf, M_NAMEI); 945 VTONFS(dvp)->n_flag |= NMODIFIED; 946 /* 947 * Kludge City: If the first reply to the remove rpc is lost.. 948 * the reply to the retransmitted request will be ENOENT 949 * since the file was in fact removed 950 * Therefore, we cheat and return success. 951 */ 952 if (error == ENOENT) 953 error = 0; 954 } 955 np->n_attrstamp = 0; 956 vrele(dvp); 957 vrele(vp); 958 return (error); 959 } 960 961 /* 962 * nfs file remove rpc called from nfs_inactive 963 */ 964 int 965 nfs_removeit(sp, procp) 966 register struct sillyrename *sp; 967 struct proc *procp; 968 { 969 register u_long *tl; 970 register caddr_t cp; 971 register long t2; 972 caddr_t bpos, dpos; 973 int error = 0; 974 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 975 976 nfsstats.rpccnt[NFSPROC_REMOVE]++; 977 nfsm_reqhead(sp->s_dvp, NFSPROC_REMOVE, 978 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(sp->s_namlen)); 979 nfsm_fhtom(sp->s_dvp); 980 nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN); 981 nfsm_request(sp->s_dvp, NFSPROC_REMOVE, procp, sp->s_cred); 982 nfsm_reqdone; 983 VTONFS(sp->s_dvp)->n_flag |= NMODIFIED; 984 return (error); 985 } 986 987 /* 988 * nfs file rename call 989 */ 990 int 991 nfs_rename(ap) 992 struct vop_rename_args *ap; 993 { 994 register struct vnode *fvp = ap->a_fvp; 995 register struct vnode *tvp = ap->a_tvp; 996 register struct vnode *fdvp = ap->a_fdvp; 997 register struct vnode *tdvp = ap->a_tdvp; 998 register struct componentname *tcnp = ap->a_tcnp; 999 register struct componentname *fcnp = ap->a_fcnp; 1000 register u_long *tl; 1001 register caddr_t cp; 1002 register long t2; 1003 caddr_t bpos, dpos; 1004 int error = 0; 1005 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1006 1007 /* Check for cross-device rename */ 1008 if ((fvp->v_mount != tdvp->v_mount) || 1009 (tvp && (fvp->v_mount != tvp->v_mount))) { 1010 error = EXDEV; 1011 goto out; 1012 } 1013 1014 1015 nfsstats.rpccnt[NFSPROC_RENAME]++; 1016 nfsm_reqhead(fdvp, NFSPROC_RENAME, 1017 (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(fcnp->cn_namelen)+ 1018 nfsm_rndup(fcnp->cn_namelen)); /* or fcnp->cn_cred?*/ 1019 nfsm_fhtom(fdvp); 1020 nfsm_strtom(fcnp->cn_nameptr, fcnp->cn_namelen, NFS_MAXNAMLEN); 1021 nfsm_fhtom(tdvp); 1022 nfsm_strtom(tcnp->cn_nameptr, tcnp->cn_namelen, NFS_MAXNAMLEN); 1023 nfsm_request(fdvp, NFSPROC_RENAME, tcnp->cn_proc, tcnp->cn_cred); 1024 nfsm_reqdone; 1025 VTONFS(fdvp)->n_flag |= NMODIFIED; 1026 VTONFS(tdvp)->n_flag |= NMODIFIED; 1027 if (fvp->v_type == VDIR) { 1028 if (tvp != NULL && tvp->v_type == VDIR) 1029 cache_purge(tdvp); 1030 cache_purge(fdvp); 1031 } 1032 out: 1033 if (tdvp == tvp) 1034 vrele(tdvp); 1035 else 1036 vput(tdvp); 1037 if (tvp) 1038 vput(tvp); 1039 vrele(fdvp); 1040 vrele(fvp); 1041 /* 1042 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. 1043 */ 1044 if (error == ENOENT) 1045 error = 0; 1046 return (error); 1047 } 1048 1049 /* 1050 * nfs file rename rpc called from nfs_remove() above 1051 */ 1052 int 1053 nfs_renameit(sdvp, scnp, sp) 1054 struct vnode *sdvp; 1055 struct componentname *scnp; 1056 register struct sillyrename *sp; 1057 { 1058 register u_long *tl; 1059 register caddr_t cp; 1060 register long t2; 1061 caddr_t bpos, dpos; 1062 int error = 0; 1063 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1064 1065 nfsstats.rpccnt[NFSPROC_RENAME]++; 1066 nfsm_reqhead(sdvp, NFSPROC_RENAME, 1067 (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(scnp->cn_namelen)+ 1068 nfsm_rndup(sp->s_namlen)); 1069 nfsm_fhtom(sdvp); 1070 nfsm_strtom(scnp->cn_nameptr, scnp->cn_namelen, NFS_MAXNAMLEN); 1071 nfsm_fhtom(sdvp); 1072 nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN); 1073 nfsm_request(sdvp, NFSPROC_RENAME, scnp->cn_proc, scnp->cn_cred); 1074 nfsm_reqdone; 1075 FREE(scnp->cn_pnbuf, M_NAMEI); 1076 VTONFS(sdvp)->n_flag |= NMODIFIED; 1077 return (error); 1078 } 1079 1080 /* 1081 * nfs hard link create call 1082 */ 1083 int 1084 nfs_link(ap) 1085 struct vop_link_args *ap; 1086 { 1087 register struct vnode *vp = ap->a_vp; 1088 register struct vnode *tdvp = ap->a_tdvp; 1089 register struct componentname *cnp = ap->a_cnp; 1090 register u_long *tl; 1091 register caddr_t cp; 1092 register long t2; 1093 caddr_t bpos, dpos; 1094 int error = 0; 1095 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1096 1097 if (vp->v_mount != tdvp->v_mount) { 1098 /*VOP_ABORTOP(vp, cnp);*/ 1099 if (tdvp == vp) 1100 vrele(vp); 1101 else 1102 vput(vp); 1103 return (EXDEV); 1104 } 1105 1106 nfsstats.rpccnt[NFSPROC_LINK]++; 1107 nfsm_reqhead(tdvp, NFSPROC_LINK, 1108 NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)); 1109 nfsm_fhtom(tdvp); 1110 nfsm_fhtom(vp); 1111 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1112 nfsm_request(tdvp, NFSPROC_LINK, cnp->cn_proc, cnp->cn_cred); 1113 nfsm_reqdone; 1114 FREE(cnp->cn_pnbuf, M_NAMEI); 1115 VTONFS(tdvp)->n_attrstamp = 0; 1116 VTONFS(vp)->n_flag |= NMODIFIED; 1117 vrele(vp); 1118 /* 1119 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. 1120 */ 1121 if (error == EEXIST) 1122 error = 0; 1123 return (error); 1124 } 1125 1126 /* 1127 * nfs symbolic link create call 1128 */ 1129 /* start here */ 1130 int 1131 nfs_symlink(ap) 1132 struct vop_symlink_args *ap; 1133 { 1134 register struct vnode *dvp = ap->a_dvp; 1135 register struct vattr *vap = ap->a_vap; 1136 register struct componentname *cnp = ap->a_cnp; 1137 register struct nfsv2_sattr *sp; 1138 register u_long *tl; 1139 register caddr_t cp; 1140 register long t2; 1141 caddr_t bpos, dpos; 1142 int slen, error = 0; 1143 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1144 1145 nfsstats.rpccnt[NFSPROC_SYMLINK]++; 1146 slen = strlen(ap->a_target); 1147 nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH+2*NFSX_UNSIGNED+ 1148 nfsm_rndup(cnp->cn_namelen)+nfsm_rndup(slen)+NFSX_SATTR); 1149 nfsm_fhtom(dvp); 1150 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1151 nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN); 1152 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 1153 sp->sa_mode = vtonfs_mode(VLNK, vap->va_mode); 1154 sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid); 1155 sp->sa_gid = txdr_unsigned(cnp->cn_cred->cr_gid); 1156 sp->sa_size = txdr_unsigned(VNOVAL); 1157 txdr_time(&vap->va_atime, &sp->sa_atime); /* or VNOVAL ?? */ 1158 txdr_time(&vap->va_mtime, &sp->sa_mtime); /* or VNOVAL ?? */ 1159 nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_proc, cnp->cn_cred); 1160 nfsm_reqdone; 1161 FREE(cnp->cn_pnbuf, M_NAMEI); 1162 VTONFS(dvp)->n_flag |= NMODIFIED; 1163 vrele(dvp); 1164 /* 1165 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. 1166 */ 1167 if (error == EEXIST) 1168 error = 0; 1169 return (error); 1170 } 1171 1172 /* 1173 * nfs make dir call 1174 */ 1175 int 1176 nfs_mkdir(ap) 1177 struct vop_mkdir_args *ap; 1178 { 1179 register struct vnode *dvp = ap->a_dvp; 1180 register struct vattr *vap = ap->a_vap; 1181 register struct componentname *cnp = ap->a_cnp; 1182 register struct nfsv2_sattr *sp; 1183 register u_long *tl; 1184 register caddr_t cp; 1185 register long t1, t2; 1186 register int len; 1187 caddr_t bpos, dpos, cp2; 1188 int error = 0, firsttry = 1; 1189 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1190 1191 len = cnp->cn_namelen; 1192 nfsstats.rpccnt[NFSPROC_MKDIR]++; 1193 nfsm_reqhead(dvp, NFSPROC_MKDIR, 1194 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)+NFSX_SATTR); 1195 nfsm_fhtom(dvp); 1196 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 1197 nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR); 1198 sp->sa_mode = vtonfs_mode(VDIR, vap->va_mode); 1199 sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid); 1200 sp->sa_gid = txdr_unsigned(cnp->cn_cred->cr_gid); 1201 sp->sa_size = txdr_unsigned(VNOVAL); 1202 txdr_time(&vap->va_atime, &sp->sa_atime); /* or VNOVAL ?? */ 1203 txdr_time(&vap->va_mtime, &sp->sa_mtime); /* or VNOVAL ?? */ 1204 nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_proc, cnp->cn_cred); 1205 nfsm_mtofh(dvp, *ap->a_vpp); 1206 nfsm_reqdone; 1207 VTONFS(dvp)->n_flag |= NMODIFIED; 1208 /* 1209 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry 1210 * if we can succeed in looking up the directory. 1211 * "firsttry" is necessary since the macros may "goto nfsmout" which 1212 * is above the if on errors. (Ugh) 1213 */ 1214 if (error == EEXIST && firsttry) { 1215 firsttry = 0; 1216 error = 0; 1217 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 1218 *ap->a_vpp = NULL; 1219 nfsm_reqhead(dvp, NFSPROC_LOOKUP, 1220 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)); 1221 nfsm_fhtom(dvp); 1222 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 1223 nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_proc, cnp->cn_cred); 1224 nfsm_mtofh(dvp, *ap->a_vpp); 1225 if ((*ap->a_vpp)->v_type != VDIR) { 1226 vput(*ap->a_vpp); 1227 error = EEXIST; 1228 } 1229 m_freem(mrep); 1230 } 1231 FREE(cnp->cn_pnbuf, M_NAMEI); 1232 vrele(dvp); 1233 return (error); 1234 } 1235 1236 /* 1237 * nfs remove directory call 1238 */ 1239 int 1240 nfs_rmdir(ap) 1241 struct vop_rmdir_args *ap; 1242 { 1243 register struct vnode *vp = ap->a_vp; 1244 register struct vnode *dvp = ap->a_dvp; 1245 register struct componentname *cnp = ap->a_cnp; 1246 register u_long *tl; 1247 register caddr_t cp; 1248 register long t2; 1249 caddr_t bpos, dpos; 1250 int error = 0; 1251 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1252 1253 if (dvp == vp) { 1254 vrele(dvp); 1255 vrele(dvp); 1256 FREE(cnp->cn_pnbuf, M_NAMEI); 1257 return (EINVAL); 1258 } 1259 nfsstats.rpccnt[NFSPROC_RMDIR]++; 1260 nfsm_reqhead(dvp, NFSPROC_RMDIR, 1261 NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)); 1262 nfsm_fhtom(dvp); 1263 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1264 nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_proc, cnp->cn_cred); 1265 nfsm_reqdone; 1266 FREE(cnp->cn_pnbuf, M_NAMEI); 1267 VTONFS(dvp)->n_flag |= NMODIFIED; 1268 cache_purge(dvp); 1269 cache_purge(vp); 1270 vrele(vp); 1271 vrele(dvp); 1272 /* 1273 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. 1274 */ 1275 if (error == ENOENT) 1276 error = 0; 1277 return (error); 1278 } 1279 1280 /* 1281 * nfs readdir call 1282 * Although cookie is defined as opaque, I translate it to/from net byte 1283 * order so that it looks more sensible. This appears consistent with the 1284 * Ultrix implementation of NFS. 1285 */ 1286 int 1287 nfs_readdir(ap) 1288 struct vop_readdir_args *ap; 1289 { 1290 USES_VOP_GETATTR; 1291 register struct vnode *vp = ap->a_vp; 1292 register struct nfsnode *np = VTONFS(vp); 1293 register struct uio *uio = ap->a_uio; 1294 register int *eofflagp = ap->a_eofflagp; 1295 int tresid, error; 1296 struct vattr vattr; 1297 1298 if (vp->v_type != VDIR) 1299 return (EPERM); 1300 /* 1301 * First, check for hit on the EOF offset cache 1302 */ 1303 if (uio->uio_offset != 0 && uio->uio_offset == np->n_direofoffset && 1304 (np->n_flag & NMODIFIED) == 0) { 1305 if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) { 1306 if (NQNFS_CKCACHABLE(vp, NQL_READ)) { 1307 *eofflagp = 1; 1308 nfsstats.direofcache_hits++; 1309 return (0); 1310 } 1311 } else if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_procp) == 0 && 1312 np->n_mtime == vattr.va_mtime.ts_sec) { 1313 *eofflagp = 1; 1314 nfsstats.direofcache_hits++; 1315 return (0); 1316 } 1317 } 1318 1319 /* 1320 * Call nfs_bioread() to do the real work. 1321 */ 1322 tresid = uio->uio_resid; 1323 error = nfs_bioread(vp, uio, 0, ap->a_cred); 1324 1325 if (!error && uio->uio_resid == tresid) { 1326 *eofflagp = 1; 1327 nfsstats.direofcache_misses++; 1328 } else 1329 *eofflagp = 0; 1330 return (error); 1331 } 1332 1333 /* 1334 * Readdir rpc call. 1335 * Called from below the buffer cache by nfs_doio(). 1336 */ 1337 int 1338 nfs_readdirrpc(vp, uiop, cred) 1339 register struct vnode *vp; 1340 struct uio *uiop; 1341 struct ucred *cred; 1342 { 1343 register long len; 1344 register struct readdir *dp; 1345 register u_long *tl; 1346 register caddr_t cp; 1347 register long t1; 1348 long tlen, lastlen; 1349 caddr_t bpos, dpos, cp2; 1350 int error = 0; 1351 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1352 struct mbuf *md2; 1353 caddr_t dpos2; 1354 int siz; 1355 int more_dirs = 1; 1356 off_t off, savoff; 1357 struct readdir *savdp; 1358 struct nfsmount *nmp; 1359 struct nfsnode *np = VTONFS(vp); 1360 long tresid; 1361 1362 nmp = VFSTONFS(vp->v_mount); 1363 tresid = uiop->uio_resid; 1364 /* 1365 * Loop around doing readdir rpc's of size uio_resid or nm_rsize, 1366 * whichever is smaller, truncated to a multiple of NFS_DIRBLKSIZ. 1367 * The stopping criteria is EOF or buffer full. 1368 */ 1369 while (more_dirs && uiop->uio_resid >= NFS_DIRBLKSIZ) { 1370 nfsstats.rpccnt[NFSPROC_READDIR]++; 1371 nfsm_reqhead(vp, NFSPROC_READDIR, 1372 NFSX_FH+2*NFSX_UNSIGNED); 1373 nfsm_fhtom(vp); 1374 nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED); 1375 *tl++ = txdr_unsigned(uiop->uio_offset); 1376 *tl = txdr_unsigned(((uiop->uio_resid > nmp->nm_rsize) ? 1377 nmp->nm_rsize : uiop->uio_resid) & ~(NFS_DIRBLKSIZ-1)); 1378 nfsm_request(vp, NFSPROC_READDIR, uiop->uio_procp, cred); 1379 siz = 0; 1380 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); 1381 more_dirs = fxdr_unsigned(int, *tl); 1382 1383 /* Save the position so that we can do nfsm_mtouio() later */ 1384 dpos2 = dpos; 1385 md2 = md; 1386 1387 /* loop thru the dir entries, doctoring them to 4bsd form */ 1388 off = uiop->uio_offset; 1389 #ifdef lint 1390 dp = (struct readdir *)0; 1391 #endif /* lint */ 1392 while (more_dirs && siz < uiop->uio_resid) { 1393 savoff = off; /* Hold onto offset and dp */ 1394 savdp = dp; 1395 nfsm_dissecton(tl, u_long *, 2*NFSX_UNSIGNED); 1396 dp = (struct readdir *)tl; 1397 dp->d_ino = fxdr_unsigned(u_long, *tl++); 1398 len = fxdr_unsigned(int, *tl); 1399 if (len <= 0 || len > NFS_MAXNAMLEN) { 1400 error = EBADRPC; 1401 m_freem(mrep); 1402 goto nfsmout; 1403 } 1404 dp->d_namlen = (u_short)len; 1405 nfsm_adv(len); /* Point past name */ 1406 tlen = nfsm_rndup(len); 1407 /* 1408 * This should not be necessary, but some servers have 1409 * broken XDR such that these bytes are not null filled. 1410 */ 1411 if (tlen != len) { 1412 *dpos = '\0'; /* Null-terminate */ 1413 nfsm_adv(tlen - len); 1414 len = tlen; 1415 } 1416 nfsm_dissecton(tl, u_long *, 2*NFSX_UNSIGNED); 1417 off = fxdr_unsigned(off_t, *tl); 1418 *tl++ = 0; /* Ensures null termination of name */ 1419 more_dirs = fxdr_unsigned(int, *tl); 1420 dp->d_reclen = len+4*NFSX_UNSIGNED; 1421 siz += dp->d_reclen; 1422 } 1423 /* 1424 * If at end of rpc data, get the eof boolean 1425 */ 1426 if (!more_dirs) { 1427 nfsm_dissecton(tl, u_long *, NFSX_UNSIGNED); 1428 more_dirs = (fxdr_unsigned(int, *tl) == 0); 1429 1430 /* 1431 * If at EOF, cache directory offset 1432 */ 1433 if (!more_dirs) 1434 np->n_direofoffset = off; 1435 } 1436 /* 1437 * If there is too much to fit in the data buffer, use savoff and 1438 * savdp to trim off the last record. 1439 * --> we are not at eof 1440 */ 1441 if (siz > uiop->uio_resid) { 1442 off = savoff; 1443 siz -= dp->d_reclen; 1444 dp = savdp; 1445 more_dirs = 0; /* Paranoia */ 1446 } 1447 if (siz > 0) { 1448 lastlen = dp->d_reclen; 1449 md = md2; 1450 dpos = dpos2; 1451 nfsm_mtouio(uiop, siz); 1452 uiop->uio_offset = off; 1453 } else 1454 more_dirs = 0; /* Ugh, never happens, but in case.. */ 1455 m_freem(mrep); 1456 } 1457 /* 1458 * Fill last record, iff any, out to a multiple of NFS_DIRBLKSIZ 1459 * by increasing d_reclen for the last record. 1460 */ 1461 if (uiop->uio_resid < tresid) { 1462 len = uiop->uio_resid & (NFS_DIRBLKSIZ - 1); 1463 if (len > 0) { 1464 dp = (struct readdir *) 1465 (uiop->uio_iov->iov_base - lastlen); 1466 dp->d_reclen += len; 1467 uiop->uio_iov->iov_base += len; 1468 uiop->uio_iov->iov_len -= len; 1469 uiop->uio_resid -= len; 1470 } 1471 } 1472 nfsmout: 1473 return (error); 1474 } 1475 1476 /* 1477 * Nqnfs readdir_and_lookup RPC. Used in place of nfs_readdirrpc() when 1478 * the "rdirlook" mount option is specified. 1479 */ 1480 int 1481 nfs_readdirlookrpc(vp, uiop, cred) 1482 struct vnode *vp; 1483 register struct uio *uiop; 1484 struct ucred *cred; 1485 { 1486 register int len; 1487 register struct readdir *dp; 1488 register u_long *tl; 1489 register caddr_t cp; 1490 register long t1; 1491 caddr_t bpos, dpos, cp2; 1492 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1493 struct nameidata nami, *ndp = &nami; 1494 struct componentname *cnp = &ndp->ni_cnd; 1495 off_t off, endoff; 1496 time_t reqtime, ltime; 1497 struct nfsmount *nmp; 1498 struct nfsnode *np, *tp; 1499 struct vnode *newvp; 1500 nfsv2fh_t *fhp; 1501 u_long fileno; 1502 u_quad_t frev; 1503 int error = 0, tlen, more_dirs = 1, tresid, doit, bigenough, i; 1504 int cachable; 1505 1506 if (uiop->uio_iovcnt != 1) 1507 panic("nfs rdirlook"); 1508 nmp = VFSTONFS(vp->v_mount); 1509 tresid = uiop->uio_resid; 1510 ndp->ni_dvp = vp; 1511 newvp = NULLVP; 1512 /* 1513 * Loop around doing readdir rpc's of size uio_resid or nm_rsize, 1514 * whichever is smaller, truncated to a multiple of NFS_DIRBLKSIZ. 1515 * The stopping criteria is EOF or buffer full. 1516 */ 1517 while (more_dirs && uiop->uio_resid >= NFS_DIRBLKSIZ) { 1518 nfsstats.rpccnt[NQNFSPROC_READDIRLOOK]++; 1519 nfsm_reqhead(vp, NQNFSPROC_READDIRLOOK, 1520 NFSX_FH+3*NFSX_UNSIGNED); 1521 nfsm_fhtom(vp); 1522 nfsm_build(tl, u_long *, 3*NFSX_UNSIGNED); 1523 *tl++ = txdr_unsigned(uiop->uio_offset); 1524 *tl++ = txdr_unsigned(((uiop->uio_resid > nmp->nm_rsize) ? 1525 nmp->nm_rsize : uiop->uio_resid) & ~(NFS_DIRBLKSIZ-1)); 1526 *tl = txdr_unsigned(nmp->nm_leaseterm); 1527 reqtime = time.tv_sec; 1528 nfsm_request(vp, NQNFSPROC_READDIRLOOK, uiop->uio_procp, cred); 1529 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); 1530 more_dirs = fxdr_unsigned(int, *tl); 1531 1532 /* loop thru the dir entries, doctoring them to 4bsd form */ 1533 off = uiop->uio_offset; 1534 bigenough = 1; 1535 while (more_dirs && bigenough) { 1536 doit = 1; 1537 nfsm_dissect(tl, u_long *, 4*NFSX_UNSIGNED); 1538 cachable = fxdr_unsigned(int, *tl++); 1539 ltime = reqtime + fxdr_unsigned(int, *tl++); 1540 fxdr_hyper(tl, &frev); 1541 nfsm_dissect(fhp, nfsv2fh_t *, NFSX_FH); 1542 if (!bcmp(VTONFS(vp)->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) { 1543 VREF(vp); 1544 newvp = vp; 1545 np = VTONFS(vp); 1546 } else { 1547 if (error = nfs_nget(vp->v_mount, fhp, &np)) 1548 doit = 0; 1549 newvp = NFSTOV(np); 1550 } 1551 if (error = nfs_loadattrcache(&newvp, &md, &dpos, 1552 (struct vattr *)0)) 1553 doit = 0; 1554 nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); 1555 fileno = fxdr_unsigned(u_long, *tl++); 1556 len = fxdr_unsigned(int, *tl); 1557 if (len <= 0 || len > NFS_MAXNAMLEN) { 1558 error = EBADRPC; 1559 m_freem(mrep); 1560 goto nfsmout; 1561 } 1562 tlen = (len + 4) & ~0x3; 1563 if ((tlen + DIRHDSIZ) > uiop->uio_resid) 1564 bigenough = 0; 1565 if (bigenough && doit) { 1566 dp = (struct readdir *)uiop->uio_iov->iov_base; 1567 dp->d_ino = fileno; 1568 dp->d_namlen = len; 1569 dp->d_reclen = tlen + DIRHDSIZ; 1570 uiop->uio_resid -= DIRHDSIZ; 1571 uiop->uio_iov->iov_base += DIRHDSIZ; 1572 uiop->uio_iov->iov_len -= DIRHDSIZ; 1573 cnp->cn_nameptr = uiop->uio_iov->iov_base; 1574 cnp->cn_namelen = len; 1575 ndp->ni_vp = newvp; 1576 nfsm_mtouio(uiop, len); 1577 cp = uiop->uio_iov->iov_base; 1578 tlen -= len; 1579 for (i = 0; i < tlen; i++) 1580 *cp++ = '\0'; 1581 uiop->uio_iov->iov_base += tlen; 1582 uiop->uio_iov->iov_len -= tlen; 1583 uiop->uio_resid -= tlen; 1584 cnp->cn_hash = 0; 1585 for (cp = cnp->cn_nameptr, i = 1; i <= len; i++, cp++) 1586 cnp->cn_hash += (unsigned char)*cp * i; 1587 if (ltime > time.tv_sec) { 1588 if (np->n_tnext) { 1589 if (np->n_tnext == (struct nfsnode *)nmp) 1590 nmp->nm_tprev = np->n_tprev; 1591 else 1592 np->n_tnext->n_tprev = np->n_tprev; 1593 if (np->n_tprev == (struct nfsnode *)nmp) 1594 nmp->nm_tnext = np->n_tnext; 1595 else 1596 np->n_tprev->n_tnext = np->n_tnext; 1597 } else 1598 np->n_flag &= ~NQNFSWRITE; 1599 if (cachable) 1600 np->n_flag &= ~NQNFSNONCACHE; 1601 else 1602 np->n_flag |= NQNFSNONCACHE; 1603 np->n_expiry = ltime; 1604 np->n_lrev = frev; 1605 tp = nmp->nm_tprev; 1606 while (tp != (struct nfsnode *)nmp && tp->n_expiry > np->n_expiry) 1607 tp = tp->n_tprev; 1608 if (tp == (struct nfsnode *)nmp) { 1609 np->n_tnext = nmp->nm_tnext; 1610 nmp->nm_tnext = np; 1611 } else { 1612 np->n_tnext = tp->n_tnext; 1613 tp->n_tnext = np; 1614 } 1615 np->n_tprev = tp; 1616 if (np->n_tnext == (struct nfsnode *)nmp) 1617 nmp->nm_tprev = np; 1618 else 1619 np->n_tnext->n_tprev = np; 1620 cache_enter(ndp->ni_dvp, ndp->ni_vp, cnp); 1621 } 1622 } else { 1623 nfsm_adv(nfsm_rndup(len)); 1624 } 1625 if (newvp != NULLVP) { 1626 vrele(newvp); 1627 newvp = NULLVP; 1628 } 1629 nfsm_dissect(tl, u_long *, 2*NFSX_UNSIGNED); 1630 if (bigenough) 1631 endoff = off = fxdr_unsigned(off_t, *tl++); 1632 else 1633 endoff = fxdr_unsigned(off_t, *tl++); 1634 more_dirs = fxdr_unsigned(int, *tl); 1635 } 1636 /* 1637 * If at end of rpc data, get the eof boolean 1638 */ 1639 if (!more_dirs) { 1640 nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); 1641 more_dirs = (fxdr_unsigned(int, *tl) == 0); 1642 1643 /* 1644 * If at EOF, cache directory offset 1645 */ 1646 if (!more_dirs) 1647 VTONFS(vp)->n_direofoffset = endoff; 1648 } 1649 if (uiop->uio_resid < tresid) 1650 uiop->uio_offset = off; 1651 else 1652 more_dirs = 0; 1653 m_freem(mrep); 1654 } 1655 /* 1656 * Fill last record, iff any, out to a multiple of NFS_DIRBLKSIZ 1657 * by increasing d_reclen for the last record. 1658 */ 1659 if (uiop->uio_resid < tresid) { 1660 len = uiop->uio_resid & (NFS_DIRBLKSIZ - 1); 1661 if (len > 0) { 1662 dp->d_reclen += len; 1663 uiop->uio_iov->iov_base += len; 1664 uiop->uio_iov->iov_len -= len; 1665 uiop->uio_resid -= len; 1666 } 1667 } 1668 nfsmout: 1669 if (newvp != NULLVP) 1670 vrele(newvp); 1671 return (error); 1672 } 1673 static char hextoasc[] = "0123456789abcdef"; 1674 1675 /* 1676 * Silly rename. To make the NFS filesystem that is stateless look a little 1677 * more like the "ufs" a remove of an active vnode is translated to a rename 1678 * to a funny looking filename that is removed by nfs_inactive on the 1679 * nfsnode. There is the potential for another process on a different client 1680 * to create the same funny name between the nfs_lookitup() fails and the 1681 * nfs_rename() completes, but... 1682 */ 1683 int 1684 nfs_sillyrename(dvp, vp, cnp) 1685 struct vnode *dvp, *vp; 1686 struct componentname *cnp; 1687 { 1688 register struct nfsnode *np; 1689 register struct sillyrename *sp; 1690 int error; 1691 short pid; 1692 1693 cache_purge(dvp); 1694 np = VTONFS(vp); 1695 #ifdef SILLYSEPARATE 1696 MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename), 1697 M_NFSREQ, M_WAITOK); 1698 #else 1699 sp = &np->n_silly; 1700 #endif 1701 sp->s_cred = crdup(cnp->cn_cred); 1702 sp->s_dvp = dvp; 1703 VREF(dvp); 1704 1705 /* Fudge together a funny name */ 1706 pid = cnp->cn_proc->p_pid; 1707 bcopy(".nfsAxxxx4.4", sp->s_name, 13); 1708 sp->s_namlen = 12; 1709 sp->s_name[8] = hextoasc[pid & 0xf]; 1710 sp->s_name[7] = hextoasc[(pid >> 4) & 0xf]; 1711 sp->s_name[6] = hextoasc[(pid >> 8) & 0xf]; 1712 sp->s_name[5] = hextoasc[(pid >> 12) & 0xf]; 1713 1714 /* Try lookitups until we get one that isn't there */ 1715 while (nfs_lookitup(sp, (nfsv2fh_t *)0, cnp->cn_proc) == 0) { 1716 sp->s_name[4]++; 1717 if (sp->s_name[4] > 'z') { 1718 error = EINVAL; 1719 goto bad; 1720 } 1721 } 1722 if (error = nfs_renameit(dvp, cnp, sp)) 1723 goto bad; 1724 nfs_lookitup(sp, &np->n_fh, cnp->cn_proc); 1725 np->n_sillyrename = sp; 1726 return (0); 1727 bad: 1728 vrele(sp->s_dvp); 1729 crfree(sp->s_cred); 1730 #ifdef SILLYSEPARATE 1731 free((caddr_t)sp, M_NFSREQ); 1732 #endif 1733 return (error); 1734 } 1735 1736 /* 1737 * Look up a file name for silly rename stuff. 1738 * Just like nfs_lookup() except that it doesn't load returned values 1739 * into the nfsnode table. 1740 * If fhp != NULL it copies the returned file handle out 1741 */ 1742 int 1743 nfs_lookitup(sp, fhp, procp) 1744 register struct sillyrename *sp; 1745 nfsv2fh_t *fhp; 1746 struct proc *procp; 1747 { 1748 register struct vnode *vp = sp->s_dvp; 1749 register u_long *tl; 1750 register caddr_t cp; 1751 register long t1, t2; 1752 caddr_t bpos, dpos, cp2; 1753 u_long xid; 1754 int error = 0; 1755 struct mbuf *mreq, *mrep, *md, *mb, *mb2; 1756 long len; 1757 1758 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 1759 len = sp->s_namlen; 1760 nfsm_reqhead(vp, NFSPROC_LOOKUP, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)); 1761 nfsm_fhtom(vp); 1762 nfsm_strtom(sp->s_name, len, NFS_MAXNAMLEN); 1763 nfsm_request(vp, NFSPROC_LOOKUP, procp, sp->s_cred); 1764 if (fhp != NULL) { 1765 nfsm_dissect(cp, caddr_t, NFSX_FH); 1766 bcopy(cp, (caddr_t)fhp, NFSX_FH); 1767 } 1768 nfsm_reqdone; 1769 return (error); 1770 } 1771 1772 /* 1773 * Kludge City.. 1774 * - make nfs_bmap() essentially a no-op that does no translation 1775 * - do nfs_strategy() by faking physical I/O with nfs_readrpc/nfs_writerpc 1776 * after mapping the physical addresses into Kernel Virtual space in the 1777 * nfsiobuf area. 1778 * (Maybe I could use the process's page mapping, but I was concerned that 1779 * Kernel Write might not be enabled and also figured copyout() would do 1780 * a lot more work than bcopy() and also it currently happens in the 1781 * context of the swapper process (2). 1782 */ 1783 int 1784 nfs_bmap(ap) 1785 struct vop_bmap_args *ap; 1786 { 1787 register struct vnode *vp = ap->a_vp; 1788 1789 if (ap->a_vpp != NULL) 1790 *ap->a_vpp = vp; 1791 if (ap->a_bnp != NULL) 1792 *ap->a_bnp = ap->a_bn * btodb(vp->v_mount->mnt_stat.f_iosize); 1793 return (0); 1794 } 1795 1796 /* 1797 * Strategy routine for phys. i/o 1798 * If the biod's are running, queue a request 1799 * otherwise just call nfs_doio() to get it done 1800 */ 1801 int 1802 nfs_strategy(ap) 1803 struct vop_strategy_args *ap; 1804 { 1805 register struct buf *bp = ap->a_bp; 1806 register struct buf *dp; 1807 register int i; 1808 int error = 0; 1809 int fnd = 0; 1810 1811 /* 1812 * Set b_proc. It seems a bit silly to do it here, but since bread() 1813 * doesn't set it, I will. 1814 * Set b_proc == NULL for asynchronous ops, since these may still 1815 * be hanging about after the process terminates. 1816 */ 1817 if ((bp->b_flags & B_PHYS) == 0) { 1818 if (bp->b_flags & B_ASYNC) 1819 bp->b_proc = (struct proc *)0; 1820 else 1821 bp->b_proc = curproc; 1822 } 1823 /* 1824 * If the op is asynchronous and an i/o daemon is waiting 1825 * queue the request, wake it up and wait for completion 1826 * otherwise just do it ourselves. 1827 */ 1828 if ((bp->b_flags & B_ASYNC) == 0 || nfs_numasync == 0) 1829 return (nfs_doio(bp)); 1830 for (i = 0; i < NFS_MAXASYNCDAEMON; i++) { 1831 if (nfs_iodwant[i]) { 1832 dp = &nfs_bqueue; 1833 if (dp->b_actf == NULL) { 1834 dp->b_actl = bp; 1835 bp->b_actf = dp; 1836 } else { 1837 dp->b_actf->b_actl = bp; 1838 bp->b_actf = dp->b_actf; 1839 } 1840 dp->b_actf = bp; 1841 bp->b_actl = dp; 1842 fnd++; 1843 wakeup((caddr_t)&nfs_iodwant[i]); 1844 break; 1845 } 1846 } 1847 if (!fnd) 1848 error = nfs_doio(bp); 1849 return (error); 1850 } 1851 1852 /* 1853 * Fun and games with i/o 1854 * Essentially play ubasetup() and disk interrupt service routine by 1855 * mapping the data buffer into kernel virtual space and doing the 1856 * nfs read or write rpc's from it. 1857 * If the nfsiod's are not running, this is just called from nfs_strategy(), 1858 * otherwise it is called by the nfsiods to do what would normally be 1859 * partially disk interrupt driven. 1860 */ 1861 int 1862 nfs_doio(bp) 1863 register struct buf *bp; 1864 { 1865 register struct uio *uiop; 1866 register struct vnode *vp; 1867 struct nfsnode *np; 1868 struct ucred *cr; 1869 int error; 1870 struct uio uio; 1871 struct iovec io; 1872 1873 vp = bp->b_vp; 1874 np = VTONFS(vp); 1875 uiop = &uio; 1876 uiop->uio_iov = &io; 1877 uiop->uio_iovcnt = 1; 1878 uiop->uio_segflg = UIO_SYSSPACE; 1879 uiop->uio_procp = bp->b_proc; 1880 1881 /* 1882 * For phys i/o, map the b_addr into kernel virtual space using 1883 * the Nfsiomap pte's 1884 * Also, add a temporary b_rcred for reading using the process's uid 1885 * and a guess at a group 1886 */ 1887 if (bp->b_flags & B_PHYS) { 1888 if (bp->b_flags & B_DIRTY) 1889 uiop->uio_procp = pageproc; 1890 cr = crcopy(uiop->uio_procp->p_ucred); 1891 /* mapping was already done by vmapbuf */ 1892 io.iov_base = bp->b_un.b_addr; 1893 1894 /* 1895 * And do the i/o rpc 1896 */ 1897 io.iov_len = uiop->uio_resid = bp->b_bcount; 1898 uiop->uio_offset = bp->b_blkno * DEV_BSIZE; 1899 if (bp->b_flags & B_READ) { 1900 uiop->uio_rw = UIO_READ; 1901 nfsstats.read_physios++; 1902 bp->b_error = error = nfs_readrpc(vp, uiop, cr); 1903 (void) vnode_pager_uncache(vp); 1904 } else { 1905 uiop->uio_rw = UIO_WRITE; 1906 nfsstats.write_physios++; 1907 bp->b_error = error = nfs_writerpc(vp, uiop, cr); 1908 } 1909 1910 /* 1911 * Finally, release pte's used by physical i/o 1912 */ 1913 crfree(cr); 1914 } else { 1915 if (bp->b_flags & B_READ) { 1916 io.iov_len = uiop->uio_resid = bp->b_bcount; 1917 io.iov_base = bp->b_un.b_addr; 1918 uiop->uio_rw = UIO_READ; 1919 switch (vp->v_type) { 1920 case VREG: 1921 uiop->uio_offset = bp->b_blkno * DEV_BSIZE; 1922 nfsstats.read_bios++; 1923 error = nfs_readrpc(vp, uiop, bp->b_rcred); 1924 break; 1925 case VLNK: 1926 uiop->uio_offset = 0; 1927 nfsstats.readlink_bios++; 1928 error = nfs_readlinkrpc(vp, uiop, bp->b_rcred); 1929 break; 1930 case VDIR: 1931 uiop->uio_offset = bp->b_lblkno; 1932 nfsstats.readdir_bios++; 1933 if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_RDIRALOOK) 1934 error = nfs_readdirlookrpc(vp, uiop, bp->b_rcred); 1935 else 1936 error = nfs_readdirrpc(vp, uiop, bp->b_rcred); 1937 /* 1938 * Save offset cookie in b_blkno. 1939 */ 1940 bp->b_blkno = uiop->uio_offset; 1941 break; 1942 }; 1943 bp->b_error = error; 1944 } else { 1945 io.iov_len = uiop->uio_resid = bp->b_dirtyend 1946 - bp->b_dirtyoff; 1947 uiop->uio_offset = (bp->b_blkno * DEV_BSIZE) 1948 + bp->b_dirtyoff; 1949 io.iov_base = bp->b_un.b_addr + bp->b_dirtyoff; 1950 uiop->uio_rw = UIO_WRITE; 1951 nfsstats.write_bios++; 1952 bp->b_error = error = nfs_writerpc(vp, uiop, 1953 bp->b_wcred); 1954 if (error) { 1955 np->n_error = error; 1956 np->n_flag |= NWRITEERR; 1957 } 1958 bp->b_dirtyoff = bp->b_dirtyend = 0; 1959 } 1960 } 1961 if (error) 1962 bp->b_flags |= B_ERROR; 1963 bp->b_resid = uiop->uio_resid; 1964 biodone(bp); 1965 return (error); 1966 } 1967 1968 /* 1969 * Mmap a file 1970 * 1971 * NB Currently unsupported. 1972 */ 1973 /* ARGSUSED */ 1974 int 1975 nfs_mmap(ap) 1976 struct vop_mmap_args *ap; 1977 { 1978 1979 return (EINVAL); 1980 } 1981 1982 /* 1983 * Flush all the blocks associated with a vnode. 1984 * Walk through the buffer pool and push any dirty pages 1985 * associated with the vnode. 1986 */ 1987 /* ARGSUSED */ 1988 int 1989 nfs_fsync(ap) 1990 struct vop_fsync_args *ap; 1991 { 1992 register struct nfsnode *np = VTONFS(ap->a_vp); 1993 int error = 0; 1994 1995 if (np->n_flag & NMODIFIED) { 1996 np->n_flag &= ~NMODIFIED; 1997 vflushbuf(ap->a_vp, ap->a_waitfor == MNT_WAIT ? B_SYNC : 0); 1998 } 1999 if (np->n_flag & NWRITEERR) { 2000 error = np->n_error; 2001 np->n_flag &= ~NWRITEERR; 2002 } 2003 return (error); 2004 } 2005 2006 /* 2007 * NFS advisory byte-level locks. 2008 * Currently unsupported. 2009 */ 2010 int 2011 nfs_advlock(ap) 2012 struct vop_advlock_args *ap; 2013 { 2014 2015 return (EOPNOTSUPP); 2016 } 2017 2018 /* 2019 * Print out the contents of an nfsnode. 2020 */ 2021 int 2022 nfs_print(ap) 2023 struct vop_print_args *ap; 2024 { 2025 register struct vnode *vp = ap->a_vp; 2026 register struct nfsnode *np = VTONFS(vp); 2027 2028 printf("tag VT_NFS, fileid %d fsid 0x%x", 2029 np->n_vattr.va_fileid, np->n_vattr.va_fsid); 2030 #ifdef FIFO 2031 if (vp->v_type == VFIFO) 2032 fifo_printinfo(vp); 2033 #endif /* FIFO */ 2034 printf("\n"); 2035 } 2036 2037 /* 2038 * NFS directory offset lookup. 2039 * Currently unsupported. 2040 */ 2041 int 2042 nfs_blkatoff(ap) 2043 struct vop_blkatoff_args *ap; 2044 { 2045 2046 return (EOPNOTSUPP); 2047 } 2048 2049 /* 2050 * NFS flat namespace lookup. 2051 * Currently unsupported. 2052 */ 2053 int 2054 nfs_vget(ap) 2055 struct vop_vget_args *ap; 2056 { 2057 2058 return (EOPNOTSUPP); 2059 } 2060 2061 /* 2062 * NFS flat namespace allocation. 2063 * Currently unsupported. 2064 */ 2065 int 2066 nfs_valloc(ap) 2067 struct vop_valloc_args *ap; 2068 { 2069 2070 return (EOPNOTSUPP); 2071 } 2072 2073 /* 2074 * NFS flat namespace free. 2075 * Currently unsupported. 2076 */ 2077 int 2078 nfs_vfree(ap) 2079 struct vop_vfree_args *ap; 2080 { 2081 2082 return (EOPNOTSUPP); 2083 } 2084 2085 /* 2086 * NFS file truncation. 2087 */ 2088 int 2089 nfs_truncate(ap) 2090 struct vop_truncate_args *ap; 2091 { 2092 2093 /* Use nfs_setattr */ 2094 printf("nfs_truncate: need to implement!!"); 2095 return (EOPNOTSUPP); 2096 } 2097 2098 /* 2099 * NFS update. 2100 */ 2101 int 2102 nfs_update(ap) 2103 struct vop_update_args *ap; 2104 { 2105 2106 /* Use nfs_setattr */ 2107 printf("nfs_update: need to implement!!"); 2108 return (EOPNOTSUPP); 2109 } 2110 2111 /* 2112 * Read wrapper for special devices. 2113 */ 2114 int 2115 nfsspec_read(ap) 2116 struct vop_read_args *ap; 2117 { 2118 extern int (**spec_vnodeop_p)(); 2119 register struct nfsnode *np = VTONFS(ap->a_vp); 2120 2121 /* 2122 * Set access flag. 2123 */ 2124 np->n_flag |= NACC; 2125 np->n_atim = time; 2126 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap)); 2127 } 2128 2129 /* 2130 * Write wrapper for special devices. 2131 */ 2132 int 2133 nfsspec_write(ap) 2134 struct vop_write_args *ap; 2135 { 2136 extern int (**spec_vnodeop_p)(); 2137 register struct nfsnode *np = VTONFS(ap->a_vp); 2138 2139 /* 2140 * Set update flag. 2141 */ 2142 np->n_flag |= NUPD; 2143 np->n_mtim = time; 2144 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap)); 2145 } 2146 2147 /* 2148 * Close wrapper for special devices. 2149 * 2150 * Update the times on the nfsnode then do device close. 2151 */ 2152 int 2153 nfsspec_close(ap) 2154 struct vop_close_args *ap; 2155 { 2156 USES_VOP_SETATTR; 2157 register struct vnode *vp = ap->a_vp; 2158 register struct nfsnode *np = VTONFS(vp); 2159 struct vattr vattr; 2160 extern int (**spec_vnodeop_p)(); 2161 2162 if (np->n_flag & (NACC | NUPD)) { 2163 if (np->n_flag & NACC) 2164 np->n_atim = time; 2165 if (np->n_flag & NUPD) 2166 np->n_mtim = time; 2167 np->n_flag |= NCHG; 2168 if (vp->v_usecount == 1 && 2169 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 2170 VATTR_NULL(&vattr); 2171 if (np->n_flag & NACC) { 2172 vattr.va_atime.ts_sec = np->n_atim.tv_sec; 2173 vattr.va_atime.ts_nsec = 2174 np->n_atim.tv_usec * 1000; 2175 } 2176 if (np->n_flag & NUPD) { 2177 vattr.va_mtime.ts_sec = np->n_mtim.tv_sec; 2178 vattr.va_mtime.ts_nsec = 2179 np->n_mtim.tv_usec * 1000; 2180 } 2181 (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_p); 2182 } 2183 } 2184 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap)); 2185 } 2186 2187 #ifdef FIFO 2188 /* 2189 * Read wrapper for fifos. 2190 */ 2191 int 2192 nfsfifo_read(ap) 2193 struct vop_read_args *ap; 2194 { 2195 extern int (**fifo_vnodeop_p)(); 2196 register struct nfsnode *np = VTONFS(ap->a_vp); 2197 2198 /* 2199 * Set access flag. 2200 */ 2201 np->n_flag |= NACC; 2202 np->n_atim = time; 2203 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap)); 2204 } 2205 2206 /* 2207 * Write wrapper for fifos. 2208 */ 2209 int 2210 nfsfifo_write(ap) 2211 struct vop_write_args *ap; 2212 { 2213 extern int (**fifo_vnodeop_p)(); 2214 register struct nfsnode *np = VTONFS(ap->a_vp); 2215 2216 /* 2217 * Set update flag. 2218 */ 2219 np->n_flag |= NUPD; 2220 np->n_mtim = time; 2221 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap)); 2222 } 2223 2224 /* 2225 * Close wrapper for fifos. 2226 * 2227 * Update the times on the nfsnode then do fifo close. 2228 */ 2229 int 2230 nfsfifo_close(ap) 2231 struct vop_close_args *ap; 2232 { 2233 USES_VOP_SETATTR; 2234 register struct vnode *vp = ap->a_vp; 2235 register struct nfsnode *np = VTONFS(vp); 2236 struct vattr vattr; 2237 extern int (**fifo_vnodeop_p)(); 2238 2239 if (np->n_flag & (NACC | NUPD)) { 2240 if (np->n_flag & NACC) 2241 np->n_atim = time; 2242 if (np->n_flag & NUPD) 2243 np->n_mtim = time; 2244 np->n_flag |= NCHG; 2245 if (vp->v_usecount == 1 && 2246 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 2247 VATTR_NULL(&vattr); 2248 if (np->n_flag & NACC) { 2249 vattr.va_atime.ts_sec = np->n_atim.tv_sec; 2250 vattr.va_atime.ts_nsec = 2251 np->n_atim.tv_usec * 1000; 2252 } 2253 if (np->n_flag & NUPD) { 2254 vattr.va_mtime.ts_sec = np->n_mtim.tv_sec; 2255 vattr.va_mtime.ts_nsec = 2256 np->n_mtim.tv_usec * 1000; 2257 } 2258 (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_p); 2259 } 2260 } 2261 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap)); 2262 } 2263 #endif /* FIFO */ 2264