• No results found

B_ENTRY_CREATED B_ENTRY_REMOVED

In document Practical File System Design (Page 192-195)

The Vnode Layer

B_ENTRY_CREATED B_ENTRY_REMOVED

B_ENTRY_MOVED B_STAT_CHANGED B_ATTR_CHANGED

A file system passes one of these constants as the op argument of theno- tify listener() call. The vnid arguments are used to identify the file and directories involved in the event. Not all of the vnids must be filled in (in fact, only theB ENTRY MOVEDnotification uses all three vnid slots). The name argument is for the creation of new nodes (files, symbolic links, or directories) and when a file is renamed.

When a file system callsnotify listener(), it does not concern itself with who the notifications are sent to nor how many are sent. The only require- ment is that the file system call this when an operation completes success- fully. Although it would seem possible for the vnode layer to send the notifi- cations itself, it is not possible because the vnode layer does not always know all the vnids involved in an operation such asrename.

Internally the node monitor API is simple for a file system to implement. It only requires a few calls tonotify listener()to be made in the proper places (create,unlink,rename,close, andwrite attr). Implementing this feature in a file system requires no modifications or additions to any data structures,

1 0 . 6 L I V E Q U E R I E S

183

and it can even be used with file systems from other systems that do not support notifications.

At the vnode level, node monitors are managed in two ways. Eachioctx has a list of node monitors. The list begins at themonfield of theioctxstruc- ture. Themonlist is necessary so that when theioctxis destroyed, the vnode layer can free any node monitors still allocated by a program. In addition, the vnode layer manages a hash table of all node monitors. The hash value is based on the vnid of the node being monitored. This enables efficient lookups when a file system callsnotify listener().

The node monitoring system of the BeOS requires very little extra work on the part of a file system. Even the implemenation at the vnode layer is relatively small. The extra functionality offered by the node monitor makes it well worth the effort.

10.6

Live Queries

In addition to the node monitoring API, the BeOS also supports live queries. A query is a search of the indices maintained by a file system for a set of files that match the query criteria. As an option when opening a query, a program can specify that the query islive. A program iterates through a live query the first time just as it would with a static query. The difference is that a live query continues reporting additions and deletions to the set of files that match a query until the live query is closed. In a manner similar to node monitoring, a program will receive updates to a live query as files and directories enter and leave the set of matching files of the query.

Live queries are an extremely powerful mechanism used by the find mech- anism of the file manager as well as by other programs. For example, in the BeOS find panel, you can query for all unread email. The find panel uses live queries, and so even after the query is issued, if new mail arrives, the win- dow showing the results of the query (i.e., all new email) will be updated and the new email will appear in the window. Live queries help many parts of the system to work together in sophisticated ways without requiring special APIs for private notifications or updates.

Implementing live queries in a file system is not easy because of the many race conditions and complicated locking scenarios that can arise. Whenever a program issues a live query, the file system must tag all the indices involved in the query so that if a file is created or deleted from the index, the file sys- tem can determine if a notification needs to be sent. This requires checking the file against the full query to determine if it matches the query. If the file is entering or leaving the set of files that match the query, the file system must send a notification to any interested threads.

The vnode layer plays a smaller role in live query updates than it does with node monitor notifications. The file system must maintain the information

about exactly who to send the notification to and is responsible for calling the vnode layer function:

int send_notification(port_id port, long token,

ulong what, long op, nspace_id nsida, nspace_id nsidb, vnode_id vnida, vnode_id vnidb, vnode_id vnidc, const char *name);

for each update to all live queries. The file system must keep track of the port to send each update to and the token for the message. It is important to keep in mind that changes to a single file may require sending notifications to multiple different live queries.

At first the implementation of live queries seemed a daunting task for BFS, and much effort went into procrastinating on the actual implementation. Al- though it does seem fraught with race conditions and deadlock problems, implementing live queries did not turn out to be as difficult as initially imag- ined. The BFS implementation of live queries works by tagging each index used in the query with a callback function. Each index has a list of callbacks, and any modifications made to the index will iterate over the list of call- backs. The index code then calls into the query code with a reference to the file the index is manipulating. The query callback is also passed a pointer to the original query. The file is checked against the query parse tree, and, if appropriate, a notification is sent.

Live queries offer a very significant feature for programmers to take ad- vantage of. They enable programs to receive notification based on sophisti- cated criteria. The implementation of live queries adds a nontrivial amount of complexity to a file system, but the effort is well worth it for the features it enables.

10.7

Summary

A vnode layer connects the user-level abstraction of a file descriptor with specific file system implementations. In general, a vnode layer allows many different file systems to hook into the file system name space and appear as one seamless unit. The vnode layer defines an API that all file systems must implement. Through this API all file systems appear the same to the vnode layer. The BeOS vnode layer extends the traditional set of functions defined by a vnode layer and offers hooks for monitoring files and submitting queries to a file system. These nontraditional interfaces are necessary to provide the functionality required by the rest of the BeOS. A vnode layer is an important part of any kernel and defines the I/O model of the system.

11

In document Practical File System Design (Page 192-195)