Release new version 3.8.5-1+grml.1 of linux-meta-grml
[grml-kernel.git] / 2.6.36 / 4305_aufs_for_2.6.36.patch
1 From 03d2de515c04772f081c2775a82554089c9e12ab Mon Sep 17 00:00:00 2001
2 From: Michael <mika@grml.org>
3 Date: Wed, 24 Nov 2010 11:58:11 +0000
4 Subject: aufs for 2.6.36
5
6 Based on 
7 http://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-standalone.git
8 (version 2-standalone.tree-36-rcN-20100823,
9 git commit 35c9de03d765d93d9d88e403637c1424d38cddf5) and
10 http://www.mail-archive.com/aufs-users@lists.sourceforge.net/msg02919/a.patch.bz2
11
12 ---
13  Documentation/ABI/testing/debugfs-aufs |   37 +
14  Documentation/ABI/testing/sysfs-aufs   |   24 +
15  fs/Kconfig                             |    1 +
16  fs/Makefile                            |    1 +
17  fs/aufs/Kconfig                        |  173 ++++
18  fs/aufs/Makefile                       |   37 +
19  fs/aufs/aufs.h                         |   61 ++
20  fs/aufs/branch.c                       | 1005 ++++++++++++++++++++
21  fs/aufs/branch.h                       |  224 +++++
22  fs/aufs/conf.mk                        |   36 +
23  fs/aufs/cpup.c                         | 1059 +++++++++++++++++++++
24  fs/aufs/cpup.h                         |   81 ++
25  fs/aufs/dbgaufs.c                      |  334 +++++++
26  fs/aufs/dbgaufs.h                      |   52 ++
27  fs/aufs/dcsub.c                        |  200 ++++
28  fs/aufs/dcsub.h                        |   54 ++
29  fs/aufs/debug.c                        |  426 +++++++++
30  fs/aufs/debug.h                        |  243 +++++
31  fs/aufs/dentry.c                       |  851 +++++++++++++++++
32  fs/aufs/dentry.h                       |  231 +++++
33  fs/aufs/dinfo.c                        |  395 ++++++++
34  fs/aufs/dir.c                          |  638 +++++++++++++
35  fs/aufs/dir.h                          |  138 +++
36  fs/aufs/dynop.c                        |  425 +++++++++
37  fs/aufs/dynop.h                        |   89 ++
38  fs/aufs/export.c                       |  788 ++++++++++++++++
39  fs/aufs/f_op.c                         |  886 ++++++++++++++++++
40  fs/aufs/f_op_sp.c                      |  301 ++++++
41  fs/aufs/file.c                         |  652 +++++++++++++
42  fs/aufs/file.h                         |  238 +++++
43  fs/aufs/finfo.c                        |  167 ++++
44  fs/aufs/fstype.h                       |  497 ++++++++++
45  fs/aufs/hfsnotify.c                    |  216 +++++
46  fs/aufs/hfsplus.c                      |   58 ++
47  fs/aufs/hnotify.c                      |  663 ++++++++++++++
48  fs/aufs/i_op.c                         |  911 ++++++++++++++++++
49  fs/aufs/i_op_add.c                     |  672 ++++++++++++++
50  fs/aufs/i_op_del.c                     |  472 ++++++++++
51  fs/aufs/i_op_ren.c                     |  977 ++++++++++++++++++++
52  fs/aufs/iinfo.c                        |  257 ++++++
53  fs/aufs/inode.c                        |  443 +++++++++
54  fs/aufs/inode.h                        |  498 ++++++++++
55  fs/aufs/ioctl.c                        |  155 ++++
56  fs/aufs/loop.c                         |   63 ++
57  fs/aufs/loop.h                         |   42 +
58  fs/aufs/magic.mk                       |   54 ++
59  fs/aufs/module.c                       |  171 ++++
60  fs/aufs/module.h                       |   82 ++
61  fs/aufs/mtx.h                          |   48 +
62  fs/aufs/opts.c                         | 1571 ++++++++++++++++++++++++++++++++
63  fs/aufs/opts.h                         |  198 ++++
64  fs/aufs/plink.c                        |  451 +++++++++
65  fs/aufs/poll.c                         |   56 ++
66  fs/aufs/rdu.c                          |  377 ++++++++
67  fs/aufs/rwsem.h                        |  187 ++++
68  fs/aufs/sbinfo.c                       |  269 ++++++
69  fs/aufs/spl.h                          |   66 ++
70  fs/aufs/super.c                        |  852 +++++++++++++++++
71  fs/aufs/super.h                        |  465 ++++++++++
72  fs/aufs/sysaufs.c                      |  107 +++
73  fs/aufs/sysaufs.h                      |  105 +++
74  fs/aufs/sysfs.c                        |  250 +++++
75  fs/aufs/sysrq.c                        |  120 +++
76  fs/aufs/vdir.c                         |  884 ++++++++++++++++++
77  fs/aufs/vfsub.c                        |  789 ++++++++++++++++
78  fs/aufs/vfsub.h                        |  209 +++++
79  fs/aufs/wbr_policy.c                   |  699 ++++++++++++++
80  fs/aufs/whout.c                        | 1052 +++++++++++++++++++++
81  fs/aufs/whout.h                        |   87 ++
82  fs/aufs/wkq.c                          |  226 +++++
83  fs/aufs/wkq.h                          |   88 ++
84  fs/aufs/xino.c                         | 1263 +++++++++++++++++++++++++
85  fs/file_table.c                        |    2 +
86  fs/inode.c                             |    1 +
87  fs/namei.c                             |    7 +-
88  fs/namespace.c                         |    1 +
89  fs/notify/group.c                      |    3 +
90  fs/notify/mark.c                       |    4 +
91  fs/open.c                              |    1 +
92  fs/splice.c                            |   12 +-
93  fs/statfs.c                            |    1 +
94  include/linux/Kbuild                   |    1 +
95  include/linux/aufs_type.h              |  198 ++++
96  include/linux/namei.h                  |    3 +
97  include/linux/splice.h                 |    6 +
98  security/commoncap.c                   |    1 +
99  security/device_cgroup.c               |    1 +
100  security/security.c                    |   13 +
101  88 files changed, 26745 insertions(+), 7 deletions(-)
102  create mode 100644 Documentation/ABI/testing/debugfs-aufs
103  create mode 100644 Documentation/ABI/testing/sysfs-aufs
104  create mode 100644 fs/aufs/Kconfig
105  create mode 100644 fs/aufs/Makefile
106  create mode 100644 fs/aufs/aufs.h
107  create mode 100644 fs/aufs/branch.c
108  create mode 100644 fs/aufs/branch.h
109  create mode 100644 fs/aufs/conf.mk
110  create mode 100644 fs/aufs/cpup.c
111  create mode 100644 fs/aufs/cpup.h
112  create mode 100644 fs/aufs/dbgaufs.c
113  create mode 100644 fs/aufs/dbgaufs.h
114  create mode 100644 fs/aufs/dcsub.c
115  create mode 100644 fs/aufs/dcsub.h
116  create mode 100644 fs/aufs/debug.c
117  create mode 100644 fs/aufs/debug.h
118  create mode 100644 fs/aufs/dentry.c
119  create mode 100644 fs/aufs/dentry.h
120  create mode 100644 fs/aufs/dinfo.c
121  create mode 100644 fs/aufs/dir.c
122  create mode 100644 fs/aufs/dir.h
123  create mode 100644 fs/aufs/dynop.c
124  create mode 100644 fs/aufs/dynop.h
125  create mode 100644 fs/aufs/export.c
126  create mode 100644 fs/aufs/f_op.c
127  create mode 100644 fs/aufs/f_op_sp.c
128  create mode 100644 fs/aufs/file.c
129  create mode 100644 fs/aufs/file.h
130  create mode 100644 fs/aufs/finfo.c
131  create mode 100644 fs/aufs/fstype.h
132  create mode 100644 fs/aufs/hfsnotify.c
133  create mode 100644 fs/aufs/hfsplus.c
134  create mode 100644 fs/aufs/hnotify.c
135  create mode 100644 fs/aufs/i_op.c
136  create mode 100644 fs/aufs/i_op_add.c
137  create mode 100644 fs/aufs/i_op_del.c
138  create mode 100644 fs/aufs/i_op_ren.c
139  create mode 100644 fs/aufs/iinfo.c
140  create mode 100644 fs/aufs/inode.c
141  create mode 100644 fs/aufs/inode.h
142  create mode 100644 fs/aufs/ioctl.c
143  create mode 100644 fs/aufs/loop.c
144  create mode 100644 fs/aufs/loop.h
145  create mode 100644 fs/aufs/magic.mk
146  create mode 100644 fs/aufs/module.c
147  create mode 100644 fs/aufs/module.h
148  create mode 100644 fs/aufs/mtx.h
149  create mode 100644 fs/aufs/opts.c
150  create mode 100644 fs/aufs/opts.h
151  create mode 100644 fs/aufs/plink.c
152  create mode 100644 fs/aufs/poll.c
153  create mode 100644 fs/aufs/rdu.c
154  create mode 100644 fs/aufs/rwsem.h
155  create mode 100644 fs/aufs/sbinfo.c
156  create mode 100644 fs/aufs/spl.h
157  create mode 100644 fs/aufs/super.c
158  create mode 100644 fs/aufs/super.h
159  create mode 100644 fs/aufs/sysaufs.c
160  create mode 100644 fs/aufs/sysaufs.h
161  create mode 100644 fs/aufs/sysfs.c
162  create mode 100644 fs/aufs/sysrq.c
163  create mode 100644 fs/aufs/vdir.c
164  create mode 100644 fs/aufs/vfsub.c
165  create mode 100644 fs/aufs/vfsub.h
166  create mode 100644 fs/aufs/wbr_policy.c
167  create mode 100644 fs/aufs/whout.c
168  create mode 100644 fs/aufs/whout.h
169  create mode 100644 fs/aufs/wkq.c
170  create mode 100644 fs/aufs/wkq.h
171  create mode 100644 fs/aufs/xino.c
172  create mode 100644 include/linux/aufs_type.h
173
174 diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs
175 new file mode 100644
176 index 0000000..7d2e65f
177 --- /dev/null
178 +++ b/Documentation/ABI/testing/debugfs-aufs
179 @@ -0,0 +1,37 @@
180 +What:          /debug/aufs/si_<id>/
181 +Date:          March 2009
182 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
183 +Description:
184 +               Under /debug/aufs, a directory named si_<id> is created
185 +               per aufs mount, where <id> is a unique id generated
186 +               internally.
187 +
188 +What:          /debug/aufs/si_<id>/xib
189 +Date:          March 2009
190 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
191 +Description:
192 +               It shows the consumed blocks by xib (External Inode Number
193 +               Bitmap), its block size and file size.
194 +               When the aufs mount option 'noxino' is specified, it
195 +               will be empty. About XINO files, see the aufs manual.
196 +
197 +What:          /debug/aufs/si_<id>/xino0, xino1 ... xinoN
198 +Date:          March 2009
199 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
200 +Description:
201 +               It shows the consumed blocks by xino (External Inode Number
202 +               Translation Table), its link count, block size and file
203 +               size.
204 +               When the aufs mount option 'noxino' is specified, it
205 +               will be empty. About XINO files, see the aufs manual.
206 +
207 +What:          /debug/aufs/si_<id>/xigen
208 +Date:          March 2009
209 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
210 +Description:
211 +               It shows the consumed blocks by xigen (External Inode
212 +               Generation Table), its block size and file size.
213 +               If CONFIG_AUFS_EXPORT is disabled, this entry will not
214 +               be created.
215 +               When the aufs mount option 'noxino' is specified, it
216 +               will be empty. About XINO files, see the aufs manual.
217 diff --git a/Documentation/ABI/testing/sysfs-aufs b/Documentation/ABI/testing/sysfs-aufs
218 new file mode 100644
219 index 0000000..7af6dc0
220 --- /dev/null
221 +++ b/Documentation/ABI/testing/sysfs-aufs
222 @@ -0,0 +1,24 @@
223 +What:          /sys/fs/aufs/si_<id>/
224 +Date:          March 2009
225 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
226 +Description:
227 +               Under /sys/fs/aufs, a directory named si_<id> is created
228 +               per aufs mount, where <id> is a unique id generated
229 +               internally.
230 +
231 +What:          /sys/fs/aufs/si_<id>/br0, br1 ... brN
232 +Date:          March 2009
233 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
234 +Description:
235 +               It shows the abolute path of a member directory (which
236 +               is called branch) in aufs, and its permission.
237 +
238 +What:          /sys/fs/aufs/si_<id>/xi_path
239 +Date:          March 2009
240 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
241 +Description:
242 +               It shows the abolute path of XINO (External Inode Number
243 +               Bitmap, Translation Table and Generation Table) file
244 +               even if it is the default path.
245 +               When the aufs mount option 'noxino' is specified, it
246 +               will be empty. About XINO files, see the aufs manual.
247 diff --git a/fs/Kconfig b/fs/Kconfig
248 index 3d18530..8f582e1 100644
249 --- a/fs/Kconfig
250 +++ b/fs/Kconfig
251 @@ -189,6 +189,7 @@ source "fs/romfs/Kconfig"
252  source "fs/sysv/Kconfig"
253  source "fs/ufs/Kconfig"
254  source "fs/exofs/Kconfig"
255 +source "fs/aufs/Kconfig"
256  
257  endif # MISC_FILESYSTEMS
258  
259 diff --git a/fs/Makefile b/fs/Makefile
260 index e6ec1d3..b0d795a 100644
261 --- a/fs/Makefile
262 +++ b/fs/Makefile
263 @@ -126,3 +126,4 @@ obj-$(CONFIG_BTRFS_FS)              += btrfs/
264  obj-$(CONFIG_GFS2_FS)           += gfs2/
265  obj-$(CONFIG_EXOFS_FS)          += exofs/
266  obj-$(CONFIG_CEPH_FS)          += ceph/
267 +obj-$(CONFIG_AUFS_FS)           += aufs/
268 diff --git a/fs/aufs/Kconfig b/fs/aufs/Kconfig
269 new file mode 100644
270 index 0000000..54ecd33
271 --- /dev/null
272 +++ b/fs/aufs/Kconfig
273 @@ -0,0 +1,173 @@
274 +config AUFS_FS
275 +       tristate "Aufs (Advanced multi layered unification filesystem) support"
276 +       depends on EXPERIMENTAL
277 +       help
278 +       Aufs is a stackable unification filesystem such as Unionfs,
279 +       which unifies several directories and provides a merged single
280 +       directory.
281 +       In the early days, aufs was entirely re-designed and
282 +       re-implemented Unionfs Version 1.x series. Introducing many
283 +       original ideas, approaches and improvements, it becomes totally
284 +       different from Unionfs while keeping the basic features.
285 +
286 +if AUFS_FS
287 +choice
288 +       prompt "Maximum number of branches"
289 +       default AUFS_BRANCH_MAX_127
290 +       help
291 +       Specifies the maximum number of branches (or member directories)
292 +       in a single aufs. The larger value consumes more system
293 +       resources and has a minor impact to performance.
294 +config AUFS_BRANCH_MAX_127
295 +       bool "127"
296 +       help
297 +       Specifies the maximum number of branches (or member directories)
298 +       in a single aufs. The larger value consumes more system
299 +       resources and has a minor impact to performance.
300 +config AUFS_BRANCH_MAX_511
301 +       bool "511"
302 +       help
303 +       Specifies the maximum number of branches (or member directories)
304 +       in a single aufs. The larger value consumes more system
305 +       resources and has a minor impact to performance.
306 +config AUFS_BRANCH_MAX_1023
307 +       bool "1023"
308 +       help
309 +       Specifies the maximum number of branches (or member directories)
310 +       in a single aufs. The larger value consumes more system
311 +       resources and has a minor impact to performance.
312 +config AUFS_BRANCH_MAX_32767
313 +       bool "32767"
314 +       help
315 +       Specifies the maximum number of branches (or member directories)
316 +       in a single aufs. The larger value consumes more system
317 +       resources and has a minor impact to performance.
318 +endchoice
319 +
320 +config AUFS_HNOTIFY
321 +       bool "Detect direct branch access (bypassing aufs)"
322 +       help
323 +       If you want to modify files on branches directly, eg. bypassing aufs,
324 +       and want aufs to detect the changes of them fully, then enable this
325 +       option and use 'udba=notify' mount option.
326 +       Currently there is only one available configuration, "fsnotify".
327 +       It will have a negative impact to the performance.
328 +       See detail in aufs.5.
329 +
330 +
331 +choice
332 +       prompt "method" if AUFS_HNOTIFY
333 +       default AUFS_HFSNOTIFY
334 +config AUFS_HFSNOTIFY
335 +       bool "fsnotify"
336 +       select FSNOTIFY
337 +endchoice
338 +
339 +config AUFS_EXPORT
340 +       bool "NFS-exportable aufs"
341 +       depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS)
342 +       help
343 +       If you want to export your mounted aufs via NFS, then enable this
344 +       option. There are several requirements for this configuration.
345 +       See detail in aufs.5.
346 +
347 +config AUFS_INO_T_64
348 +       bool
349 +       depends on AUFS_EXPORT
350 +       depends on 64BIT && !(ALPHA || S390)
351 +       default y
352 +       help
353 +       Automatic configuration for internal use.
354 +       /* typedef unsigned long/int __kernel_ino_t */
355 +       /* alpha and s390x are int */
356 +
357 +config AUFS_RDU
358 +       bool "Readdir in userspace"
359 +       help
360 +       Aufs has two methods to provide a merged view for a directory,
361 +       by a user-space library and by kernel-space natively. The latter
362 +       is always enabled but sometimes large and slow.
363 +       If you enable this option, install the library in aufs2-util
364 +       package, and set some environment variables for your readdir(3),
365 +       then the work will be handled in user-space which generally
366 +       shows better performance in most cases.
367 +       See detail in aufs.5.
368 +
369 +config AUFS_SP_IATTR
370 +       bool "Respect the attributes (mtime/ctime mainly) of special files"
371 +       help
372 +       When you write something to a special file, some attributes of it
373 +       (mtime/ctime mainly) may be updated. Generally such updates are
374 +       less important (actually some device drivers and NFS ignore
375 +       it). But some applications (such like test program) requires
376 +       such updates. If you need these updates, then enable this
377 +       configuration which introduces some overhead.
378 +       Currently this configuration handles FIFO only.
379 +
380 +config AUFS_SHWH
381 +       bool "Show whiteouts"
382 +       help
383 +       If you want to make the whiteouts in aufs visible, then enable
384 +       this option and specify 'shwh' mount option. Although it may
385 +       sounds like philosophy or something, but in technically it
386 +       simply shows the name of whiteout with keeping its behaviour.
387 +
388 +config AUFS_BR_RAMFS
389 +       bool "Ramfs (initramfs/rootfs) as an aufs branch"
390 +       help
391 +       If you want to use ramfs as an aufs branch fs, then enable this
392 +       option. Generally tmpfs is recommended.
393 +       Aufs prohibited them to be a branch fs by default, because
394 +       initramfs becomes unusable after switch_root or something
395 +       generally. If you sets initramfs as an aufs branch and boot your
396 +       system by switch_root, you will meet a problem easily since the
397 +       files in initramfs may be inaccessible.
398 +       Unless you are going to use ramfs as an aufs branch fs without
399 +       switch_root or something, leave it N.
400 +
401 +config AUFS_BR_FUSE
402 +       bool "Fuse fs as an aufs branch"
403 +       depends on FUSE_FS
404 +       select AUFS_POLL
405 +       help
406 +       If you want to use fuse-based userspace filesystem as an aufs
407 +       branch fs, then enable this option.
408 +       It implements the internal poll(2) operation which is
409 +       implemented by fuse only (curretnly).
410 +
411 +config AUFS_POLL
412 +       bool
413 +       help
414 +       Automatic configuration for internal use.
415 +
416 +config AUFS_BR_HFSPLUS
417 +       bool "Hfsplus as an aufs branch"
418 +       depends on HFSPLUS_FS
419 +       default y
420 +       help
421 +       If you want to use hfsplus fs as an aufs branch fs, then enable
422 +       this option. This option introduces a small overhead at
423 +       copying-up a file on hfsplus.
424 +
425 +config AUFS_BDEV_LOOP
426 +       bool
427 +       depends on BLK_DEV_LOOP
428 +       default y
429 +       help
430 +       Automatic configuration for internal use.
431 +       Convert =[ym] into =y.
432 +
433 +config AUFS_DEBUG
434 +       bool "Debug aufs"
435 +       help
436 +       Enable this to compile aufs internal debug code.
437 +       It will have a negative impact to the performance.
438 +
439 +config AUFS_MAGIC_SYSRQ
440 +       bool
441 +       depends on AUFS_DEBUG && MAGIC_SYSRQ
442 +       default y
443 +       help
444 +       Automatic configuration for internal use.
445 +       When aufs supports Magic SysRq, enabled automatically.
446 +endif
447 diff --git a/fs/aufs/Makefile b/fs/aufs/Makefile
448 new file mode 100644
449 index 0000000..0817a55
450 --- /dev/null
451 +++ b/fs/aufs/Makefile
452 @@ -0,0 +1,37 @@
453 +
454 +include ${src}/magic.mk
455 +ifeq (${CONFIG_AUFS_FS},m)
456 +include ${src}/conf.mk
457 +endif
458 +-include ${src}/priv_def.mk
459 +
460 +# cf. include/linux/kernel.h
461 +# enable pr_debug
462 +ccflags-y += -DDEBUG
463 +ccflags-y += -D'pr_fmt(fmt)="aufs %s:%d:%s[%d]: " fmt, \
464 +       __func__, __LINE__, current->comm, current->pid'
465 +
466 +obj-$(CONFIG_AUFS_FS) += aufs.o
467 +aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
468 +       wkq.o vfsub.o dcsub.o \
469 +       cpup.o whout.o plink.o wbr_policy.o \
470 +       dinfo.o dentry.o \
471 +       dynop.o \
472 +       finfo.o file.o f_op.o \
473 +       dir.o vdir.o \
474 +       iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
475 +       ioctl.o
476 +
477 +# all are boolean
478 +aufs-$(CONFIG_SYSFS) += sysfs.o
479 +aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
480 +aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
481 +aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
482 +aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
483 +aufs-$(CONFIG_AUFS_EXPORT) += export.o
484 +aufs-$(CONFIG_AUFS_POLL) += poll.o
485 +aufs-$(CONFIG_AUFS_RDU) += rdu.o
486 +aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
487 +aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
488 +aufs-$(CONFIG_AUFS_DEBUG) += debug.o
489 +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
490 diff --git a/fs/aufs/aufs.h b/fs/aufs/aufs.h
491 new file mode 100644
492 index 0000000..1363f58
493 --- /dev/null
494 +++ b/fs/aufs/aufs.h
495 @@ -0,0 +1,61 @@
496 +/*
497 + * Copyright (C) 2005-2010 Junjiro R. Okajima
498 + *
499 + * This program, aufs is free software; you can redistribute it and/or modify
500 + * it under the terms of the GNU General Public License as published by
501 + * the Free Software Foundation; either version 2 of the License, or
502 + * (at your option) any later version.
503 + *
504 + * This program is distributed in the hope that it will be useful,
505 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
506 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
507 + * GNU General Public License for more details.
508 + *
509 + * You should have received a copy of the GNU General Public License
510 + * along with this program; if not, write to the Free Software
511 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
512 + */
513 +
514 +/*
515 + * all header files
516 + */
517 +
518 +#ifndef __AUFS_H__
519 +#define __AUFS_H__
520 +
521 +#ifdef __KERNEL__
522 +
523 +#define AuStub(type, name, body, ...) \
524 +       static inline type name(__VA_ARGS__) { body; }
525 +
526 +#define AuStubVoid(name, ...) \
527 +       AuStub(void, name, , __VA_ARGS__)
528 +#define AuStubInt0(name, ...) \
529 +       AuStub(int, name, return 0, __VA_ARGS__)
530 +
531 +#include "debug.h"
532 +
533 +#include "branch.h"
534 +#include "cpup.h"
535 +#include "dcsub.h"
536 +#include "dbgaufs.h"
537 +#include "dentry.h"
538 +#include "dir.h"
539 +#include "dynop.h"
540 +#include "file.h"
541 +#include "fstype.h"
542 +#include "inode.h"
543 +#include "loop.h"
544 +#include "module.h"
545 +/* never include ./mtx.h */
546 +#include "opts.h"
547 +#include "rwsem.h"
548 +#include "spl.h"
549 +#include "super.h"
550 +#include "sysaufs.h"
551 +#include "vfsub.h"
552 +#include "whout.h"
553 +#include "wkq.h"
554 +
555 +#endif /* __KERNEL__ */
556 +#endif /* __AUFS_H__ */
557 diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c
558 new file mode 100644
559 index 0000000..43c0115
560 --- /dev/null
561 +++ b/fs/aufs/branch.c
562 @@ -0,0 +1,1005 @@
563 +/*
564 + * Copyright (C) 2005-2010 Junjiro R. Okajima
565 + *
566 + * This program, aufs is free software; you can redistribute it and/or modify
567 + * it under the terms of the GNU General Public License as published by
568 + * the Free Software Foundation; either version 2 of the License, or
569 + * (at your option) any later version.
570 + *
571 + * This program is distributed in the hope that it will be useful,
572 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
573 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
574 + * GNU General Public License for more details.
575 + *
576 + * You should have received a copy of the GNU General Public License
577 + * along with this program; if not, write to the Free Software
578 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
579 + */
580 +
581 +/*
582 + * branch management
583 + */
584 +
585 +#include <linux/file.h>
586 +#include <linux/statfs.h>
587 +#include "aufs.h"
588 +
589 +/*
590 + * free a single branch
591 + */
592 +static void au_br_do_free(struct au_branch *br)
593 +{
594 +       int i;
595 +       struct au_wbr *wbr;
596 +       struct au_dykey **key;
597 +
598 +       if (br->br_xino.xi_file)
599 +               fput(br->br_xino.xi_file);
600 +       mutex_destroy(&br->br_xino.xi_nondir_mtx);
601 +
602 +       AuDebugOn(atomic_read(&br->br_count));
603 +
604 +       wbr = br->br_wbr;
605 +       if (wbr) {
606 +               for (i = 0; i < AuBrWh_Last; i++)
607 +                       dput(wbr->wbr_wh[i]);
608 +               AuDebugOn(atomic_read(&wbr->wbr_wh_running));
609 +               AuRwDestroy(&wbr->wbr_wh_rwsem);
610 +       }
611 +
612 +       key = br->br_dykey;
613 +       for (i = 0; i < AuBrDynOp; i++, key++)
614 +               if (*key)
615 +                       au_dy_put(*key);
616 +               else
617 +                       break;
618 +
619 +       mntput(br->br_mnt);
620 +       kfree(wbr);
621 +       kfree(br);
622 +}
623 +
624 +/*
625 + * frees all branches
626 + */
627 +void au_br_free(struct au_sbinfo *sbinfo)
628 +{
629 +       aufs_bindex_t bmax;
630 +       struct au_branch **br;
631 +
632 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
633 +
634 +       bmax = sbinfo->si_bend + 1;
635 +       br = sbinfo->si_branch;
636 +       while (bmax--)
637 +               au_br_do_free(*br++);
638 +}
639 +
640 +/*
641 + * find the index of a branch which is specified by @br_id.
642 + */
643 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
644 +{
645 +       aufs_bindex_t bindex, bend;
646 +
647 +       bend = au_sbend(sb);
648 +       for (bindex = 0; bindex <= bend; bindex++)
649 +               if (au_sbr_id(sb, bindex) == br_id)
650 +                       return bindex;
651 +       return -1;
652 +}
653 +
654 +/* ---------------------------------------------------------------------- */
655 +
656 +/*
657 + * add a branch
658 + */
659 +
660 +static int test_overlap(struct super_block *sb, struct dentry *h_adding,
661 +                       struct dentry *h_root)
662 +{
663 +       if (unlikely(h_adding == h_root
664 +                    || au_test_loopback_overlap(sb, h_adding)))
665 +               return 1;
666 +       if (h_adding->d_sb != h_root->d_sb)
667 +               return 0;
668 +       return au_test_subdir(h_adding, h_root)
669 +               || au_test_subdir(h_root, h_adding);
670 +}
671 +
672 +/*
673 + * returns a newly allocated branch. @new_nbranch is a number of branches
674 + * after adding a branch.
675 + */
676 +static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
677 +                                    int perm)
678 +{
679 +       struct au_branch *add_branch;
680 +       struct dentry *root;
681 +       int err;
682 +
683 +       err = -ENOMEM;
684 +       root = sb->s_root;
685 +       add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
686 +       if (unlikely(!add_branch))
687 +               goto out;
688 +
689 +       add_branch->br_wbr = NULL;
690 +       if (au_br_writable(perm)) {
691 +               /* may be freed separately at changing the branch permission */
692 +               add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
693 +                                            GFP_NOFS);
694 +               if (unlikely(!add_branch->br_wbr))
695 +                       goto out_br;
696 +       }
697 +
698 +       err = au_sbr_realloc(au_sbi(sb), new_nbranch);
699 +       if (!err)
700 +               err = au_di_realloc(au_di(root), new_nbranch);
701 +       if (!err)
702 +               err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
703 +       if (!err)
704 +               return add_branch; /* success */
705 +
706 +       kfree(add_branch->br_wbr);
707 +
708 +out_br:
709 +       kfree(add_branch);
710 +out:
711 +       return ERR_PTR(err);
712 +}
713 +
714 +/*
715 + * test if the branch permission is legal or not.
716 + */
717 +static int test_br(struct inode *inode, int brperm, char *path)
718 +{
719 +       int err;
720 +
721 +       err = (au_br_writable(brperm) && IS_RDONLY(inode));
722 +       if (!err)
723 +               goto out;
724 +
725 +       err = -EINVAL;
726 +       pr_err("write permission for readonly mount or inode, %s\n", path);
727 +
728 +out:
729 +       return err;
730 +}
731 +
732 +/*
733 + * returns:
734 + * 0: success, the caller will add it
735 + * plus: success, it is already unified, the caller should ignore it
736 + * minus: error
737 + */
738 +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
739 +{
740 +       int err;
741 +       aufs_bindex_t bend, bindex;
742 +       struct dentry *root;
743 +       struct inode *inode, *h_inode;
744 +
745 +       root = sb->s_root;
746 +       bend = au_sbend(sb);
747 +       if (unlikely(bend >= 0
748 +                    && au_find_dbindex(root, add->path.dentry) >= 0)) {
749 +               err = 1;
750 +               if (!remount) {
751 +                       err = -EINVAL;
752 +                       pr_err("%s duplicated\n", add->pathname);
753 +               }
754 +               goto out;
755 +       }
756 +
757 +       err = -ENOSPC; /* -E2BIG; */
758 +       if (unlikely(AUFS_BRANCH_MAX <= add->bindex
759 +                    || AUFS_BRANCH_MAX - 1 <= bend)) {
760 +               pr_err("number of branches exceeded %s\n", add->pathname);
761 +               goto out;
762 +       }
763 +
764 +       err = -EDOM;
765 +       if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
766 +               pr_err("bad index %d\n", add->bindex);
767 +               goto out;
768 +       }
769 +
770 +       inode = add->path.dentry->d_inode;
771 +       err = -ENOENT;
772 +       if (unlikely(!inode->i_nlink)) {
773 +               pr_err("no existence %s\n", add->pathname);
774 +               goto out;
775 +       }
776 +
777 +       err = -EINVAL;
778 +       if (unlikely(inode->i_sb == sb)) {
779 +               pr_err("%s must be outside\n", add->pathname);
780 +               goto out;
781 +       }
782 +
783 +       if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
784 +               pr_err("unsupported filesystem, %s (%s)\n",
785 +                      add->pathname, au_sbtype(inode->i_sb));
786 +               goto out;
787 +       }
788 +
789 +       err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
790 +       if (unlikely(err))
791 +               goto out;
792 +
793 +       if (bend < 0)
794 +               return 0; /* success */
795 +
796 +       err = -EINVAL;
797 +       for (bindex = 0; bindex <= bend; bindex++)
798 +               if (unlikely(test_overlap(sb, add->path.dentry,
799 +                                         au_h_dptr(root, bindex)))) {
800 +                       pr_err("%s is overlapped\n", add->pathname);
801 +                       goto out;
802 +               }
803 +
804 +       err = 0;
805 +       if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
806 +               h_inode = au_h_dptr(root, 0)->d_inode;
807 +               if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
808 +                   || h_inode->i_uid != inode->i_uid
809 +                   || h_inode->i_gid != inode->i_gid)
810 +                       pr_warning("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
811 +                                  add->pathname,
812 +                                  inode->i_uid, inode->i_gid,
813 +                                  (inode->i_mode & S_IALLUGO),
814 +                                  h_inode->i_uid, h_inode->i_gid,
815 +                                  (h_inode->i_mode & S_IALLUGO));
816 +       }
817 +
818 +out:
819 +       return err;
820 +}
821 +
822 +/*
823 + * initialize or clean the whiteouts for an adding branch
824 + */
825 +static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
826 +                        int new_perm, struct dentry *h_root)
827 +{
828 +       int err, old_perm;
829 +       aufs_bindex_t bindex;
830 +       struct mutex *h_mtx;
831 +       struct au_wbr *wbr;
832 +       struct au_hinode *hdir;
833 +
834 +       wbr = br->br_wbr;
835 +       old_perm = br->br_perm;
836 +       br->br_perm = new_perm;
837 +       hdir = NULL;
838 +       h_mtx = NULL;
839 +       bindex = au_br_index(sb, br->br_id);
840 +       if (0 <= bindex) {
841 +               hdir = au_hi(sb->s_root->d_inode, bindex);
842 +               au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
843 +       } else {
844 +               h_mtx = &h_root->d_inode->i_mutex;
845 +               mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
846 +       }
847 +       if (!wbr)
848 +               err = au_wh_init(h_root, br, sb);
849 +       else {
850 +               wbr_wh_write_lock(wbr);
851 +               err = au_wh_init(h_root, br, sb);
852 +               wbr_wh_write_unlock(wbr);
853 +       }
854 +       if (hdir)
855 +               au_hn_imtx_unlock(hdir);
856 +       else
857 +               mutex_unlock(h_mtx);
858 +       br->br_perm = old_perm;
859 +
860 +       if (!err && wbr && !au_br_writable(new_perm)) {
861 +               kfree(wbr);
862 +               br->br_wbr = NULL;
863 +       }
864 +
865 +       return err;
866 +}
867 +
868 +static int au_wbr_init(struct au_branch *br, struct super_block *sb,
869 +                      int perm, struct path *path)
870 +{
871 +       int err;
872 +       struct kstatfs kst;
873 +       struct au_wbr *wbr;
874 +       struct dentry *h_dentry;
875 +
876 +       wbr = br->br_wbr;
877 +       au_rw_init(&wbr->wbr_wh_rwsem);
878 +       memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
879 +       atomic_set(&wbr->wbr_wh_running, 0);
880 +       wbr->wbr_bytes = 0;
881 +
882 +       /*
883 +        * a limit for rmdir/rename a dir
884 +        * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h
885 +        */
886 +       err = vfs_statfs(path, &kst);
887 +       if (unlikely(err))
888 +               goto out;
889 +       err = -EINVAL;
890 +       h_dentry = path->dentry;
891 +       if (kst.f_namelen >= NAME_MAX)
892 +               err = au_br_init_wh(sb, br, perm, h_dentry);
893 +       else
894 +               pr_err("%.*s(%s), unsupported namelen %ld\n",
895 +                      AuDLNPair(h_dentry), au_sbtype(h_dentry->d_sb),
896 +                      kst.f_namelen);
897 +
898 +out:
899 +       return err;
900 +}
901 +
902 +/* intialize a new branch */
903 +static int au_br_init(struct au_branch *br, struct super_block *sb,
904 +                     struct au_opt_add *add)
905 +{
906 +       int err;
907 +
908 +       err = 0;
909 +       memset(&br->br_xino, 0, sizeof(br->br_xino));
910 +       mutex_init(&br->br_xino.xi_nondir_mtx);
911 +       br->br_perm = add->perm;
912 +       br->br_mnt = add->path.mnt; /* set first, mntget() later */
913 +       spin_lock_init(&br->br_dykey_lock);
914 +       memset(br->br_dykey, 0, sizeof(br->br_dykey));
915 +       atomic_set(&br->br_count, 0);
916 +       br->br_xino_upper = AUFS_XINO_TRUNC_INIT;
917 +       atomic_set(&br->br_xino_running, 0);
918 +       br->br_id = au_new_br_id(sb);
919 +
920 +       if (au_br_writable(add->perm)) {
921 +               err = au_wbr_init(br, sb, add->perm, &add->path);
922 +               if (unlikely(err))
923 +                       goto out_err;
924 +       }
925 +
926 +       if (au_opt_test(au_mntflags(sb), XINO)) {
927 +               err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
928 +                                au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
929 +               if (unlikely(err)) {
930 +                       AuDebugOn(br->br_xino.xi_file);
931 +                       goto out_err;
932 +               }
933 +       }
934 +
935 +       sysaufs_br_init(br);
936 +       mntget(add->path.mnt);
937 +       goto out; /* success */
938 +
939 +out_err:
940 +       br->br_mnt = NULL;
941 +out:
942 +       return err;
943 +}
944 +
945 +static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
946 +                            struct au_branch *br, aufs_bindex_t bend,
947 +                            aufs_bindex_t amount)
948 +{
949 +       struct au_branch **brp;
950 +
951 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
952 +
953 +       brp = sbinfo->si_branch + bindex;
954 +       memmove(brp + 1, brp, sizeof(*brp) * amount);
955 +       *brp = br;
956 +       sbinfo->si_bend++;
957 +       if (unlikely(bend < 0))
958 +               sbinfo->si_bend = 0;
959 +}
960 +
961 +static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
962 +                            aufs_bindex_t bend, aufs_bindex_t amount)
963 +{
964 +       struct au_hdentry *hdp;
965 +
966 +       AuRwMustWriteLock(&dinfo->di_rwsem);
967 +
968 +       hdp = dinfo->di_hdentry + bindex;
969 +       memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
970 +       au_h_dentry_init(hdp);
971 +       dinfo->di_bend++;
972 +       if (unlikely(bend < 0))
973 +               dinfo->di_bstart = 0;
974 +}
975 +
976 +static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
977 +                            aufs_bindex_t bend, aufs_bindex_t amount)
978 +{
979 +       struct au_hinode *hip;
980 +
981 +       AuRwMustWriteLock(&iinfo->ii_rwsem);
982 +
983 +       hip = iinfo->ii_hinode + bindex;
984 +       memmove(hip + 1, hip, sizeof(*hip) * amount);
985 +       hip->hi_inode = NULL;
986 +       au_hn_init(hip);
987 +       iinfo->ii_bend++;
988 +       if (unlikely(bend < 0))
989 +               iinfo->ii_bstart = 0;
990 +}
991 +
992 +static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry,
993 +                        struct au_branch *br, aufs_bindex_t bindex)
994 +{
995 +       struct dentry *root;
996 +       struct inode *root_inode;
997 +       aufs_bindex_t bend, amount;
998 +
999 +       root = sb->s_root;
1000 +       root_inode = root->d_inode;
1001 +       au_plink_maint_block(sb);
1002 +       bend = au_sbend(sb);
1003 +       amount = bend + 1 - bindex;
1004 +       au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
1005 +       au_br_do_add_hdp(au_di(root), bindex, bend, amount);
1006 +       au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
1007 +       au_set_h_dptr(root, bindex, dget(h_dentry));
1008 +       au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
1009 +                     /*flags*/0);
1010 +}
1011 +
1012 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
1013 +{
1014 +       int err;
1015 +       aufs_bindex_t bend, add_bindex;
1016 +       struct dentry *root, *h_dentry;
1017 +       struct inode *root_inode;
1018 +       struct au_branch *add_branch;
1019 +
1020 +       root = sb->s_root;
1021 +       root_inode = root->d_inode;
1022 +       IMustLock(root_inode);
1023 +       err = test_add(sb, add, remount);
1024 +       if (unlikely(err < 0))
1025 +               goto out;
1026 +       if (err) {
1027 +               err = 0;
1028 +               goto out; /* success */
1029 +       }
1030 +
1031 +       bend = au_sbend(sb);
1032 +       add_branch = au_br_alloc(sb, bend + 2, add->perm);
1033 +       err = PTR_ERR(add_branch);
1034 +       if (IS_ERR(add_branch))
1035 +               goto out;
1036 +
1037 +       err = au_br_init(add_branch, sb, add);
1038 +       if (unlikely(err)) {
1039 +               au_br_do_free(add_branch);
1040 +               goto out;
1041 +       }
1042 +
1043 +       add_bindex = add->bindex;
1044 +       h_dentry = add->path.dentry;
1045 +       if (!remount)
1046 +               au_br_do_add(sb, h_dentry, add_branch, add_bindex);
1047 +       else {
1048 +               sysaufs_brs_del(sb, add_bindex);
1049 +               au_br_do_add(sb, h_dentry, add_branch, add_bindex);
1050 +               sysaufs_brs_add(sb, add_bindex);
1051 +       }
1052 +
1053 +       if (!add_bindex) {
1054 +               au_cpup_attr_all(root_inode, /*force*/1);
1055 +               sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
1056 +       } else
1057 +               au_add_nlink(root_inode, h_dentry->d_inode);
1058 +
1059 +       /*
1060 +        * this test/set prevents aufs from handling unnecesary notify events
1061 +        * of xino files, in a case of re-adding a writable branch which was
1062 +        * once detached from aufs.
1063 +        */
1064 +       if (au_xino_brid(sb) < 0
1065 +           && au_br_writable(add_branch->br_perm)
1066 +           && !au_test_fs_bad_xino(h_dentry->d_sb)
1067 +           && add_branch->br_xino.xi_file
1068 +           && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
1069 +               au_xino_brid_set(sb, add_branch->br_id);
1070 +
1071 +out:
1072 +       return err;
1073 +}
1074 +
1075 +/* ---------------------------------------------------------------------- */
1076 +
1077 +/*
1078 + * delete a branch
1079 + */
1080 +
1081 +/* to show the line number, do not make it inlined function */
1082 +#define AuVerbose(do_info, fmt, ...) do { \
1083 +       if (do_info) \
1084 +               pr_info(fmt, ##__VA_ARGS__); \
1085 +} while (0)
1086 +
1087 +/*
1088 + * test if the branch is deletable or not.
1089 + */
1090 +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
1091 +                           unsigned int sigen, const unsigned int verbose)
1092 +{
1093 +       int err, i, j, ndentry;
1094 +       aufs_bindex_t bstart, bend;
1095 +       struct au_dcsub_pages dpages;
1096 +       struct au_dpage *dpage;
1097 +       struct dentry *d;
1098 +       struct inode *inode;
1099 +
1100 +       err = au_dpages_init(&dpages, GFP_NOFS);
1101 +       if (unlikely(err))
1102 +               goto out;
1103 +       err = au_dcsub_pages(&dpages, root, NULL, NULL);
1104 +       if (unlikely(err))
1105 +               goto out_dpages;
1106 +
1107 +       for (i = 0; !err && i < dpages.ndpage; i++) {
1108 +               dpage = dpages.dpages + i;
1109 +               ndentry = dpage->ndentry;
1110 +               for (j = 0; !err && j < ndentry; j++) {
1111 +                       d = dpage->dentries[j];
1112 +                       AuDebugOn(!atomic_read(&d->d_count));
1113 +                       inode = d->d_inode;
1114 +                       if (au_digen(d) == sigen && au_iigen(inode) == sigen)
1115 +                               di_read_lock_child(d, AuLock_IR);
1116 +                       else {
1117 +                               di_write_lock_child(d);
1118 +                               err = au_reval_dpath(d, sigen);
1119 +                               if (!err)
1120 +                                       di_downgrade_lock(d, AuLock_IR);
1121 +                               else {
1122 +                                       di_write_unlock(d);
1123 +                                       break;
1124 +                               }
1125 +                       }
1126 +
1127 +                       bstart = au_dbstart(d);
1128 +                       bend = au_dbend(d);
1129 +                       if (bstart <= bindex
1130 +                           && bindex <= bend
1131 +                           && au_h_dptr(d, bindex)
1132 +                           && (!S_ISDIR(inode->i_mode) || bstart == bend)) {
1133 +                               err = -EBUSY;
1134 +                               AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
1135 +                       }
1136 +                       di_read_unlock(d, AuLock_IR);
1137 +               }
1138 +       }
1139 +
1140 +out_dpages:
1141 +       au_dpages_free(&dpages);
1142 +out:
1143 +       return err;
1144 +}
1145 +
1146 +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
1147 +                          unsigned int sigen, const unsigned int verbose)
1148 +{
1149 +       int err;
1150 +       struct inode *i;
1151 +       aufs_bindex_t bstart, bend;
1152 +
1153 +       err = 0;
1154 +       list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
1155 +               AuDebugOn(!atomic_read(&i->i_count));
1156 +               if (!list_empty(&i->i_dentry))
1157 +                       continue;
1158 +
1159 +               if (au_iigen(i) == sigen)
1160 +                       ii_read_lock_child(i);
1161 +               else {
1162 +                       ii_write_lock_child(i);
1163 +                       err = au_refresh_hinode_self(i, /*do_attr*/1);
1164 +                       if (!err)
1165 +                               ii_downgrade_lock(i);
1166 +                       else {
1167 +                               ii_write_unlock(i);
1168 +                               break;
1169 +                       }
1170 +               }
1171 +
1172 +               bstart = au_ibstart(i);
1173 +               bend = au_ibend(i);
1174 +               if (bstart <= bindex
1175 +                   && bindex <= bend
1176 +                   && au_h_iptr(i, bindex)
1177 +                   && (!S_ISDIR(i->i_mode) || bstart == bend)) {
1178 +                       err = -EBUSY;
1179 +                       AuVerbose(verbose, "busy i%lu\n", i->i_ino);
1180 +                       ii_read_unlock(i);
1181 +                       break;
1182 +               }
1183 +               ii_read_unlock(i);
1184 +       }
1185 +
1186 +       return err;
1187 +}
1188 +
1189 +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
1190 +                             const unsigned int verbose)
1191 +{
1192 +       int err;
1193 +       unsigned int sigen;
1194 +
1195 +       sigen = au_sigen(root->d_sb);
1196 +       DiMustNoWaiters(root);
1197 +       IiMustNoWaiters(root->d_inode);
1198 +       di_write_unlock(root);
1199 +       err = test_dentry_busy(root, bindex, sigen, verbose);
1200 +       if (!err)
1201 +               err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1202 +       di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
1203 +
1204 +       return err;
1205 +}
1206 +
1207 +static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
1208 +                            const aufs_bindex_t bindex,
1209 +                            const aufs_bindex_t bend)
1210 +{
1211 +       struct au_branch **brp, **p;
1212 +
1213 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
1214 +
1215 +       brp = sbinfo->si_branch + bindex;
1216 +       if (bindex < bend)
1217 +               memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
1218 +       sbinfo->si_branch[0 + bend] = NULL;
1219 +       sbinfo->si_bend--;
1220 +
1221 +       p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, GFP_NOFS);
1222 +       if (p)
1223 +               sbinfo->si_branch = p;
1224 +       /* harmless error */
1225 +}
1226 +
1227 +static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
1228 +                            const aufs_bindex_t bend)
1229 +{
1230 +       struct au_hdentry *hdp, *p;
1231 +
1232 +       AuRwMustWriteLock(&dinfo->di_rwsem);
1233 +
1234 +       hdp = dinfo->di_hdentry;
1235 +       if (bindex < bend)
1236 +               memmove(hdp + bindex, hdp + bindex + 1,
1237 +                       sizeof(*hdp) * (bend - bindex));
1238 +       hdp[0 + bend].hd_dentry = NULL;
1239 +       dinfo->di_bend--;
1240 +
1241 +       p = krealloc(hdp, sizeof(*p) * bend, GFP_NOFS);
1242 +       if (p)
1243 +               dinfo->di_hdentry = p;
1244 +       /* harmless error */
1245 +}
1246 +
1247 +static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
1248 +                            const aufs_bindex_t bend)
1249 +{
1250 +       struct au_hinode *hip, *p;
1251 +
1252 +       AuRwMustWriteLock(&iinfo->ii_rwsem);
1253 +
1254 +       hip = iinfo->ii_hinode + bindex;
1255 +       if (bindex < bend)
1256 +               memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
1257 +       iinfo->ii_hinode[0 + bend].hi_inode = NULL;
1258 +       au_hn_init(iinfo->ii_hinode + bend);
1259 +       iinfo->ii_bend--;
1260 +
1261 +       p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, GFP_NOFS);
1262 +       if (p)
1263 +               iinfo->ii_hinode = p;
1264 +       /* harmless error */
1265 +}
1266 +
1267 +static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
1268 +                        struct au_branch *br)
1269 +{
1270 +       aufs_bindex_t bend;
1271 +       struct au_sbinfo *sbinfo;
1272 +       struct dentry *root;
1273 +       struct inode *inode;
1274 +
1275 +       SiMustWriteLock(sb);
1276 +
1277 +       root = sb->s_root;
1278 +       inode = root->d_inode;
1279 +       au_plink_maint_block(sb);
1280 +       sbinfo = au_sbi(sb);
1281 +       bend = sbinfo->si_bend;
1282 +
1283 +       dput(au_h_dptr(root, bindex));
1284 +       au_hiput(au_hi(inode, bindex));
1285 +       au_br_do_free(br);
1286 +
1287 +       au_br_do_del_brp(sbinfo, bindex, bend);
1288 +       au_br_do_del_hdp(au_di(root), bindex, bend);
1289 +       au_br_do_del_hip(au_ii(inode), bindex, bend);
1290 +}
1291 +
1292 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
1293 +{
1294 +       int err, rerr, i;
1295 +       unsigned int mnt_flags;
1296 +       aufs_bindex_t bindex, bend, br_id;
1297 +       unsigned char do_wh, verbose;
1298 +       struct au_branch *br;
1299 +       struct au_wbr *wbr;
1300 +
1301 +       err = 0;
1302 +       bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
1303 +       if (bindex < 0) {
1304 +               if (remount)
1305 +                       goto out; /* success */
1306 +               err = -ENOENT;
1307 +               pr_err("%s no such branch\n", del->pathname);
1308 +               goto out;
1309 +       }
1310 +       AuDbg("bindex b%d\n", bindex);
1311 +
1312 +       err = -EBUSY;
1313 +       mnt_flags = au_mntflags(sb);
1314 +       verbose = !!au_opt_test(mnt_flags, VERBOSE);
1315 +       bend = au_sbend(sb);
1316 +       if (unlikely(!bend)) {
1317 +               AuVerbose(verbose, "no more branches left\n");
1318 +               goto out;
1319 +       }
1320 +       br = au_sbr(sb, bindex);
1321 +       i = atomic_read(&br->br_count);
1322 +       if (unlikely(i)) {
1323 +               AuVerbose(verbose, "%d file(s) opened\n", i);
1324 +               if (!verbose)
1325 +                       goto out;
1326 +       }
1327 +
1328 +       wbr = br->br_wbr;
1329 +       do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
1330 +       if (do_wh) {
1331 +               /* instead of WbrWhMustWriteLock(wbr) */
1332 +               SiMustWriteLock(sb);
1333 +               for (i = 0; i < AuBrWh_Last; i++) {
1334 +                       dput(wbr->wbr_wh[i]);
1335 +                       wbr->wbr_wh[i] = NULL;
1336 +               }
1337 +       }
1338 +
1339 +       err = test_children_busy(sb->s_root, bindex, verbose);
1340 +       if (unlikely(err)) {
1341 +               if (do_wh)
1342 +                       goto out_wh;
1343 +               goto out;
1344 +       }
1345 +
1346 +       err = 0;
1347 +       br_id = br->br_id;
1348 +       if (!remount)
1349 +               au_br_do_del(sb, bindex, br);
1350 +       else {
1351 +               sysaufs_brs_del(sb, bindex);
1352 +               au_br_do_del(sb, bindex, br);
1353 +               sysaufs_brs_add(sb, bindex);
1354 +       }
1355 +
1356 +       if (!bindex) {
1357 +               au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
1358 +               sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
1359 +       } else
1360 +               au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
1361 +       if (au_opt_test(mnt_flags, PLINK))
1362 +               au_plink_half_refresh(sb, br_id);
1363 +
1364 +       if (au_xino_brid(sb) == br_id)
1365 +               au_xino_brid_set(sb, -1);
1366 +       goto out; /* success */
1367 +
1368 +out_wh:
1369 +       /* revert */
1370 +       rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry);
1371 +       if (rerr)
1372 +               pr_warning("failed re-creating base whiteout, %s. (%d)\n",
1373 +                          del->pathname, rerr);
1374 +out:
1375 +       return err;
1376 +}
1377 +
1378 +/* ---------------------------------------------------------------------- */
1379 +
1380 +/*
1381 + * change a branch permission
1382 + */
1383 +
1384 +static void au_warn_ima(void)
1385 +{
1386 +#ifdef CONFIG_IMA
1387 +       /* since it doesn't support mark_files_ro() */
1388 +       pr_warning("RW -> RO makes IMA to produce wrong message");
1389 +#endif
1390 +}
1391 +
1392 +static int do_need_sigen_inc(int a, int b)
1393 +{
1394 +       return au_br_whable(a) && !au_br_whable(b);
1395 +}
1396 +
1397 +static int need_sigen_inc(int old, int new)
1398 +{
1399 +       return do_need_sigen_inc(old, new)
1400 +               || do_need_sigen_inc(new, old);
1401 +}
1402 +
1403 +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
1404 +{
1405 +       int err;
1406 +       unsigned long n, ul, bytes, files;
1407 +       aufs_bindex_t bstart;
1408 +       struct file *file, *hf, **a;
1409 +       const int step_bytes = 1024, /* memory allocation unit */
1410 +               step_files = step_bytes / sizeof(*a);
1411 +
1412 +       err = -ENOMEM;
1413 +       n = 0;
1414 +       bytes = step_bytes;
1415 +       files = step_files;
1416 +       a = kmalloc(bytes, GFP_NOFS);
1417 +       if (unlikely(!a))
1418 +               goto out;
1419 +
1420 +       /* no need file_list_lock() since sbinfo is locked? defered? */
1421 +       do_file_list_for_each_entry(sb, file) {
1422 +               if (special_file(file->f_dentry->d_inode->i_mode))
1423 +                       continue;
1424 +
1425 +               AuDbg("%.*s\n", AuDLNPair(file->f_dentry));
1426 +               fi_read_lock(file);
1427 +               if (unlikely(au_test_mmapped(file))) {
1428 +                       err = -EBUSY;
1429 +                       FiMustNoWaiters(file);
1430 +                       fi_read_unlock(file);
1431 +                       goto out_free;
1432 +               }
1433 +
1434 +               bstart = au_fbstart(file);
1435 +               if (!S_ISREG(file->f_dentry->d_inode->i_mode)
1436 +                   || !(file->f_mode & FMODE_WRITE)
1437 +                   || bstart != bindex) {
1438 +                       FiMustNoWaiters(file);
1439 +                       fi_read_unlock(file);
1440 +                       continue;
1441 +               }
1442 +
1443 +               hf = au_hf_top(file);
1444 +               FiMustNoWaiters(file);
1445 +               fi_read_unlock(file);
1446 +
1447 +               if (n < files)
1448 +                       a[n++] = hf;
1449 +               else {
1450 +                       void *p;
1451 +
1452 +                       err = -ENOMEM;
1453 +                       bytes += step_bytes;
1454 +                       files += step_files;
1455 +                       p = krealloc(a, bytes, GFP_NOFS);
1456 +                       if (p) {
1457 +                               a = p;
1458 +                               a[n++] = hf;
1459 +                       } else
1460 +                               goto out_free;
1461 +               }
1462 +       } while_file_list_for_each_entry;
1463 +
1464 +       err = 0;
1465 +       if (n)
1466 +               au_warn_ima();
1467 +       for (ul = 0; ul < n; ul++) {
1468 +               /* todo: already flushed? */
1469 +               /* cf. fs/super.c:mark_files_ro() */
1470 +               hf = a[ul];
1471 +               hf->f_mode &= ~FMODE_WRITE;
1472 +               if (!file_check_writeable(hf)) {
1473 +                       file_release_write(hf);
1474 +                       mnt_drop_write(hf->f_vfsmnt);
1475 +               }
1476 +       }
1477 +
1478 +out_free:
1479 +       kfree(a);
1480 +out:
1481 +       return err;
1482 +}
1483 +
1484 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
1485 +             int *do_update)
1486 +{
1487 +       int err, rerr;
1488 +       aufs_bindex_t bindex;
1489 +       struct path path;
1490 +       struct dentry *root;
1491 +       struct au_branch *br;
1492 +
1493 +       root = sb->s_root;
1494 +       au_plink_maint_block(sb);
1495 +       bindex = au_find_dbindex(root, mod->h_root);
1496 +       if (bindex < 0) {
1497 +               if (remount)
1498 +                       return 0; /* success */
1499 +               err = -ENOENT;
1500 +               pr_err("%s no such branch\n", mod->path);
1501 +               goto out;
1502 +       }
1503 +       AuDbg("bindex b%d\n", bindex);
1504 +
1505 +       err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
1506 +       if (unlikely(err))
1507 +               goto out;
1508 +
1509 +       br = au_sbr(sb, bindex);
1510 +       if (br->br_perm == mod->perm)
1511 +               return 0; /* success */
1512 +
1513 +       if (au_br_writable(br->br_perm)) {
1514 +               /* remove whiteout base */
1515 +               err = au_br_init_wh(sb, br, mod->perm, mod->h_root);
1516 +               if (unlikely(err))
1517 +                       goto out;
1518 +
1519 +               if (!au_br_writable(mod->perm)) {
1520 +                       /* rw --> ro, file might be mmapped */
1521 +                       DiMustNoWaiters(root);
1522 +                       IiMustNoWaiters(root->d_inode);
1523 +                       di_write_unlock(root);
1524 +                       err = au_br_mod_files_ro(sb, bindex);
1525 +                       /* aufs_write_lock() calls ..._child() */
1526 +                       di_write_lock_child(root);
1527 +
1528 +                       if (unlikely(err)) {
1529 +                               rerr = -ENOMEM;
1530 +                               br->br_wbr = kmalloc(sizeof(*br->br_wbr),
1531 +                                                    GFP_NOFS);
1532 +                               if (br->br_wbr) {
1533 +                                       path.mnt = br->br_mnt;
1534 +                                       path.dentry = mod->h_root;
1535 +                                       rerr = au_wbr_init(br, sb, br->br_perm,
1536 +                                                          &path);
1537 +                               }
1538 +                               if (unlikely(rerr)) {
1539 +                                       AuIOErr("nested error %d (%d)\n",
1540 +                                               rerr, err);
1541 +                                       br->br_perm = mod->perm;
1542 +                               }
1543 +                       }
1544 +               }
1545 +       } else if (au_br_writable(mod->perm)) {
1546 +               /* ro --> rw */
1547 +               err = -ENOMEM;
1548 +               br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
1549 +               if (br->br_wbr) {
1550 +                       path.mnt = br->br_mnt;
1551 +                       path.dentry = mod->h_root;
1552 +                       err = au_wbr_init(br, sb, mod->perm, &path);
1553 +                       if (unlikely(err)) {
1554 +                               kfree(br->br_wbr);
1555 +                               br->br_wbr = NULL;
1556 +                       }
1557 +               }
1558 +       }
1559 +
1560 +       if (!err) {
1561 +               *do_update |= need_sigen_inc(br->br_perm, mod->perm);
1562 +               br->br_perm = mod->perm;
1563 +       }
1564 +
1565 +out:
1566 +       return err;
1567 +}
1568 diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h
1569 new file mode 100644
1570 index 0000000..9e77476
1571 --- /dev/null
1572 +++ b/fs/aufs/branch.h
1573 @@ -0,0 +1,224 @@
1574 +/*
1575 + * Copyright (C) 2005-2010 Junjiro R. Okajima
1576 + *
1577 + * This program, aufs is free software; you can redistribute it and/or modify
1578 + * it under the terms of the GNU General Public License as published by
1579 + * the Free Software Foundation; either version 2 of the License, or
1580 + * (at your option) any later version.
1581 + *
1582 + * This program is distributed in the hope that it will be useful,
1583 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1584 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1585 + * GNU General Public License for more details.
1586 + *
1587 + * You should have received a copy of the GNU General Public License
1588 + * along with this program; if not, write to the Free Software
1589 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1590 + */
1591 +
1592 +/*
1593 + * branch filesystems and xino for them
1594 + */
1595 +
1596 +#ifndef __AUFS_BRANCH_H__
1597 +#define __AUFS_BRANCH_H__
1598 +
1599 +#ifdef __KERNEL__
1600 +
1601 +#include <linux/fs.h>
1602 +#include <linux/mount.h>
1603 +#include <linux/aufs_type.h>
1604 +#include "dynop.h"
1605 +#include "rwsem.h"
1606 +#include "super.h"
1607 +
1608 +/* ---------------------------------------------------------------------- */
1609 +
1610 +/* a xino file */
1611 +struct au_xino_file {
1612 +       struct file             *xi_file;
1613 +       struct mutex            xi_nondir_mtx;
1614 +
1615 +       /* todo: make xino files an array to support huge inode number */
1616 +
1617 +#ifdef CONFIG_DEBUG_FS
1618 +       struct dentry            *xi_dbgaufs;
1619 +#endif
1620 +};
1621 +
1622 +/* members for writable branch only */
1623 +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
1624 +struct au_wbr {
1625 +       struct au_rwsem         wbr_wh_rwsem;
1626 +       struct dentry           *wbr_wh[AuBrWh_Last];
1627 +       atomic_t                wbr_wh_running;
1628 +#define wbr_whbase             wbr_wh[AuBrWh_BASE]     /* whiteout base */
1629 +#define wbr_plink              wbr_wh[AuBrWh_PLINK]    /* pseudo-link dir */
1630 +#define wbr_orph               wbr_wh[AuBrWh_ORPH]     /* dir for orphans */
1631 +
1632 +       /* mfs mode */
1633 +       unsigned long long      wbr_bytes;
1634 +};
1635 +
1636 +/* ext2 has 3 types of operations at least, ext3 has 4 */
1637 +#define AuBrDynOp (AuDyLast * 4)
1638 +
1639 +/* protected by superblock rwsem */
1640 +struct au_branch {
1641 +       struct au_xino_file     br_xino;
1642 +
1643 +       aufs_bindex_t           br_id;
1644 +
1645 +       int                     br_perm;
1646 +       struct vfsmount         *br_mnt;
1647 +       spinlock_t              br_dykey_lock;
1648 +       struct au_dykey         *br_dykey[AuBrDynOp];
1649 +       atomic_t                br_count;
1650 +
1651 +       struct au_wbr           *br_wbr;
1652 +
1653 +       /* xino truncation */
1654 +       blkcnt_t                br_xino_upper;  /* watermark in blocks */
1655 +       atomic_t                br_xino_running;
1656 +
1657 +#ifdef CONFIG_SYSFS
1658 +       /* an entry under sysfs per mount-point */
1659 +       char                    br_name[8];
1660 +       struct attribute        br_attr;
1661 +#endif
1662 +};
1663 +
1664 +/* ---------------------------------------------------------------------- */
1665 +
1666 +/* branch permission and attribute */
1667 +enum {
1668 +       AuBrPerm_RW,            /* writable, linkable wh */
1669 +       AuBrPerm_RO,            /* readonly, no wh */
1670 +       AuBrPerm_RR,            /* natively readonly, no wh */
1671 +
1672 +       AuBrPerm_RWNoLinkWH,    /* un-linkable whiteouts */
1673 +
1674 +       AuBrPerm_ROWH,          /* whiteout-able */
1675 +       AuBrPerm_RRWH,          /* whiteout-able */
1676 +
1677 +       AuBrPerm_Last
1678 +};
1679 +
1680 +static inline int au_br_writable(int brperm)
1681 +{
1682 +       return brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH;
1683 +}
1684 +
1685 +static inline int au_br_whable(int brperm)
1686 +{
1687 +       return brperm == AuBrPerm_RW
1688 +               || brperm == AuBrPerm_ROWH
1689 +               || brperm == AuBrPerm_RRWH;
1690 +}
1691 +
1692 +static inline int au_br_rdonly(struct au_branch *br)
1693 +{
1694 +       return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY)
1695 +               || !au_br_writable(br->br_perm))
1696 +               ? -EROFS : 0;
1697 +}
1698 +
1699 +static inline int au_br_hnotifyable(int brperm __maybe_unused)
1700 +{
1701 +#ifdef CONFIG_AUFS_HNOTIFY
1702 +       return brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH;
1703 +#else
1704 +       return 0;
1705 +#endif
1706 +}
1707 +
1708 +/* ---------------------------------------------------------------------- */
1709 +
1710 +/* branch.c */
1711 +struct au_sbinfo;
1712 +void au_br_free(struct au_sbinfo *sinfo);
1713 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
1714 +struct au_opt_add;
1715 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
1716 +struct au_opt_del;
1717 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
1718 +struct au_opt_mod;
1719 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
1720 +             int *do_update);
1721 +
1722 +/* xino.c */
1723 +static const loff_t au_loff_max = LLONG_MAX;
1724 +
1725 +int au_xib_trunc(struct super_block *sb);
1726 +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
1727 +                  loff_t *pos);
1728 +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
1729 +                   loff_t *pos);
1730 +struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
1731 +struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
1732 +ino_t au_xino_new_ino(struct super_block *sb);
1733 +void au_xino_delete_inode(struct inode *inode, const int unlinked);
1734 +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
1735 +                 ino_t ino);
1736 +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
1737 +                ino_t *ino);
1738 +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
1739 +              struct file *base_file, int do_test);
1740 +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
1741 +
1742 +struct au_opt_xino;
1743 +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
1744 +void au_xino_clr(struct super_block *sb);
1745 +struct file *au_xino_def(struct super_block *sb);
1746 +int au_xino_path(struct seq_file *seq, struct file *file);
1747 +
1748 +/* ---------------------------------------------------------------------- */
1749 +
1750 +/* Superblock to branch */
1751 +static inline
1752 +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
1753 +{
1754 +       return au_sbr(sb, bindex)->br_id;
1755 +}
1756 +
1757 +static inline
1758 +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
1759 +{
1760 +       return au_sbr(sb, bindex)->br_mnt;
1761 +}
1762 +
1763 +static inline
1764 +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
1765 +{
1766 +       return au_sbr_mnt(sb, bindex)->mnt_sb;
1767 +}
1768 +
1769 +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
1770 +{
1771 +       atomic_dec_return(&au_sbr(sb, bindex)->br_count);
1772 +}
1773 +
1774 +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
1775 +{
1776 +       return au_sbr(sb, bindex)->br_perm;
1777 +}
1778 +
1779 +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
1780 +{
1781 +       return au_br_whable(au_sbr_perm(sb, bindex));
1782 +}
1783 +
1784 +/* ---------------------------------------------------------------------- */
1785 +
1786 +/*
1787 + * wbr_wh_read_lock, wbr_wh_write_lock
1788 + * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
1789 + */
1790 +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
1791 +
1792 +#define WbrWhMustNoWaiters(wbr)        AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
1793 +#define WbrWhMustAnyLock(wbr)  AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
1794 +#define WbrWhMustWriteLock(wbr)        AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
1795 +
1796 +#endif /* __KERNEL__ */
1797 +#endif /* __AUFS_BRANCH_H__ */
1798 diff --git a/fs/aufs/conf.mk b/fs/aufs/conf.mk
1799 new file mode 100644
1800 index 0000000..041248d
1801 --- /dev/null
1802 +++ b/fs/aufs/conf.mk
1803 @@ -0,0 +1,36 @@
1804 +
1805 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
1806 +
1807 +define AuConf
1808 +ifdef ${1}
1809 +AuConfStr += ${1}=${${1}}
1810 +endif
1811 +endef
1812 +
1813 +AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
1814 +       HNOTIFY HFSNOTIFY \
1815 +       EXPORT INO_T_64 \
1816 +       RDU \
1817 +       SP_IATTR \
1818 +       SHWH \
1819 +       BR_RAMFS \
1820 +       BR_FUSE POLL \
1821 +       BR_HFSPLUS \
1822 +       BDEV_LOOP \
1823 +       DEBUG MAGIC_SYSRQ
1824 +$(foreach i, ${AuConfAll}, \
1825 +       $(eval $(call AuConf,CONFIG_AUFS_${i})))
1826 +
1827 +AuConfName = ${obj}/conf.str
1828 +${AuConfName}.tmp: FORCE
1829 +       @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
1830 +${AuConfName}: ${AuConfName}.tmp
1831 +       @diff -q $< $@ > /dev/null 2>&1 || { \
1832 +       echo '  GEN    ' $@; \
1833 +       cp -p $< $@; \
1834 +       }
1835 +FORCE:
1836 +clean-files += ${AuConfName} ${AuConfName}.tmp
1837 +${obj}/sysfs.o: ${AuConfName}
1838 +
1839 +-include ${srctree}/${src}/conf_priv.mk
1840 diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c
1841 new file mode 100644
1842 index 0000000..962fd50
1843 --- /dev/null
1844 +++ b/fs/aufs/cpup.c
1845 @@ -0,0 +1,1059 @@
1846 +/*
1847 + * Copyright (C) 2005-2010 Junjiro R. Okajima
1848 + *
1849 + * This program, aufs is free software; you can redistribute it and/or modify
1850 + * it under the terms of the GNU General Public License as published by
1851 + * the Free Software Foundation; either version 2 of the License, or
1852 + * (at your option) any later version.
1853 + *
1854 + * This program is distributed in the hope that it will be useful,
1855 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1856 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1857 + * GNU General Public License for more details.
1858 + *
1859 + * You should have received a copy of the GNU General Public License
1860 + * along with this program; if not, write to the Free Software
1861 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1862 + */
1863 +
1864 +/*
1865 + * copy-up functions, see wbr_policy.c for copy-down
1866 + */
1867 +
1868 +#include <linux/file.h>
1869 +#include <linux/fs_stack.h>
1870 +#include <linux/mm.h>
1871 +#include <linux/uaccess.h>
1872 +#include "aufs.h"
1873 +
1874 +void au_cpup_attr_flags(struct inode *dst, struct inode *src)
1875 +{
1876 +       const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
1877 +               | S_NOATIME | S_NOCMTIME;
1878 +
1879 +       dst->i_flags |= src->i_flags & ~mask;
1880 +       if (au_test_fs_notime(dst->i_sb))
1881 +               dst->i_flags |= S_NOATIME | S_NOCMTIME;
1882 +}
1883 +
1884 +void au_cpup_attr_timesizes(struct inode *inode)
1885 +{
1886 +       struct inode *h_inode;
1887 +
1888 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
1889 +       fsstack_copy_attr_times(inode, h_inode);
1890 +       fsstack_copy_inode_size(inode, h_inode);
1891 +}
1892 +
1893 +void au_cpup_attr_nlink(struct inode *inode, int force)
1894 +{
1895 +       struct inode *h_inode;
1896 +       struct super_block *sb;
1897 +       aufs_bindex_t bindex, bend;
1898 +
1899 +       sb = inode->i_sb;
1900 +       bindex = au_ibstart(inode);
1901 +       h_inode = au_h_iptr(inode, bindex);
1902 +       if (!force
1903 +           && !S_ISDIR(h_inode->i_mode)
1904 +           && au_opt_test(au_mntflags(sb), PLINK)
1905 +           && au_plink_test(inode))
1906 +               return;
1907 +
1908 +       inode->i_nlink = h_inode->i_nlink;
1909 +
1910 +       /*
1911 +        * fewer nlink makes find(1) noisy, but larger nlink doesn't.
1912 +        * it may includes whplink directory.
1913 +        */
1914 +       if (S_ISDIR(h_inode->i_mode)) {
1915 +               bend = au_ibend(inode);
1916 +               for (bindex++; bindex <= bend; bindex++) {
1917 +                       h_inode = au_h_iptr(inode, bindex);
1918 +                       if (h_inode)
1919 +                               au_add_nlink(inode, h_inode);
1920 +               }
1921 +       }
1922 +}
1923 +
1924 +void au_cpup_attr_changeable(struct inode *inode)
1925 +{
1926 +       struct inode *h_inode;
1927 +
1928 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
1929 +       inode->i_mode = h_inode->i_mode;
1930 +       inode->i_uid = h_inode->i_uid;
1931 +       inode->i_gid = h_inode->i_gid;
1932 +       au_cpup_attr_timesizes(inode);
1933 +       au_cpup_attr_flags(inode, h_inode);
1934 +}
1935 +
1936 +void au_cpup_igen(struct inode *inode, struct inode *h_inode)
1937 +{
1938 +       struct au_iinfo *iinfo = au_ii(inode);
1939 +
1940 +       IiMustWriteLock(inode);
1941 +
1942 +       iinfo->ii_higen = h_inode->i_generation;
1943 +       iinfo->ii_hsb1 = h_inode->i_sb;
1944 +}
1945 +
1946 +void au_cpup_attr_all(struct inode *inode, int force)
1947 +{
1948 +       struct inode *h_inode;
1949 +
1950 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
1951 +       au_cpup_attr_changeable(inode);
1952 +       if (inode->i_nlink > 0)
1953 +               au_cpup_attr_nlink(inode, force);
1954 +       inode->i_rdev = h_inode->i_rdev;
1955 +       inode->i_blkbits = h_inode->i_blkbits;
1956 +       au_cpup_igen(inode, h_inode);
1957 +}
1958 +
1959 +/* ---------------------------------------------------------------------- */
1960 +
1961 +/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
1962 +
1963 +/* keep the timestamps of the parent dir when cpup */
1964 +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
1965 +                   struct path *h_path)
1966 +{
1967 +       struct inode *h_inode;
1968 +
1969 +       dt->dt_dentry = dentry;
1970 +       dt->dt_h_path = *h_path;
1971 +       h_inode = h_path->dentry->d_inode;
1972 +       dt->dt_atime = h_inode->i_atime;
1973 +       dt->dt_mtime = h_inode->i_mtime;
1974 +       /* smp_mb(); */
1975 +}
1976 +
1977 +void au_dtime_revert(struct au_dtime *dt)
1978 +{
1979 +       struct iattr attr;
1980 +       int err;
1981 +
1982 +       attr.ia_atime = dt->dt_atime;
1983 +       attr.ia_mtime = dt->dt_mtime;
1984 +       attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
1985 +               | ATTR_ATIME | ATTR_ATIME_SET;
1986 +
1987 +       err = vfsub_notify_change(&dt->dt_h_path, &attr);
1988 +       if (unlikely(err))
1989 +               pr_warning("restoring timestamps failed(%d). ignored\n", err);
1990 +}
1991 +
1992 +/* ---------------------------------------------------------------------- */
1993 +
1994 +static noinline_for_stack
1995 +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src)
1996 +{
1997 +       int err, sbits;
1998 +       struct iattr ia;
1999 +       struct path h_path;
2000 +       struct inode *h_isrc, *h_idst;
2001 +
2002 +       h_path.dentry = au_h_dptr(dst, bindex);
2003 +       h_idst = h_path.dentry->d_inode;
2004 +       h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
2005 +       h_isrc = h_src->d_inode;
2006 +       ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
2007 +               | ATTR_ATIME | ATTR_MTIME
2008 +               | ATTR_ATIME_SET | ATTR_MTIME_SET;
2009 +       ia.ia_uid = h_isrc->i_uid;
2010 +       ia.ia_gid = h_isrc->i_gid;
2011 +       ia.ia_atime = h_isrc->i_atime;
2012 +       ia.ia_mtime = h_isrc->i_mtime;
2013 +       if (h_idst->i_mode != h_isrc->i_mode
2014 +           && !S_ISLNK(h_idst->i_mode)) {
2015 +               ia.ia_valid |= ATTR_MODE;
2016 +               ia.ia_mode = h_isrc->i_mode;
2017 +       }
2018 +       sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
2019 +       au_cpup_attr_flags(h_idst, h_isrc);
2020 +       err = vfsub_notify_change(&h_path, &ia);
2021 +
2022 +       /* is this nfs only? */
2023 +       if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
2024 +               ia.ia_valid = ATTR_FORCE | ATTR_MODE;
2025 +               ia.ia_mode = h_isrc->i_mode;
2026 +               err = vfsub_notify_change(&h_path, &ia);
2027 +       }
2028 +
2029 +       return err;
2030 +}
2031 +
2032 +/* ---------------------------------------------------------------------- */
2033 +
2034 +static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
2035 +                          char *buf, unsigned long blksize)
2036 +{
2037 +       int err;
2038 +       size_t sz, rbytes, wbytes;
2039 +       unsigned char all_zero;
2040 +       char *p, *zp;
2041 +       struct mutex *h_mtx;
2042 +       /* reduce stack usage */
2043 +       struct iattr *ia;
2044 +
2045 +       zp = page_address(ZERO_PAGE(0));
2046 +       if (unlikely(!zp))
2047 +               return -ENOMEM; /* possible? */
2048 +
2049 +       err = 0;
2050 +       all_zero = 0;
2051 +       while (len) {
2052 +               AuDbg("len %lld\n", len);
2053 +               sz = blksize;
2054 +               if (len < blksize)
2055 +                       sz = len;
2056 +
2057 +               rbytes = 0;
2058 +               /* todo: signal_pending? */
2059 +               while (!rbytes || err == -EAGAIN || err == -EINTR) {
2060 +                       rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
2061 +                       err = rbytes;
2062 +               }
2063 +               if (unlikely(err < 0))
2064 +                       break;
2065 +
2066 +               all_zero = 0;
2067 +               if (len >= rbytes && rbytes == blksize)
2068 +                       all_zero = !memcmp(buf, zp, rbytes);
2069 +               if (!all_zero) {
2070 +                       wbytes = rbytes;
2071 +                       p = buf;
2072 +                       while (wbytes) {
2073 +                               size_t b;
2074 +
2075 +                               b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
2076 +                               err = b;
2077 +                               /* todo: signal_pending? */
2078 +                               if (unlikely(err == -EAGAIN || err == -EINTR))
2079 +                                       continue;
2080 +                               if (unlikely(err < 0))
2081 +                                       break;
2082 +                               wbytes -= b;
2083 +                               p += b;
2084 +                       }
2085 +               } else {
2086 +                       loff_t res;
2087 +
2088 +                       AuLabel(hole);
2089 +                       res = vfsub_llseek(dst, rbytes, SEEK_CUR);
2090 +                       err = res;
2091 +                       if (unlikely(res < 0))
2092 +                               break;
2093 +               }
2094 +               len -= rbytes;
2095 +               err = 0;
2096 +       }
2097 +
2098 +       /* the last block may be a hole */
2099 +       if (!err && all_zero) {
2100 +               AuLabel(last hole);
2101 +
2102 +               err = 1;
2103 +               if (au_test_nfs(dst->f_dentry->d_sb)) {
2104 +                       /* nfs requires this step to make last hole */
2105 +                       /* is this only nfs? */
2106 +                       do {
2107 +                               /* todo: signal_pending? */
2108 +                               err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
2109 +                       } while (err == -EAGAIN || err == -EINTR);
2110 +                       if (err == 1)
2111 +                               dst->f_pos--;
2112 +               }
2113 +
2114 +               if (err == 1) {
2115 +                       ia = (void *)buf;
2116 +                       ia->ia_size = dst->f_pos;
2117 +                       ia->ia_valid = ATTR_SIZE | ATTR_FILE;
2118 +                       ia->ia_file = dst;
2119 +                       h_mtx = &dst->f_dentry->d_inode->i_mutex;
2120 +                       mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
2121 +                       err = vfsub_notify_change(&dst->f_path, ia);
2122 +                       mutex_unlock(h_mtx);
2123 +               }
2124 +       }
2125 +
2126 +       return err;
2127 +}
2128 +
2129 +int au_copy_file(struct file *dst, struct file *src, loff_t len)
2130 +{
2131 +       int err;
2132 +       unsigned long blksize;
2133 +       unsigned char do_kfree;
2134 +       char *buf;
2135 +
2136 +       err = -ENOMEM;
2137 +       blksize = dst->f_dentry->d_sb->s_blocksize;
2138 +       if (!blksize || PAGE_SIZE < blksize)
2139 +               blksize = PAGE_SIZE;
2140 +       AuDbg("blksize %lu\n", blksize);
2141 +       do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
2142 +       if (do_kfree)
2143 +               buf = kmalloc(blksize, GFP_NOFS);
2144 +       else
2145 +               buf = (void *)__get_free_page(GFP_NOFS);
2146 +       if (unlikely(!buf))
2147 +               goto out;
2148 +
2149 +       if (len > (1 << 22))
2150 +               AuDbg("copying a large file %lld\n", (long long)len);
2151 +
2152 +       src->f_pos = 0;
2153 +       dst->f_pos = 0;
2154 +       err = au_do_copy_file(dst, src, len, buf, blksize);
2155 +       if (do_kfree)
2156 +               kfree(buf);
2157 +       else
2158 +               free_page((unsigned long)buf);
2159 +
2160 +out:
2161 +       return err;
2162 +}
2163 +
2164 +/*
2165 + * to support a sparse file which is opened with O_APPEND,
2166 + * we need to close the file.
2167 + */
2168 +static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst,
2169 +                        aufs_bindex_t bsrc, loff_t len)
2170 +{
2171 +       int err, i;
2172 +       enum { SRC, DST };
2173 +       struct {
2174 +               aufs_bindex_t bindex;
2175 +               unsigned int flags;
2176 +               struct dentry *dentry;
2177 +               struct file *file;
2178 +               void *label, *label_file;
2179 +       } *f, file[] = {
2180 +               {
2181 +                       .bindex = bsrc,
2182 +                       .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
2183 +                       .file = NULL,
2184 +                       .label = &&out,
2185 +                       .label_file = &&out_src
2186 +               },
2187 +               {
2188 +                       .bindex = bdst,
2189 +                       .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
2190 +                       .file = NULL,
2191 +                       .label = &&out_src,
2192 +                       .label_file = &&out_dst
2193 +               }
2194 +       };
2195 +       struct super_block *sb;
2196 +
2197 +       /* bsrc branch can be ro/rw. */
2198 +       sb = dentry->d_sb;
2199 +       f = file;
2200 +       for (i = 0; i < 2; i++, f++) {
2201 +               f->dentry = au_h_dptr(dentry, f->bindex);
2202 +               f->file = au_h_open(dentry, f->bindex, f->flags, /*file*/NULL);
2203 +               err = PTR_ERR(f->file);
2204 +               if (IS_ERR(f->file))
2205 +                       goto *f->label;
2206 +               err = -EINVAL;
2207 +               if (unlikely(!f->file->f_op))
2208 +                       goto *f->label_file;
2209 +       }
2210 +
2211 +       /* try stopping to update while we copyup */
2212 +       IMustLock(file[SRC].dentry->d_inode);
2213 +       err = au_copy_file(file[DST].file, file[SRC].file, len);
2214 +
2215 +out_dst:
2216 +       fput(file[DST].file);
2217 +       au_sbr_put(sb, file[DST].bindex);
2218 +out_src:
2219 +       fput(file[SRC].file);
2220 +       au_sbr_put(sb, file[SRC].bindex);
2221 +out:
2222 +       return err;
2223 +}
2224 +
2225 +static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst,
2226 +                             aufs_bindex_t bsrc, loff_t len,
2227 +                             struct inode *h_dir, struct path *h_path)
2228 +{
2229 +       int err, rerr;
2230 +       loff_t l;
2231 +
2232 +       err = 0;
2233 +       l = i_size_read(au_h_iptr(dentry->d_inode, bsrc));
2234 +       if (len == -1 || l < len)
2235 +               len = l;
2236 +       if (len)
2237 +               err = au_cp_regular(dentry, bdst, bsrc, len);
2238 +       if (!err)
2239 +               goto out; /* success */
2240 +
2241 +       rerr = vfsub_unlink(h_dir, h_path, /*force*/0);
2242 +       if (rerr) {
2243 +               AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n",
2244 +                       AuDLNPair(h_path->dentry), err, rerr);
2245 +               err = -EIO;
2246 +       }
2247 +
2248 +out:
2249 +       return err;
2250 +}
2251 +
2252 +static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
2253 +                             struct inode *h_dir)
2254 +{
2255 +       int err, symlen;
2256 +       mm_segment_t old_fs;
2257 +       union {
2258 +               char *k;
2259 +               char __user *u;
2260 +       } sym;
2261 +
2262 +       err = -ENOSYS;
2263 +       if (unlikely(!h_src->d_inode->i_op->readlink))
2264 +               goto out;
2265 +
2266 +       err = -ENOMEM;
2267 +       sym.k = __getname_gfp(GFP_NOFS);
2268 +       if (unlikely(!sym.k))
2269 +               goto out;
2270 +
2271 +       old_fs = get_fs();
2272 +       set_fs(KERNEL_DS);
2273 +       symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
2274 +       err = symlen;
2275 +       set_fs(old_fs);
2276 +
2277 +       if (symlen > 0) {
2278 +               sym.k[symlen] = 0;
2279 +               err = vfsub_symlink(h_dir, h_path, sym.k);
2280 +       }
2281 +       __putname(sym.k);
2282 +
2283 +out:
2284 +       return err;
2285 +}
2286 +
2287 +/* return with the lower dst inode is locked */
2288 +static noinline_for_stack
2289 +int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst,
2290 +              aufs_bindex_t bsrc, loff_t len, unsigned int flags,
2291 +              struct dentry *dst_parent)
2292 +{
2293 +       int err;
2294 +       umode_t mode;
2295 +       unsigned int mnt_flags;
2296 +       unsigned char isdir;
2297 +       const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME);
2298 +       struct au_dtime dt;
2299 +       struct path h_path;
2300 +       struct dentry *h_src, *h_dst, *h_parent;
2301 +       struct inode *h_inode, *h_dir;
2302 +       struct super_block *sb;
2303 +
2304 +       /* bsrc branch can be ro/rw. */
2305 +       h_src = au_h_dptr(dentry, bsrc);
2306 +       h_inode = h_src->d_inode;
2307 +       AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc));
2308 +
2309 +       /* try stopping to be referenced while we are creating */
2310 +       h_dst = au_h_dptr(dentry, bdst);
2311 +       h_parent = h_dst->d_parent; /* dir inode is locked */
2312 +       h_dir = h_parent->d_inode;
2313 +       IMustLock(h_dir);
2314 +       AuDebugOn(h_parent != h_dst->d_parent);
2315 +
2316 +       sb = dentry->d_sb;
2317 +       h_path.mnt = au_sbr_mnt(sb, bdst);
2318 +       if (do_dt) {
2319 +               h_path.dentry = h_parent;
2320 +               au_dtime_store(&dt, dst_parent, &h_path);
2321 +       }
2322 +       h_path.dentry = h_dst;
2323 +
2324 +       isdir = 0;
2325 +       mode = h_inode->i_mode;
2326 +       switch (mode & S_IFMT) {
2327 +       case S_IFREG:
2328 +               /* try stopping to update while we are referencing */
2329 +               IMustLock(h_inode);
2330 +               err = vfsub_create(h_dir, &h_path, mode | S_IWUSR);
2331 +               if (!err)
2332 +                       err = au_do_cpup_regular
2333 +                               (dentry, bdst, bsrc, len,
2334 +                                au_h_iptr(dst_parent->d_inode, bdst), &h_path);
2335 +               break;
2336 +       case S_IFDIR:
2337 +               isdir = 1;
2338 +               err = vfsub_mkdir(h_dir, &h_path, mode);
2339 +               if (!err) {
2340 +                       /*
2341 +                        * strange behaviour from the users view,
2342 +                        * particularry setattr case
2343 +                        */
2344 +                       if (au_ibstart(dst_parent->d_inode) == bdst)
2345 +                               au_cpup_attr_nlink(dst_parent->d_inode,
2346 +                                                  /*force*/1);
2347 +                       au_cpup_attr_nlink(dentry->d_inode, /*force*/1);
2348 +               }
2349 +               break;
2350 +       case S_IFLNK:
2351 +               err = au_do_cpup_symlink(&h_path, h_src, h_dir);
2352 +               break;
2353 +       case S_IFCHR:
2354 +       case S_IFBLK:
2355 +               AuDebugOn(!capable(CAP_MKNOD));
2356 +               /*FALLTHROUGH*/
2357 +       case S_IFIFO:
2358 +       case S_IFSOCK:
2359 +               err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
2360 +               break;
2361 +       default:
2362 +               AuIOErr("Unknown inode type 0%o\n", mode);
2363 +               err = -EIO;
2364 +       }
2365 +
2366 +       mnt_flags = au_mntflags(sb);
2367 +       if (!au_opt_test(mnt_flags, UDBA_NONE)
2368 +           && !isdir
2369 +           && au_opt_test(mnt_flags, XINO)
2370 +           && h_inode->i_nlink == 1
2371 +           /* todo: unnecessary? */
2372 +           /* && dentry->d_inode->i_nlink == 1 */
2373 +           && bdst < bsrc
2374 +           && !au_ftest_cpup(flags, KEEPLINO))
2375 +               au_xino_write(sb, bsrc, h_inode->i_ino, /*ino*/0);
2376 +               /* ignore this error */
2377 +
2378 +       if (do_dt)
2379 +               au_dtime_revert(&dt);
2380 +       return err;
2381 +}
2382 +
2383 +/*
2384 + * copyup the @dentry from @bsrc to @bdst.
2385 + * the caller must set the both of lower dentries.
2386 + * @len is for truncating when it is -1 copyup the entire file.
2387 + * in link/rename cases, @dst_parent may be different from the real one.
2388 + */
2389 +static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
2390 +                         aufs_bindex_t bsrc, loff_t len, unsigned int flags,
2391 +                         struct dentry *dst_parent)
2392 +{
2393 +       int err, rerr;
2394 +       aufs_bindex_t old_ibstart;
2395 +       unsigned char isdir, plink;
2396 +       struct au_dtime dt;
2397 +       struct path h_path;
2398 +       struct dentry *h_src, *h_dst, *h_parent;
2399 +       struct inode *dst_inode, *h_dir, *inode;
2400 +       struct super_block *sb;
2401 +
2402 +       AuDebugOn(bsrc <= bdst);
2403 +
2404 +       sb = dentry->d_sb;
2405 +       h_path.mnt = au_sbr_mnt(sb, bdst);
2406 +       h_dst = au_h_dptr(dentry, bdst);
2407 +       h_parent = h_dst->d_parent; /* dir inode is locked */
2408 +       h_dir = h_parent->d_inode;
2409 +       IMustLock(h_dir);
2410 +
2411 +       h_src = au_h_dptr(dentry, bsrc);
2412 +       inode = dentry->d_inode;
2413 +
2414 +       if (!dst_parent)
2415 +               dst_parent = dget_parent(dentry);
2416 +       else
2417 +               dget(dst_parent);
2418 +
2419 +       plink = !!au_opt_test(au_mntflags(sb), PLINK);
2420 +       dst_inode = au_h_iptr(inode, bdst);
2421 +       if (dst_inode) {
2422 +               if (unlikely(!plink)) {
2423 +                       err = -EIO;
2424 +                       AuIOErr("i%lu exists on a upper branch "
2425 +                               "but plink is disabled\n", inode->i_ino);
2426 +                       goto out;
2427 +               }
2428 +
2429 +               if (dst_inode->i_nlink) {
2430 +                       const int do_dt = au_ftest_cpup(flags, DTIME);
2431 +
2432 +                       h_src = au_plink_lkup(inode, bdst);
2433 +                       err = PTR_ERR(h_src);
2434 +                       if (IS_ERR(h_src))
2435 +                               goto out;
2436 +                       if (unlikely(!h_src->d_inode)) {
2437 +                               err = -EIO;
2438 +                               AuIOErr("i%lu exists on a upper branch "
2439 +                                       "but plink is broken\n", inode->i_ino);
2440 +                               dput(h_src);
2441 +                               goto out;
2442 +                       }
2443 +
2444 +                       if (do_dt) {
2445 +                               h_path.dentry = h_parent;
2446 +                               au_dtime_store(&dt, dst_parent, &h_path);
2447 +                       }
2448 +                       h_path.dentry = h_dst;
2449 +                       err = vfsub_link(h_src, h_dir, &h_path);
2450 +                       if (do_dt)
2451 +                               au_dtime_revert(&dt);
2452 +                       dput(h_src);
2453 +                       goto out;
2454 +               } else
2455 +                       /* todo: cpup_wh_file? */
2456 +                       /* udba work */
2457 +                       au_update_ibrange(inode, /*do_put_zero*/1);
2458 +       }
2459 +
2460 +       old_ibstart = au_ibstart(inode);
2461 +       err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent);
2462 +       if (unlikely(err))
2463 +               goto out;
2464 +       dst_inode = h_dst->d_inode;
2465 +       mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
2466 +
2467 +       err = cpup_iattr(dentry, bdst, h_src);
2468 +       isdir = S_ISDIR(dst_inode->i_mode);
2469 +       if (!err) {
2470 +               if (bdst < old_ibstart) {
2471 +                       if (S_ISREG(inode->i_mode)) {
2472 +                               err = au_dy_iaop(inode, bdst, dst_inode);
2473 +                               if (unlikely(err))
2474 +                                       goto out_rev;
2475 +                       }
2476 +                       au_set_ibstart(inode, bdst);
2477 +               }
2478 +               au_set_h_iptr(inode, bdst, au_igrab(dst_inode),
2479 +                             au_hi_flags(inode, isdir));
2480 +               mutex_unlock(&dst_inode->i_mutex);
2481 +               if (!isdir
2482 +                   && h_src->d_inode->i_nlink > 1
2483 +                   && plink)
2484 +                       au_plink_append(inode, bdst, h_dst);
2485 +               goto out; /* success */
2486 +       }
2487 +
2488 +       /* revert */
2489 +out_rev:
2490 +       h_path.dentry = h_parent;
2491 +       mutex_unlock(&dst_inode->i_mutex);
2492 +       au_dtime_store(&dt, dst_parent, &h_path);
2493 +       h_path.dentry = h_dst;
2494 +       if (!isdir)
2495 +               rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
2496 +       else
2497 +               rerr = vfsub_rmdir(h_dir, &h_path);
2498 +       au_dtime_revert(&dt);
2499 +       if (rerr) {
2500 +               AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
2501 +               err = -EIO;
2502 +       }
2503 +
2504 +out:
2505 +       dput(dst_parent);
2506 +       return err;
2507 +}
2508 +
2509 +struct au_cpup_single_args {
2510 +       int *errp;
2511 +       struct dentry *dentry;
2512 +       aufs_bindex_t bdst, bsrc;
2513 +       loff_t len;
2514 +       unsigned int flags;
2515 +       struct dentry *dst_parent;
2516 +};
2517 +
2518 +static void au_call_cpup_single(void *args)
2519 +{
2520 +       struct au_cpup_single_args *a = args;
2521 +       *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len,
2522 +                                 a->flags, a->dst_parent);
2523 +}
2524 +
2525 +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
2526 +                      aufs_bindex_t bsrc, loff_t len, unsigned int flags,
2527 +                      struct dentry *dst_parent)
2528 +{
2529 +       int err, wkq_err;
2530 +       umode_t mode;
2531 +       struct dentry *h_dentry;
2532 +
2533 +       h_dentry = au_h_dptr(dentry, bsrc);
2534 +       mode = h_dentry->d_inode->i_mode & S_IFMT;
2535 +       if ((mode != S_IFCHR && mode != S_IFBLK)
2536 +           || capable(CAP_MKNOD))
2537 +               err = au_cpup_single(dentry, bdst, bsrc, len, flags,
2538 +                                    dst_parent);
2539 +       else {
2540 +               struct au_cpup_single_args args = {
2541 +                       .errp           = &err,
2542 +                       .dentry         = dentry,
2543 +                       .bdst           = bdst,
2544 +                       .bsrc           = bsrc,
2545 +                       .len            = len,
2546 +                       .flags          = flags,
2547 +                       .dst_parent     = dst_parent
2548 +               };
2549 +               wkq_err = au_wkq_wait(au_call_cpup_single, &args);
2550 +               if (unlikely(wkq_err))
2551 +                       err = wkq_err;
2552 +       }
2553 +
2554 +       return err;
2555 +}
2556 +
2557 +/*
2558 + * copyup the @dentry from the first active lower branch to @bdst,
2559 + * using au_cpup_single().
2560 + */
2561 +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2562 +                         unsigned int flags)
2563 +{
2564 +       int err;
2565 +       aufs_bindex_t bsrc, bend;
2566 +
2567 +       bend = au_dbend(dentry);
2568 +       for (bsrc = bdst + 1; bsrc <= bend; bsrc++)
2569 +               if (au_h_dptr(dentry, bsrc))
2570 +                       break;
2571 +
2572 +       err = au_lkup_neg(dentry, bdst);
2573 +       if (!err) {
2574 +               err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL);
2575 +               if (!err)
2576 +                       return 0; /* success */
2577 +
2578 +               /* revert */
2579 +               au_set_h_dptr(dentry, bdst, NULL);
2580 +               au_set_dbstart(dentry, bsrc);
2581 +       }
2582 +
2583 +       return err;
2584 +}
2585 +
2586 +struct au_cpup_simple_args {
2587 +       int *errp;
2588 +       struct dentry *dentry;
2589 +       aufs_bindex_t bdst;
2590 +       loff_t len;
2591 +       unsigned int flags;
2592 +};
2593 +
2594 +static void au_call_cpup_simple(void *args)
2595 +{
2596 +       struct au_cpup_simple_args *a = args;
2597 +       *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags);
2598 +}
2599 +
2600 +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2601 +                      unsigned int flags)
2602 +{
2603 +       int err, wkq_err;
2604 +       unsigned char do_sio;
2605 +       struct dentry *parent;
2606 +       struct inode *h_dir;
2607 +
2608 +       parent = dget_parent(dentry);
2609 +       h_dir = au_h_iptr(parent->d_inode, bdst);
2610 +       do_sio = !!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE);
2611 +       if (!do_sio) {
2612 +               /*
2613 +                * testing CAP_MKNOD is for generic fs,
2614 +                * but CAP_FSETID is for xfs only, currently.
2615 +                */
2616 +               umode_t mode = dentry->d_inode->i_mode;
2617 +               do_sio = (((mode & (S_IFCHR | S_IFBLK))
2618 +                          && !capable(CAP_MKNOD))
2619 +                         || ((mode & (S_ISUID | S_ISGID))
2620 +                             && !capable(CAP_FSETID)));
2621 +       }
2622 +       if (!do_sio)
2623 +               err = au_cpup_simple(dentry, bdst, len, flags);
2624 +       else {
2625 +               struct au_cpup_simple_args args = {
2626 +                       .errp           = &err,
2627 +                       .dentry         = dentry,
2628 +                       .bdst           = bdst,
2629 +                       .len            = len,
2630 +                       .flags          = flags
2631 +               };
2632 +               wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
2633 +               if (unlikely(wkq_err))
2634 +                       err = wkq_err;
2635 +       }
2636 +
2637 +       dput(parent);
2638 +       return err;
2639 +}
2640 +
2641 +/* ---------------------------------------------------------------------- */
2642 +
2643 +/*
2644 + * copyup the deleted file for writing.
2645 + */
2646 +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
2647 +                        struct dentry *wh_dentry, struct file *file,
2648 +                        loff_t len)
2649 +{
2650 +       int err;
2651 +       aufs_bindex_t bstart;
2652 +       struct au_dinfo *dinfo;
2653 +       struct dentry *h_d_dst, *h_d_start;
2654 +       struct au_hdentry *hdp;
2655 +
2656 +       dinfo = au_di(dentry);
2657 +       AuRwMustWriteLock(&dinfo->di_rwsem);
2658 +
2659 +       bstart = dinfo->di_bstart;
2660 +       hdp = dinfo->di_hdentry;
2661 +       h_d_dst = hdp[0 + bdst].hd_dentry;
2662 +       dinfo->di_bstart = bdst;
2663 +       hdp[0 + bdst].hd_dentry = wh_dentry;
2664 +       h_d_start = hdp[0 + bstart].hd_dentry;
2665 +       if (file)
2666 +               hdp[0 + bstart].hd_dentry = au_hf_top(file)->f_dentry;
2667 +       err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME,
2668 +                            /*h_parent*/NULL);
2669 +       if (!err && file) {
2670 +               err = au_reopen_nondir(file);
2671 +               hdp[0 + bstart].hd_dentry = h_d_start;
2672 +       }
2673 +       hdp[0 + bdst].hd_dentry = h_d_dst;
2674 +       dinfo->di_bstart = bstart;
2675 +
2676 +       return err;
2677 +}
2678 +
2679 +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2680 +                     struct file *file)
2681 +{
2682 +       int err;
2683 +       struct au_dtime dt;
2684 +       struct dentry *parent, *h_parent, *wh_dentry;
2685 +       struct au_branch *br;
2686 +       struct path h_path;
2687 +
2688 +       br = au_sbr(dentry->d_sb, bdst);
2689 +       parent = dget_parent(dentry);
2690 +       h_parent = au_h_dptr(parent, bdst);
2691 +       wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
2692 +       err = PTR_ERR(wh_dentry);
2693 +       if (IS_ERR(wh_dentry))
2694 +               goto out;
2695 +
2696 +       h_path.dentry = h_parent;
2697 +       h_path.mnt = br->br_mnt;
2698 +       au_dtime_store(&dt, parent, &h_path);
2699 +       err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len);
2700 +       if (unlikely(err))
2701 +               goto out_wh;
2702 +
2703 +       dget(wh_dentry);
2704 +       h_path.dentry = wh_dentry;
2705 +       if (!S_ISDIR(wh_dentry->d_inode->i_mode))
2706 +               err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0);
2707 +       else
2708 +               err = vfsub_rmdir(h_parent->d_inode, &h_path);
2709 +       if (unlikely(err)) {
2710 +               AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
2711 +                       AuDLNPair(wh_dentry), err);
2712 +               err = -EIO;
2713 +       }
2714 +       au_dtime_revert(&dt);
2715 +       au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
2716 +
2717 +out_wh:
2718 +       dput(wh_dentry);
2719 +out:
2720 +       dput(parent);
2721 +       return err;
2722 +}
2723 +
2724 +struct au_cpup_wh_args {
2725 +       int *errp;
2726 +       struct dentry *dentry;
2727 +       aufs_bindex_t bdst;
2728 +       loff_t len;
2729 +       struct file *file;
2730 +};
2731 +
2732 +static void au_call_cpup_wh(void *args)
2733 +{
2734 +       struct au_cpup_wh_args *a = args;
2735 +       *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file);
2736 +}
2737 +
2738 +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2739 +                  struct file *file)
2740 +{
2741 +       int err, wkq_err;
2742 +       struct dentry *parent, *h_orph, *h_parent, *h_dentry;
2743 +       struct inode *dir, *h_dir, *h_tmpdir, *h_inode;
2744 +       struct au_wbr *wbr;
2745 +
2746 +       parent = dget_parent(dentry);
2747 +       dir = parent->d_inode;
2748 +       h_orph = NULL;
2749 +       h_parent = NULL;
2750 +       h_dir = au_igrab(au_h_iptr(dir, bdst));
2751 +       h_tmpdir = h_dir;
2752 +       if (!h_dir->i_nlink) {
2753 +               wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
2754 +               h_orph = wbr->wbr_orph;
2755 +
2756 +               h_parent = dget(au_h_dptr(parent, bdst));
2757 +               au_set_h_dptr(parent, bdst, dget(h_orph));
2758 +               h_tmpdir = h_orph->d_inode;
2759 +               au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
2760 +
2761 +               /* this temporary unlock is safe */
2762 +               if (file)
2763 +                       h_dentry = au_hf_top(file)->f_dentry;
2764 +               else
2765 +                       h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
2766 +               h_inode = h_dentry->d_inode;
2767 +               IMustLock(h_inode);
2768 +               mutex_unlock(&h_inode->i_mutex);
2769 +               mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
2770 +               mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
2771 +               /* todo: au_h_open_pre()? */
2772 +       }
2773 +
2774 +       if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE))
2775 +               err = au_cpup_wh(dentry, bdst, len, file);
2776 +       else {
2777 +               struct au_cpup_wh_args args = {
2778 +                       .errp   = &err,
2779 +                       .dentry = dentry,
2780 +                       .bdst   = bdst,
2781 +                       .len    = len,
2782 +                       .file   = file
2783 +               };
2784 +               wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
2785 +               if (unlikely(wkq_err))
2786 +                       err = wkq_err;
2787 +       }
2788 +
2789 +       if (h_orph) {
2790 +               mutex_unlock(&h_tmpdir->i_mutex);
2791 +               /* todo: au_h_open_post()? */
2792 +               au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
2793 +               au_set_h_dptr(parent, bdst, h_parent);
2794 +       }
2795 +       iput(h_dir);
2796 +       dput(parent);
2797 +
2798 +       return err;
2799 +}
2800 +
2801 +/* ---------------------------------------------------------------------- */
2802 +
2803 +/*
2804 + * generic routine for both of copy-up and copy-down.
2805 + */
2806 +/* cf. revalidate function in file.c */
2807 +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
2808 +              int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
2809 +                        struct dentry *h_parent, void *arg),
2810 +              void *arg)
2811 +{
2812 +       int err;
2813 +       struct au_pin pin;
2814 +       struct dentry *d, *parent, *h_parent, *real_parent;
2815 +
2816 +       err = 0;
2817 +       parent = dget_parent(dentry);
2818 +       if (IS_ROOT(parent))
2819 +               goto out;
2820 +
2821 +       au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
2822 +                   au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
2823 +
2824 +       /* do not use au_dpage */
2825 +       real_parent = parent;
2826 +       while (1) {
2827 +               dput(parent);
2828 +               parent = dget_parent(dentry);
2829 +               h_parent = au_h_dptr(parent, bdst);
2830 +               if (h_parent)
2831 +                       goto out; /* success */
2832 +
2833 +               /* find top dir which is necessary to cpup */
2834 +               do {
2835 +                       d = parent;
2836 +                       dput(parent);
2837 +                       parent = dget_parent(d);
2838 +                       di_read_lock_parent3(parent, !AuLock_IR);
2839 +                       h_parent = au_h_dptr(parent, bdst);
2840 +                       di_read_unlock(parent, !AuLock_IR);
2841 +               } while (!h_parent);
2842 +
2843 +               if (d != real_parent)
2844 +                       di_write_lock_child3(d);
2845 +
2846 +               /* somebody else might create while we were sleeping */
2847 +               if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
2848 +                       if (au_h_dptr(d, bdst))
2849 +                               au_update_dbstart(d);
2850 +
2851 +                       au_pin_set_dentry(&pin, d);
2852 +                       err = au_do_pin(&pin);
2853 +                       if (!err) {
2854 +                               err = cp(d, bdst, h_parent, arg);
2855 +                               au_unpin(&pin);
2856 +                       }
2857 +               }
2858 +
2859 +               if (d != real_parent)
2860 +                       di_write_unlock(d);
2861 +               if (unlikely(err))
2862 +                       break;
2863 +       }
2864 +
2865 +out:
2866 +       dput(parent);
2867 +       return err;
2868 +}
2869 +
2870 +static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
2871 +                      struct dentry *h_parent __maybe_unused ,
2872 +                      void *arg __maybe_unused)
2873 +{
2874 +       return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME);
2875 +}
2876 +
2877 +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
2878 +{
2879 +       return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
2880 +}
2881 +
2882 +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
2883 +{
2884 +       int err;
2885 +       struct dentry *parent;
2886 +       struct inode *dir;
2887 +
2888 +       parent = dget_parent(dentry);
2889 +       dir = parent->d_inode;
2890 +       err = 0;
2891 +       if (au_h_iptr(dir, bdst))
2892 +               goto out;
2893 +
2894 +       di_read_unlock(parent, AuLock_IR);
2895 +       di_write_lock_parent(parent);
2896 +       /* someone else might change our inode while we were sleeping */
2897 +       if (!au_h_iptr(dir, bdst))
2898 +               err = au_cpup_dirs(dentry, bdst);
2899 +       di_downgrade_lock(parent, AuLock_IR);
2900 +
2901 +out:
2902 +       dput(parent);
2903 +       return err;
2904 +}
2905 diff --git a/fs/aufs/cpup.h b/fs/aufs/cpup.h
2906 new file mode 100644
2907 index 0000000..506350d
2908 --- /dev/null
2909 +++ b/fs/aufs/cpup.h
2910 @@ -0,0 +1,81 @@
2911 +/*
2912 + * Copyright (C) 2005-2010 Junjiro R. Okajima
2913 + *
2914 + * This program, aufs is free software; you can redistribute it and/or modify
2915 + * it under the terms of the GNU General Public License as published by
2916 + * the Free Software Foundation; either version 2 of the License, or
2917 + * (at your option) any later version.
2918 + *
2919 + * This program is distributed in the hope that it will be useful,
2920 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2921 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2922 + * GNU General Public License for more details.
2923 + *
2924 + * You should have received a copy of the GNU General Public License
2925 + * along with this program; if not, write to the Free Software
2926 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
2927 + */
2928 +
2929 +/*
2930 + * copy-up/down functions
2931 + */
2932 +
2933 +#ifndef __AUFS_CPUP_H__
2934 +#define __AUFS_CPUP_H__
2935 +
2936 +#ifdef __KERNEL__
2937 +
2938 +#include <linux/path.h>
2939 +#include <linux/time.h>
2940 +#include <linux/aufs_type.h>
2941 +
2942 +struct inode;
2943 +struct file;
2944 +
2945 +void au_cpup_attr_flags(struct inode *dst, struct inode *src);
2946 +void au_cpup_attr_timesizes(struct inode *inode);
2947 +void au_cpup_attr_nlink(struct inode *inode, int force);
2948 +void au_cpup_attr_changeable(struct inode *inode);
2949 +void au_cpup_igen(struct inode *inode, struct inode *h_inode);
2950 +void au_cpup_attr_all(struct inode *inode, int force);
2951 +
2952 +/* ---------------------------------------------------------------------- */
2953 +
2954 +/* cpup flags */
2955 +#define AuCpup_DTIME   1               /* do dtime_store/revert */
2956 +#define AuCpup_KEEPLINO        (1 << 1)        /* do not clear the lower xino,
2957 +                                          for link(2) */
2958 +#define au_ftest_cpup(flags, name)     ((flags) & AuCpup_##name)
2959 +#define au_fset_cpup(flags, name)      { (flags) |= AuCpup_##name; }
2960 +#define au_fclr_cpup(flags, name)      { (flags) &= ~AuCpup_##name; }
2961 +
2962 +int au_copy_file(struct file *dst, struct file *src, loff_t len);
2963 +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
2964 +                      aufs_bindex_t bsrc, loff_t len, unsigned int flags,
2965 +                      struct dentry *dst_parent);
2966 +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2967 +                      unsigned int flags);
2968 +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2969 +                  struct file *file);
2970 +
2971 +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
2972 +              int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
2973 +                        struct dentry *h_parent, void *arg),
2974 +              void *arg);
2975 +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
2976 +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
2977 +
2978 +/* ---------------------------------------------------------------------- */
2979 +
2980 +/* keep timestamps when copyup */
2981 +struct au_dtime {
2982 +       struct dentry *dt_dentry;
2983 +       struct path dt_h_path;
2984 +       struct timespec dt_atime, dt_mtime;
2985 +};
2986 +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
2987 +                   struct path *h_path);
2988 +void au_dtime_revert(struct au_dtime *dt);
2989 +
2990 +#endif /* __KERNEL__ */
2991 +#endif /* __AUFS_CPUP_H__ */
2992 diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c
2993 new file mode 100644
2994 index 0000000..6205871
2995 --- /dev/null
2996 +++ b/fs/aufs/dbgaufs.c
2997 @@ -0,0 +1,334 @@
2998 +/*
2999 + * Copyright (C) 2005-2010 Junjiro R. Okajima
3000 + *
3001 + * This program, aufs is free software; you can redistribute it and/or modify
3002 + * it under the terms of the GNU General Public License as published by
3003 + * the Free Software Foundation; either version 2 of the License, or
3004 + * (at your option) any later version.
3005 + *
3006 + * This program is distributed in the hope that it will be useful,
3007 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3008 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3009 + * GNU General Public License for more details.
3010 + *
3011 + * You should have received a copy of the GNU General Public License
3012 + * along with this program; if not, write to the Free Software
3013 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
3014 + */
3015 +
3016 +/*
3017 + * debugfs interface
3018 + */
3019 +
3020 +#include <linux/debugfs.h>
3021 +#include "aufs.h"
3022 +
3023 +#ifndef CONFIG_SYSFS
3024 +#error DEBUG_FS depends upon SYSFS
3025 +#endif
3026 +
3027 +static struct dentry *dbgaufs;
3028 +static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
3029 +
3030 +/* 20 is max digits length of ulong 64 */
3031 +struct dbgaufs_arg {
3032 +       int n;
3033 +       char a[20 * 4];
3034 +};
3035 +
3036 +/*
3037 + * common function for all XINO files
3038 + */
3039 +static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
3040 +                             struct file *file)
3041 +{
3042 +       kfree(file->private_data);
3043 +       return 0;
3044 +}
3045 +
3046 +static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
3047 +{
3048 +       int err;
3049 +       struct kstat st;
3050 +       struct dbgaufs_arg *p;
3051 +
3052 +       err = -ENOMEM;
3053 +       p = kmalloc(sizeof(*p), GFP_NOFS);
3054 +       if (unlikely(!p))
3055 +               goto out;
3056 +
3057 +       err = 0;
3058 +       p->n = 0;
3059 +       file->private_data = p;
3060 +       if (!xf)
3061 +               goto out;
3062 +
3063 +       err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st);
3064 +       if (!err) {
3065 +               if (do_fcnt)
3066 +                       p->n = snprintf
3067 +                               (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
3068 +                                (long)file_count(xf), st.blocks, st.blksize,
3069 +                                (long long)st.size);
3070 +               else
3071 +                       p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
3072 +                                       st.blocks, st.blksize,
3073 +                                       (long long)st.size);
3074 +               AuDebugOn(p->n >= sizeof(p->a));
3075 +       } else {
3076 +               p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
3077 +               err = 0;
3078 +       }
3079 +
3080 +out:
3081 +       return err;
3082 +
3083 +}
3084 +
3085 +static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
3086 +                              size_t count, loff_t *ppos)
3087 +{
3088 +       struct dbgaufs_arg *p;
3089 +
3090 +       p = file->private_data;
3091 +       return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
3092 +}
3093 +
3094 +/* ---------------------------------------------------------------------- */
3095 +
3096 +static int dbgaufs_xib_open(struct inode *inode, struct file *file)
3097 +{
3098 +       int err;
3099 +       struct au_sbinfo *sbinfo;
3100 +       struct super_block *sb;
3101 +
3102 +       sbinfo = inode->i_private;
3103 +       sb = sbinfo->si_sb;
3104 +       si_noflush_read_lock(sb);
3105 +       err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
3106 +       si_read_unlock(sb);
3107 +       return err;
3108 +}
3109 +
3110 +static const struct file_operations dbgaufs_xib_fop = {
3111 +       .owner          = THIS_MODULE,
3112 +       .open           = dbgaufs_xib_open,
3113 +       .release        = dbgaufs_xi_release,
3114 +       .read           = dbgaufs_xi_read
3115 +};
3116 +
3117 +/* ---------------------------------------------------------------------- */
3118 +
3119 +#define DbgaufsXi_PREFIX "xi"
3120 +
3121 +static int dbgaufs_xino_open(struct inode *inode, struct file *file)
3122 +{
3123 +       int err;
3124 +       long l;
3125 +       struct au_sbinfo *sbinfo;
3126 +       struct super_block *sb;
3127 +       struct file *xf;
3128 +       struct qstr *name;
3129 +
3130 +       err = -ENOENT;
3131 +       xf = NULL;
3132 +       name = &file->f_dentry->d_name;
3133 +       if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
3134 +                    || memcmp(name->name, DbgaufsXi_PREFIX,
3135 +                              sizeof(DbgaufsXi_PREFIX) - 1)))
3136 +               goto out;
3137 +       err = strict_strtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
3138 +       if (unlikely(err))
3139 +               goto out;
3140 +
3141 +       sbinfo = inode->i_private;
3142 +       sb = sbinfo->si_sb;
3143 +       si_noflush_read_lock(sb);
3144 +       if (l <= au_sbend(sb)) {
3145 +               xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
3146 +               err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
3147 +       } else
3148 +               err = -ENOENT;
3149 +       si_read_unlock(sb);
3150 +
3151 +out:
3152 +       return err;
3153 +}
3154 +
3155 +static const struct file_operations dbgaufs_xino_fop = {
3156 +       .owner          = THIS_MODULE,
3157 +       .open           = dbgaufs_xino_open,
3158 +       .release        = dbgaufs_xi_release,
3159 +       .read           = dbgaufs_xi_read
3160 +};
3161 +
3162 +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
3163 +{
3164 +       aufs_bindex_t bend;
3165 +       struct au_branch *br;
3166 +       struct au_xino_file *xi;
3167 +
3168 +       if (!au_sbi(sb)->si_dbgaufs)
3169 +               return;
3170 +
3171 +       bend = au_sbend(sb);
3172 +       for (; bindex <= bend; bindex++) {
3173 +               br = au_sbr(sb, bindex);
3174 +               xi = &br->br_xino;
3175 +               if (xi->xi_dbgaufs) {
3176 +                       debugfs_remove(xi->xi_dbgaufs);
3177 +                       xi->xi_dbgaufs = NULL;
3178 +               }
3179 +       }
3180 +}
3181 +
3182 +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
3183 +{
3184 +       struct au_sbinfo *sbinfo;
3185 +       struct dentry *parent;
3186 +       struct au_branch *br;
3187 +       struct au_xino_file *xi;
3188 +       aufs_bindex_t bend;
3189 +       char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
3190 +
3191 +       sbinfo = au_sbi(sb);
3192 +       parent = sbinfo->si_dbgaufs;
3193 +       if (!parent)
3194 +               return;
3195 +
3196 +       bend = au_sbend(sb);
3197 +       for (; bindex <= bend; bindex++) {
3198 +               snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
3199 +               br = au_sbr(sb, bindex);
3200 +               xi = &br->br_xino;
3201 +               AuDebugOn(xi->xi_dbgaufs);
3202 +               xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
3203 +                                                    sbinfo, &dbgaufs_xino_fop);
3204 +               /* ignore an error */
3205 +               if (unlikely(!xi->xi_dbgaufs))
3206 +                       AuWarn1("failed %s under debugfs\n", name);
3207 +       }
3208 +}
3209 +
3210 +/* ---------------------------------------------------------------------- */
3211 +
3212 +#ifdef CONFIG_AUFS_EXPORT
3213 +static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
3214 +{
3215 +       int err;
3216 +       struct au_sbinfo *sbinfo;
3217 +       struct super_block *sb;
3218 +
3219 +       sbinfo = inode->i_private;
3220 +       sb = sbinfo->si_sb;
3221 +       si_noflush_read_lock(sb);
3222 +       err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
3223 +       si_read_unlock(sb);
3224 +       return err;
3225 +}
3226 +
3227 +static const struct file_operations dbgaufs_xigen_fop = {
3228 +       .owner          = THIS_MODULE,
3229 +       .open           = dbgaufs_xigen_open,
3230 +       .release        = dbgaufs_xi_release,
3231 +       .read           = dbgaufs_xi_read
3232 +};
3233 +
3234 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
3235 +{
3236 +       int err;
3237 +
3238 +       /*
3239 +        * This function is a dynamic '__init' fucntion actually,
3240 +        * so the tiny check for si_rwsem is unnecessary.
3241 +        */
3242 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
3243 +
3244 +       err = -EIO;
3245 +       sbinfo->si_dbgaufs_xigen = debugfs_create_file
3246 +               ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
3247 +                &dbgaufs_xigen_fop);
3248 +       if (sbinfo->si_dbgaufs_xigen)
3249 +               err = 0;
3250 +
3251 +       return err;
3252 +}
3253 +#else
3254 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
3255 +{
3256 +       return 0;
3257 +}
3258 +#endif /* CONFIG_AUFS_EXPORT */
3259 +
3260 +/* ---------------------------------------------------------------------- */
3261 +
3262 +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
3263 +{
3264 +       /*
3265 +        * This function is a dynamic '__init' fucntion actually,
3266 +        * so the tiny check for si_rwsem is unnecessary.
3267 +        */
3268 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
3269 +
3270 +       debugfs_remove_recursive(sbinfo->si_dbgaufs);
3271 +       sbinfo->si_dbgaufs = NULL;
3272 +       kobject_put(&sbinfo->si_kobj);
3273 +}
3274 +
3275 +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
3276 +{
3277 +       int err;
3278 +       char name[SysaufsSiNameLen];
3279 +
3280 +       /*
3281 +        * This function is a dynamic '__init' fucntion actually,
3282 +        * so the tiny check for si_rwsem is unnecessary.
3283 +        */
3284 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
3285 +
3286 +       err = -ENOENT;
3287 +       if (!dbgaufs) {
3288 +               AuErr1("/debug/aufs is uninitialized\n");
3289 +               goto out;
3290 +       }
3291 +
3292 +       err = -EIO;
3293 +       sysaufs_name(sbinfo, name);
3294 +       sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
3295 +       if (unlikely(!sbinfo->si_dbgaufs))
3296 +               goto out;
3297 +       kobject_get(&sbinfo->si_kobj);
3298 +
3299 +       sbinfo->si_dbgaufs_xib = debugfs_create_file
3300 +               ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
3301 +                &dbgaufs_xib_fop);
3302 +       if (unlikely(!sbinfo->si_dbgaufs_xib))
3303 +               goto out_dir;
3304 +
3305 +       err = dbgaufs_xigen_init(sbinfo);
3306 +       if (!err)
3307 +               goto out; /* success */
3308 +
3309 +out_dir:
3310 +       dbgaufs_si_fin(sbinfo);
3311 +out:
3312 +       return err;
3313 +}
3314 +
3315 +/* ---------------------------------------------------------------------- */
3316 +
3317 +void dbgaufs_fin(void)
3318 +{
3319 +       debugfs_remove(dbgaufs);
3320 +}
3321 +
3322 +int __init dbgaufs_init(void)
3323 +{
3324 +       int err;
3325 +
3326 +       err = -EIO;
3327 +       dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
3328 +       if (dbgaufs)
3329 +               err = 0;
3330 +       return err;
3331 +}
3332 diff --git a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h
3333 new file mode 100644
3334 index 0000000..ae41480
3335 --- /dev/null
3336 +++ b/fs/aufs/dbgaufs.h
3337 @@ -0,0 +1,52 @@
3338 +/*
3339 + * Copyright (C) 2005-2010 Junjiro R. Okajima
3340 + *
3341 + * This program, aufs is free software; you can redistribute it and/or modify
3342 + * it under the terms of the GNU General Public License as published by
3343 + * the Free Software Foundation; either version 2 of the License, or
3344 + * (at your option) any later version.
3345 + *
3346 + * This program is distributed in the hope that it will be useful,
3347 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3348 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3349 + * GNU General Public License for more details.
3350 + *
3351 + * You should have received a copy of the GNU General Public License
3352 + * along with this program; if not, write to the Free Software
3353 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
3354 + */
3355 +
3356 +/*
3357 + * debugfs interface
3358 + */
3359 +
3360 +#ifndef __DBGAUFS_H__
3361 +#define __DBGAUFS_H__
3362 +
3363 +#ifdef __KERNEL__
3364 +
3365 +#include <linux/init.h>
3366 +#include <linux/aufs_type.h>
3367 +
3368 +struct super_block;
3369 +struct au_sbinfo;
3370 +
3371 +#ifdef CONFIG_DEBUG_FS
3372 +/* dbgaufs.c */
3373 +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
3374 +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
3375 +void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
3376 +int dbgaufs_si_init(struct au_sbinfo *sbinfo);
3377 +void dbgaufs_fin(void);
3378 +int __init dbgaufs_init(void);
3379 +#else
3380 +AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
3381 +AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
3382 +AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
3383 +AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
3384 +AuStubVoid(dbgaufs_fin, void)
3385 +AuStubInt0(__init dbgaufs_init, void)
3386 +#endif /* CONFIG_DEBUG_FS */
3387 +
3388 +#endif /* __KERNEL__ */
3389 +#endif /* __DBGAUFS_H__ */
3390 diff --git a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c
3391 new file mode 100644
3392 index 0000000..d5ab352
3393 --- /dev/null
3394 +++ b/fs/aufs/dcsub.c
3395 @@ -0,0 +1,200 @@
3396 +/*
3397 + * Copyright (C) 2005-2010 Junjiro R. Okajima
3398 + *
3399 + * This program, aufs is free software; you can redistribute it and/or modify
3400 + * it under the terms of the GNU General Public License as published by
3401 + * the Free Software Foundation; either version 2 of the License, or
3402 + * (at your option) any later version.
3403 + *
3404 + * This program is distributed in the hope that it will be useful,
3405 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3406 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3407 + * GNU General Public License for more details.
3408 + *
3409 + * You should have received a copy of the GNU General Public License
3410 + * along with this program; if not, write to the Free Software
3411 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
3412 + */
3413 +
3414 +/*
3415 + * sub-routines for dentry cache
3416 + */
3417 +
3418 +#include "aufs.h"
3419 +
3420 +static void au_dpage_free(struct au_dpage *dpage)
3421 +{
3422 +       int i;
3423 +       struct dentry **p;
3424 +
3425 +       p = dpage->dentries;
3426 +       for (i = 0; i < dpage->ndentry; i++)
3427 +               dput(*p++);
3428 +       free_page((unsigned long)dpage->dentries);
3429 +}
3430 +
3431 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
3432 +{
3433 +       int err;
3434 +       void *p;
3435 +
3436 +       err = -ENOMEM;
3437 +       dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
3438 +       if (unlikely(!dpages->dpages))
3439 +               goto out;
3440 +
3441 +       p = (void *)__get_free_page(gfp);
3442 +       if (unlikely(!p))
3443 +               goto out_dpages;
3444 +
3445 +       dpages->dpages[0].ndentry = 0;
3446 +       dpages->dpages[0].dentries = p;
3447 +       dpages->ndpage = 1;
3448 +       return 0; /* success */
3449 +
3450 +out_dpages:
3451 +       kfree(dpages->dpages);
3452 +out:
3453 +       return err;
3454 +}
3455 +
3456 +void au_dpages_free(struct au_dcsub_pages *dpages)
3457 +{
3458 +       int i;
3459 +       struct au_dpage *p;
3460 +
3461 +       p = dpages->dpages;
3462 +       for (i = 0; i < dpages->ndpage; i++)
3463 +               au_dpage_free(p++);
3464 +       kfree(dpages->dpages);
3465 +}
3466 +
3467 +static int au_dpages_append(struct au_dcsub_pages *dpages,
3468 +                           struct dentry *dentry, gfp_t gfp)
3469 +{
3470 +       int err, sz;
3471 +       struct au_dpage *dpage;
3472 +       void *p;
3473 +
3474 +       dpage = dpages->dpages + dpages->ndpage - 1;
3475 +       sz = PAGE_SIZE / sizeof(dentry);
3476 +       if (unlikely(dpage->ndentry >= sz)) {
3477 +               AuLabel(new dpage);
3478 +               err = -ENOMEM;
3479 +               sz = dpages->ndpage * sizeof(*dpages->dpages);
3480 +               p = au_kzrealloc(dpages->dpages, sz,
3481 +                                sz + sizeof(*dpages->dpages), gfp);
3482 +               if (unlikely(!p))
3483 +                       goto out;
3484 +
3485 +               dpages->dpages = p;
3486 +               dpage = dpages->dpages + dpages->ndpage;
3487 +               p = (void *)__get_free_page(gfp);
3488 +               if (unlikely(!p))
3489 +                       goto out;
3490 +
3491 +               dpage->ndentry = 0;
3492 +               dpage->dentries = p;
3493 +               dpages->ndpage++;
3494 +       }
3495 +
3496 +       dpage->dentries[dpage->ndentry++] = dget(dentry);
3497 +       return 0; /* success */
3498 +
3499 +out:
3500 +       return err;
3501 +}
3502 +
3503 +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
3504 +                  au_dpages_test test, void *arg)
3505 +{
3506 +       int err;
3507 +       struct dentry *this_parent = root;
3508 +       struct list_head *next;
3509 +       struct super_block *sb = root->d_sb;
3510 +
3511 +       err = 0;
3512 +       spin_lock(&dcache_lock);
3513 +repeat:
3514 +       next = this_parent->d_subdirs.next;
3515 +resume:
3516 +       if (this_parent->d_sb == sb
3517 +           && !IS_ROOT(this_parent)
3518 +           && atomic_read(&this_parent->d_count)
3519 +           && this_parent->d_inode
3520 +           && (!test || test(this_parent, arg))) {
3521 +               err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
3522 +               if (unlikely(err))
3523 +                       goto out;
3524 +       }
3525 +
3526 +       while (next != &this_parent->d_subdirs) {
3527 +               struct list_head *tmp = next;
3528 +               struct dentry *dentry = list_entry(tmp, struct dentry,
3529 +                                                  d_u.d_child);
3530 +               next = tmp->next;
3531 +               if (/*d_unhashed(dentry) || */!dentry->d_inode)
3532 +                       continue;
3533 +               if (!list_empty(&dentry->d_subdirs)) {
3534 +                       this_parent = dentry;
3535 +                       goto repeat;
3536 +               }
3537 +               if (dentry->d_sb == sb
3538 +                   && atomic_read(&dentry->d_count)
3539 +                   && (!test || test(dentry, arg))) {
3540 +                       err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
3541 +                       if (unlikely(err))
3542 +                               goto out;
3543 +               }
3544 +       }
3545 +
3546 +       if (this_parent != root) {
3547 +               next = this_parent->d_u.d_child.next;
3548 +               this_parent = this_parent->d_parent; /* dcache_lock is locked */
3549 +               goto resume;
3550 +       }
3551 +out:
3552 +       spin_unlock(&dcache_lock);
3553 +       return err;
3554 +}
3555 +
3556 +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
3557 +                      int do_include, au_dpages_test test, void *arg)
3558 +{
3559 +       int err;
3560 +
3561 +       err = 0;
3562 +       spin_lock(&dcache_lock);
3563 +       if (do_include && (!test || test(dentry, arg))) {
3564 +               err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
3565 +               if (unlikely(err))
3566 +                       goto out;
3567 +       }
3568 +       while (!IS_ROOT(dentry)) {
3569 +               dentry = dentry->d_parent; /* dcache_lock is locked */
3570 +               if (!test || test(dentry, arg)) {
3571 +                       err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
3572 +                       if (unlikely(err))
3573 +                               break;
3574 +               }
3575 +       }
3576 +
3577 +out:
3578 +       spin_unlock(&dcache_lock);
3579 +
3580 +       return err;
3581 +}
3582 +
3583 +int au_test_subdir(struct dentry *d1, struct dentry *d2)
3584 +{
3585 +       struct path path[2] = {
3586 +               {
3587 +                       .dentry = d1
3588 +               },
3589 +               {
3590 +                       .dentry = d2
3591 +               }
3592 +       };
3593 +
3594 +       return path_is_under(path + 0, path + 1);
3595 +}
3596 diff --git a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h
3597 new file mode 100644
3598 index 0000000..0c87168
3599 --- /dev/null
3600 +++ b/fs/aufs/dcsub.h
3601 @@ -0,0 +1,54 @@
3602 +/*
3603 + * Copyright (C) 2005-2010 Junjiro R. Okajima
3604 + *
3605 + * This program, aufs is free software; you can redistribute it and/or modify
3606 + * it under the terms of the GNU General Public License as published by
3607 + * the Free Software Foundation; either version 2 of the License, or
3608 + * (at your option) any later version.
3609 + *
3610 + * This program is distributed in the hope that it will be useful,
3611 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3612 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3613 + * GNU General Public License for more details.
3614 + *
3615 + * You should have received a copy of the GNU General Public License
3616 + * along with this program; if not, write to the Free Software
3617 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
3618 + */
3619 +
3620 +/*
3621 + * sub-routines for dentry cache
3622 + */
3623 +
3624 +#ifndef __AUFS_DCSUB_H__
3625 +#define __AUFS_DCSUB_H__
3626 +
3627 +#ifdef __KERNEL__
3628 +
3629 +#include <linux/types.h>
3630 +
3631 +struct dentry;
3632 +
3633 +struct au_dpage {
3634 +       int ndentry;
3635 +       struct dentry **dentries;
3636 +};
3637 +
3638 +struct au_dcsub_pages {
3639 +       int ndpage;
3640 +       struct au_dpage *dpages;
3641 +};
3642 +
3643 +/* ---------------------------------------------------------------------- */
3644 +
3645 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
3646 +void au_dpages_free(struct au_dcsub_pages *dpages);
3647 +typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
3648 +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
3649 +                  au_dpages_test test, void *arg);
3650 +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
3651 +                      int do_include, au_dpages_test test, void *arg);
3652 +int au_test_subdir(struct dentry *d1, struct dentry *d2);
3653 +
3654 +#endif /* __KERNEL__ */
3655 +#endif /* __AUFS_DCSUB_H__ */
3656 diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c
3657 new file mode 100644
3658 index 0000000..f14f6ad
3659 --- /dev/null
3660 +++ b/fs/aufs/debug.c
3661 @@ -0,0 +1,426 @@
3662 +/*
3663 + * Copyright (C) 2005-2010 Junjiro R. Okajima
3664 + *
3665 + * This program, aufs is free software; you can redistribute it and/or modify
3666 + * it under the terms of the GNU General Public License as published by
3667 + * the Free Software Foundation; either version 2 of the License, or
3668 + * (at your option) any later version.
3669 + *
3670 + * This program is distributed in the hope that it will be useful,
3671 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3672 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3673 + * GNU General Public License for more details.
3674 + *
3675 + * You should have received a copy of the GNU General Public License
3676 + * along with this program; if not, write to the Free Software
3677 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
3678 + */
3679 +
3680 +/*
3681 + * debug print functions
3682 + */
3683 +
3684 +#include <linux/module.h>
3685 +/*#include <linux/vt_kern.h>*/
3686 +#include "aufs.h"
3687 +
3688 +int aufs_debug;
3689 +MODULE_PARM_DESC(debug, "debug print");
3690 +module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
3691 +
3692 +char *au_plevel = KERN_DEBUG;
3693 +#define dpri(fmt, ...) do { \
3694 +       if (au_debug_test()) \
3695 +               printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
3696 +} while (0)
3697 +
3698 +/* ---------------------------------------------------------------------- */
3699 +
3700 +void au_dpri_whlist(struct au_nhash *whlist)
3701 +{
3702 +       unsigned long ul, n;
3703 +       struct hlist_head *head;
3704 +       struct au_vdir_wh *tpos;
3705 +       struct hlist_node *pos;
3706 +
3707 +       n = whlist->nh_num;
3708 +       head = whlist->nh_head;
3709 +       for (ul = 0; ul < n; ul++) {
3710 +               hlist_for_each_entry(tpos, pos, head, wh_hash)
3711 +                       dpri("b%d, %.*s, %d\n",
3712 +                            tpos->wh_bindex,
3713 +                            tpos->wh_str.len, tpos->wh_str.name,
3714 +                            tpos->wh_str.len);
3715 +               head++;
3716 +       }
3717 +}
3718 +
3719 +void au_dpri_vdir(struct au_vdir *vdir)
3720 +{
3721 +       unsigned long ul;
3722 +       union au_vdir_deblk_p p;
3723 +       unsigned char *o;
3724 +
3725 +       if (!vdir || IS_ERR(vdir)) {
3726 +               dpri("err %ld\n", PTR_ERR(vdir));
3727 +               return;
3728 +       }
3729 +
3730 +       dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
3731 +            vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
3732 +            vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
3733 +       for (ul = 0; ul < vdir->vd_nblk; ul++) {
3734 +               p.deblk = vdir->vd_deblk[ul];
3735 +               o = p.deblk;
3736 +               dpri("[%lu]: %p\n", ul, o);
3737 +       }
3738 +}
3739 +
3740 +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode,
3741 +                       struct dentry *wh)
3742 +{
3743 +       char *n = NULL;
3744 +       int l = 0;
3745 +
3746 +       if (!inode || IS_ERR(inode)) {
3747 +               dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
3748 +               return -1;
3749 +       }
3750 +
3751 +       /* the type of i_blocks depends upon CONFIG_LSF */
3752 +       BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
3753 +                    && sizeof(inode->i_blocks) != sizeof(u64));
3754 +       if (wh) {
3755 +               n = (void *)wh->d_name.name;
3756 +               l = wh->d_name.len;
3757 +       }
3758 +
3759 +       dpri("i%d: i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
3760 +            " ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
3761 +            bindex,
3762 +            inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
3763 +            atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
3764 +            i_size_read(inode), (unsigned long long)inode->i_blocks,
3765 +            (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
3766 +            inode->i_mapping ? inode->i_mapping->nrpages : 0,
3767 +            inode->i_state, inode->i_flags, inode->i_version,
3768 +            inode->i_generation,
3769 +            l ? ", wh " : "", l, n);
3770 +       return 0;
3771 +}
3772 +
3773 +void au_dpri_inode(struct inode *inode)
3774 +{
3775 +       struct au_iinfo *iinfo;
3776 +       aufs_bindex_t bindex;
3777 +       int err;
3778 +
3779 +       err = do_pri_inode(-1, inode, NULL);
3780 +       if (err || !au_test_aufs(inode->i_sb))
3781 +               return;
3782 +
3783 +       iinfo = au_ii(inode);
3784 +       if (!iinfo)
3785 +               return;
3786 +       dpri("i-1: bstart %d, bend %d, gen %d\n",
3787 +            iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode));
3788 +       if (iinfo->ii_bstart < 0)
3789 +               return;
3790 +       for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++)
3791 +               do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode,
3792 +                            iinfo->ii_hinode[0 + bindex].hi_whdentry);
3793 +}
3794 +
3795 +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
3796 +{
3797 +       struct dentry *wh = NULL;
3798 +
3799 +       if (!dentry || IS_ERR(dentry)) {
3800 +               dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
3801 +               return -1;
3802 +       }
3803 +       /* do not call dget_parent() here */
3804 +       dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
3805 +            bindex,
3806 +            AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
3807 +            dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
3808 +            atomic_read(&dentry->d_count), dentry->d_flags);
3809 +       if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
3810 +               struct au_iinfo *iinfo = au_ii(dentry->d_inode);
3811 +               if (iinfo)
3812 +                       wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
3813 +       }
3814 +       do_pri_inode(bindex, dentry->d_inode, wh);
3815 +       return 0;
3816 +}