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