xref: /netbsd/sys/sys/vnode_impl.h (revision 2c948cf0)
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