1 /* $NetBSD: tmpfs_args.h,v 1.2 2008/07/28 18:00:20 pooka Exp $ */ 2 3 /* 4 * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 9 * 2005 program. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef _FS_TMPFS_TMPFS_ARGS_H_ 34 #define _FS_TMPFS_TMPFS_ARGS_H_ 35 36 #include <sys/vnode.h> 37 38 /* 39 * Internal representation of a tmpfs directory entry. 40 */ 41 struct tmpfs_dirent { 42 TAILQ_ENTRY(tmpfs_dirent) td_entries; 43 44 /* Length of the name stored in this directory entry. This avoids 45 * the need to recalculate it every time the name is used. */ 46 uint16_t td_namelen; 47 48 /* The name of the entry, allocated from a string pool. This 49 * string is not required to be zero-terminated; therefore, the 50 * td_namelen field must always be used when accessing its value. */ 51 char * td_name; 52 53 /* Pointer to the node this entry refers to. */ 54 struct tmpfs_node * td_node; 55 }; 56 57 /* A directory in tmpfs holds a sorted list of directory entries, which in 58 * turn point to other files (which can be directories themselves). 59 * 60 * In tmpfs, this list is managed by a tail queue, whose head is defined by 61 * the struct tmpfs_dir type. 62 * 63 * It is imporant to notice that directories do not have entries for . and 64 * .. as other file systems do. These can be generated when requested 65 * based on information available by other means, such as the pointer to 66 * the node itself in the former case or the pointer to the parent directory 67 * in the latter case. This is done to simplify tmpfs's code and, more 68 * importantly, to remove redundancy. */ 69 TAILQ_HEAD(tmpfs_dir, tmpfs_dirent); 70 71 /* 72 * Internal representation of a tmpfs file system node. 73 * 74 * This structure is splitted in two parts: one holds attributes common 75 * to all file types and the other holds data that is only applicable to 76 * a particular type. The code must be careful to only access those 77 * attributes that are actually allowed by the node's type. 78 */ 79 struct tmpfs_node { 80 /* Doubly-linked list entry which links all existing nodes for a 81 * single file system. This is provided to ease the removal of 82 * all nodes during the unmount operation. */ 83 LIST_ENTRY(tmpfs_node) tn_entries; 84 85 /* The node's type. Any of 'VBLK', 'VCHR', 'VDIR', 'VFIFO', 86 * 'VLNK', 'VREG' and 'VSOCK' is allowed. The usage of vnode 87 * types instead of a custom enumeration is to make things simpler 88 * and faster, as we do not need to convert between two types. */ 89 enum vtype tn_type; 90 91 /* Node identifier. */ 92 ino_t tn_id; 93 94 /* Node's internal status. This is used by several file system 95 * operations to do modifications to the node in a delayed 96 * fashion. */ 97 int tn_status; 98 #define TMPFS_NODE_ACCESSED (1 << 1) 99 #define TMPFS_NODE_MODIFIED (1 << 2) 100 #define TMPFS_NODE_CHANGED (1 << 3) 101 102 /* The node size. It does not necessarily match the real amount 103 * of memory consumed by it. */ 104 off_t tn_size; 105 106 /* Generic node attributes. */ 107 uid_t tn_uid; 108 gid_t tn_gid; 109 mode_t tn_mode; 110 int tn_flags; 111 nlink_t tn_links; 112 struct timespec tn_atime; 113 struct timespec tn_mtime; 114 struct timespec tn_ctime; 115 struct timespec tn_birthtime; 116 unsigned long tn_gen; 117 118 /* Head of byte-level lock list (used by tmpfs_advlock). */ 119 struct lockf * tn_lockf; 120 121 /* As there is a single vnode for each active file within the 122 * system, care has to be taken to avoid allocating more than one 123 * vnode per file. In order to do this, a bidirectional association 124 * is kept between vnodes and nodes. 125 * 126 * Whenever a vnode is allocated, its v_data field is updated to 127 * point to the node it references. At the same time, the node's 128 * tn_vnode field is modified to point to the new vnode representing 129 * it. Further attempts to allocate a vnode for this same node will 130 * result in returning a new reference to the value stored in 131 * tn_vnode. 132 * 133 * May be NULL when the node is unused (that is, no vnode has been 134 * allocated for it or it has been reclaimed). */ 135 kmutex_t tn_vlock; 136 struct vnode * tn_vnode; 137 138 union { 139 /* Valid when tn_type == VBLK || tn_type == VCHR. */ 140 struct { 141 dev_t tn_rdev; 142 } tn_dev; 143 144 /* Valid when tn_type == VDIR. */ 145 struct { 146 /* Pointer to the parent directory. The root 147 * directory has a pointer to itself in this field; 148 * this property identifies the root node. */ 149 struct tmpfs_node * tn_parent; 150 151 /* Head of a tail-queue that links the contents of 152 * the directory together. See above for a 153 * description of its contents. */ 154 struct tmpfs_dir tn_dir; 155 156 /* Number and pointer of the first directory entry 157 * returned by the readdir operation if it were 158 * called again to continue reading data from the 159 * same directory as before. This is used to speed 160 * up reads of long directories, assuming that no 161 * more than one read is in progress at a given time. 162 * Otherwise, these values are discarded and a linear 163 * scan is performed from the beginning up to the 164 * point where readdir starts returning values. */ 165 off_t tn_readdir_lastn; 166 struct tmpfs_dirent * tn_readdir_lastp; 167 } tn_dir; 168 169 /* Valid when tn_type == VLNK. */ 170 struct tn_lnk { 171 /* The link's target, allocated from a string pool. */ 172 char * tn_link; 173 } tn_lnk; 174 175 /* Valid when tn_type == VREG. */ 176 struct tn_reg { 177 /* The contents of regular files stored in a tmpfs 178 * file system are represented by a single anonymous 179 * memory object (aobj, for short). The aobj provides 180 * direct access to any position within the file, 181 * because its contents are always mapped in a 182 * contiguous region of virtual memory. It is a task 183 * of the memory management subsystem (see uvm(9)) to 184 * issue the required page ins or page outs whenever 185 * a position within the file is accessed. */ 186 struct uvm_object * tn_aobj; 187 size_t tn_aobj_pages; 188 } tn_reg; 189 } tn_spec; 190 }; 191 192 static __inline 193 struct tmpfs_node * 194 VP_TO_TMPFS_NODE(struct vnode *vp) 195 { 196 struct tmpfs_node *node; 197 198 #ifdef KASSERT 199 KASSERT((vp) != NULL && (vp)->v_data != NULL); 200 #endif 201 node = (struct tmpfs_node *)vp->v_data; 202 return node; 203 } 204 205 /* 206 * This structure is used to communicate mount parameters between userland 207 * and kernel space. 208 */ 209 #define TMPFS_ARGS_VERSION 1 210 struct tmpfs_args { 211 int ta_version; 212 213 /* Size counters. */ 214 ino_t ta_nodes_max; 215 off_t ta_size_max; 216 217 /* Root node attributes. */ 218 uid_t ta_root_uid; 219 gid_t ta_root_gid; 220 mode_t ta_root_mode; 221 }; 222 223 #endif /* _FS_TMPFS_TMPFS_ARGS_H_ */ 224