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