19ec7b004SRick Macklem /*- 251369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 351369649SPedro F. Giffuni * 49ec7b004SRick Macklem * Copyright (c) 1989, 1993 59ec7b004SRick Macklem * The Regents of the University of California. All rights reserved. 69ec7b004SRick Macklem * 79ec7b004SRick Macklem * This code is derived from software contributed to Berkeley by 89ec7b004SRick Macklem * Rick Macklem at The University of Guelph. 99ec7b004SRick Macklem * 109ec7b004SRick Macklem * Redistribution and use in source and binary forms, with or without 119ec7b004SRick Macklem * modification, are permitted provided that the following conditions 129ec7b004SRick Macklem * are met: 139ec7b004SRick Macklem * 1. Redistributions of source code must retain the above copyright 149ec7b004SRick Macklem * notice, this list of conditions and the following disclaimer. 159ec7b004SRick Macklem * 2. Redistributions in binary form must reproduce the above copyright 169ec7b004SRick Macklem * notice, this list of conditions and the following disclaimer in the 179ec7b004SRick Macklem * documentation and/or other materials provided with the distribution. 18fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 199ec7b004SRick Macklem * may be used to endorse or promote products derived from this software 209ec7b004SRick Macklem * without specific prior written permission. 219ec7b004SRick Macklem * 229ec7b004SRick Macklem * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 239ec7b004SRick Macklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 249ec7b004SRick Macklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 259ec7b004SRick Macklem * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 269ec7b004SRick Macklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 279ec7b004SRick Macklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 289ec7b004SRick Macklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 299ec7b004SRick Macklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 309ec7b004SRick Macklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 319ec7b004SRick Macklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 329ec7b004SRick Macklem * SUCH DAMAGE. 339ec7b004SRick Macklem * 349ec7b004SRick Macklem * from nfs_node.c 8.6 (Berkeley) 5/22/95 359ec7b004SRick Macklem */ 369ec7b004SRick Macklem 379ec7b004SRick Macklem #include <sys/cdefs.h> 389ec7b004SRick Macklem __FBSDID("$FreeBSD$"); 399ec7b004SRick Macklem 409ec7b004SRick Macklem #include <sys/param.h> 419ec7b004SRick Macklem #include <sys/systm.h> 42ca27c028SRick Macklem #include <sys/fcntl.h> 439ec7b004SRick Macklem #include <sys/lock.h> 449ec7b004SRick Macklem #include <sys/malloc.h> 459ec7b004SRick Macklem #include <sys/mount.h> 469ec7b004SRick Macklem #include <sys/namei.h> 479ec7b004SRick Macklem #include <sys/proc.h> 489ec7b004SRick Macklem #include <sys/socket.h> 499ec7b004SRick Macklem #include <sys/sysctl.h> 50e2eb210cSRick Macklem #include <sys/taskqueue.h> 519ec7b004SRick Macklem #include <sys/vnode.h> 529ec7b004SRick Macklem 539ec7b004SRick Macklem #include <vm/uma.h> 549ec7b004SRick Macklem 559ec7b004SRick Macklem #include <fs/nfs/nfsport.h> 569ec7b004SRick Macklem #include <fs/nfsclient/nfsnode.h> 579ec7b004SRick Macklem #include <fs/nfsclient/nfsmount.h> 589ec7b004SRick Macklem #include <fs/nfsclient/nfs.h> 598f0e65c9SRick Macklem #include <fs/nfsclient/nfs_kdtrace.h> 609ec7b004SRick Macklem 61ca27c028SRick Macklem #include <nfs/nfs_lock.h> 62ca27c028SRick Macklem 639ec7b004SRick Macklem extern struct vop_vector newnfs_vnodeops; 649ec7b004SRick Macklem extern struct buf_ops buf_ops_newnfs; 659ec7b004SRick Macklem MALLOC_DECLARE(M_NEWNFSREQ); 669ec7b004SRick Macklem 679ec7b004SRick Macklem uma_zone_t newnfsnode_zone; 689ec7b004SRick Macklem 6943a993bbSKirk McKusick const char nfs_vnode_tag[] = "nfs"; 7043a993bbSKirk McKusick 71e2eb210cSRick Macklem static void nfs_freesillyrename(void *arg, __unused int pending); 72e2eb210cSRick Macklem 739ec7b004SRick Macklem void 749ec7b004SRick Macklem ncl_nhinit(void) 759ec7b004SRick Macklem { 769ec7b004SRick Macklem 779ec7b004SRick Macklem newnfsnode_zone = uma_zcreate("NCLNODE", sizeof(struct nfsnode), NULL, 789ec7b004SRick Macklem NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 799ec7b004SRick Macklem } 809ec7b004SRick Macklem 819ec7b004SRick Macklem void 829ec7b004SRick Macklem ncl_nhuninit(void) 839ec7b004SRick Macklem { 849ec7b004SRick Macklem uma_zdestroy(newnfsnode_zone); 859ec7b004SRick Macklem } 869ec7b004SRick Macklem 879ec7b004SRick Macklem /* 889ec7b004SRick Macklem * ONLY USED FOR THE ROOT DIRECTORY. nfscl_nget() does the rest. If this 899ec7b004SRick Macklem * function is going to be used to get Regular Files, code must be added 909ec7b004SRick Macklem * to fill in the "struct nfsv4node". 919ec7b004SRick Macklem * Look up a vnode/nfsnode by file handle. 929ec7b004SRick Macklem * Callers must check for mount points!! 939ec7b004SRick Macklem * In all cases, a pointer to a 949ec7b004SRick Macklem * nfsnode structure is returned. 959ec7b004SRick Macklem */ 969ec7b004SRick Macklem int 974b3a38ecSRick Macklem ncl_nget(struct mount *mntp, u_int8_t *fhp, int fhsize, struct nfsnode **npp, 984b3a38ecSRick Macklem int lkflags) 999ec7b004SRick Macklem { 1009ec7b004SRick Macklem struct thread *td = curthread; /* XXX */ 1019ec7b004SRick Macklem struct nfsnode *np; 1029ec7b004SRick Macklem struct vnode *vp; 1039ec7b004SRick Macklem struct vnode *nvp; 1049ec7b004SRick Macklem int error; 1059ec7b004SRick Macklem u_int hash; 1069ec7b004SRick Macklem struct nfsmount *nmp; 1079ec7b004SRick Macklem struct nfsfh *nfhp; 1089ec7b004SRick Macklem 1099ec7b004SRick Macklem nmp = VFSTONFS(mntp); 1109ec7b004SRick Macklem *npp = NULL; 1119ec7b004SRick Macklem 1129ec7b004SRick Macklem hash = fnv_32_buf(fhp, fhsize, FNV1_32_INIT); 1139ec7b004SRick Macklem 114222daa42SConrad Meyer nfhp = malloc(sizeof (struct nfsfh) + fhsize, 1159ec7b004SRick Macklem M_NFSFH, M_WAITOK); 1169ec7b004SRick Macklem bcopy(fhp, &nfhp->nfh_fh[0], fhsize); 1179ec7b004SRick Macklem nfhp->nfh_len = fhsize; 1184b3a38ecSRick Macklem error = vfs_hash_get(mntp, hash, lkflags, 1199ec7b004SRick Macklem td, &nvp, newnfs_vncmpf, nfhp); 120222daa42SConrad Meyer free(nfhp, M_NFSFH); 1219ec7b004SRick Macklem if (error) 1229ec7b004SRick Macklem return (error); 1239ec7b004SRick Macklem if (nvp != NULL) { 1249ec7b004SRick Macklem *npp = VTONFS(nvp); 1259ec7b004SRick Macklem return (0); 1269ec7b004SRick Macklem } 1279ec7b004SRick Macklem np = uma_zalloc(newnfsnode_zone, M_WAITOK | M_ZERO); 1289ec7b004SRick Macklem 12943a993bbSKirk McKusick error = getnewvnode(nfs_vnode_tag, mntp, &newnfs_vnodeops, &nvp); 1309ec7b004SRick Macklem if (error) { 1319ec7b004SRick Macklem uma_zfree(newnfsnode_zone, np); 1329ec7b004SRick Macklem return (error); 1339ec7b004SRick Macklem } 1349ec7b004SRick Macklem vp = nvp; 1357f763fc3SRick Macklem KASSERT(vp->v_bufobj.bo_bsize != 0, ("ncl_nget: bo_bsize == 0")); 1369ec7b004SRick Macklem vp->v_bufobj.bo_ops = &buf_ops_newnfs; 1379ec7b004SRick Macklem vp->v_data = np; 1389ec7b004SRick Macklem np->n_vnode = vp; 1399ec7b004SRick Macklem /* 1409ec7b004SRick Macklem * Initialize the mutex even if the vnode is going to be a loser. 1419ec7b004SRick Macklem * This simplifies the logic in reclaim, which can then unconditionally 1429ec7b004SRick Macklem * destroy the mutex (in the case of the loser, or if hash_insert 1439ec7b004SRick Macklem * happened to return an error no special casing is needed). 1449ec7b004SRick Macklem */ 1459ec7b004SRick Macklem mtx_init(&np->n_mtx, "NEWNFSnode lock", NULL, MTX_DEF | MTX_DUPOK); 146e5cffdd3SKonstantin Belousov lockinit(&np->n_excl, PVFS, "nfsupg", VLKTIMEOUT, LK_NOSHARE | 147e5cffdd3SKonstantin Belousov LK_CANRECURSE); 148e5cffdd3SKonstantin Belousov 1499ec7b004SRick Macklem /* 1509ec7b004SRick Macklem * NFS supports recursive and shared locking. 1519ec7b004SRick Macklem */ 1523634d5b2SJohn Baldwin lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL); 1539ec7b004SRick Macklem VN_LOCK_AREC(vp); 1549ec7b004SRick Macklem VN_LOCK_ASHARE(vp); 1559ec7b004SRick Macklem /* 1569ec7b004SRick Macklem * Are we getting the root? If so, make sure the vnode flags 1579ec7b004SRick Macklem * are correct 1589ec7b004SRick Macklem */ 1599ec7b004SRick Macklem if ((fhsize == nmp->nm_fhsize) && 1609ec7b004SRick Macklem !bcmp(fhp, nmp->nm_fh, fhsize)) { 1619ec7b004SRick Macklem if (vp->v_type == VNON) 1629ec7b004SRick Macklem vp->v_type = VDIR; 1639ec7b004SRick Macklem vp->v_vflag |= VV_ROOT; 1649ec7b004SRick Macklem } 165c6ba06d8SKonstantin Belousov 166c6ba06d8SKonstantin Belousov vp->v_vflag |= VV_VMSIZEVNLOCK; 1679ec7b004SRick Macklem 168222daa42SConrad Meyer np->n_fhp = malloc(sizeof (struct nfsfh) + fhsize, 1699ec7b004SRick Macklem M_NFSFH, M_WAITOK); 1709ec7b004SRick Macklem bcopy(fhp, np->n_fhp->nfh_fh, fhsize); 1719ec7b004SRick Macklem np->n_fhp->nfh_len = fhsize; 1729ec7b004SRick Macklem error = insmntque(vp, mntp); 1739ec7b004SRick Macklem if (error != 0) { 1749ec7b004SRick Macklem *npp = NULL; 175222daa42SConrad Meyer free(np->n_fhp, M_NFSFH); 1769ec7b004SRick Macklem mtx_destroy(&np->n_mtx); 177e5cffdd3SKonstantin Belousov lockdestroy(&np->n_excl); 1789ec7b004SRick Macklem uma_zfree(newnfsnode_zone, np); 1799ec7b004SRick Macklem return (error); 1809ec7b004SRick Macklem } 181*829f0bcbSMateusz Guzik vn_set_state(vp, VSTATE_CONSTRUCTED); 1824b3a38ecSRick Macklem error = vfs_hash_insert(vp, hash, lkflags, 1839ec7b004SRick Macklem td, &nvp, newnfs_vncmpf, np->n_fhp); 1849ec7b004SRick Macklem if (error) 1859ec7b004SRick Macklem return (error); 1869ec7b004SRick Macklem if (nvp != NULL) { 1879ec7b004SRick Macklem *npp = VTONFS(nvp); 1889ec7b004SRick Macklem /* vfs_hash_insert() vput()'s the losing vnode */ 1899ec7b004SRick Macklem return (0); 1909ec7b004SRick Macklem } 1919ec7b004SRick Macklem *npp = np; 1929ec7b004SRick Macklem 1939ec7b004SRick Macklem return (0); 1949ec7b004SRick Macklem } 1959ec7b004SRick Macklem 196e2eb210cSRick Macklem /* 197e2eb210cSRick Macklem * Do the vrele(sp->s_dvp) as a separate task in order to avoid a 198e2eb210cSRick Macklem * deadlock because of a LOR when vrele() locks the directory vnode. 199e2eb210cSRick Macklem */ 200e2eb210cSRick Macklem static void 201e2eb210cSRick Macklem nfs_freesillyrename(void *arg, __unused int pending) 202e2eb210cSRick Macklem { 203e2eb210cSRick Macklem struct sillyrename *sp; 204e2eb210cSRick Macklem 205e2eb210cSRick Macklem sp = arg; 206e2eb210cSRick Macklem vrele(sp->s_dvp); 207e2eb210cSRick Macklem free(sp, M_NEWNFSREQ); 208e2eb210cSRick Macklem } 209e2eb210cSRick Macklem 2108f73d398SKonstantin Belousov static void 2118f73d398SKonstantin Belousov ncl_releasesillyrename(struct vnode *vp, struct thread *td) 2129ec7b004SRick Macklem { 2139ec7b004SRick Macklem struct nfsnode *np; 2149ec7b004SRick Macklem struct sillyrename *sp; 2158f73d398SKonstantin Belousov 2168f73d398SKonstantin Belousov ASSERT_VOP_ELOCKED(vp, "releasesillyrename"); 2178f73d398SKonstantin Belousov np = VTONFS(vp); 218ee7201a7SRick Macklem NFSASSERTNODE(np); 2198f73d398SKonstantin Belousov if (vp->v_type != VDIR) { 2208f73d398SKonstantin Belousov sp = np->n_sillyrename; 2218f73d398SKonstantin Belousov np->n_sillyrename = NULL; 2228f73d398SKonstantin Belousov } else 2238f73d398SKonstantin Belousov sp = NULL; 2248f73d398SKonstantin Belousov if (sp != NULL) { 2255d85e12fSRick Macklem NFSUNLOCKNODE(np); 2268f73d398SKonstantin Belousov (void) ncl_vinvalbuf(vp, 0, td, 1); 2278f73d398SKonstantin Belousov /* 2288f73d398SKonstantin Belousov * Remove the silly file that was rename'd earlier 2298f73d398SKonstantin Belousov */ 2308f73d398SKonstantin Belousov ncl_removeit(sp, vp); 2318f73d398SKonstantin Belousov crfree(sp->s_cred); 2328f73d398SKonstantin Belousov TASK_INIT(&sp->s_task, 0, nfs_freesillyrename, sp); 2338f73d398SKonstantin Belousov taskqueue_enqueue(taskqueue_thread, &sp->s_task); 2345d85e12fSRick Macklem NFSLOCKNODE(np); 2358f73d398SKonstantin Belousov } 2368f73d398SKonstantin Belousov } 2378f73d398SKonstantin Belousov 2388f73d398SKonstantin Belousov int 2398f73d398SKonstantin Belousov ncl_inactive(struct vop_inactive_args *ap) 2408f73d398SKonstantin Belousov { 241d00a615aSRick Macklem struct vnode *vp = ap->a_vp; 24220de93c6SKonstantin Belousov struct nfsnode *np; 243ab21ed17SMateusz Guzik struct thread *td; 24453e1b8fbSRick Macklem boolean_t retv; 2459ec7b004SRick Macklem 246ab21ed17SMateusz Guzik td = curthread; 247efea1bc1SRick Macklem np = VTONFS(vp); 248d00a615aSRick Macklem if (NFS_ISV4(vp) && vp->v_type == VREG) { 249efea1bc1SRick Macklem NFSLOCKNODE(np); 250efea1bc1SRick Macklem np->n_openstateid = NULL; 251efea1bc1SRick Macklem NFSUNLOCKNODE(np); 25247a59856SRick Macklem /* 253fdd88deeSRick Macklem * Since mmap()'d files do I/O after VOP_CLOSE(), the NFSv4 25453e1b8fbSRick Macklem * Close operations are delayed until now. Any dirty 25553e1b8fbSRick Macklem * buffers/pages must be flushed before the close, so that the 25653e1b8fbSRick Macklem * stateid is available for the writes. 25747a59856SRick Macklem */ 25853e1b8fbSRick Macklem if (vp->v_object != NULL) { 25989f6b863SAttilio Rao VM_OBJECT_WLOCK(vp->v_object); 26053e1b8fbSRick Macklem retv = vm_object_page_clean(vp->v_object, 0, 0, 26153e1b8fbSRick Macklem OBJPC_SYNC); 26289f6b863SAttilio Rao VM_OBJECT_WUNLOCK(vp->v_object); 26353e1b8fbSRick Macklem } else 26453e1b8fbSRick Macklem retv = TRUE; 26553e1b8fbSRick Macklem if (retv == TRUE) { 266ab21ed17SMateusz Guzik (void)ncl_flush(vp, MNT_WAIT, td, 1, 0); 267ab21ed17SMateusz Guzik (void)nfsrpc_close(vp, 1, td); 268fdd88deeSRick Macklem } 26953e1b8fbSRick Macklem } 27047a59856SRick Macklem 2715d85e12fSRick Macklem NFSLOCKNODE(np); 272ab21ed17SMateusz Guzik ncl_releasesillyrename(vp, td); 27320de93c6SKonstantin Belousov 27420de93c6SKonstantin Belousov /* 27520de93c6SKonstantin Belousov * NMODIFIED means that there might be dirty/stale buffers 27681b07aacSRick Macklem * associated with the NFS vnode. 27781b07aacSRick Macklem * NDSCOMMIT means that the file is on a pNFS server and commits 27881b07aacSRick Macklem * should be done to the DS. 27981b07aacSRick Macklem * None of the other flags are meaningful after the vnode is unused. 28020de93c6SKonstantin Belousov */ 28181b07aacSRick Macklem np->n_flag &= (NMODIFIED | NDSCOMMIT); 2825d85e12fSRick Macklem NFSUNLOCKNODE(np); 2839ec7b004SRick Macklem return (0); 2849ec7b004SRick Macklem } 2859ec7b004SRick Macklem 2869ec7b004SRick Macklem /* 2879ec7b004SRick Macklem * Reclaim an nfsnode so that it can be used for other purposes. 2889ec7b004SRick Macklem */ 2899ec7b004SRick Macklem int 2909ec7b004SRick Macklem ncl_reclaim(struct vop_reclaim_args *ap) 2919ec7b004SRick Macklem { 2929ec7b004SRick Macklem struct vnode *vp = ap->a_vp; 2939ec7b004SRick Macklem struct nfsnode *np = VTONFS(vp); 2949ec7b004SRick Macklem struct nfsdmap *dp, *dp2; 2958f226f4cSMateusz Guzik struct thread *td; 296f6fec55fSRick Macklem struct mount *mp; 2978f226f4cSMateusz Guzik 2988f226f4cSMateusz Guzik td = curthread; 299f6fec55fSRick Macklem mp = vp->v_mount; 3009ec7b004SRick Macklem 3019ec7b004SRick Macklem /* 3029ec7b004SRick Macklem * If the NLM is running, give it a chance to abort pending 3039ec7b004SRick Macklem * locks. 3049ec7b004SRick Macklem */ 305ca27c028SRick Macklem if (nfs_reclaim_p != NULL) 306ca27c028SRick Macklem nfs_reclaim_p(ap); 3079ec7b004SRick Macklem 3085d85e12fSRick Macklem NFSLOCKNODE(np); 3098f226f4cSMateusz Guzik ncl_releasesillyrename(vp, td); 3108f73d398SKonstantin Belousov 311aad78046SRick Macklem if (NFS_ISV4(vp) && vp->v_type == VREG) { 312efea1bc1SRick Macklem np->n_openstateid = NULL; 313efea1bc1SRick Macklem NFSUNLOCKNODE(np); 31479cafccdSRick Macklem /* 31579cafccdSRick Macklem * We can now safely close any remaining NFSv4 Opens for 31679cafccdSRick Macklem * this file. Most opens will have already been closed by 31779cafccdSRick Macklem * ncl_inactive(), but there are cases where it is not 31879cafccdSRick Macklem * called, so we need to do it again here. 31979cafccdSRick Macklem */ 3208f226f4cSMateusz Guzik (void) nfsrpc_close(vp, 1, td); 321aad78046SRick Macklem /* 322aad78046SRick Macklem * It it unlikely a delegation will still exist, but 323aad78046SRick Macklem * if one does, it must be returned before calling 324aad78046SRick Macklem * vfs_hash_remove(), since it cannot be recalled once the 325aad78046SRick Macklem * nfs node is no longer available. 326aad78046SRick Macklem */ 327f6fec55fSRick Macklem MNT_ILOCK(mp); 328f6fec55fSRick Macklem if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) == 0) { 329f6fec55fSRick Macklem MNT_IUNLOCK(mp); 330aad78046SRick Macklem nfscl_delegreturnvp(vp, td); 331f6fec55fSRick Macklem } else 332f6fec55fSRick Macklem MNT_IUNLOCK(mp); 333efea1bc1SRick Macklem } else 334efea1bc1SRick Macklem NFSUNLOCKNODE(np); 33579cafccdSRick Macklem 3369ec7b004SRick Macklem vfs_hash_remove(vp); 3379ec7b004SRick Macklem 3389ec7b004SRick Macklem /* 3399ec7b004SRick Macklem * Call nfscl_reclaimnode() to save attributes in the delegation, 3409ec7b004SRick Macklem * as required. 3419ec7b004SRick Macklem */ 3429ec7b004SRick Macklem if (vp->v_type == VREG) 3439ec7b004SRick Macklem nfscl_reclaimnode(vp); 3449ec7b004SRick Macklem 3459ec7b004SRick Macklem /* 3469ec7b004SRick Macklem * Free up any directory cookie structures and 3479ec7b004SRick Macklem * large file handle structures that might be associated with 3489ec7b004SRick Macklem * this nfs node. 3499ec7b004SRick Macklem */ 3509ec7b004SRick Macklem if (vp->v_type == VDIR) { 3519ec7b004SRick Macklem dp = LIST_FIRST(&np->n_cookies); 3529ec7b004SRick Macklem while (dp) { 3539ec7b004SRick Macklem dp2 = dp; 3549ec7b004SRick Macklem dp = LIST_NEXT(dp, ndm_list); 355222daa42SConrad Meyer free(dp2, M_NFSDIROFF); 3569ec7b004SRick Macklem } 3579ec7b004SRick Macklem } 3587af1242aSRick Macklem if (np->n_writecred != NULL) 3597af1242aSRick Macklem crfree(np->n_writecred); 360222daa42SConrad Meyer free(np->n_fhp, M_NFSFH); 3619ec7b004SRick Macklem if (np->n_v4 != NULL) 362222daa42SConrad Meyer free(np->n_v4, M_NFSV4NODE); 3639ec7b004SRick Macklem mtx_destroy(&np->n_mtx); 364e5cffdd3SKonstantin Belousov lockdestroy(&np->n_excl); 3659ec7b004SRick Macklem uma_zfree(newnfsnode_zone, vp->v_data); 3669ec7b004SRick Macklem vp->v_data = NULL; 3679ec7b004SRick Macklem return (0); 3689ec7b004SRick Macklem } 3699ec7b004SRick Macklem 3709ec7b004SRick Macklem /* 3719ec7b004SRick Macklem * Invalidate both the access and attribute caches for this vnode. 3729ec7b004SRick Macklem */ 3739ec7b004SRick Macklem void 3749ec7b004SRick Macklem ncl_invalcaches(struct vnode *vp) 3759ec7b004SRick Macklem { 3769ec7b004SRick Macklem struct nfsnode *np = VTONFS(vp); 3779ec7b004SRick Macklem int i; 3789ec7b004SRick Macklem 3795d85e12fSRick Macklem NFSLOCKNODE(np); 3809ec7b004SRick Macklem for (i = 0; i < NFS_ACCESSCACHESIZE; i++) 3819ec7b004SRick Macklem np->n_accesscache[i].stamp = 0; 3828f0e65c9SRick Macklem KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp); 3839ec7b004SRick Macklem np->n_attrstamp = 0; 3848f0e65c9SRick Macklem KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); 3855d85e12fSRick Macklem NFSUNLOCKNODE(np); 3869ec7b004SRick Macklem } 387