xref: /haiku/docs/user/drivers/fs_modules.dox (revision 2f470aec1c92ce6917b8a903e343795dc77af41f)
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