1/*! 2\page fs_modules File System Modules 3 4To support a particular file system (FS), a kernel module implementing a special 5interface (\c file_system_module_info defined in \c <fs_interface.h>) has to be 6provided. As for any other module the 7\c std_ops() hook is invoked with \c B_MODULE_INIT directly after the FS module 8has been loaded by the kernel, and with \c B_MODULE_UNINIT before it is 9unloaded, thus providing a simple mechanism for one-time module initializations. 10The same module is used for accessing any volume of that FS type. 11 12 13\section objects File System Objects 14 15There are several types of objects a FS module has to deal with directly or 16indirectly: 17 18- A \em volume is an instance of a file system. For a disk-based file 19 system it corresponds to a disk, partition, or disk image file. When 20 mounting a volume the virtual file system layer (VFS) assigns a unique number 21 (ID, of type \c mount_id aka \c dev_t) to it and a handle (type 22 \c fs_volume, in fact \c void*) provided by 23 the file system. Whenever the FS requests a volume-related service from the 24 kernel, it has to pass the volume ID, and whenever the VFS asks the FS to 25 perform an operation, it supplies the handle. Normally the handle is a pointer 26 to a data structure the FS allocates to associate data with the volume. 27 28- A \em node is contained by a volume. It can be of type file, directory, or 29 symbolic link (symlink). Just as volumes nodes are associated with an ID 30 (type \c vnode_id aka ino_t) and, if in use, also with a handle 31 (type \c fs_vnode, in fact \c void*). 32 Unlike the volume ID the node ID is defined by the FS. It often 33 has a meaning to the FS, e.g. file systems using inodes might choose the 34 inode number corresponding to the node. As long as the volume is mounted and 35 the node is known to the VFS, its node ID must not change. The node handle is 36 again a pointer to a data structure allocated by the FS. 37 38- A \em vnode (VFS node) is the VFS representation of a node. A volume may 39 contain a great number of nodes, but at a time only a few are represented by 40 vnodes, usually only those that are currently in use (sometimes a few more). 41 42- An \em entry (directory entry) belongs to a directory, has a name, and refers 43 to a node. It is important to understand the difference between entries and 44 nodes: A node doesn't have a name, only the entries that refer to it have. 45 If a FS supports to have more than one entry refer to a single node, it is 46 also said to support "hard links". It is possible that no entry refers 47 to a node. This happens when a node (e.g. a file) is still open, but the last 48 entry referring to it has been removed (the node will be deleted when the 49 it is closed). While entries are to be understood as independent entities, 50 the FS interface does not use IDs or handles to refer to them; it always uses 51 directory and entry name pairs to do that. 52 53- An \em attribute is a named and typed data container belonging to a node. A 54 node may have any number of attributes; they are organized in a (virtual or 55 actually existing) attribute directory, through which one can iterate. 56 57- An \em index is supposed to provide fast searching capabilities for attributes 58 with a certain name. A volume's index directory allows for iterating through 59 the indices. 60 61- A \em query is a fully virtual object for searching for entries via an 62 expression matching entry name, node size, node modification date, and/or 63 node attributes. The mechanism of retrieving the entries found by a query 64 is similar to that for reading a directory contents. A query can be live 65 in which case the creator of the query is notified by the FS whenever an 66 entry no longer matches the query expression or starts matching. 67 68 69\section concepts Generic Concepts 70 71A FS module has to (or can) provide quite a lot of hook functions. There are 72a few concepts that apply to several groups of them: 73 74- <em>Opening, Closing, and Cookies</em>: Many FS objects can be opened and 75 closed, namely nodes in general, directories, attribute directories, 76 attributes, the index directory, and queries. In each case there are three 77 hook functions: <tt>open*()</tt>, <tt>close*()</tt>, and 78 <tt>free*_cookie()</tt>. The <tt>open*()</tt> hook is passed all that is 79 needed to identify the object to be opened and, in some cases, additional 80 parameters e.g. specifying a particular opening mode. The implementation 81 is required to return a cookie (type \c fs_cookie, in fact \c void*), usually 82 a pointer to a data structure the FS allocates. In some cases (e.g. when an 83 iteration state is associated with the cookie) a new cookie must be allocated 84 for each instance of opening the object. The cookie is passed to all hooks 85 that operate on a thusly opened object. The <tt>close*()</tt> hook is invoked 86 to signal that the cookie is to be closed. At this point the cookie might 87 still be in use. Blocking FS hooks (e.g. blocking read/write operations) 88 using the same cookie have to be unblocked. When the cookie stops being in 89 use the <tt>free*_cookie()</tt> hook is called; it has to free the cookie. 90 91- <em>Entry Iteration</em>: For the FS objects serving as containers for other 92 objects, i.e. directories, attribute directories, the index directory, 93 and queries, the cookie mechanism is used for a stateful iteration through 94 the contained objects. The <tt>read_*()</tt> hook reads the next one or more 95 entries into a <tt>struct dirent</tt> buffer. The <tt>rewind_*()</tt> hook 96 resets the iteration state to the first entry. 97 98- <em>Stat Information</em>: In case of nodes, attributes, and indices 99 detailed information about an object are requested via a <tt>read*_stat()</tt> 100 hook and must be written into a <tt>struct stat</tt> buffer. 101 102 103\section vnodes VNodes 104 105A vnode is the VFS representation of a node. As soon as an access to a node 106is requested, the VFS creates a corresponding vnode. The requesting entity 107gets a reference to the vnode for the time it works with the vnode and 108releases the reference when done. When the last reference to a vnode has been 109surrendered, the vnode is unused and the VFS can decide to destroy it (usually 110it is cached for a while longer). 111 112When the VFS creates a vnode, it invokes the FS's 113\link file_system_module_info::get_vnode get_vnode() \endlink 114hook to let it create the respective node handle (unless the FS requests the 115creation of the vnode explicitely by calling publish_vnode()). That's the only 116hook that specifies a node by ID; to all other node-related hooks the node 117handle is passed. When the VFS deletes the vnode, it invokes the FS's 118\link file_system_module_info::put_vnode put_vnode() \endlink 119hook or, if the node was marked removed, 120\link file_system_module_info::remove_vnode remove_vnode() \endlink. 121 122There are only four FS hooks through which the VFS gains knowledge of the 123existence of a node. The first one is the 124\link file_system_module_info::mount mount() \endlink 125hook. It is supposed to call \c publish_vnode() for the root node of the volume 126and return its ID. The second one is the 127\link file_system_module_info::lookup lookup() \endlink 128hook. Given a node handle of a directory and an entry name, it is supposed to 129call \c get_vnode() for the node the entry refers to and return the node ID. 130The remaining two hooks, 131\link file_system_module_info::read_dir read_dir() \endlink 132and 133\link file_system_module_info::read_query read_query() \endlink, 134both return entries in a <tt>struct dirent</tt> structure, which also contains 135the ID of the node the entry refers to. 136 137 138\section mandatory_hooks Mandatory Hooks 139 140Which hooks a FS module should provide mainly depends on what functionality 141it features. E.g. a FS without support for attribute, indices, and/or queries 142can omit the respective hooks (i.e. set them to \c NULL in the module 143structure). Some hooks are mandatory, though. A minimal read-only FS module 144must implement: 145 146- \link file_system_module_info::mount mount() \endlink and 147 \link file_system_module_info::unmount unmount() \endlink: 148 Mounting and unmounting a volume is required for pretty obvious reasons. 149 150- \link file_system_module_info::lookup lookup() \endlink: 151 The VFS uses this hook to resolve path names. It is probably one of the 152 most frequently invoked hooks. 153 154- \link file_system_module_info::get_vnode get_vnode() \endlink and 155 \link file_system_module_info::put_vnode put_vnode() \endlink: 156 Create respectively destroy the FS's private node handle when 157 the VFS creates/deletes the vnode for a particular node. 158 159- \link file_system_module_info::read_stat read_stat() \endlink: 160 Return a <tt>struct stat</tt> info for the given node, consisting of the 161 type and size of the node, its owner and access permissions, as well as 162 certain access times. 163 164- \link file_system_module_info::open open() \endlink, 165 \link file_system_module_info::close close() \endlink, and 166 \link file_system_module_info::free_cookie free_cookie() \endlink: 167 Open and close a node as explained in \ref concepts. 168 169- \link file_system_module_info::read read() \endlink: 170 Read data from an opened node (file). Even if the FS does not feature files, 171 the hook has to be present anyway; it should return an error in this case. 172 173- \link file_system_module_info::open_dir open_dir() \endlink, 174 \link file_system_module_info::close_dir close_dir() \endlink, and 175 \link file_system_module_info::free_dir_cookie free_dir_cookie() \endlink: 176 Open and close a directory for entry iteration as explained in \ref concepts. 177 178- \link file_system_module_info::read_dir read_dir() \endlink and 179 \link file_system_module_info::rewind_dir rewind_dir() \endlink: 180 Read the next entry/entries from a directory, respectively reset the iterator 181 to the first entry, as explained in \ref concepts. 182 183Although not strictly mandatory, a FS should additionally implement the 184following hooks: 185 186- \link file_system_module_info::read_fs_info read_fs_info() \endlink: 187 Return general information about the volume, e.g. total and free size, and 188 what special features (attributes, MIME types, queries) the volume/FS 189 supports. 190 191- \link file_system_module_info::read_symlink read_symlink() \endlink: 192 Read the value of a symbolic link. Needed only, if the FS and volume support 193 symbolic links at all. If absent symbolic links stored on the volume won't 194 be interpreted. 195 196- \link file_system_module_info::access access() \endlink: 197 Return whether the current user has the given access permissions for a node. 198 If the hook is absent the user is considerd to have all permissions. 199*/ 200