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
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
13 Documentation/ABI/testing/debugfs-aufs | 37 +
14 Documentation/ABI/testing/sysfs-aufs | 24 +
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 ++
58 fs/aufs/magic.mk | 54 ++
59 fs/aufs/module.c | 171 ++++
60 fs/aufs/module.h | 82 ++
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 ++++++
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 +++++
84 fs/aufs/xino.c | 1263 +++++++++++++++++++++++++
89 fs/notify/group.c | 3 +
90 fs/notify/mark.c | 4 +
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
174 diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs
176 index 0000000..7d2e65f
178 +++ b/Documentation/ABI/testing/debugfs-aufs
180 +What: /debug/aufs/si_<id>/
182 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
184 + Under /debug/aufs, a directory named si_<id> is created
185 + per aufs mount, where <id> is a unique id generated
188 +What: /debug/aufs/si_<id>/xib
190 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
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.
197 +What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
199 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
201 + It shows the consumed blocks by xino (External Inode Number
202 + Translation Table), its link count, block size and file
204 + When the aufs mount option 'noxino' is specified, it
205 + will be empty. About XINO files, see the aufs manual.
207 +What: /debug/aufs/si_<id>/xigen
209 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
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
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
219 index 0000000..7af6dc0
221 +++ b/Documentation/ABI/testing/sysfs-aufs
223 +What: /sys/fs/aufs/si_<id>/
225 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
227 + Under /sys/fs/aufs, a directory named si_<id> is created
228 + per aufs mount, where <id> is a unique id generated
231 +What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
233 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
235 + It shows the abolute path of a member directory (which
236 + is called branch) in aufs, and its permission.
238 +What: /sys/fs/aufs/si_<id>/xi_path
240 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
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
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"
257 endif # MISC_FILESYSTEMS
259 diff --git a/fs/Makefile b/fs/Makefile
260 index e6ec1d3..b0d795a 100644
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
270 index 0000000..54ecd33
272 +++ b/fs/aufs/Kconfig
275 + tristate "Aufs (Advanced multi layered unification filesystem) support"
276 + depends on EXPERIMENTAL
278 + Aufs is a stackable unification filesystem such as Unionfs,
279 + which unifies several directories and provides a merged single
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.
288 + prompt "Maximum number of branches"
289 + default AUFS_BRANCH_MAX_127
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
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
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
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
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.
321 + bool "Detect direct branch access (bypassing aufs)"
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.
332 + prompt "method" if AUFS_HNOTIFY
333 + default AUFS_HFSNOTIFY
334 +config AUFS_HFSNOTIFY
340 + bool "NFS-exportable aufs"
341 + depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS)
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.
347 +config AUFS_INO_T_64
349 + depends on AUFS_EXPORT
350 + depends on 64BIT && !(ALPHA || S390)
353 + Automatic configuration for internal use.
354 + /* typedef unsigned long/int __kernel_ino_t */
355 + /* alpha and s390x are int */
358 + bool "Readdir in userspace"
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.
369 +config AUFS_SP_IATTR
370 + bool "Respect the attributes (mtime/ctime mainly) of special files"
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.
381 + bool "Show whiteouts"
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.
388 +config AUFS_BR_RAMFS
389 + bool "Ramfs (initramfs/rootfs) as an aufs branch"
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.
402 + bool "Fuse fs as an aufs branch"
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).
414 + Automatic configuration for internal use.
416 +config AUFS_BR_HFSPLUS
417 + bool "Hfsplus as an aufs branch"
418 + depends on HFSPLUS_FS
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.
425 +config AUFS_BDEV_LOOP
427 + depends on BLK_DEV_LOOP
430 + Automatic configuration for internal use.
431 + Convert =[ym] into =y.
436 + Enable this to compile aufs internal debug code.
437 + It will have a negative impact to the performance.
439 +config AUFS_MAGIC_SYSRQ
441 + depends on AUFS_DEBUG && MAGIC_SYSRQ
444 + Automatic configuration for internal use.
445 + When aufs supports Magic SysRq, enabled automatically.
447 diff --git a/fs/aufs/Makefile b/fs/aufs/Makefile
449 index 0000000..0817a55
451 +++ b/fs/aufs/Makefile
454 +include ${src}/magic.mk
455 +ifeq (${CONFIG_AUFS_FS},m)
456 +include ${src}/conf.mk
458 +-include ${src}/priv_def.mk
460 +# cf. include/linux/kernel.h
462 +ccflags-y += -DDEBUG
463 +ccflags-y += -D'pr_fmt(fmt)="aufs %s:%d:%s[%d]: " fmt, \
464 + __func__, __LINE__, current->comm, current->pid'
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 \
472 + finfo.o file.o f_op.o \
474 + iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
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
492 index 0000000..1363f58
497 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
523 +#define AuStub(type, name, body, ...) \
524 + static inline type name(__VA_ARGS__) { body; }
526 +#define AuStubVoid(name, ...) \
527 + AuStub(void, name, , __VA_ARGS__)
528 +#define AuStubInt0(name, ...) \
529 + AuStub(int, name, return 0, __VA_ARGS__)
536 +#include "dbgaufs.h"
545 +/* never include ./mtx.h */
550 +#include "sysaufs.h"
555 +#endif /* __KERNEL__ */
556 +#endif /* __AUFS_H__ */
557 diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c
559 index 0000000..43c0115
561 +++ b/fs/aufs/branch.c
564 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
582 + * branch management
585 +#include <linux/file.h>
586 +#include <linux/statfs.h>
590 + * free a single branch
592 +static void au_br_do_free(struct au_branch *br)
595 + struct au_wbr *wbr;
596 + struct au_dykey **key;
598 + if (br->br_xino.xi_file)
599 + fput(br->br_xino.xi_file);
600 + mutex_destroy(&br->br_xino.xi_nondir_mtx);
602 + AuDebugOn(atomic_read(&br->br_count));
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);
612 + key = br->br_dykey;
613 + for (i = 0; i < AuBrDynOp; i++, key++)
619 + mntput(br->br_mnt);
625 + * frees all branches
627 +void au_br_free(struct au_sbinfo *sbinfo)
629 + aufs_bindex_t bmax;
630 + struct au_branch **br;
632 + AuRwMustWriteLock(&sbinfo->si_rwsem);
634 + bmax = sbinfo->si_bend + 1;
635 + br = sbinfo->si_branch;
637 + au_br_do_free(*br++);
641 + * find the index of a branch which is specified by @br_id.
643 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
645 + aufs_bindex_t bindex, bend;
647 + bend = au_sbend(sb);
648 + for (bindex = 0; bindex <= bend; bindex++)
649 + if (au_sbr_id(sb, bindex) == br_id)
654 +/* ---------------------------------------------------------------------- */
660 +static int test_overlap(struct super_block *sb, struct dentry *h_adding,
661 + struct dentry *h_root)
663 + if (unlikely(h_adding == h_root
664 + || au_test_loopback_overlap(sb, h_adding)))
666 + if (h_adding->d_sb != h_root->d_sb)
668 + return au_test_subdir(h_adding, h_root)
669 + || au_test_subdir(h_root, h_adding);
673 + * returns a newly allocated branch. @new_nbranch is a number of branches
674 + * after adding a branch.
676 +static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
679 + struct au_branch *add_branch;
680 + struct dentry *root;
685 + add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
686 + if (unlikely(!add_branch))
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),
694 + if (unlikely(!add_branch->br_wbr))
698 + err = au_sbr_realloc(au_sbi(sb), new_nbranch);
700 + err = au_di_realloc(au_di(root), new_nbranch);
702 + err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
704 + return add_branch; /* success */
706 + kfree(add_branch->br_wbr);
711 + return ERR_PTR(err);
715 + * test if the branch permission is legal or not.
717 +static int test_br(struct inode *inode, int brperm, char *path)
721 + err = (au_br_writable(brperm) && IS_RDONLY(inode));
726 + pr_err("write permission for readonly mount or inode, %s\n", path);
734 + * 0: success, the caller will add it
735 + * plus: success, it is already unified, the caller should ignore it
738 +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
741 + aufs_bindex_t bend, bindex;
742 + struct dentry *root;
743 + struct inode *inode, *h_inode;
746 + bend = au_sbend(sb);
747 + if (unlikely(bend >= 0
748 + && au_find_dbindex(root, add->path.dentry) >= 0)) {
752 + pr_err("%s duplicated\n", add->pathname);
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);
765 + if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
766 + pr_err("bad index %d\n", add->bindex);
770 + inode = add->path.dentry->d_inode;
772 + if (unlikely(!inode->i_nlink)) {
773 + pr_err("no existence %s\n", add->pathname);
778 + if (unlikely(inode->i_sb == sb)) {
779 + pr_err("%s must be outside\n", add->pathname);
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));
789 + err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
794 + return 0; /* success */
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);
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",
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));
823 + * initialize or clean the whiteouts for an adding branch
825 +static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
826 + int new_perm, struct dentry *h_root)
829 + aufs_bindex_t bindex;
830 + struct mutex *h_mtx;
831 + struct au_wbr *wbr;
832 + struct au_hinode *hdir;
835 + old_perm = br->br_perm;
836 + br->br_perm = new_perm;
839 + bindex = au_br_index(sb, br->br_id);
841 + hdir = au_hi(sb->s_root->d_inode, bindex);
842 + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
844 + h_mtx = &h_root->d_inode->i_mutex;
845 + mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
848 + err = au_wh_init(h_root, br, sb);
850 + wbr_wh_write_lock(wbr);
851 + err = au_wh_init(h_root, br, sb);
852 + wbr_wh_write_unlock(wbr);
855 + au_hn_imtx_unlock(hdir);
857 + mutex_unlock(h_mtx);
858 + br->br_perm = old_perm;
860 + if (!err && wbr && !au_br_writable(new_perm)) {
868 +static int au_wbr_init(struct au_branch *br, struct super_block *sb,
869 + int perm, struct path *path)
872 + struct kstatfs kst;
873 + struct au_wbr *wbr;
874 + struct dentry *h_dentry;
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;
883 + * a limit for rmdir/rename a dir
884 + * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h
886 + err = vfs_statfs(path, &kst);
890 + h_dentry = path->dentry;
891 + if (kst.f_namelen >= NAME_MAX)
892 + err = au_br_init_wh(sb, br, perm, h_dentry);
894 + pr_err("%.*s(%s), unsupported namelen %ld\n",
895 + AuDLNPair(h_dentry), au_sbtype(h_dentry->d_sb),
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)
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);
920 + if (au_br_writable(add->perm)) {
921 + err = au_wbr_init(br, sb, add->perm, &add->path);
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);
935 + sysaufs_br_init(br);
936 + mntget(add->path.mnt);
937 + goto out; /* success */
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)
949 + struct au_branch **brp;
951 + AuRwMustWriteLock(&sbinfo->si_rwsem);
953 + brp = sbinfo->si_branch + bindex;
954 + memmove(brp + 1, brp, sizeof(*brp) * amount);
957 + if (unlikely(bend < 0))
958 + sbinfo->si_bend = 0;
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)
964 + struct au_hdentry *hdp;
966 + AuRwMustWriteLock(&dinfo->di_rwsem);
968 + hdp = dinfo->di_hdentry + bindex;
969 + memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
970 + au_h_dentry_init(hdp);
972 + if (unlikely(bend < 0))
973 + dinfo->di_bstart = 0;
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)
979 + struct au_hinode *hip;
981 + AuRwMustWriteLock(&iinfo->ii_rwsem);
983 + hip = iinfo->ii_hinode + bindex;
984 + memmove(hip + 1, hip, sizeof(*hip) * amount);
985 + hip->hi_inode = NULL;
988 + if (unlikely(bend < 0))
989 + iinfo->ii_bstart = 0;
992 +static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry,
993 + struct au_branch *br, aufs_bindex_t bindex)
995 + struct dentry *root;
996 + struct inode *root_inode;
997 + aufs_bindex_t bend, amount;
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),
1012 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
1015 + aufs_bindex_t bend, add_bindex;
1016 + struct dentry *root, *h_dentry;
1017 + struct inode *root_inode;
1018 + struct au_branch *add_branch;
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))
1028 + goto out; /* success */
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))
1037 + err = au_br_init(add_branch, sb, add);
1038 + if (unlikely(err)) {
1039 + au_br_do_free(add_branch);
1043 + add_bindex = add->bindex;
1044 + h_dentry = add->path.dentry;
1046 + au_br_do_add(sb, h_dentry, add_branch, add_bindex);
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);
1053 + if (!add_bindex) {
1054 + au_cpup_attr_all(root_inode, /*force*/1);
1055 + sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
1057 + au_add_nlink(root_inode, h_dentry->d_inode);
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.
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);
1075 +/* ---------------------------------------------------------------------- */
1081 +/* to show the line number, do not make it inlined function */
1082 +#define AuVerbose(do_info, fmt, ...) do { \
1084 + pr_info(fmt, ##__VA_ARGS__); \
1088 + * test if the branch is deletable or not.
1090 +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
1091 + unsigned int sigen, const unsigned int verbose)
1093 + int err, i, j, ndentry;
1094 + aufs_bindex_t bstart, bend;
1095 + struct au_dcsub_pages dpages;
1096 + struct au_dpage *dpage;
1098 + struct inode *inode;
1100 + err = au_dpages_init(&dpages, GFP_NOFS);
1101 + if (unlikely(err))
1103 + err = au_dcsub_pages(&dpages, root, NULL, NULL);
1104 + if (unlikely(err))
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);
1117 + di_write_lock_child(d);
1118 + err = au_reval_dpath(d, sigen);
1120 + di_downgrade_lock(d, AuLock_IR);
1122 + di_write_unlock(d);
1127 + bstart = au_dbstart(d);
1128 + bend = au_dbend(d);
1129 + if (bstart <= bindex
1131 + && au_h_dptr(d, bindex)
1132 + && (!S_ISDIR(inode->i_mode) || bstart == bend)) {
1134 + AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
1136 + di_read_unlock(d, AuLock_IR);
1141 + au_dpages_free(&dpages);
1146 +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
1147 + unsigned int sigen, const unsigned int verbose)
1151 + aufs_bindex_t bstart, bend;
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))
1159 + if (au_iigen(i) == sigen)
1160 + ii_read_lock_child(i);
1162 + ii_write_lock_child(i);
1163 + err = au_refresh_hinode_self(i, /*do_attr*/1);
1165 + ii_downgrade_lock(i);
1167 + ii_write_unlock(i);
1172 + bstart = au_ibstart(i);
1173 + bend = au_ibend(i);
1174 + if (bstart <= bindex
1176 + && au_h_iptr(i, bindex)
1177 + && (!S_ISDIR(i->i_mode) || bstart == bend)) {
1179 + AuVerbose(verbose, "busy i%lu\n", i->i_ino);
1180 + ii_read_unlock(i);
1183 + ii_read_unlock(i);
1189 +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
1190 + const unsigned int verbose)
1193 + unsigned int sigen;
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);
1201 + err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1202 + di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
1207 +static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
1208 + const aufs_bindex_t bindex,
1209 + const aufs_bindex_t bend)
1211 + struct au_branch **brp, **p;
1213 + AuRwMustWriteLock(&sbinfo->si_rwsem);
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--;
1221 + p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, GFP_NOFS);
1223 + sbinfo->si_branch = p;
1224 + /* harmless error */
1227 +static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
1228 + const aufs_bindex_t bend)
1230 + struct au_hdentry *hdp, *p;
1232 + AuRwMustWriteLock(&dinfo->di_rwsem);
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;
1241 + p = krealloc(hdp, sizeof(*p) * bend, GFP_NOFS);
1243 + dinfo->di_hdentry = p;
1244 + /* harmless error */
1247 +static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
1248 + const aufs_bindex_t bend)
1250 + struct au_hinode *hip, *p;
1252 + AuRwMustWriteLock(&iinfo->ii_rwsem);
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);
1261 + p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, GFP_NOFS);
1263 + iinfo->ii_hinode = p;
1264 + /* harmless error */
1267 +static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
1268 + struct au_branch *br)
1270 + aufs_bindex_t bend;
1271 + struct au_sbinfo *sbinfo;
1272 + struct dentry *root;
1273 + struct inode *inode;
1275 + SiMustWriteLock(sb);
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;
1283 + dput(au_h_dptr(root, bindex));
1284 + au_hiput(au_hi(inode, bindex));
1285 + au_br_do_free(br);
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);
1292 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
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;
1302 + bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
1305 + goto out; /* success */
1307 + pr_err("%s no such branch\n", del->pathname);
1310 + AuDbg("bindex b%d\n", bindex);
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");
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);
1329 + do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
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;
1339 + err = test_children_busy(sb->s_root, bindex, verbose);
1340 + if (unlikely(err)) {
1347 + br_id = br->br_id;
1349 + au_br_do_del(sb, bindex, br);
1351 + sysaufs_brs_del(sb, bindex);
1352 + au_br_do_del(sb, bindex, br);
1353 + sysaufs_brs_add(sb, bindex);
1357 + au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
1358 + sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
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);
1364 + if (au_xino_brid(sb) == br_id)
1365 + au_xino_brid_set(sb, -1);
1366 + goto out; /* success */
1370 + rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry);
1372 + pr_warning("failed re-creating base whiteout, %s. (%d)\n",
1373 + del->pathname, rerr);
1378 +/* ---------------------------------------------------------------------- */
1381 + * change a branch permission
1384 +static void au_warn_ima(void)
1387 + /* since it doesn't support mark_files_ro() */
1388 + pr_warning("RW -> RO makes IMA to produce wrong message");
1392 +static int do_need_sigen_inc(int a, int b)
1394 + return au_br_whable(a) && !au_br_whable(b);
1397 +static int need_sigen_inc(int old, int new)
1399 + return do_need_sigen_inc(old, new)
1400 + || do_need_sigen_inc(new, old);
1403 +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
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);
1414 + bytes = step_bytes;
1415 + files = step_files;
1416 + a = kmalloc(bytes, GFP_NOFS);
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))
1425 + AuDbg("%.*s\n", AuDLNPair(file->f_dentry));
1426 + fi_read_lock(file);
1427 + if (unlikely(au_test_mmapped(file))) {
1429 + FiMustNoWaiters(file);
1430 + fi_read_unlock(file);
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);
1443 + hf = au_hf_top(file);
1444 + FiMustNoWaiters(file);
1445 + fi_read_unlock(file);
1453 + bytes += step_bytes;
1454 + files += step_files;
1455 + p = krealloc(a, bytes, GFP_NOFS);
1462 + } while_file_list_for_each_entry;
1467 + for (ul = 0; ul < n; ul++) {
1468 + /* todo: already flushed? */
1469 + /* cf. fs/super.c:mark_files_ro() */
1471 + hf->f_mode &= ~FMODE_WRITE;
1472 + if (!file_check_writeable(hf)) {
1473 + file_release_write(hf);
1474 + mnt_drop_write(hf->f_vfsmnt);
1484 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
1488 + aufs_bindex_t bindex;
1490 + struct dentry *root;
1491 + struct au_branch *br;
1493 + root = sb->s_root;
1494 + au_plink_maint_block(sb);
1495 + bindex = au_find_dbindex(root, mod->h_root);
1498 + return 0; /* success */
1500 + pr_err("%s no such branch\n", mod->path);
1503 + AuDbg("bindex b%d\n", bindex);
1505 + err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
1506 + if (unlikely(err))
1509 + br = au_sbr(sb, bindex);
1510 + if (br->br_perm == mod->perm)
1511 + return 0; /* success */
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))
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);
1528 + if (unlikely(err)) {
1530 + br->br_wbr = kmalloc(sizeof(*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,
1538 + if (unlikely(rerr)) {
1539 + AuIOErr("nested error %d (%d)\n",
1541 + br->br_perm = mod->perm;
1545 + } else if (au_br_writable(mod->perm)) {
1548 + br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
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;
1561 + *do_update |= need_sigen_inc(br->br_perm, mod->perm);
1562 + br->br_perm = mod->perm;
1568 diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h
1569 new file mode 100644
1570 index 0000000..9e77476
1572 +++ b/fs/aufs/branch.h
1575 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
1593 + * branch filesystems and xino for them
1596 +#ifndef __AUFS_BRANCH_H__
1597 +#define __AUFS_BRANCH_H__
1601 +#include <linux/fs.h>
1602 +#include <linux/mount.h>
1603 +#include <linux/aufs_type.h>
1608 +/* ---------------------------------------------------------------------- */
1611 +struct au_xino_file {
1612 + struct file *xi_file;
1613 + struct mutex xi_nondir_mtx;
1615 + /* todo: make xino files an array to support huge inode number */
1617 +#ifdef CONFIG_DEBUG_FS
1618 + struct dentry *xi_dbgaufs;
1622 +/* members for writable branch only */
1623 +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
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 */
1633 + unsigned long long wbr_bytes;
1636 +/* ext2 has 3 types of operations at least, ext3 has 4 */
1637 +#define AuBrDynOp (AuDyLast * 4)
1639 +/* protected by superblock rwsem */
1641 + struct au_xino_file br_xino;
1643 + aufs_bindex_t br_id;
1646 + struct vfsmount *br_mnt;
1647 + spinlock_t br_dykey_lock;
1648 + struct au_dykey *br_dykey[AuBrDynOp];
1649 + atomic_t br_count;
1651 + struct au_wbr *br_wbr;
1653 + /* xino truncation */
1654 + blkcnt_t br_xino_upper; /* watermark in blocks */
1655 + atomic_t br_xino_running;
1657 +#ifdef CONFIG_SYSFS
1658 + /* an entry under sysfs per mount-point */
1660 + struct attribute br_attr;
1664 +/* ---------------------------------------------------------------------- */
1666 +/* branch permission and attribute */
1668 + AuBrPerm_RW, /* writable, linkable wh */
1669 + AuBrPerm_RO, /* readonly, no wh */
1670 + AuBrPerm_RR, /* natively readonly, no wh */
1672 + AuBrPerm_RWNoLinkWH, /* un-linkable whiteouts */
1674 + AuBrPerm_ROWH, /* whiteout-able */
1675 + AuBrPerm_RRWH, /* whiteout-able */
1680 +static inline int au_br_writable(int brperm)
1682 + return brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH;
1685 +static inline int au_br_whable(int brperm)
1687 + return brperm == AuBrPerm_RW
1688 + || brperm == AuBrPerm_ROWH
1689 + || brperm == AuBrPerm_RRWH;
1692 +static inline int au_br_rdonly(struct au_branch *br)
1694 + return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY)
1695 + || !au_br_writable(br->br_perm))
1699 +static inline int au_br_hnotifyable(int brperm __maybe_unused)
1701 +#ifdef CONFIG_AUFS_HNOTIFY
1702 + return brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH;
1708 +/* ---------------------------------------------------------------------- */
1712 +void au_br_free(struct au_sbinfo *sinfo);
1713 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
1715 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
1717 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
1719 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
1723 +static const loff_t au_loff_max = LLONG_MAX;
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,
1728 +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
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,
1736 +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_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);
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);
1748 +/* ---------------------------------------------------------------------- */
1750 +/* Superblock to branch */
1752 +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
1754 + return au_sbr(sb, bindex)->br_id;
1758 +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
1760 + return au_sbr(sb, bindex)->br_mnt;
1764 +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
1766 + return au_sbr_mnt(sb, bindex)->mnt_sb;
1769 +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
1771 + atomic_dec_return(&au_sbr(sb, bindex)->br_count);
1774 +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
1776 + return au_sbr(sb, bindex)->br_perm;
1779 +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
1781 + return au_br_whable(au_sbr_perm(sb, bindex));
1784 +/* ---------------------------------------------------------------------- */
1787 + * wbr_wh_read_lock, wbr_wh_write_lock
1788 + * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
1790 +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
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)
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
1802 +++ b/fs/aufs/conf.mk
1805 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
1809 +AuConfStr += ${1}=${${1}}
1813 +AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
1814 + HNOTIFY HFSNOTIFY \
1824 +$(foreach i, ${AuConfAll}, \
1825 + $(eval $(call AuConf,CONFIG_AUFS_${i})))
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 ' $@; \
1836 +clean-files += ${AuConfName} ${AuConfName}.tmp
1837 +${obj}/sysfs.o: ${AuConfName}
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
1844 +++ b/fs/aufs/cpup.c
1847 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
1865 + * copy-up functions, see wbr_policy.c for copy-down
1868 +#include <linux/file.h>
1869 +#include <linux/fs_stack.h>
1870 +#include <linux/mm.h>
1871 +#include <linux/uaccess.h>
1874 +void au_cpup_attr_flags(struct inode *dst, struct inode *src)
1876 + const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
1877 + | S_NOATIME | S_NOCMTIME;
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;
1884 +void au_cpup_attr_timesizes(struct inode *inode)
1886 + struct inode *h_inode;
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);
1893 +void au_cpup_attr_nlink(struct inode *inode, int force)
1895 + struct inode *h_inode;
1896 + struct super_block *sb;
1897 + aufs_bindex_t bindex, bend;
1900 + bindex = au_ibstart(inode);
1901 + h_inode = au_h_iptr(inode, bindex);
1903 + && !S_ISDIR(h_inode->i_mode)
1904 + && au_opt_test(au_mntflags(sb), PLINK)
1905 + && au_plink_test(inode))
1908 + inode->i_nlink = h_inode->i_nlink;
1911 + * fewer nlink makes find(1) noisy, but larger nlink doesn't.
1912 + * it may includes whplink directory.
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);
1919 + au_add_nlink(inode, h_inode);
1924 +void au_cpup_attr_changeable(struct inode *inode)
1926 + struct inode *h_inode;
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);
1936 +void au_cpup_igen(struct inode *inode, struct inode *h_inode)
1938 + struct au_iinfo *iinfo = au_ii(inode);
1940 + IiMustWriteLock(inode);
1942 + iinfo->ii_higen = h_inode->i_generation;
1943 + iinfo->ii_hsb1 = h_inode->i_sb;
1946 +void au_cpup_attr_all(struct inode *inode, int force)
1948 + struct inode *h_inode;
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);
1959 +/* ---------------------------------------------------------------------- */
1961 +/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
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)
1967 + struct inode *h_inode;
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;
1977 +void au_dtime_revert(struct au_dtime *dt)
1979 + struct iattr attr;
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;
1987 + err = vfsub_notify_change(&dt->dt_h_path, &attr);
1988 + if (unlikely(err))
1989 + pr_warning("restoring timestamps failed(%d). ignored\n", err);
1992 +/* ---------------------------------------------------------------------- */
1994 +static noinline_for_stack
1995 +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src)
1999 + struct path h_path;
2000 + struct inode *h_isrc, *h_idst;
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;
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);
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);
2032 +/* ---------------------------------------------------------------------- */
2034 +static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
2035 + char *buf, unsigned long blksize)
2038 + size_t sz, rbytes, wbytes;
2039 + unsigned char all_zero;
2041 + struct mutex *h_mtx;
2042 + /* reduce stack usage */
2045 + zp = page_address(ZERO_PAGE(0));
2046 + if (unlikely(!zp))
2047 + return -ENOMEM; /* possible? */
2052 + AuDbg("len %lld\n", len);
2054 + if (len < blksize)
2058 + /* todo: signal_pending? */
2059 + while (!rbytes || err == -EAGAIN || err == -EINTR) {
2060 + rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
2063 + if (unlikely(err < 0))
2067 + if (len >= rbytes && rbytes == blksize)
2068 + all_zero = !memcmp(buf, zp, rbytes);
2075 + b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
2077 + /* todo: signal_pending? */
2078 + if (unlikely(err == -EAGAIN || err == -EINTR))
2080 + if (unlikely(err < 0))
2089 + res = vfsub_llseek(dst, rbytes, SEEK_CUR);
2091 + if (unlikely(res < 0))
2098 + /* the last block may be a hole */
2099 + if (!err && all_zero) {
2100 + AuLabel(last hole);
2103 + if (au_test_nfs(dst->f_dentry->d_sb)) {
2104 + /* nfs requires this step to make last hole */
2105 + /* is this only nfs? */
2107 + /* todo: signal_pending? */
2108 + err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
2109 + } while (err == -EAGAIN || err == -EINTR);
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);
2129 +int au_copy_file(struct file *dst, struct file *src, loff_t len)
2132 + unsigned long blksize;
2133 + unsigned char do_kfree;
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 *));
2143 + buf = kmalloc(blksize, GFP_NOFS);
2145 + buf = (void *)__get_free_page(GFP_NOFS);
2146 + if (unlikely(!buf))
2149 + if (len > (1 << 22))
2150 + AuDbg("copying a large file %lld\n", (long long)len);
2154 + err = au_do_copy_file(dst, src, len, buf, blksize);
2158 + free_page((unsigned long)buf);
2165 + * to support a sparse file which is opened with O_APPEND,
2166 + * we need to close the file.
2168 +static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst,
2169 + aufs_bindex_t bsrc, loff_t len)
2172 + enum { SRC, DST };
2174 + aufs_bindex_t bindex;
2175 + unsigned int flags;
2176 + struct dentry *dentry;
2177 + struct file *file;
2178 + void *label, *label_file;
2182 + .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
2185 + .label_file = &&out_src
2189 + .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
2191 + .label = &&out_src,
2192 + .label_file = &&out_dst
2195 + struct super_block *sb;
2197 + /* bsrc branch can be ro/rw. */
2198 + sb = dentry->d_sb;
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))
2207 + if (unlikely(!f->file->f_op))
2208 + goto *f->label_file;
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);
2216 + fput(file[DST].file);
2217 + au_sbr_put(sb, file[DST].bindex);
2219 + fput(file[SRC].file);
2220 + au_sbr_put(sb, file[SRC].bindex);
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)
2233 + l = i_size_read(au_h_iptr(dentry->d_inode, bsrc));
2234 + if (len == -1 || l < len)
2237 + err = au_cp_regular(dentry, bdst, bsrc, len);
2239 + goto out; /* success */
2241 + rerr = vfsub_unlink(h_dir, h_path, /*force*/0);
2243 + AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n",
2244 + AuDLNPair(h_path->dentry), err, rerr);
2252 +static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
2253 + struct inode *h_dir)
2256 + mm_segment_t old_fs;
2263 + if (unlikely(!h_src->d_inode->i_op->readlink))
2267 + sym.k = __getname_gfp(GFP_NOFS);
2268 + if (unlikely(!sym.k))
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);
2278 + sym.k[symlen] = 0;
2279 + err = vfsub_symlink(h_dir, h_path, sym.k);
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)
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;
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));
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;
2314 + AuDebugOn(h_parent != h_dst->d_parent);
2316 + sb = dentry->d_sb;
2317 + h_path.mnt = au_sbr_mnt(sb, bdst);
2319 + h_path.dentry = h_parent;
2320 + au_dtime_store(&dt, dst_parent, &h_path);
2322 + h_path.dentry = h_dst;
2325 + mode = h_inode->i_mode;
2326 + switch (mode & S_IFMT) {
2328 + /* try stopping to update while we are referencing */
2329 + IMustLock(h_inode);
2330 + err = vfsub_create(h_dir, &h_path, mode | S_IWUSR);
2332 + err = au_do_cpup_regular
2333 + (dentry, bdst, bsrc, len,
2334 + au_h_iptr(dst_parent->d_inode, bdst), &h_path);
2338 + err = vfsub_mkdir(h_dir, &h_path, mode);
2341 + * strange behaviour from the users view,
2342 + * particularry setattr case
2344 + if (au_ibstart(dst_parent->d_inode) == bdst)
2345 + au_cpup_attr_nlink(dst_parent->d_inode,
2347 + au_cpup_attr_nlink(dentry->d_inode, /*force*/1);
2351 + err = au_do_cpup_symlink(&h_path, h_src, h_dir);
2355 + AuDebugOn(!capable(CAP_MKNOD));
2359 + err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
2362 + AuIOErr("Unknown inode type 0%o\n", mode);
2366 + mnt_flags = au_mntflags(sb);
2367 + if (!au_opt_test(mnt_flags, UDBA_NONE)
2369 + && au_opt_test(mnt_flags, XINO)
2370 + && h_inode->i_nlink == 1
2371 + /* todo: unnecessary? */
2372 + /* && dentry->d_inode->i_nlink == 1 */
2374 + && !au_ftest_cpup(flags, KEEPLINO))
2375 + au_xino_write(sb, bsrc, h_inode->i_ino, /*ino*/0);
2376 + /* ignore this error */
2379 + au_dtime_revert(&dt);
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.
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)
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;
2402 + AuDebugOn(bsrc <= bdst);
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;
2411 + h_src = au_h_dptr(dentry, bsrc);
2412 + inode = dentry->d_inode;
2415 + dst_parent = dget_parent(dentry);
2419 + plink = !!au_opt_test(au_mntflags(sb), PLINK);
2420 + dst_inode = au_h_iptr(inode, bdst);
2422 + if (unlikely(!plink)) {
2424 + AuIOErr("i%lu exists on a upper branch "
2425 + "but plink is disabled\n", inode->i_ino);
2429 + if (dst_inode->i_nlink) {
2430 + const int do_dt = au_ftest_cpup(flags, DTIME);
2432 + h_src = au_plink_lkup(inode, bdst);
2433 + err = PTR_ERR(h_src);
2434 + if (IS_ERR(h_src))
2436 + if (unlikely(!h_src->d_inode)) {
2438 + AuIOErr("i%lu exists on a upper branch "
2439 + "but plink is broken\n", inode->i_ino);
2445 + h_path.dentry = h_parent;
2446 + au_dtime_store(&dt, dst_parent, &h_path);
2448 + h_path.dentry = h_dst;
2449 + err = vfsub_link(h_src, h_dir, &h_path);
2451 + au_dtime_revert(&dt);
2455 + /* todo: cpup_wh_file? */
2457 + au_update_ibrange(inode, /*do_put_zero*/1);
2460 + old_ibstart = au_ibstart(inode);
2461 + err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent);
2462 + if (unlikely(err))
2464 + dst_inode = h_dst->d_inode;
2465 + mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
2467 + err = cpup_iattr(dentry, bdst, h_src);
2468 + isdir = S_ISDIR(dst_inode->i_mode);
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))
2476 + au_set_ibstart(inode, bdst);
2478 + au_set_h_iptr(inode, bdst, au_igrab(dst_inode),
2479 + au_hi_flags(inode, isdir));
2480 + mutex_unlock(&dst_inode->i_mutex);
2482 + && h_src->d_inode->i_nlink > 1
2484 + au_plink_append(inode, bdst, h_dst);
2485 + goto out; /* success */
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;
2495 + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
2497 + rerr = vfsub_rmdir(h_dir, &h_path);
2498 + au_dtime_revert(&dt);
2500 + AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
2509 +struct au_cpup_single_args {
2511 + struct dentry *dentry;
2512 + aufs_bindex_t bdst, bsrc;
2514 + unsigned int flags;
2515 + struct dentry *dst_parent;
2518 +static void au_call_cpup_single(void *args)
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);
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)
2531 + struct dentry *h_dentry;
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,
2540 + struct au_cpup_single_args args = {
2547 + .dst_parent = dst_parent
2549 + wkq_err = au_wkq_wait(au_call_cpup_single, &args);
2550 + if (unlikely(wkq_err))
2558 + * copyup the @dentry from the first active lower branch to @bdst,
2559 + * using au_cpup_single().
2561 +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2562 + unsigned int flags)
2565 + aufs_bindex_t bsrc, bend;
2567 + bend = au_dbend(dentry);
2568 + for (bsrc = bdst + 1; bsrc <= bend; bsrc++)
2569 + if (au_h_dptr(dentry, bsrc))
2572 + err = au_lkup_neg(dentry, bdst);
2574 + err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL);
2576 + return 0; /* success */
2579 + au_set_h_dptr(dentry, bdst, NULL);
2580 + au_set_dbstart(dentry, bsrc);
2586 +struct au_cpup_simple_args {
2588 + struct dentry *dentry;
2589 + aufs_bindex_t bdst;
2591 + unsigned int flags;
2594 +static void au_call_cpup_simple(void *args)
2596 + struct au_cpup_simple_args *a = args;
2597 + *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags);
2600 +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2601 + unsigned int flags)
2604 + unsigned char do_sio;
2605 + struct dentry *parent;
2606 + struct inode *h_dir;
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);
2613 + * testing CAP_MKNOD is for generic fs,
2614 + * but CAP_FSETID is for xfs only, currently.
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)));
2623 + err = au_cpup_simple(dentry, bdst, len, flags);
2625 + struct au_cpup_simple_args args = {
2632 + wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
2633 + if (unlikely(wkq_err))
2641 +/* ---------------------------------------------------------------------- */
2644 + * copyup the deleted file for writing.
2646 +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
2647 + struct dentry *wh_dentry, struct file *file,
2651 + aufs_bindex_t bstart;
2652 + struct au_dinfo *dinfo;
2653 + struct dentry *h_d_dst, *h_d_start;
2654 + struct au_hdentry *hdp;
2656 + dinfo = au_di(dentry);
2657 + AuRwMustWriteLock(&dinfo->di_rwsem);
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;
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;
2673 + hdp[0 + bdst].hd_dentry = h_d_dst;
2674 + dinfo->di_bstart = bstart;
2679 +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2680 + struct file *file)
2683 + struct au_dtime dt;
2684 + struct dentry *parent, *h_parent, *wh_dentry;
2685 + struct au_branch *br;
2686 + struct path h_path;
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))
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))
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);
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);
2714 + au_dtime_revert(&dt);
2715 + au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
2724 +struct au_cpup_wh_args {
2726 + struct dentry *dentry;
2727 + aufs_bindex_t bdst;
2729 + struct file *file;
2732 +static void au_call_cpup_wh(void *args)
2734 + struct au_cpup_wh_args *a = args;
2735 + *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file);
2738 +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
2739 + struct file *file)
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;
2746 + parent = dget_parent(dentry);
2747 + dir = parent->d_inode;
2750 + h_dir = au_igrab(au_h_iptr(dir, bdst));
2752 + if (!h_dir->i_nlink) {
2753 + wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
2754 + h_orph = wbr->wbr_orph;
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);
2761 + /* this temporary unlock is safe */
2763 + h_dentry = au_hf_top(file)->f_dentry;
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()? */
2774 + if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE))
2775 + err = au_cpup_wh(dentry, bdst, len, file);
2777 + struct au_cpup_wh_args args = {
2784 + wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
2785 + if (unlikely(wkq_err))
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);
2801 +/* ---------------------------------------------------------------------- */
2804 + * generic routine for both of copy-up and copy-down.
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),
2813 + struct au_pin pin;
2814 + struct dentry *d, *parent, *h_parent, *real_parent;
2817 + parent = dget_parent(dentry);
2818 + if (IS_ROOT(parent))
2821 + au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
2822 + au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
2824 + /* do not use au_dpage */
2825 + real_parent = parent;
2828 + parent = dget_parent(dentry);
2829 + h_parent = au_h_dptr(parent, bdst);
2831 + goto out; /* success */
2833 + /* find top dir which is necessary to cpup */
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);
2843 + if (d != real_parent)
2844 + di_write_lock_child3(d);
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);
2851 + au_pin_set_dentry(&pin, d);
2852 + err = au_do_pin(&pin);
2854 + err = cp(d, bdst, h_parent, arg);
2859 + if (d != real_parent)
2860 + di_write_unlock(d);
2861 + if (unlikely(err))
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)
2874 + return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME);
2877 +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
2879 + return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
2882 +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
2885 + struct dentry *parent;
2886 + struct inode *dir;
2888 + parent = dget_parent(dentry);
2889 + dir = parent->d_inode;
2891 + if (au_h_iptr(dir, bdst))
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);
2905 diff --git a/fs/aufs/cpup.h b/fs/aufs/cpup.h
2906 new file mode 100644
2907 index 0000000..506350d
2909 +++ b/fs/aufs/cpup.h
2912 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
2930 + * copy-up/down functions
2933 +#ifndef __AUFS_CPUP_H__
2934 +#define __AUFS_CPUP_H__
2938 +#include <linux/path.h>
2939 +#include <linux/time.h>
2940 +#include <linux/aufs_type.h>
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);
2952 +/* ---------------------------------------------------------------------- */
2955 +#define AuCpup_DTIME 1 /* do dtime_store/revert */
2956 +#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
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; }
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);
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),
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);
2978 +/* ---------------------------------------------------------------------- */
2980 +/* keep timestamps when copyup */
2982 + struct dentry *dt_dentry;
2983 + struct path dt_h_path;
2984 + struct timespec dt_atime, dt_mtime;
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);
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
2996 +++ b/fs/aufs/dbgaufs.c
2999 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
3017 + * debugfs interface
3020 +#include <linux/debugfs.h>
3023 +#ifndef CONFIG_SYSFS
3024 +#error DEBUG_FS depends upon SYSFS
3027 +static struct dentry *dbgaufs;
3028 +static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
3030 +/* 20 is max digits length of ulong 64 */
3031 +struct dbgaufs_arg {
3037 + * common function for all XINO files
3039 +static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
3040 + struct file *file)
3042 + kfree(file->private_data);
3046 +static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
3050 + struct dbgaufs_arg *p;
3053 + p = kmalloc(sizeof(*p), GFP_NOFS);
3059 + file->private_data = p;
3063 + err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st);
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);
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));
3076 + p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
3085 +static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
3086 + size_t count, loff_t *ppos)
3088 + struct dbgaufs_arg *p;
3090 + p = file->private_data;
3091 + return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
3094 +/* ---------------------------------------------------------------------- */
3096 +static int dbgaufs_xib_open(struct inode *inode, struct file *file)
3099 + struct au_sbinfo *sbinfo;
3100 + struct super_block *sb;
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);
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
3117 +/* ---------------------------------------------------------------------- */
3119 +#define DbgaufsXi_PREFIX "xi"
3121 +static int dbgaufs_xino_open(struct inode *inode, struct file *file)
3125 + struct au_sbinfo *sbinfo;
3126 + struct super_block *sb;
3128 + struct qstr *name;
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)))
3137 + err = strict_strtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
3138 + if (unlikely(err))
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);
3149 + si_read_unlock(sb);
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
3162 +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
3164 + aufs_bindex_t bend;
3165 + struct au_branch *br;
3166 + struct au_xino_file *xi;
3168 + if (!au_sbi(sb)->si_dbgaufs)
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;
3182 +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
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 */
3191 + sbinfo = au_sbi(sb);
3192 + parent = sbinfo->si_dbgaufs;
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);
3210 +/* ---------------------------------------------------------------------- */
3212 +#ifdef CONFIG_AUFS_EXPORT
3213 +static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
3216 + struct au_sbinfo *sbinfo;
3217 + struct super_block *sb;
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);
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
3234 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
3239 + * This function is a dynamic '__init' fucntion actually,
3240 + * so the tiny check for si_rwsem is unnecessary.
3242 + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
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)
3254 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
3258 +#endif /* CONFIG_AUFS_EXPORT */
3260 +/* ---------------------------------------------------------------------- */
3262 +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
3265 + * This function is a dynamic '__init' fucntion actually,
3266 + * so the tiny check for si_rwsem is unnecessary.
3268 + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
3270 + debugfs_remove_recursive(sbinfo->si_dbgaufs);
3271 + sbinfo->si_dbgaufs = NULL;
3272 + kobject_put(&sbinfo->si_kobj);
3275 +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
3278 + char name[SysaufsSiNameLen];
3281 + * This function is a dynamic '__init' fucntion actually,
3282 + * so the tiny check for si_rwsem is unnecessary.
3284 + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
3288 + AuErr1("/debug/aufs is uninitialized\n");
3293 + sysaufs_name(sbinfo, name);
3294 + sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
3295 + if (unlikely(!sbinfo->si_dbgaufs))
3297 + kobject_get(&sbinfo->si_kobj);
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))
3305 + err = dbgaufs_xigen_init(sbinfo);
3307 + goto out; /* success */
3310 + dbgaufs_si_fin(sbinfo);
3315 +/* ---------------------------------------------------------------------- */
3317 +void dbgaufs_fin(void)
3319 + debugfs_remove(dbgaufs);
3322 +int __init dbgaufs_init(void)
3327 + dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
3332 diff --git a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h
3333 new file mode 100644
3334 index 0000000..ae41480
3336 +++ b/fs/aufs/dbgaufs.h
3339 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
3357 + * debugfs interface
3360 +#ifndef __DBGAUFS_H__
3361 +#define __DBGAUFS_H__
3365 +#include <linux/init.h>
3366 +#include <linux/aufs_type.h>
3368 +struct super_block;
3371 +#ifdef CONFIG_DEBUG_FS
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);
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 */
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
3394 +++ b/fs/aufs/dcsub.c
3397 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
3415 + * sub-routines for dentry cache
3420 +static void au_dpage_free(struct au_dpage *dpage)
3423 + struct dentry **p;
3425 + p = dpage->dentries;
3426 + for (i = 0; i < dpage->ndentry; i++)
3428 + free_page((unsigned long)dpage->dentries);
3431 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
3437 + dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
3438 + if (unlikely(!dpages->dpages))
3441 + p = (void *)__get_free_page(gfp);
3445 + dpages->dpages[0].ndentry = 0;
3446 + dpages->dpages[0].dentries = p;
3447 + dpages->ndpage = 1;
3448 + return 0; /* success */
3451 + kfree(dpages->dpages);
3456 +void au_dpages_free(struct au_dcsub_pages *dpages)
3459 + struct au_dpage *p;
3461 + p = dpages->dpages;
3462 + for (i = 0; i < dpages->ndpage; i++)
3463 + au_dpage_free(p++);
3464 + kfree(dpages->dpages);
3467 +static int au_dpages_append(struct au_dcsub_pages *dpages,
3468 + struct dentry *dentry, gfp_t gfp)
3471 + struct au_dpage *dpage;
3474 + dpage = dpages->dpages + dpages->ndpage - 1;
3475 + sz = PAGE_SIZE / sizeof(dentry);
3476 + if (unlikely(dpage->ndentry >= sz)) {
3477 + AuLabel(new dpage);
3479 + sz = dpages->ndpage * sizeof(*dpages->dpages);
3480 + p = au_kzrealloc(dpages->dpages, sz,
3481 + sz + sizeof(*dpages->dpages), gfp);
3485 + dpages->dpages = p;
3486 + dpage = dpages->dpages + dpages->ndpage;
3487 + p = (void *)__get_free_page(gfp);
3491 + dpage->ndentry = 0;
3492 + dpage->dentries = p;
3496 + dpage->dentries[dpage->ndentry++] = dget(dentry);
3497 + return 0; /* success */
3503 +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
3504 + au_dpages_test test, void *arg)
3507 + struct dentry *this_parent = root;
3508 + struct list_head *next;
3509 + struct super_block *sb = root->d_sb;
3512 + spin_lock(&dcache_lock);
3514 + next = this_parent->d_subdirs.next;
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))
3526 + while (next != &this_parent->d_subdirs) {
3527 + struct list_head *tmp = next;
3528 + struct dentry *dentry = list_entry(tmp, struct dentry,
3531 + if (/*d_unhashed(dentry) || */!dentry->d_inode)
3533 + if (!list_empty(&dentry->d_subdirs)) {
3534 + this_parent = dentry;
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))
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 */
3552 + spin_unlock(&dcache_lock);
3556 +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
3557 + int do_include, au_dpages_test test, void *arg)
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))
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))
3578 + spin_unlock(&dcache_lock);
3583 +int au_test_subdir(struct dentry *d1, struct dentry *d2)
3585 + struct path path[2] = {
3594 + return path_is_under(path + 0, path + 1);
3596 diff --git a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h
3597 new file mode 100644
3598 index 0000000..0c87168
3600 +++ b/fs/aufs/dcsub.h
3603 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
3621 + * sub-routines for dentry cache
3624 +#ifndef __AUFS_DCSUB_H__
3625 +#define __AUFS_DCSUB_H__
3629 +#include <linux/types.h>
3635 + struct dentry **dentries;
3638 +struct au_dcsub_pages {
3640 + struct au_dpage *dpages;
3643 +/* ---------------------------------------------------------------------- */
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);
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
3660 +++ b/fs/aufs/debug.c
3663 + * Copyright (C) 2005-2010 Junjiro R. Okajima
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.
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.
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
3681 + * debug print functions
3684 +#include <linux/module.h>
3685 +/*#include <linux/vt_kern.h>*/
3689 +MODULE_PARM_DESC(debug, "debug print");
3690 +module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
3692 +char *au_plevel = KERN_DEBUG;
3693 +#define dpri(fmt, ...) do { \
3694 + if (au_debug_test()) \
3695 + printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
3698 +/* ---------------------------------------------------------------------- */
3700 +void au_dpri_whlist(struct au_nhash *whlist)
3702 + unsigned long ul, n;
3703 + struct hlist_head *head;
3704 + struct au_vdir_wh *tpos;
3705 + struct hlist_node *pos;
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",
3713 + tpos->wh_str.len, tpos->wh_str.name,
3714 + tpos->wh_str.len);
3719 +void au_dpri_vdir(struct au_vdir *vdir)
3722 + union au_vdir_deblk_p p;
3725 + if (!vdir || IS_ERR(vdir)) {
3726 + dpri("err %ld\n", PTR_ERR(vdir));
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];
3736 + dpri("[%lu]: %p\n", ul, o);
3740 +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode,
3741 + struct dentry *wh)
3746 + if (!inode || IS_ERR(inode)) {
3747 + dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
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));
3755 + n = (void *)wh->d_name.name;
3756 + l = wh->d_name.len;
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",
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);
3773 +void au_dpri_inode(struct inode *inode)
3775 + struct au_iinfo *iinfo;
3776 + aufs_bindex_t bindex;
3779 + err = do_pri_inode(-1, inode, NULL);
3780 + if (err || !au_test_aufs(inode->i_sb))
3783 + iinfo = au_ii(inode);
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)
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);
3795 +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
3797 + struct dentry *wh = NULL;
3799 + if (!dentry || IS_ERR(dentry)) {
3800 + dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
3803 + /* do not call dget_parent() here */
3804 + dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
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);
3812 + wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
3814 + do_pri_inode(bindex, dentry->d_inode, wh);