1/* $NetBSD: vnode_impl.h,v 1.27 2023/08/01 16:33:43 dholland 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 36struct namecache; 37struct nchnode; 38 39enum 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 49TAILQ_HEAD(vnodelst, vnode_impl); 50typedef struct vnodelst vnodelst_t; 51 52struct 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 both vi_nc_lock + vi_nc_listlock to modify, either to read 70 * s syncer_data_lock 71 */ 72struct 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}; 121typedef 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 */ 129void _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 */ 148const char * 149 vstate_name(enum vnode_state); 150vnode_t * 151 vnalloc_marker(struct mount *); 152void vnfree_marker(vnode_t *); 153bool vnis_marker(vnode_t *); 154void vcache_make_anon(vnode_t *); 155int vcache_vget(vnode_t *); 156int vcache_tryvget(vnode_t *); 157int vfs_drainvnodes(void); 158 159SDT_PROVIDER_DECLARE(vfs); 160 161#endif /* defined(_KERNEL) || defined(_KMEMUSER) */ 162#endif /* !_SYS_VNODE_IMPL_H_ */ 163