2c1c6f3689b2b0afb2f43a3cb04212655617bd18
[pandora-kernel.git] / Documentation / filesystems / aufs / design / 01intro.txt
1
2 # Copyright (C) 2005-2011 Junjiro R. Okajima
3
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 Introduction
19 ----------------------------------------
20
21 aufs [ei ju: ef es] | [a u f s]
22 1. abbrev. for "advanced multi-layered unification filesystem".
23 2. abbrev. for "another unionfs".
24 3. abbrev. for "auf das" in German which means "on the" in English.
25    Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
26    But "Filesystem aufs Filesystem" is hard to understand.
27
28 AUFS is a filesystem with features:
29 - multi layered stackable unification filesystem, the member directory
30   is called as a branch.
31 - branch permission and attribute, 'readonly', 'real-readonly',
32   'readwrite', 'whiteout-able', 'link-able whiteout' and their
33   combination.
34 - internal "file copy-on-write".
35 - logical deletion, whiteout.
36 - dynamic branch manipulation, adding, deleting and changing permission.
37 - allow bypassing aufs, user's direct branch access.
38 - external inode number translation table and bitmap which maintains the
39   persistent aufs inode number.
40 - seekable directory, including NFS readdir.
41 - file mapping, mmap and sharing pages.
42 - pseudo-link, hardlink over branches.
43 - loopback mounted filesystem as a branch.
44 - several policies to select one among multiple writable branches.
45 - revert a single systemcall when an error occurs in aufs.
46 - and more...
47
48
49 Multi Layered Stackable Unification Filesystem
50 ----------------------------------------------------------------------
51 Most people already knows what it is.
52 It is a filesystem which unifies several directories and provides a
53 merged single directory. When users access a file, the access will be
54 passed/re-directed/converted (sorry, I am not sure which English word is
55 correct) to the real file on the member filesystem. The member
56 filesystem is called 'lower filesystem' or 'branch' and has a mode
57 'readonly' and 'readwrite.' And the deletion for a file on the lower
58 readonly branch is handled by creating 'whiteout' on the upper writable
59 branch.
60
61 On LKML, there have been discussions about UnionMount (Jan Blunck,
62 Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
63 different approaches to implement the merged-view.
64 The former tries putting it into VFS, and the latter implements as a
65 separate filesystem.
66 (If I misunderstand about these implementations, please let me know and
67 I shall correct it. Because it is a long time ago when I read their
68 source files last time).
69
70 UnionMount's approach will be able to small, but may be hard to share
71 branches between several UnionMount since the whiteout in it is
72 implemented in the inode on branch filesystem and always
73 shared. According to Bharata's post, readdir does not seems to be
74 finished yet.
75 There are several missing features known in this implementations such as
76 - for users, the inode number may change silently. eg. copy-up.
77 - link(2) may break by copy-up.
78 - read(2) may get an obsoleted filedata (fstat(2) too).
79 - fcntl(F_SETLK) may be broken by copy-up.
80 - unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
81   open(O_RDWR).
82
83 Unionfs has a longer history. When I started implementing a stacking filesystem
84 (Aug 2005), it already existed. It has virtual super_block, inode,
85 dentry and file objects and they have an array pointing lower same kind
86 objects. After contributing many patches for Unionfs, I re-started my
87 project AUFS (Jun 2006).
88
89 In AUFS, the structure of filesystem resembles to Unionfs, but I
90 implemented my own ideas, approaches and enhancements and it became
91 totally different one.
92
93 Comparing DM snapshot and fs based implementation
94 - the number of bytes to be copied between devices is much smaller.
95 - the type of filesystem must be one and only.
96 - the fs must be writable, no readonly fs, even for the lower original
97   device. so the compression fs will not be usable. but if we use
98   loopback mount, we may address this issue.
99   for instance,
100         mount /cdrom/squashfs.img /sq
101         losetup /sq/ext2.img
102         losetup /somewhere/cow
103         dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
104 - it will be difficult (or needs more operations) to extract the
105   difference between the original device and COW.
106 - DM snapshot-merge may help a lot when users try merging. in the
107   fs-layer union, users will use rsync(1).
108
109
110 Several characters/aspects of aufs
111 ----------------------------------------------------------------------
112
113 Aufs has several characters or aspects.
114 1. a filesystem, callee of VFS helper
115 2. sub-VFS, caller of VFS helper for branches
116 3. a virtual filesystem which maintains persistent inode number
117 4. reader/writer of files on branches such like an application
118
119 1. Callee of VFS Helper
120 As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
121 unlink(2) from an application reaches sys_unlink() kernel function and
122 then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
123 calls filesystem specific unlink operation. Actually aufs implements the
124 unlink operation but it behaves like a redirector.
125
126 2. Caller of VFS Helper for Branches
127 aufs_unlink() passes the unlink request to the branch filesystem as if
128 it were called from VFS. So the called unlink operation of the branch
129 filesystem acts as usual. As a caller of VFS helper, aufs should handle
130 every necessary pre/post operation for the branch filesystem.
131 - acquire the lock for the parent dir on a branch
132 - lookup in a branch
133 - revalidate dentry on a branch
134 - mnt_want_write() for a branch
135 - vfs_unlink() for a branch
136 - mnt_drop_write() for a branch
137 - release the lock on a branch
138
139 3. Persistent Inode Number
140 One of the most important issue for a filesystem is to maintain inode
141 numbers. This is particularly important to support exporting a
142 filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
143 backend block device for its own. But some storage is necessary to
144 maintain inode number. It may be a large space and may not suit to keep
145 in memory. Aufs rents some space from its first writable branch
146 filesystem (by default) and creates file(s) on it. These files are
147 created by aufs internally and removed soon (currently) keeping opened.
148 Note: Because these files are removed, they are totally gone after
149       unmounting aufs. It means the inode numbers are not persistent
150       across unmount or reboot. I have a plan to make them really
151       persistent which will be important for aufs on NFS server.
152
153 4. Read/Write Files Internally (copy-on-write)
154 Because a branch can be readonly, when you write a file on it, aufs will
155 "copy-up" it to the upper writable branch internally. And then write the
156 originally requested thing to the file. Generally kernel doesn't
157 open/read/write file actively. In aufs, even a single write may cause a
158 internal "file copy". This behaviour is very similar to cp(1) command.
159
160 Some people may think it is better to pass such work to user space
161 helper, instead of doing in kernel space. Actually I am still thinking
162 about it. But currently I have implemented it in kernel space.