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