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