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