📄 fs_nscache.h
字号:
/* Copyright (C) 2005 David Decotigny Copyright (C) 2000-2005 The KOS Team (Thomas Petazzoni, David Decotigny, Julien Munier) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifndef _SOS_FS_NSCACHE_H_#define _SOS_FS_NSCACHE_H_/** * @file fs_nscache.h * * FS Namespace cache (aka file hierarchy) management. Internal API * reserved to fs.c and to the FS managers ! See fs.c for details and * role of this subsystem in the whole VFS. * * We keep the usual filesystem semantics of a "file hierarchy": * * parent0 * / \ * child1 child2 * / \ \ * child1a child1b child2a * * The system allows that different children actually reference the * same "on-disk" node (sos_fs_node). For example: child1a and child2a * might reference the same sos_fs_node: this represents a so-called * "hard link". * * The functions of this module are in charge of updating the nscache * nodes and their reference count. They don't influence the other * subsystems (apart from the sos_fs_nscache_unref_node() function * which can unreference the underlying sos_fs_node). * * Note: only the nscache nodes that are actually used or those that * are their parents (ie in the path from these nodes to the global * root) will remain in memory. The others will be destroyed as soon * as they are not needed anymore. For example, il I do a * stat("/mnt/toto/titi.txt", & st), all the nscache nodes from "/" to * "titi.txt" will be allocated, the stat performed, and all of them * will be destroyed. We could imagine a real "cache" here to avoid * these bursts of allocations/deallocations, by keeping the last * accessed nodes aside when they are not referenced anymore (in a * hash table for example, the key being {parent nscache node address, * child name}). * * Note about mountpoints: When a FS is mounted in, say "/mnt", the * nscache node of the new FS is registered neither as its child nor * as its parent, but as a kind of "brother" of /mnt. As seen from the * global root ("/"), "mnt" in a direct child and the mounted root is * its brother. But, once mounted, as seen from a child node * "/mnt/toto", the mounted root is seen as the direct parent of * /mnt/toto and "mnt" is seen as its brother. That is, each time we * try to resolve (lookup) the children on a mountpoint, we must * "follow" the mountchain. In the previous example, multiple * successive FS could be mounted on the same "/mnt". */#include <sos/types.h>#include <sos/errno.h>/** * Opaque structure defined in fs_nscache.c * * Essentially contains: * - a name (allocated in-place) * - a reference to the associated FS node (struct sos_fs_node) * - a reference to the parent nscache node (if any) * - a list of pointers to the children nscache nodes (for directories) */struct sos_fs_nscache_node;#include "fs.h"/** * Support for non-0 terminated strings (Pascal-style). Useful to * prevent from altering the contents of the string in order to split * pathnames into components (@see sos_fs_pathname_split_path) */struct sos_fs_pathname{ const char * contents; sos_size_t length;};sos_ret_t sos_fs_nscache_subsystem_setup();/** * Lookup the given entry in the given nsnode. The lookup is limited * to the children entries that are already in memory. When this * lookup fails, this simply means that the entry is not already in * memory, and has to be resolved using disk accesses (@see * fs_lookup_node in fs.c) * * @param cur_nsnode The node in which we are looking for the entry * @param root_node The base node beyond which lookup must not go (to * support chroot): a kind of "barrier" * * @param result_nsnode The nsnode for the given entry (set only when * the return value is SOS_OK) * * @return error if the entry could not be found in the nsnode * directory. OK otherwise, and *result_nsnode is set. * * @note The symlinks are NOT expanded. The mountpoints ARE followed. * @note result_nsnode is a NEW reference to the node. It should be * unreferenced when unused */sos_ret_tsos_fs_nscache_lookup(struct sos_fs_nscache_node * cur_nsnode, const struct sos_fs_pathname * node_name, const struct sos_fs_nscache_node * root_nsnode, struct sos_fs_nscache_node ** result_nsnode);/** * Add a new child node for the given parent, for the given fs_node * * @param parent might be NULL, meaning that the node is the root of a * mounted filesystem * * @note The new node has the value 0 for the opened_file and * mount_chain counters * @note result_nsnode is a NEW reference to the node. It should be * unreferenced when unused */sos_ret_tsos_fs_nscache_add_new_child_node(struct sos_fs_nscache_node * parent, const struct sos_fs_pathname * node_name, struct sos_fs_node * fsnode, struct sos_fs_nscache_node ** result_nsnode);/** * Add a new child node for the given parent, for the given already * existing nsnode (with no parent !) * * @param parent can not be NULL * * @note nsnode should NOT have any parent */sos_ret_tsos_fs_nscache_add_existing_child_node(struct sos_fs_nscache_node * parent, const struct sos_fs_pathname * node_name, struct sos_fs_nscache_node * nsnode);/** * Disconnect the given node from its parent, if any * @note reference count of nsnode is NOT modified */sos_ret_tsos_fs_nscache_disconnect_node(struct sos_fs_nscache_node * nsnode);/** * Register the given root of a new file system (mounted_root) in the * mountpoint chain located at mountpoint, ie build the mountchain. */sos_ret_tsos_fs_nscache_mount(struct sos_fs_nscache_node * mountpoint, struct sos_fs_nscache_node * mounted_root);/** * Break the mountchain at the given mounted root, making sure that * this nscache node is not reference by any opened file or child node * anymore. */sos_ret_tsos_fs_nscache_umount(struct sos_fs_nscache_node * mounted_root);/** Return true if the node is involved in any mountchain */sos_bool_tsos_fs_nscache_is_mountnode(const struct sos_fs_nscache_node * nsnode);/* * Accessor functions *//** * Return the FS node of the given nscache node. * * @note The FS node returned is NOT newly referenced */struct sos_fs_node *sos_fs_nscache_get_fs_node(const struct sos_fs_nscache_node * nsnode);/** * Return the parent nscache node of the given nscache node. * * @note The nscache node returned is NOT newly referenced */sos_ret_tsos_fs_nscache_get_parent(const struct sos_fs_nscache_node * nsnode, struct sos_fs_nscache_node ** result_parent);sos_ret_tsos_fs_nscache_get_name(const struct sos_fs_nscache_node * nsnode, struct sos_fs_pathname * result_pathname);/** * Return the value of the reference count for the given nscache node */sos_ret_tsos_fs_nscache_get_ref_cnt(const struct sos_fs_nscache_node * nsnode);sos_ret_tsos_fs_nscache_register_opened_file(struct sos_fs_nscache_node * nsnode, struct sos_fs_opened_file * of);sos_ret_t sos_fs_nscache_ref_node(struct sos_fs_nscache_node * nsnode);sos_ret_t _sos_fs_nscache_unref_node(struct sos_fs_nscache_node ** nsnode);#define sos_fs_nscache_unref_node(n) _sos_fs_nscache_unref_node(& (n))/* * Functions reserved to sos_fs_manager_type::mount() and * sos_fs_manager_type::umount() */#define sos_fs_nscache_create_mounted_root(fsnode,result_nsnode) \ sos_fs_nscache_add_new_child_node(NULL, NULL, (fsnode), (result_nsnode))/* * Pathname manipulation functions */sos_bool_t fs_pathname_iseq(const struct sos_fs_pathname * p1, const struct sos_fs_pathname * p2);/** * Remove any leading slash from the path * * @Return TRUE when slashes were found at the begining */sos_bool_t sos_fs_pathname_eat_slashes(const struct sos_fs_pathname * path, struct sos_fs_pathname * result);/** * Transform "a/b/c" into { first_component="a" remaining_path="/b/c" } * Transform "/a/b/c" into { first_component="a" remaining_path="/b/c" } * Transform "////a////b/c" into { first_component="a" remaining_path="////b/c" } * Transform "a" into { first_component="a" remaining_path="" } * Transform "/a" into { first_component="a" remaining_path="" } * Transform "a/" into { first_component="a" remaining_path="" } * Transform "/a/" into { first_component="a" remaining_path="" } * * @Return TRUE when slashes after first component were found. In the * previous example: true everywhere except for the path "a" and "/a" */sos_bool_tsos_fs_pathname_split_path(const struct sos_fs_pathname * path, struct sos_fs_pathname * result_first_component, struct sos_fs_pathname * result_remaining_path);#endif /* _SOS_FS_NSCACHE_H_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -