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