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