|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2005 David Decotigny 002 Copyright (C) 2000-2005 The KOS Team (Thomas Petazzoni, David 003 Decotigny, Julien Munier) 004 005 This program is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License 007 as published by the Free Software Foundation; either version 2 008 of the License, or (at your option) any later version. 009 010 This program is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 GNU General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this program; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 018 USA. 019 */ 020 #ifndef _SOS_FS_NSCACHE_H_ 021 #define _SOS_FS_NSCACHE_H_ 022 023 024 /** 025 * @file fs_nscache.h 026 * 027 * FS Namespace cache (aka file hierarchy) management. Internal API 028 * reserved to fs.c and to the FS managers ! See fs.c for details and 029 * role of this subsystem in the whole VFS. 030 * 031 * We keep the usual filesystem semantics of a "file hierarchy": 032 * 033 * parent0 034 * / \ 035 * child1 child2 036 * / \ \ 037 * child1a child1b child2a 038 * 039 * The system allows that different children actually reference the 040 * same "on-disk" node (sos_fs_node). For example: child1a and child2a 041 * might reference the same sos_fs_node: this represents a so-called 042 * "hard link". 043 * 044 * The functions of this module are in charge of updating the nscache 045 * nodes and their reference count. They don't influence the other 046 * subsystems (apart from the sos_fs_nscache_unref_node() function 047 * which can unreference the underlying sos_fs_node). 048 * 049 * Note: only the nscache nodes that are actually used or those that 050 * are their parents (ie in the path from these nodes to the global 051 * root) will remain in memory. The others will be destroyed as soon 052 * as they are not needed anymore. For example, il I do a 053 * stat("/mnt/toto/titi.txt", & st), all the nscache nodes from "/" to 054 * "titi.txt" will be allocated, the stat performed, and all of them 055 * will be destroyed. We could imagine a real "cache" here to avoid 056 * these bursts of allocations/deallocations, by keeping the last 057 * accessed nodes aside when they are not referenced anymore (in a 058 * hash table for example, the key being {parent nscache node address, 059 * child name}). 060 * 061 * Note about mountpoints: When a FS is mounted in, say "/mnt", the 062 * nscache node of the new FS is registered neither as its child nor 063 * as its parent, but as a kind of "brother" of /mnt. As seen from the 064 * global root ("/"), "mnt" in a direct child and the mounted root is 065 * its brother. But, once mounted, as seen from a child node 066 * "/mnt/toto", the mounted root is seen as the direct parent of 067 * /mnt/toto and "mnt" is seen as its brother. That is, each time we 068 * try to resolve (lookup) the children on a mountpoint, we must 069 * "follow" the mountchain. In the previous example, multiple 070 * successive FS could be mounted on the same "/mnt". 071 */ 072 073 #include <sos/types.h> 074 #include <sos/errno.h> 075 076 /** 077 * Opaque structure defined in fs_nscache.c 078 * 079 * Essentially contains: 080 * - a name (allocated in-place) 081 * - a reference to the associated FS node (struct sos_fs_node) 082 * - a reference to the parent nscache node (if any) 083 * - a list of pointers to the children nscache nodes (for directories) 084 */ 085 struct sos_fs_nscache_node; 086 087 #include "fs.h" 088 089 090 /** 091 * Support for non-0 terminated strings (Pascal-style). Useful to 092 * prevent from altering the contents of the string in order to split 093 * pathnames into components (@see sos_fs_pathname_split_path) 094 */ 095 struct sos_fs_pathname 096 { 097 const char * contents; 098 sos_size_t length; 099 }; 100 101 102 sos_ret_t sos_fs_nscache_subsystem_setup(); 103 104 105 /** 106 * Lookup the given entry in the given nsnode. The lookup is limited 107 * to the children entries that are already in memory. When this 108 * lookup fails, this simply means that the entry is not already in 109 * memory, and has to be resolved using disk accesses (@see 110 * fs_lookup_node in fs.c) 111 * 112 * @param cur_nsnode The node in which we are looking for the entry 113 * @param root_node The base node beyond which lookup must not go (to 114 * support chroot): a kind of "barrier" 115 * 116 * @param result_nsnode The nsnode for the given entry (set only when 117 * the return value is SOS_OK) 118 * 119 * @return error if the entry could not be found in the nsnode 120 * directory. OK otherwise, and *result_nsnode is set. 121 * 122 * @note The symlinks are NOT expanded. The mountpoints ARE followed. 123 * @note result_nsnode is a NEW reference to the node. It should be 124 * unreferenced when unused 125 */ 126 sos_ret_t 127 sos_fs_nscache_lookup(struct sos_fs_nscache_node * cur_nsnode, 128 const struct sos_fs_pathname * node_name, 129 const struct sos_fs_nscache_node * root_nsnode, 130 struct sos_fs_nscache_node ** result_nsnode); 131 132 133 /** 134 * Add a new child node for the given parent, for the given fs_node 135 * 136 * @param parent might be NULL, meaning that the node is the root of a 137 * mounted filesystem 138 * 139 * @note The new node has the value 0 for the opened_file and 140 * mount_chain counters 141 * @note result_nsnode is a NEW reference to the node. It should be 142 * unreferenced when unused 143 */ 144 sos_ret_t 145 sos_fs_nscache_add_new_child_node(struct sos_fs_nscache_node * parent, 146 const struct sos_fs_pathname * node_name, 147 struct sos_fs_node * fsnode, 148 struct sos_fs_nscache_node ** result_nsnode); 149 150 151 /** 152 * Add a new child node for the given parent, for the given already 153 * existing nsnode (with no parent !) 154 * 155 * @param parent can not be NULL 156 * 157 * @note nsnode should NOT have any parent 158 */ 159 sos_ret_t 160 sos_fs_nscache_add_existing_child_node(struct sos_fs_nscache_node * parent, 161 const struct sos_fs_pathname * node_name, 162 struct sos_fs_nscache_node * nsnode); 163 164 165 /** 166 * Disconnect the given node from its parent, if any 167 * @note reference count of nsnode is NOT modified 168 */ 169 sos_ret_t 170 sos_fs_nscache_disconnect_node(struct sos_fs_nscache_node * nsnode); 171 172 173 /** 174 * Register the given root of a new file system (mounted_root) in the 175 * mountpoint chain located at mountpoint, ie build the mountchain. 176 */ 177 sos_ret_t 178 sos_fs_nscache_mount(struct sos_fs_nscache_node * mountpoint, 179 struct sos_fs_nscache_node * mounted_root); 180 181 182 /** 183 * Break the mountchain at the given mounted root, making sure that 184 * this nscache node is not reference by any opened file or child node 185 * anymore. 186 */ 187 sos_ret_t 188 sos_fs_nscache_umount(struct sos_fs_nscache_node * mounted_root); 189 190 191 /** Return true if the node is involved in any mountchain */ 192 sos_bool_t 193 sos_fs_nscache_is_mountnode(const struct sos_fs_nscache_node * nsnode); 194 195 196 /* 197 * Accessor functions 198 */ 199 200 201 /** 202 * Return the FS node of the given nscache node. 203 * 204 * @note The FS node returned is NOT newly referenced 205 */ 206 struct sos_fs_node * 207 sos_fs_nscache_get_fs_node(const struct sos_fs_nscache_node * nsnode); 208 209 210 /** 211 * Return the parent nscache node of the given nscache node. 212 * 213 * @note The nscache node returned is NOT newly referenced 214 */ 215 sos_ret_t 216 sos_fs_nscache_get_parent(const struct sos_fs_nscache_node * nsnode, 217 struct sos_fs_nscache_node ** result_parent); 218 219 220 sos_ret_t 221 sos_fs_nscache_get_name(const struct sos_fs_nscache_node * nsnode, 222 struct sos_fs_pathname * result_pathname); 223 224 225 /** 226 * Return the value of the reference count for the given nscache node 227 */ 228 sos_ret_t 229 sos_fs_nscache_get_ref_cnt(const struct sos_fs_nscache_node * nsnode); 230 231 232 sos_ret_t 233 sos_fs_nscache_register_opened_file(struct sos_fs_nscache_node * nsnode, 234 struct sos_fs_opened_file * of); 235 236 237 sos_ret_t sos_fs_nscache_ref_node(struct sos_fs_nscache_node * nsnode); 238 239 240 sos_ret_t _sos_fs_nscache_unref_node(struct sos_fs_nscache_node ** nsnode); 241 #define sos_fs_nscache_unref_node(n) _sos_fs_nscache_unref_node(& (n)) 242 243 244 /* 245 * Functions reserved to sos_fs_manager_type::mount() and 246 * sos_fs_manager_type::umount() 247 */ 248 #define sos_fs_nscache_create_mounted_root(fsnode,result_nsnode) \ 249 sos_fs_nscache_add_new_child_node(NULL, NULL, (fsnode), (result_nsnode)) 250 251 252 /* 253 * Pathname manipulation functions 254 */ 255 256 sos_bool_t fs_pathname_iseq(const struct sos_fs_pathname * p1, 257 const struct sos_fs_pathname * p2); 258 259 /** 260 * Remove any leading slash from the path 261 * 262 * @Return TRUE when slashes were found at the begining 263 */ 264 sos_bool_t sos_fs_pathname_eat_slashes(const struct sos_fs_pathname * path, 265 struct sos_fs_pathname * result); 266 267 /** 268 * Transform "a/b/c" into { first_component="a" remaining_path="/b/c" } 269 * Transform "/a/b/c" into { first_component="a" remaining_path="/b/c" } 270 * Transform "////a////b/c" into { first_component="a" remaining_path="////b/c" } 271 * Transform "a" into { first_component="a" remaining_path="" } 272 * Transform "/a" into { first_component="a" remaining_path="" } 273 * Transform "a/" into { first_component="a" remaining_path="" } 274 * Transform "/a/" into { first_component="a" remaining_path="" } 275 * 276 * @Return TRUE when slashes after first component were found. In the 277 * previous example: true everywhere except for the path "a" and "/a" 278 */ 279 sos_bool_t 280 sos_fs_pathname_split_path(const struct sos_fs_pathname * path, 281 struct sos_fs_pathname * result_first_component, 282 struct sos_fs_pathname * result_remaining_path); 283 284 #endif /* _SOS_FS_NSCACHE_H_ */
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |