Most file systems fall into two categories: (1) kernel resident native file systems that interact directly with lower level media such as disks[11] and networks[16], and (2) user-level file systems that are based on an NFS server such as the Amd automounter[13].
Native kernel-resident file systems are difficult to develop and debug because they interact directly with device drivers, and require deep understanding of operating systems internals. User-level file systems are easier to develop and debug, but suffer from poor performance due to the extra number of context switches that take place in order to serve a user request.
We advocate a third category: kernel-resident stackable file systems, that is based on the Virtual File System (VFS). This model results in file systems with performance close to that of native kernel-resident file systems, and development effort matching that of user-level file systems. Such stackable file systems can be written from our template wrapper file system -- Wrapfs. Wrapfs takes care of interfacing with the rest of the kernel; it provides the developer with simple hooks to modify or inspect file data, file names, and file attributes. Wrapfs can be mounted on top of one or more existing directories, and act as an intermediary between the user accessing the mount point and the lower level file system it is mounted on. Wrapfs can then transparently change the behavior of the file system as seen by users, while keeping the underlying media unaware of the upper-level changes.
Wrapfs is implemented as a stackable vnode interface. A Virtual Node or vnode (known in Linux as a memory inode) is a data structure used within Unix-based operating systems to represent an open file, directory, device, or other entity (e.g., socket) that can appear in the file system name-space. A vnode does not expose what type of physical file system it implements. Thus, the vnode interface allows higher level operating system modules to perform operations on vnodes uniformly.
One notable improvement to the vnode concept is vnode stacking[8,14,18], a technique for modularizing file system functions by allowing one vnode interface to call another. Before stacking existed, there was only a single vnode interface; higher level operating system code called the vnode interface which in turn called code for a specific file system. With vnode stacking, several instances of the vnode interface may exist and may call each other in sequence: the code for a certain operation at stack level Ntypically calls the corresponding operation at level N-1, and so on.
Figure 1 shows the structure for a simple, single-level, stackable wrapper file system. System calls are translated into vnode level calls, and those invoke their Wrapfs equivalents. Wrapfs again invokes generic vnode operations, and the latter call their respective lower level file system specific operations such as EXT2FS. Wrapfs can also call the lower level file system directly, by invoking the respective vnode operations of the lower vnode. It accomplishes that without knowing who or what type of lower file system it is calling.
The rest of this paper is organized as follows. Section 2 discusses the design of Wrapfs. Section 3 details Wrapfs' implementation. Section 4 describes four examples of file systems written using the Wrapfs template. Section 5 evaluates their performance and portability. We survey related works in Section 6 and conclude in Section 7.