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