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