SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

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 ]