master
  1/*	$NetBSD: vnode_impl.h,v 1.24 2022/07/18 04:30:30 thorpej 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/vnode.h>
 34
 35struct namecache;
 36struct nchnode;
 37
 38enum vnode_state {
 39	VS_ACTIVE,	/* Assert only, fs node attached and usecount > 0. */
 40	VS_MARKER,	/* Stable, used as marker. Will not change. */
 41	VS_LOADING,	/* Intermediate, initialising the fs node. */
 42	VS_LOADED,	/* Stable, valid fs node attached. */
 43	VS_BLOCKED,	/* Intermediate, active, no new references allowed. */
 44	VS_RECLAIMING,	/* Intermediate, detaching the fs node. */
 45	VS_RECLAIMED	/* Stable, no fs node attached. */
 46};
 47
 48TAILQ_HEAD(vnodelst, vnode_impl);
 49typedef struct vnodelst vnodelst_t;
 50
 51struct vcache_key {
 52	struct mount *vk_mount;
 53	const void *vk_key;
 54	size_t vk_key_len;
 55};
 56
 57/*
 58 * Reading or writing any of these items requires holding the appropriate
 59 * lock.  Field markings and the corresponding locks:
 60 *
 61 *	-	stable throughout the life of the vnode
 62 *	c	vcache_lock
 63 *	d	vdrain_lock
 64 *	i	v_interlock
 65 *	l	vi_nc_listlock
 66 *	m	mnt_vnodelock
 67 *	n	vi_nc_lock
 68 *	n,l	vi_nc_lock + vi_nc_listlock to modify
 69 *	s	syncer_data_lock
 70 */
 71struct vnode_impl {
 72	struct vnode vi_vnode;
 73
 74	/*
 75	 * Largely stable data.
 76	 */
 77	struct vcache_key vi_key;		/* c   vnode cache key */
 78
 79	/*
 80	 * The vnode klist is accessed frequently, but rarely
 81	 * modified.
 82	 */
 83	struct vnode_klist vi_klist;		/* i   kevent / knote state */
 84
 85	/*
 86	 * vnode cache, LRU and syncer.  This all changes with some
 87	 * regularity so keep it together.
 88	 */
 89	struct vnodelst	*vi_lrulisthd;		/* d   current lru list head */
 90	TAILQ_ENTRY(vnode_impl) vi_lrulist;	/* d   lru list */
 91	int 		vi_synclist_slot;	/* s   synclist slot index */
 92	int 		vi_lrulisttm;		/* i   time of lru enqueue */
 93	TAILQ_ENTRY(vnode_impl) vi_synclist;	/* s   vnodes with dirty bufs */
 94	SLIST_ENTRY(vnode_impl) vi_hash;	/* c   vnode cache list */
 95	enum vnode_state vi_state;		/* i   current state */
 96	TAILQ_ENTRY(vnode_impl) vi_mntvnodes;	/* m   vnodes for mount point */
 97
 98	/*
 99	 * Namecache.  Give it a separate line so activity doesn't impinge
100	 * on the stable stuff.
101	 */
102	rb_tree_t	vi_nc_tree		/* n   namecache tree */
103	    __aligned(COHERENCY_UNIT);
104	TAILQ_HEAD(,namecache) vi_nc_list;	/* l   namecaches (parent) */
105	mode_t		vi_nc_mode;		/* n,l cached mode or VNOVAL */
106	uid_t		vi_nc_uid;		/* n,l cached UID or VNOVAL */
107	gid_t		vi_nc_gid;		/* n,l cached GID or VNOVAL */
108	uint32_t	vi_nc_spare;		/* -   spare (padding) */
109
110	/*
111	 * Locks and expensive to access items which can be expected to
112	 * generate a cache miss.
113	 */
114	krwlock_t	vi_lock			/* -   lock for this vnode */
115	    __aligned(COHERENCY_UNIT);
116	krwlock_t	vi_nc_lock		/* -   lock on node */
117	    __aligned(COHERENCY_UNIT);
118	krwlock_t	vi_nc_listlock;		/* -   lock on nn_list */
119};
120typedef struct vnode_impl vnode_impl_t;
121
122#define VIMPL_TO_VNODE(vip)	(&(vip)->vi_vnode)
123#define VNODE_TO_VIMPL(vp)	container_of((vp), struct vnode_impl, vi_vnode)
124
125/*
126 * Vnode state assertion.
127 */
128void _vstate_assert(vnode_t *, enum vnode_state, const char *, int, bool);
129
130#if defined(DIAGNOSTIC) 
131
132#define VSTATE_ASSERT(vp, state) \
133	_vstate_assert((vp), (state), __func__, __LINE__, true)
134#define VSTATE_ASSERT_UNLOCKED(vp, state) \
135	_vstate_assert((vp), (state), __func__, __LINE__, false)
136
137#else /* defined(DIAGNOSTIC) */
138
139#define VSTATE_ASSERT(vp, state)
140#define VSTATE_ASSERT_UNLOCKED(vp, state)
141
142#endif /* defined(DIAGNOSTIC) */
143
144/*
145 * Vnode manipulation functions.
146 */
147const char *
148	vstate_name(enum vnode_state);
149vnode_t *
150	vnalloc_marker(struct mount *);
151void	vnfree_marker(vnode_t *);
152bool	vnis_marker(vnode_t *);
153void	vcache_make_anon(vnode_t *);
154int	vcache_vget(vnode_t *);
155int	vcache_tryvget(vnode_t *);
156int	vfs_drainvnodes(void);
157
158#endif	/* defined(_KERNEL) || defined(_KMEMUSER) */
159#endif	/* !_SYS_VNODE_IMPL_H_ */