1 /* $NetBSD: nfs_vnops.c,v 1.184 2003/12/07 21:15:47 fvdl Exp $ */ 2 3 /* 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Rick Macklem at The University of Guelph. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)nfs_vnops.c 8.19 (Berkeley) 7/31/95 35 */ 36 37 /* 38 * vnode op calls for Sun NFS version 2 and 3 39 */ 40 41 #include <sys/cdefs.h> 42 __KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.184 2003/12/07 21:15:47 fvdl Exp $"); 43 44 #include "opt_nfs.h" 45 #include "opt_uvmhist.h" 46 47 #include <sys/param.h> 48 #include <sys/proc.h> 49 #include <sys/kernel.h> 50 #include <sys/systm.h> 51 #include <sys/resourcevar.h> 52 #include <sys/proc.h> 53 #include <sys/mount.h> 54 #include <sys/buf.h> 55 #include <sys/malloc.h> 56 #include <sys/mbuf.h> 57 #include <sys/namei.h> 58 #include <sys/vnode.h> 59 #include <sys/dirent.h> 60 #include <sys/fcntl.h> 61 #include <sys/hash.h> 62 #include <sys/lockf.h> 63 #include <sys/stat.h> 64 #include <sys/unistd.h> 65 66 #include <uvm/uvm_extern.h> 67 #include <uvm/uvm.h> 68 69 #include <miscfs/fifofs/fifo.h> 70 #include <miscfs/genfs/genfs.h> 71 #include <miscfs/specfs/specdev.h> 72 73 #include <nfs/rpcv2.h> 74 #include <nfs/nfsproto.h> 75 #include <nfs/nfs.h> 76 #include <nfs/nfsnode.h> 77 #include <nfs/nfsmount.h> 78 #include <nfs/xdr_subs.h> 79 #include <nfs/nfsm_subs.h> 80 #include <nfs/nqnfs.h> 81 #include <nfs/nfs_var.h> 82 83 #include <net/if.h> 84 #include <netinet/in.h> 85 #include <netinet/in_var.h> 86 87 /* 88 * Global vfs data structures for nfs 89 */ 90 int (**nfsv2_vnodeop_p) __P((void *)); 91 const struct vnodeopv_entry_desc nfsv2_vnodeop_entries[] = { 92 { &vop_default_desc, vn_default_error }, 93 { &vop_lookup_desc, nfs_lookup }, /* lookup */ 94 { &vop_create_desc, nfs_create }, /* create */ 95 { &vop_mknod_desc, nfs_mknod }, /* mknod */ 96 { &vop_open_desc, nfs_open }, /* open */ 97 { &vop_close_desc, nfs_close }, /* close */ 98 { &vop_access_desc, nfs_access }, /* access */ 99 { &vop_getattr_desc, nfs_getattr }, /* getattr */ 100 { &vop_setattr_desc, nfs_setattr }, /* setattr */ 101 { &vop_read_desc, nfs_read }, /* read */ 102 { &vop_write_desc, nfs_write }, /* write */ 103 { &vop_lease_desc, nfs_lease_check }, /* lease */ 104 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ 105 { &vop_ioctl_desc, nfs_ioctl }, /* ioctl */ 106 { &vop_poll_desc, nfs_poll }, /* poll */ 107 { &vop_kqfilter_desc, nfs_kqfilter }, /* kqfilter */ 108 { &vop_revoke_desc, nfs_revoke }, /* revoke */ 109 { &vop_mmap_desc, nfs_mmap }, /* mmap */ 110 { &vop_fsync_desc, nfs_fsync }, /* fsync */ 111 { &vop_seek_desc, nfs_seek }, /* seek */ 112 { &vop_remove_desc, nfs_remove }, /* remove */ 113 { &vop_link_desc, nfs_link }, /* link */ 114 { &vop_rename_desc, nfs_rename }, /* rename */ 115 { &vop_mkdir_desc, nfs_mkdir }, /* mkdir */ 116 { &vop_rmdir_desc, nfs_rmdir }, /* rmdir */ 117 { &vop_symlink_desc, nfs_symlink }, /* symlink */ 118 { &vop_readdir_desc, nfs_readdir }, /* readdir */ 119 { &vop_readlink_desc, nfs_readlink }, /* readlink */ 120 { &vop_abortop_desc, nfs_abortop }, /* abortop */ 121 { &vop_inactive_desc, nfs_inactive }, /* inactive */ 122 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */ 123 { &vop_lock_desc, nfs_lock }, /* lock */ 124 { &vop_unlock_desc, nfs_unlock }, /* unlock */ 125 { &vop_bmap_desc, nfs_bmap }, /* bmap */ 126 { &vop_strategy_desc, nfs_strategy }, /* strategy */ 127 { &vop_print_desc, nfs_print }, /* print */ 128 { &vop_islocked_desc, nfs_islocked }, /* islocked */ 129 { &vop_pathconf_desc, nfs_pathconf }, /* pathconf */ 130 { &vop_advlock_desc, nfs_advlock }, /* advlock */ 131 { &vop_blkatoff_desc, nfs_blkatoff }, /* blkatoff */ 132 { &vop_valloc_desc, nfs_valloc }, /* valloc */ 133 { &vop_reallocblks_desc, nfs_reallocblks }, /* reallocblks */ 134 { &vop_vfree_desc, nfs_vfree }, /* vfree */ 135 { &vop_truncate_desc, nfs_truncate }, /* truncate */ 136 { &vop_update_desc, nfs_update }, /* update */ 137 { &vop_bwrite_desc, nfs_bwrite }, /* bwrite */ 138 { &vop_getpages_desc, nfs_getpages }, /* getpages */ 139 { &vop_putpages_desc, genfs_putpages }, /* putpages */ 140 { NULL, NULL } 141 }; 142 const struct vnodeopv_desc nfsv2_vnodeop_opv_desc = 143 { &nfsv2_vnodeop_p, nfsv2_vnodeop_entries }; 144 145 /* 146 * Special device vnode ops 147 */ 148 int (**spec_nfsv2nodeop_p) __P((void *)); 149 const struct vnodeopv_entry_desc spec_nfsv2nodeop_entries[] = { 150 { &vop_default_desc, vn_default_error }, 151 { &vop_lookup_desc, spec_lookup }, /* lookup */ 152 { &vop_create_desc, spec_create }, /* create */ 153 { &vop_mknod_desc, spec_mknod }, /* mknod */ 154 { &vop_open_desc, spec_open }, /* open */ 155 { &vop_close_desc, nfsspec_close }, /* close */ 156 { &vop_access_desc, nfsspec_access }, /* access */ 157 { &vop_getattr_desc, nfs_getattr }, /* getattr */ 158 { &vop_setattr_desc, nfs_setattr }, /* setattr */ 159 { &vop_read_desc, nfsspec_read }, /* read */ 160 { &vop_write_desc, nfsspec_write }, /* write */ 161 { &vop_lease_desc, spec_lease_check }, /* lease */ 162 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ 163 { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 164 { &vop_poll_desc, spec_poll }, /* poll */ 165 { &vop_kqfilter_desc, spec_kqfilter }, /* kqfilter */ 166 { &vop_revoke_desc, spec_revoke }, /* revoke */ 167 { &vop_mmap_desc, spec_mmap }, /* mmap */ 168 { &vop_fsync_desc, spec_fsync }, /* fsync */ 169 { &vop_seek_desc, spec_seek }, /* seek */ 170 { &vop_remove_desc, spec_remove }, /* remove */ 171 { &vop_link_desc, spec_link }, /* link */ 172 { &vop_rename_desc, spec_rename }, /* rename */ 173 { &vop_mkdir_desc, spec_mkdir }, /* mkdir */ 174 { &vop_rmdir_desc, spec_rmdir }, /* rmdir */ 175 { &vop_symlink_desc, spec_symlink }, /* symlink */ 176 { &vop_readdir_desc, spec_readdir }, /* readdir */ 177 { &vop_readlink_desc, spec_readlink }, /* readlink */ 178 { &vop_abortop_desc, spec_abortop }, /* abortop */ 179 { &vop_inactive_desc, nfs_inactive }, /* inactive */ 180 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */ 181 { &vop_lock_desc, nfs_lock }, /* lock */ 182 { &vop_unlock_desc, nfs_unlock }, /* unlock */ 183 { &vop_bmap_desc, spec_bmap }, /* bmap */ 184 { &vop_strategy_desc, spec_strategy }, /* strategy */ 185 { &vop_print_desc, nfs_print }, /* print */ 186 { &vop_islocked_desc, nfs_islocked }, /* islocked */ 187 { &vop_pathconf_desc, spec_pathconf }, /* pathconf */ 188 { &vop_advlock_desc, spec_advlock }, /* advlock */ 189 { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ 190 { &vop_valloc_desc, spec_valloc }, /* valloc */ 191 { &vop_reallocblks_desc, spec_reallocblks }, /* reallocblks */ 192 { &vop_vfree_desc, spec_vfree }, /* vfree */ 193 { &vop_truncate_desc, spec_truncate }, /* truncate */ 194 { &vop_update_desc, nfs_update }, /* update */ 195 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 196 { &vop_getpages_desc, spec_getpages }, /* getpages */ 197 { &vop_putpages_desc, spec_putpages }, /* putpages */ 198 { NULL, NULL } 199 }; 200 const struct vnodeopv_desc spec_nfsv2nodeop_opv_desc = 201 { &spec_nfsv2nodeop_p, spec_nfsv2nodeop_entries }; 202 203 int (**fifo_nfsv2nodeop_p) __P((void *)); 204 const struct vnodeopv_entry_desc fifo_nfsv2nodeop_entries[] = { 205 { &vop_default_desc, vn_default_error }, 206 { &vop_lookup_desc, fifo_lookup }, /* lookup */ 207 { &vop_create_desc, fifo_create }, /* create */ 208 { &vop_mknod_desc, fifo_mknod }, /* mknod */ 209 { &vop_open_desc, fifo_open }, /* open */ 210 { &vop_close_desc, nfsfifo_close }, /* close */ 211 { &vop_access_desc, nfsspec_access }, /* access */ 212 { &vop_getattr_desc, nfs_getattr }, /* getattr */ 213 { &vop_setattr_desc, nfs_setattr }, /* setattr */ 214 { &vop_read_desc, nfsfifo_read }, /* read */ 215 { &vop_write_desc, nfsfifo_write }, /* write */ 216 { &vop_lease_desc, fifo_lease_check }, /* lease */ 217 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ 218 { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ 219 { &vop_poll_desc, fifo_poll }, /* poll */ 220 { &vop_kqfilter_desc, fifo_kqfilter }, /* kqfilter */ 221 { &vop_revoke_desc, fifo_revoke }, /* revoke */ 222 { &vop_mmap_desc, fifo_mmap }, /* mmap */ 223 { &vop_fsync_desc, nfs_fsync }, /* fsync */ 224 { &vop_seek_desc, fifo_seek }, /* seek */ 225 { &vop_remove_desc, fifo_remove }, /* remove */ 226 { &vop_link_desc, fifo_link }, /* link */ 227 { &vop_rename_desc, fifo_rename }, /* rename */ 228 { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */ 229 { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */ 230 { &vop_symlink_desc, fifo_symlink }, /* symlink */ 231 { &vop_readdir_desc, fifo_readdir }, /* readdir */ 232 { &vop_readlink_desc, fifo_readlink }, /* readlink */ 233 { &vop_abortop_desc, fifo_abortop }, /* abortop */ 234 { &vop_inactive_desc, nfs_inactive }, /* inactive */ 235 { &vop_reclaim_desc, nfs_reclaim }, /* reclaim */ 236 { &vop_lock_desc, nfs_lock }, /* lock */ 237 { &vop_unlock_desc, nfs_unlock }, /* unlock */ 238 { &vop_bmap_desc, fifo_bmap }, /* bmap */ 239 { &vop_strategy_desc, genfs_badop }, /* strategy */ 240 { &vop_print_desc, nfs_print }, /* print */ 241 { &vop_islocked_desc, nfs_islocked }, /* islocked */ 242 { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */ 243 { &vop_advlock_desc, fifo_advlock }, /* advlock */ 244 { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ 245 { &vop_valloc_desc, fifo_valloc }, /* valloc */ 246 { &vop_reallocblks_desc, fifo_reallocblks }, /* reallocblks */ 247 { &vop_vfree_desc, fifo_vfree }, /* vfree */ 248 { &vop_truncate_desc, fifo_truncate }, /* truncate */ 249 { &vop_update_desc, nfs_update }, /* update */ 250 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 251 { &vop_putpages_desc, fifo_putpages }, /* putpages */ 252 { NULL, NULL } 253 }; 254 const struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc = 255 { &fifo_nfsv2nodeop_p, fifo_nfsv2nodeop_entries }; 256 257 static void nfs_writerpc_extfree(struct mbuf *, caddr_t, size_t, void *); 258 259 /* 260 * Global variables 261 */ 262 extern u_int32_t nfs_true, nfs_false; 263 extern u_int32_t nfs_xdrneg1; 264 extern const nfstype nfsv3_type[9]; 265 266 int nfs_numasync = 0; 267 #define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1)) 268 269 /* 270 * nfs null call from vfs. 271 */ 272 int 273 nfs_null(vp, cred, procp) 274 struct vnode *vp; 275 struct ucred *cred; 276 struct proc *procp; 277 { 278 caddr_t bpos, dpos; 279 int error = 0; 280 struct mbuf *mreq, *mrep, *md, *mb; 281 struct nfsnode *np = VTONFS(vp); 282 283 nfsm_reqhead(np, NFSPROC_NULL, 0); 284 nfsm_request(np, NFSPROC_NULL, procp, cred); 285 nfsm_reqdone; 286 return (error); 287 } 288 289 /* 290 * nfs access vnode op. 291 * For nfs version 2, just return ok. File accesses may fail later. 292 * For nfs version 3, use the access rpc to check accessibility. If file modes 293 * are changed on the server, accesses might still fail later. 294 */ 295 int 296 nfs_access(v) 297 void *v; 298 { 299 struct vop_access_args /* { 300 struct vnode *a_vp; 301 int a_mode; 302 struct ucred *a_cred; 303 struct proc *a_p; 304 } */ *ap = v; 305 struct vnode *vp = ap->a_vp; 306 u_int32_t *tl; 307 caddr_t cp; 308 int32_t t1, t2; 309 caddr_t bpos, dpos, cp2; 310 int error = 0, attrflag, cachevalid; 311 struct mbuf *mreq, *mrep, *md, *mb; 312 u_int32_t mode, rmode; 313 const int v3 = NFS_ISV3(vp); 314 struct nfsnode *np = VTONFS(vp); 315 316 cachevalid = (np->n_accstamp != -1 && 317 (time.tv_sec - np->n_accstamp) < NFS_ATTRTIMEO(np) && 318 np->n_accuid == ap->a_cred->cr_uid); 319 320 /* 321 * Check access cache first. If this request has been made for this 322 * uid shortly before, use the cached result. 323 */ 324 if (cachevalid) { 325 if (!np->n_accerror) { 326 if ((np->n_accmode & ap->a_mode) == ap->a_mode) 327 return np->n_accerror; 328 } else if ((np->n_accmode & ap->a_mode) == np->n_accmode) 329 return np->n_accerror; 330 } 331 332 /* 333 * For nfs v3, do an access rpc, otherwise you are stuck emulating 334 * ufs_access() locally using the vattr. This may not be correct, 335 * since the server may apply other access criteria such as 336 * client uid-->server uid mapping that we do not know about, but 337 * this is better than just returning anything that is lying about 338 * in the cache. 339 */ 340 if (v3) { 341 nfsstats.rpccnt[NFSPROC_ACCESS]++; 342 nfsm_reqhead(np, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED); 343 nfsm_fhtom(np, v3); 344 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); 345 if (ap->a_mode & VREAD) 346 mode = NFSV3ACCESS_READ; 347 else 348 mode = 0; 349 if (vp->v_type != VDIR) { 350 if (ap->a_mode & VWRITE) 351 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND); 352 if (ap->a_mode & VEXEC) 353 mode |= NFSV3ACCESS_EXECUTE; 354 } else { 355 if (ap->a_mode & VWRITE) 356 mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND | 357 NFSV3ACCESS_DELETE); 358 if (ap->a_mode & VEXEC) 359 mode |= NFSV3ACCESS_LOOKUP; 360 } 361 *tl = txdr_unsigned(mode); 362 nfsm_request(np, NFSPROC_ACCESS, ap->a_p, ap->a_cred); 363 nfsm_postop_attr(vp, attrflag, 0); 364 if (!error) { 365 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 366 rmode = fxdr_unsigned(u_int32_t, *tl); 367 /* 368 * The NFS V3 spec does not clarify whether or not 369 * the returned access bits can be a superset of 370 * the ones requested, so... 371 */ 372 if ((rmode & mode) != mode) 373 error = EACCES; 374 } 375 nfsm_reqdone; 376 } else 377 return (nfsspec_access(ap)); 378 /* 379 * Disallow write attempts on filesystems mounted read-only; 380 * unless the file is a socket, fifo, or a block or character 381 * device resident on the filesystem. 382 */ 383 if (!error && (ap->a_mode & VWRITE) && 384 (vp->v_mount->mnt_flag & MNT_RDONLY)) { 385 switch (vp->v_type) { 386 case VREG: 387 case VDIR: 388 case VLNK: 389 error = EROFS; 390 default: 391 break; 392 } 393 } 394 395 if (!error || error == EACCES) { 396 /* 397 * If we got the same result as for a previous, 398 * different request, OR it in. Don't update 399 * the timestamp in that case. 400 */ 401 if (cachevalid && np->n_accstamp != -1 && 402 error == np->n_accerror) { 403 if (!error) 404 np->n_accmode |= ap->a_mode; 405 else if ((np->n_accmode & ap->a_mode) == ap->a_mode) 406 np->n_accmode = ap->a_mode; 407 } else { 408 np->n_accstamp = time.tv_sec; 409 np->n_accuid = ap->a_cred->cr_uid; 410 np->n_accmode = ap->a_mode; 411 np->n_accerror = error; 412 } 413 } 414 415 return (error); 416 } 417 418 /* 419 * nfs open vnode op 420 * Check to see if the type is ok 421 * and that deletion is not in progress. 422 * For paged in text files, you will need to flush the page cache 423 * if consistency is lost. 424 */ 425 /* ARGSUSED */ 426 int 427 nfs_open(v) 428 void *v; 429 { 430 struct vop_open_args /* { 431 struct vnode *a_vp; 432 int a_mode; 433 struct ucred *a_cred; 434 struct proc *a_p; 435 } */ *ap = v; 436 struct vnode *vp = ap->a_vp; 437 struct nfsnode *np = VTONFS(vp); 438 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 439 struct vattr vattr; 440 int error; 441 442 if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) { 443 return (EACCES); 444 } 445 446 if (ap->a_mode & FREAD) { 447 if (np->n_rcred != NULL) 448 crfree(np->n_rcred); 449 np->n_rcred = ap->a_cred; 450 crhold(np->n_rcred); 451 } 452 if (ap->a_mode & FWRITE) { 453 if (np->n_wcred != NULL) 454 crfree(np->n_wcred); 455 np->n_wcred = ap->a_cred; 456 crhold(np->n_wcred); 457 } 458 459 #ifndef NFS_V2_ONLY 460 /* 461 * Get a valid lease. If cached data is stale, flush it. 462 */ 463 if (nmp->nm_flag & NFSMNT_NQNFS) { 464 if (NQNFS_CKINVALID(vp, np, ND_READ)) { 465 do { 466 error = nqnfs_getlease(vp, ND_READ, ap->a_cred, 467 ap->a_p); 468 } while (error == NQNFS_EXPIRED); 469 if (error) 470 return (error); 471 if (np->n_lrev != np->n_brev || 472 (np->n_flag & NQNFSNONCACHE)) { 473 if ((error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, 474 ap->a_p, 1)) == EINTR) 475 return (error); 476 np->n_brev = np->n_lrev; 477 } 478 } 479 } else 480 #endif 481 { 482 if (np->n_flag & NMODIFIED) { 483 if ((error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, 484 ap->a_p, 1)) == EINTR) 485 return (error); 486 np->n_attrstamp = 0; 487 if (vp->v_type == VDIR) { 488 nfs_invaldircache(vp, 0); 489 np->n_direofoffset = 0; 490 } 491 error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p); 492 if (error) 493 return (error); 494 np->n_mtime = vattr.va_mtime; 495 } else { 496 error = VOP_GETATTR(vp, &vattr, ap->a_cred, ap->a_p); 497 if (error) 498 return (error); 499 if (timespeccmp(&np->n_mtime, &vattr.va_mtime, !=)) { 500 if (vp->v_type == VDIR) { 501 nfs_invaldircache(vp, 0); 502 np->n_direofoffset = 0; 503 } 504 if ((error = nfs_vinvalbuf(vp, V_SAVE, 505 ap->a_cred, ap->a_p, 1)) == EINTR) 506 return (error); 507 np->n_mtime = vattr.va_mtime; 508 } 509 } 510 } 511 if ((nmp->nm_flag & NFSMNT_NQNFS) == 0) 512 np->n_attrstamp = 0; /* For Open/Close consistency */ 513 return (0); 514 } 515 516 /* 517 * nfs close vnode op 518 * What an NFS client should do upon close after writing is a debatable issue. 519 * Most NFS clients push delayed writes to the server upon close, basically for 520 * two reasons: 521 * 1 - So that any write errors may be reported back to the client process 522 * doing the close system call. By far the two most likely errors are 523 * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure. 524 * 2 - To put a worst case upper bound on cache inconsistency between 525 * multiple clients for the file. 526 * There is also a consistency problem for Version 2 of the protocol w.r.t. 527 * not being able to tell if other clients are writing a file concurrently, 528 * since there is no way of knowing if the changed modify time in the reply 529 * is only due to the write for this client. 530 * (NFS Version 3 provides weak cache consistency data in the reply that 531 * should be sufficient to detect and handle this case.) 532 * 533 * The current code does the following: 534 * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers 535 * for NFS Version 3 - flush dirty buffers to the server but don't invalidate 536 * or commit them (this satisfies 1 and 2 except for the 537 * case where the server crashes after this close but 538 * before the commit RPC, which is felt to be "good 539 * enough". Changing the last argument to nfs_flush() to 540 * a 1 would force a commit operation, if it is felt a 541 * commit is necessary now. 542 * for NQNFS - do nothing now, since 2 is dealt with via leases and 543 * 1 should be dealt with via an fsync() system call for 544 * cases where write errors are important. 545 */ 546 /* ARGSUSED */ 547 int 548 nfs_close(v) 549 void *v; 550 { 551 struct vop_close_args /* { 552 struct vnodeop_desc *a_desc; 553 struct vnode *a_vp; 554 int a_fflag; 555 struct ucred *a_cred; 556 struct proc *a_p; 557 } */ *ap = v; 558 struct vnode *vp = ap->a_vp; 559 struct nfsnode *np = VTONFS(vp); 560 int error = 0; 561 UVMHIST_FUNC("nfs_close"); UVMHIST_CALLED(ubchist); 562 563 if (vp->v_type == VREG) { 564 if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS) == 0 && 565 (np->n_flag & NMODIFIED)) { 566 if (NFS_ISV3(vp)) { 567 error = nfs_flush(vp, ap->a_cred, MNT_WAIT, ap->a_p, 0); 568 np->n_flag &= ~NMODIFIED; 569 } else 570 error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 1); 571 np->n_attrstamp = 0; 572 } 573 if (np->n_flag & NWRITEERR) { 574 np->n_flag &= ~NWRITEERR; 575 error = np->n_error; 576 } 577 } 578 UVMHIST_LOG(ubchist, "returning %d", error,0,0,0); 579 return (error); 580 } 581 582 /* 583 * nfs getattr call from vfs. 584 */ 585 int 586 nfs_getattr(v) 587 void *v; 588 { 589 struct vop_getattr_args /* { 590 struct vnode *a_vp; 591 struct vattr *a_vap; 592 struct ucred *a_cred; 593 struct proc *a_p; 594 } */ *ap = v; 595 struct vnode *vp = ap->a_vp; 596 struct nfsnode *np = VTONFS(vp); 597 caddr_t cp; 598 u_int32_t *tl; 599 int32_t t1, t2; 600 caddr_t bpos, dpos; 601 int error = 0; 602 struct mbuf *mreq, *mrep, *md, *mb; 603 const int v3 = NFS_ISV3(vp); 604 605 /* 606 * Update local times for special files. 607 */ 608 if (np->n_flag & (NACC | NUPD)) 609 np->n_flag |= NCHG; 610 611 /* 612 * if we have delayed truncation, do it now. 613 */ 614 nfs_delayedtruncate(vp); 615 616 /* 617 * First look in the cache. 618 */ 619 if (nfs_getattrcache(vp, ap->a_vap) == 0) 620 return (0); 621 nfsstats.rpccnt[NFSPROC_GETATTR]++; 622 nfsm_reqhead(np, NFSPROC_GETATTR, NFSX_FH(v3)); 623 nfsm_fhtom(np, v3); 624 nfsm_request(np, NFSPROC_GETATTR, ap->a_p, ap->a_cred); 625 if (!error) { 626 nfsm_loadattr(vp, ap->a_vap, 0); 627 if (vp->v_type == VDIR && 628 ap->a_vap->va_blocksize < NFS_DIRFRAGSIZ) 629 ap->a_vap->va_blocksize = NFS_DIRFRAGSIZ; 630 } 631 nfsm_reqdone; 632 return (error); 633 } 634 635 /* 636 * nfs setattr call. 637 */ 638 int 639 nfs_setattr(v) 640 void *v; 641 { 642 struct vop_setattr_args /* { 643 struct vnodeop_desc *a_desc; 644 struct vnode *a_vp; 645 struct vattr *a_vap; 646 struct ucred *a_cred; 647 struct proc *a_p; 648 } */ *ap = v; 649 struct vnode *vp = ap->a_vp; 650 struct nfsnode *np = VTONFS(vp); 651 struct vattr *vap = ap->a_vap; 652 int error = 0; 653 u_quad_t tsize = 0; 654 655 /* 656 * Setting of flags is not supported. 657 */ 658 if (vap->va_flags != VNOVAL) 659 return (EOPNOTSUPP); 660 661 /* 662 * Disallow write attempts if the filesystem is mounted read-only. 663 */ 664 if ((vap->va_uid != (uid_t)VNOVAL || 665 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || 666 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) && 667 (vp->v_mount->mnt_flag & MNT_RDONLY)) 668 return (EROFS); 669 if (vap->va_size != VNOVAL) { 670 switch (vp->v_type) { 671 case VDIR: 672 return (EISDIR); 673 case VCHR: 674 case VBLK: 675 case VSOCK: 676 case VFIFO: 677 if (vap->va_mtime.tv_sec == VNOVAL && 678 vap->va_atime.tv_sec == VNOVAL && 679 vap->va_mode == (mode_t)VNOVAL && 680 vap->va_uid == (uid_t)VNOVAL && 681 vap->va_gid == (gid_t)VNOVAL) 682 return (0); 683 vap->va_size = VNOVAL; 684 break; 685 default: 686 /* 687 * Disallow write attempts if the filesystem is 688 * mounted read-only. 689 */ 690 if (vp->v_mount->mnt_flag & MNT_RDONLY) 691 return (EROFS); 692 uvm_vnp_setsize(vp, vap->va_size); 693 tsize = np->n_size; 694 np->n_size = vap->va_size; 695 if (vap->va_size == 0) 696 error = nfs_vinvalbuf(vp, 0, 697 ap->a_cred, ap->a_p, 1); 698 else 699 error = nfs_vinvalbuf(vp, V_SAVE, 700 ap->a_cred, ap->a_p, 1); 701 if (error) { 702 uvm_vnp_setsize(vp, tsize); 703 return (error); 704 } 705 np->n_vattr->va_size = vap->va_size; 706 } 707 } else if ((vap->va_mtime.tv_sec != VNOVAL || 708 vap->va_atime.tv_sec != VNOVAL) && 709 vp->v_type == VREG && 710 (error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, 711 ap->a_p, 1)) == EINTR) 712 return (error); 713 error = nfs_setattrrpc(vp, vap, ap->a_cred, ap->a_p); 714 if (error && vap->va_size != VNOVAL) { 715 np->n_size = np->n_vattr->va_size = tsize; 716 uvm_vnp_setsize(vp, np->n_size); 717 } 718 VN_KNOTE(vp, NOTE_ATTRIB); 719 return (error); 720 } 721 722 /* 723 * Do an nfs setattr rpc. 724 */ 725 int 726 nfs_setattrrpc(vp, vap, cred, procp) 727 struct vnode *vp; 728 struct vattr *vap; 729 struct ucred *cred; 730 struct proc *procp; 731 { 732 struct nfsv2_sattr *sp; 733 caddr_t cp; 734 int32_t t1, t2; 735 caddr_t bpos, dpos, cp2; 736 u_int32_t *tl; 737 int error = 0, wccflag = NFSV3_WCCRATTR; 738 struct mbuf *mreq, *mrep, *md, *mb; 739 const int v3 = NFS_ISV3(vp); 740 struct nfsnode *np = VTONFS(vp); 741 742 nfsstats.rpccnt[NFSPROC_SETATTR]++; 743 nfsm_reqhead(np, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3)); 744 nfsm_fhtom(np, v3); 745 if (v3) { 746 nfsm_v3attrbuild(vap, TRUE); 747 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); 748 *tl = nfs_false; 749 } else { 750 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); 751 if (vap->va_mode == (mode_t)VNOVAL) 752 sp->sa_mode = nfs_xdrneg1; 753 else 754 sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode); 755 if (vap->va_uid == (uid_t)VNOVAL) 756 sp->sa_uid = nfs_xdrneg1; 757 else 758 sp->sa_uid = txdr_unsigned(vap->va_uid); 759 if (vap->va_gid == (gid_t)VNOVAL) 760 sp->sa_gid = nfs_xdrneg1; 761 else 762 sp->sa_gid = txdr_unsigned(vap->va_gid); 763 sp->sa_size = txdr_unsigned(vap->va_size); 764 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 765 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 766 } 767 nfsm_request(np, NFSPROC_SETATTR, procp, cred); 768 if (v3) { 769 nfsm_wcc_data(vp, wccflag, 0); 770 } else 771 nfsm_loadattr(vp, (struct vattr *)0, 0); 772 nfsm_reqdone; 773 return (error); 774 } 775 776 /* 777 * nfs lookup call, one step at a time... 778 * First look in cache 779 * If not found, unlock the directory nfsnode and do the rpc 780 * 781 * This code is full of lock/unlock statements and checks, because 782 * we continue after cache_lookup has finished (we need to check 783 * with the attr cache and do an rpc if it has timed out). This means 784 * that the locking effects of cache_lookup have to be taken into 785 * account. 786 */ 787 int 788 nfs_lookup(v) 789 void *v; 790 { 791 struct vop_lookup_args /* { 792 struct vnodeop_desc *a_desc; 793 struct vnode *a_dvp; 794 struct vnode **a_vpp; 795 struct componentname *a_cnp; 796 } */ *ap = v; 797 struct componentname *cnp = ap->a_cnp; 798 struct vnode *dvp = ap->a_dvp; 799 struct vnode **vpp = ap->a_vpp; 800 int flags; 801 struct vnode *newvp; 802 u_int32_t *tl; 803 caddr_t cp; 804 int32_t t1, t2; 805 caddr_t bpos, dpos, cp2; 806 struct mbuf *mreq, *mrep, *md, *mb; 807 long len; 808 nfsfh_t *fhp; 809 struct nfsnode *np; 810 int lockparent, wantparent, error = 0, attrflag, fhsize; 811 const int v3 = NFS_ISV3(dvp); 812 813 cnp->cn_flags &= ~PDIRUNLOCK; 814 flags = cnp->cn_flags; 815 816 *vpp = NULLVP; 817 newvp = NULLVP; 818 if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && 819 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) 820 return (EROFS); 821 if (dvp->v_type != VDIR) 822 return (ENOTDIR); 823 824 lockparent = flags & LOCKPARENT; 825 wantparent = flags & (LOCKPARENT|WANTPARENT); 826 np = VTONFS(dvp); 827 828 /* 829 * Before tediously performing a linear scan of the directory, 830 * check the name cache to see if the directory/name pair 831 * we are looking for is known already. 832 * If the directory/name pair is found in the name cache, 833 * we have to ensure the directory has not changed from 834 * the time the cache entry has been created. If it has, 835 * the cache entry has to be ignored. 836 */ 837 if ((error = cache_lookup(dvp, vpp, cnp)) >= 0) { 838 struct vattr vattr; 839 int err2; 840 841 if (error && error != ENOENT) { 842 *vpp = NULLVP; 843 return error; 844 } 845 846 if (cnp->cn_flags & PDIRUNLOCK) { 847 err2 = vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 848 if (err2 != 0) { 849 *vpp = NULLVP; 850 return err2; 851 } 852 cnp->cn_flags &= ~PDIRUNLOCK; 853 } 854 855 err2 = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, cnp->cn_proc); 856 if (err2 != 0) { 857 if (error == 0) { 858 if (*vpp != dvp) 859 vput(*vpp); 860 else 861 vrele(*vpp); 862 } 863 *vpp = NULLVP; 864 return err2; 865 } 866 867 if (error == ENOENT) { 868 if (!VOP_GETATTR(dvp, &vattr, cnp->cn_cred, 869 cnp->cn_proc) && timespeccmp(&vattr.va_mtime, 870 &VTONFS(dvp)->n_nctime, ==)) 871 return ENOENT; 872 cache_purge(dvp); 873 timespecclear(&np->n_nctime); 874 goto dorpc; 875 } 876 877 newvp = *vpp; 878 if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred, cnp->cn_proc) 879 && vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime) 880 { 881 nfsstats.lookupcache_hits++; 882 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) 883 cnp->cn_flags |= SAVENAME; 884 if ((!lockparent || !(flags & ISLASTCN)) && 885 newvp != dvp) 886 VOP_UNLOCK(dvp, 0); 887 return (0); 888 } 889 cache_purge(newvp); 890 if (newvp != dvp) 891 vput(newvp); 892 else 893 vrele(newvp); 894 *vpp = NULLVP; 895 } 896 dorpc: 897 error = 0; 898 newvp = NULLVP; 899 nfsstats.lookupcache_misses++; 900 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 901 len = cnp->cn_namelen; 902 nfsm_reqhead(np, NFSPROC_LOOKUP, 903 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); 904 nfsm_fhtom(np, v3); 905 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 906 nfsm_request(np, NFSPROC_LOOKUP, cnp->cn_proc, cnp->cn_cred); 907 if (error) { 908 nfsm_postop_attr(dvp, attrflag, 0); 909 m_freem(mrep); 910 goto nfsmout; 911 } 912 nfsm_getfh(fhp, fhsize, v3); 913 914 /* 915 * Handle RENAME case... 916 */ 917 if (cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN)) { 918 if (NFS_CMPFH(np, fhp, fhsize)) { 919 m_freem(mrep); 920 return (EISDIR); 921 } 922 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); 923 if (error) { 924 m_freem(mrep); 925 return error; 926 } 927 newvp = NFSTOV(np); 928 if (v3) { 929 nfsm_postop_attr(newvp, attrflag, 0); 930 nfsm_postop_attr(dvp, attrflag, 0); 931 } else 932 nfsm_loadattr(newvp, (struct vattr *)0, 0); 933 *vpp = newvp; 934 m_freem(mrep); 935 cnp->cn_flags |= SAVENAME; 936 if (!lockparent) { 937 VOP_UNLOCK(dvp, 0); 938 cnp->cn_flags |= PDIRUNLOCK; 939 } 940 return (0); 941 } 942 943 /* 944 * The postop attr handling is duplicated for each if case, 945 * because it should be done while dvp is locked (unlocking 946 * dvp is different for each case). 947 */ 948 949 if (NFS_CMPFH(np, fhp, fhsize)) { 950 /* 951 * "." lookup 952 */ 953 VREF(dvp); 954 newvp = dvp; 955 if (v3) { 956 nfsm_postop_attr(newvp, attrflag, 0); 957 nfsm_postop_attr(dvp, attrflag, 0); 958 } else 959 nfsm_loadattr(newvp, (struct vattr *)0, 0); 960 } else if (flags & ISDOTDOT) { 961 /* 962 * ".." lookup 963 */ 964 VOP_UNLOCK(dvp, 0); 965 cnp->cn_flags |= PDIRUNLOCK; 966 967 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); 968 if (error) { 969 if (vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY) == 0) 970 cnp->cn_flags &= ~PDIRUNLOCK; 971 m_freem(mrep); 972 return error; 973 } 974 newvp = NFSTOV(np); 975 976 if (v3) { 977 nfsm_postop_attr(newvp, attrflag, 0); 978 nfsm_postop_attr(dvp, attrflag, 0); 979 } else 980 nfsm_loadattr(newvp, (struct vattr *)0, 0); 981 982 if (lockparent && (flags & ISLASTCN)) { 983 if ((error = vn_lock(dvp, LK_EXCLUSIVE))) { 984 m_freem(mrep); 985 vput(newvp); 986 return error; 987 } 988 cnp->cn_flags &= ~PDIRUNLOCK; 989 } 990 } else { 991 /* 992 * Other lookups. 993 */ 994 error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); 995 if (error) { 996 m_freem(mrep); 997 return error; 998 } 999 newvp = NFSTOV(np); 1000 if (v3) { 1001 nfsm_postop_attr(newvp, attrflag, 0); 1002 nfsm_postop_attr(dvp, attrflag, 0); 1003 } else 1004 nfsm_loadattr(newvp, (struct vattr *)0, 0); 1005 if (!lockparent || !(flags & ISLASTCN)) { 1006 VOP_UNLOCK(dvp, 0); 1007 cnp->cn_flags |= PDIRUNLOCK; 1008 } 1009 } 1010 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) 1011 cnp->cn_flags |= SAVENAME; 1012 if ((cnp->cn_flags & MAKEENTRY) && 1013 (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) { 1014 np->n_ctime = np->n_vattr->va_ctime.tv_sec; 1015 cache_enter(dvp, newvp, cnp); 1016 } 1017 *vpp = newvp; 1018 nfsm_reqdone; 1019 if (error) { 1020 /* 1021 * We get here only because of errors returned by 1022 * the RPC. Otherwise we'll have returned above 1023 * (the nfsm_* macros will jump to nfsm_reqdone 1024 * on error). 1025 */ 1026 if (error == ENOENT && (cnp->cn_flags & MAKEENTRY) && 1027 cnp->cn_nameiop != CREATE) { 1028 if (!timespecisset(&VTONFS(dvp)->n_nctime)) 1029 VTONFS(dvp)->n_nctime = 1030 VTONFS(dvp)->n_vattr->va_mtime; 1031 1032 cache_enter(dvp, NULL, cnp); 1033 } 1034 if (newvp != NULLVP) { 1035 vrele(newvp); 1036 if (newvp != dvp) 1037 VOP_UNLOCK(newvp, 0); 1038 } 1039 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && 1040 (flags & ISLASTCN) && error == ENOENT) { 1041 if (dvp->v_mount->mnt_flag & MNT_RDONLY) 1042 error = EROFS; 1043 else 1044 error = EJUSTRETURN; 1045 } 1046 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) 1047 cnp->cn_flags |= SAVENAME; 1048 *vpp = NULL; 1049 } 1050 1051 return error; 1052 } 1053 1054 /* 1055 * nfs read call. 1056 * Just call nfs_bioread() to do the work. 1057 */ 1058 int 1059 nfs_read(v) 1060 void *v; 1061 { 1062 struct vop_read_args /* { 1063 struct vnode *a_vp; 1064 struct uio *a_uio; 1065 int a_ioflag; 1066 struct ucred *a_cred; 1067 } */ *ap = v; 1068 struct vnode *vp = ap->a_vp; 1069 1070 if (vp->v_type != VREG) 1071 return (EPERM); 1072 return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred, 0)); 1073 } 1074 1075 /* 1076 * nfs readlink call 1077 */ 1078 int 1079 nfs_readlink(v) 1080 void *v; 1081 { 1082 struct vop_readlink_args /* { 1083 struct vnode *a_vp; 1084 struct uio *a_uio; 1085 struct ucred *a_cred; 1086 } */ *ap = v; 1087 struct vnode *vp = ap->a_vp; 1088 1089 if (vp->v_type != VLNK) 1090 return (EPERM); 1091 return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred, 0)); 1092 } 1093 1094 /* 1095 * Do a readlink rpc. 1096 * Called by nfs_doio() from below the buffer cache. 1097 */ 1098 int 1099 nfs_readlinkrpc(vp, uiop, cred) 1100 struct vnode *vp; 1101 struct uio *uiop; 1102 struct ucred *cred; 1103 { 1104 u_int32_t *tl; 1105 caddr_t cp; 1106 int32_t t1, t2; 1107 caddr_t bpos, dpos, cp2; 1108 int error = 0, attrflag; 1109 uint32_t len; 1110 struct mbuf *mreq, *mrep, *md, *mb; 1111 const int v3 = NFS_ISV3(vp); 1112 struct nfsnode *np = VTONFS(vp); 1113 1114 nfsstats.rpccnt[NFSPROC_READLINK]++; 1115 nfsm_reqhead(np, NFSPROC_READLINK, NFSX_FH(v3)); 1116 nfsm_fhtom(np, v3); 1117 nfsm_request(np, NFSPROC_READLINK, uiop->uio_procp, cred); 1118 if (v3) 1119 nfsm_postop_attr(vp, attrflag, 0); 1120 if (!error) { 1121 if (v3) { 1122 nfsm_dissect(tl, uint32_t *, NFSX_UNSIGNED); 1123 len = fxdr_unsigned(uint32_t, *tl); 1124 if (len > MAXPATHLEN) { 1125 /* 1126 * this pathname is too long for us. 1127 */ 1128 m_freem(mrep); 1129 /* Solaris returns EINVAL. should we follow? */ 1130 error = ENAMETOOLONG; 1131 goto nfsmout; 1132 } 1133 } else { 1134 nfsm_strsiz(len, NFS_MAXPATHLEN); 1135 } 1136 nfsm_mtouio(uiop, len); 1137 } 1138 nfsm_reqdone; 1139 return (error); 1140 } 1141 1142 /* 1143 * nfs read rpc call 1144 * Ditto above 1145 */ 1146 int 1147 nfs_readrpc(vp, uiop) 1148 struct vnode *vp; 1149 struct uio *uiop; 1150 { 1151 u_int32_t *tl; 1152 caddr_t cp; 1153 int32_t t1, t2; 1154 caddr_t bpos, dpos, cp2; 1155 struct mbuf *mreq, *mrep, *md, *mb; 1156 struct nfsmount *nmp; 1157 int error = 0, len, retlen, tsiz, eof, attrflag; 1158 const int v3 = NFS_ISV3(vp); 1159 struct nfsnode *np = VTONFS(vp); 1160 1161 #ifndef nolint 1162 eof = 0; 1163 #endif 1164 nmp = VFSTONFS(vp->v_mount); 1165 tsiz = uiop->uio_resid; 1166 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) 1167 return (EFBIG); 1168 while (tsiz > 0) { 1169 nfsstats.rpccnt[NFSPROC_READ]++; 1170 len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; 1171 nfsm_reqhead(np, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3); 1172 nfsm_fhtom(np, v3); 1173 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED * 3); 1174 if (v3) { 1175 txdr_hyper(uiop->uio_offset, tl); 1176 *(tl + 2) = txdr_unsigned(len); 1177 } else { 1178 *tl++ = txdr_unsigned(uiop->uio_offset); 1179 *tl++ = txdr_unsigned(len); 1180 *tl = 0; 1181 } 1182 nfsm_request(np, NFSPROC_READ, uiop->uio_procp, np->n_rcred); 1183 if (v3) { 1184 nfsm_postop_attr(vp, attrflag, NAC_NOTRUNC); 1185 if (error) { 1186 m_freem(mrep); 1187 goto nfsmout; 1188 } 1189 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 1190 eof = fxdr_unsigned(int, *(tl + 1)); 1191 } else 1192 nfsm_loadattr(vp, (struct vattr *)0, NAC_NOTRUNC); 1193 nfsm_strsiz(retlen, nmp->nm_rsize); 1194 nfsm_mtouio(uiop, retlen); 1195 m_freem(mrep); 1196 tsiz -= retlen; 1197 if (v3) { 1198 if (eof || retlen == 0) 1199 tsiz = 0; 1200 } else if (retlen < len) 1201 tsiz = 0; 1202 } 1203 nfsmout: 1204 return (error); 1205 } 1206 1207 struct nfs_writerpc_context { 1208 struct simplelock nwc_slock; 1209 volatile int nwc_mbufcount; 1210 }; 1211 1212 /* 1213 * free mbuf used to refer protected pages while write rpc call. 1214 * called at splvm. 1215 */ 1216 static void 1217 nfs_writerpc_extfree(struct mbuf *m, caddr_t buf, size_t size, void *arg) 1218 { 1219 struct nfs_writerpc_context *ctx = arg; 1220 1221 KASSERT(m != NULL); 1222 KASSERT(ctx != NULL); 1223 pool_cache_put(&mbpool_cache, m); 1224 simple_lock(&ctx->nwc_slock); 1225 if (--ctx->nwc_mbufcount == 0) { 1226 wakeup(ctx); 1227 } 1228 simple_unlock(&ctx->nwc_slock); 1229 } 1230 1231 /* 1232 * nfs write call 1233 */ 1234 int 1235 nfs_writerpc(vp, uiop, iomode, pageprotected, stalewriteverfp) 1236 struct vnode *vp; 1237 struct uio *uiop; 1238 int *iomode; 1239 boolean_t pageprotected; 1240 boolean_t *stalewriteverfp; 1241 { 1242 u_int32_t *tl; 1243 caddr_t cp; 1244 int32_t t1, t2; 1245 caddr_t bpos, dpos, cp2; 1246 struct mbuf *mreq, *mrep, *md, *mb; 1247 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 1248 int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit; 1249 const int v3 = NFS_ISV3(vp); 1250 int committed = NFSV3WRITE_FILESYNC; 1251 struct nfsnode *np = VTONFS(vp); 1252 struct nfs_writerpc_context ctx; 1253 int s; 1254 struct lwp *l = NULL; 1255 size_t origresid; 1256 1257 simple_lock_init(&ctx.nwc_slock); 1258 ctx.nwc_mbufcount = 1; 1259 1260 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1261 panic("writerpc readonly vp %p", vp); 1262 } 1263 1264 #ifdef DIAGNOSTIC 1265 if (uiop->uio_iovcnt != 1) 1266 panic("nfs: writerpc iovcnt > 1"); 1267 #endif 1268 tsiz = uiop->uio_resid; 1269 if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) 1270 return (EFBIG); 1271 if (pageprotected) { 1272 l = curlwp; 1273 PHOLD(l); 1274 } 1275 retry: 1276 origresid = uiop->uio_resid; 1277 KASSERT(origresid == uiop->uio_iov->iov_len); 1278 while (tsiz > 0) { 1279 uint32_t datalen; /* data bytes need to be allocated in mbuf */ 1280 uint32_t backup; 1281 boolean_t stalewriteverf = FALSE; 1282 1283 nfsstats.rpccnt[NFSPROC_WRITE]++; 1284 len = min(tsiz, nmp->nm_wsize); 1285 datalen = pageprotected ? 0 : nfsm_rndup(len); 1286 nfsm_reqhead(np, NFSPROC_WRITE, 1287 NFSX_FH(v3) + 5 * NFSX_UNSIGNED + datalen); 1288 nfsm_fhtom(np, v3); 1289 if (v3) { 1290 nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED); 1291 txdr_hyper(uiop->uio_offset, tl); 1292 tl += 2; 1293 *tl++ = txdr_unsigned(len); 1294 *tl++ = txdr_unsigned(*iomode); 1295 *tl = txdr_unsigned(len); 1296 } else { 1297 u_int32_t x; 1298 1299 nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED); 1300 /* Set both "begin" and "current" to non-garbage. */ 1301 x = txdr_unsigned((u_int32_t)uiop->uio_offset); 1302 *tl++ = x; /* "begin offset" */ 1303 *tl++ = x; /* "current offset" */ 1304 x = txdr_unsigned(len); 1305 *tl++ = x; /* total to this offset */ 1306 *tl = x; /* size of this write */ 1307 1308 } 1309 if (pageprotected) { 1310 /* 1311 * since we know pages can't be modified during i/o, 1312 * no need to copy them for us. 1313 */ 1314 struct mbuf *m; 1315 struct iovec *iovp = uiop->uio_iov; 1316 1317 m = m_get(M_WAIT, MT_DATA); 1318 MCLAIM(m, &nfs_mowner); 1319 MEXTADD(m, iovp->iov_base, len, M_MBUF, 1320 nfs_writerpc_extfree, &ctx); 1321 m->m_flags |= M_EXT_ROMAP; 1322 m->m_len = len; 1323 mb->m_next = m; 1324 /* 1325 * no need to maintain mb and bpos here 1326 * because no one care them later. 1327 */ 1328 #if 0 1329 mb = m; 1330 bpos = mtod(caddr_t, mb) + mb->m_len; 1331 #endif 1332 iovp->iov_base = (char *)iovp->iov_base + len; 1333 iovp->iov_len -= len; 1334 uiop->uio_offset += len; 1335 uiop->uio_resid -= len; 1336 s = splvm(); 1337 simple_lock(&ctx.nwc_slock); 1338 ctx.nwc_mbufcount++; 1339 simple_unlock(&ctx.nwc_slock); 1340 splx(s); 1341 nfs_zeropad(mb, 0, nfsm_padlen(len)); 1342 } else { 1343 nfsm_uiotom(uiop, len); 1344 } 1345 nfsm_request(np, NFSPROC_WRITE, uiop->uio_procp, np->n_wcred); 1346 if (v3) { 1347 wccflag = NFSV3_WCCCHK; 1348 nfsm_wcc_data(vp, wccflag, NAC_NOTRUNC); 1349 if (!error) { 1350 nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED 1351 + NFSX_V3WRITEVERF); 1352 rlen = fxdr_unsigned(int, *tl++); 1353 if (rlen == 0) { 1354 error = NFSERR_IO; 1355 m_freem(mrep); 1356 break; 1357 } else if (rlen < len) { 1358 backup = len - rlen; 1359 uiop->uio_iov->iov_base = 1360 (caddr_t)uiop->uio_iov->iov_base - 1361 backup; 1362 uiop->uio_iov->iov_len += backup; 1363 uiop->uio_offset -= backup; 1364 uiop->uio_resid += backup; 1365 len = rlen; 1366 } 1367 commit = fxdr_unsigned(int, *tl++); 1368 1369 /* 1370 * Return the lowest committment level 1371 * obtained by any of the RPCs. 1372 */ 1373 if (committed == NFSV3WRITE_FILESYNC) 1374 committed = commit; 1375 else if (committed == NFSV3WRITE_DATASYNC && 1376 commit == NFSV3WRITE_UNSTABLE) 1377 committed = commit; 1378 simple_lock(&nmp->nm_slock); 1379 if ((nmp->nm_iflag & NFSMNT_HASWRITEVERF) == 0){ 1380 memcpy(nmp->nm_writeverf, tl, 1381 NFSX_V3WRITEVERF); 1382 nmp->nm_iflag |= NFSMNT_HASWRITEVERF; 1383 } else if ((nmp->nm_iflag & 1384 NFSMNT_STALEWRITEVERF) || 1385 memcmp(tl, nmp->nm_writeverf, 1386 NFSX_V3WRITEVERF)) { 1387 memcpy(nmp->nm_writeverf, tl, 1388 NFSX_V3WRITEVERF); 1389 /* 1390 * note NFSMNT_STALEWRITEVERF 1391 * if we're the first thread to 1392 * notice it. 1393 */ 1394 if ((nmp->nm_iflag & 1395 NFSMNT_STALEWRITEVERF) == 0) { 1396 stalewriteverf = TRUE; 1397 nmp->nm_iflag |= 1398 NFSMNT_STALEWRITEVERF; 1399 } 1400 } 1401 simple_unlock(&nmp->nm_slock); 1402 } 1403 } else 1404 nfsm_loadattr(vp, (struct vattr *)0, NAC_NOTRUNC); 1405 if (wccflag) 1406 VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr->va_mtime; 1407 m_freem(mrep); 1408 if (error) 1409 break; 1410 tsiz -= len; 1411 if (stalewriteverf) { 1412 *stalewriteverfp = TRUE; 1413 stalewriteverf = FALSE; 1414 if (committed == NFSV3WRITE_UNSTABLE && 1415 len != origresid) { 1416 /* 1417 * if our write requests weren't atomic but 1418 * unstable, datas in previous iterations 1419 * might have already been lost now. 1420 * then, we should resend them to nfsd. 1421 */ 1422 backup = origresid - tsiz; 1423 uiop->uio_iov->iov_base = 1424 (caddr_t)uiop->uio_iov->iov_base - backup; 1425 uiop->uio_iov->iov_len += backup; 1426 uiop->uio_offset -= backup; 1427 uiop->uio_resid += backup; 1428 tsiz = origresid; 1429 goto retry; 1430 } 1431 } 1432 } 1433 if (pageprotected) { 1434 /* 1435 * wait until mbufs go away. 1436 * retransmitted mbufs can survive longer than rpc requests 1437 * themselves. 1438 */ 1439 s = splvm(); 1440 simple_lock(&ctx.nwc_slock); 1441 ctx.nwc_mbufcount--; 1442 while (ctx.nwc_mbufcount > 0) { 1443 ltsleep(&ctx, PRIBIO, "nfsmblk", 0, &ctx.nwc_slock); 1444 } 1445 simple_unlock(&ctx.nwc_slock); 1446 splx(s); 1447 PRELE(l); 1448 } 1449 nfsmout: 1450 *iomode = committed; 1451 if (error) 1452 uiop->uio_resid = tsiz; 1453 return (error); 1454 } 1455 1456 /* 1457 * nfs mknod rpc 1458 * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the 1459 * mode set to specify the file type and the size field for rdev. 1460 */ 1461 int 1462 nfs_mknodrpc(dvp, vpp, cnp, vap) 1463 struct vnode *dvp; 1464 struct vnode **vpp; 1465 struct componentname *cnp; 1466 struct vattr *vap; 1467 { 1468 struct nfsv2_sattr *sp; 1469 u_int32_t *tl; 1470 caddr_t cp; 1471 int32_t t1, t2; 1472 struct vnode *newvp = (struct vnode *)0; 1473 struct nfsnode *dnp, *np; 1474 char *cp2; 1475 caddr_t bpos, dpos; 1476 int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0; 1477 struct mbuf *mreq, *mrep, *md, *mb; 1478 u_int32_t rdev; 1479 const int v3 = NFS_ISV3(dvp); 1480 1481 if (vap->va_type == VCHR || vap->va_type == VBLK) 1482 rdev = txdr_unsigned(vap->va_rdev); 1483 else if (vap->va_type == VFIFO || vap->va_type == VSOCK) 1484 rdev = nfs_xdrneg1; 1485 else { 1486 VOP_ABORTOP(dvp, cnp); 1487 vput(dvp); 1488 return (EOPNOTSUPP); 1489 } 1490 nfsstats.rpccnt[NFSPROC_MKNOD]++; 1491 dnp = VTONFS(dvp); 1492 nfsm_reqhead(dnp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED + 1493 + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); 1494 nfsm_fhtom(dnp, v3); 1495 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1496 if (v3) { 1497 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); 1498 *tl++ = vtonfsv3_type(vap->va_type); 1499 nfsm_v3attrbuild(vap, FALSE); 1500 if (vap->va_type == VCHR || vap->va_type == VBLK) { 1501 nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 1502 *tl++ = txdr_unsigned(major(vap->va_rdev)); 1503 *tl = txdr_unsigned(minor(vap->va_rdev)); 1504 } 1505 } else { 1506 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); 1507 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); 1508 sp->sa_uid = nfs_xdrneg1; 1509 sp->sa_gid = nfs_xdrneg1; 1510 sp->sa_size = rdev; 1511 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1512 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1513 } 1514 nfsm_request(dnp, NFSPROC_MKNOD, cnp->cn_proc, cnp->cn_cred); 1515 if (!error) { 1516 nfsm_mtofh(dvp, newvp, v3, gotvp); 1517 if (!gotvp) { 1518 error = nfs_lookitup(dvp, cnp->cn_nameptr, 1519 cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc, &np); 1520 if (!error) 1521 newvp = NFSTOV(np); 1522 } 1523 } 1524 if (v3) 1525 nfsm_wcc_data(dvp, wccflag, 0); 1526 nfsm_reqdone; 1527 if (error) { 1528 if (newvp) 1529 vput(newvp); 1530 } else { 1531 if (cnp->cn_flags & MAKEENTRY) 1532 cache_enter(dvp, newvp, cnp); 1533 *vpp = newvp; 1534 } 1535 PNBUF_PUT(cnp->cn_pnbuf); 1536 VTONFS(dvp)->n_flag |= NMODIFIED; 1537 if (!wccflag) 1538 VTONFS(dvp)->n_attrstamp = 0; 1539 vput(dvp); 1540 return (error); 1541 } 1542 1543 /* 1544 * nfs mknod vop 1545 * just call nfs_mknodrpc() to do the work. 1546 */ 1547 /* ARGSUSED */ 1548 int 1549 nfs_mknod(v) 1550 void *v; 1551 { 1552 struct vop_mknod_args /* { 1553 struct vnode *a_dvp; 1554 struct vnode **a_vpp; 1555 struct componentname *a_cnp; 1556 struct vattr *a_vap; 1557 } */ *ap = v; 1558 int error; 1559 1560 error = nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap); 1561 VN_KNOTE(ap->a_dvp, NOTE_WRITE); 1562 return (error); 1563 } 1564 1565 static u_long create_verf; 1566 /* 1567 * nfs file create call 1568 */ 1569 int 1570 nfs_create(v) 1571 void *v; 1572 { 1573 struct vop_create_args /* { 1574 struct vnode *a_dvp; 1575 struct vnode **a_vpp; 1576 struct componentname *a_cnp; 1577 struct vattr *a_vap; 1578 } */ *ap = v; 1579 struct vnode *dvp = ap->a_dvp; 1580 struct vattr *vap = ap->a_vap; 1581 struct componentname *cnp = ap->a_cnp; 1582 struct nfsv2_sattr *sp; 1583 u_int32_t *tl; 1584 caddr_t cp; 1585 int32_t t1, t2; 1586 struct nfsnode *dnp, *np = (struct nfsnode *)0; 1587 struct vnode *newvp = (struct vnode *)0; 1588 caddr_t bpos, dpos, cp2; 1589 int error, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0; 1590 struct mbuf *mreq, *mrep, *md, *mb; 1591 const int v3 = NFS_ISV3(dvp); 1592 1593 /* 1594 * Oops, not for me.. 1595 */ 1596 if (vap->va_type == VSOCK) 1597 return (nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap)); 1598 1599 #ifdef VA_EXCLUSIVE 1600 if (vap->va_vaflags & VA_EXCLUSIVE) 1601 fmode |= O_EXCL; 1602 #endif 1603 again: 1604 error = 0; 1605 nfsstats.rpccnt[NFSPROC_CREATE]++; 1606 dnp = VTONFS(dvp); 1607 nfsm_reqhead(dnp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED + 1608 nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); 1609 nfsm_fhtom(dnp, v3); 1610 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1611 if (v3) { 1612 nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); 1613 if (fmode & O_EXCL) { 1614 *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); 1615 nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF); 1616 #ifdef INET 1617 if (TAILQ_FIRST(&in_ifaddr)) 1618 *tl++ = TAILQ_FIRST(&in_ifaddr)->ia_addr.sin_addr.s_addr; 1619 else 1620 *tl++ = create_verf; 1621 #else 1622 *tl++ = create_verf; 1623 #endif 1624 *tl = ++create_verf; 1625 } else { 1626 *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED); 1627 nfsm_v3attrbuild(vap, FALSE); 1628 } 1629 } else { 1630 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); 1631 sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); 1632 sp->sa_uid = nfs_xdrneg1; 1633 sp->sa_gid = nfs_xdrneg1; 1634 sp->sa_size = 0; 1635 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 1636 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 1637 } 1638 nfsm_request(dnp, NFSPROC_CREATE, cnp->cn_proc, cnp->cn_cred); 1639 if (!error) { 1640 nfsm_mtofh(dvp, newvp, v3, gotvp); 1641 if (!gotvp) { 1642 error = nfs_lookitup(dvp, cnp->cn_nameptr, 1643 cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc, &np); 1644 if (!error) 1645 newvp = NFSTOV(np); 1646 } 1647 } 1648 if (v3) 1649 nfsm_wcc_data(dvp, wccflag, 0); 1650 nfsm_reqdone; 1651 if (error) { 1652 if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) { 1653 fmode &= ~O_EXCL; 1654 goto again; 1655 } 1656 if (newvp) 1657 vput(newvp); 1658 } else if (v3 && (fmode & O_EXCL)) 1659 error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_proc); 1660 if (!error) { 1661 if (cnp->cn_flags & MAKEENTRY) 1662 cache_enter(dvp, newvp, cnp); 1663 *ap->a_vpp = newvp; 1664 } 1665 PNBUF_PUT(cnp->cn_pnbuf); 1666 VTONFS(dvp)->n_flag |= NMODIFIED; 1667 if (!wccflag) 1668 VTONFS(dvp)->n_attrstamp = 0; 1669 VN_KNOTE(ap->a_dvp, NOTE_WRITE); 1670 vput(dvp); 1671 return (error); 1672 } 1673 1674 /* 1675 * nfs file remove call 1676 * To try and make nfs semantics closer to ufs semantics, a file that has 1677 * other processes using the vnode is renamed instead of removed and then 1678 * removed later on the last close. 1679 * - If v_usecount > 1 1680 * If a rename is not already in the works 1681 * call nfs_sillyrename() to set it up 1682 * else 1683 * do the remove rpc 1684 */ 1685 int 1686 nfs_remove(v) 1687 void *v; 1688 { 1689 struct vop_remove_args /* { 1690 struct vnodeop_desc *a_desc; 1691 struct vnode * a_dvp; 1692 struct vnode * a_vp; 1693 struct componentname * a_cnp; 1694 } */ *ap = v; 1695 struct vnode *vp = ap->a_vp; 1696 struct vnode *dvp = ap->a_dvp; 1697 struct componentname *cnp = ap->a_cnp; 1698 struct nfsnode *np = VTONFS(vp); 1699 int error = 0; 1700 struct vattr vattr; 1701 1702 #ifndef DIAGNOSTIC 1703 if ((cnp->cn_flags & HASBUF) == 0) 1704 panic("nfs_remove: no name"); 1705 if (vp->v_usecount < 1) 1706 panic("nfs_remove: bad v_usecount"); 1707 #endif 1708 if (vp->v_type == VDIR) 1709 error = EPERM; 1710 else if (vp->v_usecount == 1 || (np->n_sillyrename && 1711 VOP_GETATTR(vp, &vattr, cnp->cn_cred, cnp->cn_proc) == 0 && 1712 vattr.va_nlink > 1)) { 1713 /* 1714 * Purge the name cache so that the chance of a lookup for 1715 * the name succeeding while the remove is in progress is 1716 * minimized. Without node locking it can still happen, such 1717 * that an I/O op returns ESTALE, but since you get this if 1718 * another host removes the file.. 1719 */ 1720 cache_purge(vp); 1721 /* 1722 * throw away biocache buffers, mainly to avoid 1723 * unnecessary delayed writes later. 1724 */ 1725 error = nfs_vinvalbuf(vp, 0, cnp->cn_cred, cnp->cn_proc, 1); 1726 /* Do the rpc */ 1727 if (error != EINTR) 1728 error = nfs_removerpc(dvp, cnp->cn_nameptr, 1729 cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc); 1730 /* 1731 * Kludge City: If the first reply to the remove rpc is lost.. 1732 * the reply to the retransmitted request will be ENOENT 1733 * since the file was in fact removed 1734 * Therefore, we cheat and return success. 1735 */ 1736 if (error == ENOENT) 1737 error = 0; 1738 } else if (!np->n_sillyrename) 1739 error = nfs_sillyrename(dvp, vp, cnp); 1740 PNBUF_PUT(cnp->cn_pnbuf); 1741 if (!error && nfs_getattrcache(vp, &vattr) == 0 && 1742 vattr.va_nlink == 1) { 1743 np->n_flag |= NREMOVED; 1744 } 1745 np->n_attrstamp = 0; 1746 VN_KNOTE(vp, NOTE_DELETE); 1747 VN_KNOTE(dvp, NOTE_WRITE); 1748 if (dvp == vp) 1749 vrele(vp); 1750 else 1751 vput(vp); 1752 vput(dvp); 1753 return (error); 1754 } 1755 1756 /* 1757 * nfs file remove rpc called from nfs_inactive 1758 */ 1759 int 1760 nfs_removeit(sp) 1761 struct sillyrename *sp; 1762 { 1763 1764 return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred, 1765 (struct proc *)0)); 1766 } 1767 1768 /* 1769 * Nfs remove rpc, called from nfs_remove() and nfs_removeit(). 1770 */ 1771 int 1772 nfs_removerpc(dvp, name, namelen, cred, proc) 1773 struct vnode *dvp; 1774 const char *name; 1775 int namelen; 1776 struct ucred *cred; 1777 struct proc *proc; 1778 { 1779 u_int32_t *tl; 1780 caddr_t cp; 1781 int32_t t1, t2; 1782 caddr_t bpos, dpos, cp2; 1783 int error = 0, wccflag = NFSV3_WCCRATTR; 1784 struct mbuf *mreq, *mrep, *md, *mb; 1785 const int v3 = NFS_ISV3(dvp); 1786 struct nfsnode *dnp = VTONFS(dvp); 1787 1788 nfsstats.rpccnt[NFSPROC_REMOVE]++; 1789 nfsm_reqhead(dnp, NFSPROC_REMOVE, 1790 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen)); 1791 nfsm_fhtom(dnp, v3); 1792 nfsm_strtom(name, namelen, NFS_MAXNAMLEN); 1793 nfsm_request(dnp, NFSPROC_REMOVE, proc, cred); 1794 if (v3) 1795 nfsm_wcc_data(dvp, wccflag, 0); 1796 nfsm_reqdone; 1797 VTONFS(dvp)->n_flag |= NMODIFIED; 1798 if (!wccflag) 1799 VTONFS(dvp)->n_attrstamp = 0; 1800 return (error); 1801 } 1802 1803 /* 1804 * nfs file rename call 1805 */ 1806 int 1807 nfs_rename(v) 1808 void *v; 1809 { 1810 struct vop_rename_args /* { 1811 struct vnode *a_fdvp; 1812 struct vnode *a_fvp; 1813 struct componentname *a_fcnp; 1814 struct vnode *a_tdvp; 1815 struct vnode *a_tvp; 1816 struct componentname *a_tcnp; 1817 } */ *ap = v; 1818 struct vnode *fvp = ap->a_fvp; 1819 struct vnode *tvp = ap->a_tvp; 1820 struct vnode *fdvp = ap->a_fdvp; 1821 struct vnode *tdvp = ap->a_tdvp; 1822 struct componentname *tcnp = ap->a_tcnp; 1823 struct componentname *fcnp = ap->a_fcnp; 1824 int error; 1825 1826 #ifndef DIAGNOSTIC 1827 if ((tcnp->cn_flags & HASBUF) == 0 || 1828 (fcnp->cn_flags & HASBUF) == 0) 1829 panic("nfs_rename: no name"); 1830 #endif 1831 /* Check for cross-device rename */ 1832 if ((fvp->v_mount != tdvp->v_mount) || 1833 (tvp && (fvp->v_mount != tvp->v_mount))) { 1834 error = EXDEV; 1835 goto out; 1836 } 1837 1838 /* 1839 * If the tvp exists and is in use, sillyrename it before doing the 1840 * rename of the new file over it. 1841 */ 1842 if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)->n_sillyrename && 1843 tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) { 1844 VN_KNOTE(tvp, NOTE_DELETE); 1845 vput(tvp); 1846 tvp = NULL; 1847 } 1848 1849 error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen, 1850 tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred, 1851 tcnp->cn_proc); 1852 1853 VN_KNOTE(fdvp, NOTE_WRITE); 1854 VN_KNOTE(tdvp, NOTE_WRITE); 1855 if (fvp->v_type == VDIR) { 1856 if (tvp != NULL && tvp->v_type == VDIR) 1857 cache_purge(tdvp); 1858 cache_purge(fdvp); 1859 } 1860 out: 1861 if (tdvp == tvp) 1862 vrele(tdvp); 1863 else 1864 vput(tdvp); 1865 if (tvp) 1866 vput(tvp); 1867 vrele(fdvp); 1868 vrele(fvp); 1869 /* 1870 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. 1871 */ 1872 if (error == ENOENT) 1873 error = 0; 1874 return (error); 1875 } 1876 1877 /* 1878 * nfs file rename rpc called from nfs_remove() above 1879 */ 1880 int 1881 nfs_renameit(sdvp, scnp, sp) 1882 struct vnode *sdvp; 1883 struct componentname *scnp; 1884 struct sillyrename *sp; 1885 { 1886 return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, 1887 sdvp, sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_proc)); 1888 } 1889 1890 /* 1891 * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit(). 1892 */ 1893 int 1894 nfs_renamerpc(fdvp, fnameptr, fnamelen, tdvp, tnameptr, tnamelen, cred, proc) 1895 struct vnode *fdvp; 1896 const char *fnameptr; 1897 int fnamelen; 1898 struct vnode *tdvp; 1899 const char *tnameptr; 1900 int tnamelen; 1901 struct ucred *cred; 1902 struct proc *proc; 1903 { 1904 u_int32_t *tl; 1905 caddr_t cp; 1906 int32_t t1, t2; 1907 caddr_t bpos, dpos, cp2; 1908 int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR; 1909 struct mbuf *mreq, *mrep, *md, *mb; 1910 const int v3 = NFS_ISV3(fdvp); 1911 struct nfsnode *fdnp = VTONFS(fdvp); 1912 1913 nfsstats.rpccnt[NFSPROC_RENAME]++; 1914 nfsm_reqhead(fdnp, NFSPROC_RENAME, 1915 (NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) + 1916 nfsm_rndup(tnamelen)); 1917 nfsm_fhtom(fdnp, v3); 1918 nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN); 1919 nfsm_fhtom(VTONFS(tdvp), v3); 1920 nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN); 1921 nfsm_request(fdnp, NFSPROC_RENAME, proc, cred); 1922 if (v3) { 1923 nfsm_wcc_data(fdvp, fwccflag, 0); 1924 nfsm_wcc_data(tdvp, twccflag, 0); 1925 } 1926 nfsm_reqdone; 1927 VTONFS(fdvp)->n_flag |= NMODIFIED; 1928 VTONFS(tdvp)->n_flag |= NMODIFIED; 1929 if (!fwccflag) 1930 VTONFS(fdvp)->n_attrstamp = 0; 1931 if (!twccflag) 1932 VTONFS(tdvp)->n_attrstamp = 0; 1933 return (error); 1934 } 1935 1936 /* 1937 * nfs hard link create call 1938 */ 1939 int 1940 nfs_link(v) 1941 void *v; 1942 { 1943 struct vop_link_args /* { 1944 struct vnode *a_dvp; 1945 struct vnode *a_vp; 1946 struct componentname *a_cnp; 1947 } */ *ap = v; 1948 struct vnode *vp = ap->a_vp; 1949 struct vnode *dvp = ap->a_dvp; 1950 struct componentname *cnp = ap->a_cnp; 1951 u_int32_t *tl; 1952 caddr_t cp; 1953 int32_t t1, t2; 1954 caddr_t bpos, dpos, cp2; 1955 int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0; 1956 struct mbuf *mreq, *mrep, *md, *mb; 1957 /* XXX Should be const and initialised? */ 1958 int v3; 1959 struct nfsnode *np; 1960 1961 if (dvp->v_mount != vp->v_mount) { 1962 VOP_ABORTOP(dvp, cnp); 1963 vput(dvp); 1964 return (EXDEV); 1965 } 1966 if (dvp != vp) { 1967 error = vn_lock(vp, LK_EXCLUSIVE); 1968 if (error != 0) { 1969 VOP_ABORTOP(dvp, cnp); 1970 vput(dvp); 1971 return error; 1972 } 1973 } 1974 1975 /* 1976 * Push all writes to the server, so that the attribute cache 1977 * doesn't get "out of sync" with the server. 1978 * XXX There should be a better way! 1979 */ 1980 VOP_FSYNC(vp, cnp->cn_cred, FSYNC_WAIT, 0, 0, cnp->cn_proc); 1981 1982 v3 = NFS_ISV3(vp); 1983 nfsstats.rpccnt[NFSPROC_LINK]++; 1984 np = VTONFS(vp); 1985 nfsm_reqhead(np, NFSPROC_LINK, 1986 NFSX_FH(v3)*2 + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); 1987 nfsm_fhtom(np, v3); 1988 nfsm_fhtom(VTONFS(dvp), v3); 1989 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 1990 nfsm_request(np, NFSPROC_LINK, cnp->cn_proc, cnp->cn_cred); 1991 if (v3) { 1992 nfsm_postop_attr(vp, attrflag, 0); 1993 nfsm_wcc_data(dvp, wccflag, 0); 1994 } 1995 nfsm_reqdone; 1996 PNBUF_PUT(cnp->cn_pnbuf); 1997 VTONFS(dvp)->n_flag |= NMODIFIED; 1998 if (!attrflag) 1999 VTONFS(vp)->n_attrstamp = 0; 2000 if (!wccflag) 2001 VTONFS(dvp)->n_attrstamp = 0; 2002 if (dvp != vp) 2003 VOP_UNLOCK(vp, 0); 2004 VN_KNOTE(vp, NOTE_LINK); 2005 VN_KNOTE(dvp, NOTE_WRITE); 2006 vput(dvp); 2007 /* 2008 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. 2009 */ 2010 if (error == EEXIST) 2011 error = 0; 2012 return (error); 2013 } 2014 2015 /* 2016 * nfs symbolic link create call 2017 */ 2018 int 2019 nfs_symlink(v) 2020 void *v; 2021 { 2022 struct vop_symlink_args /* { 2023 struct vnode *a_dvp; 2024 struct vnode **a_vpp; 2025 struct componentname *a_cnp; 2026 struct vattr *a_vap; 2027 char *a_target; 2028 } */ *ap = v; 2029 struct vnode *dvp = ap->a_dvp; 2030 struct vattr *vap = ap->a_vap; 2031 struct componentname *cnp = ap->a_cnp; 2032 struct nfsv2_sattr *sp; 2033 u_int32_t *tl; 2034 caddr_t cp; 2035 int32_t t1, t2; 2036 caddr_t bpos, dpos, cp2; 2037 int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp; 2038 struct mbuf *mreq, *mrep, *md, *mb; 2039 struct vnode *newvp = (struct vnode *)0; 2040 const int v3 = NFS_ISV3(dvp); 2041 struct nfsnode *dnp = VTONFS(dvp); 2042 2043 *ap->a_vpp = NULL; 2044 nfsstats.rpccnt[NFSPROC_SYMLINK]++; 2045 slen = strlen(ap->a_target); 2046 nfsm_reqhead(dnp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED + 2047 nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3)); 2048 nfsm_fhtom(dnp, v3); 2049 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 2050 if (v3) 2051 nfsm_v3attrbuild(vap, FALSE); 2052 nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN); 2053 if (!v3) { 2054 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); 2055 sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode); 2056 sp->sa_uid = nfs_xdrneg1; 2057 sp->sa_gid = nfs_xdrneg1; 2058 sp->sa_size = nfs_xdrneg1; 2059 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 2060 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 2061 } 2062 nfsm_request(dnp, NFSPROC_SYMLINK, cnp->cn_proc, cnp->cn_cred); 2063 if (v3) { 2064 if (!error) 2065 nfsm_mtofh(dvp, newvp, v3, gotvp); 2066 nfsm_wcc_data(dvp, wccflag, 0); 2067 } 2068 nfsm_reqdone; 2069 /* 2070 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. 2071 */ 2072 if (error == EEXIST) 2073 error = 0; 2074 if (error == 0 && newvp == NULL) { 2075 struct nfsnode *np = NULL; 2076 2077 error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen, 2078 cnp->cn_cred, cnp->cn_proc, &np); 2079 if (error == 0) 2080 newvp = NFSTOV(np); 2081 } 2082 if (error) { 2083 if (newvp != NULL) 2084 vput(newvp); 2085 } else { 2086 *ap->a_vpp = newvp; 2087 } 2088 PNBUF_PUT(cnp->cn_pnbuf); 2089 VTONFS(dvp)->n_flag |= NMODIFIED; 2090 if (!wccflag) 2091 VTONFS(dvp)->n_attrstamp = 0; 2092 VN_KNOTE(dvp, NOTE_WRITE); 2093 vput(dvp); 2094 return (error); 2095 } 2096 2097 /* 2098 * nfs make dir call 2099 */ 2100 int 2101 nfs_mkdir(v) 2102 void *v; 2103 { 2104 struct vop_mkdir_args /* { 2105 struct vnode *a_dvp; 2106 struct vnode **a_vpp; 2107 struct componentname *a_cnp; 2108 struct vattr *a_vap; 2109 } */ *ap = v; 2110 struct vnode *dvp = ap->a_dvp; 2111 struct vattr *vap = ap->a_vap; 2112 struct componentname *cnp = ap->a_cnp; 2113 struct nfsv2_sattr *sp; 2114 u_int32_t *tl; 2115 caddr_t cp; 2116 int32_t t1, t2; 2117 int len; 2118 struct nfsnode *dnp = VTONFS(dvp), *np = (struct nfsnode *)0; 2119 struct vnode *newvp = (struct vnode *)0; 2120 caddr_t bpos, dpos, cp2; 2121 int error = 0, wccflag = NFSV3_WCCRATTR; 2122 int gotvp = 0; 2123 struct mbuf *mreq, *mrep, *md, *mb; 2124 const int v3 = NFS_ISV3(dvp); 2125 2126 len = cnp->cn_namelen; 2127 nfsstats.rpccnt[NFSPROC_MKDIR]++; 2128 nfsm_reqhead(dnp, NFSPROC_MKDIR, 2129 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(v3)); 2130 nfsm_fhtom(dnp, v3); 2131 nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); 2132 if (v3) { 2133 nfsm_v3attrbuild(vap, FALSE); 2134 } else { 2135 nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); 2136 sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode); 2137 sp->sa_uid = nfs_xdrneg1; 2138 sp->sa_gid = nfs_xdrneg1; 2139 sp->sa_size = nfs_xdrneg1; 2140 txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); 2141 txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); 2142 } 2143 nfsm_request(dnp, NFSPROC_MKDIR, cnp->cn_proc, cnp->cn_cred); 2144 if (!error) 2145 nfsm_mtofh(dvp, newvp, v3, gotvp); 2146 if (v3) 2147 nfsm_wcc_data(dvp, wccflag, 0); 2148 nfsm_reqdone; 2149 VTONFS(dvp)->n_flag |= NMODIFIED; 2150 if (!wccflag) 2151 VTONFS(dvp)->n_attrstamp = 0; 2152 /* 2153 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry 2154 * if we can succeed in looking up the directory. 2155 */ 2156 if (error == EEXIST || (!error && !gotvp)) { 2157 if (newvp) { 2158 vput(newvp); 2159 newvp = (struct vnode *)0; 2160 } 2161 error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred, 2162 cnp->cn_proc, &np); 2163 if (!error) { 2164 newvp = NFSTOV(np); 2165 if (newvp->v_type != VDIR) 2166 error = EEXIST; 2167 } 2168 } 2169 if (error) { 2170 if (newvp) 2171 vput(newvp); 2172 } else { 2173 VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); 2174 if (cnp->cn_flags & MAKEENTRY) 2175 cache_enter(dvp, newvp, cnp); 2176 *ap->a_vpp = newvp; 2177 } 2178 PNBUF_PUT(cnp->cn_pnbuf); 2179 vput(dvp); 2180 return (error); 2181 } 2182 2183 /* 2184 * nfs remove directory call 2185 */ 2186 int 2187 nfs_rmdir(v) 2188 void *v; 2189 { 2190 struct vop_rmdir_args /* { 2191 struct vnode *a_dvp; 2192 struct vnode *a_vp; 2193 struct componentname *a_cnp; 2194 } */ *ap = v; 2195 struct vnode *vp = ap->a_vp; 2196 struct vnode *dvp = ap->a_dvp; 2197 struct componentname *cnp = ap->a_cnp; 2198 u_int32_t *tl; 2199 caddr_t cp; 2200 int32_t t1, t2; 2201 caddr_t bpos, dpos, cp2; 2202 int error = 0, wccflag = NFSV3_WCCRATTR; 2203 struct mbuf *mreq, *mrep, *md, *mb; 2204 const int v3 = NFS_ISV3(dvp); 2205 struct nfsnode *dnp; 2206 2207 if (dvp == vp) { 2208 vrele(dvp); 2209 vput(dvp); 2210 PNBUF_PUT(cnp->cn_pnbuf); 2211 return (EINVAL); 2212 } 2213 nfsstats.rpccnt[NFSPROC_RMDIR]++; 2214 dnp = VTONFS(dvp); 2215 nfsm_reqhead(dnp, NFSPROC_RMDIR, 2216 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); 2217 nfsm_fhtom(dnp, v3); 2218 nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); 2219 nfsm_request(dnp, NFSPROC_RMDIR, cnp->cn_proc, cnp->cn_cred); 2220 if (v3) 2221 nfsm_wcc_data(dvp, wccflag, 0); 2222 nfsm_reqdone; 2223 PNBUF_PUT(cnp->cn_pnbuf); 2224 VTONFS(dvp)->n_flag |= NMODIFIED; 2225 if (!wccflag) 2226 VTONFS(dvp)->n_attrstamp = 0; 2227 VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); 2228 VN_KNOTE(vp, NOTE_DELETE); 2229 cache_purge(dvp); 2230 cache_purge(vp); 2231 vput(vp); 2232 vput(dvp); 2233 /* 2234 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. 2235 */ 2236 if (error == ENOENT) 2237 error = 0; 2238 return (error); 2239 } 2240 2241 /* 2242 * nfs readdir call 2243 */ 2244 int 2245 nfs_readdir(v) 2246 void *v; 2247 { 2248 struct vop_readdir_args /* { 2249 struct vnode *a_vp; 2250 struct uio *a_uio; 2251 struct ucred *a_cred; 2252 int *a_eofflag; 2253 off_t **a_cookies; 2254 int *a_ncookies; 2255 } */ *ap = v; 2256 struct vnode *vp = ap->a_vp; 2257 struct uio *uio = ap->a_uio; 2258 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2259 char *base = uio->uio_iov->iov_base; 2260 int tresid, error; 2261 size_t count, lost; 2262 struct dirent *dp; 2263 off_t *cookies = NULL; 2264 int ncookies = 0, nc; 2265 2266 if (vp->v_type != VDIR) 2267 return (EPERM); 2268 2269 lost = uio->uio_resid & (NFS_DIRFRAGSIZ - 1); 2270 count = uio->uio_resid - lost; 2271 if (count <= 0) 2272 return (EINVAL); 2273 2274 /* 2275 * Call nfs_bioread() to do the real work. 2276 */ 2277 tresid = uio->uio_resid = count; 2278 error = nfs_bioread(vp, uio, 0, ap->a_cred, 2279 ap->a_cookies ? NFSBIO_CACHECOOKIES : 0); 2280 2281 if (!error && ap->a_cookies) { 2282 ncookies = count / 16; 2283 cookies = malloc(sizeof (off_t) * ncookies, M_TEMP, M_WAITOK); 2284 *ap->a_cookies = cookies; 2285 } 2286 2287 if (!error && uio->uio_resid == tresid) { 2288 uio->uio_resid += lost; 2289 nfsstats.direofcache_misses++; 2290 if (ap->a_cookies) 2291 *ap->a_ncookies = 0; 2292 *ap->a_eofflag = 1; 2293 return (0); 2294 } 2295 2296 if (!error && ap->a_cookies) { 2297 /* 2298 * Only the NFS server and emulations use cookies, and they 2299 * load the directory block into system space, so we can 2300 * just look at it directly. 2301 */ 2302 if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) 2303 panic("nfs_readdir: lost in space"); 2304 for (nc = 0; ncookies-- && 2305 base < (char *)uio->uio_iov->iov_base; nc++){ 2306 dp = (struct dirent *) base; 2307 if (dp->d_reclen == 0) 2308 break; 2309 if (nmp->nm_flag & NFSMNT_XLATECOOKIE) 2310 *(cookies++) = (off_t)NFS_GETCOOKIE32(dp); 2311 else 2312 *(cookies++) = NFS_GETCOOKIE(dp); 2313 base += dp->d_reclen; 2314 } 2315 uio->uio_resid += 2316 ((caddr_t)uio->uio_iov->iov_base - base); 2317 uio->uio_iov->iov_len += 2318 ((caddr_t)uio->uio_iov->iov_base - base); 2319 uio->uio_iov->iov_base = base; 2320 *ap->a_ncookies = nc; 2321 } 2322 2323 uio->uio_resid += lost; 2324 *ap->a_eofflag = 0; 2325 return (error); 2326 } 2327 2328 /* 2329 * Readdir rpc call. 2330 * Called from below the buffer cache by nfs_doio(). 2331 */ 2332 int 2333 nfs_readdirrpc(vp, uiop, cred) 2334 struct vnode *vp; 2335 struct uio *uiop; 2336 struct ucred *cred; 2337 { 2338 int len, left; 2339 struct dirent *dp = NULL; 2340 u_int32_t *tl; 2341 caddr_t cp; 2342 int32_t t1, t2; 2343 caddr_t bpos, dpos, cp2; 2344 struct mbuf *mreq, *mrep, *md, *mb; 2345 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2346 struct nfsnode *dnp = VTONFS(vp); 2347 u_quad_t fileno; 2348 int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1; 2349 int attrflag, nrpcs = 0, reclen; 2350 const int v3 = NFS_ISV3(vp); 2351 2352 #ifdef DIAGNOSTIC 2353 /* 2354 * Should be called from buffer cache, so only amount of 2355 * NFS_DIRBLKSIZ will be requested. 2356 */ 2357 if (uiop->uio_iovcnt != 1 || (uiop->uio_resid & (NFS_DIRBLKSIZ - 1))) 2358 panic("nfs readdirrpc bad uio"); 2359 #endif 2360 2361 /* 2362 * Loop around doing readdir rpc's of size nm_readdirsize 2363 * truncated to a multiple of NFS_DIRFRAGSIZ. 2364 * The stopping criteria is EOF or buffer full. 2365 */ 2366 while (more_dirs && bigenough) { 2367 /* 2368 * Heuristic: don't bother to do another RPC to further 2369 * fill up this block if there is not much room left. (< 50% 2370 * of the readdir RPC size). This wastes some buffer space 2371 * but can save up to 50% in RPC calls. 2372 */ 2373 if (nrpcs > 0 && uiop->uio_resid < (nmp->nm_readdirsize / 2)) { 2374 bigenough = 0; 2375 break; 2376 } 2377 nfsstats.rpccnt[NFSPROC_READDIR]++; 2378 nfsm_reqhead(dnp, NFSPROC_READDIR, NFSX_FH(v3) + 2379 NFSX_READDIR(v3)); 2380 nfsm_fhtom(dnp, v3); 2381 if (v3) { 2382 nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED); 2383 if (nmp->nm_iflag & NFSMNT_SWAPCOOKIE) { 2384 txdr_swapcookie3(uiop->uio_offset, tl); 2385 } else { 2386 txdr_cookie3(uiop->uio_offset, tl); 2387 } 2388 tl += 2; 2389 *tl++ = dnp->n_cookieverf.nfsuquad[0]; 2390 *tl++ = dnp->n_cookieverf.nfsuquad[1]; 2391 } else { 2392 nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); 2393 *tl++ = txdr_unsigned(uiop->uio_offset); 2394 } 2395 *tl = txdr_unsigned(nmp->nm_readdirsize); 2396 nfsm_request(dnp, NFSPROC_READDIR, uiop->uio_procp, cred); 2397 nrpcs++; 2398 if (v3) { 2399 nfsm_postop_attr(vp, attrflag, 0); 2400 if (!error) { 2401 nfsm_dissect(tl, u_int32_t *, 2402 2 * NFSX_UNSIGNED); 2403 dnp->n_cookieverf.nfsuquad[0] = *tl++; 2404 dnp->n_cookieverf.nfsuquad[1] = *tl; 2405 } else { 2406 m_freem(mrep); 2407 goto nfsmout; 2408 } 2409 } 2410 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2411 more_dirs = fxdr_unsigned(int, *tl); 2412 2413 /* loop thru the dir entries, doctoring them to 4bsd form */ 2414 while (more_dirs && bigenough) { 2415 if (v3) { 2416 nfsm_dissect(tl, u_int32_t *, 2417 3 * NFSX_UNSIGNED); 2418 fileno = fxdr_hyper(tl); 2419 len = fxdr_unsigned(int, *(tl + 2)); 2420 } else { 2421 nfsm_dissect(tl, u_int32_t *, 2422 2 * NFSX_UNSIGNED); 2423 fileno = fxdr_unsigned(u_quad_t, *tl++); 2424 len = fxdr_unsigned(int, *tl); 2425 } 2426 if (len <= 0 || len > NFS_MAXNAMLEN) { 2427 error = EBADRPC; 2428 m_freem(mrep); 2429 goto nfsmout; 2430 } 2431 tlen = nfsm_rndup(len); 2432 if (tlen == len) 2433 tlen += 4; /* To ensure null termination */ 2434 tlen += sizeof (off_t) + sizeof (int); 2435 reclen = ALIGN(tlen + DIRHDSIZ); 2436 tlen = reclen - DIRHDSIZ; 2437 left = NFS_DIRFRAGSIZ - blksiz; 2438 if (reclen > left) { 2439 dp->d_reclen += left; 2440 uiop->uio_iov->iov_base = 2441 (caddr_t)uiop->uio_iov->iov_base + left; 2442 uiop->uio_iov->iov_len -= left; 2443 uiop->uio_resid -= left; 2444 blksiz = 0; 2445 NFS_STASHCOOKIE(dp, uiop->uio_offset); 2446 } 2447 if (reclen > uiop->uio_resid) 2448 bigenough = 0; 2449 if (bigenough) { 2450 dp = (struct dirent *)uiop->uio_iov->iov_base; 2451 dp->d_fileno = (int)fileno; 2452 dp->d_namlen = len; 2453 dp->d_reclen = reclen; 2454 dp->d_type = DT_UNKNOWN; 2455 blksiz += dp->d_reclen; 2456 if (blksiz == NFS_DIRFRAGSIZ) 2457 blksiz = 0; 2458 uiop->uio_resid -= DIRHDSIZ; 2459 uiop->uio_iov->iov_base = 2460 (caddr_t)uiop->uio_iov->iov_base + DIRHDSIZ; 2461 uiop->uio_iov->iov_len -= DIRHDSIZ; 2462 nfsm_mtouio(uiop, len); 2463 cp = uiop->uio_iov->iov_base; 2464 tlen -= len; 2465 *cp = '\0'; /* null terminate */ 2466 uiop->uio_iov->iov_base = 2467 (caddr_t)uiop->uio_iov->iov_base + tlen; 2468 uiop->uio_iov->iov_len -= tlen; 2469 uiop->uio_resid -= tlen; 2470 } else 2471 nfsm_adv(nfsm_rndup(len)); 2472 if (v3) { 2473 nfsm_dissect(tl, u_int32_t *, 2474 3 * NFSX_UNSIGNED); 2475 } else { 2476 nfsm_dissect(tl, u_int32_t *, 2477 2 * NFSX_UNSIGNED); 2478 } 2479 if (bigenough) { 2480 if (v3) { 2481 if (nmp->nm_iflag & NFSMNT_SWAPCOOKIE) 2482 uiop->uio_offset = 2483 fxdr_swapcookie3(tl); 2484 else 2485 uiop->uio_offset = 2486 fxdr_cookie3(tl); 2487 } 2488 else { 2489 uiop->uio_offset = 2490 fxdr_unsigned(off_t, *tl); 2491 } 2492 NFS_STASHCOOKIE(dp, uiop->uio_offset); 2493 } 2494 if (v3) 2495 tl += 2; 2496 else 2497 tl++; 2498 more_dirs = fxdr_unsigned(int, *tl); 2499 } 2500 /* 2501 * If at end of rpc data, get the eof boolean 2502 */ 2503 if (!more_dirs) { 2504 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2505 more_dirs = (fxdr_unsigned(int, *tl) == 0); 2506 } 2507 m_freem(mrep); 2508 } 2509 /* 2510 * Fill last record, iff any, out to a multiple of NFS_DIRFRAGSIZ 2511 * by increasing d_reclen for the last record. 2512 */ 2513 if (blksiz > 0) { 2514 left = NFS_DIRFRAGSIZ - blksiz; 2515 dp->d_reclen += left; 2516 NFS_STASHCOOKIE(dp, uiop->uio_offset); 2517 uiop->uio_iov->iov_base = (caddr_t)uiop->uio_iov->iov_base + 2518 left; 2519 uiop->uio_iov->iov_len -= left; 2520 uiop->uio_resid -= left; 2521 } 2522 2523 /* 2524 * We are now either at the end of the directory or have filled the 2525 * block. 2526 */ 2527 if (bigenough) 2528 dnp->n_direofoffset = uiop->uio_offset; 2529 nfsmout: 2530 return (error); 2531 } 2532 2533 /* 2534 * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc(). 2535 */ 2536 int 2537 nfs_readdirplusrpc(vp, uiop, cred) 2538 struct vnode *vp; 2539 struct uio *uiop; 2540 struct ucred *cred; 2541 { 2542 int len, left; 2543 struct dirent *dp = NULL; 2544 u_int32_t *tl; 2545 caddr_t cp; 2546 int32_t t1, t2; 2547 struct vnode *newvp; 2548 caddr_t bpos, dpos, cp2; 2549 struct mbuf *mreq, *mrep, *md, *mb; 2550 struct nameidata nami, *ndp = &nami; 2551 struct componentname *cnp = &ndp->ni_cnd; 2552 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2553 struct nfsnode *dnp = VTONFS(vp), *np; 2554 nfsfh_t *fhp; 2555 u_quad_t fileno; 2556 int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i; 2557 int attrflag, fhsize, nrpcs = 0, reclen; 2558 struct nfs_fattr fattr, *fp; 2559 2560 #ifdef DIAGNOSTIC 2561 if (uiop->uio_iovcnt != 1 || (uiop->uio_resid & (NFS_DIRBLKSIZ - 1))) 2562 panic("nfs readdirplusrpc bad uio"); 2563 #endif 2564 ndp->ni_dvp = vp; 2565 newvp = NULLVP; 2566 2567 /* 2568 * Loop around doing readdir rpc's of size nm_readdirsize 2569 * truncated to a multiple of NFS_DIRFRAGSIZ. 2570 * The stopping criteria is EOF or buffer full. 2571 */ 2572 while (more_dirs && bigenough) { 2573 if (nrpcs > 0 && uiop->uio_resid < (nmp->nm_readdirsize / 2)) { 2574 bigenough = 0; 2575 break; 2576 } 2577 nfsstats.rpccnt[NFSPROC_READDIRPLUS]++; 2578 nfsm_reqhead(dnp, NFSPROC_READDIRPLUS, 2579 NFSX_FH(1) + 6 * NFSX_UNSIGNED); 2580 nfsm_fhtom(dnp, 1); 2581 nfsm_build(tl, u_int32_t *, 6 * NFSX_UNSIGNED); 2582 if (nmp->nm_iflag & NFSMNT_SWAPCOOKIE) { 2583 txdr_swapcookie3(uiop->uio_offset, tl); 2584 } else { 2585 txdr_cookie3(uiop->uio_offset, tl); 2586 } 2587 tl += 2; 2588 *tl++ = dnp->n_cookieverf.nfsuquad[0]; 2589 *tl++ = dnp->n_cookieverf.nfsuquad[1]; 2590 *tl++ = txdr_unsigned(nmp->nm_readdirsize); 2591 *tl = txdr_unsigned(nmp->nm_rsize); 2592 nfsm_request(dnp, NFSPROC_READDIRPLUS, uiop->uio_procp, cred); 2593 nfsm_postop_attr(vp, attrflag, 0); 2594 if (error) { 2595 m_freem(mrep); 2596 goto nfsmout; 2597 } 2598 nrpcs++; 2599 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); 2600 dnp->n_cookieverf.nfsuquad[0] = *tl++; 2601 dnp->n_cookieverf.nfsuquad[1] = *tl++; 2602 more_dirs = fxdr_unsigned(int, *tl); 2603 2604 /* loop thru the dir entries, doctoring them to 4bsd form */ 2605 while (more_dirs && bigenough) { 2606 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); 2607 fileno = fxdr_hyper(tl); 2608 len = fxdr_unsigned(int, *(tl + 2)); 2609 if (len <= 0 || len > NFS_MAXNAMLEN) { 2610 error = EBADRPC; 2611 m_freem(mrep); 2612 goto nfsmout; 2613 } 2614 tlen = nfsm_rndup(len); 2615 if (tlen == len) 2616 tlen += 4; /* To ensure null termination*/ 2617 tlen += sizeof (off_t) + sizeof (int); 2618 reclen = ALIGN(tlen + DIRHDSIZ); 2619 tlen = reclen - DIRHDSIZ; 2620 left = NFS_DIRFRAGSIZ - blksiz; 2621 if (reclen > left) { 2622 /* 2623 * DIRFRAGSIZ is aligned, no need to align 2624 * again here. 2625 */ 2626 dp->d_reclen += left; 2627 uiop->uio_iov->iov_base = 2628 (caddr_t)uiop->uio_iov->iov_base + left; 2629 uiop->uio_iov->iov_len -= left; 2630 uiop->uio_resid -= left; 2631 NFS_STASHCOOKIE(dp, uiop->uio_offset); 2632 blksiz = 0; 2633 } 2634 if (reclen > uiop->uio_resid) 2635 bigenough = 0; 2636 if (bigenough) { 2637 dp = (struct dirent *)uiop->uio_iov->iov_base; 2638 dp->d_fileno = (int)fileno; 2639 dp->d_namlen = len; 2640 dp->d_reclen = reclen; 2641 dp->d_type = DT_UNKNOWN; 2642 blksiz += dp->d_reclen; 2643 if (blksiz == NFS_DIRFRAGSIZ) 2644 blksiz = 0; 2645 uiop->uio_resid -= DIRHDSIZ; 2646 uiop->uio_iov->iov_base = 2647 (caddr_t)uiop->uio_iov->iov_base + 2648 DIRHDSIZ; 2649 uiop->uio_iov->iov_len -= DIRHDSIZ; 2650 cnp->cn_nameptr = uiop->uio_iov->iov_base; 2651 cnp->cn_namelen = len; 2652 nfsm_mtouio(uiop, len); 2653 cp = uiop->uio_iov->iov_base; 2654 tlen -= len; 2655 *cp = '\0'; 2656 uiop->uio_iov->iov_base = 2657 (caddr_t)uiop->uio_iov->iov_base + tlen; 2658 uiop->uio_iov->iov_len -= tlen; 2659 uiop->uio_resid -= tlen; 2660 } else 2661 nfsm_adv(nfsm_rndup(len)); 2662 nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); 2663 if (bigenough) { 2664 if (nmp->nm_iflag & NFSMNT_SWAPCOOKIE) 2665 uiop->uio_offset = 2666 fxdr_swapcookie3(tl); 2667 else 2668 uiop->uio_offset = 2669 fxdr_cookie3(tl); 2670 NFS_STASHCOOKIE(dp, uiop->uio_offset); 2671 } 2672 tl += 2; 2673 2674 /* 2675 * Since the attributes are before the file handle 2676 * (sigh), we must skip over the attributes and then 2677 * come back and get them. 2678 */ 2679 attrflag = fxdr_unsigned(int, *tl); 2680 if (attrflag) { 2681 nfsm_dissect(fp, struct nfs_fattr *, NFSX_V3FATTR); 2682 memcpy(&fattr, fp, NFSX_V3FATTR); 2683 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2684 doit = fxdr_unsigned(int, *tl); 2685 if (doit) { 2686 nfsm_getfh(fhp, fhsize, 1); 2687 if (NFS_CMPFH(dnp, fhp, fhsize)) { 2688 VREF(vp); 2689 newvp = vp; 2690 np = dnp; 2691 } else { 2692 error = nfs_nget(vp->v_mount, fhp, 2693 fhsize, &np); 2694 if (!error) 2695 newvp = NFSTOV(np); 2696 } 2697 if (!error) { 2698 const char *cp; 2699 2700 nfs_loadattrcache(&newvp, &fattr, 0, 0); 2701 dp->d_type = 2702 IFTODT(VTTOIF(np->n_vattr->va_type)); 2703 ndp->ni_vp = newvp; 2704 cp = cnp->cn_nameptr + cnp->cn_namelen; 2705 cnp->cn_hash = 2706 namei_hash(cnp->cn_nameptr, &cp); 2707 if (cnp->cn_namelen <= NCHNAMLEN) 2708 cache_enter(ndp->ni_dvp, ndp->ni_vp, 2709 cnp); 2710 } 2711 } 2712 } else { 2713 /* Just skip over the file handle */ 2714 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2715 i = fxdr_unsigned(int, *tl); 2716 nfsm_adv(nfsm_rndup(i)); 2717 } 2718 if (newvp != NULLVP) { 2719 if (newvp == vp) 2720 vrele(newvp); 2721 else 2722 vput(newvp); 2723 newvp = NULLVP; 2724 } 2725 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2726 more_dirs = fxdr_unsigned(int, *tl); 2727 } 2728 /* 2729 * If at end of rpc data, get the eof boolean 2730 */ 2731 if (!more_dirs) { 2732 nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); 2733 more_dirs = (fxdr_unsigned(int, *tl) == 0); 2734 } 2735 m_freem(mrep); 2736 } 2737 /* 2738 * Fill last record, iff any, out to a multiple of NFS_DIRFRAGSIZ 2739 * by increasing d_reclen for the last record. 2740 */ 2741 if (blksiz > 0) { 2742 left = NFS_DIRFRAGSIZ - blksiz; 2743 dp->d_reclen += left; 2744 NFS_STASHCOOKIE(dp, uiop->uio_offset); 2745 uiop->uio_iov->iov_base = (caddr_t)uiop->uio_iov->iov_base + 2746 left; 2747 uiop->uio_iov->iov_len -= left; 2748 uiop->uio_resid -= left; 2749 } 2750 2751 /* 2752 * We are now either at the end of the directory or have filled the 2753 * block. 2754 */ 2755 if (bigenough) 2756 dnp->n_direofoffset = uiop->uio_offset; 2757 nfsmout: 2758 if (newvp != NULLVP) { 2759 if(newvp == vp) 2760 vrele(newvp); 2761 else 2762 vput(newvp); 2763 } 2764 return (error); 2765 } 2766 static char hextoasc[] = "0123456789abcdef"; 2767 2768 /* 2769 * Silly rename. To make the NFS filesystem that is stateless look a little 2770 * more like the "ufs" a remove of an active vnode is translated to a rename 2771 * to a funny looking filename that is removed by nfs_inactive on the 2772 * nfsnode. There is the potential for another process on a different client 2773 * to create the same funny name between the nfs_lookitup() fails and the 2774 * nfs_rename() completes, but... 2775 */ 2776 int 2777 nfs_sillyrename(dvp, vp, cnp) 2778 struct vnode *dvp, *vp; 2779 struct componentname *cnp; 2780 { 2781 struct sillyrename *sp; 2782 struct nfsnode *np; 2783 int error; 2784 short pid; 2785 2786 cache_purge(dvp); 2787 np = VTONFS(vp); 2788 #ifndef DIAGNOSTIC 2789 if (vp->v_type == VDIR) 2790 panic("nfs: sillyrename dir"); 2791 #endif 2792 MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename), 2793 M_NFSREQ, M_WAITOK); 2794 sp->s_cred = crdup(cnp->cn_cred); 2795 sp->s_dvp = dvp; 2796 VREF(dvp); 2797 2798 /* Fudge together a funny name */ 2799 pid = cnp->cn_proc->p_pid; 2800 memcpy(sp->s_name, ".nfsAxxxx4.4", 13); 2801 sp->s_namlen = 12; 2802 sp->s_name[8] = hextoasc[pid & 0xf]; 2803 sp->s_name[7] = hextoasc[(pid >> 4) & 0xf]; 2804 sp->s_name[6] = hextoasc[(pid >> 8) & 0xf]; 2805 sp->s_name[5] = hextoasc[(pid >> 12) & 0xf]; 2806 2807 /* Try lookitups until we get one that isn't there */ 2808 while (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2809 cnp->cn_proc, (struct nfsnode **)0) == 0) { 2810 sp->s_name[4]++; 2811 if (sp->s_name[4] > 'z') { 2812 error = EINVAL; 2813 goto bad; 2814 } 2815 } 2816 error = nfs_renameit(dvp, cnp, sp); 2817 if (error) 2818 goto bad; 2819 error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, 2820 cnp->cn_proc, &np); 2821 np->n_sillyrename = sp; 2822 return (0); 2823 bad: 2824 vrele(sp->s_dvp); 2825 crfree(sp->s_cred); 2826 free((caddr_t)sp, M_NFSREQ); 2827 return (error); 2828 } 2829 2830 /* 2831 * Look up a file name and optionally either update the file handle or 2832 * allocate an nfsnode, depending on the value of npp. 2833 * npp == NULL --> just do the lookup 2834 * *npp == NULL --> allocate a new nfsnode and make sure attributes are 2835 * handled too 2836 * *npp != NULL --> update the file handle in the vnode 2837 */ 2838 int 2839 nfs_lookitup(dvp, name, len, cred, procp, npp) 2840 struct vnode *dvp; 2841 const char *name; 2842 int len; 2843 struct ucred *cred; 2844 struct proc *procp; 2845 struct nfsnode **npp; 2846 { 2847 u_int32_t *tl; 2848 caddr_t cp; 2849 int32_t t1, t2; 2850 struct vnode *newvp = (struct vnode *)0; 2851 struct nfsnode *np, *dnp = VTONFS(dvp); 2852 caddr_t bpos, dpos, cp2; 2853 int error = 0, fhlen, attrflag; 2854 struct mbuf *mreq, *mrep, *md, *mb; 2855 nfsfh_t *nfhp; 2856 const int v3 = NFS_ISV3(dvp); 2857 2858 nfsstats.rpccnt[NFSPROC_LOOKUP]++; 2859 nfsm_reqhead(dnp, NFSPROC_LOOKUP, 2860 NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); 2861 nfsm_fhtom(dnp, v3); 2862 nfsm_strtom(name, len, NFS_MAXNAMLEN); 2863 nfsm_request(dnp, NFSPROC_LOOKUP, procp, cred); 2864 if (npp && !error) { 2865 nfsm_getfh(nfhp, fhlen, v3); 2866 if (*npp) { 2867 np = *npp; 2868 if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) { 2869 free((caddr_t)np->n_fhp, M_NFSBIGFH); 2870 np->n_fhp = &np->n_fh; 2871 } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH) 2872 np->n_fhp =(nfsfh_t *)malloc(fhlen,M_NFSBIGFH,M_WAITOK); 2873 memcpy((caddr_t)np->n_fhp, (caddr_t)nfhp, fhlen); 2874 np->n_fhsize = fhlen; 2875 newvp = NFSTOV(np); 2876 } else if (NFS_CMPFH(dnp, nfhp, fhlen)) { 2877 VREF(dvp); 2878 newvp = dvp; 2879 } else { 2880 error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np); 2881 if (error) { 2882 m_freem(mrep); 2883 return (error); 2884 } 2885 newvp = NFSTOV(np); 2886 } 2887 if (v3) { 2888 nfsm_postop_attr(newvp, attrflag, 0); 2889 if (!attrflag && *npp == NULL) { 2890 m_freem(mrep); 2891 vput(newvp); 2892 return (ENOENT); 2893 } 2894 } else 2895 nfsm_loadattr(newvp, (struct vattr *)0, 0); 2896 } 2897 nfsm_reqdone; 2898 if (npp && *npp == NULL) { 2899 if (error) { 2900 if (newvp) 2901 vput(newvp); 2902 } else 2903 *npp = np; 2904 } 2905 return (error); 2906 } 2907 2908 /* 2909 * Nfs Version 3 commit rpc 2910 */ 2911 int 2912 nfs_commit(vp, offset, cnt, procp) 2913 struct vnode *vp; 2914 off_t offset; 2915 uint32_t cnt; 2916 struct proc *procp; 2917 { 2918 caddr_t cp; 2919 u_int32_t *tl; 2920 int32_t t1, t2; 2921 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 2922 caddr_t bpos, dpos, cp2; 2923 int error = 0, wccflag = NFSV3_WCCRATTR; 2924 struct mbuf *mreq, *mrep, *md, *mb; 2925 struct nfsnode *np; 2926 2927 KASSERT(NFS_ISV3(vp)); 2928 2929 #ifdef NFS_DEBUG_COMMIT 2930 printf("commit %lu - %lu\n", (unsigned long)offset, 2931 (unsigned long)(offset + cnt)); 2932 #endif 2933 2934 simple_lock(&nmp->nm_slock); 2935 if ((nmp->nm_iflag & NFSMNT_HASWRITEVERF) == 0) { 2936 simple_unlock(&nmp->nm_slock); 2937 return (0); 2938 } 2939 simple_unlock(&nmp->nm_slock); 2940 nfsstats.rpccnt[NFSPROC_COMMIT]++; 2941 np = VTONFS(vp); 2942 nfsm_reqhead(np, NFSPROC_COMMIT, NFSX_FH(1)); 2943 nfsm_fhtom(np, 1); 2944 nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); 2945 txdr_hyper(offset, tl); 2946 tl += 2; 2947 *tl = txdr_unsigned(cnt); 2948 nfsm_request(np, NFSPROC_COMMIT, procp, np->n_wcred); 2949 nfsm_wcc_data(vp, wccflag, 0); 2950 if (!error) { 2951 nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF); 2952 simple_lock(&nmp->nm_slock); 2953 if ((nmp->nm_iflag & NFSMNT_STALEWRITEVERF) || 2954 memcmp(nmp->nm_writeverf, tl, NFSX_V3WRITEVERF)) { 2955 memcpy(nmp->nm_writeverf, tl, NFSX_V3WRITEVERF); 2956 error = NFSERR_STALEWRITEVERF; 2957 nmp->nm_iflag |= NFSMNT_STALEWRITEVERF; 2958 } 2959 simple_unlock(&nmp->nm_slock); 2960 } 2961 nfsm_reqdone; 2962 return (error); 2963 } 2964 2965 /* 2966 * Kludge City.. 2967 * - make nfs_bmap() essentially a no-op that does no translation 2968 * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc 2969 * (Maybe I could use the process's page mapping, but I was concerned that 2970 * Kernel Write might not be enabled and also figured copyout() would do 2971 * a lot more work than memcpy() and also it currently happens in the 2972 * context of the swapper process (2). 2973 */ 2974 int 2975 nfs_bmap(v) 2976 void *v; 2977 { 2978 struct vop_bmap_args /* { 2979 struct vnode *a_vp; 2980 daddr_t a_bn; 2981 struct vnode **a_vpp; 2982 daddr_t *a_bnp; 2983 int *a_runp; 2984 } */ *ap = v; 2985 struct vnode *vp = ap->a_vp; 2986 int bshift = vp->v_mount->mnt_fs_bshift - vp->v_mount->mnt_dev_bshift; 2987 2988 if (ap->a_vpp != NULL) 2989 *ap->a_vpp = vp; 2990 if (ap->a_bnp != NULL) 2991 *ap->a_bnp = ap->a_bn << bshift; 2992 if (ap->a_runp != NULL) 2993 *ap->a_runp = 1024 * 1024; /* XXX */ 2994 return (0); 2995 } 2996 2997 /* 2998 * Strategy routine. 2999 * For async requests when nfsiod(s) are running, queue the request by 3000 * calling nfs_asyncio(), otherwise just all nfs_doio() to do the 3001 * request. 3002 */ 3003 int 3004 nfs_strategy(v) 3005 void *v; 3006 { 3007 struct vop_strategy_args *ap = v; 3008 struct buf *bp = ap->a_bp; 3009 struct proc *p; 3010 int error = 0; 3011 3012 if ((bp->b_flags & (B_PHYS|B_ASYNC)) == (B_PHYS|B_ASYNC)) 3013 panic("nfs physio/async"); 3014 if (bp->b_flags & B_ASYNC) 3015 p = NULL; 3016 else 3017 p = curproc; /* XXX */ 3018 3019 /* 3020 * If the op is asynchronous and an i/o daemon is waiting 3021 * queue the request, wake it up and wait for completion 3022 * otherwise just do it ourselves. 3023 */ 3024 3025 if ((bp->b_flags & B_ASYNC) == 0 || 3026 nfs_asyncio(bp)) 3027 error = nfs_doio(bp, p); 3028 return (error); 3029 } 3030 3031 /* 3032 * fsync vnode op. Just call nfs_flush() with commit == 1. 3033 */ 3034 /* ARGSUSED */ 3035 int 3036 nfs_fsync(v) 3037 void *v; 3038 { 3039 struct vop_fsync_args /* { 3040 struct vnodeop_desc *a_desc; 3041 struct vnode * a_vp; 3042 struct ucred * a_cred; 3043 int a_flags; 3044 off_t offlo; 3045 off_t offhi; 3046 struct proc * a_p; 3047 } */ *ap = v; 3048 3049 return (nfs_flush(ap->a_vp, ap->a_cred, 3050 (ap->a_flags & FSYNC_WAIT) != 0 ? MNT_WAIT : 0, ap->a_p, 1)); 3051 } 3052 3053 /* 3054 * Flush all the data associated with a vnode. 3055 */ 3056 int 3057 nfs_flush(vp, cred, waitfor, p, commit) 3058 struct vnode *vp; 3059 struct ucred *cred; 3060 int waitfor; 3061 struct proc *p; 3062 int commit; 3063 { 3064 struct nfsnode *np = VTONFS(vp); 3065 int error; 3066 int flushflags = PGO_ALLPAGES|PGO_CLEANIT|PGO_SYNCIO; 3067 UVMHIST_FUNC("nfs_flush"); UVMHIST_CALLED(ubchist); 3068 3069 simple_lock(&vp->v_interlock); 3070 error = VOP_PUTPAGES(vp, 0, 0, flushflags); 3071 if (np->n_flag & NWRITEERR) { 3072 error = np->n_error; 3073 np->n_flag &= ~NWRITEERR; 3074 } 3075 UVMHIST_LOG(ubchist, "returning %d", error,0,0,0); 3076 return (error); 3077 } 3078 3079 /* 3080 * Return POSIX pathconf information applicable to nfs. 3081 * 3082 * N.B. The NFS V2 protocol doesn't support this RPC. 3083 */ 3084 /* ARGSUSED */ 3085 int 3086 nfs_pathconf(v) 3087 void *v; 3088 { 3089 struct vop_pathconf_args /* { 3090 struct vnode *a_vp; 3091 int a_name; 3092 register_t *a_retval; 3093 } */ *ap = v; 3094 struct nfsv3_pathconf *pcp; 3095 struct vnode *vp = ap->a_vp; 3096 struct mbuf *mreq, *mrep, *md, *mb; 3097 int32_t t1, t2; 3098 u_int32_t *tl; 3099 caddr_t bpos, dpos, cp, cp2; 3100 int error = 0, attrflag; 3101 #ifndef NFS_V2_ONLY 3102 struct nfsmount *nmp; 3103 unsigned int l; 3104 u_int64_t maxsize; 3105 #endif 3106 const int v3 = NFS_ISV3(vp); 3107 struct nfsnode *np = VTONFS(vp); 3108 3109 switch (ap->a_name) { 3110 /* Names that can be resolved locally. */ 3111 case _PC_PIPE_BUF: 3112 *ap->a_retval = PIPE_BUF; 3113 break; 3114 case _PC_SYNC_IO: 3115 *ap->a_retval = 1; 3116 break; 3117 /* Names that cannot be resolved locally; do an RPC, if possible. */ 3118 case _PC_LINK_MAX: 3119 case _PC_NAME_MAX: 3120 case _PC_CHOWN_RESTRICTED: 3121 case _PC_NO_TRUNC: 3122 if (!v3) { 3123 error = EINVAL; 3124 break; 3125 } 3126 nfsstats.rpccnt[NFSPROC_PATHCONF]++; 3127 nfsm_reqhead(np, NFSPROC_PATHCONF, NFSX_FH(1)); 3128 nfsm_fhtom(np, 1); 3129 nfsm_request(np, NFSPROC_PATHCONF, 3130 curproc, curproc->p_ucred); /* XXX */ 3131 nfsm_postop_attr(vp, attrflag, 0); 3132 if (!error) { 3133 nfsm_dissect(pcp, struct nfsv3_pathconf *, 3134 NFSX_V3PATHCONF); 3135 switch (ap->a_name) { 3136 case _PC_LINK_MAX: 3137 *ap->a_retval = 3138 fxdr_unsigned(register_t, pcp->pc_linkmax); 3139 break; 3140 case _PC_NAME_MAX: 3141 *ap->a_retval = 3142 fxdr_unsigned(register_t, pcp->pc_namemax); 3143 break; 3144 case _PC_CHOWN_RESTRICTED: 3145 *ap->a_retval = 3146 (pcp->pc_chownrestricted == nfs_true); 3147 break; 3148 case _PC_NO_TRUNC: 3149 *ap->a_retval = 3150 (pcp->pc_notrunc == nfs_true); 3151 break; 3152 } 3153 } 3154 nfsm_reqdone; 3155 break; 3156 case _PC_FILESIZEBITS: 3157 #ifndef NFS_V2_ONLY 3158 if (v3) { 3159 nmp = VFSTONFS(vp->v_mount); 3160 if ((nmp->nm_iflag & NFSMNT_GOTFSINFO) == 0) 3161 if ((error = nfs_fsinfo(nmp, vp, 3162 curproc->p_ucred, curproc)) != 0) /* XXX */ 3163 break; 3164 for (l = 0, maxsize = nmp->nm_maxfilesize; 3165 (maxsize >> l) > 0; l++) 3166 ; 3167 *ap->a_retval = l + 1; 3168 } else 3169 #endif 3170 { 3171 *ap->a_retval = 32; /* NFS V2 limitation */ 3172 } 3173 break; 3174 default: 3175 error = EINVAL; 3176 break; 3177 } 3178 3179 return (error); 3180 } 3181 3182 /* 3183 * NFS advisory byte-level locks. 3184 */ 3185 int 3186 nfs_advlock(v) 3187 void *v; 3188 { 3189 struct vop_advlock_args /* { 3190 struct vnode *a_vp; 3191 caddr_t a_id; 3192 int a_op; 3193 struct flock *a_fl; 3194 int a_flags; 3195 } */ *ap = v; 3196 struct nfsnode *np = VTONFS(ap->a_vp); 3197 3198 return lf_advlock(ap, &np->n_lockf, np->n_size); 3199 } 3200 3201 /* 3202 * Print out the contents of an nfsnode. 3203 */ 3204 int 3205 nfs_print(v) 3206 void *v; 3207 { 3208 struct vop_print_args /* { 3209 struct vnode *a_vp; 3210 } */ *ap = v; 3211 struct vnode *vp = ap->a_vp; 3212 struct nfsnode *np = VTONFS(vp); 3213 3214 printf("tag VT_NFS, fileid %ld fsid 0x%lx", 3215 np->n_vattr->va_fileid, np->n_vattr->va_fsid); 3216 if (vp->v_type == VFIFO) 3217 fifo_printinfo(vp); 3218 printf("\n"); 3219 return (0); 3220 } 3221 3222 /* 3223 * NFS file truncation. 3224 */ 3225 int 3226 nfs_truncate(v) 3227 void *v; 3228 { 3229 #if 0 3230 struct vop_truncate_args /* { 3231 struct vnode *a_vp; 3232 off_t a_length; 3233 int a_flags; 3234 struct ucred *a_cred; 3235 struct proc *a_p; 3236 } */ *ap = v; 3237 #endif 3238 3239 /* Use nfs_setattr */ 3240 return (EOPNOTSUPP); 3241 } 3242 3243 /* 3244 * NFS update. 3245 */ 3246 int 3247 nfs_update(v) 3248 void *v; 3249 #if 0 3250 struct vop_update_args /* { 3251 struct vnode *a_vp; 3252 struct timespec *a_ta; 3253 struct timespec *a_tm; 3254 int a_waitfor; 3255 } */ *ap = v; 3256 #endif 3257 { 3258 3259 /* Use nfs_setattr */ 3260 return (EOPNOTSUPP); 3261 } 3262 3263 /* 3264 * Just call bwrite(). 3265 */ 3266 int 3267 nfs_bwrite(v) 3268 void *v; 3269 { 3270 struct vop_bwrite_args /* { 3271 struct vnode *a_bp; 3272 } */ *ap = v; 3273 3274 return (bwrite(ap->a_bp)); 3275 } 3276 3277 /* 3278 * nfs unlock wrapper. 3279 */ 3280 int 3281 nfs_unlock(void *v) 3282 { 3283 struct vop_unlock_args /* { 3284 struct vnode *a_vp; 3285 int a_flags; 3286 } */ *ap = v; 3287 struct vnode *vp = ap->a_vp; 3288 3289 /* 3290 * VOP_UNLOCK can be called by nfs_loadattrcache 3291 * with v_data == 0. 3292 */ 3293 if (VTONFS(vp)) { 3294 nfs_delayedtruncate(vp); 3295 } 3296 3297 return genfs_unlock(v); 3298 } 3299 3300 /* 3301 * nfs special file access vnode op. 3302 * Essentially just get vattr and then imitate iaccess() since the device is 3303 * local to the client. 3304 */ 3305 int 3306 nfsspec_access(v) 3307 void *v; 3308 { 3309 struct vop_access_args /* { 3310 struct vnode *a_vp; 3311 int a_mode; 3312 struct ucred *a_cred; 3313 struct proc *a_p; 3314 } */ *ap = v; 3315 struct vattr va; 3316 struct vnode *vp = ap->a_vp; 3317 int error; 3318 3319 error = VOP_GETATTR(vp, &va, ap->a_cred, ap->a_p); 3320 if (error) 3321 return (error); 3322 3323 /* 3324 * Disallow write attempts on filesystems mounted read-only; 3325 * unless the file is a socket, fifo, or a block or character 3326 * device resident on the filesystem. 3327 */ 3328 if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { 3329 switch (vp->v_type) { 3330 case VREG: 3331 case VDIR: 3332 case VLNK: 3333 return (EROFS); 3334 default: 3335 break; 3336 } 3337 } 3338 3339 return (vaccess(va.va_type, va.va_mode, 3340 va.va_uid, va.va_gid, ap->a_mode, ap->a_cred)); 3341 } 3342 3343 /* 3344 * Read wrapper for special devices. 3345 */ 3346 int 3347 nfsspec_read(v) 3348 void *v; 3349 { 3350 struct vop_read_args /* { 3351 struct vnode *a_vp; 3352 struct uio *a_uio; 3353 int a_ioflag; 3354 struct ucred *a_cred; 3355 } */ *ap = v; 3356 struct nfsnode *np = VTONFS(ap->a_vp); 3357 3358 /* 3359 * Set access flag. 3360 */ 3361 np->n_flag |= NACC; 3362 np->n_atim.tv_sec = time.tv_sec; 3363 np->n_atim.tv_nsec = time.tv_usec * 1000; 3364 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap)); 3365 } 3366 3367 /* 3368 * Write wrapper for special devices. 3369 */ 3370 int 3371 nfsspec_write(v) 3372 void *v; 3373 { 3374 struct vop_write_args /* { 3375 struct vnode *a_vp; 3376 struct uio *a_uio; 3377 int a_ioflag; 3378 struct ucred *a_cred; 3379 } */ *ap = v; 3380 struct nfsnode *np = VTONFS(ap->a_vp); 3381 3382 /* 3383 * Set update flag. 3384 */ 3385 np->n_flag |= NUPD; 3386 np->n_mtim.tv_sec = time.tv_sec; 3387 np->n_mtim.tv_nsec = time.tv_usec * 1000; 3388 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap)); 3389 } 3390 3391 /* 3392 * Close wrapper for special devices. 3393 * 3394 * Update the times on the nfsnode then do device close. 3395 */ 3396 int 3397 nfsspec_close(v) 3398 void *v; 3399 { 3400 struct vop_close_args /* { 3401 struct vnode *a_vp; 3402 int a_fflag; 3403 struct ucred *a_cred; 3404 struct proc *a_p; 3405 } */ *ap = v; 3406 struct vnode *vp = ap->a_vp; 3407 struct nfsnode *np = VTONFS(vp); 3408 struct vattr vattr; 3409 3410 if (np->n_flag & (NACC | NUPD)) { 3411 np->n_flag |= NCHG; 3412 if (vp->v_usecount == 1 && 3413 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 3414 VATTR_NULL(&vattr); 3415 if (np->n_flag & NACC) 3416 vattr.va_atime = np->n_atim; 3417 if (np->n_flag & NUPD) 3418 vattr.va_mtime = np->n_mtim; 3419 (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_p); 3420 } 3421 } 3422 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap)); 3423 } 3424 3425 /* 3426 * Read wrapper for fifos. 3427 */ 3428 int 3429 nfsfifo_read(v) 3430 void *v; 3431 { 3432 struct vop_read_args /* { 3433 struct vnode *a_vp; 3434 struct uio *a_uio; 3435 int a_ioflag; 3436 struct ucred *a_cred; 3437 } */ *ap = v; 3438 struct nfsnode *np = VTONFS(ap->a_vp); 3439 3440 /* 3441 * Set access flag. 3442 */ 3443 np->n_flag |= NACC; 3444 np->n_atim.tv_sec = time.tv_sec; 3445 np->n_atim.tv_nsec = time.tv_usec * 1000; 3446 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap)); 3447 } 3448 3449 /* 3450 * Write wrapper for fifos. 3451 */ 3452 int 3453 nfsfifo_write(v) 3454 void *v; 3455 { 3456 struct vop_write_args /* { 3457 struct vnode *a_vp; 3458 struct uio *a_uio; 3459 int a_ioflag; 3460 struct ucred *a_cred; 3461 } */ *ap = v; 3462 struct nfsnode *np = VTONFS(ap->a_vp); 3463 3464 /* 3465 * Set update flag. 3466 */ 3467 np->n_flag |= NUPD; 3468 np->n_mtim.tv_sec = time.tv_sec; 3469 np->n_mtim.tv_nsec = time.tv_usec * 1000; 3470 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap)); 3471 } 3472 3473 /* 3474 * Close wrapper for fifos. 3475 * 3476 * Update the times on the nfsnode then do fifo close. 3477 */ 3478 int 3479 nfsfifo_close(v) 3480 void *v; 3481 { 3482 struct vop_close_args /* { 3483 struct vnode *a_vp; 3484 int a_fflag; 3485 struct ucred *a_cred; 3486 struct proc *a_p; 3487 } */ *ap = v; 3488 struct vnode *vp = ap->a_vp; 3489 struct nfsnode *np = VTONFS(vp); 3490 struct vattr vattr; 3491 3492 if (np->n_flag & (NACC | NUPD)) { 3493 if (np->n_flag & NACC) { 3494 np->n_atim.tv_sec = time.tv_sec; 3495 np->n_atim.tv_nsec = time.tv_usec * 1000; 3496 } 3497 if (np->n_flag & NUPD) { 3498 np->n_mtim.tv_sec = time.tv_sec; 3499 np->n_mtim.tv_nsec = time.tv_usec * 1000; 3500 } 3501 np->n_flag |= NCHG; 3502 if (vp->v_usecount == 1 && 3503 (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 3504 VATTR_NULL(&vattr); 3505 if (np->n_flag & NACC) 3506 vattr.va_atime = np->n_atim; 3507 if (np->n_flag & NUPD) 3508 vattr.va_mtime = np->n_mtim; 3509 (void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_p); 3510 } 3511 } 3512 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap)); 3513 } 3514