1171802Sdelphij/* $NetBSD: tmpfs.h,v 1.26 2007/02/22 06:37:00 thorpej Exp $ */ 2170808Sdelphij 3182739Sdelphij/*- 4171802Sdelphij * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc. 5170808Sdelphij * All rights reserved. 6170808Sdelphij * 7170808Sdelphij * This code is derived from software contributed to The NetBSD Foundation 8170808Sdelphij * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 9170808Sdelphij * 2005 program. 10170808Sdelphij * 11170808Sdelphij * Redistribution and use in source and binary forms, with or without 12170808Sdelphij * modification, are permitted provided that the following conditions 13170808Sdelphij * are met: 14170808Sdelphij * 1. Redistributions of source code must retain the above copyright 15170808Sdelphij * notice, this list of conditions and the following disclaimer. 16170808Sdelphij * 2. Redistributions in binary form must reproduce the above copyright 17170808Sdelphij * notice, this list of conditions and the following disclaimer in the 18170808Sdelphij * documentation and/or other materials provided with the distribution. 19170808Sdelphij * 20170808Sdelphij * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21170808Sdelphij * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22170808Sdelphij * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23170808Sdelphij * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24170808Sdelphij * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25170808Sdelphij * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26170808Sdelphij * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27170808Sdelphij * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28170808Sdelphij * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29170808Sdelphij * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30170808Sdelphij * POSSIBILITY OF SUCH DAMAGE. 31170808Sdelphij * 32170808Sdelphij * $FreeBSD: releng/10.2/sys/fs/tmpfs/tmpfs.h 278571 2015-02-11 09:02:21Z kib $ 33170808Sdelphij */ 34170808Sdelphij 35170808Sdelphij#ifndef _FS_TMPFS_TMPFS_H_ 36170808Sdelphij#define _FS_TMPFS_TMPFS_H_ 37170808Sdelphij 38170808Sdelphij#include <sys/dirent.h> 39170808Sdelphij#include <sys/mount.h> 40170808Sdelphij#include <sys/queue.h> 41170808Sdelphij#include <sys/vnode.h> 42170808Sdelphij#include <sys/file.h> 43170808Sdelphij#include <sys/lock.h> 44170808Sdelphij#include <sys/mutex.h> 45170808Sdelphij 46170808Sdelphij#include <sys/malloc.h> 47170808Sdelphij#include <sys/systm.h> 48245115Sgleb#include <sys/tree.h> 49170808Sdelphij#include <sys/vmmeter.h> 50170808Sdelphij#include <vm/swap_pager.h> 51170808Sdelphij 52170808SdelphijMALLOC_DECLARE(M_TMPFSMNT); 53171087SdelphijMALLOC_DECLARE(M_TMPFSNAME); 54170808Sdelphij 55170808Sdelphij/* 56170808Sdelphij * Internal representation of a tmpfs directory entry. 57170808Sdelphij */ 58245115Sgleb 59245115SglebLIST_HEAD(tmpfs_dir_duphead, tmpfs_dirent); 60245115Sgleb 61170808Sdelphijstruct tmpfs_dirent { 62245115Sgleb /* 63245115Sgleb * Depending on td_cookie flag entry can be of 3 types: 64245115Sgleb * - regular -- no hash collisions, stored in RB-Tree 65245115Sgleb * - duphead -- synthetic linked list head for dup entries 66245115Sgleb * - dup -- stored in linked list instead of RB-Tree 67245115Sgleb */ 68245115Sgleb union { 69245115Sgleb /* regular and duphead entry types */ 70245115Sgleb RB_ENTRY(tmpfs_dirent) td_entries; 71170808Sdelphij 72245115Sgleb /* dup entry type */ 73245115Sgleb struct { 74245115Sgleb LIST_ENTRY(tmpfs_dirent) entries; 75245115Sgleb LIST_ENTRY(tmpfs_dirent) index_entries; 76245115Sgleb } td_dup; 77245115Sgleb } uh; 78170808Sdelphij 79245115Sgleb uint32_t td_cookie; 80245115Sgleb uint32_t td_hash; 81245115Sgleb u_int td_namelen; 82170808Sdelphij 83211598Sed /* Pointer to the node this entry refers to. In case this field 84211598Sed * is NULL, the node is a whiteout. */ 85170808Sdelphij struct tmpfs_node * td_node; 86245115Sgleb 87245115Sgleb union { 88245115Sgleb /* 89245115Sgleb * The name of the entry, allocated from a string pool. This 90245115Sgleb * string is not required to be zero-terminated. 91245115Sgleb */ 92245115Sgleb char * td_name; /* regular, dup */ 93245115Sgleb struct tmpfs_dir_duphead td_duphead; /* duphead */ 94245115Sgleb } ud; 95170808Sdelphij}; 96170808Sdelphij 97245115Sgleb/* A directory in tmpfs holds a list of directory entries, which in 98170808Sdelphij * turn point to other files (which can be directories themselves). 99170808Sdelphij * 100245115Sgleb * In tmpfs, this list is managed by a RB-Tree, whose head is defined by 101170808Sdelphij * the struct tmpfs_dir type. 102170808Sdelphij * 103245115Sgleb * It is important to notice that directories do not have entries for . and 104170808Sdelphij * .. as other file systems do. These can be generated when requested 105170808Sdelphij * based on information available by other means, such as the pointer to 106170808Sdelphij * the node itself in the former case or the pointer to the parent directory 107170808Sdelphij * in the latter case. This is done to simplify tmpfs's code and, more 108170808Sdelphij * importantly, to remove redundancy. */ 109245115SglebRB_HEAD(tmpfs_dir, tmpfs_dirent); 110170808Sdelphij 111171802Sdelphij/* Each entry in a directory has a cookie that identifies it. Cookies 112171802Sdelphij * supersede offsets within directories because, given how tmpfs stores 113245115Sgleb * directories in memory, there is no such thing as an offset. 114245115Sgleb * 115171802Sdelphij * The '.', '..' and the end of directory markers have fixed cookies which 116171802Sdelphij * cannot collide with the cookies generated by other entries. The cookies 117245115Sgleb * for the other entries are generated based on the file name hash value or 118245115Sgleb * unique number in case of name hash collision. 119171802Sdelphij * 120245115Sgleb * To preserve compatibility cookies are limited to 31 bits. 121245115Sgleb */ 122170808Sdelphij 123245115Sgleb#define TMPFS_DIRCOOKIE_DOT 0 124245115Sgleb#define TMPFS_DIRCOOKIE_DOTDOT 1 125245115Sgleb#define TMPFS_DIRCOOKIE_EOF 2 126245115Sgleb#define TMPFS_DIRCOOKIE_MASK ((off_t)0x3fffffffU) 127245115Sgleb#define TMPFS_DIRCOOKIE_MIN ((off_t)0x00000004U) 128245115Sgleb#define TMPFS_DIRCOOKIE_DUP ((off_t)0x40000000U) 129245115Sgleb#define TMPFS_DIRCOOKIE_DUPHEAD ((off_t)0x80000000U) 130245115Sgleb#define TMPFS_DIRCOOKIE_DUP_MIN TMPFS_DIRCOOKIE_DUP 131245115Sgleb#define TMPFS_DIRCOOKIE_DUP_MAX \ 132245115Sgleb (TMPFS_DIRCOOKIE_DUP | TMPFS_DIRCOOKIE_MASK) 133171802Sdelphij 134170808Sdelphij/* 135170808Sdelphij * Internal representation of a tmpfs file system node. 136170808Sdelphij * 137170808Sdelphij * This structure is splitted in two parts: one holds attributes common 138170808Sdelphij * to all file types and the other holds data that is only applicable to 139170808Sdelphij * a particular type. The code must be careful to only access those 140170808Sdelphij * attributes that are actually allowed by the node's type. 141170808Sdelphij * 142170808Sdelphij * 143170808Sdelphij * Below is the key of locks used to protected the fields in the following 144170808Sdelphij * structures. 145170808Sdelphij * 146170808Sdelphij */ 147170808Sdelphijstruct tmpfs_node { 148170808Sdelphij /* Doubly-linked list entry which links all existing nodes for a 149170808Sdelphij * single file system. This is provided to ease the removal of 150170808Sdelphij * all nodes during the unmount operation. */ 151170808Sdelphij LIST_ENTRY(tmpfs_node) tn_entries; 152170808Sdelphij 153170808Sdelphij /* The node's type. Any of 'VBLK', 'VCHR', 'VDIR', 'VFIFO', 154170808Sdelphij * 'VLNK', 'VREG' and 'VSOCK' is allowed. The usage of vnode 155170808Sdelphij * types instead of a custom enumeration is to make things simpler 156170808Sdelphij * and faster, as we do not need to convert between two types. */ 157170808Sdelphij enum vtype tn_type; 158170808Sdelphij 159170808Sdelphij /* Node identifier. */ 160170808Sdelphij ino_t tn_id; 161170808Sdelphij 162170808Sdelphij /* Node's internal status. This is used by several file system 163170808Sdelphij * operations to do modifications to the node in a delayed 164170808Sdelphij * fashion. */ 165170808Sdelphij int tn_status; 166170808Sdelphij#define TMPFS_NODE_ACCESSED (1 << 1) 167170808Sdelphij#define TMPFS_NODE_MODIFIED (1 << 2) 168170808Sdelphij#define TMPFS_NODE_CHANGED (1 << 3) 169170808Sdelphij 170170808Sdelphij /* The node size. It does not necessarily match the real amount 171170808Sdelphij * of memory consumed by it. */ 172170808Sdelphij off_t tn_size; 173170808Sdelphij 174170808Sdelphij /* Generic node attributes. */ 175170808Sdelphij uid_t tn_uid; 176170808Sdelphij gid_t tn_gid; 177170808Sdelphij mode_t tn_mode; 178248597Spjd u_long tn_flags; 179170808Sdelphij nlink_t tn_links; 180170808Sdelphij struct timespec tn_atime; 181170808Sdelphij struct timespec tn_mtime; 182170808Sdelphij struct timespec tn_ctime; 183170808Sdelphij struct timespec tn_birthtime; 184170808Sdelphij unsigned long tn_gen; 185170808Sdelphij 186170808Sdelphij /* As there is a single vnode for each active file within the 187170808Sdelphij * system, care has to be taken to avoid allocating more than one 188170808Sdelphij * vnode per file. In order to do this, a bidirectional association 189170808Sdelphij * is kept between vnodes and nodes. 190170808Sdelphij * 191170808Sdelphij * Whenever a vnode is allocated, its v_data field is updated to 192170808Sdelphij * point to the node it references. At the same time, the node's 193170808Sdelphij * tn_vnode field is modified to point to the new vnode representing 194170808Sdelphij * it. Further attempts to allocate a vnode for this same node will 195170808Sdelphij * result in returning a new reference to the value stored in 196170808Sdelphij * tn_vnode. 197170808Sdelphij * 198170808Sdelphij * May be NULL when the node is unused (that is, no vnode has been 199170808Sdelphij * allocated for it or it has been reclaimed). */ 200170808Sdelphij struct vnode * tn_vnode; 201170808Sdelphij 202170808Sdelphij /* interlock to protect tn_vpstate */ 203170808Sdelphij struct mtx tn_interlock; 204170808Sdelphij 205170808Sdelphij /* Identify if current node has vnode assiocate with 206170808Sdelphij * or allocating vnode. 207170808Sdelphij */ 208170808Sdelphij int tn_vpstate; 209170808Sdelphij 210170808Sdelphij /* misc data field for different tn_type node */ 211170808Sdelphij union { 212170808Sdelphij /* Valid when tn_type == VBLK || tn_type == VCHR. */ 213170808Sdelphij dev_t tn_rdev; 214170808Sdelphij 215170808Sdelphij /* Valid when tn_type == VDIR. */ 216245115Sgleb struct tn_dir { 217170808Sdelphij /* Pointer to the parent directory. The root 218170808Sdelphij * directory has a pointer to itself in this field; 219170808Sdelphij * this property identifies the root node. */ 220170808Sdelphij struct tmpfs_node * tn_parent; 221170808Sdelphij 222245115Sgleb /* Head of a tree that links the contents of 223245115Sgleb * the directory together. */ 224170808Sdelphij struct tmpfs_dir tn_dirhead; 225170808Sdelphij 226245115Sgleb /* Head of a list the contains fake directory entries 227245115Sgleb * heads, i.e. entries with TMPFS_DIRCOOKIE_DUPHEAD 228245115Sgleb * flag. */ 229245115Sgleb struct tmpfs_dir_duphead tn_dupindex; 230245115Sgleb 231170808Sdelphij /* Number and pointer of the first directory entry 232170808Sdelphij * returned by the readdir operation if it were 233170808Sdelphij * called again to continue reading data from the 234170808Sdelphij * same directory as before. This is used to speed 235170808Sdelphij * up reads of long directories, assuming that no 236170808Sdelphij * more than one read is in progress at a given time. 237245115Sgleb * Otherwise, these values are discarded. */ 238170808Sdelphij off_t tn_readdir_lastn; 239170808Sdelphij struct tmpfs_dirent * tn_readdir_lastp; 240245115Sgleb } tn_dir; 241170808Sdelphij 242170808Sdelphij /* Valid when tn_type == VLNK. */ 243170808Sdelphij /* The link's target, allocated from a string pool. */ 244170808Sdelphij char * tn_link; 245170808Sdelphij 246170808Sdelphij /* Valid when tn_type == VREG. */ 247170808Sdelphij struct tn_reg { 248170808Sdelphij /* The contents of regular files stored in a tmpfs 249170808Sdelphij * file system are represented by a single anonymous 250170808Sdelphij * memory object (aobj, for short). The aobj provides 251170808Sdelphij * direct access to any position within the file, 252170808Sdelphij * because its contents are always mapped in a 253170808Sdelphij * contiguous region of virtual memory. It is a task 254170808Sdelphij * of the memory management subsystem (see uvm(9)) to 255170808Sdelphij * issue the required page ins or page outs whenever 256170808Sdelphij * a position within the file is accessed. */ 257170808Sdelphij vm_object_t tn_aobj; 258170808Sdelphij 259170808Sdelphij }tn_reg; 260170808Sdelphij 261170808Sdelphij /* Valid when tn_type = VFIFO */ 262170808Sdelphij struct tn_fifo { 263170808Sdelphij fo_rdwr_t *tn_fo_read; 264170808Sdelphij fo_rdwr_t *tn_fo_write; 265170808Sdelphij }tn_fifo; 266170808Sdelphij }tn_spec; 267170808Sdelphij}; 268170808SdelphijLIST_HEAD(tmpfs_node_list, tmpfs_node); 269170808Sdelphij 270170808Sdelphij#define tn_rdev tn_spec.tn_rdev 271170808Sdelphij#define tn_dir tn_spec.tn_dir 272170808Sdelphij#define tn_link tn_spec.tn_link 273170808Sdelphij#define tn_reg tn_spec.tn_reg 274170808Sdelphij#define tn_fifo tn_spec.tn_fifo 275170808Sdelphij 276170808Sdelphij#define TMPFS_NODE_LOCK(node) mtx_lock(&(node)->tn_interlock) 277170808Sdelphij#define TMPFS_NODE_UNLOCK(node) mtx_unlock(&(node)->tn_interlock) 278197953Sdelphij#define TMPFS_NODE_MTX(node) (&(node)->tn_interlock) 279269169Skib#define TMPFS_NODE_ASSERT_LOCKED(node) mtx_assert(TMPFS_NODE_MTX(node), \ 280269169Skib MA_OWNED) 281170808Sdelphij 282197953Sdelphij#ifdef INVARIANTS 283197953Sdelphij#define TMPFS_ASSERT_LOCKED(node) do { \ 284197953Sdelphij MPASS(node != NULL); \ 285197953Sdelphij MPASS(node->tn_vnode != NULL); \ 286197953Sdelphij if (!VOP_ISLOCKED(node->tn_vnode) && \ 287197953Sdelphij !mtx_owned(TMPFS_NODE_MTX(node))) \ 288197953Sdelphij panic("tmpfs: node is not locked: %p", node); \ 289197953Sdelphij } while (0) 290197953Sdelphij#define TMPFS_ASSERT_ELOCKED(node) do { \ 291197953Sdelphij MPASS((node) != NULL); \ 292197953Sdelphij MPASS((node)->tn_vnode != NULL); \ 293197953Sdelphij mtx_assert(TMPFS_NODE_MTX(node), MA_OWNED); \ 294197953Sdelphij ASSERT_VOP_LOCKED((node)->tn_vnode, "tmpfs"); \ 295197953Sdelphij } while (0) 296197953Sdelphij#else 297197953Sdelphij#define TMPFS_ASSERT_LOCKED(node) (void)0 298197953Sdelphij#define TMPFS_ASSERT_ELOCKED(node) (void)0 299197953Sdelphij#endif 300197953Sdelphij 301170808Sdelphij#define TMPFS_VNODE_ALLOCATING 1 302170808Sdelphij#define TMPFS_VNODE_WANT 2 303197953Sdelphij#define TMPFS_VNODE_DOOMED 4 304253967Skib#define TMPFS_VNODE_WRECLAIM 8 305170808Sdelphij 306170808Sdelphij/* 307170808Sdelphij * Internal representation of a tmpfs mount point. 308170808Sdelphij */ 309170808Sdelphijstruct tmpfs_mount { 310170808Sdelphij /* Maximum number of memory pages available for use by the file 311170808Sdelphij * system, set during mount time. This variable must never be 312171038Sdelphij * used directly as it may be bigger than the current amount of 313170808Sdelphij * free memory; in the extreme case, it will hold the SIZE_MAX 314233998Sgleb * value. */ 315170808Sdelphij size_t tm_pages_max; 316170808Sdelphij 317233998Sgleb /* Number of pages in use by the file system. */ 318170808Sdelphij size_t tm_pages_used; 319170808Sdelphij 320170808Sdelphij /* Pointer to the node representing the root directory of this 321170808Sdelphij * file system. */ 322170808Sdelphij struct tmpfs_node * tm_root; 323170808Sdelphij 324170808Sdelphij /* Maximum number of possible nodes for this file system; set 325170808Sdelphij * during mount time. We need a hard limit on the maximum number 326170808Sdelphij * of nodes to avoid allocating too much of them; their objects 327170808Sdelphij * cannot be released until the file system is unmounted. 328170808Sdelphij * Otherwise, we could easily run out of memory by creating lots 329170808Sdelphij * of empty files and then simply removing them. */ 330170808Sdelphij ino_t tm_nodes_max; 331170808Sdelphij 332171362Sdelphij /* unrhdr used to allocate inode numbers */ 333171362Sdelphij struct unrhdr * tm_ino_unr; 334170808Sdelphij 335170808Sdelphij /* Number of nodes currently that are in use. */ 336170808Sdelphij ino_t tm_nodes_inuse; 337170808Sdelphij 338170808Sdelphij /* maximum representable file size */ 339170808Sdelphij u_int64_t tm_maxfilesize; 340171070Sdelphij 341170808Sdelphij /* Nodes are organized in two different lists. The used list 342170808Sdelphij * contains all nodes that are currently used by the file system; 343170808Sdelphij * i.e., they refer to existing files. The available list contains 344170808Sdelphij * all nodes that are currently available for use by new files. 345170808Sdelphij * Nodes must be kept in this list (instead of deleting them) 346170808Sdelphij * because we need to keep track of their generation number (tn_gen 347170808Sdelphij * field). 348170808Sdelphij * 349170808Sdelphij * Note that nodes are lazily allocated: if the available list is 350170808Sdelphij * empty and we have enough space to create more nodes, they will be 351170808Sdelphij * created and inserted in the used list. Once these are released, 352170808Sdelphij * they will go into the available list, remaining alive until the 353170808Sdelphij * file system is unmounted. */ 354170808Sdelphij struct tmpfs_node_list tm_nodes_used; 355170808Sdelphij 356170808Sdelphij /* All node lock to protect the node list and tmp_pages_used */ 357170808Sdelphij struct mtx allnode_lock; 358170808Sdelphij 359170808Sdelphij /* Pools used to store file system meta data. These are not shared 360170808Sdelphij * across several instances of tmpfs for the reasons described in 361170808Sdelphij * tmpfs_pool.c. */ 362170808Sdelphij uma_zone_t tm_dirent_pool; 363170808Sdelphij uma_zone_t tm_node_pool; 364234346Sjh 365234346Sjh /* Read-only status. */ 366234346Sjh int tm_ronly; 367170808Sdelphij}; 368170808Sdelphij#define TMPFS_LOCK(tm) mtx_lock(&(tm)->allnode_lock) 369170808Sdelphij#define TMPFS_UNLOCK(tm) mtx_unlock(&(tm)->allnode_lock) 370170808Sdelphij 371170808Sdelphij/* 372170808Sdelphij * This structure maps a file identifier to a tmpfs node. Used by the 373170808Sdelphij * NFS code. 374170808Sdelphij */ 375170808Sdelphijstruct tmpfs_fid { 376170808Sdelphij uint16_t tf_len; 377170808Sdelphij uint16_t tf_pad; 378171067Sdelphij ino_t tf_id; 379170808Sdelphij unsigned long tf_gen; 380170808Sdelphij}; 381170808Sdelphij 382170808Sdelphij#ifdef _KERNEL 383170808Sdelphij/* 384170808Sdelphij * Prototypes for tmpfs_subr.c. 385170808Sdelphij */ 386170808Sdelphij 387269175Skibint tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *, enum vtype, 388170808Sdelphij uid_t uid, gid_t gid, mode_t mode, struct tmpfs_node *, 389191990Sattilio char *, dev_t, struct tmpfs_node **); 390170808Sdelphijvoid tmpfs_free_node(struct tmpfs_mount *, struct tmpfs_node *); 391170808Sdelphijint tmpfs_alloc_dirent(struct tmpfs_mount *, struct tmpfs_node *, 392245115Sgleb const char *, u_int, struct tmpfs_dirent **); 393245115Sglebvoid tmpfs_free_dirent(struct tmpfs_mount *, struct tmpfs_dirent *); 394245115Sglebvoid tmpfs_dirent_init(struct tmpfs_dirent *, const char *, u_int); 395250189Skibvoid tmpfs_destroy_vobject(struct vnode *vp, vm_object_t obj); 396171799Sdelphijint tmpfs_alloc_vp(struct mount *, struct tmpfs_node *, int, 397191990Sattilio struct vnode **); 398170808Sdelphijvoid tmpfs_free_vp(struct vnode *); 399170808Sdelphijint tmpfs_alloc_file(struct vnode *, struct vnode **, struct vattr *, 400170808Sdelphij struct componentname *, char *); 401278571Skibvoid tmpfs_check_mtime(struct vnode *); 402170808Sdelphijvoid tmpfs_dir_attach(struct vnode *, struct tmpfs_dirent *); 403170808Sdelphijvoid tmpfs_dir_detach(struct vnode *, struct tmpfs_dirent *); 404245115Sglebvoid tmpfs_dir_destroy(struct tmpfs_mount *, struct tmpfs_node *); 405170808Sdelphijstruct tmpfs_dirent * tmpfs_dir_lookup(struct tmpfs_node *node, 406188318Skib struct tmpfs_node *f, 407170808Sdelphij struct componentname *cnp); 408245115Sglebint tmpfs_dir_getdents(struct tmpfs_node *, struct uio *, int, 409245115Sgleb u_long *, int *); 410211598Sedint tmpfs_dir_whiteout_add(struct vnode *, struct componentname *); 411211598Sedvoid tmpfs_dir_whiteout_remove(struct vnode *, struct componentname *); 412230180Salcint tmpfs_reg_resize(struct vnode *, off_t, boolean_t); 413248597Spjdint tmpfs_chflags(struct vnode *, u_long, struct ucred *, struct thread *); 414170808Sdelphijint tmpfs_chmod(struct vnode *, mode_t, struct ucred *, struct thread *); 415170808Sdelphijint tmpfs_chown(struct vnode *, uid_t, gid_t, struct ucred *, 416170808Sdelphij struct thread *); 417170808Sdelphijint tmpfs_chsize(struct vnode *, u_quad_t, struct ucred *, struct thread *); 418267816Skibint tmpfs_chtimes(struct vnode *, struct vattr *, struct ucred *cred, 419267816Skib struct thread *); 420170808Sdelphijvoid tmpfs_itimes(struct vnode *, const struct timespec *, 421170808Sdelphij const struct timespec *); 422170808Sdelphij 423170808Sdelphijvoid tmpfs_update(struct vnode *); 424170808Sdelphijint tmpfs_truncate(struct vnode *, off_t); 425170808Sdelphij 426170808Sdelphij/* 427170808Sdelphij * Convenience macros to simplify some logical expressions. 428170808Sdelphij */ 429170808Sdelphij#define IMPLIES(a, b) (!(a) || (b)) 430170808Sdelphij#define IFF(a, b) (IMPLIES(a, b) && IMPLIES(b, a)) 431170808Sdelphij 432170808Sdelphij/* 433170808Sdelphij * Checks that the directory entry pointed by 'de' matches the name 'name' 434170808Sdelphij * with a length of 'len'. 435170808Sdelphij */ 436170808Sdelphij#define TMPFS_DIRENT_MATCHES(de, name, len) \ 437245115Sgleb (de->td_namelen == len && \ 438245115Sgleb bcmp((de)->ud.td_name, (name), (de)->td_namelen) == 0) 439170808Sdelphij 440170808Sdelphij/* 441170808Sdelphij * Ensures that the node pointed by 'node' is a directory and that its 442170808Sdelphij * contents are consistent with respect to directories. 443170808Sdelphij */ 444245115Sgleb#define TMPFS_VALIDATE_DIR(node) do { \ 445245115Sgleb MPASS((node)->tn_type == VDIR); \ 446245115Sgleb MPASS((node)->tn_size % sizeof(struct tmpfs_dirent) == 0); \ 447245115Sgleb} while (0) 448170808Sdelphij 449170808Sdelphij/* 450170808Sdelphij * Memory management stuff. 451170808Sdelphij */ 452170808Sdelphij 453233998Sgleb/* 454233998Sgleb * Amount of memory pages to reserve for the system (e.g., to not use by 455170808Sdelphij * tmpfs). 456170808Sdelphij */ 457233998Sgleb#define TMPFS_PAGES_MINRESERVED (4 * 1024 * 1024 / PAGE_SIZE) 458170808Sdelphij 459233998Sglebsize_t tmpfs_mem_avail(void); 460170808Sdelphij 461233998Sglebsize_t tmpfs_pages_used(struct tmpfs_mount *tmp); 462170808Sdelphij 463170808Sdelphij#endif 464170808Sdelphij 465170808Sdelphij/* 466170808Sdelphij * Macros/functions to convert from generic data structures to tmpfs 467170808Sdelphij * specific ones. 468170808Sdelphij */ 469170808Sdelphij 470170808Sdelphijstatic inline 471170808Sdelphijstruct tmpfs_mount * 472170808SdelphijVFS_TO_TMPFS(struct mount *mp) 473170808Sdelphij{ 474170808Sdelphij struct tmpfs_mount *tmp; 475170808Sdelphij 476170808Sdelphij MPASS((mp) != NULL && (mp)->mnt_data != NULL); 477170808Sdelphij tmp = (struct tmpfs_mount *)(mp)->mnt_data; 478170808Sdelphij return tmp; 479170808Sdelphij} 480170808Sdelphij 481170808Sdelphijstatic inline 482170808Sdelphijstruct tmpfs_node * 483170808SdelphijVP_TO_TMPFS_NODE(struct vnode *vp) 484170808Sdelphij{ 485170808Sdelphij struct tmpfs_node *node; 486170808Sdelphij 487170808Sdelphij MPASS((vp) != NULL && (vp)->v_data != NULL); 488170808Sdelphij node = (struct tmpfs_node *)vp->v_data; 489170808Sdelphij return node; 490170808Sdelphij} 491170808Sdelphij 492170808Sdelphijstatic inline 493170808Sdelphijstruct tmpfs_node * 494170808SdelphijVP_TO_TMPFS_DIR(struct vnode *vp) 495170808Sdelphij{ 496170808Sdelphij struct tmpfs_node *node; 497170808Sdelphij 498170808Sdelphij node = VP_TO_TMPFS_NODE(vp); 499170808Sdelphij TMPFS_VALIDATE_DIR(node); 500170808Sdelphij return node; 501170808Sdelphij} 502170808Sdelphij 503170808Sdelphij#endif /* _FS_TMPFS_TMPFS_H_ */ 504