/* $NetBSD: vnode_impl.h,v 1.27 2023/08/01 16:33:43 dholland Exp $ */
/*-
* Copyright (c) 2016, 2019, 2020 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SYS_VNODE_IMPL_H_
#define _SYS_VNODE_IMPL_H_
#if defined(_KERNEL) || defined(_KMEMUSER)
#include <sys/sdt.h>
#include <sys/vnode.h>
struct namecache;
struct nchnode;
enum vnode_state {
VS_ACTIVE, /* Assert only, fs node attached and usecount > 0. */
VS_MARKER, /* Stable, used as marker. Will not change. */
VS_LOADING, /* Intermediate, initialising the fs node. */
VS_LOADED, /* Stable, valid fs node attached. */
VS_BLOCKED, /* Intermediate, active, no new references allowed. */
VS_RECLAIMING, /* Intermediate, detaching the fs node. */
VS_RECLAIMED /* Stable, no fs node attached. */
};
TAILQ_HEAD(vnodelst, vnode_impl);
typedef struct vnodelst vnodelst_t;
struct vcache_key {
struct mount *vk_mount;
const void *vk_key;
size_t vk_key_len;
};
/*
* Reading or writing any of these items requires holding the appropriate
* lock. Field markings and the corresponding locks:
*
* - stable throughout the life of the vnode
* c vcache_lock
* d vdrain_lock
* i v_interlock
* l vi_nc_listlock
* m mnt_vnodelock
* n vi_nc_lock
* n,l both vi_nc_lock + vi_nc_listlock to modify, either to read
* s syncer_data_lock
*/
struct vnode_impl {
struct vnode vi_vnode;
/*
* Largely stable data.
*/
struct vcache_key vi_key; /* c vnode cache key */
/*
* The vnode klist is accessed frequently, but rarely
* modified.
*/
struct vnode_klist vi_klist; /* i kevent / knote state */
/*
* vnode cache, LRU and syncer. This all changes with some
* regularity so keep it together.
*/
struct vnodelst *vi_lrulisthd; /* d current lru list head */
TAILQ_ENTRY(vnode_impl) vi_lrulist; /* d lru list */
int vi_synclist_slot; /* s synclist slot index */
int vi_lrulisttm; /* i time of lru enqueue */
TAILQ_ENTRY(vnode_impl) vi_synclist; /* s vnodes with dirty bufs */
SLIST_ENTRY(vnode_impl) vi_hash; /* c vnode cache list */
enum vnode_state vi_state; /* i current state */
TAILQ_ENTRY(vnode_impl) vi_mntvnodes; /* m vnodes for mount point */
/*
* Namecache. Give it a separate line so activity doesn't impinge
* on the stable stuff.
*/
rb_tree_t vi_nc_tree /* n namecache tree */
__aligned(COHERENCY_UNIT);
TAILQ_HEAD(,namecache) vi_nc_list; /* l namecaches (parent) */
mode_t vi_nc_mode; /* n,l cached mode or VNOVAL */
uid_t vi_nc_uid; /* n,l cached UID or VNOVAL */
gid_t vi_nc_gid; /* n,l cached GID or VNOVAL */
uint32_t vi_nc_spare; /* - spare (padding) */
/*
* Locks and expensive to access items which can be expected to
* generate a cache miss.
*/
krwlock_t vi_lock /* - lock for this vnode */
__aligned(COHERENCY_UNIT);
krwlock_t vi_nc_lock /* - lock on node */
__aligned(COHERENCY_UNIT);
krwlock_t vi_nc_listlock; /* - lock on nn_list */
};
typedef struct vnode_impl vnode_impl_t;
#define VIMPL_TO_VNODE(vip) (&(vip)->vi_vnode)
#define VNODE_TO_VIMPL(vp) container_of((vp), struct vnode_impl, vi_vnode)
/*
* Vnode state assertion.
*/
void _vstate_assert(vnode_t *, enum vnode_state, const char *, int, bool);
#if defined(DIAGNOSTIC)
#define VSTATE_ASSERT(vp, state) \
_vstate_assert((vp), (state), __func__, __LINE__, true)
#define VSTATE_ASSERT_UNLOCKED(vp, state) \
_vstate_assert((vp), (state), __func__, __LINE__, false)
#else /* defined(DIAGNOSTIC) */
#define VSTATE_ASSERT(vp, state)
#define VSTATE_ASSERT_UNLOCKED(vp, state)
#endif /* defined(DIAGNOSTIC) */
/*
* Vnode manipulation functions.
*/
const char *
vstate_name(enum vnode_state);
vnode_t *
vnalloc_marker(struct mount *);
void vnfree_marker(vnode_t *);
bool vnis_marker(vnode_t *);
void vcache_make_anon(vnode_t *);
int vcache_vget(vnode_t *);
int vcache_tryvget(vnode_t *);
int vfs_drainvnodes(void);
SDT_PROVIDER_DECLARE(vfs);
#endif /* defined(_KERNEL) || defined(_KMEMUSER) */
#endif /* !_SYS_VNODE_IMPL_H_ */
CVSweb <webmaster@jp.NetBSD.org>