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