/* $NetBSD: tmpfs.h,v 1.56 2020/05/17 19:39:15 ad Exp $ */
/*
* Copyright (c) 2005, 2006, 2007, 2020 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Julio M. Merino Vidal, developed as part of Google's Summer of Code
* 2005 program.
*
* 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.
*/
/*
* Internal representation of a tmpfs directory entry.
*
* All fields are protected by vnode lock.
*/
typedef struct tmpfs_dirent {
TAILQ_ENTRY(tmpfs_dirent) td_entries;
/* Pointer to the inode this entry refers to. */
struct tmpfs_node * td_node;
/* Sequence number, see tmpfs_dir_getseq(). */
uint32_t td_seq;
/* Name and its length. */
char * td_name;
uint16_t td_namelen;
} tmpfs_dirent_t;
TAILQ_HEAD(tmpfs_dir, tmpfs_dirent);
/*
* Internal representation of a tmpfs file system node -- inode.
*
* This structure is split in two parts: one holds attributes common
* to all file types and the other holds data that is only applicable to
* a particular type.
*
* All fields are protected by vnode lock. The vnode association itself
* is protected by vcache.
*/
typedef struct tmpfs_node {
LIST_ENTRY(tmpfs_node) tn_entries;
/*
* Each inode has a corresponding vnode. It is a bi-directional
* association. Whenever vnode is allocated, its v_data field is
* set to the inode it reference, and tmpfs_node_t::tn_vnode is
* set to point to the said vnode.
*
* Further attempts to allocate a vnode for this same node will
* result in returning a new reference to the value stored in
* tn_vnode. It may be NULL when the node is unused (that is,
* no vnode has been allocated or it has been reclaimed).
*/
vnode_t * tn_vnode;
/* Prevent node from being reclaimed. */
uint32_t tn_holdcount;
/* Directory entry. Only a hint, since hard link can have multiple. */
tmpfs_dirent_t * tn_dirent_hint;
/* The inode type: VBLK, VCHR, VDIR, VFIFO, VLNK, VREG or VSOCK. */
enum vtype tn_type;
/*
* Reserved values for the virtual entries (the first must be 0) and EOF.
* The start/end of the incremental range, see tmpfs_dir_getseq().
*/
#define TMPFS_DIRSEQ_DOT 0
#define TMPFS_DIRSEQ_DOTDOT 1
#define TMPFS_DIRSEQ_EOF 2
/*
* Bit indicating this node must be reclaimed when holdcount reaches zero.
* Ored into tmpfs_node_t::tn_holdcount.
*/
#define TMPFS_NODE_RECLAIMED (1U << 30)
/*
* Internal representation of a tmpfs mount point.
*/
typedef struct tmpfs_mount {
/* Limit and number of bytes in use by the file system. */
uint64_t tm_mem_limit;
uint64_t tm_bytes_used;
kmutex_t tm_acc_lock;
/* Pointer to the root inode. */
tmpfs_node_t * tm_root;
/* Maximum number of possible nodes for this file system. */
unsigned int tm_nodes_max;
/* Number of nodes currently allocated. */
unsigned int tm_nodes_cnt;
/* List of inodes and the lock protecting it. */
kmutex_t tm_lock;
struct tmpfs_node_list tm_nodes;
} tmpfs_mount_t;
/*
* This structure maps a file identifier to a tmpfs node. Used by the
* NFS code.
*/
typedef struct tmpfs_fid {
uint16_t tf_len;
uint16_t tf_pad;
uint32_t tf_gen;
ino_t tf_id;
} tmpfs_fid_t;
/*
* Ensures that the node pointed by 'node' is a directory and that its
* contents are consistent with respect to directories.
*/
#define TMPFS_VALIDATE_DIR(node) \
KASSERT((node)->tn_vnode == NULL || VOP_ISLOCKED((node)->tn_vnode)); \
KASSERT((node)->tn_type == VDIR); \
KASSERT((node)->tn_size % sizeof(tmpfs_dirent_t) == 0);
/*
* Routines to convert VFS structures to tmpfs internal ones.
*/