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_ */