* Wrapfs, stackable file systems Kernel: 1. system calls 2. VFS 2.5: stackable f/s 3. f/s driver (ext4, nfs, ramfs, cdfs, etc.) 4. media to store data: - ext4: block driver, hard disks, ssd - nfs: network/socket calls - ramfs: DRAM - cdfs: ISO CD/DVD media (readonly) A stackable f/s sits below VFS and above OTHER file systems, intercepts VFS calls, and then passes them to another file-system. A null-layer stackable f/s does "nothing": just pass ops b/t VFS and another file system (called a "lower" f/s). A stackable f/s sits below VFS, so it looks to the VFS as a just another regular file system. At same time, a stackable f/s has to treat the "lower" f/s as if the lower f/s was called by the VFS. A stackable f/s has a bottom half that looks like a VFS and a top half that looks like a regular f/s. If this works well, you can stack N f/s on top of each other, each stackable f/s adds some other functionality. * Example object mgmt User opens a file A. wrapfs ("upper" file system) B. ext4 ("lower" file system) F' -> D' -> I' (wrapfs) | | | F -> D -> I (ext4) F's RC is at least +1 what it was before. D's RC is at least 2: upper D' and lower F point to it. I's RC is at least 2: upper I' and lower D point to it. Use void* in structs to point to lower objects. Have to maintain proper refcounts. Some f/s ops like ->create are called to create a new object. 1. before wrapfs_create calls vfs_create on lower objects, the dentry (2nd arg) would look like: D' | D Both are null dentries. After successful return from vfs_create at lower f/s, structures would look like this: D' | D -> I wrapfs_interpose finishes setting up the structures for stacking, adding an upper Inode and linking it with upper dentry and lower inode (and handle RCs): D' -> I' | | D -> I