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