Work in progress. I'm still working on documenting many of the fs hooks, but I just wanted to commit this to quiet down the amount of warnings that are produced.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21257 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Niels Sascha Reedijk
2007-05-28 08:18:43 +00:00
parent c24f6c7e26
commit 8ace9affed
2 changed files with 1560 additions and 677 deletions
File diff suppressed because it is too large Load Diff
+175 -162
View File
@@ -1,199 +1,212 @@
/*! /*
\page fs_modules File System Modules * Copyright 2007 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ingo Weinhold
*/
/*!
\page fs_modules File System Modules
To support a particular file system (FS), a kernel module implementing a special To support a particular file system (FS), a kernel module implementing a
interface (\c file_system_module_info defined in \c <fs_interface.h>) has to be special interface (\c file_system_module_info defined in \c <fs_interface.h>)
provided. As for any other module the has to be provided. As for any other module the \c std_ops() hook is invoked
\c std_ops() hook is invoked with \c B_MODULE_INIT directly after the FS module with \c B_MODULE_INIT directly after the FS module has been loaded by the
has been loaded by the kernel, and with \c B_MODULE_UNINIT before it is kernel, and with \c B_MODULE_UNINIT before it is unloaded, thus providing
unloaded, thus providing a simple mechanism for one-time module initializations. a simple mechanism for one-time module initializations. The same module is
The same module is used for accessing any volume of that FS type. used for accessing any volume of that FS type.
\section objects File System Objects \section objects File System Objects
There are several types of objects a FS module has to deal with directly or There are several types of objects a FS module has to deal with directly or
indirectly: indirectly:
- A \em volume is an instance of a file system. For a disk-based file - A \em volume is an instance of a file system. For a disk-based file
system it corresponds to a disk, partition, or disk image file. When system it corresponds to a disk, partition, or disk image file. When
mounting a volume the virtual file system layer (VFS) assigns a unique number mounting a volume the virtual file system layer (VFS) assigns a unique
(ID, of type \c mount_id aka \c dev_t) to it and a handle (type number (ID, of type \c mount_id aka \c dev_t) to it and a handle (type
\c fs_volume, in fact \c void*) provided by \c fs_volume, in fact \c void*) provided by
the file system. Whenever the FS requests a volume-related service from the the file system. Whenever the FS requests a volume-related service from the
kernel, it has to pass the volume ID, and whenever the VFS asks the FS to kernel, it has to pass the volume ID, and whenever the VFS asks the FS to
perform an operation, it supplies the handle. Normally the handle is a pointer perform an operation, it supplies the handle. Normally the handle is a
to a data structure the FS allocates to associate data with the volume. pointer to a data structure the FS allocates to associate data with the
volume.
- A \em node is contained by a volume. It can be of type file, directory, or - A \em node is contained by a volume. It can be of type file, directory, or
symbolic link (symlink). Just as volumes nodes are associated with an ID symbolic link (symlink). Just as volumes nodes are associated with an ID
(type \c vnode_id aka ino_t) and, if in use, also with a handle (type \c vnode_id aka ino_t) and, if in use, also with a handle
(type \c fs_vnode, in fact \c void*). (type \c fs_vnode, in fact \c void*).
Unlike the volume ID the node ID is defined by the FS. It often Unlike the volume ID the node ID is defined by the FS. It often
has a meaning to the FS, e.g. file systems using inodes might choose the has a meaning to the FS, e.g. file systems using inodes might choose the
inode number corresponding to the node. As long as the volume is mounted and inode number corresponding to the node. As long as the volume is mounted
the node is known to the VFS, its node ID must not change. The node handle is and the node is known to the VFS, its node ID must not change. The node
again a pointer to a data structure allocated by the FS. handle is again a pointer to a data structure allocated by the FS.
- A \em vnode (VFS node) is the VFS representation of a node. A volume may - A \em vnode (VFS node) is the VFS representation of a node. A volume may
contain a great number of nodes, but at a time only a few are represented by contain a great number of nodes, but at a time only a few are represented
vnodes, usually only those that are currently in use (sometimes a few more). by vnodes, usually only those that are currently in use (sometimes a few
more).
- An \em entry (directory entry) belongs to a directory, has a name, and refers - An \em entry (directory entry) belongs to a directory, has a name, and
to a node. It is important to understand the difference between entries and refers to a node. It is important to understand the difference between
nodes: A node doesn't have a name, only the entries that refer to it have. entries and nodes: A node doesn't have a name, only the entries that refer
If a FS supports to have more than one entry refer to a single node, it is to it have. If a FS supports to have more than one entry refer to a single
also said to support "hard links". It is possible that no entry refers node, it is also said to support "hard links". It is possible that no entry
to a node. This happens when a node (e.g. a file) is still open, but the last refers to a node. This happens when a node (e.g. a file) is still open, but
entry referring to it has been removed (the node will be deleted when the the last entry referring to it has been removed (the node will be deleted
it is closed). While entries are to be understood as independent entities, when the it is closed). While entries are to be understood as independent
the FS interface does not use IDs or handles to refer to them; it always uses entities, the FS interface does not use IDs or handles to refer to them;
directory and entry name pairs to do that. it always uses directory and entry name pairs to do that.
- An \em attribute is a named and typed data container belonging to a node. A - An \em attribute is a named and typed data container belonging to a node. A
node may have any number of attributes; they are organized in a (virtual or node may have any number of attributes; they are organized in a (virtual or
actually existing) attribute directory, through which one can iterate. actually existing) attribute directory, through which one can iterate.
- An \em index is supposed to provide fast searching capabilities for attributes - An \em index is supposed to provide fast searching capabilities for
with a certain name. A volume's index directory allows for iterating through attributes with a certain name. A volume's index directory allows for
the indices. iterating through the indices.
- A \em query is a fully virtual object for searching for entries via an - A \em query is a fully virtual object for searching for entries via an
expression matching entry name, node size, node modification date, and/or expression matching entry name, node size, node modification date, and/or
node attributes. The mechanism of retrieving the entries found by a query node attributes. The mechanism of retrieving the entries found by a query
is similar to that for reading a directory contents. A query can be live is similar to that for reading a directory contents. A query can be live
in which case the creator of the query is notified by the FS whenever an in which case the creator of the query is notified by the FS whenever an
entry no longer matches the query expression or starts matching. entry no longer matches the query expression or starts matching.
\section concepts Generic Concepts \section concepts Generic Concepts
A FS module has to (or can) provide quite a lot of hook functions. There are A FS module has to (or can) provide quite a lot of hook functions. There are
a few concepts that apply to several groups of them: a few concepts that apply to several groups of them:
- <em>Opening, Closing, and Cookies</em>: Many FS objects can be opened and - <em>Opening, Closing, and Cookies</em>: Many FS objects can be opened and
closed, namely nodes in general, directories, attribute directories, closed, namely nodes in general, directories, attribute directories,
attributes, the index directory, and queries. In each case there are three attributes, the index directory, and queries. In each case there are three
hook functions: <tt>open*()</tt>, <tt>close*()</tt>, and hook functions: <tt>open*()</tt>, <tt>close*()</tt>, and
<tt>free*_cookie()</tt>. The <tt>open*()</tt> hook is passed all that is <tt>free*_cookie()</tt>. The <tt>open*()</tt> hook is passed all that is
needed to identify the object to be opened and, in some cases, additional needed to identify the object to be opened and, in some cases, additional
parameters e.g. specifying a particular opening mode. The implementation parameters e.g. specifying a particular opening mode. The implementation
is required to return a cookie (type \c fs_cookie, in fact \c void*), usually is required to return a cookie (type \c fs_cookie, in fact \c void*),
a pointer to a data structure the FS allocates. In some cases (e.g. when an usually a pointer to a data structure the FS allocates. In some cases (e.g.
iteration state is associated with the cookie) a new cookie must be allocated when an iteration state is associated with the cookie) a new cookie must
for each instance of opening the object. The cookie is passed to all hooks be allocated for each instance of opening the object. The cookie is passed
that operate on a thusly opened object. The <tt>close*()</tt> hook is invoked to all hooks that operate on a thusly opened object. The <tt>close*()</tt>
to signal that the cookie is to be closed. At this point the cookie might hook is invoked to signal that the cookie is to be closed. At this point
still be in use. Blocking FS hooks (e.g. blocking read/write operations) the cookie might still be in use. Blocking FS hooks (e.g. blocking
using the same cookie have to be unblocked. When the cookie stops being in read/write operations) using the same cookie have to be unblocked. When
use the <tt>free*_cookie()</tt> hook is called; it has to free the cookie. the cookie stops being in use the <tt>free*_cookie()</tt> hook is called;
it has to free the cookie.
- <em>Entry Iteration</em>: For the FS objects serving as containers for other - <em>Entry Iteration</em>: For the FS objects serving as containers for
objects, i.e. directories, attribute directories, the index directory, other objects, i.e. directories, attribute directories, the index
and queries, the cookie mechanism is used for a stateful iteration through directory, and queries, the cookie mechanism is used for a stateful
the contained objects. The <tt>read_*()</tt> hook reads the next one or more iteration through the contained objects. The <tt>read_*()</tt> hook reads
entries into a <tt>struct dirent</tt> buffer. The <tt>rewind_*()</tt> hook the next one or more entries into a <tt>struct dirent</tt> buffer. The
resets the iteration state to the first entry. <tt>rewind_*()</tt> hook resets the iteration state to the first entry.
- <em>Stat Information</em>: In case of nodes, attributes, and indices - <em>Stat Information</em>: In case of nodes, attributes, and indices
detailed information about an object are requested via a <tt>read*_stat()</tt> detailed information about an object are requested via a
hook and must be written into a <tt>struct stat</tt> buffer. <tt>read*_stat()</tt> hook and must be written into a <tt>struct stat</tt>
buffer.
\section vnodes VNodes \section vnodes VNodes
A vnode is the VFS representation of a node. As soon as an access to a node A vnode is the VFS representation of a node. As soon as an access to a node
is requested, the VFS creates a corresponding vnode. The requesting entity is requested, the VFS creates a corresponding vnode. The requesting entity
gets a reference to the vnode for the time it works with the vnode and gets a reference to the vnode for the time it works with the vnode and
releases the reference when done. When the last reference to a vnode has been releases the reference when done. When the last reference to a vnode has been
surrendered, the vnode is unused and the VFS can decide to destroy it (usually surrendered, the vnode is unused and the VFS can decide to destroy it
it is cached for a while longer). (usually it is cached for a while longer).
When the VFS creates a vnode, it invokes the FS's When the VFS creates a vnode, it invokes the FS's
\link file_system_module_info::get_vnode get_vnode() \endlink \link file_system_module_info::get_vnode get_vnode() \endlink
hook to let it create the respective node handle (unless the FS requests the hook to let it create the respective node handle (unless the FS requests the
creation of the vnode explicitely by calling publish_vnode()). That's the only creation of the vnode explicitely by calling publish_vnode()). That's the
hook that specifies a node by ID; to all other node-related hooks the node only hook that specifies a node by ID; to all other node-related hooks the
handle is passed. When the VFS deletes the vnode, it invokes the FS's node handle is passed. When the VFS deletes the vnode, it invokes the FS's
\link file_system_module_info::put_vnode put_vnode() \endlink \link file_system_module_info::put_vnode put_vnode() \endlink
hook or, if the node was marked removed, hook or, if the node was marked removed,
\link file_system_module_info::remove_vnode remove_vnode() \endlink. \link file_system_module_info::remove_vnode remove_vnode() \endlink.
There are only four FS hooks through which the VFS gains knowledge of the There are only four FS hooks through which the VFS gains knowledge of the
existence of a node. The first one is the existence of a node. The first one is the
\link file_system_module_info::mount mount() \endlink \link file_system_module_info::mount mount() \endlink
hook. It is supposed to call \c publish_vnode() for the root node of the volume hook. It is supposed to call \c publish_vnode() for the root node of the
and return its ID. The second one is the volume and return its ID. The second one is the
\link file_system_module_info::lookup lookup() \endlink \link file_system_module_info::lookup lookup() \endlink
hook. Given a node handle of a directory and an entry name, it is supposed to hook. Given a node handle of a directory and an entry name, it is supposed to
call \c get_vnode() for the node the entry refers to and return the node ID. call \c get_vnode() for the node the entry refers to and return the node ID.
The remaining two hooks, The remaining two hooks,
\link file_system_module_info::read_dir read_dir() \endlink \link file_system_module_info::read_dir read_dir() \endlink and
and \link file_system_module_info::read_query read_query() \endlink,
\link file_system_module_info::read_query read_query() \endlink, both return entries in a <tt>struct dirent</tt> structure, which also
both return entries in a <tt>struct dirent</tt> structure, which also contains contains the ID of the node the entry refers to.
the ID of the node the entry refers to.
\section mandatory_hooks Mandatory Hooks \section mandatory_hooks Mandatory Hooks
Which hooks a FS module should provide mainly depends on what functionality Which hooks a FS module should provide mainly depends on what functionality
it features. E.g. a FS without support for attribute, indices, and/or queries it features. E.g. a FS without support for attribute, indices, and/or queries
can omit the respective hooks (i.e. set them to \c NULL in the module can omit the respective hooks (i.e. set them to \c NULL in the module
structure). Some hooks are mandatory, though. A minimal read-only FS module structure). Some hooks are mandatory, though. A minimal read-only FS module
must implement: must implement:
- \link file_system_module_info::mount mount() \endlink and - \link file_system_module_info::mount mount() \endlink and
\link file_system_module_info::unmount unmount() \endlink: \link file_system_module_info::unmount unmount() \endlink:
Mounting and unmounting a volume is required for pretty obvious reasons. Mounting and unmounting a volume is required for pretty obvious reasons.
- \link file_system_module_info::lookup lookup() \endlink: - \link file_system_module_info::lookup lookup() \endlink:
The VFS uses this hook to resolve path names. It is probably one of the The VFS uses this hook to resolve path names. It is probably one of the
most frequently invoked hooks. most frequently invoked hooks.
- \link file_system_module_info::get_vnode get_vnode() \endlink and - \link file_system_module_info::get_vnode get_vnode() \endlink and
\link file_system_module_info::put_vnode put_vnode() \endlink: \link file_system_module_info::put_vnode put_vnode() \endlink:
Create respectively destroy the FS's private node handle when Create respectively destroy the FS's private node handle when
the VFS creates/deletes the vnode for a particular node. the VFS creates/deletes the vnode for a particular node.
- \link file_system_module_info::read_stat read_stat() \endlink: - \link file_system_module_info::read_stat read_stat() \endlink:
Return a <tt>struct stat</tt> info for the given node, consisting of the Return a <tt>struct stat</tt> info for the given node, consisting of the
type and size of the node, its owner and access permissions, as well as type and size of the node, its owner and access permissions, as well as
certain access times. certain access times.
- \link file_system_module_info::open open() \endlink, - \link file_system_module_info::open open() \endlink,
\link file_system_module_info::close close() \endlink, and \link file_system_module_info::close close() \endlink, and
\link file_system_module_info::free_cookie free_cookie() \endlink: \link file_system_module_info::free_cookie free_cookie() \endlink:
Open and close a node as explained in \ref concepts. Open and close a node as explained in \ref concepts.
- \link file_system_module_info::read read() \endlink: - \link file_system_module_info::read read() \endlink:
Read data from an opened node (file). Even if the FS does not feature files, Read data from an opened node (file). Even if the FS does not feature
the hook has to be present anyway; it should return an error in this case. files, the hook has to be present anyway; it should return an error in this
case.
- \link file_system_module_info::open_dir open_dir() \endlink, - \link file_system_module_info::open_dir open_dir() \endlink,
\link file_system_module_info::close_dir close_dir() \endlink, and \link file_system_module_info::close_dir close_dir() \endlink, and
\link file_system_module_info::free_dir_cookie free_dir_cookie() \endlink: \link file_system_module_info::free_dir_cookie free_dir_cookie() \endlink:
Open and close a directory for entry iteration as explained in \ref concepts. Open and close a directory for entry iteration as explained in
\ref concepts.
- \link file_system_module_info::read_dir read_dir() \endlink and - \link file_system_module_info::read_dir read_dir() \endlink and
\link file_system_module_info::rewind_dir rewind_dir() \endlink: \link file_system_module_info::rewind_dir rewind_dir() \endlink:
Read the next entry/entries from a directory, respectively reset the iterator Read the next entry/entries from a directory, respectively reset the
to the first entry, as explained in \ref concepts. iterator to the first entry, as explained in \ref concepts.
Although not strictly mandatory, a FS should additionally implement the Although not strictly mandatory, a FS should additionally implement the
following hooks: following hooks:
- \link file_system_module_info::read_fs_info read_fs_info() \endlink: - \link file_system_module_info::read_fs_info read_fs_info() \endlink:
Return general information about the volume, e.g. total and free size, and Return general information about the volume, e.g. total and free size, and
what special features (attributes, MIME types, queries) the volume/FS what special features (attributes, MIME types, queries) the volume/FS
supports. supports.
- \link file_system_module_info::read_symlink read_symlink() \endlink: - \link file_system_module_info::read_symlink read_symlink() \endlink:
Read the value of a symbolic link. Needed only, if the FS and volume support Read the value of a symbolic link. Needed only, if the FS and volume
symbolic links at all. If absent symbolic links stored on the volume won't support symbolic links at all. If absent symbolic links stored on the
be interpreted. volume won't be interpreted.
- \link file_system_module_info::access access() \endlink: - \link file_system_module_info::access access() \endlink:
Return whether the current user has the given access permissions for a node. Return whether the current user has the given access permissions for a
If the hook is absent the user is considerd to have all permissions. node. If the hook is absent the user is considerd to have all permissions.
*/ */