1 /* $NetBSD: vnode_impl.h,v 1.26 2023/04/29 10:07:05 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 2016, 2019, 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef _SYS_VNODE_IMPL_H_ 30 #define _SYS_VNODE_IMPL_H_ 31 #if defined(_KERNEL) || defined(_KMEMUSER) 32 33 #include <sys/sdt.h> 34 #include <sys/vnode.h> 35 36 struct namecache; 37 struct nchnode; 38 39 enum vnode_state { 40 VS_ACTIVE, /* Assert only, fs node attached and usecount > 0. */ 41 VS_MARKER, /* Stable, used as marker. Will not change. */ 42 VS_LOADING, /* Intermediate, initialising the fs node. */ 43 VS_LOADED, /* Stable, valid fs node attached. */ 44 VS_BLOCKED, /* Intermediate, active, no new references allowed. */ 45 VS_RECLAIMING, /* Intermediate, detaching the fs node. */ 46 VS_RECLAIMED /* Stable, no fs node attached. */ 47 }; 48 49 TAILQ_HEAD(vnodelst, vnode_impl); 50 typedef struct vnodelst vnodelst_t; 51 52 struct vcache_key { 53 struct mount *vk_mount; 54 const void *vk_key; 55 size_t vk_key_len; 56 }; 57 58 /* 59 * Reading or writing any of these items requires holding the appropriate 60 * lock. Field markings and the corresponding locks: 61 * 62 * - stable throughout the life of the vnode 63 * c vcache_lock 64 * d vdrain_lock 65 * i v_interlock 66 * l vi_nc_listlock 67 * m mnt_vnodelock 68 * n vi_nc_lock 69 * n,l vi_nc_lock + vi_nc_listlock to modify 70 * s syncer_data_lock 71 */ 72 struct vnode_impl { 73 struct vnode vi_vnode; 74 75 /* 76 * Largely stable data. 77 */ 78 struct vcache_key vi_key; /* c vnode cache key */ 79 80 /* 81 * The vnode klist is accessed frequently, but rarely 82 * modified. 83 */ 84 struct vnode_klist vi_klist; /* i kevent / knote state */ 85 86 /* 87 * vnode cache, LRU and syncer. This all changes with some 88 * regularity so keep it together. 89 */ 90 struct vnodelst *vi_lrulisthd; /* d current lru list head */ 91 TAILQ_ENTRY(vnode_impl) vi_lrulist; /* d lru list */ 92 int vi_synclist_slot; /* s synclist slot index */ 93 int vi_lrulisttm; /* i time of lru enqueue */ 94 TAILQ_ENTRY(vnode_impl) vi_synclist; /* s vnodes with dirty bufs */ 95 SLIST_ENTRY(vnode_impl) vi_hash; /* c vnode cache list */ 96 enum vnode_state vi_state; /* i current state */ 97 TAILQ_ENTRY(vnode_impl) vi_mntvnodes; /* m vnodes for mount point */ 98 99 /* 100 * Namecache. Give it a separate line so activity doesn't impinge 101 * on the stable stuff. 102 */ 103 rb_tree_t vi_nc_tree /* n namecache tree */ 104 __aligned(COHERENCY_UNIT); 105 TAILQ_HEAD(,namecache) vi_nc_list; /* l namecaches (parent) */ 106 mode_t vi_nc_mode; /* n,l cached mode or VNOVAL */ 107 uid_t vi_nc_uid; /* n,l cached UID or VNOVAL */ 108 gid_t vi_nc_gid; /* n,l cached GID or VNOVAL */ 109 uint32_t vi_nc_spare; /* - spare (padding) */ 110 111 /* 112 * Locks and expensive to access items which can be expected to 113 * generate a cache miss. 114 */ 115 krwlock_t vi_lock /* - lock for this vnode */ 116 __aligned(COHERENCY_UNIT); 117 krwlock_t vi_nc_lock /* - lock on node */ 118 __aligned(COHERENCY_UNIT); 119 krwlock_t vi_nc_listlock; /* - lock on nn_list */ 120 }; 121 typedef struct vnode_impl vnode_impl_t; 122 123 #define VIMPL_TO_VNODE(vip) (&(vip)->vi_vnode) 124 #define VNODE_TO_VIMPL(vp) container_of((vp), struct vnode_impl, vi_vnode) 125 126 /* 127 * Vnode state assertion. 128 */ 129 void _vstate_assert(vnode_t *, enum vnode_state, const char *, int, bool); 130 131 #if defined(DIAGNOSTIC) 132 133 #define VSTATE_ASSERT(vp, state) \ 134 _vstate_assert((vp), (state), __func__, __LINE__, true) 135 #define VSTATE_ASSERT_UNLOCKED(vp, state) \ 136 _vstate_assert((vp), (state), __func__, __LINE__, false) 137 138 #else /* defined(DIAGNOSTIC) */ 139 140 #define VSTATE_ASSERT(vp, state) 141 #define VSTATE_ASSERT_UNLOCKED(vp, state) 142 143 #endif /* defined(DIAGNOSTIC) */ 144 145 /* 146 * Vnode manipulation functions. 147 */ 148 const char * 149 vstate_name(enum vnode_state); 150 vnode_t * 151 vnalloc_marker(struct mount *); 152 void vnfree_marker(vnode_t *); 153 bool vnis_marker(vnode_t *); 154 void vcache_make_anon(vnode_t *); 155 int vcache_vget(vnode_t *); 156 int vcache_tryvget(vnode_t *); 157 int vfs_drainvnodes(void); 158 159 SDT_PROVIDER_DECLARE(vfs); 160 161 #endif /* defined(_KERNEL) || defined(_KMEMUSER) */ 162 #endif /* !_SYS_VNODE_IMPL_H_ */ 163