Home | History | Annotate | Line # | Download | only in sys
      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 
     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	both vi_nc_lock + vi_nc_listlock to modify, either to read
     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