Started documenting the FS API a bit.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20544 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-04-04 01:27:50 +00:00
parent ecde9adfaf
commit 3458a335ab
5 changed files with 309 additions and 1 deletions

View File

@ -460,9 +460,11 @@ WARN_LOGFILE =
# with spaces.
INPUT = . \
drivers \
midi \
midi2 \
support \
../../headers/os/drivers/fs_interface.h \
../../headers/os/midi2 \
../../headers/os/support \
../../headers/posix/syslog.h

View File

@ -3,6 +3,7 @@
\section kits Kits and Servers
- \ref drivers
- \ref midi1
- \ref midi2 | \link midi2_intro \em Introduction \endlink
- \ref support | \link support_intro \em Introduction \endlink
@ -15,6 +16,7 @@
///// Define main kits /////
/*!
\defgroup drivers Drivers
\defgroup midi2 MIDI 2 Kit
\brief API for producing and consuming MIDI events.
\defgroup libmidi2 (libmidi2.so)
@ -29,4 +31,4 @@
/*!
\defgroup support_globals Global functions in the support kit
\ingroup support
*/
*/

View File

@ -0,0 +1,8 @@
/*!
\page drivers Drivers
\section topics Topics
- \ref fs_modules
*/

View File

@ -0,0 +1,173 @@
/*!
\file fs_interface.h
\ingroup drivers
*/
/*!
\fn status_t new_vnode(mount_id mountID, vnode_id vnodeID, fs_vnode privateNode)
\brief Creates the vnode with ID \a vnodeID and associates it with the private
data handle \a privateNode, but leaves is in an unpublished state.
The effect of the function is similar to publish_vnode(), but the vnode
remains in an unpublished state, with the effect that a subsequent
remove_vnode() will just delete the vnode and not invoke the file system's
\link file_system_module_info::remove_vnode remove_vnode() \endlink is not
invoked.
If the vnode shall be kept, publish_vnode() has to be invoked afterwards to
mark the vnode published. The combined effect is the same as only invoking
publish_vnode().
The function fails, if the vnode does already exist.
\param mountID The ID of the volume.
\param vnodeID The ID of the node.
\param privateNode The private data handle to be associated with the node.
\return \c B_OK if everything went fine, another error code otherwise.
*/
/*!
\fn status_t publish_vnode(mount_id mountID, vnode_id vnodeID,
fs_vnode privateNode)
\brief Creates the vnode with ID \a vnodeID and associates it with the private
data handle \a privateNode or just marks it published.
If the vnode does already exist and has been published, the function fails.
If it has not been published yet (i.e. after a successful new_vnode()), the
function just marks the vnode published. If the vnode did not exist at all
before, it is created and published.
If the function is successful, the caller owns a reference to the vnode. A
sequence of new_vnode() and publish_vnode() results in just one reference as
well. The reference can be surrendered by calling put_vnode().
\param mountID The ID of the volume.
\param vnodeID The ID of the node.
\param privateNode The private data handle to be associated with the node.
\return \c B_OK if everything went fine, another error code otherwise.
*/
/*!
\fn status_t get_vnode(mount_id mountID, vnode_id vnodeID,
fs_vnode *_privateNode)
\brief Retrieves the private data handle for the node with the given ID.
If the function is successful, the caller owns a reference to the vnode. The
reference can be surrendered by calling put_vnode().
\param mountID The ID of the volume.
\param vnodeID The ID of the node.
\param _privateNode Pointer to a pre-allocated variable the private data
handle shall be written to.
\return \c B_OK if everything went fine, another error code otherwise.
*/
/*!
\fn status_t put_vnode(mount_id mountID, vnode_id vnodeID)
\brief Surrenders a reference to the specified vnode.
\param mountID The ID of the volume.
\param vnodeID The ID of the node.
\return \c B_OK if everything went fine, another error code otherwise.
*/
/*!
\fn status_t remove_vnode(mount_id mountID, vnode_id vnodeID)
\brief Marks the specified vnode removed.
The caller must own a reference to the vnode or at least ensure that a
reference to the vnode exists. The function does not surrender a reference,
though.
As soon as the last reference to the vnode has been surrendered, the VFS
invokes the file system's
\link file_system_module_info::remove_vnode remove_vnode() \endlink
hook.
\param mountID The ID of the volume.
\param vnodeID The ID of the node.
\return \c B_OK if everything went fine, another error code otherwise.
*/
/*!
\fn status_t unremove_vnode(mount_id mountID, vnode_id vnodeID);
\brief Clears the "removed" mark of the specified vnode.
The caller must own a reference to the vnode or at least ensure that a
reference to the vnode exists.
The function is usually called when the caller, who has invoked remove_vnode()
before realizes that it is not possible to remove the node (e.g. due to an
error).
\param mountID The ID of the volume.
\param vnodeID The ID of the node.
\return \c B_OK if everything went fine, another error code otherwise.
*/
/*!
\fn status_t get_vnode_removed(mount_id mountID, vnode_id vnodeID,
bool* removed);
\brief Returns whether the specified vnode is marked removed.
The caller must own a reference to the vnode or at least ensure that a
reference to the vnode exists.
\param mountID The ID of the volume.
\param vnodeID The ID of the node.
\param removed Pointer to a pre-allocated variable set to \c true, if the
node is marked removed, to \c false otherwise.
\return \c B_OK if everything went fine, another error code otherwise.
*/
/*!
\class file_system_module_info
\brief Kernel module interface for file systems.
*/
/*!
\fn status_t (*file_system_module_info::get_vnode)(fs_volume fs, vnode_id id,
fs_vnode *_vnode, bool reenter)
\brief Creates the private data handle to be associated with the node referred
to by \a id.
Invoked by the VFS when it creates the vnode for the respective node.
\param fs The volume handle.
\param id The ID of the node.
\param _vnode Pointer to a pre-allocated variable the private data handle
shall be written to.
\param reenter \c true if the hook invocation has been caused by the FS itself,
e.g. by invoking ::get_vnode().
\return \c B_OK if everything went fine, another error code otherwise.
*/
/*!
\fn \fn status_t (*file_system_module_info::put_vnode)(fs_volume fs,
fs_vnode vnode, bool reenter)
\brief Deletes the private data handle associated with the specified node.
Invoked by the VFS when it deletes the vnode for the respective node and the
node is not marked removed.
\param fs The volume handle.
\param vnode The private data handle for the node.
\param reenter \c true if the hook invocation has been caused by the FS itself,
e.g. by invoking ::put_vnode().
\return \c B_OK if everything went fine, another error code otherwise.
*/
/*!
\fn status_t (*file_system_module_info::remove_vnode)(fs_volume fs,
fs_vnode vnode, bool reenter);
\brief Deletes the private data handle associated with the specified node.
Invoked by the VFS when it deletes the vnode for the respective node and the
node is marked removed.
\param fs The volume handle.
\param vnode The private data handle for the node.
\param reenter \c true if the hook invocation has been caused by the FS itself,
e.g. by invoking ::put_vnode().
\return \c B_OK if everything went fine, another error code otherwise.
*/

View File

@ -0,0 +1,123 @@
/*!
\page fs_modules File System Modules
To support a particular file system (FS), a kernel module implementing a special
interface (\c file_system_module_info defined in \c <fs_interface.h>) has to be
provided. As for any other module the
\c std_ops() hook is invoked with \c B_MODULE_INIT directly after the FS module
has been loaded by the kernel, and with \c B_MODULE_UNINIT before it is
unloaded, thus providing a simple mechanism for one-time module initializations.
The same module is used for accessing any volume of that FS type.
\section objects File System Objects
There are several types of objects a FS module has to deal with directly or
indirectly:
- 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
mounting a volume the virtual file system layer (VFS) assigns a unique 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
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
perform an operation, it supplies the handle. Normally the handle is a 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
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 fs_vnode, in fact \c void*).
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
inode number corresponding to the node. As long as the volume is mounted and
the node is known to the VFS, its node ID must not change. The node 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
contain a great number of nodes, but at a time only a few are represented 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
to a node. It is important to understand the difference between entries and
nodes: A node doesn't have a name, only the entries that refer to it have.
If a FS supports to have more than one entry refer to a single node, it is
also said to support "hard links". It is possible that no entry refers
to a node. This happens when a node (e.g. a file) is still open, but the last
entry referring to it has been removed (the node will be deleted when the
it is closed). While entries are to be understood as independent entities,
the FS interface does not use IDs or handles to refer to them; 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
node may have any number of attributes; they are organized in a (virtual or
actually existing) attribute directory, through which one can iterate.
- An \em index is supposed to provide fast searching capabilities for attributes
with a certain name. A volume's index directory allows for iterating through
the indices.
- 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
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
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.
\section concepts Generic Concepts
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:
- <em>Opening, Closing, and Cookies</em>: Many FS objects can be opened and
closed, namely nodes in general, directories, attribute directories,
attributes, the index directory, and queries. In each case there are three
hook functions: <tt>open*()</tt>, <tt>close*()</tt>, and
<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
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
a pointer to a data structure the FS allocates. In some cases (e.g. when an
iteration state is associated with the cookie) a new cookie must be allocated
for each instance of opening the object. The cookie is passed to all hooks
that operate on a thusly opened object. The <tt>close*()</tt> hook is invoked
to signal that the cookie is to be closed. At this point the cookie might
still be in use. Blocking FS hooks (e.g. blocking read/write operations)
using the same cookie have to be unblocked. When 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
objects, i.e. directories, attribute directories, the index directory,
and queries, the cookie mechanism is used for a stateful iteration through
the contained objects. The <tt>read_*()</tt> hook reads the next one or more
entries into a <tt>struct dirent</tt> buffer. The <tt>rewind_*()</tt> hook
resets the iteration state to the first entry.
- <em>Stat Information</em>: In case of nodes, attributes, and indices
detailed information about an object are requested via a <tt>read*_stat()</tt>
hook and must be written into a <tt>struct stat</tt> buffer.
\section vnodes VNodes
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
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
surrendered, the vnode is unused and the VFS can decide to destroy it (usually
it is cached for a while longer).
When the VFS creates a vnode, it invokes the FS's
\link file_system_module_info::get_vnode get_vnode() \endlink
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
hook that specifies a node by ID; to all other node-related hooks the 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
hook or, if the node was marked removed,
\link file_system_module_info::remove_vnode remove_vnode() \endlink.
*/