3 diff --git a/fs/Kconfig b/fs/Kconfig
4 index c229f82..397b473 100644
7 @@ -212,6 +212,7 @@ source "fs/ufs/Kconfig"
8 source "fs/exofs/Kconfig"
9 source "fs/f2fs/Kconfig"
10 source "fs/efivarfs/Kconfig"
11 +source "fs/aufs/Kconfig"
13 endif # MISC_FILESYSTEMS
15 diff --git a/fs/Makefile b/fs/Makefile
16 index 4fe6df3..4a57676 100644
19 @@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules
20 obj-$(CONFIG_CEPH_FS) += ceph/
21 obj-$(CONFIG_PSTORE) += pstore/
22 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
23 +obj-$(CONFIG_AUFS_FS) += aufs/
24 diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
25 index bdc6e87..349600c 100644
26 --- a/include/uapi/linux/Kbuild
27 +++ b/include/uapi/linux/Kbuild
28 @@ -56,6 +56,7 @@ header-y += atmppp.h
32 +header-y += aufs_type.h
34 header-y += auto_fs4.h
38 diff --git a/fs/file_table.c b/fs/file_table.c
39 index 485dc0e..8db8096 100644
42 @@ -36,7 +36,7 @@ struct files_stat_struct files_stat = {
46 -DEFINE_STATIC_LGLOCK(files_lglock);
47 +DEFINE_LGLOCK(files_lglock);
49 /* SLAB cache for file structures */
50 static struct kmem_cache *filp_cachep __read_mostly;
51 diff --git a/fs/inode.c b/fs/inode.c
52 index 00d5fc3..f324521 100644
55 @@ -1498,7 +1498,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
56 * This does the actual work of updating an inodes time or version. Must have
57 * had called mnt_want_write() before calling this.
59 -static int update_time(struct inode *inode, struct timespec *time, int flags)
60 +int update_time(struct inode *inode, struct timespec *time, int flags)
62 if (inode->i_op->update_time)
63 return inode->i_op->update_time(inode, time, flags);
64 diff --git a/fs/splice.c b/fs/splice.c
65 index d37431d..987346f 100644
68 @@ -1093,8 +1093,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
70 * Attempt to initiate a splice from pipe to file.
72 -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
73 - loff_t *ppos, size_t len, unsigned int flags)
74 +long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
75 + loff_t *ppos, size_t len, unsigned int flags)
77 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
78 loff_t *, size_t, unsigned int);
79 @@ -1124,9 +1124,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
81 * Attempt to initiate a splice from a file to a pipe.
83 -static long do_splice_to(struct file *in, loff_t *ppos,
84 - struct pipe_inode_info *pipe, size_t len,
86 +long do_splice_to(struct file *in, loff_t *ppos,
87 + struct pipe_inode_info *pipe, size_t len,
90 ssize_t (*splice_read)(struct file *, loff_t *,
91 struct pipe_inode_info *, size_t, unsigned int);
92 diff --git a/include/linux/fs.h b/include/linux/fs.h
93 index 65c2be2..0148214 100644
94 --- a/include/linux/fs.h
95 +++ b/include/linux/fs.h
96 @@ -2574,6 +2574,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
97 extern int inode_newsize_ok(const struct inode *, loff_t offset);
98 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
100 +extern int update_time(struct inode *, struct timespec *, int);
101 extern int file_update_time(struct file *file);
103 extern int generic_show_options(struct seq_file *m, struct dentry *root);
104 diff --git a/include/linux/splice.h b/include/linux/splice.h
105 index 74575cb..bfc6fb6 100644
106 --- a/include/linux/splice.h
107 +++ b/include/linux/splice.h
108 @@ -92,4 +92,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
109 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
111 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
113 +extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
114 + loff_t *ppos, size_t len, unsigned int flags);
115 +extern long do_splice_to(struct file *in, loff_t *ppos,
116 + struct pipe_inode_info *pipe, size_t len,
117 + unsigned int flags);
119 aufs3.10 standalone patch
121 diff --git a/fs/file_table.c b/fs/file_table.c
122 index 8db8096..e271e28 100644
123 --- a/fs/file_table.c
124 +++ b/fs/file_table.c
125 @@ -37,6 +37,7 @@ struct files_stat_struct files_stat = {
128 DEFINE_LGLOCK(files_lglock);
129 +EXPORT_SYMBOL(files_lglock);
131 /* SLAB cache for file structures */
132 static struct kmem_cache *filp_cachep __read_mostly;
133 @@ -405,6 +406,8 @@ void file_sb_list_del(struct file *file)
137 +EXPORT_SYMBOL(file_sb_list_del);
142 diff --git a/fs/inode.c b/fs/inode.c
143 index f324521..bff7670 100644
146 @@ -56,6 +56,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
147 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
149 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
150 +EXPORT_SYMBOL(inode_sb_list_lock);
153 * Empty aops. Can be used for the cases where the user does not
154 @@ -1514,6 +1515,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
155 mark_inode_dirty_sync(inode);
158 +EXPORT_SYMBOL(update_time);
161 * touch_atime - update the access time
162 diff --git a/fs/namespace.c b/fs/namespace.c
163 index 7b1ca9b..51db6ad 100644
166 @@ -54,6 +54,7 @@ EXPORT_SYMBOL_GPL(fs_kobj);
167 * tree or hash is modified or when a vfsmount structure is modified.
169 DEFINE_BRLOCK(vfsmount_lock);
170 +EXPORT_SYMBOL(vfsmount_lock);
172 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
174 @@ -427,6 +428,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
175 mnt_dec_writers(real_mount(mnt));
178 +EXPORT_SYMBOL_GPL(__mnt_drop_write);
181 * mnt_drop_write - give up write access to a mount
182 @@ -1456,6 +1458,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
186 +EXPORT_SYMBOL(iterate_mounts);
188 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
190 diff --git a/fs/notify/group.c b/fs/notify/group.c
191 index bd2625b..2ff2a0f 100644
192 --- a/fs/notify/group.c
193 +++ b/fs/notify/group.c
195 #include <linux/srcu.h>
196 #include <linux/rculist.h>
197 #include <linux/wait.h>
198 +#include <linux/module.h>
200 #include <linux/fsnotify_backend.h>
201 #include "fsnotify.h"
202 @@ -65,6 +66,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
204 atomic_inc(&group->refcnt);
206 +EXPORT_SYMBOL(fsnotify_get_group);
209 * Drop a reference to a group. Free it if it's through.
210 @@ -74,6 +76,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
211 if (atomic_dec_and_test(&group->refcnt))
212 fsnotify_final_destroy_group(group);
214 +EXPORT_SYMBOL(fsnotify_put_group);
217 * Create a new fsnotify_group and hold a reference for the group returned.
218 @@ -102,6 +105,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
222 +EXPORT_SYMBOL(fsnotify_alloc_group);
224 int fsnotify_fasync(int fd, struct file *file, int on)
226 diff --git a/fs/notify/mark.c b/fs/notify/mark.c
227 index fc6b49b..a6bb87d 100644
228 --- a/fs/notify/mark.c
229 +++ b/fs/notify/mark.c
230 @@ -115,6 +115,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
231 mark->free_mark(mark);
234 +EXPORT_SYMBOL(fsnotify_put_mark);
237 * Any time a mark is getting freed we end up here.
238 @@ -197,6 +198,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
239 fsnotify_destroy_mark_locked(mark, group);
240 mutex_unlock(&group->mark_mutex);
242 +EXPORT_SYMBOL(fsnotify_destroy_mark);
244 void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
246 @@ -281,6 +283,7 @@ err:
250 +EXPORT_SYMBOL(fsnotify_add_mark);
252 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
253 struct inode *inode, struct vfsmount *mnt, int allow_dups)
254 @@ -342,6 +345,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
255 atomic_set(&mark->refcnt, 1);
256 mark->free_mark = free_mark;
258 +EXPORT_SYMBOL(fsnotify_init_mark);
260 static int fsnotify_mark_destroy(void *ignored)
262 diff --git a/fs/open.c b/fs/open.c
263 index 8c74100..be563cd 100644
266 @@ -61,6 +61,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
267 mutex_unlock(&dentry->d_inode->i_mutex);
270 +EXPORT_SYMBOL(do_truncate);
272 long vfs_truncate(struct path *path, loff_t length)
274 diff --git a/fs/splice.c b/fs/splice.c
275 index 987346f..8d6a045 100644
278 @@ -1120,6 +1120,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
282 +EXPORT_SYMBOL(do_splice_from);
285 * Attempt to initiate a splice from a file to a pipe.
286 @@ -1146,6 +1147,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
288 return splice_read(in, ppos, pipe, len, flags);
290 +EXPORT_SYMBOL(do_splice_to);
293 * splice_direct_to_actor - splices data directly between two non-pipes
294 diff --git a/security/commoncap.c b/security/commoncap.c
295 index c44b6fe..d78b003 100644
296 --- a/security/commoncap.c
297 +++ b/security/commoncap.c
298 @@ -988,9 +988,11 @@ int cap_mmap_addr(unsigned long addr)
302 +EXPORT_SYMBOL(cap_mmap_addr);
304 int cap_mmap_file(struct file *file, unsigned long reqprot,
305 unsigned long prot, unsigned long flags)
309 +EXPORT_SYMBOL(cap_mmap_file);
310 diff --git a/security/device_cgroup.c b/security/device_cgroup.c
311 index dd0dc57..9760ecb6 100644
312 --- a/security/device_cgroup.c
313 +++ b/security/device_cgroup.c
315 #include <linux/device_cgroup.h>
316 #include <linux/cgroup.h>
317 #include <linux/ctype.h>
318 +#include <linux/export.h>
319 #include <linux/list.h>
320 #include <linux/uaccess.h>
321 #include <linux/seq_file.h>
322 @@ -789,6 +790,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
323 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
326 +EXPORT_SYMBOL(__devcgroup_inode_permission);
328 int devcgroup_inode_mknod(int mode, dev_t dev)
330 diff --git a/security/security.c b/security/security.c
331 index a3dce87..06a6ea6 100644
332 --- a/security/security.c
333 +++ b/security/security.c
334 @@ -396,6 +396,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
336 return security_ops->path_rmdir(dir, dentry);
338 +EXPORT_SYMBOL(security_path_rmdir);
340 int security_path_unlink(struct path *dir, struct dentry *dentry)
342 @@ -412,6 +413,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
344 return security_ops->path_symlink(dir, dentry, old_name);
346 +EXPORT_SYMBOL(security_path_symlink);
348 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
349 struct dentry *new_dentry)
350 @@ -420,6 +422,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
352 return security_ops->path_link(old_dentry, new_dir, new_dentry);
354 +EXPORT_SYMBOL(security_path_link);
356 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
357 struct path *new_dir, struct dentry *new_dentry)
358 @@ -438,6 +441,7 @@ int security_path_truncate(struct path *path)
360 return security_ops->path_truncate(path);
362 +EXPORT_SYMBOL(security_path_truncate);
364 int security_path_chmod(struct path *path, umode_t mode)
366 @@ -445,6 +449,7 @@ int security_path_chmod(struct path *path, umode_t mode)
368 return security_ops->path_chmod(path, mode);
370 +EXPORT_SYMBOL(security_path_chmod);
372 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
374 @@ -452,6 +457,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
376 return security_ops->path_chown(path, uid, gid);
378 +EXPORT_SYMBOL(security_path_chown);
380 int security_path_chroot(struct path *path)
382 @@ -528,6 +534,7 @@ int security_inode_readlink(struct dentry *dentry)
384 return security_ops->inode_readlink(dentry);
386 +EXPORT_SYMBOL(security_inode_readlink);
388 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
390 @@ -542,6 +549,7 @@ int security_inode_permission(struct inode *inode, int mask)
392 return security_ops->inode_permission(inode, mask);
394 +EXPORT_SYMBOL(security_inode_permission);
396 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
398 @@ -663,6 +671,7 @@ int security_file_permission(struct file *file, int mask)
400 return fsnotify_perm(file, mask);
402 +EXPORT_SYMBOL(security_file_permission);
404 int security_file_alloc(struct file *file)
406 @@ -723,6 +732,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
408 return ima_file_mmap(file, prot);
410 +EXPORT_SYMBOL(security_mmap_file);
412 int security_mmap_addr(unsigned long addr)
414 diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
415 --- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
416 +++ linux/Documentation/ABI/testing/debugfs-aufs 2013-07-06 13:20:47.716863966 +0200
418 +What: /debug/aufs/si_<id>/
420 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
422 + Under /debug/aufs, a directory named si_<id> is created
423 + per aufs mount, where <id> is a unique id generated
426 +What: /debug/aufs/si_<id>/plink
428 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
430 + It has three lines and shows the information about the
431 + pseudo-link. The first line is a single number
432 + representing a number of buckets. The second line is a
433 + number of pseudo-links per buckets (separated by a
434 + blank). The last line is a single number representing a
435 + total number of psedo-links.
436 + When the aufs mount option 'noplink' is specified, it
437 + will show "1\n0\n0\n".
439 +What: /debug/aufs/si_<id>/xib
441 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
443 + It shows the consumed blocks by xib (External Inode Number
444 + Bitmap), its block size and file size.
445 + When the aufs mount option 'noxino' is specified, it
446 + will be empty. About XINO files, see the aufs manual.
448 +What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
450 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
452 + It shows the consumed blocks by xino (External Inode Number
453 + Translation Table), its link count, block size and file
455 + When the aufs mount option 'noxino' is specified, it
456 + will be empty. About XINO files, see the aufs manual.
458 +What: /debug/aufs/si_<id>/xigen
460 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
462 + It shows the consumed blocks by xigen (External Inode
463 + Generation Table), its block size and file size.
464 + If CONFIG_AUFS_EXPORT is disabled, this entry will not
466 + When the aufs mount option 'noxino' is specified, it
467 + will be empty. About XINO files, see the aufs manual.
468 diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
469 --- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
470 +++ linux/Documentation/ABI/testing/sysfs-aufs 2013-07-06 13:20:47.730197761 +0200
472 +What: /sys/fs/aufs/si_<id>/
474 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
476 + Under /sys/fs/aufs, a directory named si_<id> is created
477 + per aufs mount, where <id> is a unique id generated
480 +What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
482 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
484 + It shows the abolute path of a member directory (which
485 + is called branch) in aufs, and its permission.
487 +What: /sys/fs/aufs/si_<id>/xi_path
489 +Contact: J. R. Okajima <hooanon05@yahoo.co.jp>
491 + It shows the abolute path of XINO (External Inode Number
492 + Bitmap, Translation Table and Generation Table) file
493 + even if it is the default path.
494 + When the aufs mount option 'noxino' is specified, it
495 + will be empty. About XINO files, see the aufs manual.
496 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
497 --- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
498 +++ linux/Documentation/filesystems/aufs/design/01intro.txt 2013-07-06 13:20:47.730197761 +0200
501 +# Copyright (C) 2005-2013 Junjiro R. Okajima
503 +# This program is free software; you can redistribute it and/or modify
504 +# it under the terms of the GNU General Public License as published by
505 +# the Free Software Foundation; either version 2 of the License, or
506 +# (at your option) any later version.
508 +# This program is distributed in the hope that it will be useful,
509 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
510 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
511 +# GNU General Public License for more details.
513 +# You should have received a copy of the GNU General Public License
514 +# along with this program; if not, write to the Free Software
515 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
518 +----------------------------------------
520 +aufs [ei ju: ef es] | [a u f s]
521 +1. abbrev. for "advanced multi-layered unification filesystem".
522 +2. abbrev. for "another unionfs".
523 +3. abbrev. for "auf das" in German which means "on the" in English.
524 + Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
525 + But "Filesystem aufs Filesystem" is hard to understand.
527 +AUFS is a filesystem with features:
528 +- multi layered stackable unification filesystem, the member directory
529 + is called as a branch.
530 +- branch permission and attribute, 'readonly', 'real-readonly',
531 + 'readwrite', 'whiteout-able', 'link-able whiteout' and their
533 +- internal "file copy-on-write".
534 +- logical deletion, whiteout.
535 +- dynamic branch manipulation, adding, deleting and changing permission.
536 +- allow bypassing aufs, user's direct branch access.
537 +- external inode number translation table and bitmap which maintains the
538 + persistent aufs inode number.
539 +- seekable directory, including NFS readdir.
540 +- file mapping, mmap and sharing pages.
541 +- pseudo-link, hardlink over branches.
542 +- loopback mounted filesystem as a branch.
543 +- several policies to select one among multiple writable branches.
544 +- revert a single systemcall when an error occurs in aufs.
548 +Multi Layered Stackable Unification Filesystem
549 +----------------------------------------------------------------------
550 +Most people already knows what it is.
551 +It is a filesystem which unifies several directories and provides a
552 +merged single directory. When users access a file, the access will be
553 +passed/re-directed/converted (sorry, I am not sure which English word is
554 +correct) to the real file on the member filesystem. The member
555 +filesystem is called 'lower filesystem' or 'branch' and has a mode
556 +'readonly' and 'readwrite.' And the deletion for a file on the lower
557 +readonly branch is handled by creating 'whiteout' on the upper writable
560 +On LKML, there have been discussions about UnionMount (Jan Blunck,
561 +Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
562 +different approaches to implement the merged-view.
563 +The former tries putting it into VFS, and the latter implements as a
564 +separate filesystem.
565 +(If I misunderstand about these implementations, please let me know and
566 +I shall correct it. Because it is a long time ago when I read their
567 +source files last time).
569 +UnionMount's approach will be able to small, but may be hard to share
570 +branches between several UnionMount since the whiteout in it is
571 +implemented in the inode on branch filesystem and always
572 +shared. According to Bharata's post, readdir does not seems to be
574 +There are several missing features known in this implementations such as
575 +- for users, the inode number may change silently. eg. copy-up.
576 +- link(2) may break by copy-up.
577 +- read(2) may get an obsoleted filedata (fstat(2) too).
578 +- fcntl(F_SETLK) may be broken by copy-up.
579 +- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
582 +Unionfs has a longer history. When I started implementing a stacking filesystem
583 +(Aug 2005), it already existed. It has virtual super_block, inode,
584 +dentry and file objects and they have an array pointing lower same kind
585 +objects. After contributing many patches for Unionfs, I re-started my
586 +project AUFS (Jun 2006).
588 +In AUFS, the structure of filesystem resembles to Unionfs, but I
589 +implemented my own ideas, approaches and enhancements and it became
590 +totally different one.
592 +Comparing DM snapshot and fs based implementation
593 +- the number of bytes to be copied between devices is much smaller.
594 +- the type of filesystem must be one and only.
595 +- the fs must be writable, no readonly fs, even for the lower original
596 + device. so the compression fs will not be usable. but if we use
597 + loopback mount, we may address this issue.
599 + mount /cdrom/squashfs.img /sq
600 + losetup /sq/ext2.img
601 + losetup /somewhere/cow
602 + dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
603 +- it will be difficult (or needs more operations) to extract the
604 + difference between the original device and COW.
605 +- DM snapshot-merge may help a lot when users try merging. in the
606 + fs-layer union, users will use rsync(1).
609 +Several characters/aspects of aufs
610 +----------------------------------------------------------------------
612 +Aufs has several characters or aspects.
613 +1. a filesystem, callee of VFS helper
614 +2. sub-VFS, caller of VFS helper for branches
615 +3. a virtual filesystem which maintains persistent inode number
616 +4. reader/writer of files on branches such like an application
618 +1. Callee of VFS Helper
619 +As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
620 +unlink(2) from an application reaches sys_unlink() kernel function and
621 +then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
622 +calls filesystem specific unlink operation. Actually aufs implements the
623 +unlink operation but it behaves like a redirector.
625 +2. Caller of VFS Helper for Branches
626 +aufs_unlink() passes the unlink request to the branch filesystem as if
627 +it were called from VFS. So the called unlink operation of the branch
628 +filesystem acts as usual. As a caller of VFS helper, aufs should handle
629 +every necessary pre/post operation for the branch filesystem.
630 +- acquire the lock for the parent dir on a branch
631 +- lookup in a branch
632 +- revalidate dentry on a branch
633 +- mnt_want_write() for a branch
634 +- vfs_unlink() for a branch
635 +- mnt_drop_write() for a branch
636 +- release the lock on a branch
638 +3. Persistent Inode Number
639 +One of the most important issue for a filesystem is to maintain inode
640 +numbers. This is particularly important to support exporting a
641 +filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
642 +backend block device for its own. But some storage is necessary to
643 +maintain inode number. It may be a large space and may not suit to keep
644 +in memory. Aufs rents some space from its first writable branch
645 +filesystem (by default) and creates file(s) on it. These files are
646 +created by aufs internally and removed soon (currently) keeping opened.
647 +Note: Because these files are removed, they are totally gone after
648 + unmounting aufs. It means the inode numbers are not persistent
649 + across unmount or reboot. I have a plan to make them really
650 + persistent which will be important for aufs on NFS server.
652 +4. Read/Write Files Internally (copy-on-write)
653 +Because a branch can be readonly, when you write a file on it, aufs will
654 +"copy-up" it to the upper writable branch internally. And then write the
655 +originally requested thing to the file. Generally kernel doesn't
656 +open/read/write file actively. In aufs, even a single write may cause a
657 +internal "file copy". This behaviour is very similar to cp(1) command.
659 +Some people may think it is better to pass such work to user space
660 +helper, instead of doing in kernel space. Actually I am still thinking
661 +about it. But currently I have implemented it in kernel space.
662 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
663 --- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
664 +++ linux/Documentation/filesystems/aufs/design/02struct.txt 2013-07-06 13:20:47.730197761 +0200
667 +# Copyright (C) 2005-2013 Junjiro R. Okajima
669 +# This program is free software; you can redistribute it and/or modify
670 +# it under the terms of the GNU General Public License as published by
671 +# the Free Software Foundation; either version 2 of the License, or
672 +# (at your option) any later version.
674 +# This program is distributed in the hope that it will be useful,
675 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
676 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
677 +# GNU General Public License for more details.
679 +# You should have received a copy of the GNU General Public License
680 +# along with this program; if not, write to the Free Software
681 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
683 +Basic Aufs Internal Structure
685 +Superblock/Inode/Dentry/File Objects
686 +----------------------------------------------------------------------
687 +As like an ordinary filesystem, aufs has its own
688 +superblock/inode/dentry/file objects. All these objects have a
689 +dynamically allocated array and store the same kind of pointers to the
690 +lower filesystem, branch.
691 +For example, when you build a union with one readwrite branch and one
692 +readonly, mounted /au, /rw and /ro respectively.
694 +- /ro/fileA exists but /rw/fileA
696 +Aufs lookup operation finds /ro/fileA and gets dentry for that. These
697 +pointers are stored in a aufs dentry. The array in aufs dentry will be,
701 +This style of an array is essentially same to the aufs
702 +superblock/inode/dentry/file objects.
704 +Because aufs supports manipulating branches, ie. add/delete/change
705 +dynamically, these objects has its own generation. When branches are
706 +changed, the generation in aufs superblock is incremented. And a
707 +generation in other object are compared when it is accessed.
708 +When a generation in other objects are obsoleted, aufs refreshes the
713 +----------------------------------------------------------------------
714 +Additionally aufs superblock has some data for policies to select one
715 +among multiple writable branches, XIB files, pseudo-links and kobject.
716 +See below in detail.
717 +About the policies which supports copy-down a directory, see policy.txt
721 +Branch and XINO(External Inode Number Translation Table)
722 +----------------------------------------------------------------------
723 +Every branch has its own xino (external inode number translation table)
724 +file. The xino file is created and unlinked by aufs internally. When two
725 +members of a union exist on the same filesystem, they share the single
727 +The struct of a xino file is simple, just a sequence of aufs inode
728 +numbers which is indexed by the lower inode number.
729 +In the above sample, assume the inode number of /ro/fileA is i111 and
730 +aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
731 +4(8) bytes at 111 * 4(8) bytes offset in the xino file.
733 +When the inode numbers are not contiguous, the xino file will be sparse
734 +which has a hole in it and doesn't consume as much disk space as it
735 +might appear. If your branch filesystem consumes disk space for such
736 +holes, then you should specify 'xino=' option at mounting aufs.
738 +Also a writable branch has three kinds of "whiteout bases". All these
739 +are existed when the branch is joined to aufs and the names are
740 +whiteout-ed doubly, so that users will never see their names in aufs
742 +1. a regular file which will be linked to all whiteouts.
743 +2. a directory to store a pseudo-link.
744 +3. a directory to store an "orphan-ed" file temporary.
747 + When you remove a file on a readonly branch, aufs handles it as a
748 + logical deletion and creates a whiteout on the upper writable branch
749 + as a hardlink of this file in order not to consume inode on the
752 + See below, Pseudo-link.
754 + When "fileC" exists on the lower readonly branch only and it is
755 + opened and removed with its parent dir, and then user writes
756 + something into it, then aufs copies-up fileC to this
757 + directory. Because there is no other dir to store fileC. After
758 + creating a file under this dir, the file is unlinked.
760 +Because aufs supports manipulating branches, ie. add/delete/change
761 +dynamically, a branch has its own id. When the branch order changes, aufs
762 +finds the new index by searching the branch id.
766 +----------------------------------------------------------------------
767 +Assume "fileA" exists on the lower readonly branch only and it is
768 +hardlinked to "fileB" on the branch. When you write something to fileA,
769 +aufs copies-up it to the upper writable branch. Additionally aufs
770 +creates a hardlink under the Pseudo-link Directory of the writable
771 +branch. The inode of a pseudo-link is kept in aufs super_block as a
772 +simple list. If fileB is read after unlinking fileA, aufs returns
773 +filedata from the pseudo-link instead of the lower readonly
774 +branch. Because the pseudo-link is based upon the inode, to keep the
775 +inode number by xino (see above) is important.
777 +All the hardlinks under the Pseudo-link Directory of the writable branch
778 +should be restored in a proper location later. Aufs provides a utility
779 +to do this. The userspace helpers executed at remounting and unmounting
781 +During this utility is running, it puts aufs into the pseudo-link
782 +maintenance mode. In this mode, only the process which began the
783 +maintenance mode (and its child processes) is allowed to operate in
784 +aufs. Some other processes which are not related to the pseudo-link will
785 +be allowed to run too, but the rest have to return an error or wait
786 +until the maintenance mode ends. If a process already acquires an inode
787 +mutex (in VFS), it has to return an error.
790 +XIB(external inode number bitmap)
791 +----------------------------------------------------------------------
792 +Addition to the xino file per a branch, aufs has an external inode number
793 +bitmap in a superblock object. It is also a file such like a xino file.
794 +It is a simple bitmap to mark whether the aufs inode number is in-use or
796 +To reduce the file I/O, aufs prepares a single memory page to cache xib.
798 +Aufs implements a feature to truncate/refresh both of xino and xib to
799 +reduce the number of consumed disk blocks for these files.
802 +Virtual or Vertical Dir, and Readdir in Userspace
803 +----------------------------------------------------------------------
804 +In order to support multiple layers (branches), aufs readdir operation
805 +constructs a virtual dir block on memory. For readdir, aufs calls
806 +vfs_readdir() internally for each dir on branches, merges their entries
807 +with eliminating the whiteout-ed ones, and sets it to file (dir)
808 +object. So the file object has its entry list until it is closed. The
809 +entry list will be updated when the file position is zero and becomes
810 +old. This decision is made in aufs automatically.
812 +The dynamically allocated memory block for the name of entries has a
813 +unit of 512 bytes (by default) and stores the names contiguously (no
814 +padding). Another block for each entry is handled by kmem_cache too.
815 +During building dir blocks, aufs creates hash list and judging whether
816 +the entry is whiteouted by its upper branch or already listed.
817 +The merged result is cached in the corresponding inode object and
818 +maintained by a customizable life-time option.
820 +Some people may call it can be a security hole or invite DoS attack
821 +since the opened and once readdir-ed dir (file object) holds its entry
822 +list and becomes a pressure for system memory. But I'd say it is similar
823 +to files under /proc or /sys. The virtual files in them also holds a
824 +memory page (generally) while they are opened. When an idea to reduce
825 +memory for them is introduced, it will be applied to aufs too.
826 +For those who really hate this situation, I've developed readdir(3)
827 +library which operates this merging in userspace. You just need to set
828 +LD_PRELOAD environment variable, and aufs will not consume no memory in
829 +kernel space for readdir(3).
833 +----------------------------------------------------------------------
834 +Aufs sometimes requires privilege access to a branch. For instance,
835 +in copy-up/down operation. When a user process is going to make changes
836 +to a file which exists in the lower readonly branch only, and the mode
837 +of one of ancestor directories may not be writable by a user
838 +process. Here aufs copy-up the file with its ancestors and they may
839 +require privilege to set its owner/group/mode/etc.
840 +This is a typical case of a application character of aufs (see
843 +Aufs uses workqueue synchronously for this case. It creates its own
844 +workqueue. The workqueue is a kernel thread and has privilege. Aufs
845 +passes the request to call mkdir or write (for example), and wait for
846 +its completion. This approach solves a problem of a signal handler
848 +If aufs didn't adopt the workqueue and changed the privilege of the
849 +process, and if the mkdir/write call arises SIGXFSZ or other signal,
850 +then the user process might gain a privilege or the generated core file
851 +was owned by a superuser.
853 +Also aufs uses the system global workqueue ("events" kernel thread) too
854 +for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
855 +whiteout base and etc. This is unrelated to a privilege.
856 +Most of aufs operation tries acquiring a rw_semaphore for aufs
857 +superblock at the beginning, at the same time waits for the completion
858 +of all queued asynchronous tasks.
862 +----------------------------------------------------------------------
863 +The whiteout in aufs is very similar to Unionfs's. That is represented
864 +by its filename. UnionMount takes an approach of a file mode, but I am
865 +afraid several utilities (find(1) or something) will have to support it.
867 +Basically the whiteout represents "logical deletion" which stops aufs to
868 +lookup further, but also it represents "dir is opaque" which also stop
871 +In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
872 +In order to make several functions in a single systemcall to be
873 +revertible, aufs adopts an approach to rename a directory to a temporary
874 +unique whiteouted name.
875 +For example, in rename(2) dir where the target dir already existed, aufs
876 +renames the target dir to a temporary unique whiteouted name before the
877 +actual rename on a branch and then handles other actions (make it opaque,
878 +update the attributes, etc). If an error happens in these actions, aufs
879 +simply renames the whiteouted name back and returns an error. If all are
880 +succeeded, aufs registers a function to remove the whiteouted unique
881 +temporary name completely and asynchronously to the system global
886 +----------------------------------------------------------------------
887 +It is a well-known feature or concept.
888 +When user modifies a file on a readonly branch, aufs operate "copy-up"
889 +internally and makes change to the new file on the upper writable branch.
890 +When the trigger systemcall does not update the timestamps of the parent
891 +dir, aufs reverts it after copy-up.
892 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
893 --- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
894 +++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2013-07-06 13:20:47.730197761 +0200
897 +# Copyright (C) 2005-2013 Junjiro R. Okajima
899 +# This program is free software; you can redistribute it and/or modify
900 +# it under the terms of the GNU General Public License as published by
901 +# the Free Software Foundation; either version 2 of the License, or
902 +# (at your option) any later version.
904 +# This program is distributed in the hope that it will be useful,
905 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
906 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
907 +# GNU General Public License for more details.
909 +# You should have received a copy of the GNU General Public License
910 +# along with this program; if not, write to the Free Software
911 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
914 +----------------------------------------------------------------------
915 +Since aufs has a character of sub-VFS (see Introduction), it operates
916 +lookup for branches as VFS does. It may be a heavy work. Generally
917 +speaking struct nameidata is a bigger structure and includes many
918 +information. But almost all lookup operation in aufs is the simplest
919 +case, ie. lookup only an entry directly connected to its parent. Digging
920 +down the directory hierarchy is unnecessary.
922 +VFS has a function lookup_one_len() for that use, but it is not usable
923 +for a branch filesystem which requires struct nameidata. So aufs
924 +implements a simple lookup wrapper function. When a branch filesystem
925 +allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
926 +a simplest nameidata and calls lookup_hash().
927 +Here aufs applies "a principle in NFSD", ie. if the filesystem supports
928 +NFS-export, then it has to support NULL as a nameidata parameter for
929 +->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
930 +aufs tests if ->s_export_op in the branch is NULL or not.
932 +When a branch is a remote filesystem, aufs basically trusts its
933 +->d_revalidate(), also aufs forces the hardest revalidate tests for
935 +For d_revalidate, aufs implements three levels of revalidate tests. See
936 +"Revalidate Dentry and UDBA" in detail.
940 +----------------------------------------------------------------------
941 +Basically aufs supports any type of filesystem and block device for a
942 +branch (actually there are some exceptions). But it is prohibited to add
943 +a loopback mounted one whose backend file exists in a filesystem which is
944 +already added to aufs. The reason is to protect aufs from a recursive
945 +lookup. If it was allowed, the aufs lookup operation might re-enter a
946 +lookup for the loopback mounted branch in the same context, and will
950 +Revalidate Dentry and UDBA (User's Direct Branch Access)
951 +----------------------------------------------------------------------
952 +Generally VFS helpers re-validate a dentry as a part of lookup.
953 +0. digging down the directory hierarchy.
954 +1. lock the parent dir by its i_mutex.
955 +2. lookup the final (child) entry.
957 +4. call the actual operation (create, unlink, etc.)
958 +5. unlock the parent dir
960 +If the filesystem implements its ->d_revalidate() (step 3), then it is
961 +called. Actually aufs implements it and checks the dentry on a branch is
963 +But it is not enough. Because aufs has to release the lock for the
964 +parent dir on a branch at the end of ->lookup() (step 2) and
965 +->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
967 +If the file on a branch is changed directly, eg. bypassing aufs, after
968 +aufs released the lock, then the subsequent operation may cause
969 +something unpleasant result.
971 +This situation is a result of VFS architecture, ->lookup() and
972 +->d_revalidate() is separated. But I never say it is wrong. It is a good
973 +design from VFS's point of view. It is just not suitable for sub-VFS
976 +Aufs supports such case by three level of revalidation which is
978 +1. Simple Revalidate
979 + Addition to the native flow in VFS's, confirm the child-parent
980 + relationship on the branch just after locking the parent dir on the
981 + branch in the "actual operation" (step 4). When this validation
982 + fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
983 + checks the validation of the dentry on branches.
984 +2. Monitor Changes Internally by Inotify/Fsnotify
985 + Addition to above, in the "actual operation" (step 4) aufs re-lookup
986 + the dentry on the branch, and returns EBUSY if it finds different
988 + Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
989 + during it is in cache. When the event is notified, aufs registers a
990 + function to kernel 'events' thread by schedule_work(). And the
991 + function sets some special status to the cached aufs dentry and inode
992 + private data. If they are not cached, then aufs has nothing to
993 + do. When the same file is accessed through aufs (step 0-3) later,
994 + aufs will detect the status and refresh all necessary data.
995 + In this mode, aufs has to ignore the event which is fired by aufs
997 +3. No Extra Validation
998 + This is the simplest test and doesn't add any additional revalidation
999 + test, and skip therevalidatin in step 4. It is useful and improves
1000 + aufs performance when system surely hide the aufs branches from user,
1001 + by over-mounting something (or another method).
1002 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1003 --- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
1004 +++ linux/Documentation/filesystems/aufs/design/04branch.txt 2013-07-06 13:20:47.730197761 +0200
1007 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1009 +# This program is free software; you can redistribute it and/or modify
1010 +# it under the terms of the GNU General Public License as published by
1011 +# the Free Software Foundation; either version 2 of the License, or
1012 +# (at your option) any later version.
1014 +# This program is distributed in the hope that it will be useful,
1015 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1016 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1017 +# GNU General Public License for more details.
1019 +# You should have received a copy of the GNU General Public License
1020 +# along with this program; if not, write to the Free Software
1021 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1023 +Branch Manipulation
1025 +Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1026 +and changing its permission/attribute, there are a lot of works to do.
1030 +----------------------------------------------------------------------
1031 +o Confirm the adding dir exists outside of aufs, including loopback
1033 +- and other various attributes...
1034 +o Initialize the xino file and whiteout bases if necessary.
1037 +o Check the owner/group/mode of the directory
1038 + When the owner/group/mode of the adding directory differs from the
1039 + existing branch, aufs issues a warning because it may impose a
1041 + For example, when a upper writable branch has a world writable empty
1042 + top directory, a malicious user can create any files on the writable
1043 + branch directly, like copy-up and modify manually. If something like
1044 + /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1045 + writable branch, and the writable branch is world-writable, then a
1046 + malicious guy may create /etc/passwd on the writable branch directly
1047 + and the infected file will be valid in aufs.
1048 + I am afraid it can be a security issue, but nothing to do except
1049 + producing a warning.
1053 +----------------------------------------------------------------------
1054 +o Confirm the deleting branch is not busy
1055 + To be general, there is one merit to adopt "remount" interface to
1056 + manipulate branches. It is to discard caches. At deleting a branch,
1057 + aufs checks the still cached (and connected) dentries and inodes. If
1058 + there are any, then they are all in-use. An inode without its
1059 + corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1061 + For the cached one, aufs checks whether the same named entry exists on
1063 + If the cached one is a directory, because aufs provides a merged view
1064 + to users, as long as one dir is left on any branch aufs can show the
1065 + dir to users. In this case, the branch can be removed from aufs.
1066 + Otherwise aufs rejects deleting the branch.
1068 + If any file on the deleting branch is opened by aufs, then aufs
1072 +Modify the Permission of a Branch
1073 +----------------------------------------------------------------------
1074 +o Re-initialize or remove the xino file and whiteout bases if necessary.
1077 +o rw --> ro: Confirm the modifying branch is not busy
1078 + Aufs rejects the request if any of these conditions are true.
1079 + - a file on the branch is mmap-ed.
1080 + - a regular file on the branch is opened for write and there is no
1081 + same named entry on the upper branch.
1082 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1083 --- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
1084 +++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2013-07-06 13:20:47.730197761 +0200
1087 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1089 +# This program is free software; you can redistribute it and/or modify
1090 +# it under the terms of the GNU General Public License as published by
1091 +# the Free Software Foundation; either version 2 of the License, or
1092 +# (at your option) any later version.
1094 +# This program is distributed in the hope that it will be useful,
1095 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1096 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1097 +# GNU General Public License for more details.
1099 +# You should have received a copy of the GNU General Public License
1100 +# along with this program; if not, write to the Free Software
1101 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1103 +Policies to Select One among Multiple Writable Branches
1104 +----------------------------------------------------------------------
1105 +When the number of writable branch is more than one, aufs has to decide
1106 +the target branch for file creation or copy-up. By default, the highest
1107 +writable branch which has the parent (or ancestor) dir of the target
1108 +file is chosen (top-down-parent policy).
1109 +By user's request, aufs implements some other policies to select the
1110 +writable branch, for file creation two policies, round-robin and
1111 +most-free-space policies. For copy-up three policies, top-down-parent,
1112 +bottom-up-parent and bottom-up policies.
1114 +As expected, the round-robin policy selects the branch in circular. When
1115 +you have two writable branches and creates 10 new files, 5 files will be
1116 +created for each branch. mkdir(2) systemcall is an exception. When you
1117 +create 10 new directories, all will be created on the same branch.
1118 +And the most-free-space policy selects the one which has most free
1119 +space among the writable branches. The amount of free space will be
1120 +checked by aufs internally, and users can specify its time interval.
1122 +The policies for copy-up is more simple,
1123 +top-down-parent is equivalent to the same named on in create policy,
1124 +bottom-up-parent selects the writable branch where the parent dir
1125 +exists and the nearest upper one from the copyup-source,
1126 +bottom-up selects the nearest upper writable branch from the
1127 +copyup-source, regardless the existence of the parent dir.
1129 +There are some rules or exceptions to apply these policies.
1130 +- If there is a readonly branch above the policy-selected branch and
1131 + the parent dir is marked as opaque (a variation of whiteout), or the
1132 + target (creating) file is whiteout-ed on the upper readonly branch,
1133 + then the result of the policy is ignored and the target file will be
1134 + created on the nearest upper writable branch than the readonly branch.
1135 +- If there is a writable branch above the policy-selected branch and
1136 + the parent dir is marked as opaque or the target file is whiteouted
1137 + on the branch, then the result of the policy is ignored and the target
1138 + file will be created on the highest one among the upper writable
1139 + branches who has diropq or whiteout. In case of whiteout, aufs removes
1141 +- link(2) and rename(2) systemcalls are exceptions in every policy.
1142 + They try selecting the branch where the source exists as possible
1143 + since copyup a large file will take long time. If it can't be,
1144 + ie. the branch where the source exists is readonly, then they will
1145 + follow the copyup policy.
1146 +- There is an exception for rename(2) when the target exists.
1147 + If the rename target exists, aufs compares the index of the branches
1148 + where the source and the target exists and selects the higher
1149 + one. If the selected branch is readonly, then aufs follows the
1151 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1152 --- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
1153 +++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2013-07-06 13:20:47.730197761 +0200
1156 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1158 +# This program is free software; you can redistribute it and/or modify
1159 +# it under the terms of the GNU General Public License as published by
1160 +# the Free Software Foundation; either version 2 of the License, or
1161 +# (at your option) any later version.
1163 +# This program is distributed in the hope that it will be useful,
1164 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1165 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1166 +# GNU General Public License for more details.
1168 +# You should have received a copy of the GNU General Public License
1169 +# along with this program; if not, write to the Free Software
1170 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1172 +mmap(2) -- File Memory Mapping
1173 +----------------------------------------------------------------------
1174 +In aufs, the file-mapped pages are handled by a branch fs directly, no
1175 +interaction with aufs. It means aufs_mmap() calls the branch fs's
1177 +This approach is simple and good, but there is one problem.
1178 +Under /proc, several entries show the mmap-ped files by its path (with
1179 +device and inode number), and the printed path will be the path on the
1180 +branch fs's instead of virtual aufs's.
1181 +This is not a problem in most cases, but some utilities lsof(1) (and its
1182 +user) may expect the path on aufs.
1184 +To address this issue, aufs adds a new member called vm_prfile in struct
1185 +vm_area_struct (and struct vm_region). The original vm_file points to
1186 +the file on the branch fs in order to handle everything correctly as
1187 +usual. The new vm_prfile points to a virtual file in aufs, and the
1188 +show-functions in procfs refers to vm_prfile if it is set.
1189 +Also we need to maintain several other places where touching vm_file
1191 +- fork()/clone() copies vma and the reference count of vm_file is
1193 +- merging vma maintains the ref count too.
1195 +This is not a good approach. It just faking the printed path. But it
1196 +leaves all behaviour around f_mapping unchanged. This is surely an
1198 +Actually aufs had adopted another complicated approach which calls
1199 +generic_file_mmap() and handles struct vm_operations_struct. In this
1200 +approach, aufs met a hard problem and I could not solve it without
1201 +switching the approach.
1202 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1203 --- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
1204 +++ linux/Documentation/filesystems/aufs/design/07export.txt 2013-07-06 13:20:47.736864659 +0200
1207 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1209 +# This program is free software; you can redistribute it and/or modify
1210 +# it under the terms of the GNU General Public License as published by
1211 +# the Free Software Foundation; either version 2 of the License, or
1212 +# (at your option) any later version.
1214 +# This program is distributed in the hope that it will be useful,
1215 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1216 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1217 +# GNU General Public License for more details.
1219 +# You should have received a copy of the GNU General Public License
1220 +# along with this program; if not, write to the Free Software
1221 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1223 +Export Aufs via NFS
1224 +----------------------------------------------------------------------
1225 +Here is an approach.
1226 +- like xino/xib, add a new file 'xigen' which stores aufs inode
1228 +- iget_locked(): initialize aufs inode generation for a new inode, and
1229 + store it in xigen file.
1230 +- destroy_inode(): increment aufs inode generation and store it in xigen
1231 + file. it is necessary even if it is not unlinked, because any data of
1232 + inode may be changed by UDBA.
1233 +- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
1234 + build file handle by
1235 + + branch id (4 bytes)
1236 + + superblock generation (4 bytes)
1237 + + inode number (4 or 8 bytes)
1238 + + parent dir inode number (4 or 8 bytes)
1239 + + inode generation (4 bytes))
1240 + + return value of exportfs_encode_fh() for the parent on a branch (4
1242 + + file handle for a branch (by exportfs_encode_fh())
1244 + + find the index of a branch from its id in handle, and check it is
1245 + still exist in aufs.
1246 + + 1st level: get the inode number from handle and search it in cache.
1247 + + 2nd level: if not found, get the parent inode number from handle and
1248 + search it in cache. and then open the parent dir, find the matching
1249 + inode number by vfs_readdir() and get its name, and call
1250 + lookup_one_len() for the target dentry.
1251 + + 3rd level: if the parent dir is not cached, call
1252 + exportfs_decode_fh() for a branch and get the parent on a branch,
1253 + build a pathname of it, convert it a pathname in aufs, call
1254 + path_lookup(). now aufs gets a parent dir dentry, then handle it as
1256 + + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
1257 + for every branch, but not itself. to get this, (currently) aufs
1258 + searches in current->nsproxy->mnt_ns list. it may not be a good
1259 + idea, but I didn't get other approach.
1260 + + test the generation of the gotten inode.
1261 +- every inode operation: they may get EBUSY due to UDBA. in this case,
1262 + convert it into ESTALE for NFSD.
1263 +- readdir(): call lockdep_on/off() because filldir in NFSD calls
1264 + lookup_one_len(), vfs_getattr(), encode_fh() and others.
1265 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
1266 --- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
1267 +++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2013-07-06 13:20:47.736864659 +0200
1270 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1272 +# This program is free software; you can redistribute it and/or modify
1273 +# it under the terms of the GNU General Public License as published by
1274 +# the Free Software Foundation; either version 2 of the License, or
1275 +# (at your option) any later version.
1277 +# This program is distributed in the hope that it will be useful,
1278 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1279 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1280 +# GNU General Public License for more details.
1282 +# You should have received a copy of the GNU General Public License
1283 +# along with this program; if not, write to the Free Software
1284 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1286 +Show Whiteout Mode (shwh)
1287 +----------------------------------------------------------------------
1288 +Generally aufs hides the name of whiteouts. But in some cases, to show
1289 +them is very useful for users. For instance, creating a new middle layer
1290 +(branch) by merging existing layers.
1292 +(borrowing aufs1 HOW-TO from a user, Michael Towers)
1293 +When you have three branches,
1294 +- Bottom: 'system', squashfs (underlying base system), read-only
1295 +- Middle: 'mods', squashfs, read-only
1296 +- Top: 'overlay', ram (tmpfs), read-write
1298 +The top layer is loaded at boot time and saved at shutdown, to preserve
1299 +the changes made to the system during the session.
1300 +When larger changes have been made, or smaller changes have accumulated,
1301 +the size of the saved top layer data grows. At this point, it would be
1302 +nice to be able to merge the two overlay branches ('mods' and 'overlay')
1303 +and rewrite the 'mods' squashfs, clearing the top layer and thus
1304 +restoring save and load speed.
1306 +This merging is simplified by the use of another aufs mount, of just the
1307 +two overlay branches using the 'shwh' option.
1308 +# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
1309 + aufs /livesys/merge_union
1311 +A merged view of these two branches is then available at
1312 +/livesys/merge_union, and the new feature is that the whiteouts are
1314 +Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
1315 +writing to all branches. Also the default mode for all branches is 'ro'.
1316 +It is now possible to save the combined contents of the two overlay
1317 +branches to a new squashfs, e.g.:
1318 +# mksquashfs /livesys/merge_union /path/to/newmods.squash
1320 +This new squashfs archive can be stored on the boot device and the
1321 +initramfs will use it to replace the old one at the next boot.
1322 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
1323 --- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
1324 +++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2013-07-06 13:20:47.736864659 +0200
1327 +# Copyright (C) 2010-2013 Junjiro R. Okajima
1329 +# This program is free software; you can redistribute it and/or modify
1330 +# it under the terms of the GNU General Public License as published by
1331 +# the Free Software Foundation; either version 2 of the License, or
1332 +# (at your option) any later version.
1334 +# This program is distributed in the hope that it will be useful,
1335 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1336 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1337 +# GNU General Public License for more details.
1339 +# You should have received a copy of the GNU General Public License
1340 +# along with this program; if not, write to the Free Software
1341 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1343 +Dynamically customizable FS operations
1344 +----------------------------------------------------------------------
1345 +Generally FS operations (struct inode_operations, struct
1346 +address_space_operations, struct file_operations, etc.) are defined as
1347 +"static const", but it never means that FS have only one set of
1348 +operation. Some FS have multiple sets of them. For instance, ext2 has
1349 +three sets, one for XIP, for NOBH, and for normal.
1350 +Since aufs overrides and redirects these operations, sometimes aufs has
1351 +to change its behaviour according to the branch FS type. More imporantly
1352 +VFS acts differently if a function (member in the struct) is set or
1353 +not. It means aufs should have several sets of operations and select one
1354 +among them according to the branch FS definition.
1356 +In order to solve this problem and not to affect the behavour of VFS,
1357 +aufs defines these operations dynamically. For instance, aufs defines
1358 +aio_read function for struct file_operations, but it may not be set to
1359 +the file_operations. When the branch FS doesn't have it, aufs doesn't
1360 +set it to its file_operations while the function definition itself is
1361 +still alive. So the behaviour of io_submit(2) will not change, and it
1362 +will return an error when aio_read is not defined.
1364 +The lifetime of these dynamically generated operation object is
1365 +maintained by aufs branch object. When the branch is removed from aufs,
1366 +the reference counter of the object is decremented. When it reaches
1367 +zero, the dynamically generated operation object will be freed.
1369 +This approach is designed to support AIO (io_submit), Direcit I/O and
1371 +Currently this approach is applied to file_operations and
1372 +vm_operations_struct for regular files only.
1373 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
1374 --- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100
1375 +++ linux/Documentation/filesystems/aufs/design/99plan.txt 2013-07-06 13:20:47.736864659 +0200
1378 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1380 +# This program is free software; you can redistribute it and/or modify
1381 +# it under the terms of the GNU General Public License as published by
1382 +# the Free Software Foundation; either version 2 of the License, or
1383 +# (at your option) any later version.
1385 +# This program is distributed in the hope that it will be useful,
1386 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1387 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1388 +# GNU General Public License for more details.
1390 +# You should have received a copy of the GNU General Public License
1391 +# along with this program; if not, write to the Free Software
1392 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1396 +Restoring some features which was implemented in aufs1.
1397 +They were dropped in aufs2 in order to make source files simpler and
1398 +easier to be reviewed.
1401 +Test Only the Highest One for the Directory Permission (dirperm1 option)
1402 +----------------------------------------------------------------------
1403 +Let's try case study.
1404 +- aufs has two branches, upper readwrite and lower readonly.
1406 +- "dirA" exists under /ro, but /rw. and its mode is 0700.
1407 +- user invoked "chmod a+rx /au/dirA"
1408 +- then "dirA" becomes world readable?
1410 +In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1411 +or it may be a natively readonly filesystem. If aufs respects the lower
1412 +branch, it should not respond readdir request from other users. But user
1413 +allowed it by chmod. Should really aufs rejects showing the entries
1416 +To be honest, I don't have a best solution for this case. So I
1417 +implemented 'dirperm1' and 'nodirperm1' option in aufs1, and leave it to
1419 +When dirperm1 is specified, aufs checks only the highest one for the
1420 +directory permission, and shows the entries. Otherwise, as usual, checks
1421 +every dir existing on all branches and rejects the request.
1423 +As a side effect, dirperm1 option improves the performance of aufs
1424 +because the number of permission check is reduced.
1427 +Being Another Aufs's Readonly Branch (robr)
1428 +----------------------------------------------------------------------
1429 +Aufs1 allows aufs to be another aufs's readonly branch.
1430 +This feature was developed by a user's request. But it may not be used
1434 +Copy-up on Open (coo=)
1435 +----------------------------------------------------------------------
1436 +By default the internal copy-up is executed when it is really necessary.
1437 +It is not done when a file is opened for writing, but when write(2) is
1438 +done. Users who have many (over 100) branches want to know and analyse
1439 +when and what file is copied-up. To insert a new upper branch which
1440 +contains such files only may improve the performance of aufs.
1442 +Aufs1 implemented "coo=none | leaf | all" option.
1445 +Refresh the Opened File (refrof)
1446 +----------------------------------------------------------------------
1447 +This option is implemented in aufs1 but incomplete.
1449 +When user reads from a file, he expects to get its latest filedata
1450 +generally. If the file is removed and a new same named file is created,
1451 +the content he gets is unchanged, ie. the unlinked filedata.
1453 +Let's try case study again.
1454 +- aufs has two branches.
1456 +- "fileA" exists under /ro, but /rw.
1457 +- user opened "/au/fileA".
1458 +- he or someone else inserts a branch (/new) between /rw and /ro.
1459 + /au = /rw + /new + /ro
1460 +- the new branch has "fileA".
1461 +- user reads from the opened "fileA"
1462 +- which filedata should aufs return, from /ro or /new?
1464 +Some people says it has to be "from /ro" and it is a semantics of Unix.
1465 +The others say it should be "from /new" because the file is not removed
1466 +and it is equivalent to the case of someone else modifies the file.
1468 +Here again I don't have a best and final answer. I got an idea to
1469 +implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
1470 +Opened File) is specified (by default), aufs returns the filedata from
1472 +Otherwise from /new.
1473 diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
1474 --- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
1475 +++ linux/Documentation/filesystems/aufs/README 2013-07-30 22:42:46.229279157 +0200
1478 +Aufs3 -- advanced multi layered unification filesystem version 3.x
1484 +----------------------------------------
1485 +In the early days, aufs was entirely re-designed and re-implemented
1486 +Unionfs Version 1.x series. After many original ideas, approaches,
1487 +improvements and implementations, it becomes totally different from
1488 +Unionfs while keeping the basic features.
1489 +Recently, Unionfs Version 2.x series begin taking some of the same
1490 +approaches to aufs1's.
1491 +Unionfs is being developed by Professor Erez Zadok at Stony Brook
1492 +University and his team.
1494 +Aufs3 supports linux-3.0 and later.
1495 +If you want older kernel version support, try aufs2-2.6.git or
1496 +aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
1498 +Note: it becomes clear that "Aufs was rejected. Let's give it up."
1499 +According to Christoph Hellwig, linux rejects all union-type filesystems
1501 +<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
1505 +----------------------------------------
1506 +- unite several directories into a single virtual filesystem. The member
1507 + directory is called as a branch.
1508 +- you can specify the permission flags to the branch, which are 'readonly',
1509 + 'readwrite' and 'whiteout-able.'
1510 +- by upper writable branch, internal copyup and whiteout, files/dirs on
1511 + readonly branch are modifiable logically.
1512 +- dynamic branch manipulation, add, del.
1515 +Also there are many enhancements in aufs1, such as:
1516 +- readdir(3) in userspace.
1517 +- keep inode number by external inode number table
1518 +- keep the timestamps of file/dir in internal copyup operation
1519 +- seekable directory, supporting NFS readdir.
1520 +- whiteout is hardlinked in order to reduce the consumption of inodes
1522 +- do not copyup, nor create a whiteout when it is unnecessary
1523 +- revert a single systemcall when an error occurs in aufs
1524 +- remount interface instead of ioctl
1525 +- maintain /etc/mtab by an external command, /sbin/mount.aufs.
1526 +- loopback mounted filesystem as a branch
1527 +- kernel thread for removing the dir who has a plenty of whiteouts
1528 +- support copyup sparse file (a file which has a 'hole' in it)
1529 +- default permission flags for branches
1530 +- selectable permission flags for ro branch, whether whiteout can
1533 +- support <sysfs>/fs/aufs and <debugfs>/aufs.
1534 +- support multiple writable branches, some policies to select one
1535 + among multiple writable branches.
1536 +- a new semantics for link(2) and rename(2) to support multiple
1537 + writable branches.
1538 +- no glibc changes are required.
1539 +- pseudo hardlink (hardlink over branches)
1540 +- allow a direct access manually to a file on branch, e.g. bypassing aufs.
1541 + including NFS or remote filesystem branch.
1542 +- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
1545 +Currently these features are dropped temporary from aufs3.
1546 +See design/08plan.txt in detail.
1547 +- test only the highest one for the directory permission (dirperm1)
1548 +- copyup on open (coo=)
1549 +- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
1551 +- statistics of aufs thread (/sys/fs/aufs/stat)
1552 +- delegation mode (dlgt)
1553 + a delegation of the internal branch access to support task I/O
1554 + accounting, which also supports Linux Security Modules (LSM) mainly
1555 + for Suse AppArmor.
1556 +- intent.open/create (file open in a single lookup)
1558 +Features or just an idea in the future (see also design/*.txt),
1559 +- reorder the branch index without del/re-add.
1560 +- permanent xino files for NFSD
1561 +- an option for refreshing the opened files after add/del branches
1562 +- 'move' policy for copy-up between two writable branches, after
1563 + checking free space.
1564 +- light version, without branch manipulation. (unnecessary?)
1565 +- copyup in userspace
1566 +- inotify in userspace
1572 +----------------------------------------
1573 +There were three GIT trees for aufs3, aufs3-linux.git,
1574 +aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
1576 +While the aufs-util is always necessary, you need either of aufs3-linux
1577 +or aufs3-standalone.
1579 +The aufs3-linux tree includes the whole linux mainline GIT tree,
1580 +git://git.kernel.org/.../torvalds/linux.git.
1581 +And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
1582 +build aufs3 as an external kernel module.
1584 +On the other hand, the aufs3-standalone tree has only aufs source files
1585 +and necessary patches, and you can select CONFIG_AUFS_FS=m.
1587 +You will find GIT branches whose name is in form of "aufs3.x" where "x"
1588 +represents the linux kernel version, "linux-3.x". For instance,
1589 +"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
1590 +"aufs3.x-rcN" branch.
1593 +$ git clone --reference /your/linux/git/tree \
1594 + git://git.code.sf.net/p/aufs/aufs3-linux aufs-aufs3-linux \
1596 +- if you don't have linux GIT tree, then remove "--reference ..."
1597 +$ cd aufs3-linux.git
1598 +$ git checkout origin/aufs3.0
1600 +o aufs3-standalone tree
1601 +$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
1602 + aufs3-standalone.git
1603 +$ cd aufs3-standalone.git
1604 +$ git checkout origin/aufs3.0
1607 +$ git clone git://git.code.sf.net/p/aufs/aufs-util \
1610 +$ git checkout origin/aufs3.0
1612 +Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
1613 +The minor version number, 'x' in '3.x', of aufs may not always
1614 +follow the minor version number of the kernel.
1615 +Because changes in the kernel that cause the use of a new
1616 +minor version number do not always require changes to aufs-util.
1618 +Since aufs-util has its own minor version number, you may not be
1619 +able to find a GIT branch in aufs-util for your kernel's
1620 +exact minor version number.
1621 +In this case, you should git-checkout the branch for the
1622 +nearest lower number.
1624 +For (an unreleased) example:
1625 +If you are using "linux-3.10" and the "aufs3.10" branch
1626 +does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
1627 +or something numerically smaller is the branch for your kernel.
1629 +Also you can view all branches by
1633 +3. Configuration and Compilation
1634 +----------------------------------------
1635 +Make sure you have git-checkout'ed the correct branch.
1637 +For aufs3-linux tree,
1638 +- enable CONFIG_AUFS_FS.
1639 +- set other aufs configurations if necessary.
1641 +For aufs3-standalone tree,
1642 +There are several ways to build.
1645 +- apply ./aufs3-kbuild.patch to your kernel source files.
1646 +- apply ./aufs3-base.patch too.
1647 +- apply ./aufs3-proc_map.patch too, if you want to make /proc/PID/maps (and
1648 + others including lsof(1)) show the file path on aufs instead of the
1649 + path on the branch fs.
1650 +- apply ./aufs3-standalone.patch too, if you have a plan to set
1651 + CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
1652 +- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
1653 + kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
1654 +- enable CONFIG_AUFS_FS, you can select either
1656 +- and build your kernel as usual.
1657 +- install the built kernel.
1658 + Note: Since linux-3.9, every filesystem module requires an alias
1659 + "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
1660 + modules.aliases file if you set CONFIG_AUFS_FS=m.
1661 +- install the header files too by "make headers_install" to the
1662 + directory where you specify. By default, it is $PWD/usr.
1663 + "make help" shows a brief note for headers_install.
1664 +- and reboot your system.
1667 +- module only (CONFIG_AUFS_FS=m).
1668 +- apply ./aufs3-base.patch to your kernel source files.
1669 +- apply ./aufs3-proc_map.patch too to your kernel source files,
1670 + if you want to make /proc/PID/maps (and others including lsof(1)) show
1671 + the file path on aufs instead of the path on the branch fs.
1672 +- apply ./aufs3-standalone.patch too.
1673 +- build your kernel, don't forget "make headers_install", and reboot.
1674 +- edit ./config.mk and set other aufs configurations if necessary.
1675 + Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
1676 + every aufs configurations.
1677 +- build the module by simple "make".
1678 + Note: Since linux-3.9, every filesystem module requires an alias
1679 + "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
1680 + modules.aliases file.
1681 +- you can specify ${KDIR} make variable which points to your kernel
1683 +- install the files
1684 + + run "make install" to install the aufs module, or copy the built
1685 + $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
1686 + + run "make install_headers" (instead of headers_install) to install
1687 + the modified aufs header file (you can specify DESTDIR which is
1688 + available in aufs standalone version's Makefile only), or copy
1689 + $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
1690 + you like manually. By default, the target directory is $PWD/usr.
1691 +- no need to apply aufs3-kbuild.patch, nor copying source files to your
1692 + kernel source tree.
1694 +Note: The header file aufs_type.h is necessary to build aufs-util
1695 + as well as "make headers_install" in the kernel source tree.
1696 + headers_install is subject to be forgotten, but it is essentially
1697 + necessary, not only for building aufs-util.
1698 + You may not meet problems without headers_install in some older
1702 +- read README in aufs-util, build and install it
1703 +- note that your distribution may contain an obsoleted version of
1704 + aufs_type.h in /usr/include/linux or something. When you build aufs
1705 + utilities, make sure that your compiler refers the correct aufs header
1706 + file which is built by "make headers_install."
1707 +- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
1708 + then run "make install_ulib" too. And refer to the aufs manual in
1713 +----------------------------------------
1714 +At first, make sure aufs-util are installed, and please read the aufs
1715 +manual, aufs.5 in aufs-util.git tree.
1719 +$ mkdir /tmp/rw /tmp/aufs
1720 +# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
1722 +Here is another example. The result is equivalent.
1723 +# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
1725 +# mount -t aufs -o br:/tmp/rw none /tmp/aufs
1726 +# mount -o remount,append:${HOME} /tmp/aufs
1728 +Then, you can see whole tree of your home dir through /tmp/aufs. If
1729 +you modify a file under /tmp/aufs, the one on your home directory is
1730 +not affected, instead the same named file will be newly created under
1731 +/tmp/rw. And all of your modification to a file will be applied to
1732 +the one under /tmp/rw. This is called the file based Copy on Write
1734 +Aufs mount options are described in aufs.5.
1735 +If you run chroot or something and make your aufs as a root directory,
1736 +then you need to customize the shutdown script. See the aufs manual in
1739 +Additionally, there are some sample usages of aufs which are a
1740 +diskless system with network booting, and LiveCD over NFS.
1741 +See sample dir in CVS tree on SourceForge.
1745 +----------------------------------------
1746 +When you have any problems or strange behaviour in aufs, please let me
1748 +- /proc/mounts (instead of the output of mount(8))
1749 +- /sys/module/aufs/*
1750 +- /sys/fs/aufs/* (if you have them)
1751 +- /debug/aufs/* (if you have them)
1752 +- linux kernel version
1753 + if your kernel is not plain, for example modified by distributor,
1754 + the url where i can download its source is necessary too.
1755 +- aufs version which was printed at loading the module or booting the
1756 + system, instead of the date you downloaded.
1757 +- configuration (define/undefine CONFIG_AUFS_xxx)
1758 +- kernel configuration or /proc/config.gz (if you have it)
1759 +- behaviour which you think to be incorrect
1760 +- actual operation, reproducible one is better
1761 +- mailto: aufs-users at lists.sourceforge.net
1763 +Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
1764 +and Feature Requests) on SourceForge. Please join and write to
1768 +6. Acknowledgements
1769 +----------------------------------------
1770 +Thanks to everyone who have tried and are using aufs, whoever
1771 +have reported a bug or any feedback.
1773 +Especially donators:
1774 +Tomas Matejicek(slax.org) made a donation (much more than once).
1775 + Since Apr 2010, Tomas M (the author of Slax and Linux Live
1776 + scripts) is making "doubling" donations.
1777 + Unfortunately I cannot list all of the donators, but I really
1779 + It ends Aug 2010, but the ordinary donation URL is still available.
1780 + <http://sourceforge.net/donate/index.php?group_id=167503>
1781 +Dai Itasaka made a donation (2007/8).
1782 +Chuck Smith made a donation (2008/4, 10 and 12).
1783 +Henk Schoneveld made a donation (2008/9).
1784 +Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
1785 +Francois Dupoux made a donation (2008/11).
1786 +Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
1787 + aufs2 GIT tree (2009/2).
1788 +William Grant made a donation (2009/3).
1789 +Patrick Lane made a donation (2009/4).
1790 +The Mail Archive (mail-archive.com) made donations (2009/5).
1791 +Nippy Networks (Ed Wildgoose) made a donation (2009/7).
1792 +New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
1793 +Pavel Pronskiy made a donation (2011/2).
1794 +Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
1795 + Networks (Ed Wildgoose) made a donation for hardware (2011/3).
1796 +Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
1798 +Sam Liddicott made a donation (2011/9).
1799 +Era Scarecrow made a donation (2013/4).
1800 +Bor Ratajc made a donation (2013/4).
1801 +Alessandro Gorreta made a donation (2013/4).
1802 +POIRETTE Marc made a donation (2013/4).
1803 +Alessandro Gorreta made a donation (2013/4).
1804 +lauri kasvandik made a donation (2013/5).
1805 +pemasu from Finland made a donation (2013/7).
1807 +Thank you very much.
1808 +Donations are always, including future donations, very important and
1809 +helpful for me to keep on developing aufs.
1813 +----------------------------------------
1814 +If you are an experienced user, no explanation is needed. Aufs is
1815 +just a linux filesystem.
1820 +# Local variables: ;
1823 diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
1824 --- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
1825 +++ linux/fs/aufs/aufs.h 2013-07-06 13:20:47.736864659 +0200
1828 + * Copyright (C) 2005-2013 Junjiro R. Okajima
1830 + * This program, aufs is free software; you can redistribute it and/or modify
1831 + * it under the terms of the GNU General Public License as published by
1832 + * the Free Software Foundation; either version 2 of the License, or
1833 + * (at your option) any later version.
1835 + * This program is distributed in the hope that it will be useful,
1836 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1837 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1838 + * GNU General Public License for more details.
1840 + * You should have received a copy of the GNU General Public License
1841 + * along with this program; if not, write to the Free Software
1842 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1846 + * all header files
1854 +#define AuStub(type, name, body, ...) \
1855 + static inline type name(__VA_ARGS__) { body; }
1857 +#define AuStubVoid(name, ...) \
1858 + AuStub(void, name, , __VA_ARGS__)
1859 +#define AuStubInt0(name, ...) \
1860 + AuStub(int, name, return 0, __VA_ARGS__)
1864 +#include "branch.h"
1867 +#include "dbgaufs.h"
1868 +#include "dentry.h"
1872 +#include "fstype.h"
1875 +#include "module.h"
1880 +#include "sysaufs.h"
1885 +#endif /* __KERNEL__ */
1886 +#endif /* __AUFS_H__ */
1887 diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
1888 --- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
1889 +++ linux/fs/aufs/branch.c 2013-07-30 22:42:55.839613269 +0200
1892 + * Copyright (C) 2005-2013 Junjiro R. Okajima
1894 + * This program, aufs is free software; you can redistribute it and/or modify
1895 + * it under the terms of the GNU General Public License as published by
1896 + * the Free Software Foundation; either version 2 of the License, or
1897 + * (at your option) any later version.
1899 + * This program is distributed in the hope that it will be useful,
1900 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1901 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1902 + * GNU General Public License for more details.
1904 + * You should have received a copy of the GNU General Public License
1905 + * along with this program; if not, write to the Free Software
1906 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1910 + * branch management
1913 +#include <linux/compat.h>
1914 +#include <linux/statfs.h>
1918 + * free a single branch
1921 +/* prohibit rmdir to the root of the branch */
1922 +/* todo: another new flag? */
1923 +static void au_br_dflags_force(struct au_branch *br)
1925 + struct dentry *h_dentry;
1927 + h_dentry = au_br_dentry(br);
1928 + spin_lock(&h_dentry->d_lock);
1929 + br->br_dflags = h_dentry->d_flags & DCACHE_MOUNTED;
1930 + h_dentry->d_flags |= DCACHE_MOUNTED;
1931 + spin_unlock(&h_dentry->d_lock);
1934 +/* restore its d_flags */
1935 +static void au_br_dflags_restore(struct au_branch *br)
1937 + struct dentry *h_dentry;
1939 + if (br->br_dflags)
1942 + h_dentry = au_br_dentry(br);
1943 + spin_lock(&h_dentry->d_lock);
1944 + h_dentry->d_flags &= ~DCACHE_MOUNTED;
1945 + spin_unlock(&h_dentry->d_lock);
1948 +static void au_br_do_free(struct au_branch *br)
1951 + struct au_wbr *wbr;
1952 + struct au_dykey **key;
1954 + au_hnotify_fin_br(br);
1956 + if (br->br_xino.xi_file)
1957 + fput(br->br_xino.xi_file);
1958 + mutex_destroy(&br->br_xino.xi_nondir_mtx);
1960 + AuDebugOn(atomic_read(&br->br_count));
1964 + for (i = 0; i < AuBrWh_Last; i++)
1965 + dput(wbr->wbr_wh[i]);
1966 + AuDebugOn(atomic_read(&wbr->wbr_wh_running));
1967 + AuRwDestroy(&wbr->wbr_wh_rwsem);
1970 + key = br->br_dykey;
1971 + for (i = 0; i < AuBrDynOp; i++, key++)
1977 + au_br_dflags_restore(br);
1979 + /* recursive lock, s_umount of branch's */
1981 + path_put(&br->br_path);
1988 + * frees all branches
1990 +void au_br_free(struct au_sbinfo *sbinfo)
1992 + aufs_bindex_t bmax;
1993 + struct au_branch **br;
1995 + AuRwMustWriteLock(&sbinfo->si_rwsem);
1997 + bmax = sbinfo->si_bend + 1;
1998 + br = sbinfo->si_branch;
2000 + au_br_do_free(*br++);
2004 + * find the index of a branch which is specified by @br_id.
2006 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2008 + aufs_bindex_t bindex, bend;
2010 + bend = au_sbend(sb);
2011 + for (bindex = 0; bindex <= bend; bindex++)
2012 + if (au_sbr_id(sb, bindex) == br_id)
2017 +/* ---------------------------------------------------------------------- */
2023 +static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2024 + struct dentry *h_root)
2026 + if (unlikely(h_adding == h_root
2027 + || au_test_loopback_overlap(sb, h_adding)))
2029 + if (h_adding->d_sb != h_root->d_sb)
2031 + return au_test_subdir(h_adding, h_root)
2032 + || au_test_subdir(h_root, h_adding);
2036 + * returns a newly allocated branch. @new_nbranch is a number of branches
2037 + * after adding a branch.
2039 +static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2042 + struct au_branch *add_branch;
2043 + struct dentry *root;
2047 + root = sb->s_root;
2048 + add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2049 + if (unlikely(!add_branch))
2052 + err = au_hnotify_init_br(add_branch, perm);
2053 + if (unlikely(err))
2056 + add_branch->br_wbr = NULL;
2057 + if (au_br_writable(perm)) {
2058 + /* may be freed separately at changing the branch permission */
2059 + add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2061 + if (unlikely(!add_branch->br_wbr))
2065 + err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2067 + err = au_di_realloc(au_di(root), new_nbranch);
2069 + err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
2071 + return add_branch; /* success */
2073 + kfree(add_branch->br_wbr);
2076 + au_hnotify_fin_br(add_branch);
2078 + kfree(add_branch);
2080 + return ERR_PTR(err);
2084 + * test if the branch permission is legal or not.
2086 +static int test_br(struct inode *inode, int brperm, char *path)
2090 + err = (au_br_writable(brperm) && IS_RDONLY(inode));
2095 + pr_err("write permission for readonly mount or inode, %s\n", path);
2103 + * 0: success, the caller will add it
2104 + * plus: success, it is already unified, the caller should ignore it
2107 +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2110 + aufs_bindex_t bend, bindex;
2111 + struct dentry *root;
2112 + struct inode *inode, *h_inode;
2114 + root = sb->s_root;
2115 + bend = au_sbend(sb);
2116 + if (unlikely(bend >= 0
2117 + && au_find_dbindex(root, add->path.dentry) >= 0)) {
2121 + pr_err("%s duplicated\n", add->pathname);
2126 + err = -ENOSPC; /* -E2BIG; */
2127 + if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2128 + || AUFS_BRANCH_MAX - 1 <= bend)) {
2129 + pr_err("number of branches exceeded %s\n", add->pathname);
2134 + if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
2135 + pr_err("bad index %d\n", add->bindex);
2139 + inode = add->path.dentry->d_inode;
2141 + if (unlikely(!inode->i_nlink)) {
2142 + pr_err("no existence %s\n", add->pathname);
2147 + if (unlikely(inode->i_sb == sb)) {
2148 + pr_err("%s must be outside\n", add->pathname);
2152 + if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
2153 + pr_err("unsupported filesystem, %s (%s)\n",
2154 + add->pathname, au_sbtype(inode->i_sb));
2158 + err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2159 + if (unlikely(err))
2163 + return 0; /* success */
2166 + for (bindex = 0; bindex <= bend; bindex++)
2167 + if (unlikely(test_overlap(sb, add->path.dentry,
2168 + au_h_dptr(root, bindex)))) {
2169 + pr_err("%s is overlapped\n", add->pathname);
2174 + if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2175 + h_inode = au_h_dptr(root, 0)->d_inode;
2176 + if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
2177 + || !uid_eq(h_inode->i_uid, inode->i_uid)
2178 + || !gid_eq(h_inode->i_gid, inode->i_gid))
2179 + pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2181 + i_uid_read(inode), i_gid_read(inode),
2182 + (inode->i_mode & S_IALLUGO),
2183 + i_uid_read(h_inode), i_gid_read(h_inode),
2184 + (h_inode->i_mode & S_IALLUGO));
2192 + * initialize or clean the whiteouts for an adding branch
2194 +static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
2197 + int err, old_perm;
2198 + aufs_bindex_t bindex;
2199 + struct mutex *h_mtx;
2200 + struct au_wbr *wbr;
2201 + struct au_hinode *hdir;
2203 + err = vfsub_mnt_want_write(au_br_mnt(br));
2204 + if (unlikely(err))
2208 + old_perm = br->br_perm;
2209 + br->br_perm = new_perm;
2212 + bindex = au_br_index(sb, br->br_id);
2213 + if (0 <= bindex) {
2214 + hdir = au_hi(sb->s_root->d_inode, bindex);
2215 + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
2217 + h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
2218 + mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2221 + err = au_wh_init(br, sb);
2223 + wbr_wh_write_lock(wbr);
2224 + err = au_wh_init(br, sb);
2225 + wbr_wh_write_unlock(wbr);
2228 + au_hn_imtx_unlock(hdir);
2230 + mutex_unlock(h_mtx);
2231 + vfsub_mnt_drop_write(au_br_mnt(br));
2232 + br->br_perm = old_perm;
2234 + if (!err && wbr && !au_br_writable(new_perm)) {
2236 + br->br_wbr = NULL;
2243 +static int au_wbr_init(struct au_branch *br, struct super_block *sb,
2247 + struct kstatfs kst;
2248 + struct au_wbr *wbr;
2251 + au_rw_init(&wbr->wbr_wh_rwsem);
2252 + memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2253 + atomic_set(&wbr->wbr_wh_running, 0);
2254 + wbr->wbr_bytes = 0;
2257 + * a limit for rmdir/rename a dir
2258 + * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h
2260 + err = vfs_statfs(&br->br_path, &kst);
2261 + if (unlikely(err))
2264 + if (kst.f_namelen >= NAME_MAX)
2265 + err = au_br_init_wh(sb, br, perm);
2267 + pr_err("%.*s(%s), unsupported namelen %ld\n",
2268 + AuDLNPair(au_br_dentry(br)),
2269 + au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
2275 +/* intialize a new branch */
2276 +static int au_br_init(struct au_branch *br, struct super_block *sb,
2277 + struct au_opt_add *add)
2282 + memset(&br->br_xino, 0, sizeof(br->br_xino));
2283 + mutex_init(&br->br_xino.xi_nondir_mtx);
2284 + br->br_perm = add->perm;
2285 + BUILD_BUG_ON(sizeof(br->br_dflags)
2286 + != sizeof(br->br_path.dentry->d_flags));
2287 + br->br_dflags = DCACHE_MOUNTED;
2288 + br->br_path = add->path; /* set first, path_get() later */
2289 + spin_lock_init(&br->br_dykey_lock);
2290 + memset(br->br_dykey, 0, sizeof(br->br_dykey));
2291 + atomic_set(&br->br_count, 0);
2292 + br->br_xino_upper = AUFS_XINO_TRUNC_INIT;
2293 + atomic_set(&br->br_xino_running, 0);
2294 + br->br_id = au_new_br_id(sb);
2295 + AuDebugOn(br->br_id < 0);
2297 + if (au_br_writable(add->perm)) {
2298 + err = au_wbr_init(br, sb, add->perm);
2299 + if (unlikely(err))
2303 + if (au_opt_test(au_mntflags(sb), XINO)) {
2304 + err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
2305 + au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
2306 + if (unlikely(err)) {
2307 + AuDebugOn(br->br_xino.xi_file);
2312 + sysaufs_br_init(br);
2313 + path_get(&br->br_path);
2314 + goto out; /* success */
2317 + memset(&br->br_path, 0, sizeof(br->br_path));
2322 +static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
2323 + struct au_branch *br, aufs_bindex_t bend,
2324 + aufs_bindex_t amount)
2326 + struct au_branch **brp;
2328 + AuRwMustWriteLock(&sbinfo->si_rwsem);
2330 + brp = sbinfo->si_branch + bindex;
2331 + memmove(brp + 1, brp, sizeof(*brp) * amount);
2333 + sbinfo->si_bend++;
2334 + if (unlikely(bend < 0))
2335 + sbinfo->si_bend = 0;
2338 +static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
2339 + aufs_bindex_t bend, aufs_bindex_t amount)
2341 + struct au_hdentry *hdp;
2343 + AuRwMustWriteLock(&dinfo->di_rwsem);
2345 + hdp = dinfo->di_hdentry + bindex;
2346 + memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
2347 + au_h_dentry_init(hdp);
2349 + if (unlikely(bend < 0))
2350 + dinfo->di_bstart = 0;
2353 +static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
2354 + aufs_bindex_t bend, aufs_bindex_t amount)
2356 + struct au_hinode *hip;
2358 + AuRwMustWriteLock(&iinfo->ii_rwsem);
2360 + hip = iinfo->ii_hinode + bindex;
2361 + memmove(hip + 1, hip, sizeof(*hip) * amount);
2362 + hip->hi_inode = NULL;
2365 + if (unlikely(bend < 0))
2366 + iinfo->ii_bstart = 0;
2369 +static void au_br_do_add(struct super_block *sb, struct au_branch *br,
2370 + aufs_bindex_t bindex)
2372 + struct dentry *root, *h_dentry;
2373 + struct inode *root_inode;
2374 + aufs_bindex_t bend, amount;
2376 + au_br_dflags_force(br);
2378 + root = sb->s_root;
2379 + root_inode = root->d_inode;
2380 + bend = au_sbend(sb);
2381 + amount = bend + 1 - bindex;
2382 + h_dentry = au_br_dentry(br);
2383 + au_sbilist_lock();
2384 + au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
2385 + au_br_do_add_hdp(au_di(root), bindex, bend, amount);
2386 + au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
2387 + au_set_h_dptr(root, bindex, dget(h_dentry));
2388 + au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
2390 + au_sbilist_unlock();
2393 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
2396 + aufs_bindex_t bend, add_bindex;
2397 + struct dentry *root, *h_dentry;
2398 + struct inode *root_inode;
2399 + struct au_branch *add_branch;
2401 + root = sb->s_root;
2402 + root_inode = root->d_inode;
2403 + IMustLock(root_inode);
2404 + err = test_add(sb, add, remount);
2405 + if (unlikely(err < 0))
2409 + goto out; /* success */
2412 + bend = au_sbend(sb);
2413 + add_branch = au_br_alloc(sb, bend + 2, add->perm);
2414 + err = PTR_ERR(add_branch);
2415 + if (IS_ERR(add_branch))
2418 + err = au_br_init(add_branch, sb, add);
2419 + if (unlikely(err)) {
2420 + au_br_do_free(add_branch);
2424 + add_bindex = add->bindex;
2426 + au_br_do_add(sb, add_branch, add_bindex);
2428 + sysaufs_brs_del(sb, add_bindex);
2429 + au_br_do_add(sb, add_branch, add_bindex);
2430 + sysaufs_brs_add(sb, add_bindex);
2433 + h_dentry = add->path.dentry;
2434 + if (!add_bindex) {
2435 + au_cpup_attr_all(root_inode, /*force*/1);
2436 + sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
2438 + au_add_nlink(root_inode, h_dentry->d_inode);
2441 + * this test/set prevents aufs from handling unnecesary notify events
2442 + * of xino files, in case of re-adding a writable branch which was
2443 + * once detached from aufs.
2445 + if (au_xino_brid(sb) < 0
2446 + && au_br_writable(add_branch->br_perm)
2447 + && !au_test_fs_bad_xino(h_dentry->d_sb)
2448 + && add_branch->br_xino.xi_file
2449 + && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
2450 + au_xino_brid_set(sb, add_branch->br_id);
2456 +/* ---------------------------------------------------------------------- */
2462 +/* to show the line number, do not make it inlined function */
2463 +#define AuVerbose(do_info, fmt, ...) do { \
2465 + pr_info(fmt, ##__VA_ARGS__); \
2468 +static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
2469 + aufs_bindex_t bend)
2471 + return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
2474 +static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
2475 + aufs_bindex_t bend)
2477 + return au_test_ibusy(dentry->d_inode, bstart, bend);
2481 + * test if the branch is deletable or not.
2483 +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
2484 + unsigned int sigen, const unsigned int verbose)
2486 + int err, i, j, ndentry;
2487 + aufs_bindex_t bstart, bend;
2488 + struct au_dcsub_pages dpages;
2489 + struct au_dpage *dpage;
2492 + err = au_dpages_init(&dpages, GFP_NOFS);
2493 + if (unlikely(err))
2495 + err = au_dcsub_pages(&dpages, root, NULL, NULL);
2496 + if (unlikely(err))
2499 + for (i = 0; !err && i < dpages.ndpage; i++) {
2500 + dpage = dpages.dpages + i;
2501 + ndentry = dpage->ndentry;
2502 + for (j = 0; !err && j < ndentry; j++) {
2503 + d = dpage->dentries[j];
2504 + AuDebugOn(!d->d_count);
2505 + if (!au_digen_test(d, sigen)) {
2506 + di_read_lock_child(d, AuLock_IR);
2507 + if (unlikely(au_dbrange_test(d))) {
2508 + di_read_unlock(d, AuLock_IR);
2512 + di_write_lock_child(d);
2513 + if (unlikely(au_dbrange_test(d))) {
2514 + di_write_unlock(d);
2517 + err = au_reval_dpath(d, sigen);
2519 + di_downgrade_lock(d, AuLock_IR);
2521 + di_write_unlock(d);
2526 + /* AuDbgDentry(d); */
2527 + bstart = au_dbstart(d);
2528 + bend = au_dbend(d);
2529 + if (bstart <= bindex
2531 + && au_h_dptr(d, bindex)
2532 + && au_test_dbusy(d, bstart, bend)) {
2534 + AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
2537 + di_read_unlock(d, AuLock_IR);
2542 + au_dpages_free(&dpages);
2547 +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
2548 + unsigned int sigen, const unsigned int verbose)
2551 + unsigned long long max, ull;
2552 + struct inode *i, **array;
2553 + aufs_bindex_t bstart, bend;
2555 + array = au_iarray_alloc(sb, &max);
2556 + err = PTR_ERR(array);
2557 + if (IS_ERR(array))
2561 + AuDbg("b%d\n", bindex);
2562 + for (ull = 0; !err && ull < max; ull++) {
2564 + if (i->i_ino == AUFS_ROOT_INO)
2567 + /* AuDbgInode(i); */
2568 + if (au_iigen(i, NULL) == sigen)
2569 + ii_read_lock_child(i);
2571 + ii_write_lock_child(i);
2572 + err = au_refresh_hinode_self(i);
2575 + ii_downgrade_lock(i);
2577 + ii_write_unlock(i);
2582 + bstart = au_ibstart(i);
2583 + bend = au_ibend(i);
2584 + if (bstart <= bindex
2586 + && au_h_iptr(i, bindex)
2587 + && au_test_ibusy(i, bstart, bend)) {
2589 + AuVerbose(verbose, "busy i%lu\n", i->i_ino);
2592 + ii_read_unlock(i);
2594 + au_iarray_free(array, max);
2600 +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
2601 + const unsigned int verbose)
2604 + unsigned int sigen;
2606 + sigen = au_sigen(root->d_sb);
2607 + DiMustNoWaiters(root);
2608 + IiMustNoWaiters(root->d_inode);
2609 + di_write_unlock(root);
2610 + err = test_dentry_busy(root, bindex, sigen, verbose);
2612 + err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
2613 + di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
2618 +static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
2619 + const aufs_bindex_t bindex,
2620 + const aufs_bindex_t bend)
2622 + struct au_branch **brp, **p;
2624 + AuRwMustWriteLock(&sbinfo->si_rwsem);
2626 + brp = sbinfo->si_branch + bindex;
2627 + if (bindex < bend)
2628 + memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
2629 + sbinfo->si_branch[0 + bend] = NULL;
2630 + sbinfo->si_bend--;
2632 + p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
2634 + sbinfo->si_branch = p;
2635 + /* harmless error */
2638 +static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
2639 + const aufs_bindex_t bend)
2641 + struct au_hdentry *hdp, *p;
2643 + AuRwMustWriteLock(&dinfo->di_rwsem);
2645 + hdp = dinfo->di_hdentry;
2646 + if (bindex < bend)
2647 + memmove(hdp + bindex, hdp + bindex + 1,
2648 + sizeof(*hdp) * (bend - bindex));
2649 + hdp[0 + bend].hd_dentry = NULL;
2652 + p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
2654 + dinfo->di_hdentry = p;
2655 + /* harmless error */
2658 +static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
2659 + const aufs_bindex_t bend)
2661 + struct au_hinode *hip, *p;
2663 + AuRwMustWriteLock(&iinfo->ii_rwsem);
2665 + hip = iinfo->ii_hinode + bindex;
2666 + if (bindex < bend)
2667 + memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
2668 + iinfo->ii_hinode[0 + bend].hi_inode = NULL;
2669 + au_hn_init(iinfo->ii_hinode + bend);
2672 + p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
2674 + iinfo->ii_hinode = p;
2675 + /* harmless error */
2678 +static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
2679 + struct au_branch *br)
2681 + aufs_bindex_t bend;
2682 + struct au_sbinfo *sbinfo;
2683 + struct dentry *root, *h_root;
2684 + struct inode *inode, *h_inode;
2685 + struct au_hinode *hinode;
2687 + SiMustWriteLock(sb);
2689 + root = sb->s_root;
2690 + inode = root->d_inode;
2691 + sbinfo = au_sbi(sb);
2692 + bend = sbinfo->si_bend;
2694 + h_root = au_h_dptr(root, bindex);
2695 + hinode = au_hi(inode, bindex);
2696 + h_inode = au_igrab(hinode->hi_inode);
2699 + au_sbilist_lock();
2700 + au_br_do_del_brp(sbinfo, bindex, bend);
2701 + au_br_do_del_hdp(au_di(root), bindex, bend);
2702 + au_br_do_del_hip(au_ii(inode), bindex, bend);
2703 + au_sbilist_unlock();
2707 + au_br_do_free(br);
2710 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
2713 + unsigned int mnt_flags;
2714 + aufs_bindex_t bindex, bend, br_id;
2715 + unsigned char do_wh, verbose;
2716 + struct au_branch *br;
2717 + struct au_wbr *wbr;
2720 + bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
2723 + goto out; /* success */
2725 + pr_err("%s no such branch\n", del->pathname);
2728 + AuDbg("bindex b%d\n", bindex);
2731 + mnt_flags = au_mntflags(sb);
2732 + verbose = !!au_opt_test(mnt_flags, VERBOSE);
2733 + bend = au_sbend(sb);
2734 + if (unlikely(!bend)) {
2735 + AuVerbose(verbose, "no more branches left\n");
2738 + br = au_sbr(sb, bindex);
2739 + AuDebugOn(!path_equal(&br->br_path, &del->h_path));
2740 + i = atomic_read(&br->br_count);
2741 + if (unlikely(i)) {
2742 + AuVerbose(verbose, "%d file(s) opened\n", i);
2747 + do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
2749 + /* instead of WbrWhMustWriteLock(wbr) */
2750 + SiMustWriteLock(sb);
2751 + for (i = 0; i < AuBrWh_Last; i++) {
2752 + dput(wbr->wbr_wh[i]);
2753 + wbr->wbr_wh[i] = NULL;
2757 + err = test_children_busy(sb->s_root, bindex, verbose);
2758 + if (unlikely(err)) {
2765 + br_id = br->br_id;
2767 + au_br_do_del(sb, bindex, br);
2769 + sysaufs_brs_del(sb, bindex);
2770 + au_br_do_del(sb, bindex, br);
2771 + sysaufs_brs_add(sb, bindex);
2775 + au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
2776 + sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
2778 + au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
2779 + if (au_opt_test(mnt_flags, PLINK))
2780 + au_plink_half_refresh(sb, br_id);
2782 + if (au_xino_brid(sb) == br_id)
2783 + au_xino_brid_set(sb, -1);
2784 + goto out; /* success */
2788 + rerr = au_br_init_wh(sb, br, br->br_perm);
2790 + pr_warn("failed re-creating base whiteout, %s. (%d)\n",
2791 + del->pathname, rerr);
2796 +/* ---------------------------------------------------------------------- */
2798 +static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
2801 + aufs_bindex_t bstart, bend;
2802 + struct aufs_ibusy ibusy;
2803 + struct inode *inode, *h_inode;
2806 + if (unlikely(!capable(CAP_SYS_ADMIN)))
2809 + err = copy_from_user(&ibusy, arg, sizeof(ibusy));
2811 + err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
2812 + if (unlikely(err)) {
2819 + si_read_lock(sb, AuLock_FLUSH);
2820 + if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
2824 + ibusy.h_ino = 0; /* invalid */
2825 + inode = ilookup(sb, ibusy.ino);
2827 + || inode->i_ino == AUFS_ROOT_INO
2828 + || is_bad_inode(inode))
2831 + ii_read_lock_child(inode);
2832 + bstart = au_ibstart(inode);
2833 + bend = au_ibend(inode);
2834 + if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
2835 + h_inode = au_h_iptr(inode, ibusy.bindex);
2836 + if (h_inode && au_test_ibusy(inode, bstart, bend))
2837 + ibusy.h_ino = h_inode->i_ino;
2839 + ii_read_unlock(inode);
2843 + si_read_unlock(sb);
2845 + err = __put_user(ibusy.h_ino, &arg->h_ino);
2846 + if (unlikely(err)) {
2855 +long au_ibusy_ioctl(struct file *file, unsigned long arg)
2857 + return au_ibusy(file->f_dentry->d_sb, (void __user *)arg);
2860 +#ifdef CONFIG_COMPAT
2861 +long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
2863 + return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg));
2867 +/* ---------------------------------------------------------------------- */
2870 + * change a branch permission
2873 +static void au_warn_ima(void)
2876 + /* since it doesn't support mark_files_ro() */
2877 + AuWarn1("RW -> RO makes IMA to produce wrong message\n");
2881 +static int do_need_sigen_inc(int a, int b)
2883 + return au_br_whable(a) && !au_br_whable(b);
2886 +static int need_sigen_inc(int old, int new)
2888 + return do_need_sigen_inc(old, new)
2889 + || do_need_sigen_inc(new, old);
2892 +static unsigned long long au_farray_cb(void *a,
2893 + unsigned long long max __maybe_unused,
2896 + unsigned long long n;
2897 + struct file **p, *f;
2898 + struct super_block *sb = arg;
2902 + lg_global_lock(&files_lglock);
2903 + do_file_list_for_each_entry(sb, f) {
2906 + && !special_file(file_inode(f)->i_mode)) {
2910 + AuDebugOn(n > max);
2912 + } while_file_list_for_each_entry;
2913 + lg_global_unlock(&files_lglock);
2918 +static struct file **au_farray_alloc(struct super_block *sb,
2919 + unsigned long long *max)
2921 + *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
2922 + return au_array_alloc(max, au_farray_cb, sb);
2925 +static void au_farray_free(struct file **a, unsigned long long max)
2927 + unsigned long long ull;
2929 + for (ull = 0; ull < max; ull++)
2935 +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
2938 + unsigned int mnt_flags;
2939 + unsigned long long ull, max;
2940 + aufs_bindex_t br_id;
2941 + unsigned char verbose;
2942 + struct file *file, *hf, **array;
2943 + struct inode *inode;
2944 + struct au_hfile *hfile;
2946 + mnt_flags = au_mntflags(sb);
2947 + verbose = !!au_opt_test(mnt_flags, VERBOSE);
2949 + array = au_farray_alloc(sb, &max);
2950 + err = PTR_ERR(array);
2951 + if (IS_ERR(array))
2955 + br_id = au_sbr_id(sb, bindex);
2956 + for (ull = 0; ull < max; ull++) {
2957 + file = array[ull];
2959 + /* AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); */
2960 + fi_read_lock(file);
2961 + if (unlikely(au_test_mmapped(file))) {
2963 + AuVerbose(verbose, "mmapped %.*s\n",
2964 + AuDLNPair(file->f_dentry));
2966 + FiMustNoWaiters(file);
2967 + fi_read_unlock(file);
2971 + inode = file_inode(file);
2972 + hfile = &au_fi(file)->fi_htop;
2973 + hf = hfile->hf_file;
2974 + if (!S_ISREG(inode->i_mode)
2975 + || !(file->f_mode & FMODE_WRITE)
2976 + || hfile->hf_br->br_id != br_id
2977 + || !(hf->f_mode & FMODE_WRITE))
2978 + array[ull] = NULL;
2984 + FiMustNoWaiters(file);
2985 + fi_read_unlock(file);
2993 + for (ull = 0; ull < max; ull++) {
2994 + file = array[ull];
2998 + /* todo: already flushed? */
2999 + /* cf. fs/super.c:mark_files_ro() */
3000 + /* fi_read_lock(file); */
3001 + hfile = &au_fi(file)->fi_htop;
3002 + hf = hfile->hf_file;
3003 + /* fi_read_unlock(file); */
3004 + spin_lock(&hf->f_lock);
3005 + hf->f_mode &= ~FMODE_WRITE;
3006 + spin_unlock(&hf->f_lock);
3007 + if (!file_check_writeable(hf)) {
3008 + __mnt_drop_write(hf->f_path.mnt);
3009 + file_release_write(hf);
3014 + au_farray_free(array, max);
3020 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
3024 + aufs_bindex_t bindex;
3025 + struct dentry *root;
3026 + struct au_branch *br;
3028 + root = sb->s_root;
3029 + bindex = au_find_dbindex(root, mod->h_root);
3032 + return 0; /* success */
3034 + pr_err("%s no such branch\n", mod->path);
3037 + AuDbg("bindex b%d\n", bindex);
3039 + err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
3040 + if (unlikely(err))
3043 + br = au_sbr(sb, bindex);
3044 + AuDebugOn(mod->h_root != au_br_dentry(br));
3045 + if (br->br_perm == mod->perm)
3046 + return 0; /* success */
3048 + if (au_br_writable(br->br_perm)) {
3049 + /* remove whiteout base */
3050 + err = au_br_init_wh(sb, br, mod->perm);
3051 + if (unlikely(err))
3054 + if (!au_br_writable(mod->perm)) {
3055 + /* rw --> ro, file might be mmapped */
3056 + DiMustNoWaiters(root);
3057 + IiMustNoWaiters(root->d_inode);
3058 + di_write_unlock(root);
3059 + err = au_br_mod_files_ro(sb, bindex);
3060 + /* aufs_write_lock() calls ..._child() */
3061 + di_write_lock_child(root);
3063 + if (unlikely(err)) {
3065 + br->br_wbr = kmalloc(sizeof(*br->br_wbr),
3068 + rerr = au_wbr_init(br, sb, br->br_perm);
3069 + if (unlikely(rerr)) {
3070 + AuIOErr("nested error %d (%d)\n",
3072 + br->br_perm = mod->perm;
3076 + } else if (au_br_writable(mod->perm)) {
3079 + br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
3081 + err = au_wbr_init(br, sb, mod->perm);
3082 + if (unlikely(err)) {
3083 + kfree(br->br_wbr);
3084 + br->br_wbr = NULL;
3090 + if ((br->br_perm & AuBrAttr_UNPIN)
3091 + && !(mod->perm & AuBrAttr_UNPIN))
3092 + au_br_dflags_force(br);
3093 + else if (!(br->br_perm & AuBrAttr_UNPIN)
3094 + && (mod->perm & AuBrAttr_UNPIN))
3095 + au_br_dflags_restore(br);
3096 + *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
3097 + br->br_perm = mod->perm;
3104 diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
3105 --- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
3106 +++ linux/fs/aufs/branch.h 2013-07-06 13:20:47.740198107 +0200
3109 + * Copyright (C) 2005-2013 Junjiro R. Okajima
3111 + * This program, aufs is free software; you can redistribute it and/or modify
3112 + * it under the terms of the GNU General Public License as published by
3113 + * the Free Software Foundation; either version 2 of the License, or
3114 + * (at your option) any later version.
3116 + * This program is distributed in the hope that it will be useful,
3117 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3118 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3119 + * GNU General Public License for more details.
3121 + * You should have received a copy of the GNU General Public License
3122 + * along with this program; if not, write to the Free Software
3123 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3127 + * branch filesystems and xino for them
3130 +#ifndef __AUFS_BRANCH_H__
3131 +#define __AUFS_BRANCH_H__
3135 +#include <linux/mount.h>
3140 +/* ---------------------------------------------------------------------- */
3143 +struct au_xino_file {
3144 + struct file *xi_file;
3145 + struct mutex xi_nondir_mtx;
3147 + /* todo: make xino files an array to support huge inode number */
3149 +#ifdef CONFIG_DEBUG_FS
3150 + struct dentry *xi_dbgaufs;
3154 +/* members for writable branch only */
3155 +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
3157 + struct au_rwsem wbr_wh_rwsem;
3158 + struct dentry *wbr_wh[AuBrWh_Last];
3159 + atomic_t wbr_wh_running;
3160 +#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
3161 +#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
3162 +#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
3165 + unsigned long long wbr_bytes;
3168 +/* ext2 has 3 types of operations at least, ext3 has 4 */
3169 +#define AuBrDynOp (AuDyLast * 4)
3171 +#ifdef CONFIG_AUFS_HFSNOTIFY
3172 +/* support for asynchronous destruction */
3173 +struct au_br_hfsnotify {
3174 + struct fsnotify_group *hfsn_group;
3178 +/* protected by superblock rwsem */
3180 + struct au_xino_file br_xino;
3182 + aufs_bindex_t br_id;
3185 + unsigned int br_dflags;
3186 + struct path br_path;
3187 + spinlock_t br_dykey_lock;
3188 + struct au_dykey *br_dykey[AuBrDynOp];
3189 + atomic_t br_count;
3191 + struct au_wbr *br_wbr;
3193 + /* xino truncation */
3194 + blkcnt_t br_xino_upper; /* watermark in blocks */
3195 + atomic_t br_xino_running;
3197 +#ifdef CONFIG_AUFS_HFSNOTIFY
3198 + struct au_br_hfsnotify *br_hfsn;
3201 +#ifdef CONFIG_SYSFS
3202 + /* an entry under sysfs per mount-point */
3204 + struct attribute br_attr;
3208 +/* ---------------------------------------------------------------------- */
3210 +static inline struct vfsmount *au_br_mnt(struct au_branch *br)
3212 + return br->br_path.mnt;
3215 +static inline struct dentry *au_br_dentry(struct au_branch *br)
3217 + return br->br_path.dentry;
3220 +static inline struct super_block *au_br_sb(struct au_branch *br)
3222 + return au_br_mnt(br)->mnt_sb;
3225 +/* branch permissions and attributes */
3226 +#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
3227 +#define AuBrPerm_RO (1 << 1) /* readonly */
3228 +#define AuBrPerm_RR (1 << 2) /* natively readonly */
3229 +#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
3231 +#define AuBrRAttr_WH (1 << 3) /* whiteout-able */
3233 +#define AuBrWAttr_NoLinkWH (1 << 4) /* un-hardlinkable whiteouts */
3235 +#define AuBrAttr_UNPIN (1 << 5) /* rename-able top dir of
3238 +static inline int au_br_writable(int brperm)
3240 + return brperm & AuBrPerm_RW;
3243 +static inline int au_br_whable(int brperm)
3245 + return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
3248 +static inline int au_br_wh_linkable(int brperm)
3250 + return !(brperm & AuBrWAttr_NoLinkWH);
3253 +static inline int au_br_rdonly(struct au_branch *br)
3255 + return ((au_br_sb(br)->s_flags & MS_RDONLY)
3256 + || !au_br_writable(br->br_perm))
3260 +static inline int au_br_hnotifyable(int brperm __maybe_unused)
3262 +#ifdef CONFIG_AUFS_HNOTIFY
3263 + return !(brperm & AuBrPerm_RR);
3269 +/* ---------------------------------------------------------------------- */
3273 +void au_br_free(struct au_sbinfo *sinfo);
3274 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
3276 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
3278 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
3279 +long au_ibusy_ioctl(struct file *file, unsigned long arg);
3280 +#ifdef CONFIG_COMPAT
3281 +long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
3284 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
3288 +static const loff_t au_loff_max = LLONG_MAX;
3290 +int au_xib_trunc(struct super_block *sb);
3291 +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
3293 +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
3295 +struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
3296 +struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
3297 +ino_t au_xino_new_ino(struct super_block *sb);
3298 +void au_xino_delete_inode(struct inode *inode, const int unlinked);
3299 +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3301 +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3303 +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
3304 + struct file *base_file, int do_test);
3305 +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
3307 +struct au_opt_xino;
3308 +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
3309 +void au_xino_clr(struct super_block *sb);
3310 +struct file *au_xino_def(struct super_block *sb);
3311 +int au_xino_path(struct seq_file *seq, struct file *file);
3313 +/* ---------------------------------------------------------------------- */
3315 +/* Superblock to branch */
3317 +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
3319 + return au_sbr(sb, bindex)->br_id;
3323 +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
3325 + return au_br_mnt(au_sbr(sb, bindex));
3329 +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
3331 + return au_br_sb(au_sbr(sb, bindex));
3334 +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
3336 + atomic_dec(&au_sbr(sb, bindex)->br_count);
3339 +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
3341 + return au_sbr(sb, bindex)->br_perm;
3344 +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
3346 + return au_br_whable(au_sbr_perm(sb, bindex));
3349 +/* ---------------------------------------------------------------------- */
3352 + * wbr_wh_read_lock, wbr_wh_write_lock
3353 + * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
3355 +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
3357 +#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
3358 +#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
3359 +#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
3361 +#endif /* __KERNEL__ */
3362 +#endif /* __AUFS_BRANCH_H__ */
3363 diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
3364 --- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
3365 +++ linux/fs/aufs/conf.mk 2013-07-06 13:20:47.740198107 +0200
3368 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
3372 +AuConfStr += ${1}=${${1}}
3376 +AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
3378 + HNOTIFY HFSNOTIFY \
3389 +$(foreach i, ${AuConfAll}, \
3390 + $(eval $(call AuConf,CONFIG_AUFS_${i})))
3392 +AuConfName = ${obj}/conf.str
3393 +${AuConfName}.tmp: FORCE
3394 + @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
3395 +${AuConfName}: ${AuConfName}.tmp
3396 + @diff -q $< $@ > /dev/null 2>&1 || { \
3397 + echo ' GEN ' $@; \
3401 +clean-files += ${AuConfName} ${AuConfName}.tmp
3402 +${obj}/sysfs.o: ${AuConfName}
3404 +-include ${srctree}/${src}/conf_priv.mk
3405 diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
3406 --- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
3407 +++ linux/fs/aufs/cpup.c 2013-07-30 22:42:46.232612606 +0200
3410 + * Copyright (C) 2005-2013 Junjiro R. Okajima
3412 + * This program, aufs is free software; you can redistribute it and/or modify
3413 + * it under the terms of the GNU General Public License as published by
3414 + * the Free Software Foundation; either version 2 of the License, or
3415 + * (at your option) any later version.
3417 + * This program is distributed in the hope that it will be useful,
3418 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3419 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3420 + * GNU General Public License for more details.
3422 + * You should have received a copy of the GNU General Public License
3423 + * along with this program; if not, write to the Free Software
3424 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3428 + * copy-up functions, see wbr_policy.c for copy-down
3431 +#include <linux/fs_stack.h>
3432 +#include <linux/mm.h>
3435 +void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
3437 + const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
3438 + | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
3440 + BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
3442 + dst->i_flags |= iflags & ~mask;
3443 + if (au_test_fs_notime(dst->i_sb))
3444 + dst->i_flags |= S_NOATIME | S_NOCMTIME;
3447 +void au_cpup_attr_timesizes(struct inode *inode)
3449 + struct inode *h_inode;
3451 + h_inode = au_h_iptr(inode, au_ibstart(inode));
3452 + fsstack_copy_attr_times(inode, h_inode);
3453 + fsstack_copy_inode_size(inode, h_inode);
3456 +void au_cpup_attr_nlink(struct inode *inode, int force)
3458 + struct inode *h_inode;
3459 + struct super_block *sb;
3460 + aufs_bindex_t bindex, bend;
3463 + bindex = au_ibstart(inode);
3464 + h_inode = au_h_iptr(inode, bindex);
3466 + && !S_ISDIR(h_inode->i_mode)
3467 + && au_opt_test(au_mntflags(sb), PLINK)
3468 + && au_plink_test(inode))
3472 + * 0 can happen in revalidating.
3473 + * h_inode->i_mutex is not held, but it is harmless since once i_nlink
3474 + * reaches 0, it will never become positive.
3476 + set_nlink(inode, h_inode->i_nlink);
3479 + * fewer nlink makes find(1) noisy, but larger nlink doesn't.
3480 + * it may includes whplink directory.
3482 + if (S_ISDIR(h_inode->i_mode)) {
3483 + bend = au_ibend(inode);
3484 + for (bindex++; bindex <= bend; bindex++) {
3485 + h_inode = au_h_iptr(inode, bindex);
3487 + au_add_nlink(inode, h_inode);
3492 +void au_cpup_attr_changeable(struct inode *inode)
3494 + struct inode *h_inode;
3496 + h_inode = au_h_iptr(inode, au_ibstart(inode));
3497 + inode->i_mode = h_inode->i_mode;
3498 + inode->i_uid = h_inode->i_uid;
3499 + inode->i_gid = h_inode->i_gid;
3500 + au_cpup_attr_timesizes(inode);
3501 + au_cpup_attr_flags(inode, h_inode->i_flags);
3504 +void au_cpup_igen(struct inode *inode, struct inode *h_inode)
3506 + struct au_iinfo *iinfo = au_ii(inode);
3508 + IiMustWriteLock(inode);
3510 + iinfo->ii_higen = h_inode->i_generation;
3511 + iinfo->ii_hsb1 = h_inode->i_sb;
3514 +void au_cpup_attr_all(struct inode *inode, int force)
3516 + struct inode *h_inode;
3518 + h_inode = au_h_iptr(inode, au_ibstart(inode));
3519 + au_cpup_attr_changeable(inode);
3520 + if (inode->i_nlink > 0)
3521 + au_cpup_attr_nlink(inode, force);
3522 + inode->i_rdev = h_inode->i_rdev;
3523 + inode->i_blkbits = h_inode->i_blkbits;
3524 + au_cpup_igen(inode, h_inode);
3527 +/* ---------------------------------------------------------------------- */
3529 +/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
3531 +/* keep the timestamps of the parent dir when cpup */
3532 +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
3533 + struct path *h_path)
3535 + struct inode *h_inode;
3537 + dt->dt_dentry = dentry;
3538 + dt->dt_h_path = *h_path;
3539 + h_inode = h_path->dentry->d_inode;
3540 + dt->dt_atime = h_inode->i_atime;
3541 + dt->dt_mtime = h_inode->i_mtime;
3545 +void au_dtime_revert(struct au_dtime *dt)
3547 + struct iattr attr;
3550 + attr.ia_atime = dt->dt_atime;
3551 + attr.ia_mtime = dt->dt_mtime;
3552 + attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
3553 + | ATTR_ATIME | ATTR_ATIME_SET;
3555 + err = vfsub_notify_change(&dt->dt_h_path, &attr);
3556 + if (unlikely(err))
3557 + pr_warn("restoring timestamps failed(%d). ignored\n", err);
3560 +/* ---------------------------------------------------------------------- */
3562 +/* internal use only */
3563 +struct au_cpup_reg_attr {
3566 + unsigned int iflags; /* inode->i_flags */
3569 +static noinline_for_stack
3570 +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
3571 + struct au_cpup_reg_attr *h_src_attr)
3575 + struct path h_path;
3576 + struct inode *h_isrc, *h_idst;
3577 + struct kstat *h_st;
3579 + h_path.dentry = au_h_dptr(dst, bindex);
3580 + h_idst = h_path.dentry->d_inode;
3581 + h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
3582 + h_isrc = h_src->d_inode;
3583 + ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
3584 + | ATTR_ATIME | ATTR_MTIME
3585 + | ATTR_ATIME_SET | ATTR_MTIME_SET;
3586 + if (h_src_attr && h_src_attr->valid) {
3587 + h_st = &h_src_attr->st;
3588 + ia.ia_uid = h_st->uid;
3589 + ia.ia_gid = h_st->gid;
3590 + ia.ia_atime = h_st->atime;
3591 + ia.ia_mtime = h_st->mtime;
3592 + if (h_idst->i_mode != h_st->mode
3593 + && !S_ISLNK(h_idst->i_mode)) {
3594 + ia.ia_valid |= ATTR_MODE;
3595 + ia.ia_mode = h_st->mode;
3597 + sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
3598 + au_cpup_attr_flags(h_idst, h_src_attr->iflags);
3600 + ia.ia_uid = h_isrc->i_uid;
3601 + ia.ia_gid = h_isrc->i_gid;
3602 + ia.ia_atime = h_isrc->i_atime;
3603 + ia.ia_mtime = h_isrc->i_mtime;
3604 + if (h_idst->i_mode != h_isrc->i_mode
3605 + && !S_ISLNK(h_idst->i_mode)) {
3606 + ia.ia_valid |= ATTR_MODE;
3607 + ia.ia_mode = h_isrc->i_mode;
3609 + sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
3610 + au_cpup_attr_flags(h_idst, h_isrc->i_flags);
3612 + err = vfsub_notify_change(&h_path, &ia);
3614 + /* is this nfs only? */
3615 + if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
3616 + ia.ia_valid = ATTR_FORCE | ATTR_MODE;
3617 + ia.ia_mode = h_isrc->i_mode;
3618 + err = vfsub_notify_change(&h_path, &ia);
3624 +/* ---------------------------------------------------------------------- */
3626 +static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
3627 + char *buf, unsigned long blksize)
3630 + size_t sz, rbytes, wbytes;
3631 + unsigned char all_zero;
3633 + struct mutex *h_mtx;
3634 + /* reduce stack usage */
3637 + zp = page_address(ZERO_PAGE(0));
3638 + if (unlikely(!zp))
3639 + return -ENOMEM; /* possible? */
3644 + AuDbg("len %lld\n", len);
3646 + if (len < blksize)
3650 + /* todo: signal_pending? */
3651 + while (!rbytes || err == -EAGAIN || err == -EINTR) {
3652 + rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
3655 + if (unlikely(err < 0))
3659 + if (len >= rbytes && rbytes == blksize)
3660 + all_zero = !memcmp(buf, zp, rbytes);
3667 + b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
3669 + /* todo: signal_pending? */
3670 + if (unlikely(err == -EAGAIN || err == -EINTR))
3672 + if (unlikely(err < 0))
3681 + res = vfsub_llseek(dst, rbytes, SEEK_CUR);
3683 + if (unlikely(res < 0))
3690 + /* the last block may be a hole */
3691 + if (!err && all_zero) {
3692 + AuLabel(last hole);
3695 + if (au_test_nfs(dst->f_dentry->d_sb)) {
3696 + /* nfs requires this step to make last hole */
3697 + /* is this only nfs? */
3699 + /* todo: signal_pending? */
3700 + err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
3701 + } while (err == -EAGAIN || err == -EINTR);
3708 + ia->ia_size = dst->f_pos;
3709 + ia->ia_valid = ATTR_SIZE | ATTR_FILE;
3710 + ia->ia_file = dst;
3711 + h_mtx = &file_inode(dst)->i_mutex;
3712 + mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
3713 + err = vfsub_notify_change(&dst->f_path, ia);
3714 + mutex_unlock(h_mtx);
3721 +int au_copy_file(struct file *dst, struct file *src, loff_t len)
3724 + unsigned long blksize;
3725 + unsigned char do_kfree;
3729 + blksize = dst->f_dentry->d_sb->s_blocksize;
3730 + if (!blksize || PAGE_SIZE < blksize)
3731 + blksize = PAGE_SIZE;
3732 + AuDbg("blksize %lu\n", blksize);
3733 + do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
3735 + buf = kmalloc(blksize, GFP_NOFS);
3737 + buf = (void *)__get_free_page(GFP_NOFS);
3738 + if (unlikely(!buf))
3741 + if (len > (1 << 22))
3742 + AuDbg("copying a large file %lld\n", (long long)len);
3746 + err = au_do_copy_file(dst, src, len, buf, blksize);
3750 + free_page((unsigned long)buf);
3756 +/* internal use only */
3757 +struct au_cpup_basic {
3758 + struct dentry *dentry;
3759 + aufs_bindex_t bdst, bsrc;
3764 + * to support a sparse file which is opened with O_APPEND,
3765 + * we need to close the file.
3767 +static int au_cp_regular(struct au_cpup_basic *basic)
3770 + enum { SRC, DST };
3772 + aufs_bindex_t bindex;
3773 + unsigned int flags;
3774 + struct dentry *dentry;
3775 + struct file *file;
3776 + void *label, *label_file;
3779 + .bindex = basic->bsrc,
3780 + .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
3783 + .label_file = &&out_src
3786 + .bindex = basic->bdst,
3787 + .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
3789 + .label = &&out_src,
3790 + .label_file = &&out_dst
3793 + struct super_block *sb;
3795 + /* bsrc branch can be ro/rw. */
3796 + sb = basic->dentry->d_sb;
3798 + for (i = 0; i < 2; i++, f++) {
3799 + f->dentry = au_h_dptr(basic->dentry, f->bindex);
3800 + f->file = au_h_open(basic->dentry, f->bindex, f->flags,
3802 + err = PTR_ERR(f->file);
3803 + if (IS_ERR(f->file))
3806 + if (unlikely(!f->file->f_op))
3807 + goto *f->label_file;
3810 + /* try stopping to update while we copyup */
3811 + IMustLock(file[SRC].dentry->d_inode);
3812 + err = au_copy_file(file[DST].file, file[SRC].file, basic->len);
3815 + fput(file[DST].file);
3816 + au_sbr_put(sb, file[DST].bindex);
3818 + fput(file[SRC].file);
3819 + au_sbr_put(sb, file[SRC].bindex);
3824 +static int au_do_cpup_regular(struct au_cpup_basic *basic, struct au_pin *pin,
3825 + struct au_cpup_reg_attr *h_src_attr)
3829 + struct path h_path;
3830 + struct inode *h_src_inode;
3833 + h_src_inode = au_h_iptr(basic->dentry->d_inode, basic->bsrc);
3834 + l = i_size_read(h_src_inode);
3835 + if (basic->len == -1 || l < basic->len)
3838 + /* try stopping to update while we are referencing */
3839 + mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
3840 + au_pin_hdir_unlock(pin);
3842 + h_path.dentry = au_h_dptr(basic->dentry, basic->bsrc);
3843 + h_path.mnt = au_sbr_mnt(basic->dentry->d_sb, basic->bsrc);
3844 + h_src_attr->iflags = h_src_inode->i_flags;
3845 + err = vfs_getattr(&h_path, &h_src_attr->st);
3846 + if (unlikely(err)) {
3847 + mutex_unlock(&h_src_inode->i_mutex);
3850 + h_src_attr->valid = 1;
3851 + err = au_cp_regular(basic);
3852 + mutex_unlock(&h_src_inode->i_mutex);
3853 + rerr = au_pin_hdir_relock(pin);
3862 +static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
3863 + struct inode *h_dir)
3866 + mm_segment_t old_fs;
3873 + if (unlikely(!h_src->d_inode->i_op->readlink))
3877 + sym.k = (void *)__get_free_page(GFP_NOFS);
3878 + if (unlikely(!sym.k))
3881 + /* unnecessary to support mmap_sem since symlink is not mmap-able */
3882 + old_fs = get_fs();
3883 + set_fs(KERNEL_DS);
3884 + symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
3889 + sym.k[symlen] = 0;
3890 + err = vfsub_symlink(h_dir, h_path, sym.k);
3892 + free_page((unsigned long)sym.k);
3898 +static noinline_for_stack
3899 +int cpup_entry(struct au_cpup_basic *basic, unsigned int flags,
3900 + struct dentry *dst_parent, struct au_pin *pin,
3901 + struct au_cpup_reg_attr *h_src_attr)
3905 + unsigned int mnt_flags;
3906 + unsigned char isdir;
3907 + const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME);
3908 + struct au_dtime dt;
3909 + struct path h_path;
3910 + struct dentry *h_src, *h_dst, *h_parent;
3911 + struct inode *h_inode, *h_dir;
3912 + struct super_block *sb;
3914 + /* bsrc branch can be ro/rw. */
3915 + h_src = au_h_dptr(basic->dentry, basic->bsrc);
3916 + h_inode = h_src->d_inode;
3917 + AuDebugOn(h_inode != au_h_iptr(basic->dentry->d_inode, basic->bsrc));
3919 + /* try stopping to be referenced while we are creating */
3920 + h_dst = au_h_dptr(basic->dentry, basic->bdst);
3921 + if (au_ftest_cpup(flags, RENAME))
3922 + AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
3923 + AUFS_WH_PFX_LEN));
3924 + h_parent = h_dst->d_parent; /* dir inode is locked */
3925 + h_dir = h_parent->d_inode;
3927 + AuDebugOn(h_parent != h_dst->d_parent);
3929 + sb = basic->dentry->d_sb;
3930 + h_path.mnt = au_sbr_mnt(sb, basic->bdst);
3932 + h_path.dentry = h_parent;
3933 + au_dtime_store(&dt, dst_parent, &h_path);
3935 + h_path.dentry = h_dst;
3938 + mode = h_inode->i_mode;
3939 + switch (mode & S_IFMT) {
3941 + err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
3942 + /*want_excl*/true);
3944 + err = au_do_cpup_regular(basic, pin, h_src_attr);
3948 + err = vfsub_mkdir(h_dir, &h_path, mode);
3951 + * strange behaviour from the users view,
3952 + * particularry setattr case
3954 + if (au_ibstart(dst_parent->d_inode) == basic->bdst)
3955 + au_cpup_attr_nlink(dst_parent->d_inode,
3957 + au_cpup_attr_nlink(basic->dentry->d_inode, /*force*/1);
3961 + err = au_do_cpup_symlink(&h_path, h_src, h_dir);
3965 + AuDebugOn(!capable(CAP_MKNOD));
3969 + err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
3972 + AuIOErr("Unknown inode type 0%o\n", mode);
3976 + mnt_flags = au_mntflags(sb);
3977 + if (!au_opt_test(mnt_flags, UDBA_NONE)
3979 + && au_opt_test(mnt_flags, XINO)
3980 + && h_inode->i_nlink == 1
3981 + /* todo: unnecessary? */
3982 + /* && basic->dentry->d_inode->i_nlink == 1 */
3983 + && basic->bdst < basic->bsrc
3984 + && !au_ftest_cpup(flags, KEEPLINO))
3985 + au_xino_write(sb, basic->bsrc, h_inode->i_ino, /*ino*/0);
3986 + /* ignore this error */
3989 + au_dtime_revert(&dt);
3993 +static int au_do_ren_after_cpup(struct dentry *dentry, aufs_bindex_t bdst,
3994 + struct path *h_path)
3997 + struct dentry *h_dentry, *h_parent;
3998 + struct inode *h_dir;
4000 + h_dentry = dget(au_h_dptr(dentry, bdst));
4001 + au_set_h_dptr(dentry, bdst, NULL);
4002 + err = au_lkup_neg(dentry, bdst, /*wh*/0);
4003 + if (unlikely(err)) {
4004 + au_set_h_dptr(dentry, bdst, h_dentry);
4008 + h_path->dentry = dget(au_h_dptr(dentry, bdst));
4009 + au_set_h_dptr(dentry, bdst, h_dentry);
4010 + h_parent = h_dentry->d_parent; /* dir inode is locked */
4011 + h_dir = h_parent->d_inode;
4013 + AuDbg("%.*s %.*s\n", AuDLNPair(h_dentry), AuDLNPair(h_path->dentry));
4014 + err = vfsub_rename(h_dir, h_dentry, h_dir, h_path);
4015 + dput(h_path->dentry);
4022 + * copyup the @dentry from @bsrc to @bdst.
4023 + * the caller must set the both of lower dentries.
4024 + * @len is for truncating when it is -1 copyup the entire file.
4025 + * in link/rename cases, @dst_parent may be different from the real one.
4027 +static int au_cpup_single(struct au_cpup_basic *basic, unsigned int flags,
4028 + struct dentry *dst_parent, struct au_pin *pin)
4031 + aufs_bindex_t old_ibstart;
4032 + unsigned char isdir, plink;
4033 + struct au_dtime dt;
4034 + struct path h_path;
4035 + struct dentry *h_src, *h_dst, *h_parent;
4036 + struct inode *dst_inode, *h_dir, *inode;
4037 + struct super_block *sb;
4038 + struct au_branch *br;
4039 + struct au_cpup_reg_attr h_src_attr = {
4043 + AuDebugOn(basic->bsrc <= basic->bdst);
4045 + sb = basic->dentry->d_sb;
4046 + br = au_sbr(sb, basic->bdst);
4047 + h_path.mnt = au_br_mnt(br);
4048 + h_dst = au_h_dptr(basic->dentry, basic->bdst);
4049 + h_parent = h_dst->d_parent; /* dir inode is locked */
4050 + h_dir = h_parent->d_inode;
4053 + h_src = au_h_dptr(basic->dentry, basic->bsrc);
4054 + inode = basic->dentry->d_inode;
4057 + dst_parent = dget_parent(basic->dentry);
4061 + plink = !!au_opt_test(au_mntflags(sb), PLINK);
4062 + dst_inode = au_h_iptr(inode, basic->bdst);
4064 + if (unlikely(!plink)) {
4066 + AuIOErr("hi%lu(i%lu) exists on b%d "
4067 + "but plink is disabled\n",
4068 + dst_inode->i_ino, inode->i_ino, basic->bdst);
4072 + if (dst_inode->i_nlink) {
4073 + const int do_dt = au_ftest_cpup(flags, DTIME);
4075 + h_src = au_plink_lkup(inode, basic->bdst);
4076 + err = PTR_ERR(h_src);
4077 + if (IS_ERR(h_src))
4079 + if (unlikely(!h_src->d_inode)) {
4081 + AuIOErr("i%lu exists on a upper branch "
4082 + "but not pseudo-linked\n",
4089 + h_path.dentry = h_parent;
4090 + au_dtime_store(&dt, dst_parent, &h_path);
4093 + h_path.dentry = h_dst;
4094 + err = vfsub_link(h_src, h_dir, &h_path);
4095 + if (!err && au_ftest_cpup(flags, RENAME))
4096 + err = au_do_ren_after_cpup
4097 + (basic->dentry, basic->bdst, &h_path);
4099 + au_dtime_revert(&dt);
4103 + /* todo: cpup_wh_file? */
4105 + au_update_ibrange(inode, /*do_put_zero*/1);
4108 + isdir = S_ISDIR(inode->i_mode);
4109 + old_ibstart = au_ibstart(inode);
4110 + err = cpup_entry(basic, flags, dst_parent, pin, &h_src_attr);
4111 + if (unlikely(err))
4113 + dst_inode = h_dst->d_inode;
4114 + mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
4115 + /* todo: necessary? */
4116 + /* au_pin_hdir_unlock(pin); */
4118 + err = cpup_iattr(basic->dentry, basic->bdst, h_src, &h_src_attr);
4119 + if (unlikely(err)) {
4120 + /* todo: necessary? */
4121 + /* au_pin_hdir_relock(pin); */ /* ignore an error */
4122 + mutex_unlock(&dst_inode->i_mutex);
4126 + if (basic->bdst < old_ibstart) {
4127 + if (S_ISREG(inode->i_mode)) {
4128 + err = au_dy_iaop(inode, basic->bdst, dst_inode);
4129 + if (unlikely(err)) {
4130 + /* au_pin_hdir_relock(pin); ignore an error */
4131 + mutex_unlock(&dst_inode->i_mutex);
4135 + au_set_ibstart(inode, basic->bdst);
4137 + au_set_h_iptr(inode, basic->bdst, au_igrab(dst_inode),
4138 + au_hi_flags(inode, isdir));
4140 + /* todo: necessary? */
4141 + /* err = au_pin_hdir_relock(pin); */
4142 + mutex_unlock(&dst_inode->i_mutex);
4143 + if (unlikely(err))
4147 + && h_src->d_inode->i_nlink > 1
4149 + au_plink_append(inode, basic->bdst, h_dst);
4151 + if (au_ftest_cpup(flags, RENAME)) {
4152 + h_path.dentry = h_dst;
4153 + err = au_do_ren_after_cpup(basic->dentry, basic->bdst, &h_path);
4156 + goto out; /* success */
4160 + h_path.dentry = h_parent;
4161 + au_dtime_store(&dt, dst_parent, &h_path);
4162 + h_path.dentry = h_dst;
4164 + if (h_dst->d_inode) {
4166 + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
4168 + rerr = vfsub_rmdir(h_dir, &h_path);
4170 + au_dtime_revert(&dt);
4172 + AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
4180 +struct au_cpup_single_args {
4182 + struct au_cpup_basic *basic;
4183 + unsigned int flags;
4184 + struct dentry *dst_parent;
4185 + struct au_pin *pin;
4188 +static void au_call_cpup_single(void *args)
4190 + struct au_cpup_single_args *a = args;
4192 + au_pin_hdir_acquire_nest(a->pin);
4193 + *a->errp = au_cpup_single(a->basic, a->flags, a->dst_parent, a->pin);
4194 + au_pin_hdir_release(a->pin);
4198 + * prevent SIGXFSZ in copy-up.
4199 + * testing CAP_MKNOD is for generic fs,
4200 + * but CAP_FSETID is for xfs only, currently.
4202 +static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
4205 + struct super_block *sb;
4206 + struct inode *h_dir;
4209 + sb = au_pinned_parent(pin)->d_sb;
4210 + if (!au_wkq_test()
4211 + && (!au_sbi(sb)->si_plink_maint_pid
4212 + || au_plink_maint(sb, AuLock_NOPLM))) {
4213 + switch (mode & S_IFMT) {
4215 + /* no condition about RLIMIT_FSIZE and the file size */
4220 + do_sio = !capable(CAP_MKNOD);
4224 + do_sio = ((mode & (S_ISUID | S_ISGID))
4225 + && !capable(CAP_FSETID));
4226 + /* this workaround may be removed in the future */
4228 + h_dir = au_pinned_h_dir(pin);
4229 + do_sio = h_dir->i_mode & S_ISVTX;
4236 +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
4237 + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
4238 + struct dentry *dst_parent, struct au_pin *pin)
4241 + struct dentry *h_dentry;
4242 + struct au_cpup_basic basic = {
4249 + h_dentry = au_h_dptr(dentry, bsrc);
4250 + if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
4251 + err = au_cpup_single(&basic, flags, dst_parent, pin);
4253 + struct au_cpup_single_args args = {
4257 + .dst_parent = dst_parent,
4260 + wkq_err = au_wkq_wait(au_call_cpup_single, &args);
4261 + if (unlikely(wkq_err))
4269 + * copyup the @dentry from the first active lower branch to @bdst,
4270 + * using au_cpup_single().
4272 +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4273 + unsigned int flags, struct au_pin *pin)
4276 + aufs_bindex_t bsrc, bend;
4277 + struct dentry *h_dentry;
4279 + DiMustWriteLock(dentry);
4280 + bend = au_dbend(dentry);
4281 + for (bsrc = bdst + 1; bsrc <= bend; bsrc++) {
4282 + h_dentry = au_h_dptr(dentry, bsrc);
4284 + AuDebugOn(!h_dentry->d_inode);
4288 + AuDebugOn(bsrc > bend);
4290 + err = au_lkup_neg(dentry, bdst, /*wh*/1);
4292 + struct au_cpup_basic basic = {
4298 + err = au_cpup_single(&basic, flags | AuCpup_RENAME, NULL, pin);
4300 + return 0; /* success */
4303 + au_set_h_dptr(dentry, bdst, NULL);
4304 + au_set_dbstart(dentry, bsrc);
4310 +struct au_cpup_simple_args {
4312 + struct dentry *dentry;
4313 + aufs_bindex_t bdst;
4315 + unsigned int flags;
4316 + struct au_pin *pin;
4319 +static void au_call_cpup_simple(void *args)
4321 + struct au_cpup_simple_args *a = args;
4323 + au_pin_hdir_acquire_nest(a->pin);
4324 + *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags, a->pin);
4325 + au_pin_hdir_release(a->pin);
4328 +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4329 + unsigned int flags, struct au_pin *pin)
4332 + struct dentry *parent;
4333 + struct inode *h_dir;
4335 + parent = dget_parent(dentry);
4336 + h_dir = au_h_iptr(parent->d_inode, bdst);
4337 + if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
4338 + && !au_cpup_sio_test(pin, dentry->d_inode->i_mode))
4339 + err = au_cpup_simple(dentry, bdst, len, flags, pin);
4341 + struct au_cpup_simple_args args = {
4349 + wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
4350 + if (unlikely(wkq_err))
4358 +/* generalized cpup_simple() with h_open_pre/post() calls */
4359 +int au_sio_cpup_simple_h_open(struct dentry *dentry, aufs_bindex_t bdst,
4360 + loff_t len, unsigned int flags,
4361 + struct au_pin *pin, aufs_bindex_t bsrc)
4364 + struct file *h_file;
4366 + h_file = au_h_open_pre(dentry, bsrc);
4367 + if (IS_ERR(h_file))
4368 + err = PTR_ERR(h_file);
4370 + err = au_sio_cpup_simple(dentry, bdst, len, flags, pin);
4371 + au_h_open_post(dentry, bsrc, h_file);
4377 +/* ---------------------------------------------------------------------- */
4380 + * copyup the deleted file for writing.
4382 +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
4383 + struct dentry *wh_dentry, struct file *file,
4384 + loff_t len, struct au_pin *pin)
4387 + struct au_cpup_basic basic = {
4393 + struct au_dinfo *dinfo;
4394 + struct dentry *h_d_dst, *h_d_start;
4395 + struct au_hdentry *hdp;
4397 + dinfo = au_di(dentry);
4398 + AuRwMustWriteLock(&dinfo->di_rwsem);
4400 + basic.bsrc = dinfo->di_bstart;
4401 + hdp = dinfo->di_hdentry;
4402 + h_d_dst = hdp[0 + bdst].hd_dentry;
4403 + dinfo->di_bstart = bdst;
4404 + hdp[0 + bdst].hd_dentry = wh_dentry;
4407 + h_d_start = hdp[0 + basic.bsrc].hd_dentry;
4408 + hdp[0 + basic.bsrc].hd_dentry = au_hf_top(file)->f_dentry;
4410 + err = au_cpup_single(&basic, !AuCpup_DTIME, /*h_parent*/NULL, pin);
4413 + err = au_reopen_nondir(file);
4414 + hdp[0 + basic.bsrc].hd_dentry = h_d_start;
4416 + hdp[0 + bdst].hd_dentry = h_d_dst;
4417 + dinfo->di_bstart = basic.bsrc;
4422 +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4423 + struct file *file, struct au_pin *pin)
4426 + struct au_dtime dt;
4427 + struct dentry *parent, *h_parent, *wh_dentry;
4428 + struct au_branch *br;
4429 + struct path h_path;
4431 + br = au_sbr(dentry->d_sb, bdst);
4432 + parent = dget_parent(dentry);
4433 + h_parent = au_h_dptr(parent, bdst);
4434 + wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
4435 + err = PTR_ERR(wh_dentry);
4436 + if (IS_ERR(wh_dentry))
4439 + h_path.dentry = h_parent;
4440 + h_path.mnt = au_br_mnt(br);
4441 + au_dtime_store(&dt, parent, &h_path);
4442 + err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len, pin);
4443 + if (unlikely(err))
4447 + h_path.dentry = wh_dentry;
4448 + if (!S_ISDIR(wh_dentry->d_inode->i_mode))
4449 + err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0);
4451 + err = vfsub_rmdir(h_parent->d_inode, &h_path);
4452 + if (unlikely(err)) {
4453 + AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
4454 + AuDLNPair(wh_dentry), err);
4457 + au_dtime_revert(&dt);
4458 + au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
4467 +struct au_cpup_wh_args {
4469 + struct dentry *dentry;
4470 + aufs_bindex_t bdst;
4472 + struct file *file;
4473 + struct au_pin *pin;
4476 +static void au_call_cpup_wh(void *args)
4478 + struct au_cpup_wh_args *a = args;
4480 + au_pin_hdir_acquire_nest(a->pin);
4481 + *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file, a->pin);
4482 + au_pin_hdir_release(a->pin);
4485 +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4486 + struct file *file, struct au_pin *pin)
4489 + struct dentry *parent, *h_orph, *h_parent, *h_dentry;
4490 + struct inode *dir, *h_dir, *h_tmpdir;
4491 + struct au_wbr *wbr;
4492 + struct au_pin wh_pin;
4494 + parent = dget_parent(dentry);
4495 + dir = parent->d_inode;
4498 + h_dir = au_igrab(au_h_iptr(dir, bdst));
4500 + if (!h_dir->i_nlink) {
4501 + wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
4502 + h_orph = wbr->wbr_orph;
4504 + h_parent = dget(au_h_dptr(parent, bdst));
4505 + au_set_h_dptr(parent, bdst, dget(h_orph));
4506 + h_tmpdir = h_orph->d_inode;
4507 + au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
4510 + h_dentry = au_hf_top(file)->f_dentry;
4512 + h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
4513 + mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4514 + /* todo: au_h_open_pre()? */
4516 + au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
4517 + AuLsc_I_PARENT3, pin->udba, AuPin_DI_LOCKED);
4521 + if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
4522 + && !au_cpup_sio_test(pin, dentry->d_inode->i_mode))
4523 + err = au_cpup_wh(dentry, bdst, len, file, pin);
4525 + struct au_cpup_wh_args args = {
4533 + wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
4534 + if (unlikely(wkq_err))
4539 + mutex_unlock(&h_tmpdir->i_mutex);
4540 + /* todo: au_h_open_post()? */
4541 + au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
4542 + au_set_h_dptr(parent, bdst, h_parent);
4550 +/* ---------------------------------------------------------------------- */
4553 + * generic routine for both of copy-up and copy-down.
4555 +/* cf. revalidate function in file.c */
4556 +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4557 + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
4558 + struct au_pin *pin,
4559 + struct dentry *h_parent, void *arg),
4563 + struct au_pin pin;
4564 + struct dentry *d, *parent, *h_parent, *real_parent;
4567 + parent = dget_parent(dentry);
4568 + if (IS_ROOT(parent))
4571 + au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
4572 + au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
4574 + /* do not use au_dpage */
4575 + real_parent = parent;
4578 + parent = dget_parent(dentry);
4579 + h_parent = au_h_dptr(parent, bdst);
4581 + goto out; /* success */
4583 + /* find top dir which is necessary to cpup */
4587 + parent = dget_parent(d);
4588 + di_read_lock_parent3(parent, !AuLock_IR);
4589 + h_parent = au_h_dptr(parent, bdst);
4590 + di_read_unlock(parent, !AuLock_IR);
4591 + } while (!h_parent);
4593 + if (d != real_parent)
4594 + di_write_lock_child3(d);
4596 + /* somebody else might create while we were sleeping */
4597 + if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
4598 + if (au_h_dptr(d, bdst))
4599 + au_update_dbstart(d);
4601 + au_pin_set_dentry(&pin, d);
4602 + err = au_do_pin(&pin);
4604 + err = cp(d, bdst, &pin, h_parent, arg);
4609 + if (d != real_parent)
4610 + di_write_unlock(d);
4611 + if (unlikely(err))
4620 +static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
4621 + struct au_pin *pin,
4622 + struct dentry *h_parent __maybe_unused ,
4623 + void *arg __maybe_unused)
4625 + return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME, pin);
4628 +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4630 + return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
4633 +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4636 + struct dentry *parent;
4637 + struct inode *dir;
4639 + parent = dget_parent(dentry);
4640 + dir = parent->d_inode;
4642 + if (au_h_iptr(dir, bdst))
4645 + di_read_unlock(parent, AuLock_IR);
4646 + di_write_lock_parent(parent);
4647 + /* someone else might change our inode while we were sleeping */
4648 + if (!au_h_iptr(dir, bdst))
4649 + err = au_cpup_dirs(dentry, bdst);
4650 + di_downgrade_lock(parent, AuLock_IR);
4656 diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
4657 --- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
4658 +++ linux/fs/aufs/cpup.h 2013-07-30 22:42:46.232612606 +0200
4661 + * Copyright (C) 2005-2013 Junjiro R. Okajima
4663 + * This program, aufs is free software; you can redistribute it and/or modify
4664 + * it under the terms of the GNU General Public License as published by
4665 + * the Free Software Foundation; either version 2 of the License, or
4666 + * (at your option) any later version.
4668 + * This program is distributed in the hope that it will be useful,
4669 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4670 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4671 + * GNU General Public License for more details.
4673 + * You should have received a copy of the GNU General Public License
4674 + * along with this program; if not, write to the Free Software
4675 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4679 + * copy-up/down functions
4682 +#ifndef __AUFS_CPUP_H__
4683 +#define __AUFS_CPUP_H__
4687 +#include <linux/path.h>
4693 +void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
4694 +void au_cpup_attr_timesizes(struct inode *inode);
4695 +void au_cpup_attr_nlink(struct inode *inode, int force);
4696 +void au_cpup_attr_changeable(struct inode *inode);
4697 +void au_cpup_igen(struct inode *inode, struct inode *h_inode);
4698 +void au_cpup_attr_all(struct inode *inode, int force);
4700 +/* ---------------------------------------------------------------------- */
4703 +#define AuCpup_DTIME 1 /* do dtime_store/revert */
4704 +#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
4706 +#define AuCpup_RENAME (1 << 2) /* rename after cpup */
4707 +#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
4708 +#define au_fset_cpup(flags, name) \
4709 + do { (flags) |= AuCpup_##name; } while (0)
4710 +#define au_fclr_cpup(flags, name) \
4711 + do { (flags) &= ~AuCpup_##name; } while (0)
4713 +int au_copy_file(struct file *dst, struct file *src, loff_t len);
4714 +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
4715 + aufs_bindex_t bsrc, loff_t len, unsigned int flags,
4716 + struct dentry *dst_parent, struct au_pin *pin);
4717 +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4718 + unsigned int flags, struct au_pin *pin);
4719 +int au_sio_cpup_simple_h_open(struct dentry *dentry, aufs_bindex_t bdst,
4720 + loff_t len, unsigned int flags,
4721 + struct au_pin *pin, aufs_bindex_t bsrc);
4722 +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4723 + struct file *file, struct au_pin *pin);
4725 +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4726 + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
4727 + struct au_pin *pin,
4728 + struct dentry *h_parent, void *arg),
4730 +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4731 +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4733 +/* ---------------------------------------------------------------------- */
4735 +/* keep timestamps when copyup */
4737 + struct dentry *dt_dentry;
4738 + struct path dt_h_path;
4739 + struct timespec dt_atime, dt_mtime;
4741 +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4742 + struct path *h_path);
4743 +void au_dtime_revert(struct au_dtime *dt);
4745 +#endif /* __KERNEL__ */
4746 +#endif /* __AUFS_CPUP_H__ */
4747 diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
4748 --- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
4749 +++ linux/fs/aufs/dbgaufs.c 2013-07-06 13:20:47.740198107 +0200
4752 + * Copyright (C) 2005-2013 Junjiro R. Okajima
4754 + * This program, aufs is free software; you can redistribute it and/or modify
4755 + * it under the terms of the GNU General Public License as published by
4756 + * the Free Software Foundation; either version 2 of the License, or
4757 + * (at your option) any later version.
4759 + * This program is distributed in the hope that it will be useful,
4760 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4761 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4762 + * GNU General Public License for more details.
4764 + * You should have received a copy of the GNU General Public License
4765 + * along with this program; if not, write to the Free Software
4766 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4770 + * debugfs interface
4773 +#include <linux/debugfs.h>
4776 +#ifndef CONFIG_SYSFS
4777 +#error DEBUG_FS depends upon SYSFS
4780 +static struct dentry *dbgaufs;
4781 +static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
4783 +/* 20 is max digits length of ulong 64 */
4784 +struct dbgaufs_arg {
4790 + * common function for all XINO files
4792 +static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
4793 + struct file *file)
4795 + kfree(file->private_data);
4799 +static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
4803 + struct dbgaufs_arg *p;
4806 + p = kmalloc(sizeof(*p), GFP_NOFS);
4812 + file->private_data = p;
4816 + err = vfs_getattr(&xf->f_path, &st);
4820 + (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
4821 + (long)file_count(xf), st.blocks, st.blksize,
4822 + (long long)st.size);
4824 + p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
4825 + st.blocks, st.blksize,
4826 + (long long)st.size);
4827 + AuDebugOn(p->n >= sizeof(p->a));
4829 + p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
4838 +static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
4839 + size_t count, loff_t *ppos)
4841 + struct dbgaufs_arg *p;
4843 + p = file->private_data;
4844 + return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
4847 +/* ---------------------------------------------------------------------- */
4849 +struct dbgaufs_plink_arg {
4854 +static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
4855 + struct file *file)
4857 + free_page((unsigned long)file->private_data);
4861 +static int dbgaufs_plink_open(struct inode *inode, struct file *file)
4863 + int err, i, limit;
4864 + unsigned long n, sum;
4865 + struct dbgaufs_plink_arg *p;
4866 + struct au_sbinfo *sbinfo;
4867 + struct super_block *sb;
4868 + struct au_sphlhead *sphl;
4871 + p = (void *)get_zeroed_page(GFP_NOFS);
4876 + sbinfo = inode->i_private;
4877 + sb = sbinfo->si_sb;
4878 + si_noflush_read_lock(sb);
4879 + if (au_opt_test(au_mntflags(sb), PLINK)) {
4880 + limit = PAGE_SIZE - sizeof(p->n);
4882 + /* the number of buckets */
4883 + n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
4888 + for (i = 0, sphl = sbinfo->si_plink;
4889 + i < AuPlink_NHASH;
4891 + n = au_sphl_count(sphl);
4894 + n = snprintf(p->a + p->n, limit, "%lu ", n);
4897 + if (unlikely(limit <= 0))
4900 + p->a[p->n - 1] = '\n';
4902 + /* the sum of plinks */
4903 + n = snprintf(p->a + p->n, limit, "%lu\n", sum);
4906 + if (unlikely(limit <= 0))
4909 +#define str "1\n0\n0\n"
4910 + p->n = sizeof(str) - 1;
4911 + strcpy(p->a, str);
4914 + si_read_unlock(sb);
4917 + file->private_data = p;
4918 + goto out; /* success */
4921 + free_page((unsigned long)p);
4926 +static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
4927 + size_t count, loff_t *ppos)
4929 + struct dbgaufs_plink_arg *p;
4931 + p = file->private_data;
4932 + return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
4935 +static const struct file_operations dbgaufs_plink_fop = {
4936 + .owner = THIS_MODULE,
4937 + .open = dbgaufs_plink_open,
4938 + .release = dbgaufs_plink_release,
4939 + .read = dbgaufs_plink_read
4942 +/* ---------------------------------------------------------------------- */
4944 +static int dbgaufs_xib_open(struct inode *inode, struct file *file)
4947 + struct au_sbinfo *sbinfo;
4948 + struct super_block *sb;
4950 + sbinfo = inode->i_private;
4951 + sb = sbinfo->si_sb;
4952 + si_noflush_read_lock(sb);
4953 + err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
4954 + si_read_unlock(sb);
4958 +static const struct file_operations dbgaufs_xib_fop = {
4959 + .owner = THIS_MODULE,
4960 + .open = dbgaufs_xib_open,
4961 + .release = dbgaufs_xi_release,
4962 + .read = dbgaufs_xi_read
4965 +/* ---------------------------------------------------------------------- */
4967 +#define DbgaufsXi_PREFIX "xi"
4969 +static int dbgaufs_xino_open(struct inode *inode, struct file *file)
4973 + struct au_sbinfo *sbinfo;
4974 + struct super_block *sb;
4976 + struct qstr *name;
4980 + name = &file->f_dentry->d_name;
4981 + if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
4982 + || memcmp(name->name, DbgaufsXi_PREFIX,
4983 + sizeof(DbgaufsXi_PREFIX) - 1)))
4985 + err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
4986 + if (unlikely(err))
4989 + sbinfo = inode->i_private;
4990 + sb = sbinfo->si_sb;
4991 + si_noflush_read_lock(sb);
4992 + if (l <= au_sbend(sb)) {
4993 + xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
4994 + err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
4997 + si_read_unlock(sb);
5003 +static const struct file_operations dbgaufs_xino_fop = {
5004 + .owner = THIS_MODULE,
5005 + .open = dbgaufs_xino_open,
5006 + .release = dbgaufs_xi_release,
5007 + .read = dbgaufs_xi_read
5010 +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
5012 + aufs_bindex_t bend;
5013 + struct au_branch *br;
5014 + struct au_xino_file *xi;
5016 + if (!au_sbi(sb)->si_dbgaufs)
5019 + bend = au_sbend(sb);
5020 + for (; bindex <= bend; bindex++) {
5021 + br = au_sbr(sb, bindex);
5022 + xi = &br->br_xino;
5023 + debugfs_remove(xi->xi_dbgaufs);
5024 + xi->xi_dbgaufs = NULL;
5028 +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
5030 + struct au_sbinfo *sbinfo;
5031 + struct dentry *parent;
5032 + struct au_branch *br;
5033 + struct au_xino_file *xi;
5034 + aufs_bindex_t bend;
5035 + char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
5037 + sbinfo = au_sbi(sb);
5038 + parent = sbinfo->si_dbgaufs;
5042 + bend = au_sbend(sb);
5043 + for (; bindex <= bend; bindex++) {
5044 + snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
5045 + br = au_sbr(sb, bindex);
5046 + xi = &br->br_xino;
5047 + AuDebugOn(xi->xi_dbgaufs);
5048 + xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
5049 + sbinfo, &dbgaufs_xino_fop);
5050 + /* ignore an error */
5051 + if (unlikely(!xi->xi_dbgaufs))
5052 + AuWarn1("failed %s under debugfs\n", name);
5056 +/* ---------------------------------------------------------------------- */
5058 +#ifdef CONFIG_AUFS_EXPORT
5059 +static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
5062 + struct au_sbinfo *sbinfo;
5063 + struct super_block *sb;
5065 + sbinfo = inode->i_private;
5066 + sb = sbinfo->si_sb;
5067 + si_noflush_read_lock(sb);
5068 + err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
5069 + si_read_unlock(sb);
5073 +static const struct file_operations dbgaufs_xigen_fop = {
5074 + .owner = THIS_MODULE,
5075 + .open = dbgaufs_xigen_open,
5076 + .release = dbgaufs_xi_release,
5077 + .read = dbgaufs_xi_read
5080 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5085 + * This function is a dynamic '__init' fucntion actually,
5086 + * so the tiny check for si_rwsem is unnecessary.
5088 + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5091 + sbinfo->si_dbgaufs_xigen = debugfs_create_file
5092 + ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5093 + &dbgaufs_xigen_fop);
5094 + if (sbinfo->si_dbgaufs_xigen)
5100 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5104 +#endif /* CONFIG_AUFS_EXPORT */
5106 +/* ---------------------------------------------------------------------- */
5108 +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
5111 + * This function is a dynamic '__init' fucntion actually,
5112 + * so the tiny check for si_rwsem is unnecessary.
5114 + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5116 + debugfs_remove_recursive(sbinfo->si_dbgaufs);
5117 + sbinfo->si_dbgaufs = NULL;
5118 + kobject_put(&sbinfo->si_kobj);
5121 +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
5124 + char name[SysaufsSiNameLen];
5127 + * This function is a dynamic '__init' fucntion actually,
5128 + * so the tiny check for si_rwsem is unnecessary.
5130 + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5134 + AuErr1("/debug/aufs is uninitialized\n");
5139 + sysaufs_name(sbinfo, name);
5140 + sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
5141 + if (unlikely(!sbinfo->si_dbgaufs))
5143 + kobject_get(&sbinfo->si_kobj);
5145 + sbinfo->si_dbgaufs_xib = debugfs_create_file
5146 + ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5147 + &dbgaufs_xib_fop);
5148 + if (unlikely(!sbinfo->si_dbgaufs_xib))
5151 + sbinfo->si_dbgaufs_plink = debugfs_create_file
5152 + ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5153 + &dbgaufs_plink_fop);
5154 + if (unlikely(!sbinfo->si_dbgaufs_plink))
5157 + err = dbgaufs_xigen_init(sbinfo);
5159 + goto out; /* success */
5162 + dbgaufs_si_fin(sbinfo);
5167 +/* ---------------------------------------------------------------------- */
5169 +void dbgaufs_fin(void)
5171 + debugfs_remove(dbgaufs);
5174 +int __init dbgaufs_init(void)
5179 + dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
5184 diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
5185 --- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
5186 +++ linux/fs/aufs/dbgaufs.h 2013-07-06 13:20:47.740198107 +0200
5189 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5191 + * This program, aufs is free software; you can redistribute it and/or modify
5192 + * it under the terms of the GNU General Public License as published by
5193 + * the Free Software Foundation; either version 2 of the License, or
5194 + * (at your option) any later version.
5196 + * This program is distributed in the hope that it will be useful,
5197 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5198 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5199 + * GNU General Public License for more details.
5201 + * You should have received a copy of the GNU General Public License
5202 + * along with this program; if not, write to the Free Software
5203 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
5207 + * debugfs interface
5210 +#ifndef __DBGAUFS_H__
5211 +#define __DBGAUFS_H__
5215 +struct super_block;
5218 +#ifdef CONFIG_DEBUG_FS
5220 +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
5221 +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
5222 +void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
5223 +int dbgaufs_si_init(struct au_sbinfo *sbinfo);
5224 +void dbgaufs_fin(void);
5225 +int __init dbgaufs_init(void);
5227 +AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
5228 +AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
5229 +AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
5230 +AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
5231 +AuStubVoid(dbgaufs_fin, void)
5232 +AuStubInt0(__init dbgaufs_init, void)
5233 +#endif /* CONFIG_DEBUG_FS */
5235 +#endif /* __KERNEL__ */
5236 +#endif /* __DBGAUFS_H__ */
5237 diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
5238 --- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
5239 +++ linux/fs/aufs/dcsub.c 2013-07-30 22:42:55.839613269 +0200
5242 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5244 + * This program, aufs is free software; you can redistribute it and/or modify
5245 + * it under the terms of the GNU General Public License as published by
5246 + * the Free Software Foundation; either version 2 of the License, or
5247 + * (at your option) any later version.
5249 + * This program is distributed in the hope that it will be useful,
5250 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5251 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5252 + * GNU General Public License for more details.
5254 + * You should have received a copy of the GNU General Public License
5255 + * along with this program; if not, write to the Free Software
5256 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
5260 + * sub-routines for dentry cache
5265 +static void au_dpage_free(struct au_dpage *dpage)
5268 + struct dentry **p;
5270 + p = dpage->dentries;
5271 + for (i = 0; i < dpage->ndentry; i++)
5273 + free_page((unsigned long)dpage->dentries);
5276 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
5282 + dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
5283 + if (unlikely(!dpages->dpages))
5286 + p = (void *)__get_free_page(gfp);
5290 + dpages->dpages[0].ndentry = 0;
5291 + dpages->dpages[0].dentries = p;
5292 + dpages->ndpage = 1;
5293 + return 0; /* success */
5296 + kfree(dpages->dpages);
5301 +void au_dpages_free(struct au_dcsub_pages *dpages)
5304 + struct au_dpage *p;
5306 + p = dpages->dpages;
5307 + for (i = 0; i < dpages->ndpage; i++)
5308 + au_dpage_free(p++);
5309 + kfree(dpages->dpages);
5312 +static int au_dpages_append(struct au_dcsub_pages *dpages,
5313 + struct dentry *dentry, gfp_t gfp)
5316 + struct au_dpage *dpage;
5319 + dpage = dpages->dpages + dpages->ndpage - 1;
5320 + sz = PAGE_SIZE / sizeof(dentry);
5321 + if (unlikely(dpage->ndentry >= sz)) {
5322 + AuLabel(new dpage);
5324 + sz = dpages->ndpage * sizeof(*dpages->dpages);
5325 + p = au_kzrealloc(dpages->dpages, sz,
5326 + sz + sizeof(*dpages->dpages), gfp);
5330 + dpages->dpages = p;
5331 + dpage = dpages->dpages + dpages->ndpage;
5332 + p = (void *)__get_free_page(gfp);
5336 + dpage->ndentry = 0;
5337 + dpage->dentries = p;
5341 + AuDebugOn(!dentry->d_count);
5342 + dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
5343 + return 0; /* success */
5349 +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5350 + au_dpages_test test, void *arg)
5353 + struct dentry *this_parent;
5354 + struct list_head *next;
5355 + struct super_block *sb = root->d_sb;
5358 + write_seqlock(&rename_lock);
5359 + this_parent = root;
5360 + spin_lock(&this_parent->d_lock);
5362 + next = this_parent->d_subdirs.next;
5364 + if (this_parent->d_sb == sb
5365 + && !IS_ROOT(this_parent)
5366 + && au_di(this_parent)
5367 + && this_parent->d_count
5368 + && (!test || test(this_parent, arg))) {
5369 + err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
5370 + if (unlikely(err))
5374 + while (next != &this_parent->d_subdirs) {
5375 + struct list_head *tmp = next;
5376 + struct dentry *dentry = list_entry(tmp, struct dentry,
5380 + spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
5381 + if (dentry->d_count) {
5382 + if (!list_empty(&dentry->d_subdirs)) {
5383 + spin_unlock(&this_parent->d_lock);
5384 + spin_release(&dentry->d_lock.dep_map, 1,
5386 + this_parent = dentry;
5387 + spin_acquire(&this_parent->d_lock.dep_map, 0, 1,
5391 + if (dentry->d_sb == sb
5393 + && (!test || test(dentry, arg)))
5394 + err = au_dpages_append(dpages, dentry,
5397 + spin_unlock(&dentry->d_lock);
5398 + if (unlikely(err))
5402 + if (this_parent != root) {
5403 + struct dentry *tmp;
5404 + struct dentry *child;
5406 + tmp = this_parent->d_parent;
5408 + spin_unlock(&this_parent->d_lock);
5409 + child = this_parent;
5410 + this_parent = tmp;
5411 + spin_lock(&this_parent->d_lock);
5412 + rcu_read_unlock();
5413 + next = child->d_u.d_child.next;
5418 + spin_unlock(&this_parent->d_lock);
5419 + write_sequnlock(&rename_lock);
5423 +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5424 + int do_include, au_dpages_test test, void *arg)
5429 + write_seqlock(&rename_lock);
5430 + spin_lock(&dentry->d_lock);
5432 + && dentry->d_count
5433 + && (!test || test(dentry, arg)))
5434 + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
5435 + spin_unlock(&dentry->d_lock);
5436 + if (unlikely(err))
5440 + * vfsmount_lock is unnecessary since this is a traverse in a single
5443 + while (!IS_ROOT(dentry)) {
5444 + dentry = dentry->d_parent; /* rename_lock is locked */
5445 + spin_lock(&dentry->d_lock);
5446 + if (dentry->d_count
5447 + && (!test || test(dentry, arg)))
5448 + err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
5449 + spin_unlock(&dentry->d_lock);
5450 + if (unlikely(err))
5455 + write_sequnlock(&rename_lock);
5459 +static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
5461 + return au_di(dentry) && dentry->d_sb == arg;
5464 +int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5465 + struct dentry *dentry, int do_include)
5467 + return au_dcsub_pages_rev(dpages, dentry, do_include,
5468 + au_dcsub_dpages_aufs, dentry->d_sb);
5471 +int au_test_subdir(struct dentry *d1, struct dentry *d2)
5473 + struct path path[2] = {
5482 + return path_is_under(path + 0, path + 1);
5484 diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
5485 --- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
5486 +++ linux/fs/aufs/dcsub.h 2013-07-06 13:20:47.740198107 +0200
5489 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5491 + * This program, aufs is free software; you can redistribute it and/or modify
5492 + * it under the terms of the GNU General Public License as published by
5493 + * the Free Software Foundation; either version 2 of the License, or
5494 + * (at your option) any later version.
5496 + * This program is distributed in the hope that it will be useful,
5497 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5498 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5499 + * GNU General Public License for more details.
5501 + * You should have received a copy of the GNU General Public License
5502 + * along with this program; if not, write to the Free Software
5503 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
5507 + * sub-routines for dentry cache
5510 +#ifndef __AUFS_DCSUB_H__
5511 +#define __AUFS_DCSUB_H__
5515 +#include <linux/dcache.h>
5516 +#include <linux/fs.h>
5522 + struct dentry **dentries;
5525 +struct au_dcsub_pages {
5527 + struct au_dpage *dpages;
5530 +/* ---------------------------------------------------------------------- */
5533 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
5534 +void au_dpages_free(struct au_dcsub_pages *dpages);
5535 +typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
5536 +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5537 + au_dpages_test test, void *arg);
5538 +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5539 + int do_include, au_dpages_test test, void *arg);
5540 +int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5541 + struct dentry *dentry, int do_include);
5542 +int au_test_subdir(struct dentry *d1, struct dentry *d2);
5544 +/* ---------------------------------------------------------------------- */
5546 +static inline int au_d_hashed_positive(struct dentry *d)
5549 + struct inode *inode = d->d_inode;
5551 + if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
5556 +static inline int au_d_alive(struct dentry *d)
5559 + struct inode *inode;
5562 + err = au_d_hashed_positive(d);
5564 + inode = d->d_inode;
5565 + if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
5571 +static inline int au_alive_dir(struct dentry *d)
5574 + err = au_d_alive(d);
5575 + if (unlikely(err || IS_DEADDIR(d->d_inode)))
5580 +#endif /* __KERNEL__ */
5581 +#endif /* __AUFS_DCSUB_H__ */
5582 diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
5583 --- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
5584 +++ linux/fs/aufs/debug.c 2013-07-30 22:42:55.839613269 +0200
5587 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5589 + * This program, aufs is free software; you can redistribute it and/or modify
5590 + * it under the terms of the GNU General Public License as published by
5591 + * the Free Software Foundation; either version 2 of the License, or
5592 + * (at your option) any later version.
5594 + * This program is distributed in the hope that it will be useful,
5595 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5596 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5597 + * GNU General Public License for more details.
5599 + * You should have received a copy of the GNU General Public License
5600 + * along with this program; if not, write to the Free Software
5601 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
5605 + * debug print functions
5608 +#include <linux/vt_kern.h>
5612 +MODULE_PARM_DESC(debug, "debug print");
5613 +module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
5615 +char *au_plevel = KERN_DEBUG;
5616 +#define dpri(fmt, ...) do { \
5618 + && strcmp(au_plevel, KERN_DEBUG)) \
5619 + || au_debug_test()) \
5620 + printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
5623 +/* ---------------------------------------------------------------------- */
5625 +void au_dpri_whlist(struct au_nhash *whlist)
5627 + unsigned long ul, n;
5628 + struct hlist_head *head;
5629 + struct au_vdir_wh *pos;
5631 + n = whlist->nh_num;
5632 + head = whlist->nh_head;
5633 + for (ul = 0; ul < n; ul++) {
5634 + hlist_for_each_entry(pos, head, wh_hash)
5635 + dpri("b%d, %.*s, %d\n",
5637 + pos->wh_str.len, pos->wh_str.name,
5643 +void au_dpri_vdir(struct au_vdir *vdir)
5646 + union au_vdir_deblk_p p;
5649 + if (!vdir || IS_ERR(vdir)) {
5650 + dpri("err %ld\n", PTR_ERR(vdir));
5654 + dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
5655 + vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
5656 + vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
5657 + for (ul = 0; ul < vdir->vd_nblk; ul++) {
5658 + p.deblk = vdir->vd_deblk[ul];
5660 + dpri("[%lu]: %p\n", ul, o);
5664 +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
5665 + struct dentry *wh)
5670 + if (!inode || IS_ERR(inode)) {
5671 + dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
5675 + /* the type of i_blocks depends upon CONFIG_LSF */
5676 + BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
5677 + && sizeof(inode->i_blocks) != sizeof(u64));
5679 + n = (void *)wh->d_name.name;
5680 + l = wh->d_name.len;
5683 + dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
5684 + " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
5686 + inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
5687 + atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
5688 + i_size_read(inode), (unsigned long long)inode->i_blocks,
5689 + hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
5690 + inode->i_mapping ? inode->i_mapping->nrpages : 0,
5691 + inode->i_state, inode->i_flags, inode->i_version,
5692 + inode->i_generation,
5693 + l ? ", wh " : "", l, n);
5697 +void au_dpri_inode(struct inode *inode)
5699 + struct au_iinfo *iinfo;
5700 + aufs_bindex_t bindex;
5703 + err = do_pri_inode(-1, inode, -1, NULL);
5704 + if (err || !au_test_aufs(inode->i_sb))
5707 + iinfo = au_ii(inode);
5710 + dpri("i-1: bstart %d, bend %d, gen %d\n",
5711 + iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
5712 + if (iinfo->ii_bstart < 0)
5715 + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
5716 + hn = !!au_hn(iinfo->ii_hinode + bindex);
5717 + do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
5718 + iinfo->ii_hinode[0 + bindex].hi_whdentry);
5722 +void au_dpri_dalias(struct inode *inode)
5726 + spin_lock(&inode->i_lock);
5727 + hlist_for_each_entry(d, &inode->i_dentry, d_alias)
5728 + au_dpri_dentry(d);
5729 + spin_unlock(&inode->i_lock);
5732 +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
5734 + struct dentry *wh = NULL;
5737 + if (!dentry || IS_ERR(dentry)) {
5738 + dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
5741 + /* do not call dget_parent() here */
5742 + /* note: access d_xxx without d_lock */
5743 + dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
5745 + AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
5746 + dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
5747 + dentry->d_count, dentry->d_flags);
5749 + if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
5750 + struct au_iinfo *iinfo = au_ii(dentry->d_inode);
5752 + hn = !!au_hn(iinfo->ii_hinode + bindex);
5753 + wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
5756 + do_pri_inode(bindex, dentry->d_inode, hn, wh);
5760 +void au_dpri_dentry(struct dentry *dentry)
5762 + struct au_dinfo *dinfo;
5763 + aufs_bindex_t bindex;
5765 + struct au_hdentry *hdp;
5767 + err = do_pri_dentry(-1, dentry);
5768 + if (err || !au_test_aufs(dentry->d_sb))
5771 + dinfo = au_di(dentry);
5774 + dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
5775 + dinfo->di_bstart, dinfo->di_bend,
5776 + dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
5777 + if (dinfo->di_bstart < 0)
5779 + hdp = dinfo->di_hdentry;
5780 + for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
5781 + do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
5784 +static int do_pri_file(aufs_bindex_t bindex, struct file *file)
5788 + if (!file || IS_ERR(file)) {
5789 + dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
5795 + && au_test_aufs(file->f_dentry->d_sb)
5797 + snprintf(a, sizeof(a), ", gen %d, mmapped %d",
5798 + au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
5799 + dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
5800 + bindex, file->f_mode, file->f_flags, (long)file_count(file),
5801 + file->f_version, file->f_pos, a);
5802 + if (file->f_dentry)
5803 + do_pri_dentry(bindex, file->f_dentry);
5807 +void au_dpri_file(struct file *file)
5809 + struct au_finfo *finfo;
5810 + struct au_fidir *fidir;
5811 + struct au_hfile *hfile;
5812 + aufs_bindex_t bindex;
5815 + err = do_pri_file(-1, file);
5816 + if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
5819 + finfo = au_fi(file);
5822 + if (finfo->fi_btop < 0)
5824 + fidir = finfo->fi_hdir;
5826 + do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
5828 + for (bindex = finfo->fi_btop;
5829 + bindex >= 0 && bindex <= fidir->fd_bbot;
5831 + hfile = fidir->fd_hfile + bindex;
5832 + do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
5836 +static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
5838 + struct vfsmount *mnt;
5839 + struct super_block *sb;
5841 + if (!br || IS_ERR(br))
5843 + mnt = au_br_mnt(br);
5844 + if (!mnt || IS_ERR(mnt))
5847 + if (!sb || IS_ERR(sb))
5850 + dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
5851 + "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
5853 + bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
5854 + br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
5855 + sb->s_flags, sb->s_count,
5856 + atomic_read(&sb->s_active), !!br->br_xino.xi_file);
5860 + dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
5864 +void au_dpri_sb(struct super_block *sb)
5866 + struct au_sbinfo *sbinfo;
5867 + aufs_bindex_t bindex;
5869 + /* to reuduce stack size */
5871 + struct vfsmount mnt;
5872 + struct au_branch fake;
5875 + /* this function can be called from magic sysrq */
5876 + a = kzalloc(sizeof(*a), GFP_ATOMIC);
5877 + if (unlikely(!a)) {
5878 + dpri("no memory\n");
5882 + a->mnt.mnt_sb = sb;
5883 + a->fake.br_perm = 0;
5884 + a->fake.br_path.mnt = &a->mnt;
5885 + a->fake.br_xino.xi_file = NULL;
5886 + atomic_set(&a->fake.br_count, 0);
5887 + smp_mb(); /* atomic_set */
5888 + err = do_pri_br(-1, &a->fake);
5890 + dpri("dev 0x%x\n", sb->s_dev);
5891 + if (err || !au_test_aufs(sb))
5894 + sbinfo = au_sbi(sb);
5897 + dpri("nw %d, gen %u, kobj %d\n",
5898 + atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
5899 + atomic_read(&sbinfo->si_kobj.kref.refcount));
5900 + for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
5901 + do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
5904 +/* ---------------------------------------------------------------------- */
5906 +void au_dbg_sleep_jiffy(int jiffy)
5909 + jiffy = schedule_timeout_uninterruptible(jiffy);
5912 +void au_dbg_iattr(struct iattr *ia)
5914 +#define AuBit(name) \
5916 + if (ia->ia_valid & ATTR_ ## name) \
5917 + dpri(#name "\n"); \
5937 + dpri("ia_file %p\n", ia->ia_file);
5940 +/* ---------------------------------------------------------------------- */
5942 +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
5944 + struct inode *h_inode, *inode = dentry->d_inode;
5945 + struct dentry *h_dentry;
5946 + aufs_bindex_t bindex, bend, bi;
5948 + if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
5951 + bend = au_dbend(dentry);
5952 + bi = au_ibend(inode);
5955 + bindex = au_dbstart(dentry);
5956 + bi = au_ibstart(inode);
5960 + for (; bindex <= bend; bindex++) {
5961 + h_dentry = au_h_dptr(dentry, bindex);
5964 + h_inode = au_h_iptr(inode, bindex);
5965 + if (unlikely(h_inode != h_dentry->d_inode)) {
5966 + int old = au_debug_test();
5969 + AuDbg("b%d, %s:%d\n", bindex, func, line);
5970 + AuDbgDentry(dentry);
5971 + AuDbgInode(inode);
5979 +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
5981 + struct dentry *parent;
5983 + parent = dget_parent(dentry);
5984 + AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
5985 + AuDebugOn(IS_ROOT(dentry));
5986 + AuDebugOn(au_digen_test(parent, sigen));
5990 +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
5992 + struct dentry *parent;
5993 + struct inode *inode;
5995 + parent = dget_parent(dentry);
5996 + inode = dentry->d_inode;
5997 + AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
5998 + AuDebugOn(au_digen_test(parent, sigen));
6002 +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
6005 + struct au_dcsub_pages dpages;
6006 + struct au_dpage *dpage;
6007 + struct dentry **dentries;
6009 + err = au_dpages_init(&dpages, GFP_NOFS);
6011 + err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
6013 + for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
6014 + dpage = dpages.dpages + i;
6015 + dentries = dpage->dentries;
6016 + for (j = dpage->ndentry - 1; !err && j >= 0; j--)
6017 + AuDebugOn(au_digen_test(dentries[j], sigen));
6019 + au_dpages_free(&dpages);
6022 +void au_dbg_verify_kthread(void)
6024 + if (au_wkq_test()) {
6027 + * It may be recursive, but udba=notify between two aufs mounts,
6028 + * where a single ro branch is shared, is not a problem.
6034 +/* ---------------------------------------------------------------------- */
6036 +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
6038 +#ifdef AuForceNoPlink
6039 + au_opt_clr(sbinfo->si_mntflags, PLINK);
6041 +#ifdef AuForceNoXino
6042 + au_opt_clr(sbinfo->si_mntflags, XINO);
6044 +#ifdef AuForceNoRefrof
6045 + au_opt_clr(sbinfo->si_mntflags, REFROF);
6047 +#ifdef AuForceHnotify
6048 + au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
6051 + sbinfo->si_rdblk = 0;
6052 + sbinfo->si_rdhash = 0;
6056 +int __init au_debug_init(void)
6058 + aufs_bindex_t bindex;
6059 + struct au_vdir_destr destr;
6062 + AuDebugOn(bindex >= 0);
6065 + AuDebugOn(destr.len < NAME_MAX);
6067 +#ifdef CONFIG_4KSTACKS
6068 + pr_warn("CONFIG_4KSTACKS is defined.\n");
6071 +#ifdef AuForceNoBrs
6077 diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
6078 --- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
6079 +++ linux/fs/aufs/debug.h 2013-07-06 13:20:47.740198107 +0200
6082 + * Copyright (C) 2005-2013 Junjiro R. Okajima
6084 + * This program, aufs is free software; you can redistribute it and/or modify
6085 + * it under the terms of the GNU General Public License as published by
6086 + * the Free Software Foundation; either version 2 of the License, or
6087 + * (at your option) any later version.
6089 + * This program is distributed in the hope that it will be useful,
6090 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6091 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6092 + * GNU General Public License for more details.
6094 + * You should have received a copy of the GNU General Public License
6095 + * along with this program; if not, write to the Free Software
6096 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6100 + * debug print functions
6103 +#ifndef __AUFS_DEBUG_H__
6104 +#define __AUFS_DEBUG_H__
6108 +#include <linux/module.h>
6109 +#include <linux/kallsyms.h>
6110 +#include <linux/sysrq.h>
6112 +#ifdef CONFIG_AUFS_DEBUG
6113 +#define AuDebugOn(a) BUG_ON(a)
6115 +/* module parameter */
6116 +extern int aufs_debug;
6117 +static inline void au_debug(int n)
6123 +static inline int au_debug_test(void)
6125 + return aufs_debug;
6128 +#define AuDebugOn(a) do {} while (0)
6129 +AuStubVoid(au_debug, int n)
6130 +AuStubInt0(au_debug_test, void)
6131 +#endif /* CONFIG_AUFS_DEBUG */
6133 +/* ---------------------------------------------------------------------- */
6137 +#define AuDbg(fmt, ...) do { \
6138 + if (au_debug_test()) \
6139 + pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
6141 +#define AuLabel(l) AuDbg(#l "\n")
6142 +#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
6143 +#define AuWarn1(fmt, ...) do { \
6144 + static unsigned char _c; \
6146 + pr_warn(fmt, ##__VA_ARGS__); \
6149 +#define AuErr1(fmt, ...) do { \
6150 + static unsigned char _c; \
6152 + pr_err(fmt, ##__VA_ARGS__); \
6155 +#define AuIOErr1(fmt, ...) do { \
6156 + static unsigned char _c; \
6158 + AuIOErr(fmt, ##__VA_ARGS__); \
6161 +#define AuUnsupportMsg "This operation is not supported." \
6162 + " Please report this application to aufs-users ML."
6163 +#define AuUnsupport(fmt, ...) do { \
6164 + pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
6168 +#define AuTraceErr(e) do { \
6169 + if (unlikely((e) < 0)) \
6170 + AuDbg("err %d\n", (int)(e)); \
6173 +#define AuTraceErrPtr(p) do { \
6175 + AuDbg("err %ld\n", PTR_ERR(p)); \
6178 +/* dirty macros for debug print, use with "%.*s" and caution */
6179 +#define AuLNPair(qstr) (qstr)->len, (qstr)->name
6180 +#define AuDLNPair(d) AuLNPair(&(d)->d_name)
6182 +/* ---------------------------------------------------------------------- */
6187 +#ifdef CONFIG_AUFS_DEBUG
6188 +extern char *au_plevel;
6190 +void au_dpri_whlist(struct au_nhash *whlist);
6192 +void au_dpri_vdir(struct au_vdir *vdir);
6194 +void au_dpri_inode(struct inode *inode);
6195 +void au_dpri_dalias(struct inode *inode);
6196 +void au_dpri_dentry(struct dentry *dentry);
6198 +void au_dpri_file(struct file *filp);
6199 +struct super_block;
6200 +void au_dpri_sb(struct super_block *sb);
6202 +void au_dbg_sleep_jiffy(int jiffy);
6204 +void au_dbg_iattr(struct iattr *ia);
6206 +#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
6207 +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
6208 +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
6209 +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
6210 +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
6211 +void au_dbg_verify_kthread(void);
6213 +int __init au_debug_init(void);
6214 +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
6215 +#define AuDbgWhlist(w) do { \
6217 + au_dpri_whlist(w); \
6220 +#define AuDbgVdir(v) do { \
6222 + au_dpri_vdir(v); \
6225 +#define AuDbgInode(i) do { \
6227 + au_dpri_inode(i); \
6230 +#define AuDbgDAlias(i) do { \
6232 + au_dpri_dalias(i); \
6235 +#define AuDbgDentry(d) do { \
6237 + au_dpri_dentry(d); \
6240 +#define AuDbgFile(f) do { \
6242 + au_dpri_file(f); \
6245 +#define AuDbgSb(sb) do { \
6246 + AuDbg(#sb "\n"); \
6250 +#define AuDbgSleep(sec) do { \
6251 + AuDbg("sleep %d sec\n", sec); \
6255 +#define AuDbgSleepJiffy(jiffy) do { \
6256 + AuDbg("sleep %d jiffies\n", jiffy); \
6257 + au_dbg_sleep_jiffy(jiffy); \
6260 +#define AuDbgIAttr(ia) do { \
6261 + AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
6262 + au_dbg_iattr(ia); \
6265 +#define AuDbgSym(addr) do { \
6266 + char sym[KSYM_SYMBOL_LEN]; \
6267 + sprint_symbol(sym, (unsigned long)addr); \
6268 + AuDbg("%s\n", sym); \
6271 +#define AuInfoSym(addr) do { \
6272 + char sym[KSYM_SYMBOL_LEN]; \
6273 + sprint_symbol(sym, (unsigned long)addr); \
6274 + AuInfo("%s\n", sym); \
6277 +AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
6278 +AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
6279 +AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
6280 + unsigned int sigen)
6281 +AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
6282 +AuStubVoid(au_dbg_verify_kthread, void)
6283 +AuStubInt0(__init au_debug_init, void)
6284 +AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
6286 +#define AuDbgWhlist(w) do {} while (0)
6287 +#define AuDbgVdir(v) do {} while (0)
6288 +#define AuDbgInode(i) do {} while (0)
6289 +#define AuDbgDAlias(i) do {} while (0)
6290 +#define AuDbgDentry(d) do {} while (0)
6291 +#define AuDbgFile(f) do {} while (0)
6292 +#define AuDbgSb(sb) do {} while (0)
6293 +#define AuDbgSleep(sec) do {} while (0)
6294 +#define AuDbgSleepJiffy(jiffy) do {} while (0)
6295 +#define AuDbgIAttr(ia) do {} while (0)
6296 +#define AuDbgSym(addr) do {} while (0)
6297 +#define AuInfoSym(addr) do {} while (0)
6298 +#endif /* CONFIG_AUFS_DEBUG */
6300 +/* ---------------------------------------------------------------------- */
6302 +#ifdef CONFIG_AUFS_MAGIC_SYSRQ
6303 +int __init au_sysrq_init(void);
6304 +void au_sysrq_fin(void);
6306 +#ifdef CONFIG_HW_CONSOLE
6307 +#define au_dbg_blocked() do { \
6309 + handle_sysrq('w'); \
6312 +AuStubVoid(au_dbg_blocked, void)
6316 +AuStubInt0(__init au_sysrq_init, void)
6317 +AuStubVoid(au_sysrq_fin, void)
6318 +AuStubVoid(au_dbg_blocked, void)
6319 +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
6321 +#endif /* __KERNEL__ */
6322 +#endif /* __AUFS_DEBUG_H__ */
6323 diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
6324 --- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
6325 +++ linux/fs/aufs/dentry.c 2013-07-06 13:20:47.740198107 +0200
6328 + * Copyright (C) 2005-2013 Junjiro R. Okajima
6330 + * This program, aufs is free software; you can redistribute it and/or modify
6331 + * it under the terms of the GNU General Public License as published by
6332 + * the Free Software Foundation; either version 2 of the License, or
6333 + * (at your option) any later version.
6335 + * This program is distributed in the hope that it will be useful,
6336 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6337 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6338 + * GNU General Public License for more details.
6340 + * You should have received a copy of the GNU General Public License
6341 + * along with this program; if not, write to the Free Software
6342 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6346 + * lookup and dentry operations
6349 +#include <linux/namei.h>
6352 +#define AuLkup_ALLOW_NEG 1
6353 +#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
6354 +#define au_fset_lkup(flags, name) \
6355 + do { (flags) |= AuLkup_##name; } while (0)
6356 +#define au_fclr_lkup(flags, name) \
6357 + do { (flags) &= ~AuLkup_##name; } while (0)
6359 +struct au_do_lookup_args {
6360 + unsigned int flags;
6365 + * returns positive/negative dentry, NULL or an error.
6366 + * NULL means whiteout-ed or not-found.
6368 +static struct dentry*
6369 +au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
6370 + aufs_bindex_t bindex, struct qstr *wh_name,
6371 + struct au_do_lookup_args *args)
6373 + struct dentry *h_dentry;
6374 + struct inode *h_inode, *inode;
6375 + struct au_branch *br;
6376 + int wh_found, opq;
6377 + unsigned char wh_able;
6378 + const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
6381 + br = au_sbr(dentry->d_sb, bindex);
6382 + wh_able = !!au_br_whable(br->br_perm);
6384 + wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
6385 + h_dentry = ERR_PTR(wh_found);
6388 + if (unlikely(wh_found < 0))
6391 + /* We found a whiteout */
6392 + /* au_set_dbend(dentry, bindex); */
6393 + au_set_dbwh(dentry, bindex);
6395 + return NULL; /* success */
6398 + h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
6399 + if (IS_ERR(h_dentry))
6402 + h_inode = h_dentry->d_inode;
6406 + } else if (wh_found
6407 + || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
6410 + if (au_dbend(dentry) <= bindex)
6411 + au_set_dbend(dentry, bindex);
6412 + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
6413 + au_set_dbstart(dentry, bindex);
6414 + au_set_h_dptr(dentry, bindex, h_dentry);
6416 + inode = dentry->d_inode;
6417 + if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
6418 + || (inode && !S_ISDIR(inode->i_mode)))
6419 + goto out; /* success */
6421 + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
6422 + opq = au_diropq_test(h_dentry, br);
6423 + mutex_unlock(&h_inode->i_mutex);
6425 + au_set_dbdiropq(dentry, bindex);
6426 + else if (unlikely(opq < 0)) {
6427 + au_set_h_dptr(dentry, bindex, NULL);
6428 + h_dentry = ERR_PTR(opq);
6439 +static int au_test_shwh(struct super_block *sb, const struct qstr *name)
6441 + if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
6442 + && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
6448 + * returns the number of lower positive dentries,
6449 + * otherwise an error.
6450 + * can be called at unlinking with @type is zero.
6452 +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
6454 + int npositive, err;
6455 + aufs_bindex_t bindex, btail, bdiropq;
6456 + unsigned char isdir;
6457 + struct qstr whname;
6458 + struct au_do_lookup_args args = {
6462 + const struct qstr *name = &dentry->d_name;
6463 + struct dentry *parent;
6464 + struct inode *inode;
6466 + err = au_test_shwh(dentry->d_sb, name);
6467 + if (unlikely(err))
6470 + err = au_wh_name_alloc(&whname, name);
6471 + if (unlikely(err))
6474 + inode = dentry->d_inode;
6475 + isdir = !!(inode && S_ISDIR(inode->i_mode));
6477 + au_fset_lkup(args.flags, ALLOW_NEG);
6480 + parent = dget_parent(dentry);
6481 + btail = au_dbtaildir(parent);
6482 + for (bindex = bstart; bindex <= btail; bindex++) {
6483 + struct dentry *h_parent, *h_dentry;
6484 + struct inode *h_inode, *h_dir;
6486 + h_dentry = au_h_dptr(dentry, bindex);
6488 + if (h_dentry->d_inode)
6490 + if (type != S_IFDIR)
6494 + h_parent = au_h_dptr(parent, bindex);
6497 + h_dir = h_parent->d_inode;
6498 + if (!h_dir || !S_ISDIR(h_dir->i_mode))
6501 + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
6502 + h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
6504 + mutex_unlock(&h_dir->i_mutex);
6505 + err = PTR_ERR(h_dentry);
6506 + if (IS_ERR(h_dentry))
6508 + au_fclr_lkup(args.flags, ALLOW_NEG);
6510 + if (au_dbwh(dentry) >= 0)
6514 + h_inode = h_dentry->d_inode;
6519 + args.type = h_inode->i_mode & S_IFMT;
6520 + if (args.type != S_IFDIR)
6523 + /* the type of lower may be different */
6524 + bdiropq = au_dbdiropq(dentry);
6525 + if (bdiropq >= 0 && bdiropq <= bindex)
6531 + AuLabel(positive);
6532 + au_update_dbstart(dentry);
6535 + if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
6536 + && au_dbstart(dentry) < 0)) {
6538 + AuIOErr("both of real entry and whiteout found, %.*s, err %d\n",
6539 + AuDLNPair(dentry), err);
6544 + kfree(whname.name);
6549 +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
6550 + struct au_branch *br)
6552 + struct dentry *dentry;
6555 + if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
6556 + dentry = vfsub_lkup_one(name, parent);
6558 + struct vfsub_lkup_one_args args = {
6564 + wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
6565 + if (unlikely(wkq_err))
6566 + dentry = ERR_PTR(wkq_err);
6573 + * lookup @dentry on @bindex which should be negative.
6575 +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
6578 + struct dentry *parent, *h_parent, *h_dentry;
6579 + struct au_branch *br;
6581 + parent = dget_parent(dentry);
6582 + h_parent = au_h_dptr(parent, bindex);
6583 + br = au_sbr(dentry->d_sb, bindex);
6585 + h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
6587 + h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent, br);
6588 + err = PTR_ERR(h_dentry);
6589 + if (IS_ERR(h_dentry))
6591 + if (unlikely(h_dentry->d_inode)) {
6593 + AuIOErr("%.*s should be negative on b%d.\n",
6594 + AuDLNPair(h_dentry), bindex);
6600 + if (bindex < au_dbstart(dentry))
6601 + au_set_dbstart(dentry, bindex);
6602 + if (au_dbend(dentry) < bindex)
6603 + au_set_dbend(dentry, bindex);
6604 + au_set_h_dptr(dentry, bindex, h_dentry);
6611 +/* ---------------------------------------------------------------------- */
6613 +/* subset of struct inode */
6615 + unsigned long i_ino;
6616 + /* unsigned int i_nlink; */
6622 + blkcnt_t i_blocks;
6627 +static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
6629 + ia->i_ino = h_inode->i_ino;
6630 + /* ia->i_nlink = h_inode->i_nlink; */
6631 + ia->i_uid = h_inode->i_uid;
6632 + ia->i_gid = h_inode->i_gid;
6633 + ia->i_version = h_inode->i_version;
6635 + ia->i_size = h_inode->i_size;
6636 + ia->i_blocks = h_inode->i_blocks;
6638 + ia->i_mode = (h_inode->i_mode & S_IFMT);
6641 +static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
6643 + return ia->i_ino != h_inode->i_ino
6644 + /* || ia->i_nlink != h_inode->i_nlink */
6645 + || !uid_eq(ia->i_uid, h_inode->i_uid)
6646 + || !gid_eq(ia->i_gid, h_inode->i_gid)
6647 + || ia->i_version != h_inode->i_version
6649 + || ia->i_size != h_inode->i_size
6650 + || ia->i_blocks != h_inode->i_blocks
6652 + || ia->i_mode != (h_inode->i_mode & S_IFMT);
6655 +static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
6656 + struct au_branch *br)
6659 + struct au_iattr ia;
6660 + struct inode *h_inode;
6661 + struct dentry *h_d;
6662 + struct super_block *h_sb;
6665 + memset(&ia, -1, sizeof(ia));
6666 + h_sb = h_dentry->d_sb;
6667 + h_inode = h_dentry->d_inode;
6669 + au_iattr_save(&ia, h_inode);
6670 + else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
6671 + /* nfs d_revalidate may return 0 for negative dentry */
6672 + /* fuse d_revalidate always return 0 for negative dentry */
6675 + /* main purpose is namei.c:cached_lookup() and d_revalidate */
6676 + h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
6677 + err = PTR_ERR(h_d);
6682 + if (unlikely(h_d != h_dentry
6683 + || h_d->d_inode != h_inode
6684 + || (h_inode && au_iattr_test(&ia, h_inode))))
6685 + err = au_busy_or_stale();
6693 +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
6694 + struct dentry *h_parent, struct au_branch *br)
6699 + if (udba == AuOpt_UDBA_REVAL
6700 + && !au_test_fs_remote(h_dentry->d_sb)) {
6702 + err = (h_dentry->d_parent->d_inode != h_dir);
6703 + } else if (udba != AuOpt_UDBA_NONE)
6704 + err = au_h_verify_dentry(h_dentry, h_parent, br);
6709 +/* ---------------------------------------------------------------------- */
6711 +static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
6714 + aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
6715 + struct au_hdentry tmp, *p, *q;
6716 + struct au_dinfo *dinfo;
6717 + struct super_block *sb;
6719 + DiMustWriteLock(dentry);
6721 + sb = dentry->d_sb;
6722 + dinfo = au_di(dentry);
6723 + bend = dinfo->di_bend;
6724 + bwh = dinfo->di_bwh;
6725 + bdiropq = dinfo->di_bdiropq;
6726 + p = dinfo->di_hdentry + dinfo->di_bstart;
6727 + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
6728 + if (!p->hd_dentry)
6731 + new_bindex = au_br_index(sb, p->hd_id);
6732 + if (new_bindex == bindex)
6735 + if (dinfo->di_bwh == bindex)
6737 + if (dinfo->di_bdiropq == bindex)
6738 + bdiropq = new_bindex;
6739 + if (new_bindex < 0) {
6741 + p->hd_dentry = NULL;
6745 + /* swap two lower dentries, and loop again */
6746 + q = dinfo->di_hdentry + new_bindex;
6750 + if (tmp.hd_dentry) {
6756 + dinfo->di_bwh = -1;
6757 + if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
6758 + dinfo->di_bwh = bwh;
6760 + dinfo->di_bdiropq = -1;
6762 + && bdiropq <= au_sbend(sb)
6763 + && au_sbr_whable(sb, bdiropq))
6764 + dinfo->di_bdiropq = bdiropq;
6767 + dinfo->di_bstart = -1;
6768 + dinfo->di_bend = -1;
6769 + bend = au_dbend(parent);
6770 + p = dinfo->di_hdentry;
6771 + for (bindex = 0; bindex <= bend; bindex++, p++)
6772 + if (p->hd_dentry) {
6773 + dinfo->di_bstart = bindex;
6777 + if (dinfo->di_bstart >= 0) {
6778 + p = dinfo->di_hdentry + bend;
6779 + for (bindex = bend; bindex >= 0; bindex--, p--)
6780 + if (p->hd_dentry) {
6781 + dinfo->di_bend = bindex;
6790 +static void au_do_hide(struct dentry *dentry)
6792 + struct inode *inode;
6794 + inode = dentry->d_inode;
6796 + if (!S_ISDIR(inode->i_mode)) {
6797 + if (inode->i_nlink && !d_unhashed(dentry))
6798 + drop_nlink(inode);
6800 + clear_nlink(inode);
6801 + /* stop next lookup */
6802 + inode->i_flags |= S_DEAD;
6804 + smp_mb(); /* necessary? */
6809 +static int au_hide_children(struct dentry *parent)
6811 + int err, i, j, ndentry;
6812 + struct au_dcsub_pages dpages;
6813 + struct au_dpage *dpage;
6814 + struct dentry *dentry;
6816 + err = au_dpages_init(&dpages, GFP_NOFS);
6817 + if (unlikely(err))
6819 + err = au_dcsub_pages(&dpages, parent, NULL, NULL);
6820 + if (unlikely(err))
6823 + /* in reverse order */
6824 + for (i = dpages.ndpage - 1; i >= 0; i--) {
6825 + dpage = dpages.dpages + i;
6826 + ndentry = dpage->ndentry;
6827 + for (j = ndentry - 1; j >= 0; j--) {
6828 + dentry = dpage->dentries[j];
6829 + if (dentry != parent)
6830 + au_do_hide(dentry);
6835 + au_dpages_free(&dpages);
6840 +static void au_hide(struct dentry *dentry)
6843 + struct inode *inode;
6845 + AuDbgDentry(dentry);
6846 + inode = dentry->d_inode;
6847 + if (inode && S_ISDIR(inode->i_mode)) {
6848 + /* shrink_dcache_parent(dentry); */
6849 + err = au_hide_children(dentry);
6850 + if (unlikely(err))
6851 + AuIOErr("%.*s, failed hiding children, ignored %d\n",
6852 + AuDLNPair(dentry), err);
6854 + au_do_hide(dentry);
6858 + * By adding a dirty branch, a cached dentry may be affected in various ways.
6860 + * a dirty branch is added
6861 + * - on the top of layers
6862 + * - in the middle of layers
6863 + * - to the bottom of layers
6865 + * on the added branch there exists
6868 + * - a same named entry
6870 + * * negative --> positive
6871 + * * positive --> positive
6872 + * - type is unchanged
6873 + * - type is changed
6875 + * * negative --> negative
6876 + * * positive --> negative (rejected by au_br_del() for non-dir case)
6879 +static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
6880 + struct au_dinfo *tmp)
6883 + aufs_bindex_t bindex, bend;
6885 + struct dentry *dentry;
6886 + struct inode *inode;
6889 + struct au_hdentry *hd;
6890 + struct inode *inode, *h_inode;
6891 + struct dentry *h_dentry;
6894 + AuDebugOn(dinfo->di_bstart < 0);
6895 + orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
6896 + orig_h.inode = orig_h.dentry->d_inode;
6899 + orig_h.mode = orig_h.inode->i_mode & S_IFMT;
6900 + memset(&tmp_h, 0, sizeof(tmp_h));
6901 + if (tmp->di_bstart >= 0) {
6902 + tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
6903 + tmp_h.inode = tmp_h.dentry->d_inode;
6905 + tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
6908 + inode = dentry->d_inode;
6909 + if (!orig_h.inode) {
6910 + AuDbg("nagative originally\n");
6916 + AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
6917 + AuDebugOn(dinfo->di_bdiropq != -1);
6919 + if (!tmp_h.inode) {
6920 + AuDbg("negative --> negative\n");
6921 + /* should have only one negative lower */
6922 + if (tmp->di_bstart >= 0
6923 + && tmp->di_bstart < dinfo->di_bstart) {
6924 + AuDebugOn(tmp->di_bstart != tmp->di_bend);
6925 + AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
6926 + au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
6927 + au_di_cp(dinfo, tmp);
6928 + hd = tmp->di_hdentry + tmp->di_bstart;
6929 + au_set_h_dptr(dentry, tmp->di_bstart,
6930 + dget(hd->hd_dentry));
6932 + au_dbg_verify_dinode(dentry);
6934 + AuDbg("negative --> positive\n");
6936 + * similar to the behaviour of creating with bypassing
6938 + * unhash it in order to force an error in the
6939 + * succeeding create operation.
6940 + * we should not set S_DEAD here.
6943 + /* au_di_swap(tmp, dinfo); */
6944 + au_dbg_verify_dinode(dentry);
6947 + AuDbg("positive originally\n");
6948 + /* inode may be NULL */
6949 + AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
6950 + if (!tmp_h.inode) {
6951 + AuDbg("positive --> negative\n");
6952 + /* or bypassing aufs */
6954 + if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
6955 + dinfo->di_bwh = tmp->di_bwh;
6957 + err = au_refresh_hinode_self(inode);
6958 + au_dbg_verify_dinode(dentry);
6959 + } else if (orig_h.mode == tmp_h.mode) {
6960 + AuDbg("positive --> positive, same type\n");
6961 + if (!S_ISDIR(orig_h.mode)
6962 + && dinfo->di_bstart > tmp->di_bstart) {
6964 + * similar to the behaviour of removing and
6969 + err = au_refresh_hinode_self(inode);
6970 + au_dbg_verify_dinode(dentry);
6972 + /* fill empty slots */
6973 + if (dinfo->di_bstart > tmp->di_bstart)
6974 + dinfo->di_bstart = tmp->di_bstart;
6975 + if (dinfo->di_bend < tmp->di_bend)
6976 + dinfo->di_bend = tmp->di_bend;
6977 + dinfo->di_bwh = tmp->di_bwh;
6978 + dinfo->di_bdiropq = tmp->di_bdiropq;
6979 + hd = tmp->di_hdentry;
6980 + bend = dinfo->di_bend;
6981 + for (bindex = tmp->di_bstart; bindex <= bend;
6983 + if (au_h_dptr(dentry, bindex))
6985 + h_dentry = hd[bindex].hd_dentry;
6988 + h_inode = h_dentry->d_inode;
6989 + AuDebugOn(!h_inode);
6990 + AuDebugOn(orig_h.mode
6991 + != (h_inode->i_mode
6993 + au_set_h_dptr(dentry, bindex,
6996 + err = au_refresh_hinode(inode, dentry);
6997 + au_dbg_verify_dinode(dentry);
7000 + AuDbg("positive --> positive, different type\n");
7001 + /* similar to the behaviour of removing and creating */
7004 + err = au_refresh_hinode_self(inode);
7005 + au_dbg_verify_dinode(dentry);
7013 +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
7016 + unsigned int sigen;
7017 + struct au_dinfo *dinfo, *tmp;
7018 + struct super_block *sb;
7019 + struct inode *inode;
7021 + DiMustWriteLock(dentry);
7022 + AuDebugOn(IS_ROOT(dentry));
7023 + AuDebugOn(!parent->d_inode);
7025 + sb = dentry->d_sb;
7026 + inode = dentry->d_inode;
7027 + sigen = au_sigen(sb);
7028 + err = au_digen_test(parent, sigen);
7029 + if (unlikely(err))
7032 + dinfo = au_di(dentry);
7033 + err = au_di_realloc(dinfo, au_sbend(sb) + 1);
7034 + if (unlikely(err))
7036 + ebrange = au_dbrange_test(dentry);
7038 + ebrange = au_do_refresh_hdentry(dentry, parent);
7040 + if (d_unhashed(dentry) || ebrange) {
7041 + AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
7043 + err = au_refresh_hinode_self(inode);
7044 + au_dbg_verify_dinode(dentry);
7046 + goto out_dgen; /* success */
7050 + /* temporary dinfo */
7051 + AuDbgDentry(dentry);
7053 + tmp = au_di_alloc(sb, AuLsc_DI_TMP);
7054 + if (unlikely(!tmp))
7056 + au_di_swap(tmp, dinfo);
7057 + /* returns the number of positive dentries */
7059 + * if current working dir is removed, it returns an error.
7060 + * but the dentry is legal.
7062 + err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
7063 + AuDbgDentry(dentry);
7064 + au_di_swap(tmp, dinfo);
7065 + if (err == -ENOENT)
7068 + /* compare/refresh by dinfo */
7069 + AuDbgDentry(dentry);
7070 + err = au_refresh_by_dinfo(dentry, dinfo, tmp);
7071 + au_dbg_verify_dinode(dentry);
7074 + au_rw_write_unlock(&tmp->di_rwsem);
7076 + if (unlikely(err))
7080 + au_update_digen(dentry);
7082 + if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
7083 + AuIOErr("failed refreshing %.*s, %d\n",
7084 + AuDLNPair(dentry), err);
7085 + AuDbgDentry(dentry);
7091 +static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
7092 + struct dentry *dentry, aufs_bindex_t bindex)
7097 + if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
7100 + AuDbg("b%d\n", bindex);
7102 + * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
7103 + * due to whiteout and branch permission.
7105 + flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
7106 + | LOOKUP_FOLLOW | LOOKUP_EXCL);
7107 + /* it may return tri-state */
7108 + valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
7110 + if (unlikely(valid < 0))
7120 +/* todo: remove this */
7121 +static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
7122 + unsigned int flags, int do_udba)
7125 + umode_t mode, h_mode;
7126 + aufs_bindex_t bindex, btail, bstart, ibs, ibe;
7127 + unsigned char plus, unhashed, is_root, h_plus;
7128 + struct inode *h_inode, *h_cached_inode;
7129 + struct dentry *h_dentry;
7130 + struct qstr *name, *h_name;
7137 + unhashed = !!d_unhashed(dentry);
7138 + is_root = !!IS_ROOT(dentry);
7139 + name = &dentry->d_name;
7142 + * Theoretically, REVAL test should be unnecessary in case of
7144 + * But {fs,i}notify doesn't fire some necessary events,
7145 + * IN_ATTRIB for atime/nlink/pageio
7146 + * IN_DELETE for NFS dentry
7147 + * Let's do REVAL test too.
7149 + if (do_udba && inode) {
7150 + mode = (inode->i_mode & S_IFMT);
7151 + plus = (inode->i_nlink > 0);
7152 + ibs = au_ibstart(inode);
7153 + ibe = au_ibend(inode);
7156 + bstart = au_dbstart(dentry);
7158 + if (inode && S_ISDIR(inode->i_mode))
7159 + btail = au_dbtaildir(dentry);
7160 + for (bindex = bstart; bindex <= btail; bindex++) {
7161 + h_dentry = au_h_dptr(dentry, bindex);
7165 + AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
7166 + spin_lock(&h_dentry->d_lock);
7167 + h_name = &h_dentry->d_name;
7168 + if (unlikely(do_udba
7170 + && (unhashed != !!d_unhashed(h_dentry)
7171 + || name->len != h_name->len
7172 + || memcmp(name->name, h_name->name, name->len))
7174 + AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n",
7175 + unhashed, d_unhashed(h_dentry),
7176 + AuDLNPair(dentry), AuDLNPair(h_dentry));
7177 + spin_unlock(&h_dentry->d_lock);
7180 + spin_unlock(&h_dentry->d_lock);
7182 + err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
7183 + if (unlikely(err))
7184 + /* do not goto err, to keep the errno */
7187 + /* todo: plink too? */
7192 + h_inode = h_dentry->d_inode;
7193 + if (unlikely(!!inode != !!h_inode))
7198 + h_cached_inode = h_inode;
7200 + h_mode = (h_inode->i_mode & S_IFMT);
7201 + h_plus = (h_inode->i_nlink > 0);
7203 + if (inode && ibs <= bindex && bindex <= ibe)
7204 + h_cached_inode = au_h_iptr(inode, bindex);
7206 + if (unlikely(plus != h_plus
7208 + || h_cached_inode != h_inode))
7220 +/* todo: consolidate with do_refresh() and au_reval_for_attr() */
7221 +static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
7224 + struct dentry *parent;
7226 + if (!au_digen_test(dentry, sigen))
7229 + parent = dget_parent(dentry);
7230 + di_read_lock_parent(parent, AuLock_IR);
7231 + AuDebugOn(au_digen_test(parent, sigen));
7232 + au_dbg_verify_gen(parent, sigen);
7233 + err = au_refresh_dentry(dentry, parent);
7234 + di_read_unlock(parent, AuLock_IR);
7240 +int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
7243 + struct dentry *d, *parent;
7244 + struct inode *inode;
7246 + if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
7247 + return simple_reval_dpath(dentry, sigen);
7249 + /* slow loop, keep it simple and stupid */
7250 + /* cf: au_cpup_dirs() */
7253 + while (au_digen_test(dentry, sigen)) {
7257 + parent = dget_parent(d);
7258 + if (!au_digen_test(parent, sigen))
7263 + inode = d->d_inode;
7265 + di_write_lock_child2(d);
7267 + /* someone might update our dentry while we were sleeping */
7268 + if (au_digen_test(d, sigen)) {
7270 + * todo: consolidate with simple_reval_dpath(),
7271 + * do_refresh() and au_reval_for_attr().
7273 + di_read_lock_parent(parent, AuLock_IR);
7274 + err = au_refresh_dentry(d, parent);
7275 + di_read_unlock(parent, AuLock_IR);
7279 + di_write_unlock(d);
7281 + if (unlikely(err))
7289 + * if valid returns 1, otherwise 0.
7291 +static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
7294 + unsigned int sigen;
7295 + unsigned char do_udba;
7296 + struct super_block *sb;
7297 + struct inode *inode;
7299 + /* todo: support rcu-walk? */
7300 + if (flags & LOOKUP_RCU)
7304 + if (unlikely(!au_di(dentry)))
7307 + inode = dentry->d_inode;
7308 + if (inode && is_bad_inode(inode))
7312 + sb = dentry->d_sb;
7315 + * i_mutex of parent dir may be held,
7316 + * but we should not return 'invalid' due to busy.
7318 + err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
7319 + if (unlikely(err)) {
7324 + if (unlikely(au_dbrange_test(dentry))) {
7330 + sigen = au_sigen(sb);
7331 + if (au_digen_test(dentry, sigen)) {
7332 + AuDebugOn(IS_ROOT(dentry));
7333 + err = au_reval_dpath(dentry, sigen);
7334 + if (unlikely(err)) {
7339 + di_downgrade_lock(dentry, AuLock_IR);
7342 + if (inode && (IS_DEADDIR(inode) || !inode->i_nlink))
7345 + do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
7346 + if (do_udba && inode) {
7347 + aufs_bindex_t bstart = au_ibstart(inode);
7348 + struct inode *h_inode;
7350 + if (bstart >= 0) {
7351 + h_inode = au_h_iptr(inode, bstart);
7352 + if (h_inode && au_test_higen(inode, h_inode))
7357 + err = h_d_revalidate(dentry, inode, flags, do_udba);
7358 + if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
7360 + AuDbg("both of real entry and whiteout found, %.*s, err %d\n",
7361 + AuDLNPair(dentry), err);
7366 + di_downgrade_lock(dentry, AuLock_IR);
7368 + aufs_read_unlock(dentry, AuLock_IR);
7373 + AuDbg("%.*s invalid, %d\n", AuDLNPair(dentry), valid);
7379 +static void aufs_d_release(struct dentry *dentry)
7381 + if (au_di(dentry)) {
7382 + au_di_fin(dentry);
7383 + au_hn_di_reinit(dentry);
7387 +const struct dentry_operations aufs_dop = {
7388 + .d_revalidate = aufs_d_revalidate,
7389 + .d_weak_revalidate = aufs_d_revalidate,
7390 + .d_release = aufs_d_release
7392 diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
7393 --- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
7394 +++ linux/fs/aufs/dentry.h 2013-07-06 13:20:47.740198107 +0200
7397 + * Copyright (C) 2005-2013 Junjiro R. Okajima
7399 + * This program, aufs is free software; you can redistribute it and/or modify
7400 + * it under the terms of the GNU General Public License as published by
7401 + * the Free Software Foundation; either version 2 of the License, or
7402 + * (at your option) any later version.
7404 + * This program is distributed in the hope that it will be useful,
7405 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7406 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7407 + * GNU General Public License for more details.
7409 + * You should have received a copy of the GNU General Public License
7410 + * along with this program; if not, write to the Free Software
7411 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7415 + * lookup and dentry operations
7418 +#ifndef __AUFS_DENTRY_H__
7419 +#define __AUFS_DENTRY_H__
7423 +#include <linux/dcache.h>
7426 +struct au_hdentry {
7427 + struct dentry *hd_dentry;
7428 + aufs_bindex_t hd_id;
7432 + atomic_t di_generation;
7434 + struct au_rwsem di_rwsem;
7435 + aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
7436 + struct au_hdentry *di_hdentry;
7437 +} ____cacheline_aligned_in_smp;
7439 +/* ---------------------------------------------------------------------- */
7442 +extern const struct dentry_operations aufs_dop;
7444 +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
7445 + struct au_branch *br);
7446 +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7447 + struct dentry *h_parent, struct au_branch *br);
7449 +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
7450 +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
7451 +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
7452 +int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
7455 +void au_di_init_once(void *_di);
7456 +struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
7457 +void au_di_free(struct au_dinfo *dinfo);
7458 +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
7459 +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
7460 +int au_di_init(struct dentry *dentry);
7461 +void au_di_fin(struct dentry *dentry);
7462 +int au_di_realloc(struct au_dinfo *dinfo, int nbr);
7464 +void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
7465 +void di_read_unlock(struct dentry *d, int flags);
7466 +void di_downgrade_lock(struct dentry *d, int flags);
7467 +void di_write_lock(struct dentry *d, unsigned int lsc);
7468 +void di_write_unlock(struct dentry *d);
7469 +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
7470 +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
7471 +void di_write_unlock2(struct dentry *d1, struct dentry *d2);
7473 +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
7474 +struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
7475 +aufs_bindex_t au_dbtail(struct dentry *dentry);
7476 +aufs_bindex_t au_dbtaildir(struct dentry *dentry);
7478 +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
7479 + struct dentry *h_dentry);
7480 +int au_digen_test(struct dentry *dentry, unsigned int sigen);
7481 +int au_dbrange_test(struct dentry *dentry);
7482 +void au_update_digen(struct dentry *dentry);
7483 +void au_update_dbrange(struct dentry *dentry, int do_put_zero);
7484 +void au_update_dbstart(struct dentry *dentry);
7485 +void au_update_dbend(struct dentry *dentry);
7486 +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
7488 +/* ---------------------------------------------------------------------- */
7490 +static inline struct au_dinfo *au_di(struct dentry *dentry)
7492 + return dentry->d_fsdata;
7495 +/* ---------------------------------------------------------------------- */
7497 +/* lock subclass for dinfo */
7499 + AuLsc_DI_CHILD, /* child first */
7500 + AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
7501 + AuLsc_DI_CHILD3, /* copyup dirs */
7505 + AuLsc_DI_TMP /* temp for replacing dinfo */
7509 + * di_read_lock_child, di_write_lock_child,
7510 + * di_read_lock_child2, di_write_lock_child2,
7511 + * di_read_lock_child3, di_write_lock_child3,
7512 + * di_read_lock_parent, di_write_lock_parent,
7513 + * di_read_lock_parent2, di_write_lock_parent2,
7514 + * di_read_lock_parent3, di_write_lock_parent3,
7516 +#define AuReadLockFunc(name, lsc) \
7517 +static inline void di_read_lock_##name(struct dentry *d, int flags) \
7518 +{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
7520 +#define AuWriteLockFunc(name, lsc) \
7521 +static inline void di_write_lock_##name(struct dentry *d) \
7522 +{ di_write_lock(d, AuLsc_DI_##lsc); }
7524 +#define AuRWLockFuncs(name, lsc) \
7525 + AuReadLockFunc(name, lsc) \
7526 + AuWriteLockFunc(name, lsc)
7528 +AuRWLockFuncs(child, CHILD);
7529 +AuRWLockFuncs(child2, CHILD2);
7530 +AuRWLockFuncs(child3, CHILD3);
7531 +AuRWLockFuncs(parent, PARENT);
7532 +AuRWLockFuncs(parent2, PARENT2);
7533 +AuRWLockFuncs(parent3, PARENT3);
7535 +#undef AuReadLockFunc
7536 +#undef AuWriteLockFunc
7537 +#undef AuRWLockFuncs
7539 +#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
7540 +#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
7541 +#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
7543 +/* ---------------------------------------------------------------------- */
7545 +/* todo: memory barrier? */
7546 +static inline unsigned int au_digen(struct dentry *d)
7548 + return atomic_read(&au_di(d)->di_generation);
7551 +static inline void au_h_dentry_init(struct au_hdentry *hdentry)
7553 + hdentry->hd_dentry = NULL;
7556 +static inline void au_hdput(struct au_hdentry *hd)
7559 + dput(hd->hd_dentry);
7562 +static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
7564 + DiMustAnyLock(dentry);
7565 + return au_di(dentry)->di_bstart;
7568 +static inline aufs_bindex_t au_dbend(struct dentry *dentry)
7570 + DiMustAnyLock(dentry);
7571 + return au_di(dentry)->di_bend;
7574 +static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
7576 + DiMustAnyLock(dentry);
7577 + return au_di(dentry)->di_bwh;
7580 +static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
7582 + DiMustAnyLock(dentry);
7583 + return au_di(dentry)->di_bdiropq;
7586 +/* todo: hard/soft set? */
7587 +static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
7589 + DiMustWriteLock(dentry);
7590 + au_di(dentry)->di_bstart = bindex;
7593 +static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
7595 + DiMustWriteLock(dentry);
7596 + au_di(dentry)->di_bend = bindex;
7599 +static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
7601 + DiMustWriteLock(dentry);
7602 + /* dbwh can be outside of bstart - bend range */
7603 + au_di(dentry)->di_bwh = bindex;
7606 +static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
7608 + DiMustWriteLock(dentry);
7609 + au_di(dentry)->di_bdiropq = bindex;
7612 +/* ---------------------------------------------------------------------- */
7614 +#ifdef CONFIG_AUFS_HNOTIFY
7615 +static inline void au_digen_dec(struct dentry *d)
7617 + atomic_dec(&au_di(d)->di_generation);
7620 +static inline void au_hn_di_reinit(struct dentry *dentry)
7622 + dentry->d_fsdata = NULL;
7625 +AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
7626 +#endif /* CONFIG_AUFS_HNOTIFY */
7628 +#endif /* __KERNEL__ */
7629 +#endif /* __AUFS_DENTRY_H__ */
7630 diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
7631 --- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
7632 +++ linux/fs/aufs/dinfo.c 2013-07-30 22:42:55.839613269 +0200
7635 + * Copyright (C) 2005-2013 Junjiro R. Okajima
7637 + * This program, aufs is free software; you can redistribute it and/or modify
7638 + * it under the terms of the GNU General Public License as published by
7639 + * the Free Software Foundation; either version 2 of the License, or
7640 + * (at your option) any later version.
7642 + * This program is distributed in the hope that it will be useful,
7643 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7644 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7645 + * GNU General Public License for more details.
7647 + * You should have received a copy of the GNU General Public License
7648 + * along with this program; if not, write to the Free Software
7649 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
7653 + * dentry private data
7658 +void au_di_init_once(void *_dinfo)
7660 + struct au_dinfo *dinfo = _dinfo;
7661 + static struct lock_class_key aufs_di;
7663 + au_rw_init(&dinfo->di_rwsem);
7664 + au_rw_class(&dinfo->di_rwsem, &aufs_di);
7667 +struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
7669 + struct au_dinfo *dinfo;
7672 + dinfo = au_cache_alloc_dinfo();
7673 + if (unlikely(!dinfo))
7676 + nbr = au_sbend(sb) + 1;
7679 + dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
7680 + if (dinfo->di_hdentry) {
7681 + au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
7682 + dinfo->di_bstart = -1;
7683 + dinfo->di_bend = -1;
7684 + dinfo->di_bwh = -1;
7685 + dinfo->di_bdiropq = -1;
7686 + for (i = 0; i < nbr; i++)
7687 + dinfo->di_hdentry[i].hd_id = -1;
7691 + au_cache_free_dinfo(dinfo);
7698 +void au_di_free(struct au_dinfo *dinfo)
7700 + struct au_hdentry *p;
7701 + aufs_bindex_t bend, bindex;
7703 + /* dentry may not be revalidated */
7704 + bindex = dinfo->di_bstart;
7705 + if (bindex >= 0) {
7706 + bend = dinfo->di_bend;
7707 + p = dinfo->di_hdentry + bindex;
7708 + while (bindex++ <= bend)
7711 + kfree(dinfo->di_hdentry);
7712 + au_cache_free_dinfo(dinfo);
7715 +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
7717 + struct au_hdentry *p;
7720 + AuRwMustWriteLock(&a->di_rwsem);
7721 + AuRwMustWriteLock(&b->di_rwsem);
7723 +#define DiSwap(v, name) \
7725 + v = a->di_##name; \
7726 + a->di_##name = b->di_##name; \
7727 + b->di_##name = v; \
7730 + DiSwap(p, hdentry);
7731 + DiSwap(bi, bstart);
7734 + DiSwap(bi, bdiropq);
7740 +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
7742 + AuRwMustWriteLock(&dst->di_rwsem);
7743 + AuRwMustWriteLock(&src->di_rwsem);
7745 + dst->di_bstart = src->di_bstart;
7746 + dst->di_bend = src->di_bend;
7747 + dst->di_bwh = src->di_bwh;
7748 + dst->di_bdiropq = src->di_bdiropq;
7752 +int au_di_init(struct dentry *dentry)
7755 + struct super_block *sb;
7756 + struct au_dinfo *dinfo;
7759 + sb = dentry->d_sb;
7760 + dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
7762 + atomic_set(&dinfo->di_generation, au_sigen(sb));
7763 + /* smp_mb(); */ /* atomic_set */
7764 + dentry->d_fsdata = dinfo;
7771 +void au_di_fin(struct dentry *dentry)
7773 + struct au_dinfo *dinfo;
7775 + dinfo = au_di(dentry);
7776 + AuRwDestroy(&dinfo->di_rwsem);
7777 + au_di_free(dinfo);
7780 +int au_di_realloc(struct au_dinfo *dinfo, int nbr)
7783 + struct au_hdentry *hdp;
7785 + AuRwMustWriteLock(&dinfo->di_rwsem);
7788 + sz = sizeof(*hdp) * (dinfo->di_bend + 1);
7790 + sz = sizeof(*hdp);
7791 + hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
7793 + dinfo->di_hdentry = hdp;
7800 +/* ---------------------------------------------------------------------- */
7802 +static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
7805 + case AuLsc_DI_CHILD:
7806 + ii_write_lock_child(inode);
7808 + case AuLsc_DI_CHILD2:
7809 + ii_write_lock_child2(inode);
7811 + case AuLsc_DI_CHILD3:
7812 + ii_write_lock_child3(inode);
7814 + case AuLsc_DI_PARENT:
7815 + ii_write_lock_parent(inode);
7817 + case AuLsc_DI_PARENT2:
7818 + ii_write_lock_parent2(inode);
7820 + case AuLsc_DI_PARENT3:
7821 + ii_write_lock_parent3(inode);
7828 +static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
7831 + case AuLsc_DI_CHILD:
7832 + ii_read_lock_child(inode);
7834 + case AuLsc_DI_CHILD2:
7835 + ii_read_lock_child2(inode);
7837 + case AuLsc_DI_CHILD3:
7838 + ii_read_lock_child3(inode);
7840 + case AuLsc_DI_PARENT:
7841 + ii_read_lock_parent(inode);
7843 + case AuLsc_DI_PARENT2:
7844 + ii_read_lock_parent2(inode);
7846 + case AuLsc_DI_PARENT3:
7847 + ii_read_lock_parent3(inode);
7854 +void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
7856 + au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
7858 + if (au_ftest_lock(flags, IW))
7859 + do_ii_write_lock(d->d_inode, lsc);
7860 + else if (au_ftest_lock(flags, IR))
7861 + do_ii_read_lock(d->d_inode, lsc);
7865 +void di_read_unlock(struct dentry *d, int flags)
7868 + if (au_ftest_lock(flags, IW)) {
7869 + au_dbg_verify_dinode(d);
7870 + ii_write_unlock(d->d_inode);
7871 + } else if (au_ftest_lock(flags, IR)) {
7872 + au_dbg_verify_dinode(d);
7873 + ii_read_unlock(d->d_inode);
7876 + au_rw_read_unlock(&au_di(d)->di_rwsem);
7879 +void di_downgrade_lock(struct dentry *d, int flags)
7881 + if (d->d_inode && au_ftest_lock(flags, IR))
7882 + ii_downgrade_lock(d->d_inode);
7883 + au_rw_dgrade_lock(&au_di(d)->di_rwsem);
7886 +void di_write_lock(struct dentry *d, unsigned int lsc)
7888 + au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
7890 + do_ii_write_lock(d->d_inode, lsc);
7893 +void di_write_unlock(struct dentry *d)
7895 + au_dbg_verify_dinode(d);
7897 + ii_write_unlock(d->d_inode);
7898 + au_rw_write_unlock(&au_di(d)->di_rwsem);
7901 +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
7903 + AuDebugOn(d1 == d2
7904 + || d1->d_inode == d2->d_inode
7905 + || d1->d_sb != d2->d_sb);
7907 + if (isdir && au_test_subdir(d1, d2)) {
7908 + di_write_lock_child(d1);
7909 + di_write_lock_child2(d2);
7911 + /* there should be no races */
7912 + di_write_lock_child(d2);
7913 + di_write_lock_child2(d1);
7917 +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
7919 + AuDebugOn(d1 == d2
7920 + || d1->d_inode == d2->d_inode
7921 + || d1->d_sb != d2->d_sb);
7923 + if (isdir && au_test_subdir(d1, d2)) {
7924 + di_write_lock_parent(d1);
7925 + di_write_lock_parent2(d2);
7927 + /* there should be no races */
7928 + di_write_lock_parent(d2);
7929 + di_write_lock_parent2(d1);
7933 +void di_write_unlock2(struct dentry *d1, struct dentry *d2)
7935 + di_write_unlock(d1);
7936 + if (d1->d_inode == d2->d_inode)
7937 + au_rw_write_unlock(&au_di(d2)->di_rwsem);
7939 + di_write_unlock(d2);
7942 +/* ---------------------------------------------------------------------- */
7944 +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
7948 + DiMustAnyLock(dentry);
7950 + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
7952 + AuDebugOn(bindex < 0);
7953 + d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
7954 + AuDebugOn(d && d->d_count <= 0);
7959 + * extended version of au_h_dptr().
7960 + * returns a hashed and positive h_dentry in bindex, NULL, or error.
7962 +struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
7964 + struct dentry *h_dentry;
7965 + struct inode *inode, *h_inode;
7967 + inode = dentry->d_inode;
7968 + AuDebugOn(!inode);
7971 + if (au_dbstart(dentry) <= bindex
7972 + && bindex <= au_dbend(dentry))
7973 + h_dentry = au_h_dptr(dentry, bindex);
7974 + if (h_dentry && !au_d_hashed_positive(h_dentry)) {
7976 + goto out; /* success */
7979 + AuDebugOn(bindex < au_ibstart(inode));
7980 + AuDebugOn(au_ibend(inode) < bindex);
7981 + h_inode = au_h_iptr(inode, bindex);
7982 + h_dentry = d_find_alias(h_inode);
7984 + if (!IS_ERR(h_dentry)) {
7985 + if (!au_d_hashed_positive(h_dentry))
7986 + goto out; /* success */
7992 + if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
7993 + h_dentry = au_plink_lkup(inode, bindex);
7994 + AuDebugOn(!h_dentry);
7995 + if (!IS_ERR(h_dentry)) {
7996 + if (!au_d_hashed_positive(h_dentry))
7997 + goto out; /* success */
8004 + AuDbgDentry(h_dentry);
8008 +aufs_bindex_t au_dbtail(struct dentry *dentry)
8010 + aufs_bindex_t bend, bwh;
8012 + bend = au_dbend(dentry);
8014 + bwh = au_dbwh(dentry);
8017 + if (0 < bwh && bwh < bend)
8023 +aufs_bindex_t au_dbtaildir(struct dentry *dentry)
8025 + aufs_bindex_t bend, bopq;
8027 + bend = au_dbtail(dentry);
8029 + bopq = au_dbdiropq(dentry);
8030 + if (0 <= bopq && bopq < bend)
8036 +/* ---------------------------------------------------------------------- */
8038 +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8039 + struct dentry *h_dentry)
8041 + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
8042 + struct au_branch *br;
8044 + DiMustWriteLock(dentry);
8047 + hd->hd_dentry = h_dentry;
8049 + br = au_sbr(dentry->d_sb, bindex);
8050 + hd->hd_id = br->br_id;
8054 +int au_dbrange_test(struct dentry *dentry)
8057 + aufs_bindex_t bstart, bend;
8060 + bstart = au_dbstart(dentry);
8061 + bend = au_dbend(dentry);
8063 + AuDebugOn(bend < 0 && bstart > bend);
8066 + AuDebugOn(bend >= 0);
8072 +int au_digen_test(struct dentry *dentry, unsigned int sigen)
8077 + if (unlikely(au_digen(dentry) != sigen
8078 + || au_iigen_test(dentry->d_inode, sigen)))
8084 +void au_update_digen(struct dentry *dentry)
8086 + atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
8087 + /* smp_mb(); */ /* atomic_set */
8090 +void au_update_dbrange(struct dentry *dentry, int do_put_zero)
8092 + struct au_dinfo *dinfo;
8093 + struct dentry *h_d;
8094 + struct au_hdentry *hdp;
8096 + DiMustWriteLock(dentry);
8098 + dinfo = au_di(dentry);
8099 + if (!dinfo || dinfo->di_bstart < 0)
8102 + hdp = dinfo->di_hdentry;
8103 + if (do_put_zero) {
8104 + aufs_bindex_t bindex, bend;
8106 + bend = dinfo->di_bend;
8107 + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
8108 + h_d = hdp[0 + bindex].hd_dentry;
8109 + if (h_d && !h_d->d_inode)
8110 + au_set_h_dptr(dentry, bindex, NULL);
8114 + dinfo->di_bstart = -1;
8115 + while (++dinfo->di_bstart <= dinfo->di_bend)
8116 + if (hdp[0 + dinfo->di_bstart].hd_dentry)
8118 + if (dinfo->di_bstart > dinfo->di_bend) {
8119 + dinfo->di_bstart = -1;
8120 + dinfo->di_bend = -1;
8125 + while (0 <= --dinfo->di_bend)
8126 + if (hdp[0 + dinfo->di_bend].hd_dentry)
8128 + AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
8131 +void au_update_dbstart(struct dentry *dentry)
8133 + aufs_bindex_t bindex, bend;
8134 + struct dentry *h_dentry;
8136 + bend = au_dbend(dentry);
8137 + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
8138 + h_dentry = au_h_dptr(dentry, bindex);
8141 + if (h_dentry->d_inode) {
8142 + au_set_dbstart(dentry, bindex);
8145 + au_set_h_dptr(dentry, bindex, NULL);
8149 +void au_update_dbend(struct dentry *dentry)
8151 + aufs_bindex_t bindex, bstart;
8152 + struct dentry *h_dentry;
8154 + bstart = au_dbstart(dentry);
8155 + for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
8156 + h_dentry = au_h_dptr(dentry, bindex);
8159 + if (h_dentry->d_inode) {
8160 + au_set_dbend(dentry, bindex);
8163 + au_set_h_dptr(dentry, bindex, NULL);
8167 +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
8169 + aufs_bindex_t bindex, bend;
8171 + bend = au_dbend(dentry);
8172 + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
8173 + if (au_h_dptr(dentry, bindex) == h_dentry)
8177 diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
8178 --- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
8179 +++ linux/fs/aufs/dir.c 2013-07-30 22:42:55.839613269 +0200
8182 + * Copyright (C) 2005-2013 Junjiro R. Okajima
8184 + * This program, aufs is free software; you can redistribute it and/or modify
8185 + * it under the terms of the GNU General Public License as published by
8186 + * the Free Software Foundation; either version 2 of the License, or
8187 + * (at your option) any later version.
8189 + * This program is distributed in the hope that it will be useful,
8190 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8191 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8192 + * GNU General Public License for more details.
8194 + * You should have received a copy of the GNU General Public License
8195 + * along with this program; if not, write to the Free Software
8196 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8200 + * directory operations
8203 +#include <linux/fs_stack.h>
8206 +void au_add_nlink(struct inode *dir, struct inode *h_dir)
8208 + unsigned int nlink;
8210 + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8212 + nlink = dir->i_nlink;
8213 + nlink += h_dir->i_nlink - 2;
8214 + if (h_dir->i_nlink < 2)
8217 + /* 0 can happen in revaliding */
8218 + set_nlink(dir, nlink);
8221 +void au_sub_nlink(struct inode *dir, struct inode *h_dir)
8223 + unsigned int nlink;
8225 + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8227 + nlink = dir->i_nlink;
8228 + nlink -= h_dir->i_nlink - 2;
8229 + if (h_dir->i_nlink < 2)
8232 + /* nlink == 0 means the branch-fs is broken */
8233 + set_nlink(dir, nlink);
8236 +loff_t au_dir_size(struct file *file, struct dentry *dentry)
8239 + aufs_bindex_t bindex, bend;
8240 + struct file *h_file;
8241 + struct dentry *h_dentry;
8245 + AuDebugOn(!file_inode(file));
8246 + AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
8248 + bend = au_fbend_dir(file);
8249 + for (bindex = au_fbstart(file);
8250 + bindex <= bend && sz < KMALLOC_MAX_SIZE;
8252 + h_file = au_hf_dir(file, bindex);
8253 + if (h_file && file_inode(h_file))
8254 + sz += vfsub_f_size_read(h_file);
8257 + AuDebugOn(!dentry);
8258 + AuDebugOn(!dentry->d_inode);
8259 + AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
8261 + bend = au_dbtaildir(dentry);
8262 + for (bindex = au_dbstart(dentry);
8263 + bindex <= bend && sz < KMALLOC_MAX_SIZE;
8265 + h_dentry = au_h_dptr(dentry, bindex);
8266 + if (h_dentry && h_dentry->d_inode)
8267 + sz += i_size_read(h_dentry->d_inode);
8270 + if (sz < KMALLOC_MAX_SIZE)
8271 + sz = roundup_pow_of_two(sz);
8272 + if (sz > KMALLOC_MAX_SIZE)
8273 + sz = KMALLOC_MAX_SIZE;
8274 + else if (sz < NAME_MAX) {
8275 + BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
8276 + sz = AUFS_RDBLK_DEF;
8281 +/* ---------------------------------------------------------------------- */
8283 +static int reopen_dir(struct file *file)
8286 + unsigned int flags;
8287 + aufs_bindex_t bindex, btail, bstart;
8288 + struct dentry *dentry, *h_dentry;
8289 + struct file *h_file;
8291 + /* open all lower dirs */
8292 + dentry = file->f_dentry;
8293 + bstart = au_dbstart(dentry);
8294 + for (bindex = au_fbstart(file); bindex < bstart; bindex++)
8295 + au_set_h_fptr(file, bindex, NULL);
8296 + au_set_fbstart(file, bstart);
8298 + btail = au_dbtaildir(dentry);
8299 + for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
8300 + au_set_h_fptr(file, bindex, NULL);
8301 + au_set_fbend_dir(file, btail);
8303 + flags = vfsub_file_flags(file);
8304 + for (bindex = bstart; bindex <= btail; bindex++) {
8305 + h_dentry = au_h_dptr(dentry, bindex);
8308 + h_file = au_hf_dir(file, bindex);
8312 + h_file = au_h_open(dentry, bindex, flags, file);
8313 + err = PTR_ERR(h_file);
8314 + if (IS_ERR(h_file))
8315 + goto out; /* close all? */
8316 + au_set_h_fptr(file, bindex, h_file);
8318 + au_update_figen(file);
8319 + /* todo: necessary? */
8320 + /* file->f_ra = h_file->f_ra; */
8327 +static int do_open_dir(struct file *file, int flags)
8330 + aufs_bindex_t bindex, btail;
8331 + struct dentry *dentry, *h_dentry;
8332 + struct file *h_file;
8334 + FiMustWriteLock(file);
8336 + dentry = file->f_dentry;
8337 + err = au_alive_dir(dentry);
8338 + if (unlikely(err))
8341 + file->f_version = dentry->d_inode->i_version;
8342 + bindex = au_dbstart(dentry);
8343 + au_set_fbstart(file, bindex);
8344 + btail = au_dbtaildir(dentry);
8345 + au_set_fbend_dir(file, btail);
8346 + for (; !err && bindex <= btail; bindex++) {
8347 + h_dentry = au_h_dptr(dentry, bindex);
8351 + h_file = au_h_open(dentry, bindex, flags, file);
8352 + if (IS_ERR(h_file)) {
8353 + err = PTR_ERR(h_file);
8356 + au_set_h_fptr(file, bindex, h_file);
8358 + au_update_figen(file);
8359 + /* todo: necessary? */
8360 + /* file->f_ra = h_file->f_ra; */
8362 + return 0; /* success */
8365 + for (bindex = au_fbstart(file); bindex <= btail; bindex++)
8366 + au_set_h_fptr(file, bindex, NULL);
8367 + au_set_fbstart(file, -1);
8368 + au_set_fbend_dir(file, -1);
8374 +static int aufs_open_dir(struct inode *inode __maybe_unused,
8375 + struct file *file)
8378 + struct super_block *sb;
8379 + struct au_fidir *fidir;
8382 + sb = file->f_dentry->d_sb;
8383 + si_read_lock(sb, AuLock_FLUSH);
8384 + fidir = au_fidir_alloc(sb);
8386 + err = au_do_open(file, do_open_dir, fidir);
8387 + if (unlikely(err))
8390 + si_read_unlock(sb);
8394 +static int aufs_release_dir(struct inode *inode __maybe_unused,
8395 + struct file *file)
8397 + struct au_vdir *vdir_cache;
8398 + struct au_finfo *finfo;
8399 + struct au_fidir *fidir;
8400 + aufs_bindex_t bindex, bend;
8402 + finfo = au_fi(file);
8403 + fidir = finfo->fi_hdir;
8405 + vdir_cache = fidir->fd_vdir_cache; /* lock-free */
8407 + au_vdir_free(vdir_cache);
8409 + bindex = finfo->fi_btop;
8410 + if (bindex >= 0) {
8412 + * calls fput() instead of filp_close(),
8413 + * since no dnotify or lock for the lower file.
8415 + bend = fidir->fd_bbot;
8416 + for (; bindex <= bend; bindex++)
8417 + au_set_h_fptr(file, bindex, NULL);
8420 + finfo->fi_hdir = NULL;
8422 + au_finfo_fin(file);
8426 +/* ---------------------------------------------------------------------- */
8428 +static int au_do_flush_dir(struct file *file, fl_owner_t id)
8431 + aufs_bindex_t bindex, bend;
8432 + struct file *h_file;
8435 + bend = au_fbend_dir(file);
8436 + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8437 + h_file = au_hf_dir(file, bindex);
8439 + err = vfsub_flush(h_file, id);
8444 +static int aufs_flush_dir(struct file *file, fl_owner_t id)
8446 + return au_do_flush(file, id, au_do_flush_dir);
8449 +/* ---------------------------------------------------------------------- */
8451 +static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
8454 + aufs_bindex_t bend, bindex;
8455 + struct inode *inode;
8456 + struct super_block *sb;
8459 + sb = dentry->d_sb;
8460 + inode = dentry->d_inode;
8462 + bend = au_dbend(dentry);
8463 + for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
8464 + struct path h_path;
8466 + if (au_test_ro(sb, bindex, inode))
8468 + h_path.dentry = au_h_dptr(dentry, bindex);
8469 + if (!h_path.dentry)
8472 + h_path.mnt = au_sbr_mnt(sb, bindex);
8473 + err = vfsub_fsync(NULL, &h_path, datasync);
8479 +static int au_do_fsync_dir(struct file *file, int datasync)
8482 + aufs_bindex_t bend, bindex;
8483 + struct file *h_file;
8484 + struct super_block *sb;
8485 + struct inode *inode;
8487 + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8488 + if (unlikely(err))
8491 + sb = file->f_dentry->d_sb;
8492 + inode = file_inode(file);
8493 + bend = au_fbend_dir(file);
8494 + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8495 + h_file = au_hf_dir(file, bindex);
8496 + if (!h_file || au_test_ro(sb, bindex, inode))
8499 + err = vfsub_fsync(h_file, &h_file->f_path, datasync);
8507 + * @file may be NULL
8509 +static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
8513 + struct dentry *dentry;
8514 + struct super_block *sb;
8515 + struct mutex *mtx;
8518 + dentry = file->f_dentry;
8519 + mtx = &dentry->d_inode->i_mutex;
8521 + sb = dentry->d_sb;
8522 + si_noflush_read_lock(sb);
8524 + err = au_do_fsync_dir(file, datasync);
8526 + di_write_lock_child(dentry);
8527 + err = au_do_fsync_dir_no_file(dentry, datasync);
8529 + au_cpup_attr_timesizes(dentry->d_inode);
8530 + di_write_unlock(dentry);
8532 + fi_write_unlock(file);
8534 + si_read_unlock(sb);
8535 + mutex_unlock(mtx);
8539 +/* ---------------------------------------------------------------------- */
8541 +static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir)
8544 + struct dentry *dentry;
8545 + struct inode *inode, *h_inode;
8546 + struct super_block *sb;
8548 + dentry = file->f_dentry;
8549 + inode = dentry->d_inode;
8552 + sb = dentry->d_sb;
8553 + si_read_lock(sb, AuLock_FLUSH);
8554 + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8555 + if (unlikely(err))
8557 + err = au_alive_dir(dentry);
8559 + err = au_vdir_init(file);
8560 + di_downgrade_lock(dentry, AuLock_IR);
8561 + if (unlikely(err))
8564 + h_inode = au_h_iptr(inode, au_ibstart(inode));
8565 + if (!au_test_nfsd()) {
8566 + err = au_vdir_fill_de(file, dirent, filldir);
8567 + fsstack_copy_attr_atime(inode, h_inode);
8570 + * nfsd filldir may call lookup_one_len(), vfs_getattr(),
8571 + * encode_fh() and others.
8573 + atomic_inc(&h_inode->i_count);
8574 + di_read_unlock(dentry, AuLock_IR);
8575 + si_read_unlock(sb);
8576 + err = au_vdir_fill_de(file, dirent, filldir);
8577 + fsstack_copy_attr_atime(inode, h_inode);
8578 + fi_write_unlock(file);
8586 + di_read_unlock(dentry, AuLock_IR);
8587 + fi_write_unlock(file);
8589 + si_read_unlock(sb);
8593 +/* ---------------------------------------------------------------------- */
8595 +#define AuTestEmpty_WHONLY 1
8596 +#define AuTestEmpty_CALLED (1 << 1)
8597 +#define AuTestEmpty_SHWH (1 << 2)
8598 +#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
8599 +#define au_fset_testempty(flags, name) \
8600 + do { (flags) |= AuTestEmpty_##name; } while (0)
8601 +#define au_fclr_testempty(flags, name) \
8602 + do { (flags) &= ~AuTestEmpty_##name; } while (0)
8604 +#ifndef CONFIG_AUFS_SHWH
8605 +#undef AuTestEmpty_SHWH
8606 +#define AuTestEmpty_SHWH 0
8609 +struct test_empty_arg {
8610 + struct au_nhash *whlist;
8611 + unsigned int flags;
8613 + aufs_bindex_t bindex;
8616 +static int test_empty_cb(void *__arg, const char *__name, int namelen,
8617 + loff_t offset __maybe_unused, u64 ino,
8618 + unsigned int d_type)
8620 + struct test_empty_arg *arg = __arg;
8621 + char *name = (void *)__name;
8624 + au_fset_testempty(arg->flags, CALLED);
8626 + if (name[0] == '.'
8627 + && (namelen == 1 || (name[1] == '.' && namelen == 2)))
8628 + goto out; /* success */
8630 + if (namelen <= AUFS_WH_PFX_LEN
8631 + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
8632 + if (au_ftest_testempty(arg->flags, WHONLY)
8633 + && !au_nhash_test_known_wh(arg->whlist, name, namelen))
8634 + arg->err = -ENOTEMPTY;
8638 + name += AUFS_WH_PFX_LEN;
8639 + namelen -= AUFS_WH_PFX_LEN;
8640 + if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
8641 + arg->err = au_nhash_append_wh
8642 + (arg->whlist, name, namelen, ino, d_type, arg->bindex,
8643 + au_ftest_testempty(arg->flags, SHWH));
8647 + AuTraceErr(arg->err);
8651 +static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8654 + struct file *h_file;
8656 + h_file = au_h_open(dentry, arg->bindex,
8657 + O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
8659 + err = PTR_ERR(h_file);
8660 + if (IS_ERR(h_file))
8664 + if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
8665 + && !file_inode(h_file)->i_nlink)
8670 + au_fclr_testempty(arg->flags, CALLED);
8672 + err = vfsub_readdir(h_file, test_empty_cb, arg);
8675 + } while (!err && au_ftest_testempty(arg->flags, CALLED));
8679 + au_sbr_put(dentry->d_sb, arg->bindex);
8684 +struct do_test_empty_args {
8686 + struct dentry *dentry;
8687 + struct test_empty_arg *arg;
8690 +static void call_do_test_empty(void *args)
8692 + struct do_test_empty_args *a = args;
8693 + *a->errp = do_test_empty(a->dentry, a->arg);
8696 +static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8699 + struct dentry *h_dentry;
8700 + struct inode *h_inode;
8702 + h_dentry = au_h_dptr(dentry, arg->bindex);
8703 + h_inode = h_dentry->d_inode;
8704 + /* todo: i_mode changes anytime? */
8705 + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
8706 + err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
8707 + mutex_unlock(&h_inode->i_mutex);
8709 + err = do_test_empty(dentry, arg);
8711 + struct do_test_empty_args args = {
8716 + unsigned int flags = arg->flags;
8718 + wkq_err = au_wkq_wait(call_do_test_empty, &args);
8719 + if (unlikely(wkq_err))
8721 + arg->flags = flags;
8727 +int au_test_empty_lower(struct dentry *dentry)
8730 + unsigned int rdhash;
8731 + aufs_bindex_t bindex, bstart, btail;
8732 + struct au_nhash whlist;
8733 + struct test_empty_arg arg;
8735 + SiMustAnyLock(dentry->d_sb);
8737 + rdhash = au_sbi(dentry->d_sb)->si_rdhash;
8739 + rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
8740 + err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
8741 + if (unlikely(err))
8745 + arg.whlist = &whlist;
8746 + bstart = au_dbstart(dentry);
8747 + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8748 + au_fset_testempty(arg.flags, SHWH);
8749 + arg.bindex = bstart;
8750 + err = do_test_empty(dentry, &arg);
8751 + if (unlikely(err))
8754 + au_fset_testempty(arg.flags, WHONLY);
8755 + btail = au_dbtaildir(dentry);
8756 + for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
8757 + struct dentry *h_dentry;
8759 + h_dentry = au_h_dptr(dentry, bindex);
8760 + if (h_dentry && h_dentry->d_inode) {
8761 + arg.bindex = bindex;
8762 + err = do_test_empty(dentry, &arg);
8767 + au_nhash_wh_free(&whlist);
8772 +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
8775 + struct test_empty_arg arg;
8776 + aufs_bindex_t bindex, btail;
8779 + arg.whlist = whlist;
8780 + arg.flags = AuTestEmpty_WHONLY;
8781 + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8782 + au_fset_testempty(arg.flags, SHWH);
8783 + btail = au_dbtaildir(dentry);
8784 + for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
8785 + struct dentry *h_dentry;
8787 + h_dentry = au_h_dptr(dentry, bindex);
8788 + if (h_dentry && h_dentry->d_inode) {
8789 + arg.bindex = bindex;
8790 + err = sio_test_empty(dentry, &arg);
8797 +/* ---------------------------------------------------------------------- */
8799 +const struct file_operations aufs_dir_fop = {
8800 + .owner = THIS_MODULE,
8801 + .llseek = default_llseek,
8802 + .read = generic_read_dir,
8803 + .readdir = aufs_readdir,
8804 + .unlocked_ioctl = aufs_ioctl_dir,
8805 +#ifdef CONFIG_COMPAT
8806 + .compat_ioctl = aufs_compat_ioctl_dir,
8808 + .open = aufs_open_dir,
8809 + .release = aufs_release_dir,
8810 + .flush = aufs_flush_dir,
8811 + .fsync = aufs_fsync_dir
8813 diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
8814 --- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
8815 +++ linux/fs/aufs/dir.h 2013-07-30 22:42:55.839613269 +0200
8818 + * Copyright (C) 2005-2013 Junjiro R. Okajima
8820 + * This program, aufs is free software; you can redistribute it and/or modify
8821 + * it under the terms of the GNU General Public License as published by
8822 + * the Free Software Foundation; either version 2 of the License, or
8823 + * (at your option) any later version.
8825 + * This program is distributed in the hope that it will be useful,
8826 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8827 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8828 + * GNU General Public License for more details.
8830 + * You should have received a copy of the GNU General Public License
8831 + * along with this program; if not, write to the Free Software
8832 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8836 + * directory operations
8839 +#ifndef __AUFS_DIR_H__
8840 +#define __AUFS_DIR_H__
8844 +#include <linux/fs.h>
8846 +/* ---------------------------------------------------------------------- */
8848 +/* need to be faster and smaller */
8851 + unsigned int nh_num;
8852 + struct hlist_head *nh_head;
8855 +struct au_vdir_destr {
8856 + unsigned char len;
8857 + unsigned char name[0];
8860 +struct au_vdir_dehstr {
8861 + struct hlist_node hash;
8862 + struct au_vdir_destr *str;
8863 +} ____cacheline_aligned_in_smp;
8865 +struct au_vdir_de {
8867 + unsigned char de_type;
8868 + /* caution: packed */
8869 + struct au_vdir_destr de_str;
8872 +struct au_vdir_wh {
8873 + struct hlist_node wh_hash;
8874 +#ifdef CONFIG_AUFS_SHWH
8876 + aufs_bindex_t wh_bindex;
8877 + unsigned char wh_type;
8879 + aufs_bindex_t wh_bindex;
8881 + /* caution: packed */
8882 + struct au_vdir_destr wh_str;
8885 +union au_vdir_deblk_p {
8886 + unsigned char *deblk;
8887 + struct au_vdir_de *de;
8891 + unsigned char **vd_deblk;
8892 + unsigned long vd_nblk;
8895 + union au_vdir_deblk_p p;
8898 + unsigned long vd_version;
8899 + unsigned int vd_deblk_sz;
8900 + unsigned long vd_jiffy;
8901 +} ____cacheline_aligned_in_smp;
8903 +/* ---------------------------------------------------------------------- */
8906 +extern const struct file_operations aufs_dir_fop;
8907 +void au_add_nlink(struct inode *dir, struct inode *h_dir);
8908 +void au_sub_nlink(struct inode *dir, struct inode *h_dir);
8909 +loff_t au_dir_size(struct file *file, struct dentry *dentry);
8910 +int au_test_empty_lower(struct dentry *dentry);
8911 +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
8914 +unsigned int au_rdhash_est(loff_t sz);
8915 +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
8916 +void au_nhash_wh_free(struct au_nhash *whlist);
8917 +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
8919 +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
8920 +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
8921 + unsigned int d_type, aufs_bindex_t bindex,
8922 + unsigned char shwh);
8923 +void au_vdir_free(struct au_vdir *vdir);
8924 +int au_vdir_init(struct file *file);
8925 +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir);
8928 +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
8930 +#ifdef CONFIG_AUFS_RDU
8932 +long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
8933 +#ifdef CONFIG_COMPAT
8934 +long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
8935 + unsigned long arg);
8938 +static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
8939 + unsigned long arg)
8943 +#ifdef CONFIG_COMPAT
8944 +static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
8945 + unsigned long arg)
8952 +#endif /* __KERNEL__ */
8953 +#endif /* __AUFS_DIR_H__ */
8954 diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
8955 --- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
8956 +++ linux/fs/aufs/dynop.c 2013-07-30 22:42:55.839613269 +0200
8959 + * Copyright (C) 2010-2013 Junjiro R. Okajima
8961 + * This program, aufs is free software; you can redistribute it and/or modify
8962 + * it under the terms of the GNU General Public License as published by
8963 + * the Free Software Foundation; either version 2 of the License, or
8964 + * (at your option) any later version.
8966 + * This program is distributed in the hope that it will be useful,
8967 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8968 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8969 + * GNU General Public License for more details.
8971 + * You should have received a copy of the GNU General Public License
8972 + * along with this program; if not, write to the Free Software
8973 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
8977 + * dynamically customizable operations for regular files
8982 +#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
8985 + * How large will these lists be?
8986 + * Usually just a few elements, 20-30 at most for each, I guess.
8988 +static struct au_splhead dynop[AuDyLast];
8990 +static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
8992 + struct au_dykey *key, *tmp;
8993 + struct list_head *head;
8996 + head = &spl->head;
8998 + list_for_each_entry_rcu(tmp, head, dk_list)
8999 + if (tmp->dk_op.dy_hop == h_op) {
9001 + kref_get(&key->dk_kref);
9004 + rcu_read_unlock();
9009 +static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
9011 + struct au_dykey **k, *found;
9012 + const void *h_op = key->dk_op.dy_hop;
9017 + for (i = 0; i < AuBrDynOp; i++)
9019 + if (k[i]->dk_op.dy_hop == h_op) {
9026 + spin_lock(&br->br_dykey_lock);
9027 + for (; i < AuBrDynOp; i++)
9029 + if (k[i]->dk_op.dy_hop == h_op) {
9037 + spin_unlock(&br->br_dykey_lock);
9038 + BUG_ON(i == AuBrDynOp); /* expand the array */
9044 +/* kref_get() if @key is already added */
9045 +static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
9047 + struct au_dykey *tmp, *found;
9048 + struct list_head *head;
9049 + const void *h_op = key->dk_op.dy_hop;
9052 + head = &spl->head;
9053 + spin_lock(&spl->spin);
9054 + list_for_each_entry(tmp, head, dk_list)
9055 + if (tmp->dk_op.dy_hop == h_op) {
9056 + kref_get(&tmp->dk_kref);
9061 + list_add_rcu(&key->dk_list, head);
9062 + spin_unlock(&spl->spin);
9069 +static void dy_free_rcu(struct rcu_head *rcu)
9071 + struct au_dykey *key;
9073 + key = container_of(rcu, struct au_dykey, dk_rcu);
9078 +static void dy_free(struct kref *kref)
9080 + struct au_dykey *key;
9081 + struct au_splhead *spl;
9083 + key = container_of(kref, struct au_dykey, dk_kref);
9084 + spl = dynop + key->dk_op.dy_type;
9085 + au_spl_del_rcu(&key->dk_list, spl);
9086 + call_rcu(&key->dk_rcu, dy_free_rcu);
9089 +void au_dy_put(struct au_dykey *key)
9091 + kref_put(&key->dk_kref, dy_free);
9094 +/* ---------------------------------------------------------------------- */
9096 +#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
9098 +#ifdef CONFIG_AUFS_DEBUG
9099 +#define DyDbgDeclare(cnt) unsigned int cnt = 0
9100 +#define DyDbgInc(cnt) do { cnt++; } while (0)
9102 +#define DyDbgDeclare(cnt) do {} while (0)
9103 +#define DyDbgInc(cnt) do {} while (0)
9106 +#define DySet(func, dst, src, h_op, h_sb) do { \
9108 + if (h_op->func) { \
9110 + dst.func = src.func; \
9112 + AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
9116 +#define DySetForce(func, dst, src) do { \
9117 + AuDebugOn(!src.func); \
9119 + dst.func = src.func; \
9122 +#define DySetAop(func) \
9123 + DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
9124 +#define DySetAopForce(func) \
9125 + DySetForce(func, dyaop->da_op, aufs_aop)
9127 +static void dy_aop(struct au_dykey *key, const void *h_op,
9128 + struct super_block *h_sb __maybe_unused)
9130 + struct au_dyaop *dyaop = (void *)key;
9131 + const struct address_space_operations *h_aop = h_op;
9132 + DyDbgDeclare(cnt);
9134 + AuDbg("%s\n", au_sbtype(h_sb));
9136 + DySetAop(writepage);
9137 + DySetAopForce(readpage); /* force */
9138 + DySetAop(writepages);
9139 + DySetAop(set_page_dirty);
9140 + DySetAop(readpages);
9141 + DySetAop(write_begin);
9142 + DySetAop(write_end);
9144 + DySetAop(invalidatepage);
9145 + DySetAop(releasepage);
9146 + DySetAop(freepage);
9147 + /* these two will be changed according to an aufs mount option */
9148 + DySetAop(direct_IO);
9149 + DySetAop(get_xip_mem);
9150 + DySetAop(migratepage);
9151 + DySetAop(launder_page);
9152 + DySetAop(is_partially_uptodate);
9153 + DySetAop(error_remove_page);
9154 + DySetAop(swap_activate);
9155 + DySetAop(swap_deactivate);
9157 + DyDbgSize(cnt, *h_aop);
9158 + dyaop->da_get_xip_mem = h_aop->get_xip_mem;
9161 +/* ---------------------------------------------------------------------- */
9163 +static void dy_bug(struct kref *kref)
9168 +static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
9170 + struct au_dykey *key, *old;
9171 + struct au_splhead *spl;
9174 + void (*set)(struct au_dykey *key, const void *h_op,
9175 + struct super_block *h_sb __maybe_unused);
9177 + static const struct op a[] = {
9179 + .sz = sizeof(struct au_dyaop),
9183 + const struct op *p;
9185 + spl = dynop + op->dy_type;
9186 + key = dy_gfind_get(spl, op->dy_hop);
9188 + goto out_add; /* success */
9190 + p = a + op->dy_type;
9191 + key = kzalloc(p->sz, GFP_NOFS);
9192 + if (unlikely(!key)) {
9193 + key = ERR_PTR(-ENOMEM);
9197 + key->dk_op.dy_hop = op->dy_hop;
9198 + kref_init(&key->dk_kref);
9199 + p->set(key, op->dy_hop, au_br_sb(br));
9200 + old = dy_gadd(spl, key);
9207 + old = dy_bradd(br, key);
9209 + /* its ref-count should never be zero here */
9210 + kref_put(&key->dk_kref, dy_bug);
9215 +/* ---------------------------------------------------------------------- */
9217 + * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
9218 + * This behaviour is neccessary to return an error from open(O_DIRECT) instead
9219 + * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
9220 + * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
9221 + * See the aufs manual in detail.
9223 + * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
9224 + * performance of fadvise() and madvise() may be affected.
9226 +static void dy_adx(struct au_dyaop *dyaop, int do_dx)
9229 + dyaop->da_op.direct_IO = NULL;
9230 + dyaop->da_op.get_xip_mem = NULL;
9232 + dyaop->da_op.direct_IO = aufs_aop.direct_IO;
9233 + dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
9234 + if (!dyaop->da_get_xip_mem)
9235 + dyaop->da_op.get_xip_mem = NULL;
9239 +static struct au_dyaop *dy_aget(struct au_branch *br,
9240 + const struct address_space_operations *h_aop,
9243 + struct au_dyaop *dyaop;
9244 + struct au_dynop op;
9246 + op.dy_type = AuDy_AOP;
9247 + op.dy_haop = h_aop;
9248 + dyaop = (void *)dy_get(&op, br);
9249 + if (IS_ERR(dyaop))
9251 + dy_adx(dyaop, do_dx);
9257 +int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9258 + struct inode *h_inode)
9261 + struct super_block *sb;
9262 + struct au_branch *br;
9263 + struct au_dyaop *dyaop;
9265 + AuDebugOn(!S_ISREG(h_inode->i_mode));
9266 + IiMustWriteLock(inode);
9269 + br = au_sbr(sb, bindex);
9270 + do_dx = !!au_opt_test(au_mntflags(sb), DIO);
9271 + dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
9272 + err = PTR_ERR(dyaop);
9273 + if (IS_ERR(dyaop))
9274 + /* unnecessary to call dy_fput() */
9278 + inode->i_mapping->a_ops = &dyaop->da_op;
9285 + * Is it safe to replace a_ops during the inode/file is in operation?
9288 +int au_dy_irefresh(struct inode *inode)
9291 + aufs_bindex_t bstart;
9292 + struct inode *h_inode;
9295 + if (S_ISREG(inode->i_mode)) {
9296 + bstart = au_ibstart(inode);
9297 + h_inode = au_h_iptr(inode, bstart);
9298 + err = au_dy_iaop(inode, bstart, h_inode);
9303 +void au_dy_arefresh(int do_dx)
9305 + struct au_splhead *spl;
9306 + struct list_head *head;
9307 + struct au_dykey *key;
9309 + spl = dynop + AuDy_AOP;
9310 + head = &spl->head;
9311 + spin_lock(&spl->spin);
9312 + list_for_each_entry(key, head, dk_list)
9313 + dy_adx((void *)key, do_dx);
9314 + spin_unlock(&spl->spin);
9317 +/* ---------------------------------------------------------------------- */
9319 +void __init au_dy_init(void)
9323 + /* make sure that 'struct au_dykey *' can be any type */
9324 + BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
9326 + for (i = 0; i < AuDyLast; i++)
9327 + au_spl_init(dynop + i);
9330 +void au_dy_fin(void)
9334 + for (i = 0; i < AuDyLast; i++)
9335 + WARN_ON(!list_empty(&dynop[i].head));
9337 diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
9338 --- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
9339 +++ linux/fs/aufs/dynop.h 2013-07-06 13:20:47.740198107 +0200
9342 + * Copyright (C) 2010-2013 Junjiro R. Okajima
9344 + * This program, aufs is free software; you can redistribute it and/or modify
9345 + * it under the terms of the GNU General Public License as published by
9346 + * the Free Software Foundation; either version 2 of the License, or
9347 + * (at your option) any later version.
9349 + * This program is distributed in the hope that it will be useful,
9350 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9351 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9352 + * GNU General Public License for more details.
9354 + * You should have received a copy of the GNU General Public License
9355 + * along with this program; if not, write to the Free Software
9356 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9360 + * dynamically customizable operations (for regular files only)
9363 +#ifndef __AUFS_DYNOP_H__
9364 +#define __AUFS_DYNOP_H__
9370 +enum {AuDy_AOP, AuDyLast};
9375 + const void *dy_hop;
9376 + const struct address_space_operations *dy_haop;
9382 + struct list_head dk_list;
9383 + struct rcu_head dk_rcu;
9385 + struct au_dynop dk_op;
9388 + * during I am in the branch local array, kref is gotten. when the
9389 + * branch is removed, kref is put.
9391 + struct kref dk_kref;
9394 +/* stop unioning since their sizes are very different from each other */
9396 + struct au_dykey da_key;
9397 + struct address_space_operations da_op; /* not const */
9398 + int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
9399 + void **, unsigned long *);
9402 +/* ---------------------------------------------------------------------- */
9406 +void au_dy_put(struct au_dykey *key);
9407 +int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9408 + struct inode *h_inode);
9409 +int au_dy_irefresh(struct inode *inode);
9410 +void au_dy_arefresh(int do_dio);
9412 +void __init au_dy_init(void);
9413 +void au_dy_fin(void);
9415 +#endif /* __KERNEL__ */
9416 +#endif /* __AUFS_DYNOP_H__ */
9417 diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
9418 --- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
9419 +++ linux/fs/aufs/export.c 2013-07-30 22:42:55.839613269 +0200
9422 + * Copyright (C) 2005-2013 Junjiro R. Okajima
9424 + * This program, aufs is free software; you can redistribute it and/or modify
9425 + * it under the terms of the GNU General Public License as published by
9426 + * the Free Software Foundation; either version 2 of the License, or
9427 + * (at your option) any later version.
9429 + * This program is distributed in the hope that it will be useful,
9430 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9431 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9432 + * GNU General Public License for more details.
9434 + * You should have received a copy of the GNU General Public License
9435 + * along with this program; if not, write to the Free Software
9436 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9443 +#include <linux/exportfs.h>
9444 +#include <linux/fs_struct.h>
9445 +#include <linux/namei.h>
9446 +#include <linux/nsproxy.h>
9447 +#include <linux/random.h>
9448 +#include <linux/writeback.h>
9449 +#include "../fs/mount.h"
9453 +#ifdef CONFIG_AUFS_INO_T_64
9461 +static ino_t decode_ino(__u32 *a)
9465 + BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
9467 +#ifdef CONFIG_AUFS_INO_T_64
9473 +static void encode_ino(__u32 *a, ino_t ino)
9479 +#ifdef CONFIG_AUFS_INO_T_64
9484 +/* NFS file handle */
9488 +#ifdef CONFIG_AUFS_INO_T_64
9489 + /* support 64bit inode number */
9503 + Fh_dir_ino = Fh_dir_ino1
9506 +static int au_test_anon(struct dentry *dentry)
9508 + /* note: read d_flags without d_lock */
9509 + return !!(dentry->d_flags & DCACHE_DISCONNECTED);
9512 +int au_test_nfsd(void)
9515 + struct task_struct *tsk = current;
9516 + char comm[sizeof(tsk->comm)];
9519 + if (tsk->flags & PF_KTHREAD) {
9520 + get_task_comm(comm, tsk);
9521 + ret = !strcmp(comm, "nfsd");
9527 +/* ---------------------------------------------------------------------- */
9528 +/* inode generation external table */
9530 +void au_xigen_inc(struct inode *inode)
9535 + struct super_block *sb;
9536 + struct au_sbinfo *sbinfo;
9539 + AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
9541 + sbinfo = au_sbi(sb);
9542 + pos = inode->i_ino;
9543 + pos *= sizeof(igen);
9544 + igen = inode->i_generation + 1;
9545 + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
9546 + sizeof(igen), &pos);
9547 + if (sz == sizeof(igen))
9548 + return; /* success */
9550 + if (unlikely(sz >= 0))
9551 + AuIOErr("xigen error (%zd)\n", sz);
9554 +int au_xigen_new(struct inode *inode)
9559 + struct super_block *sb;
9560 + struct au_sbinfo *sbinfo;
9561 + struct file *file;
9564 + /* todo: dirty, at mount time */
9565 + if (inode->i_ino == AUFS_ROOT_INO)
9568 + SiMustAnyLock(sb);
9569 + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
9573 + pos = inode->i_ino;
9574 + if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
9575 + AuIOErr1("too large i%lld\n", pos);
9578 + pos *= sizeof(inode->i_generation);
9581 + sbinfo = au_sbi(sb);
9582 + file = sbinfo->si_xigen;
9585 + if (vfsub_f_size_read(file)
9586 + < pos + sizeof(inode->i_generation)) {
9587 + inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
9588 + sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
9589 + sizeof(inode->i_generation), &pos);
9591 + sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
9592 + sizeof(inode->i_generation), &pos);
9593 + if (sz == sizeof(inode->i_generation))
9594 + goto out; /* success */
9597 + if (unlikely(sz >= 0)) {
9599 + AuIOErr("xigen error (%zd)\n", sz);
9606 +int au_xigen_set(struct super_block *sb, struct file *base)
9609 + struct au_sbinfo *sbinfo;
9610 + struct file *file;
9612 + SiMustWriteLock(sb);
9614 + sbinfo = au_sbi(sb);
9615 + file = au_xino_create2(base, sbinfo->si_xigen);
9616 + err = PTR_ERR(file);
9620 + if (sbinfo->si_xigen)
9621 + fput(sbinfo->si_xigen);
9622 + sbinfo->si_xigen = file;
9628 +void au_xigen_clr(struct super_block *sb)
9630 + struct au_sbinfo *sbinfo;
9632 + SiMustWriteLock(sb);
9634 + sbinfo = au_sbi(sb);
9635 + if (sbinfo->si_xigen) {
9636 + fput(sbinfo->si_xigen);
9637 + sbinfo->si_xigen = NULL;
9641 +/* ---------------------------------------------------------------------- */
9643 +static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
9646 + struct dentry *dentry, *d;
9647 + struct inode *inode;
9648 + unsigned int sigen;
9651 + inode = ilookup(sb, ino);
9655 + dentry = ERR_PTR(-ESTALE);
9656 + sigen = au_sigen(sb);
9657 + if (unlikely(is_bad_inode(inode)
9658 + || IS_DEADDIR(inode)
9659 + || sigen != au_iigen(inode, NULL)))
9663 + if (!dir_ino || S_ISDIR(inode->i_mode))
9664 + dentry = d_find_alias(inode);
9666 + spin_lock(&inode->i_lock);
9667 + hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
9668 + spin_lock(&d->d_lock);
9669 + if (!au_test_anon(d)
9670 + && d->d_parent->d_inode->i_ino == dir_ino) {
9671 + dentry = dget_dlock(d);
9672 + spin_unlock(&d->d_lock);
9675 + spin_unlock(&d->d_lock);
9677 + spin_unlock(&inode->i_lock);
9679 + if (unlikely(dentry && au_digen_test(dentry, sigen))) {
9680 + /* need to refresh */
9688 + AuTraceErrPtr(dentry);
9692 +/* ---------------------------------------------------------------------- */
9695 +/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
9697 +struct au_compare_mnt_args {
9699 + struct super_block *sb;
9702 + struct vfsmount *mnt;
9705 +static int au_compare_mnt(struct vfsmount *mnt, void *arg)
9707 + struct au_compare_mnt_args *a = arg;
9709 + if (mnt->mnt_sb != a->sb)
9711 + a->mnt = mntget(mnt);
9715 +static struct vfsmount *au_mnt_get(struct super_block *sb)
9719 + struct au_compare_mnt_args args = {
9723 + get_fs_root(current->fs, &root);
9724 + br_read_lock(&vfsmount_lock);
9725 + err = iterate_mounts(au_compare_mnt, &args, root.mnt);
9726 + br_read_unlock(&vfsmount_lock);
9729 + AuDebugOn(!args.mnt);
9733 +struct au_nfsd_si_lock {
9734 + unsigned int sigen;
9735 + aufs_bindex_t bindex, br_id;
9736 + unsigned char force_lock;
9739 +static int si_nfsd_read_lock(struct super_block *sb,
9740 + struct au_nfsd_si_lock *nsi_lock)
9743 + aufs_bindex_t bindex;
9745 + si_read_lock(sb, AuLock_FLUSH);
9747 + /* branch id may be wrapped around */
9749 + bindex = au_br_index(sb, nsi_lock->br_id);
9750 + if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
9751 + goto out; /* success */
9755 + if (!nsi_lock->force_lock)
9756 + si_read_unlock(sb);
9759 + nsi_lock->bindex = bindex;
9763 +struct find_name_by_ino {
9764 + int called, found;
9771 +find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
9772 + u64 ino, unsigned int d_type)
9774 + struct find_name_by_ino *a = arg;
9777 + if (a->ino != ino)
9780 + memcpy(a->name, name, namelen);
9781 + a->namelen = namelen;
9786 +static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
9787 + struct au_nfsd_si_lock *nsi_lock)
9789 + struct dentry *dentry, *parent;
9790 + struct file *file;
9791 + struct inode *dir;
9792 + struct find_name_by_ino arg;
9795 + parent = path->dentry;
9797 + si_read_unlock(parent->d_sb);
9798 + file = vfsub_dentry_open(path, au_dir_roflags);
9799 + dentry = (void *)file;
9803 + dentry = ERR_PTR(-ENOMEM);
9804 + arg.name = (void *)__get_free_page(GFP_NOFS);
9805 + if (unlikely(!arg.name))
9812 + err = vfsub_readdir(file, find_name_by_ino, &arg);
9813 + } while (!err && !arg.found && arg.called);
9814 + dentry = ERR_PTR(err);
9815 + if (unlikely(err))
9817 + /* instead of ENOENT */
9818 + dentry = ERR_PTR(-ESTALE);
9822 + /* do not call vfsub_lkup_one() */
9823 + dir = parent->d_inode;
9824 + mutex_lock(&dir->i_mutex);
9825 + dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
9826 + mutex_unlock(&dir->i_mutex);
9827 + AuTraceErrPtr(dentry);
9828 + if (IS_ERR(dentry))
9830 + AuDebugOn(au_test_anon(dentry));
9831 + if (unlikely(!dentry->d_inode)) {
9833 + dentry = ERR_PTR(-ENOENT);
9837 + free_page((unsigned long)arg.name);
9841 + if (unlikely(nsi_lock
9842 + && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
9843 + if (!IS_ERR(dentry)) {
9845 + dentry = ERR_PTR(-ESTALE);
9847 + AuTraceErrPtr(dentry);
9851 +static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
9853 + struct au_nfsd_si_lock *nsi_lock)
9855 + struct dentry *dentry;
9858 + if (dir_ino != AUFS_ROOT_INO) {
9859 + path.dentry = decode_by_ino(sb, dir_ino, 0);
9860 + dentry = path.dentry;
9861 + if (!path.dentry || IS_ERR(path.dentry))
9863 + AuDebugOn(au_test_anon(path.dentry));
9865 + path.dentry = dget(sb->s_root);
9867 + path.mnt = au_mnt_get(sb);
9868 + dentry = au_lkup_by_ino(&path, ino, nsi_lock);
9872 + AuTraceErrPtr(dentry);
9876 +/* ---------------------------------------------------------------------- */
9878 +static int h_acceptable(void *expv, struct dentry *dentry)
9883 +static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
9884 + char *buf, int len, struct super_block *sb)
9890 + p = d_path(h_rootpath, buf, len);
9895 + path.mnt = h_rootpath->mnt;
9896 + path.dentry = h_parent;
9897 + p = d_path(&path, buf, len);
9903 + path.mnt = au_mnt_get(sb);
9904 + path.dentry = sb->s_root;
9905 + p = d_path(&path, buf, len - strlen(p));
9910 + p[strlen(p)] = '/';
9918 +struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
9919 + int fh_len, struct au_nfsd_si_lock *nsi_lock)
9921 + struct dentry *dentry, *h_parent, *root;
9922 + struct super_block *h_sb;
9923 + char *pathname, *p;
9924 + struct vfsmount *h_mnt;
9925 + struct au_branch *br;
9929 + br = au_sbr(sb, nsi_lock->bindex);
9930 + h_mnt = au_br_mnt(br);
9931 + h_sb = h_mnt->mnt_sb;
9932 + /* todo: call lower fh_to_dentry()? fh_to_parent()? */
9933 + h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
9934 + fh_len - Fh_tail, fh[Fh_h_type],
9935 + h_acceptable, /*context*/NULL);
9936 + dentry = h_parent;
9937 + if (unlikely(!h_parent || IS_ERR(h_parent))) {
9938 + AuWarn1("%s decode_fh failed, %ld\n",
9939 + au_sbtype(h_sb), PTR_ERR(h_parent));
9943 + if (unlikely(au_test_anon(h_parent))) {
9944 + AuWarn1("%s decode_fh returned a disconnected dentry\n",
9946 + goto out_h_parent;
9949 + dentry = ERR_PTR(-ENOMEM);
9950 + pathname = (void *)__get_free_page(GFP_NOFS);
9951 + if (unlikely(!pathname))
9952 + goto out_h_parent;
9954 + root = sb->s_root;
9956 + di_read_lock_parent(root, !AuLock_IR);
9957 + path.dentry = au_h_dptr(root, nsi_lock->bindex);
9958 + di_read_unlock(root, !AuLock_IR);
9959 + p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
9960 + dentry = (void *)p;
9962 + goto out_pathname;
9964 + si_read_unlock(sb);
9965 + err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
9966 + dentry = ERR_PTR(err);
9967 + if (unlikely(err))
9970 + dentry = ERR_PTR(-ENOENT);
9971 + AuDebugOn(au_test_anon(path.dentry));
9972 + if (unlikely(!path.dentry->d_inode))
9975 + if (ino != path.dentry->d_inode->i_ino)
9976 + dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
9978 + dentry = dget(path.dentry);
9983 + if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
9984 + if (!IS_ERR(dentry)) {
9986 + dentry = ERR_PTR(-ESTALE);
9989 + free_page((unsigned long)pathname);
9993 + AuTraceErrPtr(dentry);
9997 +/* ---------------------------------------------------------------------- */
9999 +static struct dentry *
10000 +aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
10003 + struct dentry *dentry;
10004 + __u32 *fh = fid->raw;
10005 + struct au_branch *br;
10006 + ino_t ino, dir_ino;
10007 + struct au_nfsd_si_lock nsi_lock = {
10011 + dentry = ERR_PTR(-ESTALE);
10012 + /* it should never happen, but the file handle is unreliable */
10013 + if (unlikely(fh_len < Fh_tail))
10015 + nsi_lock.sigen = fh[Fh_sigen];
10016 + nsi_lock.br_id = fh[Fh_br_id];
10018 + /* branch id may be wrapped around */
10020 + if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
10022 + nsi_lock.force_lock = 1;
10024 + /* is this inode still cached? */
10025 + ino = decode_ino(fh + Fh_ino);
10026 + /* it should never happen */
10027 + if (unlikely(ino == AUFS_ROOT_INO))
10030 + dir_ino = decode_ino(fh + Fh_dir_ino);
10031 + dentry = decode_by_ino(sb, ino, dir_ino);
10032 + if (IS_ERR(dentry))
10037 + /* is the parent dir cached? */
10038 + br = au_sbr(sb, nsi_lock.bindex);
10039 + atomic_inc(&br->br_count);
10040 + dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
10041 + if (IS_ERR(dentry))
10046 + /* lookup path */
10047 + dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
10048 + if (IS_ERR(dentry))
10050 + if (unlikely(!dentry))
10051 + /* todo?: make it ESTALE */
10055 + if (!au_digen_test(dentry, au_sigen(sb))
10056 + && dentry->d_inode->i_generation == fh[Fh_igen])
10057 + goto out_unlock; /* success */
10060 + dentry = ERR_PTR(-ESTALE);
10063 + atomic_dec(&br->br_count);
10064 + si_read_unlock(sb);
10066 + AuTraceErrPtr(dentry);
10070 +#if 0 /* reserved for future use */
10071 +/* support subtreecheck option */
10072 +static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
10073 + int fh_len, int fh_type)
10075 + struct dentry *parent;
10076 + __u32 *fh = fid->raw;
10079 + dir_ino = decode_ino(fh + Fh_dir_ino);
10080 + parent = decode_by_ino(sb, dir_ino, 0);
10081 + if (IS_ERR(parent))
10084 + parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
10085 + dir_ino, fh, fh_len);
10088 + AuTraceErrPtr(parent);
10093 +/* ---------------------------------------------------------------------- */
10095 +static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
10096 + struct inode *dir)
10099 + aufs_bindex_t bindex;
10100 + struct super_block *sb, *h_sb;
10101 + struct dentry *dentry, *parent, *h_parent;
10102 + struct inode *h_dir;
10103 + struct au_branch *br;
10106 + if (unlikely(*max_len <= Fh_tail)) {
10107 + AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
10111 + err = FILEID_ROOT;
10112 + if (inode->i_ino == AUFS_ROOT_INO) {
10113 + AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
10118 + sb = inode->i_sb;
10119 + err = si_read_lock(sb, AuLock_FLUSH);
10120 + if (unlikely(err))
10123 +#ifdef CONFIG_AUFS_DEBUG
10124 + if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10125 + AuWarn1("NFS-exporting requires xino\n");
10129 + ii_read_lock_child(inode);
10130 + bindex = au_ibstart(inode);
10132 + dentry = d_find_alias(inode);
10133 + if (unlikely(!dentry))
10135 + AuDebugOn(au_test_anon(dentry));
10136 + parent = dget_parent(dentry);
10138 + if (unlikely(!parent))
10140 + dir = parent->d_inode;
10143 + ii_read_lock_parent(dir);
10144 + h_dir = au_h_iptr(dir, bindex);
10145 + ii_read_unlock(dir);
10146 + if (unlikely(!h_dir))
10148 + h_parent = d_find_alias(h_dir);
10149 + if (unlikely(!h_parent))
10150 + goto out_hparent;
10153 + br = au_sbr(sb, bindex);
10154 + h_sb = au_br_sb(br);
10155 + if (unlikely(!h_sb->s_export_op)) {
10156 + AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
10157 + goto out_hparent;
10160 + fh[Fh_br_id] = br->br_id;
10161 + fh[Fh_sigen] = au_sigen(sb);
10162 + encode_ino(fh + Fh_ino, inode->i_ino);
10163 + encode_ino(fh + Fh_dir_ino, dir->i_ino);
10164 + fh[Fh_igen] = inode->i_generation;
10166 + *max_len -= Fh_tail;
10167 + fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
10169 + /*connectable or subtreecheck*/0);
10170 + err = fh[Fh_h_type];
10171 + *max_len += Fh_tail;
10172 + /* todo: macros? */
10173 + if (err != FILEID_INVALID)
10176 + AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
10183 + ii_read_unlock(inode);
10184 + si_read_unlock(sb);
10186 + if (unlikely(err < 0))
10187 + err = FILEID_INVALID;
10191 +/* ---------------------------------------------------------------------- */
10193 +static int aufs_commit_metadata(struct inode *inode)
10196 + aufs_bindex_t bindex;
10197 + struct super_block *sb;
10198 + struct inode *h_inode;
10199 + int (*f)(struct inode *inode);
10201 + sb = inode->i_sb;
10202 + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
10203 + ii_write_lock_child(inode);
10204 + bindex = au_ibstart(inode);
10205 + AuDebugOn(bindex < 0);
10206 + h_inode = au_h_iptr(inode, bindex);
10208 + f = h_inode->i_sb->s_export_op->commit_metadata;
10210 + err = f(h_inode);
10212 + struct writeback_control wbc = {
10213 + .sync_mode = WB_SYNC_ALL,
10214 + .nr_to_write = 0 /* metadata only */
10217 + err = sync_inode(h_inode, &wbc);
10220 + au_cpup_attr_timesizes(inode);
10221 + ii_write_unlock(inode);
10222 + si_read_unlock(sb);
10226 +/* ---------------------------------------------------------------------- */
10228 +static struct export_operations aufs_export_op = {
10229 + .fh_to_dentry = aufs_fh_to_dentry,
10230 + /* .fh_to_parent = aufs_fh_to_parent, */
10231 + .encode_fh = aufs_encode_fh,
10232 + .commit_metadata = aufs_commit_metadata
10235 +void au_export_init(struct super_block *sb)
10237 + struct au_sbinfo *sbinfo;
10240 + sb->s_export_op = &aufs_export_op;
10241 + sbinfo = au_sbi(sb);
10242 + sbinfo->si_xigen = NULL;
10243 + get_random_bytes(&u, sizeof(u));
10244 + BUILD_BUG_ON(sizeof(u) != sizeof(int));
10245 + atomic_set(&sbinfo->si_xigen_next, u);
10247 diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
10248 --- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
10249 +++ linux/fs/aufs/file.c 2013-07-30 22:42:55.842946719 +0200
10252 + * Copyright (C) 2005-2013 Junjiro R. Okajima
10254 + * This program, aufs is free software; you can redistribute it and/or modify
10255 + * it under the terms of the GNU General Public License as published by
10256 + * the Free Software Foundation; either version 2 of the License, or
10257 + * (at your option) any later version.
10259 + * This program is distributed in the hope that it will be useful,
10260 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10261 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10262 + * GNU General Public License for more details.
10264 + * You should have received a copy of the GNU General Public License
10265 + * along with this program; if not, write to the Free Software
10266 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10270 + * handling file/dir, and address_space operation
10273 +#ifdef CONFIG_AUFS_DEBUG
10274 +#include <linux/migrate.h>
10276 +#include <linux/pagemap.h>
10279 +/* drop flags for writing */
10280 +unsigned int au_file_roflags(unsigned int flags)
10282 + flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
10283 + flags |= O_RDONLY | O_NOATIME;
10287 +/* common functions to regular file and dir */
10288 +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
10289 + struct file *file)
10291 + struct file *h_file;
10292 + struct dentry *h_dentry;
10293 + struct inode *h_inode;
10294 + struct super_block *sb;
10295 + struct au_branch *br;
10296 + struct path h_path;
10297 + int err, exec_flag;
10299 + /* a race condition can happen between open and unlink/rmdir */
10300 + h_file = ERR_PTR(-ENOENT);
10301 + h_dentry = au_h_dptr(dentry, bindex);
10302 + if (au_test_nfsd() && !h_dentry)
10304 + h_inode = h_dentry->d_inode;
10305 + if (au_test_nfsd() && !h_inode)
10307 + spin_lock(&h_dentry->d_lock);
10308 + err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
10310 + /* || !dentry->d_inode->i_nlink */
10312 + spin_unlock(&h_dentry->d_lock);
10313 + if (unlikely(err))
10316 + sb = dentry->d_sb;
10317 + br = au_sbr(sb, bindex);
10318 + h_file = ERR_PTR(-EACCES);
10319 + exec_flag = flags & __FMODE_EXEC;
10320 + if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
10323 + /* drop flags for writing */
10324 + if (au_test_ro(sb, bindex, dentry->d_inode))
10325 + flags = au_file_roflags(flags);
10326 + flags &= ~O_CREAT;
10327 + atomic_inc(&br->br_count);
10328 + h_path.dentry = h_dentry;
10329 + h_path.mnt = au_br_mnt(br);
10330 + if (!au_special_file(h_inode->i_mode))
10331 + h_file = vfsub_dentry_open(&h_path, flags);
10333 + /* this block depends upon the configuration */
10334 + di_read_unlock(dentry, AuLock_IR);
10335 + fi_write_unlock(file);
10336 + si_read_unlock(sb);
10337 + h_file = vfsub_dentry_open(&h_path, flags);
10338 + si_noflush_read_lock(sb);
10339 + fi_write_lock(file);
10340 + di_read_lock_child(dentry, AuLock_IR);
10342 + if (IS_ERR(h_file))
10346 + err = deny_write_access(h_file);
10347 + if (unlikely(err)) {
10349 + h_file = ERR_PTR(err);
10353 + fsnotify_open(h_file);
10354 + goto out; /* success */
10357 + atomic_dec(&br->br_count);
10362 +int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
10363 + struct au_fidir *fidir)
10366 + struct dentry *dentry;
10368 + err = au_finfo_init(file, fidir);
10369 + if (unlikely(err))
10372 + dentry = file->f_dentry;
10373 + di_read_lock_child(dentry, AuLock_IR);
10374 + err = open(file, vfsub_file_flags(file));
10375 + di_read_unlock(dentry, AuLock_IR);
10377 + fi_write_unlock(file);
10378 + if (unlikely(err)) {
10379 + au_fi(file)->fi_hdir = NULL;
10380 + au_finfo_fin(file);
10387 +int au_reopen_nondir(struct file *file)
10390 + aufs_bindex_t bstart;
10391 + struct dentry *dentry;
10392 + struct file *h_file, *h_file_tmp;
10394 + dentry = file->f_dentry;
10395 + AuDebugOn(au_special_file(dentry->d_inode->i_mode));
10396 + bstart = au_dbstart(dentry);
10397 + h_file_tmp = NULL;
10398 + if (au_fbstart(file) == bstart) {
10399 + h_file = au_hf_top(file);
10400 + if (file->f_mode == h_file->f_mode)
10401 + return 0; /* success */
10402 + h_file_tmp = h_file;
10403 + get_file(h_file_tmp);
10404 + au_set_h_fptr(file, bstart, NULL);
10406 + AuDebugOn(au_fi(file)->fi_hdir);
10409 + * file exists on both of rw and ro
10410 + * open --> dbstart and fbstart are both 0
10411 + * prepend a branch as rw, "rw" become ro
10413 + * delete the top branch, "rw" becomes rw again
10414 + * --> dbstart is 1, fbstart is still 0
10415 + * write --> fbstart is 0 but dbstart is 1
10417 + /* AuDebugOn(au_fbstart(file) < bstart); */
10419 + h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
10421 + err = PTR_ERR(h_file);
10422 + if (IS_ERR(h_file)) {
10423 + if (h_file_tmp) {
10424 + atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
10425 + au_set_h_fptr(file, bstart, h_file_tmp);
10426 + h_file_tmp = NULL;
10428 + goto out; /* todo: close all? */
10432 + au_set_fbstart(file, bstart);
10433 + au_set_h_fptr(file, bstart, h_file);
10434 + au_update_figen(file);
10435 + /* todo: necessary? */
10436 + /* file->f_ra = h_file->f_ra; */
10440 + fput(h_file_tmp);
10444 +/* ---------------------------------------------------------------------- */
10446 +static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
10447 + struct dentry *hi_wh)
10450 + aufs_bindex_t bstart;
10451 + struct au_dinfo *dinfo;
10452 + struct dentry *h_dentry;
10453 + struct au_hdentry *hdp;
10455 + dinfo = au_di(file->f_dentry);
10456 + AuRwMustWriteLock(&dinfo->di_rwsem);
10458 + bstart = dinfo->di_bstart;
10459 + dinfo->di_bstart = btgt;
10460 + hdp = dinfo->di_hdentry;
10461 + h_dentry = hdp[0 + btgt].hd_dentry;
10462 + hdp[0 + btgt].hd_dentry = hi_wh;
10463 + err = au_reopen_nondir(file);
10464 + hdp[0 + btgt].hd_dentry = h_dentry;
10465 + dinfo->di_bstart = bstart;
10470 +static int au_ready_to_write_wh(struct file *file, loff_t len,
10471 + aufs_bindex_t bcpup, struct au_pin *pin)
10474 + struct inode *inode, *h_inode;
10475 + struct dentry *dentry, *h_dentry, *hi_wh;
10477 + dentry = file->f_dentry;
10478 + au_update_dbstart(dentry);
10479 + inode = dentry->d_inode;
10481 + if (au_dbstart(dentry) <= bcpup && au_dbend(dentry) >= bcpup) {
10482 + h_dentry = au_h_dptr(dentry, bcpup);
10484 + h_inode = h_dentry->d_inode;
10486 + hi_wh = au_hi_wh(inode, bcpup);
10487 + if (!hi_wh && !h_inode)
10488 + err = au_sio_cpup_wh(dentry, bcpup, len, file, pin);
10490 + /* already copied-up after unlink */
10491 + err = au_reopen_wh(file, bcpup, hi_wh);
10494 + && inode->i_nlink > 1
10495 + && au_opt_test(au_mntflags(dentry->d_sb), PLINK))
10496 + au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup));
10502 + * prepare the @file for writing.
10504 +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
10507 + aufs_bindex_t bstart, bcpup, dbstart;
10508 + struct dentry *dentry, *parent, *h_dentry;
10509 + struct inode *inode;
10510 + struct super_block *sb;
10511 + struct file *h_file;
10513 + dentry = file->f_dentry;
10514 + sb = dentry->d_sb;
10515 + inode = dentry->d_inode;
10516 + AuDebugOn(au_special_file(inode->i_mode));
10517 + bstart = au_fbstart(file);
10518 + err = au_test_ro(sb, bstart, inode);
10519 + if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
10520 + err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0);
10524 + /* need to cpup or reopen */
10525 + parent = dget_parent(dentry);
10526 + di_write_lock_parent(parent);
10527 + err = AuWbrCopyup(au_sbi(sb), dentry);
10529 + if (unlikely(err < 0))
10533 + if (!d_unhashed(dentry) && !au_h_dptr(parent, bcpup)) {
10534 + err = au_cpup_dirs(dentry, bcpup);
10535 + if (unlikely(err))
10539 + err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE,
10540 + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10541 + if (unlikely(err))
10544 + h_dentry = au_hf_top(file)->f_dentry;
10545 + dbstart = au_dbstart(dentry);
10546 + if (dbstart <= bcpup) {
10547 + h_dentry = au_h_dptr(dentry, bcpup);
10548 + AuDebugOn(!h_dentry);
10552 + if (dbstart <= bcpup /* just reopen */
10553 + || !d_unhashed(dentry) /* copyup and reopen */
10555 + h_file = au_h_open_pre(dentry, bstart);
10556 + if (IS_ERR(h_file))
10557 + err = PTR_ERR(h_file);
10559 + di_downgrade_lock(parent, AuLock_IR);
10560 + if (dbstart > bcpup)
10561 + err = au_sio_cpup_simple(dentry, bcpup, len,
10562 + AuCpup_DTIME, pin);
10564 + err = au_reopen_nondir(file);
10565 + au_h_open_post(dentry, bstart, h_file);
10567 + } else { /* copyup as wh and reopen */
10569 + * since writable hfsplus branch is not supported,
10570 + * h_open_pre/post() are unnecessary.
10572 + err = au_ready_to_write_wh(file, len, bcpup, pin);
10573 + di_downgrade_lock(parent, AuLock_IR);
10577 + au_pin_set_parent_lflag(pin, /*lflag*/0);
10578 + goto out_dput; /* success */
10584 + di_downgrade_lock(parent, AuLock_IR);
10586 + di_read_unlock(parent, AuLock_IR);
10593 +/* ---------------------------------------------------------------------- */
10595 +int au_do_flush(struct file *file, fl_owner_t id,
10596 + int (*flush)(struct file *file, fl_owner_t id))
10599 + struct super_block *sb;
10600 + struct inode *inode;
10602 + inode = file_inode(file);
10603 + sb = inode->i_sb;
10604 + si_noflush_read_lock(sb);
10605 + fi_read_lock(file);
10606 + ii_read_lock_child(inode);
10608 + err = flush(file, id);
10609 + au_cpup_attr_timesizes(inode);
10611 + ii_read_unlock(inode);
10612 + fi_read_unlock(file);
10613 + si_read_unlock(sb);
10617 +/* ---------------------------------------------------------------------- */
10619 +static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
10622 + aufs_bindex_t bstart;
10623 + struct au_pin pin;
10624 + struct au_finfo *finfo;
10625 + struct dentry *dentry, *parent, *hi_wh;
10626 + struct inode *inode;
10627 + struct super_block *sb;
10629 + FiMustWriteLock(file);
10632 + finfo = au_fi(file);
10633 + dentry = file->f_dentry;
10634 + sb = dentry->d_sb;
10635 + inode = dentry->d_inode;
10636 + bstart = au_ibstart(inode);
10637 + if (bstart == finfo->fi_btop || IS_ROOT(dentry))
10640 + parent = dget_parent(dentry);
10641 + if (au_test_ro(sb, bstart, inode)) {
10642 + di_read_lock_parent(parent, !AuLock_IR);
10643 + err = AuWbrCopyup(au_sbi(sb), dentry);
10645 + di_read_unlock(parent, !AuLock_IR);
10646 + if (unlikely(err < 0))
10651 + di_read_lock_parent(parent, AuLock_IR);
10652 + hi_wh = au_hi_wh(inode, bstart);
10653 + if (!S_ISDIR(inode->i_mode)
10654 + && au_opt_test(au_mntflags(sb), PLINK)
10655 + && au_plink_test(inode)
10656 + && !d_unhashed(dentry)
10657 + && bstart < au_dbstart(dentry)) {
10658 + err = au_test_and_cpup_dirs(dentry, bstart);
10659 + if (unlikely(err))
10662 + /* always superio. */
10663 + err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE,
10664 + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10666 + err = au_sio_cpup_simple(dentry, bstart, -1,
10667 + AuCpup_DTIME, &pin);
10670 + } else if (hi_wh) {
10671 + /* already copied-up after unlink */
10672 + err = au_reopen_wh(file, bstart, hi_wh);
10673 + *need_reopen = 0;
10677 + di_read_unlock(parent, AuLock_IR);
10684 +static void au_do_refresh_dir(struct file *file)
10686 + aufs_bindex_t bindex, bend, new_bindex, brid;
10687 + struct au_hfile *p, tmp, *q;
10688 + struct au_finfo *finfo;
10689 + struct super_block *sb;
10690 + struct au_fidir *fidir;
10692 + FiMustWriteLock(file);
10694 + sb = file->f_dentry->d_sb;
10695 + finfo = au_fi(file);
10696 + fidir = finfo->fi_hdir;
10697 + AuDebugOn(!fidir);
10698 + p = fidir->fd_hfile + finfo->fi_btop;
10699 + brid = p->hf_br->br_id;
10700 + bend = fidir->fd_bbot;
10701 + for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
10705 + new_bindex = au_br_index(sb, p->hf_br->br_id);
10706 + if (new_bindex == bindex)
10708 + if (new_bindex < 0) {
10709 + au_set_h_fptr(file, bindex, NULL);
10713 + /* swap two lower inode, and loop again */
10714 + q = fidir->fd_hfile + new_bindex;
10718 + if (tmp.hf_file) {
10724 + p = fidir->fd_hfile;
10725 + if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
10726 + bend = au_sbend(sb);
10727 + for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
10728 + finfo->fi_btop++, p++)
10729 + if (p->hf_file) {
10730 + if (file_inode(p->hf_file))
10733 + au_hfput(p, file);
10736 + bend = au_br_index(sb, brid);
10737 + for (finfo->fi_btop = 0; finfo->fi_btop < bend;
10738 + finfo->fi_btop++, p++)
10740 + au_hfput(p, file);
10741 + bend = au_sbend(sb);
10744 + p = fidir->fd_hfile + bend;
10745 + for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
10746 + fidir->fd_bbot--, p--)
10747 + if (p->hf_file) {
10748 + if (file_inode(p->hf_file))
10751 + au_hfput(p, file);
10753 + AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
10757 + * after branch manipulating, refresh the file.
10759 +static int refresh_file(struct file *file, int (*reopen)(struct file *file))
10761 + int err, need_reopen;
10762 + aufs_bindex_t bend, bindex;
10763 + struct dentry *dentry;
10764 + struct au_finfo *finfo;
10765 + struct au_hfile *hfile;
10767 + dentry = file->f_dentry;
10768 + finfo = au_fi(file);
10769 + if (!finfo->fi_hdir) {
10770 + hfile = &finfo->fi_htop;
10771 + AuDebugOn(!hfile->hf_file);
10772 + bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
10773 + AuDebugOn(bindex < 0);
10774 + if (bindex != finfo->fi_btop)
10775 + au_set_fbstart(file, bindex);
10777 + err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
10778 + if (unlikely(err))
10780 + au_do_refresh_dir(file);
10785 + if (!au_test_mmapped(file))
10786 + err = au_file_refresh_by_inode(file, &need_reopen);
10787 + if (!err && need_reopen && !d_unlinked(dentry))
10788 + err = reopen(file);
10790 + au_update_figen(file);
10791 + goto out; /* success */
10794 + /* error, close all lower files */
10795 + if (finfo->fi_hdir) {
10796 + bend = au_fbend_dir(file);
10797 + for (bindex = au_fbstart(file); bindex <= bend; bindex++)
10798 + au_set_h_fptr(file, bindex, NULL);
10805 +/* common function to regular file and dir */
10806 +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
10810 + unsigned int sigen, figen;
10811 + aufs_bindex_t bstart;
10812 + unsigned char pseudo_link;
10813 + struct dentry *dentry;
10814 + struct inode *inode;
10817 + dentry = file->f_dentry;
10818 + inode = dentry->d_inode;
10819 + AuDebugOn(au_special_file(inode->i_mode));
10820 + sigen = au_sigen(dentry->d_sb);
10821 + fi_write_lock(file);
10822 + figen = au_figen(file);
10823 + di_write_lock_child(dentry);
10824 + bstart = au_dbstart(dentry);
10825 + pseudo_link = (bstart != au_ibstart(inode));
10826 + if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
10828 + di_downgrade_lock(dentry, AuLock_IR);
10829 + fi_downgrade_lock(file);
10831 + goto out; /* success */
10834 + AuDbg("sigen %d, figen %d\n", sigen, figen);
10835 + if (au_digen_test(dentry, sigen)) {
10836 + err = au_reval_dpath(dentry, sigen);
10837 + AuDebugOn(!err && au_digen_test(dentry, sigen));
10841 + err = refresh_file(file, reopen);
10844 + di_downgrade_lock(dentry, AuLock_IR);
10845 + fi_downgrade_lock(file);
10848 + di_write_unlock(dentry);
10849 + fi_write_unlock(file);
10856 +/* ---------------------------------------------------------------------- */
10858 +/* cf. aufs_nopage() */
10859 +/* for madvise(2) */
10860 +static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
10862 + unlock_page(page);
10866 +/* it will never be called, but necessary to support O_DIRECT */
10867 +static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
10868 + const struct iovec *iov, loff_t offset,
10869 + unsigned long nr_segs)
10870 +{ BUG(); return 0; }
10873 + * it will never be called, but madvise and fadvise behaves differently
10874 + * when get_xip_mem is defined
10876 +static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
10877 + int create, void **kmem, unsigned long *pfn)
10878 +{ BUG(); return 0; }
10880 +/* they will never be called. */
10881 +#ifdef CONFIG_AUFS_DEBUG
10882 +static int aufs_write_begin(struct file *file, struct address_space *mapping,
10883 + loff_t pos, unsigned len, unsigned flags,
10884 + struct page **pagep, void **fsdata)
10885 +{ AuUnsupport(); return 0; }
10886 +static int aufs_write_end(struct file *file, struct address_space *mapping,
10887 + loff_t pos, unsigned len, unsigned copied,
10888 + struct page *page, void *fsdata)
10889 +{ AuUnsupport(); return 0; }
10890 +static int aufs_writepage(struct page *page, struct writeback_control *wbc)
10891 +{ AuUnsupport(); return 0; }
10893 +static int aufs_set_page_dirty(struct page *page)
10894 +{ AuUnsupport(); return 0; }
10895 +static void aufs_invalidatepage(struct page *page, unsigned long offset)
10896 +{ AuUnsupport(); }
10897 +static int aufs_releasepage(struct page *page, gfp_t gfp)
10898 +{ AuUnsupport(); return 0; }
10899 +static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
10900 + struct page *page, enum migrate_mode mode)
10901 +{ AuUnsupport(); return 0; }
10902 +static int aufs_launder_page(struct page *page)
10903 +{ AuUnsupport(); return 0; }
10904 +static int aufs_is_partially_uptodate(struct page *page,
10905 + read_descriptor_t *desc,
10906 + unsigned long from)
10907 +{ AuUnsupport(); return 0; }
10908 +static int aufs_error_remove_page(struct address_space *mapping,
10909 + struct page *page)
10910 +{ AuUnsupport(); return 0; }
10911 +static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
10913 +{ AuUnsupport(); return 0; }
10914 +static void aufs_swap_deactivate(struct file *file)
10915 +{ AuUnsupport(); }
10916 +#endif /* CONFIG_AUFS_DEBUG */
10918 +const struct address_space_operations aufs_aop = {
10919 + .readpage = aufs_readpage,
10920 + .direct_IO = aufs_direct_IO,
10921 + .get_xip_mem = aufs_get_xip_mem,
10922 +#ifdef CONFIG_AUFS_DEBUG
10923 + .writepage = aufs_writepage,
10924 + /* no writepages, because of writepage */
10925 + .set_page_dirty = aufs_set_page_dirty,
10926 + /* no readpages, because of readpage */
10927 + .write_begin = aufs_write_begin,
10928 + .write_end = aufs_write_end,
10929 + /* no bmap, no block device */
10930 + .invalidatepage = aufs_invalidatepage,
10931 + .releasepage = aufs_releasepage,
10932 + .migratepage = aufs_migratepage,
10933 + .launder_page = aufs_launder_page,
10934 + .is_partially_uptodate = aufs_is_partially_uptodate,
10935 + .error_remove_page = aufs_error_remove_page,
10936 + .swap_activate = aufs_swap_activate,
10937 + .swap_deactivate = aufs_swap_deactivate
10938 +#endif /* CONFIG_AUFS_DEBUG */
10940 diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
10941 --- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
10942 +++ linux/fs/aufs/file.h 2013-07-06 13:20:47.750198454 +0200
10945 + * Copyright (C) 2005-2013 Junjiro R. Okajima
10947 + * This program, aufs is free software; you can redistribute it and/or modify
10948 + * it under the terms of the GNU General Public License as published by
10949 + * the Free Software Foundation; either version 2 of the License, or
10950 + * (at your option) any later version.
10952 + * This program is distributed in the hope that it will be useful,
10953 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10954 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10955 + * GNU General Public License for more details.
10957 + * You should have received a copy of the GNU General Public License
10958 + * along with this program; if not, write to the Free Software
10959 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
10963 + * file operations
10966 +#ifndef __AUFS_FILE_H__
10967 +#define __AUFS_FILE_H__
10971 +#include <linux/file.h>
10972 +#include <linux/fs.h>
10973 +#include <linux/poll.h>
10974 +#include "rwsem.h"
10978 + struct file *hf_file;
10979 + struct au_branch *hf_br;
10984 + aufs_bindex_t fd_bbot;
10985 + aufs_bindex_t fd_nent;
10986 + struct au_vdir *fd_vdir_cache;
10987 + struct au_hfile fd_hfile[];
10990 +static inline int au_fidir_sz(int nent)
10992 + AuDebugOn(nent < 0);
10993 + return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
10997 + atomic_t fi_generation;
10999 + struct au_rwsem fi_rwsem;
11000 + aufs_bindex_t fi_btop;
11002 + /* do not union them */
11003 + struct { /* for non-dir */
11004 + struct au_hfile fi_htop;
11005 + atomic_t fi_mmapped;
11007 + struct au_fidir *fi_hdir; /* for dir only */
11008 +} ____cacheline_aligned_in_smp;
11010 +/* ---------------------------------------------------------------------- */
11013 +extern const struct address_space_operations aufs_aop;
11014 +unsigned int au_file_roflags(unsigned int flags);
11015 +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
11016 + struct file *file);
11017 +int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
11018 + struct au_fidir *fidir);
11019 +int au_reopen_nondir(struct file *file);
11021 +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
11022 +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
11024 +int au_do_flush(struct file *file, fl_owner_t id,
11025 + int (*flush)(struct file *file, fl_owner_t id));
11028 +#ifdef CONFIG_AUFS_POLL
11029 +unsigned int aufs_poll(struct file *file, poll_table *wait);
11032 +#ifdef CONFIG_AUFS_BR_HFSPLUS
11034 +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex);
11035 +void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
11036 + struct file *h_file);
11039 +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
11044 +AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
11045 + struct file *h_file);
11049 +extern const struct file_operations aufs_file_fop;
11050 +int au_do_open_nondir(struct file *file, int flags);
11051 +int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
11053 +#ifdef CONFIG_AUFS_SP_IATTR
11055 +struct au_finfo *au_fi_sp(struct file *file);
11056 +int au_special_file(umode_t mode);
11057 +void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
11059 +static inline struct au_finfo *au_fi_sp(struct file *file)
11063 +AuStubInt0(au_special_file, umode_t mode)
11064 +static inline void au_init_special_fop(struct inode *inode, umode_t mode,
11067 + init_special_inode(inode, mode, rdev);
11072 +void au_hfput(struct au_hfile *hf, struct file *file);
11073 +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
11074 + struct file *h_file);
11076 +void au_update_figen(struct file *file);
11077 +struct au_fidir *au_fidir_alloc(struct super_block *sb);
11078 +int au_fidir_realloc(struct au_finfo *finfo, int nbr);
11080 +void au_fi_init_once(void *_fi);
11081 +void au_finfo_fin(struct file *file);
11082 +int au_finfo_init(struct file *file, struct au_fidir *fidir);
11085 +long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
11086 +#ifdef CONFIG_COMPAT
11087 +long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
11088 + unsigned long arg);
11091 +/* ---------------------------------------------------------------------- */
11093 +static inline struct au_finfo *au_fi(struct file *file)
11095 + struct au_finfo *finfo;
11097 + finfo = au_fi_sp(file);
11099 + finfo = file->private_data;
11103 +/* ---------------------------------------------------------------------- */
11106 + * fi_read_lock, fi_write_lock,
11107 + * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
11109 +AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
11111 +#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
11112 +#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
11113 +#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
11115 +/* ---------------------------------------------------------------------- */
11117 +/* todo: hard/soft set? */
11118 +static inline aufs_bindex_t au_fbstart(struct file *file)
11120 + FiMustAnyLock(file);
11121 + return au_fi(file)->fi_btop;
11124 +static inline aufs_bindex_t au_fbend_dir(struct file *file)
11126 + FiMustAnyLock(file);
11127 + AuDebugOn(!au_fi(file)->fi_hdir);
11128 + return au_fi(file)->fi_hdir->fd_bbot;
11131 +static inline struct au_vdir *au_fvdir_cache(struct file *file)
11133 + FiMustAnyLock(file);
11134 + AuDebugOn(!au_fi(file)->fi_hdir);
11135 + return au_fi(file)->fi_hdir->fd_vdir_cache;
11138 +static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
11140 + FiMustWriteLock(file);
11141 + au_fi(file)->fi_btop = bindex;
11144 +static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
11146 + FiMustWriteLock(file);
11147 + AuDebugOn(!au_fi(file)->fi_hdir);
11148 + au_fi(file)->fi_hdir->fd_bbot = bindex;
11151 +static inline void au_set_fvdir_cache(struct file *file,
11152 + struct au_vdir *vdir_cache)
11154 + FiMustWriteLock(file);
11155 + AuDebugOn(!au_fi(file)->fi_hdir);
11156 + au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
11159 +static inline struct file *au_hf_top(struct file *file)
11161 + FiMustAnyLock(file);
11162 + AuDebugOn(au_fi(file)->fi_hdir);
11163 + return au_fi(file)->fi_htop.hf_file;
11166 +static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
11168 + FiMustAnyLock(file);
11169 + AuDebugOn(!au_fi(file)->fi_hdir);
11170 + return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
11173 +/* todo: memory barrier? */
11174 +static inline unsigned int au_figen(struct file *f)
11176 + return atomic_read(&au_fi(f)->fi_generation);
11179 +static inline void au_set_mmapped(struct file *f)
11181 + if (atomic_inc_return(&au_fi(f)->fi_mmapped))
11183 + pr_warn("fi_mmapped wrapped around\n");
11184 + while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
11188 +static inline void au_unset_mmapped(struct file *f)
11190 + atomic_dec(&au_fi(f)->fi_mmapped);
11193 +static inline int au_test_mmapped(struct file *f)
11195 + return atomic_read(&au_fi(f)->fi_mmapped);
11198 +/* customize vma->vm_file */
11200 +static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
11201 + struct file *file)
11205 + f = vma->vm_file;
11207 + vma->vm_file = file;
11212 +#define AuDbgVmRegion(file, vma) do {} while (0)
11214 +static inline void au_vm_file_reset(struct vm_area_struct *vma,
11215 + struct file *file)
11217 + au_do_vm_file_reset(vma, file);
11220 +#define AuDbgVmRegion(file, vma) \
11221 + AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
11223 +static inline void au_vm_file_reset(struct vm_area_struct *vma,
11224 + struct file *file)
11228 + au_do_vm_file_reset(vma, file);
11229 + f = vma->vm_region->vm_file;
11231 + vma->vm_region->vm_file = file;
11234 +#endif /* CONFIG_MMU */
11236 +/* handle vma->vm_prfile */
11237 +static inline void au_vm_prfile_set(struct vm_area_struct *vma,
11238 + struct file *file)
11240 +#ifdef CONFIG_AUFS_PROC_MAP
11242 + vma->vm_prfile = file;
11243 +#ifndef CONFIG_MMU
11245 + vma->vm_region->vm_prfile = file;
11250 +#endif /* __KERNEL__ */
11251 +#endif /* __AUFS_FILE_H__ */
11252 diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
11253 --- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
11254 +++ linux/fs/aufs/finfo.c 2013-07-06 13:20:47.750198454 +0200
11257 + * Copyright (C) 2005-2013 Junjiro R. Okajima
11259 + * This program, aufs is free software; you can redistribute it and/or modify
11260 + * it under the terms of the GNU General Public License as published by
11261 + * the Free Software Foundation; either version 2 of the License, or
11262 + * (at your option) any later version.
11264 + * This program is distributed in the hope that it will be useful,
11265 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11266 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11267 + * GNU General Public License for more details.
11269 + * You should have received a copy of the GNU General Public License
11270 + * along with this program; if not, write to the Free Software
11271 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11275 + * file private data
11280 +void au_hfput(struct au_hfile *hf, struct file *file)
11282 + /* todo: direct access f_flags */
11283 + if (vfsub_file_flags(file) & __FMODE_EXEC)
11284 + allow_write_access(hf->hf_file);
11285 + fput(hf->hf_file);
11286 + hf->hf_file = NULL;
11287 + atomic_dec(&hf->hf_br->br_count);
11288 + hf->hf_br = NULL;
11291 +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
11293 + struct au_finfo *finfo = au_fi(file);
11294 + struct au_hfile *hf;
11295 + struct au_fidir *fidir;
11297 + fidir = finfo->fi_hdir;
11299 + AuDebugOn(finfo->fi_btop != bindex);
11300 + hf = &finfo->fi_htop;
11302 + hf = fidir->fd_hfile + bindex;
11304 + if (hf && hf->hf_file)
11305 + au_hfput(hf, file);
11307 + FiMustWriteLock(file);
11308 + hf->hf_file = val;
11309 + hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
11313 +void au_update_figen(struct file *file)
11315 + atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
11316 + /* smp_mb(); */ /* atomic_set */
11319 +/* ---------------------------------------------------------------------- */
11321 +struct au_fidir *au_fidir_alloc(struct super_block *sb)
11323 + struct au_fidir *fidir;
11326 + nbr = au_sbend(sb) + 1;
11328 + nbr = 2; /* initial allocate for 2 branches */
11329 + fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
11331 + fidir->fd_bbot = -1;
11332 + fidir->fd_nent = nbr;
11333 + fidir->fd_vdir_cache = NULL;
11339 +int au_fidir_realloc(struct au_finfo *finfo, int nbr)
11342 + struct au_fidir *fidir, *p;
11344 + AuRwMustWriteLock(&finfo->fi_rwsem);
11345 + fidir = finfo->fi_hdir;
11346 + AuDebugOn(!fidir);
11349 + p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
11352 + p->fd_nent = nbr;
11353 + finfo->fi_hdir = p;
11360 +/* ---------------------------------------------------------------------- */
11362 +void au_finfo_fin(struct file *file)
11364 + struct au_finfo *finfo;
11366 + au_nfiles_dec(file->f_dentry->d_sb);
11368 + finfo = au_fi(file);
11369 + AuDebugOn(finfo->fi_hdir);
11370 + AuRwDestroy(&finfo->fi_rwsem);
11371 + au_cache_free_finfo(finfo);
11374 +void au_fi_init_once(void *_finfo)
11376 + struct au_finfo *finfo = _finfo;
11377 + static struct lock_class_key aufs_fi;
11379 + au_rw_init(&finfo->fi_rwsem);
11380 + au_rw_class(&finfo->fi_rwsem, &aufs_fi);
11383 +int au_finfo_init(struct file *file, struct au_fidir *fidir)
11386 + struct au_finfo *finfo;
11387 + struct dentry *dentry;
11390 + dentry = file->f_dentry;
11391 + finfo = au_cache_alloc_finfo();
11392 + if (unlikely(!finfo))
11396 + au_nfiles_inc(dentry->d_sb);
11397 + /* verbose coding for lock class name */
11399 + au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
11401 + au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
11402 + au_rw_write_lock(&finfo->fi_rwsem);
11403 + finfo->fi_btop = -1;
11404 + finfo->fi_hdir = fidir;
11405 + atomic_set(&finfo->fi_generation, au_digen(dentry));
11406 + /* smp_mb(); */ /* atomic_set */
11408 + file->private_data = finfo;
11413 diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
11414 --- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
11415 +++ linux/fs/aufs/f_op.c 2013-07-30 22:42:55.839613269 +0200
11418 + * Copyright (C) 2005-2013 Junjiro R. Okajima
11420 + * This program, aufs is free software; you can redistribute it and/or modify
11421 + * it under the terms of the GNU General Public License as published by
11422 + * the Free Software Foundation; either version 2 of the License, or
11423 + * (at your option) any later version.
11425 + * This program is distributed in the hope that it will be useful,
11426 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11427 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11428 + * GNU General Public License for more details.
11430 + * You should have received a copy of the GNU General Public License
11431 + * along with this program; if not, write to the Free Software
11432 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11436 + * file and vm operations
11439 +#include <linux/aio.h>
11440 +#include <linux/fs_stack.h>
11441 +#include <linux/mman.h>
11442 +#include <linux/security.h>
11445 +int au_do_open_nondir(struct file *file, int flags)
11448 + aufs_bindex_t bindex;
11449 + struct file *h_file;
11450 + struct dentry *dentry;
11451 + struct au_finfo *finfo;
11453 + FiMustWriteLock(file);
11455 + dentry = file->f_dentry;
11456 + err = au_d_alive(dentry);
11457 + if (unlikely(err))
11460 + finfo = au_fi(file);
11461 + memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
11462 + atomic_set(&finfo->fi_mmapped, 0);
11463 + bindex = au_dbstart(dentry);
11464 + h_file = au_h_open(dentry, bindex, flags, file);
11465 + if (IS_ERR(h_file))
11466 + err = PTR_ERR(h_file);
11468 + au_set_fbstart(file, bindex);
11469 + au_set_h_fptr(file, bindex, h_file);
11470 + au_update_figen(file);
11471 + /* todo: necessary? */
11472 + /* file->f_ra = h_file->f_ra; */
11479 +static int aufs_open_nondir(struct inode *inode __maybe_unused,
11480 + struct file *file)
11483 + struct super_block *sb;
11485 + AuDbg("%.*s, f_flags 0x%x, f_mode 0x%x\n",
11486 + AuDLNPair(file->f_dentry), vfsub_file_flags(file),
11489 + sb = file->f_dentry->d_sb;
11490 + si_read_lock(sb, AuLock_FLUSH);
11491 + err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
11492 + si_read_unlock(sb);
11496 +int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
11498 + struct au_finfo *finfo;
11499 + aufs_bindex_t bindex;
11501 + finfo = au_fi(file);
11502 + bindex = finfo->fi_btop;
11504 + au_set_h_fptr(file, bindex, NULL);
11506 + au_finfo_fin(file);
11510 +/* ---------------------------------------------------------------------- */
11512 +static int au_do_flush_nondir(struct file *file, fl_owner_t id)
11515 + struct file *h_file;
11518 + h_file = au_hf_top(file);
11520 + err = vfsub_flush(h_file, id);
11524 +static int aufs_flush_nondir(struct file *file, fl_owner_t id)
11526 + return au_do_flush(file, id, au_do_flush_nondir);
11529 +/* ---------------------------------------------------------------------- */
11531 + * read and write functions acquire [fdi]_rwsem once, but release before
11532 + * mmap_sem. This is because to stop a race condition between mmap(2).
11533 + * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
11534 + * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
11535 + * read functions after [fdi]_rwsem are released, but it should be harmless.
11538 +static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
11542 + struct dentry *dentry;
11543 + struct file *h_file;
11544 + struct super_block *sb;
11546 + dentry = file->f_dentry;
11547 + sb = dentry->d_sb;
11548 + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11549 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11550 + if (unlikely(err))
11553 + h_file = au_hf_top(file);
11554 + get_file(h_file);
11555 + di_read_unlock(dentry, AuLock_IR);
11556 + fi_read_unlock(file);
11558 + /* filedata may be obsoleted by concurrent copyup, but no problem */
11559 + err = vfsub_read_u(h_file, buf, count, ppos);
11560 + /* todo: necessary? */
11561 + /* file->f_ra = h_file->f_ra; */
11562 + /* update without lock, I don't think it a problem */
11563 + fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
11567 + si_read_unlock(sb);
11572 + * todo: very ugly
11573 + * it locks both of i_mutex and si_rwsem for read in safe.
11574 + * if the plink maintenance mode continues forever (that is the problem),
11575 + * may loop forever.
11577 +static void au_mtx_and_read_lock(struct inode *inode)
11580 + struct super_block *sb = inode->i_sb;
11583 + mutex_lock(&inode->i_mutex);
11584 + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11587 + mutex_unlock(&inode->i_mutex);
11588 + si_read_lock(sb, AuLock_NOPLMW);
11589 + si_read_unlock(sb);
11593 +static ssize_t aufs_write(struct file *file, const char __user *ubuf,
11594 + size_t count, loff_t *ppos)
11597 + struct au_pin pin;
11598 + struct dentry *dentry;
11599 + struct super_block *sb;
11600 + struct inode *inode;
11601 + struct file *h_file;
11602 + char __user *buf = (char __user *)ubuf;
11604 + dentry = file->f_dentry;
11605 + sb = dentry->d_sb;
11606 + inode = dentry->d_inode;
11607 + au_mtx_and_read_lock(inode);
11609 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11610 + if (unlikely(err))
11613 + err = au_ready_to_write(file, -1, &pin);
11614 + di_downgrade_lock(dentry, AuLock_IR);
11615 + if (unlikely(err)) {
11616 + di_read_unlock(dentry, AuLock_IR);
11617 + fi_write_unlock(file);
11621 + h_file = au_hf_top(file);
11622 + get_file(h_file);
11624 + di_read_unlock(dentry, AuLock_IR);
11625 + fi_write_unlock(file);
11627 + err = vfsub_write_u(h_file, buf, count, ppos);
11628 + ii_write_lock_child(inode);
11629 + au_cpup_attr_timesizes(inode);
11630 + inode->i_mode = file_inode(h_file)->i_mode;
11631 + ii_write_unlock(inode);
11635 + si_read_unlock(sb);
11636 + mutex_unlock(&inode->i_mutex);
11640 +static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
11641 + const struct iovec *iov, unsigned long nv, loff_t pos)
11644 + struct file *file;
11645 + ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
11648 + err = security_file_permission(h_file, rw);
11649 + if (unlikely(err))
11654 + if (rw == MAY_READ)
11655 + func = h_file->f_op->aio_read;
11656 + else if (rw == MAY_WRITE)
11657 + func = h_file->f_op->aio_write;
11659 + file = kio->ki_filp;
11660 + kio->ki_filp = h_file;
11662 + err = func(kio, iov, nv, pos);
11664 + kio->ki_filp = file;
11666 + /* currently there is no such fs */
11673 +static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
11674 + unsigned long nv, loff_t pos)
11677 + struct file *file, *h_file;
11678 + struct dentry *dentry;
11679 + struct super_block *sb;
11681 + file = kio->ki_filp;
11682 + dentry = file->f_dentry;
11683 + sb = dentry->d_sb;
11684 + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11685 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11686 + if (unlikely(err))
11689 + h_file = au_hf_top(file);
11690 + get_file(h_file);
11691 + di_read_unlock(dentry, AuLock_IR);
11692 + fi_read_unlock(file);
11694 + err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
11695 + /* todo: necessary? */
11696 + /* file->f_ra = h_file->f_ra; */
11697 + /* update without lock, I don't think it a problem */
11698 + fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
11702 + si_read_unlock(sb);
11706 +static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
11707 + unsigned long nv, loff_t pos)
11710 + struct au_pin pin;
11711 + struct dentry *dentry;
11712 + struct inode *inode;
11713 + struct file *file, *h_file;
11714 + struct super_block *sb;
11716 + file = kio->ki_filp;
11717 + dentry = file->f_dentry;
11718 + sb = dentry->d_sb;
11719 + inode = dentry->d_inode;
11720 + au_mtx_and_read_lock(inode);
11722 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11723 + if (unlikely(err))
11726 + err = au_ready_to_write(file, -1, &pin);
11727 + di_downgrade_lock(dentry, AuLock_IR);
11728 + if (unlikely(err)) {
11729 + di_read_unlock(dentry, AuLock_IR);
11730 + fi_write_unlock(file);
11734 + h_file = au_hf_top(file);
11735 + get_file(h_file);
11737 + di_read_unlock(dentry, AuLock_IR);
11738 + fi_write_unlock(file);
11740 + err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
11741 + ii_write_lock_child(inode);
11742 + au_cpup_attr_timesizes(inode);
11743 + inode->i_mode = file_inode(h_file)->i_mode;
11744 + ii_write_unlock(inode);
11748 + si_read_unlock(sb);
11749 + mutex_unlock(&inode->i_mutex);
11753 +static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
11754 + struct pipe_inode_info *pipe, size_t len,
11755 + unsigned int flags)
11758 + struct file *h_file;
11759 + struct dentry *dentry;
11760 + struct super_block *sb;
11762 + dentry = file->f_dentry;
11763 + sb = dentry->d_sb;
11764 + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11765 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11766 + if (unlikely(err))
11770 + h_file = au_hf_top(file);
11771 + get_file(h_file);
11772 + if (au_test_loopback_kthread()) {
11773 + au_warn_loopback(h_file->f_dentry->d_sb);
11774 + if (file->f_mapping != h_file->f_mapping) {
11775 + file->f_mapping = h_file->f_mapping;
11776 + smp_mb(); /* unnecessary? */
11779 + di_read_unlock(dentry, AuLock_IR);
11780 + fi_read_unlock(file);
11782 + err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
11783 + /* todo: necessasry? */
11784 + /* file->f_ra = h_file->f_ra; */
11785 + /* update without lock, I don't think it a problem */
11786 + fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
11790 + si_read_unlock(sb);
11795 +aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
11796 + size_t len, unsigned int flags)
11799 + struct au_pin pin;
11800 + struct dentry *dentry;
11801 + struct inode *inode;
11802 + struct file *h_file;
11803 + struct super_block *sb;
11805 + dentry = file->f_dentry;
11806 + sb = dentry->d_sb;
11807 + inode = dentry->d_inode;
11808 + au_mtx_and_read_lock(inode);
11810 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11811 + if (unlikely(err))
11814 + err = au_ready_to_write(file, -1, &pin);
11815 + di_downgrade_lock(dentry, AuLock_IR);
11816 + if (unlikely(err)) {
11817 + di_read_unlock(dentry, AuLock_IR);
11818 + fi_write_unlock(file);
11822 + h_file = au_hf_top(file);
11823 + get_file(h_file);
11825 + di_read_unlock(dentry, AuLock_IR);
11826 + fi_write_unlock(file);
11828 + err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
11829 + ii_write_lock_child(inode);
11830 + au_cpup_attr_timesizes(inode);
11831 + inode->i_mode = file_inode(h_file)->i_mode;
11832 + ii_write_unlock(inode);
11836 + si_read_unlock(sb);
11837 + mutex_unlock(&inode->i_mutex);
11841 +/* ---------------------------------------------------------------------- */
11844 + * The locking order around current->mmap_sem.
11845 + * - in most and regular cases
11846 + * file I/O syscall -- aufs_read() or something
11847 + * -- si_rwsem for read -- mmap_sem
11848 + * (Note that [fdi]i_rwsem are released before mmap_sem).
11850 + * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
11851 + * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
11852 + * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
11853 + * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
11854 + * It means that when aufs acquires si_rwsem for write, the process should never
11855 + * acquire mmap_sem.
11857 + * Actually aufs_readdir() holds [fdi]i_rwsem before mmap_sem, but this is not a
11858 + * problem either since any directory is not able to be mmap-ed.
11859 + * The similar scenario is applied to aufs_readlink() too.
11862 +/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
11863 +#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
11865 +static unsigned long au_arch_prot_conv(unsigned long flags)
11867 + /* currently ppc64 only */
11868 +#ifdef CONFIG_PPC64
11869 + /* cf. linux/arch/powerpc/include/asm/mman.h */
11870 + AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
11871 + return AuConv_VM_PROT(flags, SAO);
11873 + AuDebugOn(arch_calc_vm_prot_bits(-1));
11878 +static unsigned long au_prot_conv(unsigned long flags)
11880 + return AuConv_VM_PROT(flags, READ)
11881 + | AuConv_VM_PROT(flags, WRITE)
11882 + | AuConv_VM_PROT(flags, EXEC)
11883 + | au_arch_prot_conv(flags);
11886 +/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
11887 +#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
11889 +static unsigned long au_flag_conv(unsigned long flags)
11891 + return AuConv_VM_MAP(flags, GROWSDOWN)
11892 + | AuConv_VM_MAP(flags, DENYWRITE)
11893 + | AuConv_VM_MAP(flags, LOCKED);
11896 +static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
11899 + aufs_bindex_t bstart;
11900 + const unsigned char wlock
11901 + = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
11902 + struct dentry *dentry;
11903 + struct super_block *sb;
11904 + struct file *h_file;
11905 + struct au_branch *br;
11906 + struct au_pin pin;
11908 + AuDbgVmRegion(file, vma);
11910 + dentry = file->f_dentry;
11911 + sb = dentry->d_sb;
11913 + si_read_lock(sb, AuLock_NOPLMW);
11914 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11915 + if (unlikely(err))
11919 + err = au_ready_to_write(file, -1, &pin);
11920 + di_write_unlock(dentry);
11921 + if (unlikely(err)) {
11922 + fi_write_unlock(file);
11927 + di_write_unlock(dentry);
11929 + bstart = au_fbstart(file);
11930 + br = au_sbr(sb, bstart);
11931 + h_file = au_hf_top(file);
11932 + get_file(h_file);
11933 + au_set_mmapped(file);
11934 + fi_write_unlock(file);
11937 + au_vm_file_reset(vma, h_file);
11938 + err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
11939 + au_flag_conv(vma->vm_flags));
11941 + err = h_file->f_op->mmap(h_file, vma);
11942 + if (unlikely(err))
11945 + au_vm_prfile_set(vma, file);
11946 + /* update without lock, I don't think it a problem */
11947 + fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
11948 + goto out_fput; /* success */
11951 + au_unset_mmapped(file);
11952 + au_vm_file_reset(vma, file);
11957 + si_read_unlock(sb);
11963 +/* ---------------------------------------------------------------------- */
11965 +static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
11969 + struct au_pin pin;
11970 + struct dentry *dentry;
11971 + struct inode *inode;
11972 + struct file *h_file;
11973 + struct super_block *sb;
11975 + dentry = file->f_dentry;
11976 + inode = dentry->d_inode;
11977 + sb = dentry->d_sb;
11978 + mutex_lock(&inode->i_mutex);
11979 + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11980 + if (unlikely(err))
11983 + err = 0; /* -EBADF; */ /* posix? */
11984 + if (unlikely(!(file->f_mode & FMODE_WRITE)))
11986 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11987 + if (unlikely(err))
11990 + err = au_ready_to_write(file, -1, &pin);
11991 + di_downgrade_lock(dentry, AuLock_IR);
11992 + if (unlikely(err))
11997 + h_file = au_hf_top(file);
11998 + err = vfsub_fsync(h_file, &h_file->f_path, datasync);
11999 + au_cpup_attr_timesizes(inode);
12002 + di_read_unlock(dentry, AuLock_IR);
12003 + fi_write_unlock(file);
12005 + si_read_unlock(sb);
12007 + mutex_unlock(&inode->i_mutex);
12011 +/* no one supports this operation, currently */
12013 +static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
12016 + struct au_pin pin;
12017 + struct dentry *dentry;
12018 + struct inode *inode;
12019 + struct file *file, *h_file;
12021 + file = kio->ki_filp;
12022 + dentry = file->f_dentry;
12023 + inode = dentry->d_inode;
12024 + au_mtx_and_read_lock(inode);
12026 + err = 0; /* -EBADF; */ /* posix? */
12027 + if (unlikely(!(file->f_mode & FMODE_WRITE)))
12029 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12030 + if (unlikely(err))
12033 + err = au_ready_to_write(file, -1, &pin);
12034 + di_downgrade_lock(dentry, AuLock_IR);
12035 + if (unlikely(err))
12040 + h_file = au_hf_top(file);
12041 + if (h_file->f_op && h_file->f_op->aio_fsync) {
12042 + struct mutex *h_mtx;
12044 + h_mtx = &file_inode(h_file)->i_mutex;
12045 + if (!is_sync_kiocb(kio)) {
12046 + get_file(h_file);
12049 + kio->ki_filp = h_file;
12050 + err = h_file->f_op->aio_fsync(kio, datasync);
12051 + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
12053 + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
12055 + au_cpup_attr_timesizes(inode);
12056 + mutex_unlock(h_mtx);
12060 + di_read_unlock(dentry, AuLock_IR);
12061 + fi_write_unlock(file);
12063 + si_read_unlock(inode->sb);
12064 + mutex_unlock(&inode->i_mutex);
12069 +static int aufs_fasync(int fd, struct file *file, int flag)
12072 + struct file *h_file;
12073 + struct dentry *dentry;
12074 + struct super_block *sb;
12076 + dentry = file->f_dentry;
12077 + sb = dentry->d_sb;
12078 + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
12079 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
12080 + if (unlikely(err))
12083 + h_file = au_hf_top(file);
12084 + if (h_file->f_op && h_file->f_op->fasync)
12085 + err = h_file->f_op->fasync(fd, h_file, flag);
12087 + di_read_unlock(dentry, AuLock_IR);
12088 + fi_read_unlock(file);
12091 + si_read_unlock(sb);
12095 +/* ---------------------------------------------------------------------- */
12097 +/* no one supports this operation, currently */
12099 +static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
12100 + size_t len, loff_t *pos , int more)
12105 +/* ---------------------------------------------------------------------- */
12107 +const struct file_operations aufs_file_fop = {
12108 + .owner = THIS_MODULE,
12110 + .llseek = default_llseek,
12112 + .read = aufs_read,
12113 + .write = aufs_write,
12114 + .aio_read = aufs_aio_read,
12115 + .aio_write = aufs_aio_write,
12116 +#ifdef CONFIG_AUFS_POLL
12117 + .poll = aufs_poll,
12119 + .unlocked_ioctl = aufs_ioctl_nondir,
12120 +#ifdef CONFIG_COMPAT
12121 + .compat_ioctl = aufs_ioctl_nondir, /* same */
12123 + .mmap = aufs_mmap,
12124 + .open = aufs_open_nondir,
12125 + .flush = aufs_flush_nondir,
12126 + .release = aufs_release_nondir,
12127 + .fsync = aufs_fsync_nondir,
12128 + /* .aio_fsync = aufs_aio_fsync_nondir, */
12129 + .fasync = aufs_fasync,
12130 + /* .sendpage = aufs_sendpage, */
12131 + .splice_write = aufs_splice_write,
12132 + .splice_read = aufs_splice_read,
12134 + .aio_splice_write = aufs_aio_splice_write,
12135 + .aio_splice_read = aufs_aio_splice_read
12138 diff -urN /usr/share/empty/fs/aufs/f_op_sp.c linux/fs/aufs/f_op_sp.c
12139 --- /usr/share/empty/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100
12140 +++ linux/fs/aufs/f_op_sp.c 2013-07-06 13:20:47.750198454 +0200
12143 + * Copyright (C) 2005-2013 Junjiro R. Okajima
12145 + * This program, aufs is free software; you can redistribute it and/or modify
12146 + * it under the terms of the GNU General Public License as published by
12147 + * the Free Software Foundation; either version 2 of the License, or
12148 + * (at your option) any later version.
12150 + * This program is distributed in the hope that it will be useful,
12151 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12152 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12153 + * GNU General Public License for more details.
12155 + * You should have received a copy of the GNU General Public License
12156 + * along with this program; if not, write to the Free Software
12157 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12161 + * file operations for special files.
12162 + * while they exist in aufs virtually,
12163 + * their file I/O is handled out of aufs.
12166 +#include <linux/aio.h>
12170 + * I don't think the size of this list grows much.
12171 + * so here is a very simple list implemented in order to find finfo matching a
12174 +static struct au_sphlhead au_finfo_sp = {
12175 + .spin = __SPIN_LOCK_INITIALIZER(au_finfo_sp.spin),
12176 + .head = HLIST_HEAD_INIT
12179 +struct au_finfo_sp {
12180 + struct hlist_node hlist;
12181 + struct file *file;
12182 + struct au_finfo *finfo;
12185 +struct au_finfo *au_fi_sp(struct file *file)
12187 + struct au_finfo *finfo;
12188 + struct au_finfo_sp *sp;
12191 + spin_lock(&au_finfo_sp.spin);
12192 + hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12193 + if (sp->file != file)
12195 + finfo = sp->finfo;
12198 + spin_unlock(&au_finfo_sp.spin);
12203 +static int au_fi_sp_add(struct file *file)
12206 + struct au_finfo_sp *sp;
12209 + sp = kmalloc(sizeof(*sp), GFP_NOFS);
12213 + sp->finfo = file->private_data;
12214 + spin_lock(&au_finfo_sp.spin);
12215 + hlist_add_head(&sp->hlist, &au_finfo_sp.head);
12216 + spin_unlock(&au_finfo_sp.spin);
12221 +static void au_fi_sp_del(struct file *file)
12223 + struct au_finfo_sp *sp, *do_free;
12226 + spin_lock(&au_finfo_sp.spin);
12227 + hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12228 + if (sp->file != file)
12230 + hlist_del(&sp->hlist);
12234 + spin_unlock(&au_finfo_sp.spin);
12238 +/* ---------------------------------------------------------------------- */
12240 +static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
12241 + unsigned long nv, loff_t pos)
12244 + aufs_bindex_t bstart;
12245 + unsigned char wbr;
12246 + struct file *file, *h_file;
12247 + struct super_block *sb;
12249 + file = kio->ki_filp;
12250 + sb = file->f_dentry->d_sb;
12251 + si_read_lock(sb, AuLock_FLUSH);
12252 + fi_read_lock(file);
12253 + bstart = au_fbstart(file);
12254 + h_file = au_hf_top(file);
12255 + fi_read_unlock(file);
12256 + wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12257 + si_read_unlock(sb);
12259 + /* do not change the file in kio */
12260 + AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
12261 + err = h_file->f_op->aio_read(kio, iov, nv, pos);
12262 + if (err > 0 && wbr)
12263 + file_accessed(h_file);
12268 +static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
12269 + unsigned long nv, loff_t pos)
12272 + aufs_bindex_t bstart;
12273 + unsigned char wbr;
12274 + struct super_block *sb;
12275 + struct file *file, *h_file;
12277 + file = kio->ki_filp;
12278 + sb = file->f_dentry->d_sb;
12279 + si_read_lock(sb, AuLock_FLUSH);
12280 + fi_read_lock(file);
12281 + bstart = au_fbstart(file);
12282 + h_file = au_hf_top(file);
12283 + fi_read_unlock(file);
12284 + wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12285 + si_read_unlock(sb);
12287 + /* do not change the file in kio */
12288 + AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
12289 + err = h_file->f_op->aio_write(kio, iov, nv, pos);
12293 +/* ---------------------------------------------------------------------- */
12295 +static int aufs_release_sp(struct inode *inode, struct file *file)
12298 + struct file *h_file;
12300 + fi_read_lock(file);
12301 + h_file = au_hf_top(file);
12302 + fi_read_unlock(file);
12303 + /* close this fifo in aufs */
12304 + err = h_file->f_op->release(inode, file); /* ignore */
12305 + aufs_release_nondir(inode, file); /* ignore */
12306 + au_fi_sp_del(file);
12310 +/* ---------------------------------------------------------------------- */
12312 +/* currently, support only FIFO */
12314 + AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
12315 + /* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
12318 +static int aufs_open_sp(struct inode *inode, struct file *file);
12319 +static struct au_sp_fop {
12321 + struct file_operations fop; /* not 'const' */
12323 +} au_sp_fop[AuSp_Last] = {
12326 + .owner = THIS_MODULE,
12327 + .open = aufs_open_sp
12332 +static void au_init_fop_sp(struct file *file)
12334 + struct au_sp_fop *p;
12336 + struct file *h_file;
12339 + if (unlikely(!p->done)) {
12340 + /* initialize first time only */
12341 + static DEFINE_SPINLOCK(spin);
12343 + spin_lock(&spin);
12345 + BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
12347 + for (i = 0; i < AuSp_Last; i++)
12348 + spin_lock_init(&p[i].spin);
12351 + spin_unlock(&spin);
12354 + switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
12358 + case FMODE_WRITE:
12361 + case FMODE_READ | FMODE_WRITE:
12362 + i = AuSp_FIFO_RW;
12369 + if (unlikely(!p->done)) {
12370 + /* initialize first time only */
12371 + h_file = au_hf_top(file);
12372 + spin_lock(&p->spin);
12374 + p->fop = *h_file->f_op;
12375 + p->fop.owner = THIS_MODULE;
12376 + if (p->fop.aio_read)
12377 + p->fop.aio_read = aufs_aio_read_sp;
12378 + if (p->fop.aio_write)
12379 + p->fop.aio_write = aufs_aio_write_sp;
12380 + p->fop.release = aufs_release_sp;
12383 + spin_unlock(&p->spin);
12385 + file->f_op = &p->fop;
12388 +static int au_cpup_sp(struct dentry *dentry)
12391 + aufs_bindex_t bcpup;
12392 + struct au_pin pin;
12393 + struct au_wr_dir_args wr_dir_args = {
12394 + .force_btgt = -1,
12398 + AuDbg("%.*s\n", AuDLNPair(dentry));
12400 + di_read_unlock(dentry, AuLock_IR);
12401 + di_write_lock_child(dentry);
12402 + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
12403 + if (unlikely(err < 0))
12407 + if (bcpup == au_dbstart(dentry))
12408 + goto out; /* success */
12410 + err = au_pin(&pin, dentry, bcpup, au_opt_udba(dentry->d_sb),
12411 + AuPin_MNT_WRITE);
12413 + err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME, &pin);
12418 + di_downgrade_lock(dentry, AuLock_IR);
12422 +static int au_do_open_sp(struct file *file, int flags)
12425 + struct dentry *dentry;
12426 + struct super_block *sb;
12427 + struct file *h_file;
12428 + struct inode *h_inode;
12430 + err = au_fi_sp_add(file);
12431 + if (unlikely(err))
12434 + dentry = file->f_dentry;
12435 + AuDbg("%.*s\n", AuDLNPair(dentry));
12438 + * try copying-up.
12439 + * operate on the ro branch is not an error.
12441 + au_cpup_sp(dentry); /* ignore */
12443 + /* prepare h_file */
12444 + err = au_do_open_nondir(file, vfsub_file_flags(file));
12445 + if (unlikely(err))
12448 + sb = dentry->d_sb;
12449 + h_file = au_hf_top(file);
12450 + h_inode = file_inode(h_file);
12451 + di_read_unlock(dentry, AuLock_IR);
12452 + fi_write_unlock(file);
12453 + si_read_unlock(sb);
12454 + /* open this fifo in aufs */
12455 + err = h_inode->i_fop->open(file_inode(file), file);
12456 + si_noflush_read_lock(sb);
12457 + fi_write_lock(file);
12458 + di_read_lock_child(dentry, AuLock_IR);
12460 + au_init_fop_sp(file);
12461 + goto out; /* success */
12465 + au_fi_sp_del(file);
12470 +static int aufs_open_sp(struct inode *inode, struct file *file)
12473 + struct super_block *sb;
12475 + sb = file->f_dentry->d_sb;
12476 + si_read_lock(sb, AuLock_FLUSH);
12477 + err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
12478 + si_read_unlock(sb);
12482 +/* ---------------------------------------------------------------------- */
12484 +void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
12486 + init_special_inode(inode, mode, rdev);
12488 + switch (mode & S_IFMT) {
12490 + inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
12501 +int au_special_file(umode_t mode)
12506 + switch (mode & S_IFMT) {
12518 diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
12519 --- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
12520 +++ linux/fs/aufs/fstype.h 2013-07-06 13:20:47.750198454 +0200
12523 + * Copyright (C) 2005-2013 Junjiro R. Okajima
12525 + * This program, aufs is free software; you can redistribute it and/or modify
12526 + * it under the terms of the GNU General Public License as published by
12527 + * the Free Software Foundation; either version 2 of the License, or
12528 + * (at your option) any later version.
12530 + * This program is distributed in the hope that it will be useful,
12531 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12532 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12533 + * GNU General Public License for more details.
12535 + * You should have received a copy of the GNU General Public License
12536 + * along with this program; if not, write to the Free Software
12537 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12541 + * judging filesystem type
12544 +#ifndef __AUFS_FSTYPE_H__
12545 +#define __AUFS_FSTYPE_H__
12549 +#include <linux/fs.h>
12550 +#include <linux/magic.h>
12551 +#include <linux/romfs_fs.h>
12553 +static inline int au_test_aufs(struct super_block *sb)
12555 + return sb->s_magic == AUFS_SUPER_MAGIC;
12558 +static inline const char *au_sbtype(struct super_block *sb)
12560 + return sb->s_type->name;
12563 +static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
12565 +#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
12566 + return sb->s_magic == ROMFS_MAGIC;
12572 +static inline int au_test_romfs(struct super_block *sb __maybe_unused)
12574 +#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
12575 + return sb->s_magic == ISOFS_SUPER_MAGIC;
12581 +static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
12583 +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
12584 + return sb->s_magic == CRAMFS_MAGIC;
12589 +static inline int au_test_nfs(struct super_block *sb __maybe_unused)
12591 +#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
12592 + return sb->s_magic == NFS_SUPER_MAGIC;
12598 +static inline int au_test_fuse(struct super_block *sb __maybe_unused)
12600 +#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
12601 + return sb->s_magic == FUSE_SUPER_MAGIC;
12607 +static inline int au_test_xfs(struct super_block *sb __maybe_unused)
12609 +#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
12610 + return sb->s_magic == XFS_SB_MAGIC;
12616 +static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
12618 +#ifdef CONFIG_TMPFS
12619 + return sb->s_magic == TMPFS_MAGIC;
12625 +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
12627 +#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
12628 + return !strcmp(au_sbtype(sb), "ecryptfs");
12634 +static inline int au_test_smbfs(struct super_block *sb __maybe_unused)
12636 +#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE)
12637 + return sb->s_magic == SMB_SUPER_MAGIC;
12643 +static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
12645 +#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
12646 + return sb->s_magic == OCFS2_SUPER_MAGIC;
12652 +static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
12654 +#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
12655 + return sb->s_magic == DLMFS_MAGIC;
12661 +static inline int au_test_coda(struct super_block *sb __maybe_unused)
12663 +#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
12664 + return sb->s_magic == CODA_SUPER_MAGIC;
12670 +static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
12672 +#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
12673 + return sb->s_magic == V9FS_MAGIC;
12679 +static inline int au_test_ext4(struct super_block *sb __maybe_unused)
12681 +#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE)
12682 + return sb->s_magic == EXT4_SUPER_MAGIC;
12688 +static inline int au_test_sysv(struct super_block *sb __maybe_unused)
12690 +#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
12691 + return !strcmp(au_sbtype(sb), "sysv");
12697 +static inline int au_test_ramfs(struct super_block *sb)
12699 + return sb->s_magic == RAMFS_MAGIC;
12702 +static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
12704 +#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
12705 + return sb->s_magic == UBIFS_SUPER_MAGIC;
12711 +static inline int au_test_procfs(struct super_block *sb __maybe_unused)
12713 +#ifdef CONFIG_PROC_FS
12714 + return sb->s_magic == PROC_SUPER_MAGIC;
12720 +static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
12722 +#ifdef CONFIG_SYSFS
12723 + return sb->s_magic == SYSFS_MAGIC;
12729 +static inline int au_test_configfs(struct super_block *sb __maybe_unused)
12731 +#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
12732 + return sb->s_magic == CONFIGFS_MAGIC;
12738 +static inline int au_test_minix(struct super_block *sb __maybe_unused)
12740 +#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
12741 + return sb->s_magic == MINIX3_SUPER_MAGIC
12742 + || sb->s_magic == MINIX2_SUPER_MAGIC
12743 + || sb->s_magic == MINIX2_SUPER_MAGIC2
12744 + || sb->s_magic == MINIX_SUPER_MAGIC
12745 + || sb->s_magic == MINIX_SUPER_MAGIC2;
12751 +static inline int au_test_cifs(struct super_block *sb __maybe_unused)
12753 +#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
12754 + return sb->s_magic == CIFS_MAGIC_NUMBER;
12760 +static inline int au_test_fat(struct super_block *sb __maybe_unused)
12762 +#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
12763 + return sb->s_magic == MSDOS_SUPER_MAGIC;
12769 +static inline int au_test_msdos(struct super_block *sb)
12771 + return au_test_fat(sb);
12774 +static inline int au_test_vfat(struct super_block *sb)
12776 + return au_test_fat(sb);
12779 +static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
12781 +#ifdef CONFIG_SECURITYFS
12782 + return sb->s_magic == SECURITYFS_MAGIC;
12788 +static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
12790 +#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
12791 + return sb->s_magic == SQUASHFS_MAGIC;
12797 +static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
12799 +#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
12800 + return sb->s_magic == BTRFS_SUPER_MAGIC;
12806 +static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
12808 +#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
12809 + return sb->s_magic == XENFS_SUPER_MAGIC;
12815 +static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
12817 +#ifdef CONFIG_DEBUG_FS
12818 + return sb->s_magic == DEBUGFS_MAGIC;
12824 +static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
12826 +#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
12827 + return sb->s_magic == NILFS_SUPER_MAGIC;
12833 +static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
12835 +#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
12836 + return sb->s_magic == HFSPLUS_SUPER_MAGIC;
12842 +/* ---------------------------------------------------------------------- */
12844 + * they can't be an aufs branch.
12846 +static inline int au_test_fs_unsuppoted(struct super_block *sb)
12849 +#ifndef CONFIG_AUFS_BR_RAMFS
12850 + au_test_ramfs(sb) ||
12852 + au_test_procfs(sb)
12853 + || au_test_sysfs(sb)
12854 + || au_test_configfs(sb)
12855 + || au_test_debugfs(sb)
12856 + || au_test_securityfs(sb)
12857 + || au_test_xenfs(sb)
12858 + || au_test_ecryptfs(sb)
12859 + /* || !strcmp(au_sbtype(sb), "unionfs") */
12860 + || au_test_aufs(sb); /* will be supported in next version */
12863 +static inline int au_test_fs_remote(struct super_block *sb)
12865 + return !au_test_tmpfs(sb)
12866 +#ifdef CONFIG_AUFS_BR_RAMFS
12867 + && !au_test_ramfs(sb)
12869 + && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
12872 +/* ---------------------------------------------------------------------- */
12875 + * Note: these functions (below) are created after reading ->getattr() in all
12876 + * filesystems under linux/fs. it means we have to do so in every update...
12880 + * some filesystems require getattr to refresh the inode attributes before
12882 + * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
12883 + * and leave the work for d_revalidate()
12885 +static inline int au_test_fs_refresh_iattr(struct super_block *sb)
12887 + return au_test_nfs(sb)
12888 + || au_test_fuse(sb)
12889 + /* || au_test_smbfs(sb) */ /* untested */
12890 + /* || au_test_ocfs2(sb) */ /* untested */
12891 + /* || au_test_btrfs(sb) */ /* untested */
12892 + /* || au_test_coda(sb) */ /* untested */
12893 + /* || au_test_v9fs(sb) */ /* untested */
12898 + * filesystems which don't maintain i_size or i_blocks.
12900 +static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
12902 + return au_test_xfs(sb)
12903 + || au_test_btrfs(sb)
12904 + || au_test_ubifs(sb)
12905 + || au_test_hfsplus(sb) /* maintained, but incorrect */
12906 + /* || au_test_ext4(sb) */ /* untested */
12907 + /* || au_test_ocfs2(sb) */ /* untested */
12908 + /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
12909 + /* || au_test_sysv(sb) */ /* untested */
12910 + /* || au_test_minix(sb) */ /* untested */
12915 + * filesystems which don't store the correct value in some of their inode
12918 +static inline int au_test_fs_bad_iattr(struct super_block *sb)
12920 + return au_test_fs_bad_iattr_size(sb)
12921 + /* || au_test_cifs(sb) */ /* untested */
12922 + || au_test_fat(sb)
12923 + || au_test_msdos(sb)
12924 + || au_test_vfat(sb);
12927 +/* they don't check i_nlink in link(2) */
12928 +static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
12930 + return au_test_tmpfs(sb)
12931 +#ifdef CONFIG_AUFS_BR_RAMFS
12932 + || au_test_ramfs(sb)
12934 + || au_test_ubifs(sb)
12935 + || au_test_hfsplus(sb);
12939 + * filesystems which sets S_NOATIME and S_NOCMTIME.
12941 +static inline int au_test_fs_notime(struct super_block *sb)
12943 + return au_test_nfs(sb)
12944 + || au_test_fuse(sb)
12945 + || au_test_ubifs(sb)
12946 + /* || au_test_cifs(sb) */ /* untested */
12951 + * filesystems which requires replacing i_mapping.
12953 +static inline int au_test_fs_bad_mapping(struct super_block *sb)
12955 + return au_test_fuse(sb)
12956 + || au_test_ubifs(sb);
12959 +/* temporary support for i#1 in cramfs */
12960 +static inline int au_test_fs_unique_ino(struct inode *inode)
12962 + if (au_test_cramfs(inode->i_sb))
12963 + return inode->i_ino != 1;
12967 +/* ---------------------------------------------------------------------- */
12970 + * the filesystem where the xino files placed must support i/o after unlink and
12971 + * maintain i_size and i_blocks.
12973 +static inline int au_test_fs_bad_xino(struct super_block *sb)
12975 + return au_test_fs_remote(sb)
12976 + || au_test_fs_bad_iattr_size(sb)
12977 + /* don't want unnecessary work for xino */
12978 + || au_test_aufs(sb)
12979 + || au_test_ecryptfs(sb)
12980 + || au_test_nilfs(sb);
12983 +static inline int au_test_fs_trunc_xino(struct super_block *sb)
12985 + return au_test_tmpfs(sb)
12986 + || au_test_ramfs(sb);
12990 + * test if the @sb is real-readonly.
12992 +static inline int au_test_fs_rr(struct super_block *sb)
12994 + return au_test_squashfs(sb)
12995 + || au_test_iso9660(sb)
12996 + || au_test_cramfs(sb)
12997 + || au_test_romfs(sb);
13000 +#endif /* __KERNEL__ */
13001 +#endif /* __AUFS_FSTYPE_H__ */
13002 diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
13003 --- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
13004 +++ linux/fs/aufs/hfsnotify.c 2013-07-06 13:20:47.750198454 +0200
13007 + * Copyright (C) 2005-2013 Junjiro R. Okajima
13009 + * This program, aufs is free software; you can redistribute it and/or modify
13010 + * it under the terms of the GNU General Public License as published by
13011 + * the Free Software Foundation; either version 2 of the License, or
13012 + * (at your option) any later version.
13014 + * This program is distributed in the hope that it will be useful,
13015 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13016 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13017 + * GNU General Public License for more details.
13019 + * You should have received a copy of the GNU General Public License
13020 + * along with this program; if not, write to the Free Software
13021 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13025 + * fsnotify for the lower directories
13030 +/* FS_IN_IGNORED is unnecessary */
13031 +static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
13032 + | FS_CREATE | FS_EVENT_ON_CHILD);
13033 +static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
13034 +static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
13036 +static void au_hfsn_free_mark(struct fsnotify_mark *mark)
13038 + struct au_hnotify *hn = container_of(mark, struct au_hnotify,
13041 + au_cache_free_hnotify(hn);
13042 + smp_mb__before_atomic_dec();
13043 + if (atomic64_dec_and_test(&au_hfsn_ifree))
13044 + wake_up(&au_hfsn_wq);
13047 +static int au_hfsn_alloc(struct au_hinode *hinode)
13050 + struct au_hnotify *hn;
13051 + struct super_block *sb;
13052 + struct au_branch *br;
13053 + struct fsnotify_mark *mark;
13054 + aufs_bindex_t bindex;
13056 + hn = hinode->hi_notify;
13057 + sb = hn->hn_aufs_inode->i_sb;
13058 + bindex = au_br_index(sb, hinode->hi_id);
13059 + br = au_sbr(sb, bindex);
13060 + AuDebugOn(!br->br_hfsn);
13062 + mark = &hn->hn_mark;
13063 + fsnotify_init_mark(mark, au_hfsn_free_mark);
13064 + mark->mask = AuHfsnMask;
13066 + * by udba rename or rmdir, aufs assign a new inode to the known
13067 + * h_inode, so specify 1 to allow dups.
13069 + err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
13070 + /*mnt*/NULL, /*allow_dups*/1);
13071 + /* even if err */
13072 + fsnotify_put_mark(mark);
13077 +static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
13079 + struct fsnotify_mark *mark;
13080 + unsigned long long ull;
13081 + struct fsnotify_group *group;
13083 + ull = atomic64_inc_return(&au_hfsn_ifree);
13086 + mark = &hn->hn_mark;
13087 + spin_lock(&mark->lock);
13088 + group = mark->group;
13089 + fsnotify_get_group(group);
13090 + spin_unlock(&mark->lock);
13091 + fsnotify_destroy_mark(mark, group);
13092 + fsnotify_put_group(group);
13094 + /* free hn by myself */
13098 +/* ---------------------------------------------------------------------- */
13100 +static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
13102 + struct fsnotify_mark *mark;
13104 + mark = &hinode->hi_notify->hn_mark;
13105 + spin_lock(&mark->lock);
13107 + AuDebugOn(mark->mask & AuHfsnMask);
13108 + mark->mask |= AuHfsnMask;
13110 + AuDebugOn(!(mark->mask & AuHfsnMask));
13111 + mark->mask &= ~AuHfsnMask;
13113 + spin_unlock(&mark->lock);
13114 + /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
13117 +/* ---------------------------------------------------------------------- */
13119 +/* #define AuDbgHnotify */
13120 +#ifdef AuDbgHnotify
13121 +static char *au_hfsn_name(u32 mask)
13123 +#ifdef CONFIG_AUFS_DEBUG
13124 +#define test_ret(flag) \
13126 + if (mask & flag) \
13129 + test_ret(FS_ACCESS);
13130 + test_ret(FS_MODIFY);
13131 + test_ret(FS_ATTRIB);
13132 + test_ret(FS_CLOSE_WRITE);
13133 + test_ret(FS_CLOSE_NOWRITE);
13134 + test_ret(FS_OPEN);
13135 + test_ret(FS_MOVED_FROM);
13136 + test_ret(FS_MOVED_TO);
13137 + test_ret(FS_CREATE);
13138 + test_ret(FS_DELETE);
13139 + test_ret(FS_DELETE_SELF);
13140 + test_ret(FS_MOVE_SELF);
13141 + test_ret(FS_UNMOUNT);
13142 + test_ret(FS_Q_OVERFLOW);
13143 + test_ret(FS_IN_IGNORED);
13144 + test_ret(FS_IN_ISDIR);
13145 + test_ret(FS_IN_ONESHOT);
13146 + test_ret(FS_EVENT_ON_CHILD);
13155 +/* ---------------------------------------------------------------------- */
13157 +static void au_hfsn_free_group(struct fsnotify_group *group)
13159 + struct au_br_hfsnotify *hfsn = group->private;
13165 +static int au_hfsn_handle_event(struct fsnotify_group *group,
13166 + struct fsnotify_mark *inode_mark,
13167 + struct fsnotify_mark *vfsmount_mark,
13168 + struct fsnotify_event *event)
13171 + struct au_hnotify *hnotify;
13172 + struct inode *h_dir, *h_inode;
13174 + struct qstr h_child_qstr = QSTR_INIT(event->file_name, event->name_len);
13176 + AuDebugOn(event->data_type != FSNOTIFY_EVENT_INODE);
13179 + /* if FS_UNMOUNT happens, there must be another bug */
13180 + mask = event->mask;
13181 + AuDebugOn(mask & FS_UNMOUNT);
13182 + if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
13185 + h_dir = event->to_tell;
13186 + h_inode = event->inode;
13187 +#ifdef AuDbgHnotify
13189 + if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
13190 + || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
13191 + AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
13192 + h_dir->i_ino, mask, au_hfsn_name(mask),
13193 + AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
13194 + /* WARN_ON(1); */
13199 + AuDebugOn(!inode_mark);
13200 + hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
13201 + err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
13207 +/* isn't it waste to ask every registered 'group'? */
13208 +/* copied from linux/fs/notify/inotify/inotify_fsnotiry.c */
13209 +/* it should be exported to modules */
13210 +static bool au_hfsn_should_send_event(struct fsnotify_group *group,
13211 + struct inode *h_inode,
13212 + struct fsnotify_mark *inode_mark,
13213 + struct fsnotify_mark *vfsmount_mark,
13214 + __u32 mask, void *data, int data_type)
13216 + mask = (mask & ~FS_EVENT_ON_CHILD);
13217 + return inode_mark->mask & mask;
13220 +static struct fsnotify_ops au_hfsn_ops = {
13221 + .should_send_event = au_hfsn_should_send_event,
13222 + .handle_event = au_hfsn_handle_event,
13223 + .free_group_priv = au_hfsn_free_group
13226 +/* ---------------------------------------------------------------------- */
13228 +static void au_hfsn_fin_br(struct au_branch *br)
13230 + struct au_br_hfsnotify *hfsn;
13232 + hfsn = br->br_hfsn;
13234 + fsnotify_put_group(hfsn->hfsn_group);
13237 +static int au_hfsn_init_br(struct au_branch *br, int perm)
13240 + struct fsnotify_group *group;
13241 + struct au_br_hfsnotify *hfsn;
13244 + br->br_hfsn = NULL;
13245 + if (!au_br_hnotifyable(perm))
13249 + hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
13250 + if (unlikely(!hfsn))
13254 + group = fsnotify_alloc_group(&au_hfsn_ops);
13255 + if (IS_ERR(group)) {
13256 + err = PTR_ERR(group);
13257 + pr_err("fsnotify_alloc_group() failed, %d\n", err);
13261 + group->private = hfsn;
13262 + hfsn->hfsn_group = group;
13263 + br->br_hfsn = hfsn;
13264 + goto out; /* success */
13272 +static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
13277 + if (!br->br_hfsn)
13278 + err = au_hfsn_init_br(br, perm);
13283 +/* ---------------------------------------------------------------------- */
13285 +static void au_hfsn_fin(void)
13287 + AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
13288 + wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
13291 +const struct au_hnotify_op au_hnotify_op = {
13292 + .ctl = au_hfsn_ctl,
13293 + .alloc = au_hfsn_alloc,
13294 + .free = au_hfsn_free,
13296 + .fin = au_hfsn_fin,
13298 + .reset_br = au_hfsn_reset_br,
13299 + .fin_br = au_hfsn_fin_br,
13300 + .init_br = au_hfsn_init_br
13302 diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
13303 --- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
13304 +++ linux/fs/aufs/hfsplus.c 2013-07-06 13:20:47.750198454 +0200
13307 + * Copyright (C) 2010-2013 Junjiro R. Okajima
13309 + * This program, aufs is free software; you can redistribute it and/or modify
13310 + * it under the terms of the GNU General Public License as published by
13311 + * the Free Software Foundation; either version 2 of the License, or
13312 + * (at your option) any later version.
13314 + * This program is distributed in the hope that it will be useful,
13315 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13316 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13317 + * GNU General Public License for more details.
13319 + * You should have received a copy of the GNU General Public License
13320 + * along with this program; if not, write to the Free Software
13321 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13325 + * special support for filesystems which aqucires an inode mutex
13326 + * at final closing a file, eg, hfsplus.
13328 + * This trick is very simple and stupid, just to open the file before really
13329 + * neceeary open to tell hfsplus that this is not the final closing.
13330 + * The caller should call au_h_open_pre() after acquiring the inode mutex,
13331 + * and au_h_open_post() after releasing it.
13336 +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
13338 + struct file *h_file;
13339 + struct dentry *h_dentry;
13341 + h_dentry = au_h_dptr(dentry, bindex);
13342 + AuDebugOn(!h_dentry);
13343 + AuDebugOn(!h_dentry->d_inode);
13346 + if (au_test_hfsplus(h_dentry->d_sb)
13347 + && S_ISREG(h_dentry->d_inode->i_mode))
13348 + h_file = au_h_open(dentry, bindex,
13349 + O_RDONLY | O_NOATIME | O_LARGEFILE,
13354 +void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
13355 + struct file *h_file)
13359 + au_sbr_put(dentry->d_sb, bindex);
13362 diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
13363 --- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
13364 +++ linux/fs/aufs/hnotify.c 2013-07-30 22:42:55.842946719 +0200
13367 + * Copyright (C) 2005-2013 Junjiro R. Okajima
13369 + * This program, aufs is free software; you can redistribute it and/or modify
13370 + * it under the terms of the GNU General Public License as published by
13371 + * the Free Software Foundation; either version 2 of the License, or
13372 + * (at your option) any later version.
13374 + * This program is distributed in the hope that it will be useful,
13375 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13376 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13377 + * GNU General Public License for more details.
13379 + * You should have received a copy of the GNU General Public License
13380 + * along with this program; if not, write to the Free Software
13381 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13385 + * abstraction to notify the direct changes on lower directories
13390 +int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
13393 + struct au_hnotify *hn;
13396 + hn = au_cache_alloc_hnotify();
13398 + hn->hn_aufs_inode = inode;
13399 + hinode->hi_notify = hn;
13400 + err = au_hnotify_op.alloc(hinode);
13402 + if (unlikely(err)) {
13403 + hinode->hi_notify = NULL;
13404 + au_cache_free_hnotify(hn);
13406 + * The upper dir was removed by udba, but the same named
13407 + * dir left. In this case, aufs assignes a new inode
13408 + * number and set the monitor again.
13409 + * For the lower dir, the old monitnor is still left.
13411 + if (err == -EEXIST)
13420 +void au_hn_free(struct au_hinode *hinode)
13422 + struct au_hnotify *hn;
13424 + hn = hinode->hi_notify;
13426 + hinode->hi_notify = NULL;
13427 + if (au_hnotify_op.free(hinode, hn))
13428 + au_cache_free_hnotify(hn);
13432 +/* ---------------------------------------------------------------------- */
13434 +void au_hn_ctl(struct au_hinode *hinode, int do_set)
13436 + if (hinode->hi_notify)
13437 + au_hnotify_op.ctl(hinode, do_set);
13440 +void au_hn_reset(struct inode *inode, unsigned int flags)
13442 + aufs_bindex_t bindex, bend;
13443 + struct inode *hi;
13444 + struct dentry *iwhdentry;
13446 + bend = au_ibend(inode);
13447 + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
13448 + hi = au_h_iptr(inode, bindex);
13452 + /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
13453 + iwhdentry = au_hi_wh(inode, bindex);
13457 + au_set_h_iptr(inode, bindex, NULL, 0);
13458 + au_set_h_iptr(inode, bindex, au_igrab(hi),
13459 + flags & ~AuHi_XINO);
13462 + /* mutex_unlock(&hi->i_mutex); */
13466 +/* ---------------------------------------------------------------------- */
13468 +static int hn_xino(struct inode *inode, struct inode *h_inode)
13471 + aufs_bindex_t bindex, bend, bfound, bstart;
13472 + struct inode *h_i;
13475 + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
13476 + pr_warn("branch root dir was changed\n");
13481 + bend = au_ibend(inode);
13482 + bstart = au_ibstart(inode);
13483 +#if 0 /* reserved for future use */
13484 + if (bindex == bend) {
13485 + /* keep this ino in rename case */
13489 + for (bindex = bstart; bindex <= bend; bindex++)
13490 + if (au_h_iptr(inode, bindex) == h_inode) {
13497 + for (bindex = bstart; bindex <= bend; bindex++) {
13498 + h_i = au_h_iptr(inode, bindex);
13502 + err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
13503 + /* ignore this error */
13504 + /* bad action? */
13507 + /* children inode number will be broken */
13514 +static int hn_gen_tree(struct dentry *dentry)
13516 + int err, i, j, ndentry;
13517 + struct au_dcsub_pages dpages;
13518 + struct au_dpage *dpage;
13519 + struct dentry **dentries;
13521 + err = au_dpages_init(&dpages, GFP_NOFS);
13522 + if (unlikely(err))
13524 + err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
13525 + if (unlikely(err))
13528 + for (i = 0; i < dpages.ndpage; i++) {
13529 + dpage = dpages.dpages + i;
13530 + dentries = dpage->dentries;
13531 + ndentry = dpage->ndentry;
13532 + for (j = 0; j < ndentry; j++) {
13533 + struct dentry *d;
13541 + /* todo: reset children xino?
13542 + cached children only? */
13543 + au_iigen_dec(d->d_inode);
13548 + au_dpages_free(&dpages);
13551 + /* discard children */
13552 + dentry_unhash(dentry);
13560 + * return 0 if processed.
13562 +static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
13563 + const unsigned int isdir)
13566 + struct dentry *d;
13567 + struct qstr *dname;
13570 + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
13571 + pr_warn("branch root dir was changed\n");
13577 + AuDebugOn(!name);
13578 + au_iigen_dec(inode);
13579 + spin_lock(&inode->i_lock);
13580 + hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
13581 + spin_lock(&d->d_lock);
13582 + dname = &d->d_name;
13583 + if (dname->len != nlen
13584 + && memcmp(dname->name, name, nlen)) {
13585 + spin_unlock(&d->d_lock);
13590 + spin_unlock(&d->d_lock);
13593 + spin_unlock(&inode->i_lock);
13595 + au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
13596 + d = d_find_alias(inode);
13598 + au_iigen_dec(inode);
13602 + spin_lock(&d->d_lock);
13603 + dname = &d->d_name;
13604 + if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
13605 + spin_unlock(&d->d_lock);
13606 + err = hn_gen_tree(d);
13607 + spin_lock(&d->d_lock);
13609 + spin_unlock(&d->d_lock);
13618 +static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
13621 + struct inode *inode;
13623 + inode = dentry->d_inode;
13624 + if (IS_ROOT(dentry)
13625 + /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
13627 + pr_warn("branch root dir was changed\n");
13633 + au_digen_dec(dentry);
13635 + au_iigen_dec(inode);
13637 + au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
13639 + err = hn_gen_tree(dentry);
13646 +/* ---------------------------------------------------------------------- */
13648 +/* hnotify job flags */
13649 +#define AuHnJob_XINO0 1
13650 +#define AuHnJob_GEN (1 << 1)
13651 +#define AuHnJob_DIRENT (1 << 2)
13652 +#define AuHnJob_ISDIR (1 << 3)
13653 +#define AuHnJob_TRYXINO0 (1 << 4)
13654 +#define AuHnJob_MNTPNT (1 << 5)
13655 +#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
13656 +#define au_fset_hnjob(flags, name) \
13657 + do { (flags) |= AuHnJob_##name; } while (0)
13658 +#define au_fclr_hnjob(flags, name) \
13659 + do { (flags) &= ~AuHnJob_##name; } while (0)
13667 +struct au_hnotify_args {
13668 + struct inode *h_dir, *dir, *h_child_inode;
13670 + unsigned int flags[AuHnLast];
13671 + unsigned int h_child_nlen;
13672 + char h_child_name[];
13675 +struct hn_job_args {
13676 + unsigned int flags;
13677 + struct inode *inode, *h_inode, *dir, *h_dir;
13678 + struct dentry *dentry;
13683 +static int hn_job(struct hn_job_args *a)
13685 + const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
13688 + if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
13689 + hn_xino(a->inode, a->h_inode); /* ignore this error */
13691 + if (au_ftest_hnjob(a->flags, TRYXINO0)
13694 + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
13695 + if (!a->h_inode->i_nlink)
13696 + hn_xino(a->inode, a->h_inode); /* ignore this error */
13697 + mutex_unlock(&a->h_inode->i_mutex);
13700 + /* make the generation obsolete */
13701 + if (au_ftest_hnjob(a->flags, GEN)) {
13704 + err = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
13706 + if (err && a->dentry)
13707 + hn_gen_by_name(a->dentry, isdir);
13708 + /* ignore this error */
13711 + /* make dir entries obsolete */
13712 + if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
13713 + struct au_vdir *vdir;
13715 + vdir = au_ivdir(a->inode);
13717 + vdir->vd_jiffy = 0;
13718 + /* IMustLock(a->inode); */
13719 + /* a->inode->i_version++; */
13722 + /* can do nothing but warn */
13723 + if (au_ftest_hnjob(a->flags, MNTPNT)
13725 + && d_mountpoint(a->dentry))
13726 + pr_warn("mount-point %.*s is removed or renamed\n",
13727 + AuDLNPair(a->dentry));
13732 +/* ---------------------------------------------------------------------- */
13734 +static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
13735 + struct inode *dir)
13737 + struct dentry *dentry, *d, *parent;
13738 + struct qstr *dname;
13740 + parent = d_find_alias(dir);
13745 + spin_lock(&parent->d_lock);
13746 + list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
13747 + /* AuDbg("%.*s\n", AuDLNPair(d)); */
13748 + spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
13749 + dname = &d->d_name;
13750 + if (dname->len != nlen || memcmp(dname->name, name, nlen))
13751 + goto cont_unlock;
13755 + goto cont_unlock;
13756 + if (d->d_count) {
13757 + dentry = dget_dlock(d);
13758 + spin_unlock(&d->d_lock);
13763 + spin_unlock(&d->d_lock);
13765 + spin_unlock(&parent->d_lock);
13769 + di_write_lock_child(dentry);
13774 +static struct inode *lookup_wlock_by_ino(struct super_block *sb,
13775 + aufs_bindex_t bindex, ino_t h_ino)
13777 + struct inode *inode;
13782 + err = au_xino_read(sb, bindex, h_ino, &ino);
13784 + inode = ilookup(sb, ino);
13788 + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
13789 + pr_warn("wrong root branch\n");
13795 + ii_write_lock_child(inode);
13801 +static void au_hn_bh(void *_args)
13803 + struct au_hnotify_args *a = _args;
13804 + struct super_block *sb;
13805 + aufs_bindex_t bindex, bend, bfound;
13806 + unsigned char xino, try_iput;
13808 + struct inode *inode;
13810 + struct hn_job_args args;
13811 + struct dentry *dentry;
13812 + struct au_sbinfo *sbinfo;
13814 + AuDebugOn(!_args);
13815 + AuDebugOn(!a->h_dir);
13816 + AuDebugOn(!a->dir);
13817 + AuDebugOn(!a->mask);
13818 + AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
13819 + a->mask, a->dir->i_ino, a->h_dir->i_ino,
13820 + a->h_child_inode ? a->h_child_inode->i_ino : 0);
13825 + * do not lock a->dir->i_mutex here
13826 + * because of d_revalidate() may cause a deadlock.
13828 + sb = a->dir->i_sb;
13830 + sbinfo = au_sbi(sb);
13831 + AuDebugOn(!sbinfo);
13832 + si_write_lock(sb, AuLock_NOPLMW);
13834 + ii_read_lock_parent(a->dir);
13836 + bend = au_ibend(a->dir);
13837 + for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
13838 + if (au_h_iptr(a->dir, bindex) == a->h_dir) {
13842 + ii_read_unlock(a->dir);
13843 + if (unlikely(bfound < 0))
13846 + xino = !!au_opt_test(au_mntflags(sb), XINO);
13848 + if (a->h_child_inode)
13849 + h_ino = a->h_child_inode->i_ino;
13851 + if (a->h_child_nlen
13852 + && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
13853 + || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
13854 + dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
13858 + inode = dentry->d_inode;
13859 + if (xino && !inode && h_ino
13860 + && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
13861 + || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
13862 + || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
13863 + inode = lookup_wlock_by_ino(sb, bfound, h_ino);
13867 + args.flags = a->flags[AuHn_CHILD];
13868 + args.dentry = dentry;
13869 + args.inode = inode;
13870 + args.h_inode = a->h_child_inode;
13871 + args.dir = a->dir;
13872 + args.h_dir = a->h_dir;
13873 + args.h_name = a->h_child_name;
13874 + args.h_nlen = a->h_child_nlen;
13875 + err = hn_job(&args);
13877 + if (au_di(dentry))
13878 + di_write_unlock(dentry);
13881 + if (inode && try_iput) {
13882 + ii_write_unlock(inode);
13886 + ii_write_lock_parent(a->dir);
13887 + args.flags = a->flags[AuHn_PARENT];
13888 + args.dentry = NULL;
13889 + args.inode = a->dir;
13890 + args.h_inode = a->h_dir;
13892 + args.h_dir = NULL;
13893 + args.h_name = NULL;
13895 + err = hn_job(&args);
13896 + ii_write_unlock(a->dir);
13899 + iput(a->h_child_inode);
13902 + si_write_unlock(sb);
13903 + au_nwt_done(&sbinfo->si_nowait);
13907 +/* ---------------------------------------------------------------------- */
13909 +int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
13910 + struct qstr *h_child_qstr, struct inode *h_child_inode)
13913 + unsigned int flags[AuHnLast], f;
13914 + unsigned char isdir, isroot, wh;
13915 + struct inode *dir;
13916 + struct au_hnotify_args *args;
13917 + char *p, *h_child_name;
13920 + AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
13921 + dir = igrab(hnotify->hn_aufs_inode);
13925 + isroot = (dir->i_ino == AUFS_ROOT_INO);
13927 + h_child_name = (void *)h_child_qstr->name;
13928 + len = h_child_qstr->len;
13929 + if (h_child_name) {
13930 + if (len > AUFS_WH_PFX_LEN
13931 + && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
13932 + h_child_name += AUFS_WH_PFX_LEN;
13933 + len -= AUFS_WH_PFX_LEN;
13939 + if (h_child_inode)
13940 + isdir = !!S_ISDIR(h_child_inode->i_mode);
13941 + flags[AuHn_PARENT] = AuHnJob_ISDIR;
13942 + flags[AuHn_CHILD] = 0;
13944 + flags[AuHn_CHILD] = AuHnJob_ISDIR;
13945 + au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
13946 + au_fset_hnjob(flags[AuHn_CHILD], GEN);
13947 + switch (mask & FS_EVENTS_POSS_ON_CHILD) {
13948 + case FS_MOVED_FROM:
13949 + case FS_MOVED_TO:
13950 + au_fset_hnjob(flags[AuHn_CHILD], XINO0);
13951 + au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
13954 + AuDebugOn(!h_child_name || !h_child_inode);
13959 + * aufs never be able to get this child inode.
13960 + * revalidation should be in d_revalidate()
13961 + * by checking i_nlink, i_generation or d_unhashed().
13963 + AuDebugOn(!h_child_name);
13964 + au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
13965 + au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
13973 + h_child_inode = NULL;
13976 + /* iput() and kfree() will be called in au_hnotify() */
13977 + args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
13978 + if (unlikely(!args)) {
13979 + AuErr1("no memory\n");
13983 + args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
13984 + args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
13985 + args->mask = mask;
13987 + args->h_dir = igrab(h_dir);
13988 + if (h_child_inode)
13989 + h_child_inode = igrab(h_child_inode); /* can be NULL */
13990 + args->h_child_inode = h_child_inode;
13991 + args->h_child_nlen = len;
13993 + p = (void *)args;
13994 + p += sizeof(*args);
13995 + memcpy(p, h_child_name, len);
14000 + if (!dir->i_nlink)
14002 + err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
14003 + if (unlikely(err)) {
14004 + pr_err("wkq %d\n", err);
14005 + iput(args->h_child_inode);
14006 + iput(args->h_dir);
14015 +/* ---------------------------------------------------------------------- */
14017 +int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
14021 + AuDebugOn(!(udba & AuOptMask_UDBA));
14024 + if (au_hnotify_op.reset_br)
14025 + err = au_hnotify_op.reset_br(udba, br, perm);
14030 +int au_hnotify_init_br(struct au_branch *br, int perm)
14035 + if (au_hnotify_op.init_br)
14036 + err = au_hnotify_op.init_br(br, perm);
14041 +void au_hnotify_fin_br(struct au_branch *br)
14043 + if (au_hnotify_op.fin_br)
14044 + au_hnotify_op.fin_br(br);
14047 +static void au_hn_destroy_cache(void)
14049 + kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
14050 + au_cachep[AuCache_HNOTIFY] = NULL;
14053 +int __init au_hnotify_init(void)
14058 + au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
14059 + if (au_cachep[AuCache_HNOTIFY]) {
14061 + if (au_hnotify_op.init)
14062 + err = au_hnotify_op.init();
14063 + if (unlikely(err))
14064 + au_hn_destroy_cache();
14070 +void au_hnotify_fin(void)
14072 + if (au_hnotify_op.fin)
14073 + au_hnotify_op.fin();
14074 + /* cf. au_cache_fin() */
14075 + if (au_cachep[AuCache_HNOTIFY])
14076 + au_hn_destroy_cache();
14078 diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
14079 --- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
14080 +++ linux/fs/aufs/iinfo.c 2013-07-06 13:20:47.750198454 +0200
14083 + * Copyright (C) 2005-2013 Junjiro R. Okajima
14085 + * This program, aufs is free software; you can redistribute it and/or modify
14086 + * it under the terms of the GNU General Public License as published by
14087 + * the Free Software Foundation; either version 2 of the License, or
14088 + * (at your option) any later version.
14090 + * This program is distributed in the hope that it will be useful,
14091 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14092 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14093 + * GNU General Public License for more details.
14095 + * You should have received a copy of the GNU General Public License
14096 + * along with this program; if not, write to the Free Software
14097 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14101 + * inode private data
14106 +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
14108 + struct inode *h_inode;
14110 + IiMustAnyLock(inode);
14112 + h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
14113 + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14117 +/* todo: hard/soft set? */
14118 +void au_hiput(struct au_hinode *hinode)
14120 + au_hn_free(hinode);
14121 + dput(hinode->hi_whdentry);
14122 + iput(hinode->hi_inode);
14125 +unsigned int au_hi_flags(struct inode *inode, int isdir)
14127 + unsigned int flags;
14128 + const unsigned int mnt_flags = au_mntflags(inode->i_sb);
14131 + if (au_opt_test(mnt_flags, XINO))
14132 + au_fset_hi(flags, XINO);
14133 + if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
14134 + au_fset_hi(flags, HNOTIFY);
14138 +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
14139 + struct inode *h_inode, unsigned int flags)
14141 + struct au_hinode *hinode;
14142 + struct inode *hi;
14143 + struct au_iinfo *iinfo = au_ii(inode);
14145 + IiMustWriteLock(inode);
14147 + hinode = iinfo->ii_hinode + bindex;
14148 + hi = hinode->hi_inode;
14149 + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14152 + au_hiput(hinode);
14153 + hinode->hi_inode = h_inode;
14156 + struct super_block *sb = inode->i_sb;
14157 + struct au_branch *br;
14159 + AuDebugOn(inode->i_mode
14160 + && (h_inode->i_mode & S_IFMT)
14161 + != (inode->i_mode & S_IFMT));
14162 + if (bindex == iinfo->ii_bstart)
14163 + au_cpup_igen(inode, h_inode);
14164 + br = au_sbr(sb, bindex);
14165 + hinode->hi_id = br->br_id;
14166 + if (au_ftest_hi(flags, XINO)) {
14167 + err = au_xino_write(sb, bindex, h_inode->i_ino,
14169 + if (unlikely(err))
14170 + AuIOErr1("failed au_xino_write() %d\n", err);
14173 + if (au_ftest_hi(flags, HNOTIFY)
14174 + && au_br_hnotifyable(br->br_perm)) {
14175 + err = au_hn_alloc(hinode, inode);
14176 + if (unlikely(err))
14177 + AuIOErr1("au_hn_alloc() %d\n", err);
14182 +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
14183 + struct dentry *h_wh)
14185 + struct au_hinode *hinode;
14187 + IiMustWriteLock(inode);
14189 + hinode = au_ii(inode)->ii_hinode + bindex;
14190 + AuDebugOn(hinode->hi_whdentry);
14191 + hinode->hi_whdentry = h_wh;
14194 +void au_update_iigen(struct inode *inode, int half)
14196 + struct au_iinfo *iinfo;
14197 + struct au_iigen *iigen;
14198 + unsigned int sigen;
14200 + sigen = au_sigen(inode->i_sb);
14201 + iinfo = au_ii(inode);
14202 + iigen = &iinfo->ii_generation;
14203 + spin_lock(&iinfo->ii_genspin);
14204 + iigen->ig_generation = sigen;
14206 + au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
14208 + au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
14209 + spin_unlock(&iinfo->ii_genspin);
14212 +/* it may be called at remount time, too */
14213 +void au_update_ibrange(struct inode *inode, int do_put_zero)
14215 + struct au_iinfo *iinfo;
14216 + aufs_bindex_t bindex, bend;
14218 + iinfo = au_ii(inode);
14222 + IiMustWriteLock(inode);
14224 + if (do_put_zero && iinfo->ii_bstart >= 0) {
14225 + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14227 + struct inode *h_i;
14229 + h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
14230 + if (h_i && !h_i->i_nlink)
14231 + au_set_h_iptr(inode, bindex, NULL, 0);
14235 + iinfo->ii_bstart = -1;
14236 + iinfo->ii_bend = -1;
14237 + bend = au_sbend(inode->i_sb);
14238 + for (bindex = 0; bindex <= bend; bindex++)
14239 + if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14240 + iinfo->ii_bstart = bindex;
14243 + if (iinfo->ii_bstart >= 0)
14244 + for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
14245 + if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14246 + iinfo->ii_bend = bindex;
14249 + AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
14252 +/* ---------------------------------------------------------------------- */
14254 +void au_icntnr_init_once(void *_c)
14256 + struct au_icntnr *c = _c;
14257 + struct au_iinfo *iinfo = &c->iinfo;
14258 + static struct lock_class_key aufs_ii;
14260 + spin_lock_init(&iinfo->ii_genspin);
14261 + au_rw_init(&iinfo->ii_rwsem);
14262 + au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
14263 + inode_init_once(&c->vfs_inode);
14266 +int au_iinfo_init(struct inode *inode)
14268 + struct au_iinfo *iinfo;
14269 + struct super_block *sb;
14272 + sb = inode->i_sb;
14273 + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
14274 + nbr = au_sbend(sb) + 1;
14275 + if (unlikely(nbr <= 0))
14277 + iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
14278 + if (iinfo->ii_hinode) {
14279 + au_ninodes_inc(sb);
14280 + for (i = 0; i < nbr; i++)
14281 + iinfo->ii_hinode[i].hi_id = -1;
14283 + iinfo->ii_generation.ig_generation = au_sigen(sb);
14284 + iinfo->ii_bstart = -1;
14285 + iinfo->ii_bend = -1;
14286 + iinfo->ii_vdir = NULL;
14292 +int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
14295 + struct au_hinode *hip;
14297 + AuRwMustWriteLock(&iinfo->ii_rwsem);
14300 + sz = sizeof(*hip) * (iinfo->ii_bend + 1);
14302 + sz = sizeof(*hip);
14303 + hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
14305 + iinfo->ii_hinode = hip;
14312 +void au_iinfo_fin(struct inode *inode)
14314 + struct au_iinfo *iinfo;
14315 + struct au_hinode *hi;
14316 + struct super_block *sb;
14317 + aufs_bindex_t bindex, bend;
14318 + const unsigned char unlinked = !inode->i_nlink;
14320 + iinfo = au_ii(inode);
14321 + /* bad_inode case */
14325 + sb = inode->i_sb;
14326 + au_ninodes_dec(sb);
14327 + if (si_pid_test(sb))
14328 + au_xino_delete_inode(inode, unlinked);
14331 + * it is safe to hide the dependency between sbinfo and
14335 + si_noflush_read_lock(sb);
14336 + au_xino_delete_inode(inode, unlinked);
14337 + si_read_unlock(sb);
14341 + if (iinfo->ii_vdir)
14342 + au_vdir_free(iinfo->ii_vdir);
14344 + bindex = iinfo->ii_bstart;
14345 + if (bindex >= 0) {
14346 + hi = iinfo->ii_hinode + bindex;
14347 + bend = iinfo->ii_bend;
14348 + while (bindex++ <= bend) {
14349 + if (hi->hi_inode)
14354 + kfree(iinfo->ii_hinode);
14355 + iinfo->ii_hinode = NULL;
14356 + AuRwDestroy(&iinfo->ii_rwsem);
14358 diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
14359 --- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
14360 +++ linux/fs/aufs/inode.c 2013-07-06 13:20:47.750198454 +0200
14363 + * Copyright (C) 2005-2013 Junjiro R. Okajima
14365 + * This program, aufs is free software; you can redistribute it and/or modify
14366 + * it under the terms of the GNU General Public License as published by
14367 + * the Free Software Foundation; either version 2 of the License, or
14368 + * (at your option) any later version.
14370 + * This program is distributed in the hope that it will be useful,
14371 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14372 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14373 + * GNU General Public License for more details.
14375 + * You should have received a copy of the GNU General Public License
14376 + * along with this program; if not, write to the Free Software
14377 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14381 + * inode functions
14386 +struct inode *au_igrab(struct inode *inode)
14389 + AuDebugOn(!atomic_read(&inode->i_count));
14395 +static void au_refresh_hinode_attr(struct inode *inode, int do_version)
14397 + au_cpup_attr_all(inode, /*force*/0);
14398 + au_update_iigen(inode, /*half*/1);
14400 + inode->i_version++;
14403 +static int au_ii_refresh(struct inode *inode, int *update)
14407 + aufs_bindex_t bindex, new_bindex;
14408 + struct super_block *sb;
14409 + struct au_iinfo *iinfo;
14410 + struct au_hinode *p, *q, tmp;
14412 + IiMustWriteLock(inode);
14415 + sb = inode->i_sb;
14416 + type = inode->i_mode & S_IFMT;
14417 + iinfo = au_ii(inode);
14418 + err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
14419 + if (unlikely(err))
14422 + AuDebugOn(iinfo->ii_bstart < 0);
14423 + p = iinfo->ii_hinode + iinfo->ii_bstart;
14424 + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14426 + if (!p->hi_inode)
14429 + AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
14430 + new_bindex = au_br_index(sb, p->hi_id);
14431 + if (new_bindex == bindex)
14434 + if (new_bindex < 0) {
14437 + p->hi_inode = NULL;
14441 + if (new_bindex < iinfo->ii_bstart)
14442 + iinfo->ii_bstart = new_bindex;
14443 + if (iinfo->ii_bend < new_bindex)
14444 + iinfo->ii_bend = new_bindex;
14445 + /* swap two lower inode, and loop again */
14446 + q = iinfo->ii_hinode + new_bindex;
14450 + if (tmp.hi_inode) {
14455 + au_update_ibrange(inode, /*do_put_zero*/0);
14456 + e = au_dy_irefresh(inode);
14457 + if (unlikely(e && !err))
14465 +int au_refresh_hinode_self(struct inode *inode)
14469 + err = au_ii_refresh(inode, &update);
14471 + au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
14477 +int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
14479 + int err, e, update;
14480 + unsigned int flags;
14482 + aufs_bindex_t bindex, bend;
14483 + unsigned char isdir;
14484 + struct au_hinode *p;
14485 + struct au_iinfo *iinfo;
14487 + err = au_ii_refresh(inode, &update);
14488 + if (unlikely(err))
14492 + iinfo = au_ii(inode);
14493 + p = iinfo->ii_hinode + iinfo->ii_bstart;
14494 + mode = (inode->i_mode & S_IFMT);
14495 + isdir = S_ISDIR(mode);
14496 + flags = au_hi_flags(inode, isdir);
14497 + bend = au_dbend(dentry);
14498 + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
14499 + struct inode *h_i;
14500 + struct dentry *h_d;
14502 + h_d = au_h_dptr(dentry, bindex);
14503 + if (!h_d || !h_d->d_inode)
14506 + AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
14507 + if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
14508 + h_i = au_h_iptr(inode, bindex);
14510 + if (h_i == h_d->d_inode)
14516 + if (bindex < iinfo->ii_bstart)
14517 + iinfo->ii_bstart = bindex;
14518 + if (iinfo->ii_bend < bindex)
14519 + iinfo->ii_bend = bindex;
14520 + au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
14523 + au_update_ibrange(inode, /*do_put_zero*/0);
14524 + e = au_dy_irefresh(inode);
14525 + if (unlikely(e && !err))
14528 + au_refresh_hinode_attr(inode, update && isdir);
14535 +static int set_inode(struct inode *inode, struct dentry *dentry)
14538 + unsigned int flags;
14540 + aufs_bindex_t bindex, bstart, btail;
14541 + unsigned char isdir;
14542 + struct dentry *h_dentry;
14543 + struct inode *h_inode;
14544 + struct au_iinfo *iinfo;
14546 + IiMustWriteLock(inode);
14550 + bstart = au_dbstart(dentry);
14551 + h_inode = au_h_dptr(dentry, bstart)->d_inode;
14552 + mode = h_inode->i_mode;
14553 + switch (mode & S_IFMT) {
14555 + btail = au_dbtail(dentry);
14556 + inode->i_op = &aufs_iop;
14557 + inode->i_fop = &aufs_file_fop;
14558 + err = au_dy_iaop(inode, bstart, h_inode);
14559 + if (unlikely(err))
14564 + btail = au_dbtaildir(dentry);
14565 + inode->i_op = &aufs_dir_iop;
14566 + inode->i_fop = &aufs_dir_fop;
14569 + btail = au_dbtail(dentry);
14570 + inode->i_op = &aufs_symlink_iop;
14576 + btail = au_dbtail(dentry);
14577 + inode->i_op = &aufs_iop;
14578 + au_init_special_fop(inode, mode, h_inode->i_rdev);
14581 + AuIOErr("Unknown file type 0%o\n", mode);
14586 + /* do not set hnotify for whiteouted dirs (SHWH mode) */
14587 + flags = au_hi_flags(inode, isdir);
14588 + if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
14589 + && au_ftest_hi(flags, HNOTIFY)
14590 + && dentry->d_name.len > AUFS_WH_PFX_LEN
14591 + && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
14592 + au_fclr_hi(flags, HNOTIFY);
14593 + iinfo = au_ii(inode);
14594 + iinfo->ii_bstart = bstart;
14595 + iinfo->ii_bend = btail;
14596 + for (bindex = bstart; bindex <= btail; bindex++) {
14597 + h_dentry = au_h_dptr(dentry, bindex);
14599 + au_set_h_iptr(inode, bindex,
14600 + au_igrab(h_dentry->d_inode), flags);
14602 + au_cpup_attr_all(inode, /*force*/1);
14609 + * successful returns with iinfo write_locked
14611 + * zero: success, matched
14612 + * plus: no error, but unmatched
14614 +static int reval_inode(struct inode *inode, struct dentry *dentry)
14617 + unsigned int gen;
14618 + struct au_iigen iigen;
14619 + aufs_bindex_t bindex, bend;
14620 + struct inode *h_inode, *h_dinode;
14623 + * before this function, if aufs got any iinfo lock, it must be only
14624 + * one, the parent dir.
14625 + * it can happen by UDBA and the obsoleted inode number.
14628 + if (unlikely(inode->i_ino == parent_ino(dentry)))
14632 + ii_write_lock_new_child(inode);
14633 + h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
14634 + bend = au_ibend(inode);
14635 + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14636 + h_inode = au_h_iptr(inode, bindex);
14637 + if (!h_inode || h_inode != h_dinode)
14641 + gen = au_iigen(inode, &iigen);
14642 + if (gen == au_digen(dentry)
14643 + && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
14646 + /* fully refresh inode using dentry */
14647 + err = au_refresh_hinode(inode, dentry);
14649 + au_update_iigen(inode, /*half*/0);
14653 + if (unlikely(err))
14654 + ii_write_unlock(inode);
14659 +int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14660 + unsigned int d_type, ino_t *ino)
14663 + struct mutex *mtx;
14665 + /* prevent hardlinked inode number from race condition */
14667 + if (d_type != DT_DIR) {
14668 + mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
14671 + err = au_xino_read(sb, bindex, h_ino, ino);
14672 + if (unlikely(err))
14677 + *ino = au_xino_new_ino(sb);
14678 + if (unlikely(!*ino))
14680 + err = au_xino_write(sb, bindex, h_ino, *ino);
14681 + if (unlikely(err))
14687 + mutex_unlock(mtx);
14691 +/* successful returns with iinfo write_locked */
14692 +/* todo: return with unlocked? */
14693 +struct inode *au_new_inode(struct dentry *dentry, int must_new)
14695 + struct inode *inode, *h_inode;
14696 + struct dentry *h_dentry;
14697 + struct super_block *sb;
14698 + struct mutex *mtx;
14699 + ino_t h_ino, ino;
14701 + aufs_bindex_t bstart;
14703 + sb = dentry->d_sb;
14704 + bstart = au_dbstart(dentry);
14705 + h_dentry = au_h_dptr(dentry, bstart);
14706 + h_inode = h_dentry->d_inode;
14707 + h_ino = h_inode->i_ino;
14710 + * stop 'race'-ing between hardlinks under different
14714 + if (!S_ISDIR(h_inode->i_mode))
14715 + mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
14720 + err = au_xino_read(sb, bstart, h_ino, &ino);
14721 + inode = ERR_PTR(err);
14722 + if (unlikely(err))
14726 + ino = au_xino_new_ino(sb);
14727 + if (unlikely(!ino)) {
14728 + inode = ERR_PTR(-EIO);
14733 + AuDbg("i%lu\n", (unsigned long)ino);
14734 + inode = au_iget_locked(sb, ino);
14735 + err = PTR_ERR(inode);
14736 + if (IS_ERR(inode))
14739 + AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
14740 + if (inode->i_state & I_NEW) {
14741 + /* verbose coding for lock class name */
14742 + if (unlikely(S_ISLNK(h_inode->i_mode)))
14743 + au_rw_class(&au_ii(inode)->ii_rwsem,
14744 + au_lc_key + AuLcSymlink_IIINFO);
14745 + else if (unlikely(S_ISDIR(h_inode->i_mode)))
14746 + au_rw_class(&au_ii(inode)->ii_rwsem,
14747 + au_lc_key + AuLcDir_IIINFO);
14748 + else /* likely */
14749 + au_rw_class(&au_ii(inode)->ii_rwsem,
14750 + au_lc_key + AuLcNonDir_IIINFO);
14752 + ii_write_lock_new_child(inode);
14753 + err = set_inode(inode, dentry);
14755 + unlock_new_inode(inode);
14756 + goto out; /* success */
14760 + * iget_failed() calls iput(), but we need to call
14761 + * ii_write_unlock() after iget_failed(). so dirty hack for
14764 + atomic_inc(&inode->i_count);
14765 + iget_failed(inode);
14766 + ii_write_unlock(inode);
14767 + au_xino_write(sb, bstart, h_ino, /*ino*/0);
14768 + /* ignore this error */
14770 + } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
14772 + * horrible race condition between lookup, readdir and copyup
14773 + * (or something).
14776 + mutex_unlock(mtx);
14777 + err = reval_inode(inode, dentry);
14778 + if (unlikely(err < 0)) {
14785 + goto out; /* success */
14790 + if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
14791 + AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
14792 + " b%d, %s, %.*s, hi%lu, i%lu.\n",
14793 + bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
14794 + (unsigned long)h_ino, (unsigned long)ino);
14796 + err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
14800 + mutex_unlock(mtx);
14806 + inode = ERR_PTR(err);
14809 + mutex_unlock(mtx);
14813 +/* ---------------------------------------------------------------------- */
14815 +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14816 + struct inode *inode)
14820 + err = au_br_rdonly(au_sbr(sb, bindex));
14822 + /* pseudo-link after flushed may happen out of bounds */
14825 + && au_ibstart(inode) <= bindex
14826 + && bindex <= au_ibend(inode)) {
14828 + * permission check is unnecessary since vfsub routine
14829 + * will be called later
14831 + struct inode *hi = au_h_iptr(inode, bindex);
14833 + err = IS_IMMUTABLE(hi) ? -EROFS : 0;
14839 +int au_test_h_perm(struct inode *h_inode, int mask)
14841 + if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
14843 + return inode_permission(h_inode, mask);
14846 +int au_test_h_perm_sio(struct inode *h_inode, int mask)
14848 + if (au_test_nfs(h_inode->i_sb)
14849 + && (mask & MAY_WRITE)
14850 + && S_ISDIR(h_inode->i_mode))
14851 + mask |= MAY_READ; /* force permission check */
14852 + return au_test_h_perm(h_inode, mask);
14854 diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
14855 --- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
14856 +++ linux/fs/aufs/inode.h 2013-07-06 13:20:47.750198454 +0200
14859 + * Copyright (C) 2005-2013 Junjiro R. Okajima
14861 + * This program, aufs is free software; you can redistribute it and/or modify
14862 + * it under the terms of the GNU General Public License as published by
14863 + * the Free Software Foundation; either version 2 of the License, or
14864 + * (at your option) any later version.
14866 + * This program is distributed in the hope that it will be useful,
14867 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14868 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14869 + * GNU General Public License for more details.
14871 + * You should have received a copy of the GNU General Public License
14872 + * along with this program; if not, write to the Free Software
14873 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14877 + * inode operations
14880 +#ifndef __AUFS_INODE_H__
14881 +#define __AUFS_INODE_H__
14885 +#include <linux/fsnotify.h>
14886 +#include "rwsem.h"
14890 +struct au_hnotify {
14891 +#ifdef CONFIG_AUFS_HNOTIFY
14892 +#ifdef CONFIG_AUFS_HFSNOTIFY
14893 + /* never use fsnotify_add_vfsmount_mark() */
14894 + struct fsnotify_mark hn_mark;
14896 + struct inode *hn_aufs_inode; /* no get/put */
14898 +} ____cacheline_aligned_in_smp;
14900 +struct au_hinode {
14901 + struct inode *hi_inode;
14902 + aufs_bindex_t hi_id;
14903 +#ifdef CONFIG_AUFS_HNOTIFY
14904 + struct au_hnotify *hi_notify;
14907 + /* reference to the copied-up whiteout with get/put */
14908 + struct dentry *hi_whdentry;
14912 +#define AuIG_HALF_REFRESHED 1
14913 +#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
14914 +#define au_ig_fset(flags, name) \
14915 + do { (flags) |= AuIG_##name; } while (0)
14916 +#define au_ig_fclr(flags, name) \
14917 + do { (flags) &= ~AuIG_##name; } while (0)
14920 + __u32 ig_generation, ig_flags;
14925 + spinlock_t ii_genspin;
14926 + struct au_iigen ii_generation;
14927 + struct super_block *ii_hsb1; /* no get/put */
14929 + struct au_rwsem ii_rwsem;
14930 + aufs_bindex_t ii_bstart, ii_bend;
14932 + struct au_hinode *ii_hinode;
14933 + struct au_vdir *ii_vdir;
14936 +struct au_icntnr {
14937 + struct au_iinfo iinfo;
14938 + struct inode vfs_inode;
14939 +} ____cacheline_aligned_in_smp;
14941 +/* au_pin flags */
14942 +#define AuPin_DI_LOCKED 1
14943 +#define AuPin_MNT_WRITE (1 << 1)
14944 +#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
14945 +#define au_fset_pin(flags, name) \
14946 + do { (flags) |= AuPin_##name; } while (0)
14947 +#define au_fclr_pin(flags, name) \
14948 + do { (flags) &= ~AuPin_##name; } while (0)
14952 + struct dentry *dentry;
14953 + unsigned int udba;
14954 + unsigned char lsc_di, lsc_hi, flags;
14955 + aufs_bindex_t bindex;
14958 + struct dentry *parent;
14959 + struct au_hinode *hdir;
14960 + struct vfsmount *h_mnt;
14962 + /* temporary unlock/relock for copyup */
14963 + struct dentry *h_dentry, *h_parent;
14964 + struct au_branch *br;
14965 + struct task_struct *task;
14968 +void au_pin_hdir_unlock(struct au_pin *p);
14969 +int au_pin_hdir_relock(struct au_pin *p);
14970 +void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
14971 +void au_pin_hdir_acquire_nest(struct au_pin *p);
14972 +void au_pin_hdir_release(struct au_pin *p);
14974 +/* ---------------------------------------------------------------------- */
14976 +static inline struct au_iinfo *au_ii(struct inode *inode)
14978 + struct au_iinfo *iinfo;
14980 + iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
14981 + if (iinfo->ii_hinode)
14983 + return NULL; /* debugging bad_inode case */
14986 +/* ---------------------------------------------------------------------- */
14989 +struct inode *au_igrab(struct inode *inode);
14990 +int au_refresh_hinode_self(struct inode *inode);
14991 +int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
14992 +int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14993 + unsigned int d_type, ino_t *ino);
14994 +struct inode *au_new_inode(struct dentry *dentry, int must_new);
14995 +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14996 + struct inode *inode);
14997 +int au_test_h_perm(struct inode *h_inode, int mask);
14998 +int au_test_h_perm_sio(struct inode *h_inode, int mask);
15000 +static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
15001 + ino_t h_ino, unsigned int d_type, ino_t *ino)
15003 +#ifdef CONFIG_AUFS_SHWH
15004 + return au_ino(sb, bindex, h_ino, d_type, ino);
15011 +extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
15013 +/* au_wr_dir flags */
15014 +#define AuWrDir_ADD_ENTRY 1
15015 +#define AuWrDir_TMP_WHENTRY (1 << 1)
15016 +#define AuWrDir_ISDIR (1 << 2)
15017 +#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
15018 +#define au_fset_wrdir(flags, name) \
15019 + do { (flags) |= AuWrDir_##name; } while (0)
15020 +#define au_fclr_wrdir(flags, name) \
15021 + do { (flags) &= ~AuWrDir_##name; } while (0)
15023 +struct au_wr_dir_args {
15024 + aufs_bindex_t force_btgt;
15025 + unsigned char flags;
15027 +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
15028 + struct au_wr_dir_args *args);
15030 +struct dentry *au_pinned_h_parent(struct au_pin *pin);
15031 +void au_pin_init(struct au_pin *pin, struct dentry *dentry,
15032 + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
15033 + unsigned int udba, unsigned char flags);
15034 +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
15035 + unsigned int udba, unsigned char flags) __must_check;
15036 +int au_do_pin(struct au_pin *pin) __must_check;
15037 +void au_unpin(struct au_pin *pin);
15040 +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15041 + struct dentry *h_parent, int isdir);
15042 +int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15044 +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
15045 +int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
15047 +int aufs_link(struct dentry *src_dentry, struct inode *dir,
15048 + struct dentry *dentry);
15049 +int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
15052 +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
15053 +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
15054 + struct dentry *h_parent, int isdir);
15055 +int aufs_unlink(struct inode *dir, struct dentry *dentry);
15056 +int aufs_rmdir(struct inode *dir, struct dentry *dentry);
15059 +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
15060 +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
15061 + struct inode *dir, struct dentry *dentry);
15064 +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
15065 +void au_hiput(struct au_hinode *hinode);
15066 +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15067 + struct dentry *h_wh);
15068 +unsigned int au_hi_flags(struct inode *inode, int isdir);
15070 +/* hinode flags */
15071 +#define AuHi_XINO 1
15072 +#define AuHi_HNOTIFY (1 << 1)
15073 +#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
15074 +#define au_fset_hi(flags, name) \
15075 + do { (flags) |= AuHi_##name; } while (0)
15076 +#define au_fclr_hi(flags, name) \
15077 + do { (flags) &= ~AuHi_##name; } while (0)
15079 +#ifndef CONFIG_AUFS_HNOTIFY
15080 +#undef AuHi_HNOTIFY
15081 +#define AuHi_HNOTIFY 0
15084 +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15085 + struct inode *h_inode, unsigned int flags);
15087 +void au_update_iigen(struct inode *inode, int half);
15088 +void au_update_ibrange(struct inode *inode, int do_put_zero);
15090 +void au_icntnr_init_once(void *_c);
15091 +int au_iinfo_init(struct inode *inode);
15092 +void au_iinfo_fin(struct inode *inode);
15093 +int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
15095 +#ifdef CONFIG_PROC_FS
15097 +int au_plink_maint(struct super_block *sb, int flags);
15098 +void au_plink_maint_leave(struct au_sbinfo *sbinfo);
15099 +int au_plink_maint_enter(struct super_block *sb);
15100 +#ifdef CONFIG_AUFS_DEBUG
15101 +void au_plink_list(struct super_block *sb);
15103 +AuStubVoid(au_plink_list, struct super_block *sb)
15105 +int au_plink_test(struct inode *inode);
15106 +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
15107 +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
15108 + struct dentry *h_dentry);
15109 +void au_plink_put(struct super_block *sb, int verbose);
15110 +void au_plink_clean(struct super_block *sb, int verbose);
15111 +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
15113 +AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
15114 +AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
15115 +AuStubInt0(au_plink_maint_enter, struct super_block *sb);
15116 +AuStubVoid(au_plink_list, struct super_block *sb);
15117 +AuStubInt0(au_plink_test, struct inode *inode);
15118 +AuStub(struct dentry *, au_plink_lkup, return NULL,
15119 + struct inode *inode, aufs_bindex_t bindex);
15120 +AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
15121 + struct dentry *h_dentry);
15122 +AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
15123 +AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
15124 +AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
15125 +#endif /* CONFIG_PROC_FS */
15127 +/* ---------------------------------------------------------------------- */
15129 +/* lock subclass for iinfo */
15131 + AuLsc_II_CHILD, /* child first */
15132 + AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
15133 + AuLsc_II_CHILD3, /* copyup dirs */
15134 + AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
15135 + AuLsc_II_PARENT2,
15136 + AuLsc_II_PARENT3, /* copyup dirs */
15137 + AuLsc_II_NEW_CHILD
15141 + * ii_read_lock_child, ii_write_lock_child,
15142 + * ii_read_lock_child2, ii_write_lock_child2,
15143 + * ii_read_lock_child3, ii_write_lock_child3,
15144 + * ii_read_lock_parent, ii_write_lock_parent,
15145 + * ii_read_lock_parent2, ii_write_lock_parent2,
15146 + * ii_read_lock_parent3, ii_write_lock_parent3,
15147 + * ii_read_lock_new_child, ii_write_lock_new_child,
15149 +#define AuReadLockFunc(name, lsc) \
15150 +static inline void ii_read_lock_##name(struct inode *i) \
15152 + au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15155 +#define AuWriteLockFunc(name, lsc) \
15156 +static inline void ii_write_lock_##name(struct inode *i) \
15158 + au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15161 +#define AuRWLockFuncs(name, lsc) \
15162 + AuReadLockFunc(name, lsc) \
15163 + AuWriteLockFunc(name, lsc)
15165 +AuRWLockFuncs(child, CHILD);
15166 +AuRWLockFuncs(child2, CHILD2);
15167 +AuRWLockFuncs(child3, CHILD3);
15168 +AuRWLockFuncs(parent, PARENT);
15169 +AuRWLockFuncs(parent2, PARENT2);
15170 +AuRWLockFuncs(parent3, PARENT3);
15171 +AuRWLockFuncs(new_child, NEW_CHILD);
15173 +#undef AuReadLockFunc
15174 +#undef AuWriteLockFunc
15175 +#undef AuRWLockFuncs
15178 + * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
15180 +AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
15182 +#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
15183 +#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
15184 +#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
15186 +/* ---------------------------------------------------------------------- */
15188 +static inline void au_icntnr_init(struct au_icntnr *c)
15190 +#ifdef CONFIG_AUFS_DEBUG
15191 + c->vfs_inode.i_mode = 0;
15195 +static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
15197 + unsigned int gen;
15198 + struct au_iinfo *iinfo;
15200 + iinfo = au_ii(inode);
15201 + spin_lock(&iinfo->ii_genspin);
15203 + *iigen = iinfo->ii_generation;
15204 + gen = iinfo->ii_generation.ig_generation;
15205 + spin_unlock(&iinfo->ii_genspin);
15210 +/* tiny test for inode number */
15211 +/* tmpfs generation is too rough */
15212 +static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
15214 + struct au_iinfo *iinfo;
15216 + iinfo = au_ii(inode);
15217 + AuRwMustAnyLock(&iinfo->ii_rwsem);
15218 + return !(iinfo->ii_hsb1 == h_inode->i_sb
15219 + && iinfo->ii_higen == h_inode->i_generation);
15222 +static inline void au_iigen_dec(struct inode *inode)
15224 + struct au_iinfo *iinfo;
15226 + iinfo = au_ii(inode);
15227 + spin_lock(&iinfo->ii_genspin);
15228 + iinfo->ii_generation.ig_generation--;
15229 + spin_unlock(&iinfo->ii_genspin);
15232 +static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
15237 + if (unlikely(inode && au_iigen(inode, NULL) != sigen))
15243 +/* ---------------------------------------------------------------------- */
15245 +static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
15246 + aufs_bindex_t bindex)
15248 + IiMustAnyLock(inode);
15249 + return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
15252 +static inline aufs_bindex_t au_ibstart(struct inode *inode)
15254 + IiMustAnyLock(inode);
15255 + return au_ii(inode)->ii_bstart;
15258 +static inline aufs_bindex_t au_ibend(struct inode *inode)
15260 + IiMustAnyLock(inode);
15261 + return au_ii(inode)->ii_bend;
15264 +static inline struct au_vdir *au_ivdir(struct inode *inode)
15266 + IiMustAnyLock(inode);
15267 + return au_ii(inode)->ii_vdir;
15270 +static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
15272 + IiMustAnyLock(inode);
15273 + return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
15276 +static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
15278 + IiMustWriteLock(inode);
15279 + au_ii(inode)->ii_bstart = bindex;
15282 +static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
15284 + IiMustWriteLock(inode);
15285 + au_ii(inode)->ii_bend = bindex;
15288 +static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
15290 + IiMustWriteLock(inode);
15291 + au_ii(inode)->ii_vdir = vdir;
15294 +static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
15296 + IiMustAnyLock(inode);
15297 + return au_ii(inode)->ii_hinode + bindex;
15300 +/* ---------------------------------------------------------------------- */
15302 +static inline struct dentry *au_pinned_parent(struct au_pin *pin)
15305 + return pin->parent;
15309 +static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
15311 + if (pin && pin->hdir)
15312 + return pin->hdir->hi_inode;
15316 +static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
15319 + return pin->hdir;
15323 +static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
15326 + pin->dentry = dentry;
15329 +static inline void au_pin_set_parent_lflag(struct au_pin *pin,
15330 + unsigned char lflag)
15334 + au_fset_pin(pin->flags, DI_LOCKED);
15336 + au_fclr_pin(pin->flags, DI_LOCKED);
15340 +static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
15343 + dput(pin->parent);
15344 + pin->parent = dget(parent);
15348 +/* ---------------------------------------------------------------------- */
15351 +#ifdef CONFIG_AUFS_HNOTIFY
15352 +struct au_hnotify_op {
15353 + void (*ctl)(struct au_hinode *hinode, int do_set);
15354 + int (*alloc)(struct au_hinode *hinode);
15357 + * if it returns true, the the caller should free hinode->hi_notify,
15358 + * otherwise ->free() frees it.
15360 + int (*free)(struct au_hinode *hinode,
15361 + struct au_hnotify *hn) __must_check;
15363 + void (*fin)(void);
15364 + int (*init)(void);
15366 + int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
15367 + void (*fin_br)(struct au_branch *br);
15368 + int (*init_br)(struct au_branch *br, int perm);
15372 +int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
15373 +void au_hn_free(struct au_hinode *hinode);
15374 +void au_hn_ctl(struct au_hinode *hinode, int do_set);
15375 +void au_hn_reset(struct inode *inode, unsigned int flags);
15376 +int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15377 + struct qstr *h_child_qstr, struct inode *h_child_inode);
15378 +int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
15379 +int au_hnotify_init_br(struct au_branch *br, int perm);
15380 +void au_hnotify_fin_br(struct au_branch *br);
15381 +int __init au_hnotify_init(void);
15382 +void au_hnotify_fin(void);
15385 +extern const struct au_hnotify_op au_hnotify_op;
15388 +void au_hn_init(struct au_hinode *hinode)
15390 + hinode->hi_notify = NULL;
15393 +static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15395 + return hinode->hi_notify;
15400 +int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
15401 + struct inode *inode __maybe_unused)
15403 + return -EOPNOTSUPP;
15406 +static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15411 +AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
15412 +AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
15413 + int do_set __maybe_unused)
15414 +AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
15415 + unsigned int flags __maybe_unused)
15416 +AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
15417 + struct au_branch *br __maybe_unused,
15418 + int perm __maybe_unused)
15419 +AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
15420 + int perm __maybe_unused)
15421 +AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
15422 +AuStubInt0(__init au_hnotify_init, void)
15423 +AuStubVoid(au_hnotify_fin, void)
15424 +AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
15425 +#endif /* CONFIG_AUFS_HNOTIFY */
15427 +static inline void au_hn_suspend(struct au_hinode *hdir)
15429 + au_hn_ctl(hdir, /*do_set*/0);
15432 +static inline void au_hn_resume(struct au_hinode *hdir)
15434 + au_hn_ctl(hdir, /*do_set*/1);
15437 +static inline void au_hn_imtx_lock(struct au_hinode *hdir)
15439 + mutex_lock(&hdir->hi_inode->i_mutex);
15440 + au_hn_suspend(hdir);
15443 +static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
15444 + unsigned int sc __maybe_unused)
15446 + mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
15447 + au_hn_suspend(hdir);
15450 +static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
15452 + au_hn_resume(hdir);
15453 + mutex_unlock(&hdir->hi_inode->i_mutex);
15456 +#endif /* __KERNEL__ */
15457 +#endif /* __AUFS_INODE_H__ */
15458 diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
15459 --- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
15460 +++ linux/fs/aufs/ioctl.c 2013-07-06 13:20:47.750198454 +0200
15463 + * Copyright (C) 2005-2013 Junjiro R. Okajima
15465 + * This program, aufs is free software; you can redistribute it and/or modify
15466 + * it under the terms of the GNU General Public License as published by
15467 + * the Free Software Foundation; either version 2 of the License, or
15468 + * (at your option) any later version.
15470 + * This program is distributed in the hope that it will be useful,
15471 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15472 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15473 + * GNU General Public License for more details.
15475 + * You should have received a copy of the GNU General Public License
15476 + * along with this program; if not, write to the Free Software
15477 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15482 + * plink-management and readdir in userspace.
15483 + * assist the pathconf(3) wrapper library.
15488 +static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
15491 + aufs_bindex_t wbi, bindex, bend;
15492 + struct file *h_file;
15493 + struct super_block *sb;
15494 + struct dentry *root;
15495 + struct au_branch *br;
15496 + struct aufs_wbr_fd wbrfd = {
15497 + .oflags = au_dir_roflags,
15500 + const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
15501 + | O_NOATIME | O_CLOEXEC;
15503 + AuDebugOn(wbrfd.oflags & ~valid);
15506 + err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
15507 + if (unlikely(err)) {
15513 + AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
15514 + wbrfd.oflags |= au_dir_roflags;
15515 + AuDbg("0%o\n", wbrfd.oflags);
15516 + if (unlikely(wbrfd.oflags & ~valid))
15520 + fd = get_unused_fd();
15522 + if (unlikely(fd < 0))
15525 + h_file = ERR_PTR(-EINVAL);
15528 + sb = path->dentry->d_sb;
15529 + root = sb->s_root;
15530 + aufs_read_lock(root, AuLock_IR);
15531 + bend = au_sbend(sb);
15532 + if (wbrfd.brid >= 0) {
15533 + wbi = au_br_index(sb, wbrfd.brid);
15534 + if (unlikely(wbi < 0 || wbi > bend))
15538 + h_file = ERR_PTR(-ENOENT);
15539 + br = au_sbr(sb, wbi);
15540 + if (!au_br_writable(br->br_perm)) {
15544 + bindex = wbi + 1;
15546 + for (; bindex <= bend; bindex++) {
15547 + br = au_sbr(sb, bindex);
15548 + if (au_br_writable(br->br_perm)) {
15550 + br = au_sbr(sb, wbi);
15555 + AuDbg("wbi %d\n", wbi);
15557 + h_file = au_h_open(root, wbi, wbrfd.oflags, NULL);
15560 + aufs_read_unlock(root, AuLock_IR);
15561 + err = PTR_ERR(h_file);
15562 + if (IS_ERR(h_file))
15565 + atomic_dec(&br->br_count); /* cf. au_h_open() */
15566 + fd_install(fd, h_file);
15568 + goto out; /* success */
15571 + put_unused_fd(fd);
15577 +/* ---------------------------------------------------------------------- */
15579 +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
15584 + case AUFS_CTL_RDU:
15585 + case AUFS_CTL_RDU_INO:
15586 + err = au_rdu_ioctl(file, cmd, arg);
15589 + case AUFS_CTL_WBR_FD:
15590 + err = au_wbr_fd(&file->f_path, (void __user *)arg);
15593 + case AUFS_CTL_IBUSY:
15594 + err = au_ibusy_ioctl(file, arg);
15598 + /* do not call the lower */
15599 + AuDbg("0x%x\n", cmd);
15607 +long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
15612 + case AUFS_CTL_WBR_FD:
15613 + err = au_wbr_fd(&file->f_path, (void __user *)arg);
15617 + /* do not call the lower */
15618 + AuDbg("0x%x\n", cmd);
15626 +#ifdef CONFIG_COMPAT
15627 +long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15628 + unsigned long arg)
15633 + case AUFS_CTL_RDU:
15634 + case AUFS_CTL_RDU_INO:
15635 + err = au_rdu_compat_ioctl(file, cmd, arg);
15638 + case AUFS_CTL_IBUSY:
15639 + err = au_ibusy_compat_ioctl(file, arg);
15643 + err = aufs_ioctl_dir(file, cmd, arg);
15650 +#if 0 /* unused yet */
15651 +long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15652 + unsigned long arg)
15654 + return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
15658 diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
15659 --- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
15660 +++ linux/fs/aufs/i_op_add.c 2013-07-30 22:42:46.235946055 +0200
15663 + * Copyright (C) 2005-2013 Junjiro R. Okajima
15665 + * This program, aufs is free software; you can redistribute it and/or modify
15666 + * it under the terms of the GNU General Public License as published by
15667 + * the Free Software Foundation; either version 2 of the License, or
15668 + * (at your option) any later version.
15670 + * This program is distributed in the hope that it will be useful,
15671 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15672 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15673 + * GNU General Public License for more details.
15675 + * You should have received a copy of the GNU General Public License
15676 + * along with this program; if not, write to the Free Software
15677 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15681 + * inode operations (add entry)
15687 + * final procedure of adding a new entry, except link(2).
15688 + * remove whiteout, instantiate, copyup the parent dir's times and size
15689 + * and update version.
15690 + * if it failed, re-create the removed whiteout.
15692 +static int epilog(struct inode *dir, aufs_bindex_t bindex,
15693 + struct dentry *wh_dentry, struct dentry *dentry)
15696 + aufs_bindex_t bwh;
15697 + struct path h_path;
15698 + struct inode *inode, *h_dir;
15699 + struct dentry *wh;
15703 + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
15704 + IMustLock(h_dir);
15705 + AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
15706 + bwh = au_dbwh(dentry);
15707 + h_path.dentry = wh_dentry;
15708 + h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
15709 + err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
15711 + if (unlikely(err))
15715 + inode = au_new_inode(dentry, /*must_new*/1);
15716 + if (!IS_ERR(inode)) {
15717 + d_instantiate(dentry, inode);
15718 + dir = dentry->d_parent->d_inode; /* dir inode is locked */
15720 + if (au_ibstart(dir) == au_dbstart(dentry))
15721 + au_cpup_attr_timesizes(dir);
15722 + dir->i_version++;
15723 + return 0; /* success */
15726 + err = PTR_ERR(inode);
15731 + /* dir inode is locked */
15732 + wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
15733 + rerr = PTR_ERR(wh);
15734 + if (IS_ERR(wh)) {
15735 + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
15736 + AuDLNPair(dentry), err, rerr);
15745 +static int au_d_may_add(struct dentry *dentry)
15750 + if (unlikely(d_unhashed(dentry)))
15752 + if (unlikely(dentry->d_inode))
15758 + * simple tests for the adding inode operations.
15759 + * following the checks in vfs, plus the parent-child relationship.
15761 +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15762 + struct dentry *h_parent, int isdir)
15766 + struct dentry *h_dentry;
15767 + struct inode *h_inode;
15769 + err = -ENAMETOOLONG;
15770 + if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15773 + h_dentry = au_h_dptr(dentry, bindex);
15774 + h_inode = h_dentry->d_inode;
15775 + if (!dentry->d_inode) {
15777 + if (unlikely(h_inode))
15780 + /* rename(2) case */
15782 + if (unlikely(!h_inode || !h_inode->i_nlink))
15785 + h_mode = h_inode->i_mode;
15788 + if (unlikely(S_ISDIR(h_mode)))
15790 + } else if (unlikely(!S_ISDIR(h_mode))) {
15797 + /* expected parent dir is locked */
15798 + if (unlikely(h_parent != h_dentry->d_parent))
15807 + * initial procedure of adding a new entry.
15808 + * prepare writable branch and the parent dir, lock it,
15809 + * and lookup whiteout for the new entry.
15811 +static struct dentry*
15812 +lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
15813 + struct dentry *src_dentry, struct au_pin *pin,
15814 + struct au_wr_dir_args *wr_dir_args)
15816 + struct dentry *wh_dentry, *h_parent;
15817 + struct super_block *sb;
15818 + struct au_branch *br;
15820 + unsigned int udba;
15821 + aufs_bindex_t bcpup;
15823 + AuDbg("%.*s\n", AuDLNPair(dentry));
15825 + err = au_wr_dir(dentry, src_dentry, wr_dir_args);
15827 + wh_dentry = ERR_PTR(err);
15828 + if (unlikely(err < 0))
15831 + sb = dentry->d_sb;
15832 + udba = au_opt_udba(sb);
15833 + err = au_pin(pin, dentry, bcpup, udba,
15834 + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
15835 + wh_dentry = ERR_PTR(err);
15836 + if (unlikely(err))
15839 + h_parent = au_pinned_h_parent(pin);
15840 + if (udba != AuOpt_UDBA_NONE
15841 + && au_dbstart(dentry) == bcpup)
15842 + err = au_may_add(dentry, bcpup, h_parent,
15843 + au_ftest_wrdir(wr_dir_args->flags, ISDIR));
15844 + else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15845 + err = -ENAMETOOLONG;
15846 + wh_dentry = ERR_PTR(err);
15847 + if (unlikely(err))
15850 + br = au_sbr(sb, bcpup);
15852 + struct path tmp = {
15853 + .dentry = h_parent,
15854 + .mnt = au_br_mnt(br)
15856 + au_dtime_store(dt, au_pinned_parent(pin), &tmp);
15859 + wh_dentry = NULL;
15860 + if (bcpup != au_dbwh(dentry))
15861 + goto out; /* success */
15863 + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
15866 + if (IS_ERR(wh_dentry))
15869 + return wh_dentry;
15872 +/* ---------------------------------------------------------------------- */
15874 +enum { Mknod, Symlink, Creat };
15875 +struct simple_arg {
15883 + const char *symname;
15892 +static int add_simple(struct inode *dir, struct dentry *dentry,
15893 + struct simple_arg *arg)
15896 + aufs_bindex_t bstart;
15897 + unsigned char created;
15898 + struct au_dtime dt;
15899 + struct au_pin pin;
15900 + struct path h_path;
15901 + struct dentry *wh_dentry, *parent;
15902 + struct inode *h_dir;
15903 + struct au_wr_dir_args wr_dir_args = {
15904 + .force_btgt = -1,
15905 + .flags = AuWrDir_ADD_ENTRY
15908 + AuDbg("%.*s\n", AuDLNPair(dentry));
15911 + parent = dentry->d_parent; /* dir inode is locked */
15912 + err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
15913 + if (unlikely(err))
15915 + err = au_d_may_add(dentry);
15916 + if (unlikely(err))
15918 + di_write_lock_parent(parent);
15919 + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin,
15921 + err = PTR_ERR(wh_dentry);
15922 + if (IS_ERR(wh_dentry))
15925 + bstart = au_dbstart(dentry);
15926 + h_path.dentry = au_h_dptr(dentry, bstart);
15927 + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
15928 + h_dir = au_pinned_h_dir(&pin);
15929 + switch (arg->type) {
15931 + err = vfsub_create(h_dir, &h_path, arg->u.c.mode,
15932 + arg->u.c.want_excl);
15935 + err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname);
15938 + err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev);
15945 + err = epilog(dir, bstart, wh_dentry, dentry);
15948 + if (unlikely(created && err && h_path.dentry->d_inode)) {
15950 + rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
15952 + AuIOErr("%.*s revert failure(%d, %d)\n",
15953 + AuDLNPair(dentry), err, rerr);
15956 + au_dtime_revert(&dt);
15963 + di_write_unlock(parent);
15965 + if (unlikely(err)) {
15966 + au_update_dbstart(dentry);
15969 + aufs_read_unlock(dentry, AuLock_DW);
15974 +int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15977 + struct simple_arg arg = {
15984 + return add_simple(dir, dentry, &arg);
15987 +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
15989 + struct simple_arg arg = {
15991 + .u.s.symname = symname
15993 + return add_simple(dir, dentry, &arg);
15996 +int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
15999 + struct simple_arg arg = {
16003 + .want_excl = want_excl
16006 + return add_simple(dir, dentry, &arg);
16009 +/* ---------------------------------------------------------------------- */
16011 +struct au_link_args {
16012 + aufs_bindex_t bdst, bsrc;
16013 + struct au_pin pin;
16014 + struct path h_path;
16015 + struct dentry *src_parent, *parent;
16018 +static int au_cpup_before_link(struct dentry *src_dentry,
16019 + struct au_link_args *a)
16022 + struct dentry *h_src_dentry;
16024 + di_read_lock_parent(a->src_parent, AuLock_IR);
16025 + err = au_test_and_cpup_dirs(src_dentry, a->bdst);
16026 + if (unlikely(err))
16029 + h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
16030 + err = au_pin(&a->pin, src_dentry, a->bdst,
16031 + au_opt_udba(src_dentry->d_sb),
16032 + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16033 + if (unlikely(err))
16036 + err = au_sio_cpup_simple_h_open(src_dentry, a->bdst, -1,
16037 + AuCpup_DTIME /* | AuCpup_KEEPLINO */,
16038 + &a->pin, a->bsrc);
16039 + au_unpin(&a->pin);
16042 + di_read_unlock(a->src_parent, AuLock_IR);
16046 +static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
16047 + struct au_link_args *a)
16050 + unsigned char plink;
16051 + aufs_bindex_t bend;
16052 + struct dentry *h_src_dentry;
16053 + struct inode *h_inode, *inode;
16054 + struct super_block *sb;
16055 + struct file *h_file;
16059 + sb = src_dentry->d_sb;
16060 + inode = src_dentry->d_inode;
16061 + if (au_ibstart(inode) <= a->bdst)
16062 + h_inode = au_h_iptr(inode, a->bdst);
16063 + if (!h_inode || !h_inode->i_nlink) {
16064 + /* copyup src_dentry as the name of dentry. */
16065 + bend = au_dbend(dentry);
16066 + if (bend < a->bsrc)
16067 + au_set_dbend(dentry, a->bsrc);
16068 + au_set_h_dptr(dentry, a->bsrc,
16069 + dget(au_h_dptr(src_dentry, a->bsrc)));
16070 + dget(a->h_path.dentry);
16071 + au_set_h_dptr(dentry, a->bdst, NULL);
16072 + dentry->d_inode = src_dentry->d_inode; /* tmp */
16073 + h_file = au_h_open_pre(dentry, a->bsrc);
16074 + if (IS_ERR(h_file))
16075 + err = PTR_ERR(h_file);
16077 + err = au_sio_cpup_simple(dentry, a->bdst, -1,
16078 + AuCpup_KEEPLINO, &a->pin);
16079 + au_h_open_post(dentry, a->bsrc, h_file);
16081 + dput(a->h_path.dentry);
16082 + a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16084 + au_set_h_dptr(dentry, a->bdst,
16085 + a->h_path.dentry);
16087 + dentry->d_inode = NULL; /* restore */
16088 + au_set_h_dptr(dentry, a->bsrc, NULL);
16089 + au_set_dbend(dentry, bend);
16091 + /* the inode of src_dentry already exists on a.bdst branch */
16092 + h_src_dentry = d_find_alias(h_inode);
16093 + if (!h_src_dentry && au_plink_test(inode)) {
16095 + h_src_dentry = au_plink_lkup(inode, a->bdst);
16096 + err = PTR_ERR(h_src_dentry);
16097 + if (IS_ERR(h_src_dentry))
16100 + if (unlikely(!h_src_dentry->d_inode)) {
16101 + dput(h_src_dentry);
16102 + h_src_dentry = NULL;
16106 + if (h_src_dentry) {
16107 + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
16109 + dput(h_src_dentry);
16111 + AuIOErr("no dentry found for hi%lu on b%d\n",
16112 + h_inode->i_ino, a->bdst);
16117 + if (!err && !plink)
16118 + au_plink_append(inode, a->bdst, a->h_path.dentry);
16125 +int aufs_link(struct dentry *src_dentry, struct inode *dir,
16126 + struct dentry *dentry)
16129 + struct au_dtime dt;
16130 + struct au_link_args *a;
16131 + struct dentry *wh_dentry, *h_src_dentry;
16132 + struct inode *inode;
16133 + struct super_block *sb;
16134 + struct au_wr_dir_args wr_dir_args = {
16135 + /* .force_btgt = -1, */
16136 + .flags = AuWrDir_ADD_ENTRY
16140 + inode = src_dentry->d_inode;
16141 + IMustLock(inode);
16144 + a = kzalloc(sizeof(*a), GFP_NOFS);
16145 + if (unlikely(!a))
16148 + a->parent = dentry->d_parent; /* dir inode is locked */
16149 + err = aufs_read_and_write_lock2(dentry, src_dentry,
16150 + AuLock_NOPLM | AuLock_GEN);
16151 + if (unlikely(err))
16153 + err = au_d_hashed_positive(src_dentry);
16154 + if (unlikely(err))
16156 + err = au_d_may_add(dentry);
16157 + if (unlikely(err))
16160 + a->src_parent = dget_parent(src_dentry);
16161 + wr_dir_args.force_btgt = au_ibstart(inode);
16163 + di_write_lock_parent(a->parent);
16164 + wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
16165 + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
16167 + err = PTR_ERR(wh_dentry);
16168 + if (IS_ERR(wh_dentry))
16172 + sb = dentry->d_sb;
16173 + a->bdst = au_dbstart(dentry);
16174 + a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16175 + a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
16176 + a->bsrc = au_ibstart(inode);
16177 + h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16178 + if (!h_src_dentry) {
16179 + a->bsrc = au_dbstart(src_dentry);
16180 + h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16181 + AuDebugOn(!h_src_dentry);
16182 + } else if (IS_ERR(h_src_dentry))
16185 + if (au_opt_test(au_mntflags(sb), PLINK)) {
16186 + if (a->bdst < a->bsrc
16187 + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
16188 + err = au_cpup_or_link(src_dentry, dentry, a);
16190 + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
16192 + dput(h_src_dentry);
16195 + * copyup src_dentry to the branch we process,
16196 + * and then link(2) to it.
16198 + dput(h_src_dentry);
16199 + if (a->bdst < a->bsrc
16200 + /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
16201 + au_unpin(&a->pin);
16202 + di_write_unlock(a->parent);
16203 + err = au_cpup_before_link(src_dentry, a);
16204 + di_write_lock_parent(a->parent);
16206 + err = au_pin(&a->pin, dentry, a->bdst,
16208 + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16209 + if (unlikely(err))
16213 + h_src_dentry = au_h_dptr(src_dentry, a->bdst);
16215 + if (h_src_dentry && h_src_dentry->d_inode)
16216 + err = vfsub_link(h_src_dentry,
16217 + au_pinned_h_dir(&a->pin),
16221 + if (unlikely(err))
16225 + a->h_path.dentry = wh_dentry;
16226 + err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
16228 + if (unlikely(err))
16232 + dir->i_version++;
16233 + if (au_ibstart(dir) == au_dbstart(dentry))
16234 + au_cpup_attr_timesizes(dir);
16235 + inc_nlink(inode);
16236 + inode->i_ctime = dir->i_ctime;
16237 + d_instantiate(dentry, au_igrab(inode));
16238 + if (d_unhashed(a->h_path.dentry))
16239 + /* some filesystem calls d_drop() */
16241 + goto out_unpin; /* success */
16244 + rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
16245 + if (unlikely(rerr)) {
16246 + AuIOErr("%.*s reverting failed(%d, %d)\n",
16247 + AuDLNPair(dentry), err, rerr);
16250 + au_dtime_revert(&dt);
16252 + au_unpin(&a->pin);
16256 + di_write_unlock(a->parent);
16257 + dput(a->src_parent);
16259 + if (unlikely(err)) {
16260 + au_update_dbstart(dentry);
16263 + aufs_read_and_write_unlock2(dentry, src_dentry);
16271 +int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
16274 + aufs_bindex_t bindex;
16275 + unsigned char diropq;
16276 + struct path h_path;
16277 + struct dentry *wh_dentry, *parent, *opq_dentry;
16278 + struct mutex *h_mtx;
16279 + struct super_block *sb;
16281 + struct au_pin pin;
16282 + struct au_dtime dt;
16283 + } *a; /* reduce the stack usage */
16284 + struct au_wr_dir_args wr_dir_args = {
16285 + .force_btgt = -1,
16286 + .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
16292 + a = kmalloc(sizeof(*a), GFP_NOFS);
16293 + if (unlikely(!a))
16296 + err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
16297 + if (unlikely(err))
16299 + err = au_d_may_add(dentry);
16300 + if (unlikely(err))
16303 + parent = dentry->d_parent; /* dir inode is locked */
16304 + di_write_lock_parent(parent);
16305 + wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
16306 + &a->pin, &wr_dir_args);
16307 + err = PTR_ERR(wh_dentry);
16308 + if (IS_ERR(wh_dentry))
16311 + sb = dentry->d_sb;
16312 + bindex = au_dbstart(dentry);
16313 + h_path.dentry = au_h_dptr(dentry, bindex);
16314 + h_path.mnt = au_sbr_mnt(sb, bindex);
16315 + err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
16316 + if (unlikely(err))
16319 + /* make the dir opaque */
16321 + h_mtx = &h_path.dentry->d_inode->i_mutex;
16323 + || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
16324 + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16325 + opq_dentry = au_diropq_create(dentry, bindex);
16326 + mutex_unlock(h_mtx);
16327 + err = PTR_ERR(opq_dentry);
16328 + if (IS_ERR(opq_dentry))
16330 + dput(opq_dentry);
16334 + err = epilog(dir, bindex, wh_dentry, dentry);
16337 + goto out_unpin; /* success */
16342 + AuLabel(revert opq);
16343 + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16344 + rerr = au_diropq_remove(dentry, bindex);
16345 + mutex_unlock(h_mtx);
16347 + AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
16348 + AuDLNPair(dentry), err, rerr);
16354 + AuLabel(revert dir);
16355 + rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
16357 + AuIOErr("%.*s reverting dir failed(%d, %d)\n",
16358 + AuDLNPair(dentry), err, rerr);
16361 + au_dtime_revert(&a->dt);
16363 + au_unpin(&a->pin);
16366 + di_write_unlock(parent);
16368 + if (unlikely(err)) {
16369 + au_update_dbstart(dentry);
16372 + aufs_read_unlock(dentry, AuLock_DW);
16378 diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
16379 --- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
16380 +++ linux/fs/aufs/i_op.c 2013-07-30 22:42:46.235946055 +0200
16383 + * Copyright (C) 2005-2013 Junjiro R. Okajima
16385 + * This program, aufs is free software; you can redistribute it and/or modify
16386 + * it under the terms of the GNU General Public License as published by
16387 + * the Free Software Foundation; either version 2 of the License, or
16388 + * (at your option) any later version.
16390 + * This program is distributed in the hope that it will be useful,
16391 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16392 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16393 + * GNU General Public License for more details.
16395 + * You should have received a copy of the GNU General Public License
16396 + * along with this program; if not, write to the Free Software
16397 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16401 + * inode operations (except add/del/rename)
16404 +#include <linux/device_cgroup.h>
16405 +#include <linux/fs_stack.h>
16406 +#include <linux/mm.h>
16407 +#include <linux/namei.h>
16408 +#include <linux/security.h>
16411 +static int h_permission(struct inode *h_inode, int mask,
16412 + struct vfsmount *h_mnt, int brperm)
16415 + const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
16418 + if ((write_mask && IS_IMMUTABLE(h_inode))
16419 + || ((mask & MAY_EXEC)
16420 + && S_ISREG(h_inode->i_mode)
16421 + && ((h_mnt->mnt_flags & MNT_NOEXEC)
16422 + || !(h_inode->i_mode & S_IXUGO))))
16426 + * - skip the lower fs test in the case of write to ro branch.
16427 + * - nfs dir permission write check is optimized, but a policy for
16428 + * link/rename requires a real check.
16430 + if ((write_mask && !au_br_writable(brperm))
16431 + || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
16432 + && write_mask && !(mask & MAY_READ))
16433 + || !h_inode->i_op->permission) {
16434 + /* AuLabel(generic_permission); */
16435 + err = generic_permission(h_inode, mask);
16437 + /* AuLabel(h_inode->permission); */
16438 + err = h_inode->i_op->permission(h_inode, mask);
16443 + err = devcgroup_inode_permission(h_inode, mask);
16445 + err = security_inode_permission(h_inode, mask);
16449 + /* todo: do we need to call ima_path_check()? */
16450 + struct path h_path = {
16454 + err = ima_path_check(&h_path,
16455 + mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
16456 + IMA_COUNT_LEAVE);
16464 +static int aufs_permission(struct inode *inode, int mask)
16467 + aufs_bindex_t bindex, bend;
16468 + const unsigned char isdir = !!S_ISDIR(inode->i_mode),
16469 + write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
16470 + struct inode *h_inode;
16471 + struct super_block *sb;
16472 + struct au_branch *br;
16474 + /* todo: support rcu-walk? */
16475 + if (mask & MAY_NOT_BLOCK)
16478 + sb = inode->i_sb;
16479 + si_read_lock(sb, AuLock_FLUSH);
16480 + ii_read_lock_child(inode);
16482 + err = au_iigen_test(inode, au_sigen(sb));
16483 + if (unlikely(err))
16487 + if (!isdir || write_mask) {
16488 + err = au_busy_or_stale();
16489 + h_inode = au_h_iptr(inode, au_ibstart(inode));
16490 + if (unlikely(!h_inode
16491 + || (h_inode->i_mode & S_IFMT)
16492 + != (inode->i_mode & S_IFMT)))
16496 + bindex = au_ibstart(inode);
16497 + br = au_sbr(sb, bindex);
16498 + err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
16501 + && !special_file(h_inode->i_mode)) {
16502 + /* test whether the upper writable branch exists */
16504 + for (; bindex >= 0; bindex--)
16505 + if (!au_br_rdonly(au_sbr(sb, bindex))) {
16513 + /* non-write to dir */
16515 + bend = au_ibend(inode);
16516 + for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
16517 + h_inode = au_h_iptr(inode, bindex);
16519 + err = au_busy_or_stale();
16520 + if (unlikely(!S_ISDIR(h_inode->i_mode)))
16523 + br = au_sbr(sb, bindex);
16524 + err = h_permission(h_inode, mask, au_br_mnt(br),
16530 + ii_read_unlock(inode);
16531 + si_read_unlock(sb);
16535 +/* ---------------------------------------------------------------------- */
16537 +static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
16538 + unsigned int flags)
16540 + struct dentry *ret, *parent;
16541 + struct inode *inode;
16542 + struct super_block *sb;
16543 + int err, npositive;
16547 + /* todo: support rcu-walk? */
16548 + ret = ERR_PTR(-ECHILD);
16549 + if (flags & LOOKUP_RCU)
16552 + ret = ERR_PTR(-ENAMETOOLONG);
16553 + if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
16557 + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16558 + ret = ERR_PTR(err);
16559 + if (unlikely(err))
16562 + err = au_di_init(dentry);
16563 + ret = ERR_PTR(err);
16564 + if (unlikely(err))
16568 + npositive = 0; /* suppress a warning */
16569 + parent = dentry->d_parent; /* dir inode is locked */
16570 + di_read_lock_parent(parent, AuLock_IR);
16571 + err = au_alive_dir(parent);
16573 + err = au_digen_test(parent, au_sigen(sb));
16575 + npositive = au_lkup_dentry(dentry, au_dbstart(parent),
16579 + di_read_unlock(parent, AuLock_IR);
16580 + ret = ERR_PTR(err);
16581 + if (unlikely(err < 0))
16585 + inode = au_new_inode(dentry, /*must_new*/0);
16586 + ret = (void *)inode;
16588 + if (IS_ERR(inode)) {
16593 + ret = d_splice_alias(inode, dentry);
16595 + if (unlikely(d_need_lookup(dentry))) {
16596 + spin_lock(&dentry->d_lock);
16597 + dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
16598 + spin_unlock(&dentry->d_lock);
16601 + if (unlikely(IS_ERR(ret) && inode)) {
16602 + ii_write_unlock(inode);
16608 + di_write_unlock(dentry);
16610 + /* verbose coding for lock class name */
16611 + if (unlikely(S_ISLNK(inode->i_mode)))
16612 + au_rw_class(&au_di(dentry)->di_rwsem,
16613 + au_lc_key + AuLcSymlink_DIINFO);
16614 + else if (unlikely(S_ISDIR(inode->i_mode)))
16615 + au_rw_class(&au_di(dentry)->di_rwsem,
16616 + au_lc_key + AuLcDir_DIINFO);
16617 + else /* likely */
16618 + au_rw_class(&au_di(dentry)->di_rwsem,
16619 + au_lc_key + AuLcNonDir_DIINFO);
16622 + si_read_unlock(sb);
16627 +/* ---------------------------------------------------------------------- */
16629 +static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
16630 + const unsigned char add_entry, aufs_bindex_t bcpup,
16631 + aufs_bindex_t bstart)
16634 + struct dentry *h_parent;
16635 + struct inode *h_dir;
16638 + IMustLock(parent->d_inode);
16640 + di_write_lock_parent(parent);
16643 + if (!au_h_dptr(parent, bcpup)) {
16644 + if (bstart < bcpup)
16645 + err = au_cpdown_dirs(dentry, bcpup);
16647 + err = au_cpup_dirs(dentry, bcpup);
16649 + if (!err && add_entry) {
16650 + h_parent = au_h_dptr(parent, bcpup);
16651 + h_dir = h_parent->d_inode;
16652 + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
16653 + err = au_lkup_neg(dentry, bcpup,
16654 + au_ftest_wrdir(add_entry, TMP_WHENTRY));
16655 + /* todo: no unlock here */
16656 + mutex_unlock(&h_dir->i_mutex);
16658 + AuDbg("bcpup %d\n", bcpup);
16660 + if (!dentry->d_inode)
16661 + au_set_h_dptr(dentry, bstart, NULL);
16662 + au_update_dbrange(dentry, /*do_put_zero*/0);
16667 + di_write_unlock(parent);
16669 + err = bcpup; /* success */
16676 + * decide the branch and the parent dir where we will create a new entry.
16677 + * returns new bindex or an error.
16678 + * copyup the parent dir if needed.
16680 +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16681 + struct au_wr_dir_args *args)
16684 + aufs_bindex_t bcpup, bstart, src_bstart;
16685 + const unsigned char add_entry
16686 + = au_ftest_wrdir(args->flags, ADD_ENTRY)
16687 + | au_ftest_wrdir(args->flags, TMP_WHENTRY);
16688 + struct super_block *sb;
16689 + struct dentry *parent;
16690 + struct au_sbinfo *sbinfo;
16692 + sb = dentry->d_sb;
16693 + sbinfo = au_sbi(sb);
16694 + parent = dget_parent(dentry);
16695 + bstart = au_dbstart(dentry);
16697 + if (args->force_btgt < 0) {
16698 + if (src_dentry) {
16699 + src_bstart = au_dbstart(src_dentry);
16700 + if (src_bstart < bstart)
16701 + bcpup = src_bstart;
16702 + } else if (add_entry) {
16703 + err = AuWbrCreate(sbinfo, dentry,
16704 + au_ftest_wrdir(args->flags, ISDIR));
16708 + if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
16710 + err = AuWbrCopyup(sbinfo, dentry);
16712 + if (!IS_ROOT(dentry)) {
16713 + di_read_lock_parent(parent, !AuLock_IR);
16714 + err = AuWbrCopyup(sbinfo, dentry);
16715 + di_read_unlock(parent, !AuLock_IR);
16717 + err = AuWbrCopyup(sbinfo, dentry);
16720 + if (unlikely(err < 0))
16724 + bcpup = args->force_btgt;
16725 + AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
16728 + AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
16730 + if (bcpup == bstart)
16731 + goto out; /* success */
16733 + /* copyup the new parent into the branch we process */
16734 + err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
16736 + if (!dentry->d_inode) {
16737 + au_set_h_dptr(dentry, bstart, NULL);
16738 + au_set_dbstart(dentry, bcpup);
16739 + au_set_dbend(dentry, bcpup);
16741 + AuDebugOn(add_entry && !au_h_dptr(dentry, bcpup));
16749 +/* ---------------------------------------------------------------------- */
16751 +void au_pin_hdir_unlock(struct au_pin *p)
16754 + au_hn_imtx_unlock(p->hdir);
16757 +static int au_pin_hdir_lock(struct au_pin *p)
16765 + /* even if an error happens later, keep this lock */
16766 + au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
16769 + if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
16774 + err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
16775 + p->h_parent, p->br);
16781 +int au_pin_hdir_relock(struct au_pin *p)
16784 + struct inode *h_i;
16785 + struct dentry *h_d[] = {
16790 + err = au_pin_hdir_lock(p);
16791 + if (unlikely(err))
16794 + for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
16797 + h_i = h_d[i]->d_inode;
16799 + err = !h_i->i_nlink;
16806 +void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
16808 +#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
16809 + p->hdir->hi_inode->i_mutex.owner = task;
16813 +void au_pin_hdir_acquire_nest(struct au_pin *p)
16816 + mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
16817 + p->lsc_hi, 0, NULL, _RET_IP_);
16818 + au_pin_hdir_set_owner(p, current);
16822 +void au_pin_hdir_release(struct au_pin *p)
16825 + au_pin_hdir_set_owner(p, p->task);
16826 + mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
16830 +struct dentry *au_pinned_h_parent(struct au_pin *pin)
16832 + if (pin && pin->parent)
16833 + return au_h_dptr(pin->parent, pin->bindex);
16837 +void au_unpin(struct au_pin *p)
16840 + au_pin_hdir_unlock(p);
16841 + if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
16842 + vfsub_mnt_drop_write(p->h_mnt);
16846 + if (!au_ftest_pin(p->flags, DI_LOCKED))
16847 + di_read_unlock(p->parent, AuLock_IR);
16848 + iput(p->hdir->hi_inode);
16850 + p->parent = NULL;
16853 + /* do not clear p->task */
16856 +int au_do_pin(struct au_pin *p)
16859 + struct super_block *sb;
16860 + struct inode *h_dir;
16863 + sb = p->dentry->d_sb;
16864 + p->br = au_sbr(sb, p->bindex);
16865 + if (IS_ROOT(p->dentry)) {
16866 + if (au_ftest_pin(p->flags, MNT_WRITE)) {
16867 + p->h_mnt = au_br_mnt(p->br);
16868 + err = vfsub_mnt_want_write(p->h_mnt);
16869 + if (unlikely(err)) {
16870 + au_fclr_pin(p->flags, MNT_WRITE);
16877 + p->h_dentry = NULL;
16878 + if (p->bindex <= au_dbend(p->dentry))
16879 + p->h_dentry = au_h_dptr(p->dentry, p->bindex);
16881 + p->parent = dget_parent(p->dentry);
16882 + if (!au_ftest_pin(p->flags, DI_LOCKED))
16883 + di_read_lock(p->parent, AuLock_IR, p->lsc_di);
16886 + p->h_parent = au_h_dptr(p->parent, p->bindex);
16887 + p->hdir = au_hi(p->parent->d_inode, p->bindex);
16889 + h_dir = p->hdir->hi_inode;
16893 + * if DI_LOCKED is not set, then p->parent may be different
16894 + * and h_parent can be NULL.
16896 + if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
16898 + if (!au_ftest_pin(p->flags, DI_LOCKED))
16899 + di_read_unlock(p->parent, AuLock_IR);
16901 + p->parent = NULL;
16905 + if (au_ftest_pin(p->flags, MNT_WRITE)) {
16906 + p->h_mnt = au_br_mnt(p->br);
16907 + err = vfsub_mnt_want_write(p->h_mnt);
16908 + if (unlikely(err)) {
16909 + au_fclr_pin(p->flags, MNT_WRITE);
16910 + if (!au_ftest_pin(p->flags, DI_LOCKED))
16911 + di_read_unlock(p->parent, AuLock_IR);
16913 + p->parent = NULL;
16919 + err = au_pin_hdir_lock(p);
16921 + goto out; /* success */
16924 + pr_err("err %d\n", err);
16925 + err = au_busy_or_stale();
16930 +void au_pin_init(struct au_pin *p, struct dentry *dentry,
16931 + aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16932 + unsigned int udba, unsigned char flags)
16934 + p->dentry = dentry;
16936 + p->lsc_di = lsc_di;
16937 + p->lsc_hi = lsc_hi;
16938 + p->flags = flags;
16939 + p->bindex = bindex;
16941 + p->parent = NULL;
16945 + p->h_dentry = NULL;
16946 + p->h_parent = NULL;
16948 + p->task = current;
16951 +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16952 + unsigned int udba, unsigned char flags)
16954 + au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
16956 + return au_do_pin(pin);
16959 +/* ---------------------------------------------------------------------- */
16962 + * ->setattr() and ->getattr() are called in various cases.
16963 + * chmod, stat: dentry is revalidated.
16964 + * fchmod, fstat: file and dentry are not revalidated, additionally they may be
16966 + * for ->setattr(), ia->ia_file is passed from ftruncate only.
16968 +/* todo: consolidate with do_refresh() and simple_reval_dpath() */
16969 +static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
16972 + struct inode *inode;
16973 + struct dentry *parent;
16976 + inode = dentry->d_inode;
16977 + if (au_digen_test(dentry, sigen)) {
16978 + parent = dget_parent(dentry);
16979 + di_read_lock_parent(parent, AuLock_IR);
16980 + err = au_refresh_dentry(dentry, parent);
16981 + di_read_unlock(parent, AuLock_IR);
16989 +#define AuIcpup_DID_CPUP 1
16990 +#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
16991 +#define au_fset_icpup(flags, name) \
16992 + do { (flags) |= AuIcpup_##name; } while (0)
16993 +#define au_fclr_icpup(flags, name) \
16994 + do { (flags) &= ~AuIcpup_##name; } while (0)
16996 +struct au_icpup_args {
16997 + unsigned char flags;
16998 + unsigned char pin_flags;
16999 + aufs_bindex_t btgt;
17000 + unsigned int udba;
17001 + struct au_pin pin;
17002 + struct path h_path;
17003 + struct inode *h_inode;
17006 +static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
17007 + struct au_icpup_args *a)
17011 + aufs_bindex_t bstart, ibstart;
17012 + struct dentry *hi_wh, *parent;
17013 + struct inode *inode;
17014 + struct au_wr_dir_args wr_dir_args = {
17015 + .force_btgt = -1,
17019 + bstart = au_dbstart(dentry);
17020 + inode = dentry->d_inode;
17021 + if (S_ISDIR(inode->i_mode))
17022 + au_fset_wrdir(wr_dir_args.flags, ISDIR);
17023 + /* plink or hi_wh() case */
17024 + ibstart = au_ibstart(inode);
17025 + if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
17026 + wr_dir_args.force_btgt = ibstart;
17027 + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17028 + if (unlikely(err < 0))
17031 + if (err != bstart)
17032 + au_fset_icpup(a->flags, DID_CPUP);
17035 + a->pin_flags = AuPin_MNT_WRITE;
17037 + if (!IS_ROOT(dentry)) {
17038 + au_fset_pin(a->pin_flags, DI_LOCKED);
17039 + parent = dget_parent(dentry);
17040 + di_write_lock_parent(parent);
17043 + err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
17044 + if (unlikely(err))
17047 + a->h_path.dentry = au_h_dptr(dentry, bstart);
17048 + a->h_inode = a->h_path.dentry->d_inode;
17049 + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17051 + if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
17052 + sz = ia->ia_size;
17053 + mutex_unlock(&a->h_inode->i_mutex);
17056 + if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
17057 + hi_wh = au_hi_wh(inode, a->btgt);
17059 + err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL,
17061 + if (unlikely(err))
17063 + hi_wh = au_hi_wh(inode, a->btgt);
17064 + /* todo: revalidate hi_wh? */
17069 + au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
17070 + di_downgrade_lock(parent, AuLock_IR);
17074 + if (!au_ftest_icpup(a->flags, DID_CPUP))
17075 + goto out; /* success */
17077 + if (!d_unhashed(dentry)) {
17078 + err = au_sio_cpup_simple_h_open(dentry, a->btgt, sz,
17079 + AuCpup_DTIME, &a->pin, bstart);
17081 + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17082 + } else if (!hi_wh)
17083 + a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17085 + a->h_path.dentry = hi_wh; /* do not dget here */
17088 + a->h_inode = a->h_path.dentry->d_inode;
17090 + goto out; /* success */
17091 + au_unpin(&a->pin);
17094 + di_write_unlock(parent);
17099 + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17103 +static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
17106 + struct inode *inode;
17107 + struct super_block *sb;
17108 + struct file *file;
17109 + struct au_icpup_args *a;
17111 + inode = dentry->d_inode;
17112 + IMustLock(inode);
17115 + a = kzalloc(sizeof(*a), GFP_NOFS);
17116 + if (unlikely(!a))
17119 + if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
17120 + ia->ia_valid &= ~ATTR_MODE;
17123 + sb = dentry->d_sb;
17124 + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17125 + if (unlikely(err))
17128 + if (ia->ia_valid & ATTR_FILE) {
17129 + /* currently ftruncate(2) only */
17130 + AuDebugOn(!S_ISREG(inode->i_mode));
17131 + file = ia->ia_file;
17132 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
17133 + if (unlikely(err))
17135 + ia->ia_file = au_hf_top(file);
17136 + a->udba = AuOpt_UDBA_NONE;
17138 + /* fchmod() doesn't pass ia_file */
17139 + a->udba = au_opt_udba(sb);
17140 + di_write_lock_child(dentry);
17141 + /* no d_unlinked(), to set UDBA_NONE for root */
17142 + if (d_unhashed(dentry))
17143 + a->udba = AuOpt_UDBA_NONE;
17144 + if (a->udba != AuOpt_UDBA_NONE) {
17145 + AuDebugOn(IS_ROOT(dentry));
17146 + err = au_reval_for_attr(dentry, au_sigen(sb));
17147 + if (unlikely(err))
17152 + err = au_pin_and_icpup(dentry, ia, a);
17153 + if (unlikely(err < 0))
17155 + if (au_ftest_icpup(a->flags, DID_CPUP)) {
17156 + ia->ia_file = NULL;
17157 + ia->ia_valid &= ~ATTR_FILE;
17160 + a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
17161 + if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
17162 + == (ATTR_MODE | ATTR_CTIME)) {
17163 + err = security_path_chmod(&a->h_path, ia->ia_mode);
17164 + if (unlikely(err))
17166 + } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
17167 + && (ia->ia_valid & ATTR_CTIME)) {
17168 + err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
17169 + if (unlikely(err))
17173 + if (ia->ia_valid & ATTR_SIZE) {
17176 + if (ia->ia_size < i_size_read(inode))
17178 + truncate_setsize(inode, ia->ia_size);
17181 + if (ia->ia_valid & ATTR_FILE)
17183 + mutex_unlock(&a->h_inode->i_mutex);
17184 + err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
17185 + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17187 + err = vfsub_notify_change(&a->h_path, ia);
17189 + au_cpup_attr_changeable(inode);
17192 + mutex_unlock(&a->h_inode->i_mutex);
17193 + au_unpin(&a->pin);
17194 + if (unlikely(err))
17195 + au_update_dbstart(dentry);
17197 + di_write_unlock(dentry);
17199 + fi_write_unlock(file);
17200 + ia->ia_file = file;
17201 + ia->ia_valid |= ATTR_FILE;
17204 + si_read_unlock(sb);
17212 +static void au_refresh_iattr(struct inode *inode, struct kstat *st,
17213 + unsigned int nlink)
17217 + inode->i_mode = st->mode;
17218 + /* don't i_[ug]id_write() here */
17219 + inode->i_uid = st->uid;
17220 + inode->i_gid = st->gid;
17221 + inode->i_atime = st->atime;
17222 + inode->i_mtime = st->mtime;
17223 + inode->i_ctime = st->ctime;
17225 + au_cpup_attr_nlink(inode, /*force*/0);
17226 + if (S_ISDIR(inode->i_mode)) {
17227 + n = inode->i_nlink;
17231 + /* 0 can happen */
17232 + set_nlink(inode, n);
17235 + spin_lock(&inode->i_lock);
17236 + inode->i_blocks = st->blocks;
17237 + i_size_write(inode, st->size);
17238 + spin_unlock(&inode->i_lock);
17241 +static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
17242 + struct dentry *dentry, struct kstat *st)
17245 + unsigned int mnt_flags;
17246 + aufs_bindex_t bindex;
17247 + unsigned char udba_none, positive;
17248 + struct super_block *sb, *h_sb;
17249 + struct inode *inode;
17250 + struct path h_path;
17252 + sb = dentry->d_sb;
17253 + inode = dentry->d_inode;
17254 + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17255 + if (unlikely(err))
17257 + mnt_flags = au_mntflags(sb);
17258 + udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
17260 + /* support fstat(2) */
17261 + if (!d_unlinked(dentry) && !udba_none) {
17262 + unsigned int sigen = au_sigen(sb);
17263 + err = au_digen_test(dentry, sigen);
17265 + di_read_lock_child(dentry, AuLock_IR);
17266 + err = au_dbrange_test(dentry);
17267 + if (unlikely(err))
17270 + AuDebugOn(IS_ROOT(dentry));
17271 + di_write_lock_child(dentry);
17272 + err = au_dbrange_test(dentry);
17274 + err = au_reval_for_attr(dentry, sigen);
17275 + di_downgrade_lock(dentry, AuLock_IR);
17276 + if (unlikely(err))
17280 + di_read_lock_child(dentry, AuLock_IR);
17282 + bindex = au_ibstart(inode);
17283 + h_path.mnt = au_sbr_mnt(sb, bindex);
17284 + h_sb = h_path.mnt->mnt_sb;
17285 + if (!au_test_fs_bad_iattr(h_sb) && udba_none)
17286 + goto out_fill; /* success */
17288 + h_path.dentry = NULL;
17289 + if (au_dbstart(dentry) == bindex)
17290 + h_path.dentry = dget(au_h_dptr(dentry, bindex));
17291 + else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
17292 + h_path.dentry = au_plink_lkup(inode, bindex);
17293 + if (IS_ERR(h_path.dentry))
17294 + goto out_fill; /* pretending success */
17296 + /* illegally overlapped or something */
17297 + if (unlikely(!h_path.dentry))
17298 + goto out_fill; /* pretending success */
17300 + positive = !!h_path.dentry->d_inode;
17302 + err = vfs_getattr(&h_path, st);
17303 + dput(h_path.dentry);
17306 + au_refresh_iattr(inode, st,
17307 + h_path.dentry->d_inode->i_nlink);
17308 + goto out_fill; /* success */
17314 + generic_fillattr(inode, st);
17316 + di_read_unlock(dentry, AuLock_IR);
17317 + si_read_unlock(sb);
17323 +/* ---------------------------------------------------------------------- */
17325 +static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
17329 + struct super_block *sb;
17330 + struct dentry *h_dentry;
17333 + h_dentry = au_h_dptr(dentry, bindex);
17334 + if (unlikely(!h_dentry->d_inode->i_op->readlink))
17337 + err = security_inode_readlink(h_dentry);
17338 + if (unlikely(err))
17341 + sb = dentry->d_sb;
17342 + if (!au_test_ro(sb, bindex, dentry->d_inode)) {
17343 + vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
17344 + fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
17346 + err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
17352 +static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
17356 + err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17357 + if (unlikely(err))
17359 + err = au_d_hashed_positive(dentry);
17361 + err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
17362 + aufs_read_unlock(dentry, AuLock_IR);
17368 +static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
17371 + mm_segment_t old_fs;
17378 + buf.k = (void *)__get_free_page(GFP_NOFS);
17379 + if (unlikely(!buf.k))
17382 + err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17383 + if (unlikely(err))
17386 + err = au_d_hashed_positive(dentry);
17388 + old_fs = get_fs();
17389 + set_fs(KERNEL_DS);
17390 + err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
17393 + aufs_read_unlock(dentry, AuLock_IR);
17397 + /* will be freed by put_link */
17398 + nd_set_link(nd, buf.k);
17399 + return NULL; /* success */
17403 + free_page((unsigned long)buf.k);
17406 + return ERR_PTR(err);
17409 +static void aufs_put_link(struct dentry *dentry __maybe_unused,
17410 + struct nameidata *nd, void *cookie __maybe_unused)
17414 + p = nd_get_link(nd);
17415 + if (!IS_ERR_OR_NULL(p))
17416 + free_page((unsigned long)p);
17419 +/* ---------------------------------------------------------------------- */
17421 +static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
17424 + struct super_block *sb;
17425 + struct inode *h_inode;
17427 + sb = inode->i_sb;
17428 + /* mmap_sem might be acquired already, cf. aufs_mmap() */
17430 + si_read_lock(sb, AuLock_FLUSH);
17431 + ii_write_lock_child(inode);
17433 + h_inode = au_h_iptr(inode, au_ibstart(inode));
17434 + err = vfsub_update_time(h_inode, ts, flags);
17436 + ii_write_unlock(inode);
17437 + si_read_unlock(sb);
17442 +/* ---------------------------------------------------------------------- */
17444 +struct inode_operations aufs_symlink_iop = {
17445 + .permission = aufs_permission,
17446 + .setattr = aufs_setattr,
17447 + .getattr = aufs_getattr,
17449 + .readlink = aufs_readlink,
17450 + .follow_link = aufs_follow_link,
17451 + .put_link = aufs_put_link,
17453 + /* .update_time = aufs_update_time */
17456 +struct inode_operations aufs_dir_iop = {
17457 + .create = aufs_create,
17458 + .lookup = aufs_lookup,
17459 + .link = aufs_link,
17460 + .unlink = aufs_unlink,
17461 + .symlink = aufs_symlink,
17462 + .mkdir = aufs_mkdir,
17463 + .rmdir = aufs_rmdir,
17464 + .mknod = aufs_mknod,
17465 + .rename = aufs_rename,
17467 + .permission = aufs_permission,
17468 + .setattr = aufs_setattr,
17469 + .getattr = aufs_getattr,
17471 + .update_time = aufs_update_time
17472 + /* no support for atomic_open() */
17475 +struct inode_operations aufs_iop = {
17476 + .permission = aufs_permission,
17477 + .setattr = aufs_setattr,
17478 + .getattr = aufs_getattr,
17480 + .update_time = aufs_update_time
17482 diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
17483 --- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
17484 +++ linux/fs/aufs/i_op_del.c 2013-07-06 13:20:47.750198454 +0200
17487 + * Copyright (C) 2005-2013 Junjiro R. Okajima
17489 + * This program, aufs is free software; you can redistribute it and/or modify
17490 + * it under the terms of the GNU General Public License as published by
17491 + * the Free Software Foundation; either version 2 of the License, or
17492 + * (at your option) any later version.
17494 + * This program is distributed in the hope that it will be useful,
17495 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17496 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17497 + * GNU General Public License for more details.
17499 + * You should have received a copy of the GNU General Public License
17500 + * along with this program; if not, write to the Free Software
17501 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17505 + * inode operations (del entry)
17511 + * decide if a new whiteout for @dentry is necessary or not.
17512 + * when it is necessary, prepare the parent dir for the upper branch whose
17513 + * branch index is @bcpup for creation. the actual creation of the whiteout will
17514 + * be done by caller.
17516 + * 0: wh is unnecessary
17517 + * plus: wh is necessary
17520 +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
17522 + int need_wh, err;
17523 + aufs_bindex_t bstart;
17524 + struct super_block *sb;
17526 + sb = dentry->d_sb;
17527 + bstart = au_dbstart(dentry);
17528 + if (*bcpup < 0) {
17530 + if (au_test_ro(sb, bstart, dentry->d_inode)) {
17531 + err = AuWbrCopyup(au_sbi(sb), dentry);
17533 + if (unlikely(err < 0))
17537 + AuDebugOn(bstart < *bcpup
17538 + || au_test_ro(sb, *bcpup, dentry->d_inode));
17539 + AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
17541 + if (*bcpup != bstart) {
17542 + err = au_cpup_dirs(dentry, *bcpup);
17543 + if (unlikely(err))
17547 + struct au_dinfo *dinfo, *tmp;
17549 + need_wh = -ENOMEM;
17550 + dinfo = au_di(dentry);
17551 + tmp = au_di_alloc(sb, AuLsc_DI_TMP);
17553 + au_di_cp(tmp, dinfo);
17554 + au_di_swap(tmp, dinfo);
17555 + /* returns the number of positive dentries */
17556 + need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
17557 + au_di_swap(tmp, dinfo);
17558 + au_rw_write_unlock(&tmp->di_rwsem);
17562 + AuDbg("need_wh %d\n", need_wh);
17570 + * simple tests for the del-entry operations.
17571 + * following the checks in vfs, plus the parent-child relationship.
17573 +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
17574 + struct dentry *h_parent, int isdir)
17578 + struct dentry *h_dentry, *h_latest;
17579 + struct inode *h_inode;
17581 + h_dentry = au_h_dptr(dentry, bindex);
17582 + h_inode = h_dentry->d_inode;
17583 + if (dentry->d_inode) {
17585 + if (unlikely(!h_inode || !h_inode->i_nlink))
17588 + h_mode = h_inode->i_mode;
17591 + if (unlikely(S_ISDIR(h_mode)))
17593 + } else if (unlikely(!S_ISDIR(h_mode))) {
17598 + /* rename(2) case */
17600 + if (unlikely(h_inode))
17605 + /* expected parent dir is locked */
17606 + if (unlikely(h_parent != h_dentry->d_parent))
17611 + * rmdir a dir may break the consistency on some filesystem.
17612 + * let's try heavy test.
17615 + if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
17618 + h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
17619 + au_sbr(dentry->d_sb, bindex));
17621 + if (IS_ERR(h_latest))
17623 + if (h_latest == h_dentry)
17632 + * decide the branch where we operate for @dentry. the branch index will be set
17633 + * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
17634 + * dir for reverting.
17635 + * when a new whiteout is necessary, create it.
17637 +static struct dentry*
17638 +lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
17639 + struct au_dtime *dt, struct au_pin *pin)
17641 + struct dentry *wh_dentry;
17642 + struct super_block *sb;
17643 + struct path h_path;
17644 + int err, need_wh;
17645 + unsigned int udba;
17646 + aufs_bindex_t bcpup;
17648 + need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
17649 + wh_dentry = ERR_PTR(need_wh);
17650 + if (unlikely(need_wh < 0))
17653 + sb = dentry->d_sb;
17654 + udba = au_opt_udba(sb);
17656 + err = au_pin(pin, dentry, bcpup, udba,
17657 + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17658 + wh_dentry = ERR_PTR(err);
17659 + if (unlikely(err))
17662 + h_path.dentry = au_pinned_h_parent(pin);
17663 + if (udba != AuOpt_UDBA_NONE
17664 + && au_dbstart(dentry) == bcpup) {
17665 + err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
17666 + wh_dentry = ERR_PTR(err);
17667 + if (unlikely(err))
17671 + h_path.mnt = au_sbr_mnt(sb, bcpup);
17672 + au_dtime_store(dt, au_pinned_parent(pin), &h_path);
17673 + wh_dentry = NULL;
17675 + goto out; /* success, no need to create whiteout */
17677 + wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
17678 + if (IS_ERR(wh_dentry))
17681 + /* returns with the parent is locked and wh_dentry is dget-ed */
17682 + goto out; /* success */
17687 + return wh_dentry;
17691 + * when removing a dir, rename it to a unique temporary whiteout-ed name first
17692 + * in order to be revertible and save time for removing many child whiteouts
17694 + * returns 1 when there are too many child whiteout and caller should remove
17695 + * them asynchronously. returns 0 when the number of children is enough small to
17696 + * remove now or the branch fs is a remote fs.
17697 + * otherwise return an error.
17699 +static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
17700 + struct au_nhash *whlist, struct inode *dir)
17702 + int rmdir_later, err, dirwh;
17703 + struct dentry *h_dentry;
17704 + struct super_block *sb;
17706 + sb = dentry->d_sb;
17707 + SiMustAnyLock(sb);
17708 + h_dentry = au_h_dptr(dentry, bindex);
17709 + err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
17710 + if (unlikely(err))
17713 + /* stop monitoring */
17714 + au_hn_free(au_hi(dentry->d_inode, bindex));
17716 + if (!au_test_fs_remote(h_dentry->d_sb)) {
17717 + dirwh = au_sbi(sb)->si_dirwh;
17718 + rmdir_later = (dirwh <= 1);
17719 + if (!rmdir_later)
17720 + rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
17723 + return rmdir_later;
17726 + err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
17727 + if (unlikely(err)) {
17728 + AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
17729 + AuDLNPair(h_dentry), bindex, err);
17739 + * final procedure for deleting a entry.
17740 + * maintain dentry and iattr.
17742 +static void epilog(struct inode *dir, struct dentry *dentry,
17743 + aufs_bindex_t bindex)
17745 + struct inode *inode;
17747 + inode = dentry->d_inode;
17749 + inode->i_ctime = dir->i_ctime;
17751 + if (au_ibstart(dir) == bindex)
17752 + au_cpup_attr_timesizes(dir);
17753 + dir->i_version++;
17757 + * when an error happened, remove the created whiteout and revert everything.
17759 +static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
17760 + aufs_bindex_t bwh, struct dentry *wh_dentry,
17761 + struct dentry *dentry, struct au_dtime *dt)
17764 + struct path h_path = {
17765 + .dentry = wh_dentry,
17766 + .mnt = au_sbr_mnt(dir->i_sb, bindex)
17769 + rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
17771 + au_set_dbwh(dentry, bwh);
17772 + au_dtime_revert(dt);
17776 + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
17777 + AuDLNPair(dentry), err, rerr);
17781 +/* ---------------------------------------------------------------------- */
17783 +int aufs_unlink(struct inode *dir, struct dentry *dentry)
17786 + aufs_bindex_t bwh, bindex, bstart;
17787 + struct au_dtime dt;
17788 + struct au_pin pin;
17789 + struct path h_path;
17790 + struct inode *inode, *h_dir;
17791 + struct dentry *parent, *wh_dentry;
17795 + err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17796 + if (unlikely(err))
17798 + err = au_d_hashed_positive(dentry);
17799 + if (unlikely(err))
17801 + inode = dentry->d_inode;
17802 + IMustLock(inode);
17804 + if (unlikely(S_ISDIR(inode->i_mode)))
17805 + goto out_unlock; /* possible? */
17807 + bstart = au_dbstart(dentry);
17808 + bwh = au_dbwh(dentry);
17810 + parent = dentry->d_parent; /* dir inode is locked */
17811 + di_write_lock_parent(parent);
17812 + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
17813 + err = PTR_ERR(wh_dentry);
17814 + if (IS_ERR(wh_dentry))
17817 + h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
17818 + h_path.dentry = au_h_dptr(dentry, bstart);
17819 + dget(h_path.dentry);
17820 + if (bindex == bstart) {
17821 + h_dir = au_pinned_h_dir(&pin);
17822 + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
17824 + /* dir inode is locked */
17825 + h_dir = wh_dentry->d_parent->d_inode;
17826 + IMustLock(h_dir);
17831 + vfsub_drop_nlink(inode);
17832 + epilog(dir, dentry, bindex);
17834 + /* update target timestamps */
17835 + if (bindex == bstart) {
17836 + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
17837 + inode->i_ctime = h_path.dentry->d_inode->i_ctime;
17839 + /* todo: this timestamp may be reverted later */
17840 + inode->i_ctime = h_dir->i_ctime;
17841 + goto out_unpin; /* success */
17848 + rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
17856 + dput(h_path.dentry);
17858 + di_write_unlock(parent);
17860 + aufs_read_unlock(dentry, AuLock_DW);
17865 +int aufs_rmdir(struct inode *dir, struct dentry *dentry)
17867 + int err, rmdir_later;
17868 + aufs_bindex_t bwh, bindex, bstart;
17869 + struct au_dtime dt;
17870 + struct au_pin pin;
17871 + struct inode *inode;
17872 + struct dentry *parent, *wh_dentry, *h_dentry;
17873 + struct au_whtmp_rmdir *args;
17877 + err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
17878 + if (unlikely(err))
17880 + err = au_alive_dir(dentry);
17881 + if (unlikely(err))
17883 + inode = dentry->d_inode;
17884 + IMustLock(inode);
17886 + if (unlikely(!S_ISDIR(inode->i_mode)))
17887 + goto out_unlock; /* possible? */
17890 + args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
17891 + if (unlikely(!args))
17894 + parent = dentry->d_parent; /* dir inode is locked */
17895 + di_write_lock_parent(parent);
17896 + err = au_test_empty(dentry, &args->whlist);
17897 + if (unlikely(err))
17900 + bstart = au_dbstart(dentry);
17901 + bwh = au_dbwh(dentry);
17903 + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
17904 + err = PTR_ERR(wh_dentry);
17905 + if (IS_ERR(wh_dentry))
17908 + h_dentry = au_h_dptr(dentry, bstart);
17911 + if (bindex == bstart) {
17912 + err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
17914 + rmdir_later = err;
17918 + /* stop monitoring */
17919 + au_hn_free(au_hi(inode, bstart));
17921 + /* dir inode is locked */
17922 + IMustLock(wh_dentry->d_parent->d_inode);
17927 + vfsub_dead_dir(inode);
17928 + au_set_dbdiropq(dentry, -1);
17929 + epilog(dir, dentry, bindex);
17931 + if (rmdir_later) {
17932 + au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
17936 + goto out_unpin; /* success */
17944 + rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
17954 + di_write_unlock(parent);
17956 + au_whtmp_rmdir_free(args);
17958 + aufs_read_unlock(dentry, AuLock_DW);
17963 diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
17964 --- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
17965 +++ linux/fs/aufs/i_op_ren.c 2013-07-30 22:42:46.235946055 +0200
17968 + * Copyright (C) 2005-2013 Junjiro R. Okajima
17970 + * This program, aufs is free software; you can redistribute it and/or modify
17971 + * it under the terms of the GNU General Public License as published by
17972 + * the Free Software Foundation; either version 2 of the License, or
17973 + * (at your option) any later version.
17975 + * This program is distributed in the hope that it will be useful,
17976 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17977 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17978 + * GNU General Public License for more details.
17980 + * You should have received a copy of the GNU General Public License
17981 + * along with this program; if not, write to the Free Software
17982 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17986 + * inode operation (rename entry)
17987 + * todo: this is crazy monster
17992 +enum { AuSRC, AuDST, AuSrcDst };
17993 +enum { AuPARENT, AuCHILD, AuParentChild };
17995 +#define AuRen_ISDIR 1
17996 +#define AuRen_ISSAMEDIR (1 << 1)
17997 +#define AuRen_WHSRC (1 << 2)
17998 +#define AuRen_WHDST (1 << 3)
17999 +#define AuRen_MNT_WRITE (1 << 4)
18000 +#define AuRen_DT_DSTDIR (1 << 5)
18001 +#define AuRen_DIROPQ (1 << 6)
18002 +#define AuRen_CPUP (1 << 7)
18003 +#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
18004 +#define au_fset_ren(flags, name) \
18005 + do { (flags) |= AuRen_##name; } while (0)
18006 +#define au_fclr_ren(flags, name) \
18007 + do { (flags) &= ~AuRen_##name; } while (0)
18009 +struct au_ren_args {
18011 + struct dentry *dentry, *h_dentry, *parent, *h_parent,
18013 + struct inode *dir, *inode;
18014 + struct au_hinode *hdir;
18015 + struct au_dtime dt[AuParentChild];
18016 + aufs_bindex_t bstart;
18019 +#define src_dentry sd[AuSRC].dentry
18020 +#define src_dir sd[AuSRC].dir
18021 +#define src_inode sd[AuSRC].inode
18022 +#define src_h_dentry sd[AuSRC].h_dentry
18023 +#define src_parent sd[AuSRC].parent
18024 +#define src_h_parent sd[AuSRC].h_parent
18025 +#define src_wh_dentry sd[AuSRC].wh_dentry
18026 +#define src_hdir sd[AuSRC].hdir
18027 +#define src_h_dir sd[AuSRC].hdir->hi_inode
18028 +#define src_dt sd[AuSRC].dt
18029 +#define src_bstart sd[AuSRC].bstart
18031 +#define dst_dentry sd[AuDST].dentry
18032 +#define dst_dir sd[AuDST].dir
18033 +#define dst_inode sd[AuDST].inode
18034 +#define dst_h_dentry sd[AuDST].h_dentry
18035 +#define dst_parent sd[AuDST].parent
18036 +#define dst_h_parent sd[AuDST].h_parent
18037 +#define dst_wh_dentry sd[AuDST].wh_dentry
18038 +#define dst_hdir sd[AuDST].hdir
18039 +#define dst_h_dir sd[AuDST].hdir->hi_inode
18040 +#define dst_dt sd[AuDST].dt
18041 +#define dst_bstart sd[AuDST].bstart
18043 + struct dentry *h_trap;
18044 + struct au_branch *br;
18045 + struct au_hinode *src_hinode;
18046 + struct path h_path;
18047 + struct au_nhash whlist;
18048 + aufs_bindex_t btgt, src_bwh, src_bdiropq;
18050 + unsigned int flags;
18052 + struct au_whtmp_rmdir *thargs;
18053 + struct dentry *h_dst;
18056 +/* ---------------------------------------------------------------------- */
18059 + * functions for reverting.
18060 + * when an error happened in a single rename systemcall, we should revert
18061 + * everything as if nothing happend.
18062 + * we don't need to revert the copied-up/down the parent dir since they are
18066 +#define RevertFailure(fmt, ...) do { \
18067 + AuIOErr("revert failure: " fmt " (%d, %d)\n", \
18068 + ##__VA_ARGS__, err, rerr); \
18072 +static void au_ren_rev_diropq(int err, struct au_ren_args *a)
18076 + au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18077 + rerr = au_diropq_remove(a->src_dentry, a->btgt);
18078 + au_hn_imtx_unlock(a->src_hinode);
18079 + au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
18081 + RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
18084 +static void au_ren_rev_rename(int err, struct au_ren_args *a)
18088 + a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
18089 + a->src_h_parent);
18090 + rerr = PTR_ERR(a->h_path.dentry);
18091 + if (IS_ERR(a->h_path.dentry)) {
18092 + RevertFailure("lkup one %.*s", AuDLNPair(a->src_dentry));
18096 + rerr = vfsub_rename(a->dst_h_dir,
18097 + au_h_dptr(a->src_dentry, a->btgt),
18098 + a->src_h_dir, &a->h_path);
18099 + d_drop(a->h_path.dentry);
18100 + dput(a->h_path.dentry);
18101 + /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
18103 + RevertFailure("rename %.*s", AuDLNPair(a->src_dentry));
18106 +static void au_ren_rev_cpup(int err, struct au_ren_args *a)
18110 + a->h_path.dentry = a->dst_h_dentry;
18111 + rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0);
18112 + au_set_h_dptr(a->src_dentry, a->btgt, NULL);
18113 + au_set_dbstart(a->src_dentry, a->src_bstart);
18115 + RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry));
18118 +static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
18122 + a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
18123 + a->dst_h_parent);
18124 + rerr = PTR_ERR(a->h_path.dentry);
18125 + if (IS_ERR(a->h_path.dentry)) {
18126 + RevertFailure("lkup one %.*s", AuDLNPair(a->dst_dentry));
18129 + if (a->h_path.dentry->d_inode) {
18130 + d_drop(a->h_path.dentry);
18131 + dput(a->h_path.dentry);
18135 + rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path);
18136 + d_drop(a->h_path.dentry);
18137 + dput(a->h_path.dentry);
18139 + au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
18141 + RevertFailure("rename %.*s", AuDLNPair(a->h_dst));
18144 +static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
18148 + a->h_path.dentry = a->src_wh_dentry;
18149 + rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
18150 + au_set_dbwh(a->src_dentry, a->src_bwh);
18152 + RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
18154 +#undef RevertFailure
18156 +/* ---------------------------------------------------------------------- */
18159 + * when we have to copyup the renaming entry, do it with the rename-target name
18160 + * in order to minimize the cost (the later actual rename is unnecessary).
18161 + * otherwise rename it on the target branch.
18163 +static int au_ren_or_cpup(struct au_ren_args *a)
18166 + struct dentry *d;
18168 + d = a->src_dentry;
18169 + if (au_dbstart(d) == a->btgt) {
18170 + a->h_path.dentry = a->dst_h_dentry;
18171 + if (au_ftest_ren(a->flags, DIROPQ)
18172 + && au_dbdiropq(d) == a->btgt)
18173 + au_fclr_ren(a->flags, DIROPQ);
18174 + AuDebugOn(au_dbstart(d) != a->btgt);
18175 + err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
18176 + a->dst_h_dir, &a->h_path);
18181 + struct file *h_file;
18183 + au_fset_ren(a->flags, CPUP);
18184 + au_set_dbstart(d, a->btgt);
18185 + au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry));
18186 + h_file = au_h_open_pre(d, a->src_bstart);
18187 + if (IS_ERR(h_file))
18188 + err = PTR_ERR(h_file);
18190 + err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1,
18191 + !AuCpup_DTIME, a->dst_parent);
18192 + au_h_open_post(d, a->src_bstart, h_file);
18195 + d = a->dst_dentry;
18196 + au_set_h_dptr(d, a->btgt, NULL);
18197 + au_update_dbstart(d);
18199 + au_set_h_dptr(d, a->btgt, NULL);
18200 + au_set_dbstart(d, a->src_bstart);
18204 + if (!err && a->h_dst)
18205 + /* it will be set to dinfo later */
18211 +/* cf. aufs_rmdir() */
18212 +static int au_ren_del_whtmp(struct au_ren_args *a)
18215 + struct inode *dir;
18217 + dir = a->dst_dir;
18218 + SiMustAnyLock(dir->i_sb);
18219 + if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
18220 + au_sbi(dir->i_sb)->si_dirwh)
18221 + || au_test_fs_remote(a->h_dst->d_sb)) {
18222 + err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
18223 + if (unlikely(err))
18224 + pr_warn("failed removing whtmp dir %.*s (%d), "
18225 + "ignored.\n", AuDLNPair(a->h_dst), err);
18227 + au_nhash_wh_free(&a->thargs->whlist);
18228 + a->thargs->whlist = a->whlist;
18229 + a->whlist.nh_num = 0;
18230 + au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
18232 + a->thargs = NULL;
18238 +/* make it 'opaque' dir. */
18239 +static int au_ren_diropq(struct au_ren_args *a)
18242 + struct dentry *diropq;
18245 + a->src_bdiropq = au_dbdiropq(a->src_dentry);
18246 + a->src_hinode = au_hi(a->src_inode, a->btgt);
18247 + au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18248 + diropq = au_diropq_create(a->src_dentry, a->btgt);
18249 + au_hn_imtx_unlock(a->src_hinode);
18250 + if (IS_ERR(diropq))
18251 + err = PTR_ERR(diropq);
18257 +static int do_rename(struct au_ren_args *a)
18260 + struct dentry *d, *h_d;
18262 + /* prepare workqueue args for asynchronous rmdir */
18263 + h_d = a->dst_h_dentry;
18264 + if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
18266 + a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
18267 + if (unlikely(!a->thargs))
18269 + a->h_dst = dget(h_d);
18272 + /* create whiteout for src_dentry */
18273 + if (au_ftest_ren(a->flags, WHSRC)) {
18274 + a->src_bwh = au_dbwh(a->src_dentry);
18275 + AuDebugOn(a->src_bwh >= 0);
18277 + = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
18278 + err = PTR_ERR(a->src_wh_dentry);
18279 + if (IS_ERR(a->src_wh_dentry))
18283 + /* lookup whiteout for dentry */
18284 + if (au_ftest_ren(a->flags, WHDST)) {
18285 + h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
18287 + err = PTR_ERR(h_d);
18290 + if (!h_d->d_inode)
18293 + a->dst_wh_dentry = h_d;
18296 + /* rename dentry to tmpwh */
18298 + err = au_whtmp_ren(a->dst_h_dentry, a->br);
18299 + if (unlikely(err))
18302 + d = a->dst_dentry;
18303 + au_set_h_dptr(d, a->btgt, NULL);
18304 + err = au_lkup_neg(d, a->btgt, /*wh*/0);
18305 + if (unlikely(err))
18307 + a->dst_h_dentry = au_h_dptr(d, a->btgt);
18311 + if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) {
18315 + struct file *h_file;
18317 + h_file = au_h_open_pre(a->src_dentry, a->src_bstart);
18318 + if (IS_ERR(h_file))
18319 + err = PTR_ERR(h_file);
18321 + err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1,
18323 + au_h_open_post(a->src_dentry, a->src_bstart, h_file);
18325 + if (unlikely(err))
18330 + /* rename by vfs_rename or cpup */
18331 + d = a->dst_dentry;
18332 + if (au_ftest_ren(a->flags, ISDIR)
18333 + && (a->dst_wh_dentry
18334 + || au_dbdiropq(d) == a->btgt
18335 + /* hide the lower to keep xino */
18336 + || a->btgt < au_dbend(d)
18337 + || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
18338 + au_fset_ren(a->flags, DIROPQ);
18339 + err = au_ren_or_cpup(a);
18340 + if (unlikely(err))
18341 + /* leave the copied-up one */
18344 + /* make dir opaque */
18345 + if (au_ftest_ren(a->flags, DIROPQ)) {
18346 + err = au_ren_diropq(a);
18347 + if (unlikely(err))
18351 + /* update target timestamps */
18352 + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
18353 + a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
18354 + vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
18355 + a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
18357 + /* remove whiteout for dentry */
18358 + if (a->dst_wh_dentry) {
18359 + a->h_path.dentry = a->dst_wh_dentry;
18360 + err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
18362 + if (unlikely(err))
18366 + /* remove whtmp */
18368 + au_ren_del_whtmp(a); /* ignore this error */
18371 + goto out_success;
18374 + if (au_ftest_ren(a->flags, DIROPQ))
18375 + au_ren_rev_diropq(err, a);
18377 + if (!au_ftest_ren(a->flags, CPUP))
18378 + au_ren_rev_rename(err, a);
18380 + au_ren_rev_cpup(err, a);
18384 + au_ren_rev_whtmp(err, a);
18386 + dput(a->dst_wh_dentry);
18387 + a->dst_wh_dentry = NULL;
18389 + if (a->src_wh_dentry)
18390 + au_ren_rev_whsrc(err, a);
18392 + dput(a->src_wh_dentry);
18393 + dput(a->dst_wh_dentry);
18397 + au_whtmp_rmdir_free(a->thargs);
18398 + a->thargs = NULL;
18404 +/* ---------------------------------------------------------------------- */
18407 + * test if @dentry dir can be rename destination or not.
18408 + * success means, it is a logically empty dir.
18410 +static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
18412 + return au_test_empty(dentry, whlist);
18416 + * test if @dentry dir can be rename source or not.
18417 + * if it can, return 0 and @children is filled.
18419 + * - it is a logically empty dir.
18420 + * - or, it exists on writable branch and has no children including whiteouts
18421 + * on the lower branch.
18423 +static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
18426 + unsigned int rdhash;
18427 + aufs_bindex_t bstart;
18429 + bstart = au_dbstart(dentry);
18430 + if (bstart != btgt) {
18431 + struct au_nhash whlist;
18433 + SiMustAnyLock(dentry->d_sb);
18434 + rdhash = au_sbi(dentry->d_sb)->si_rdhash;
18436 + rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
18438 + err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
18439 + if (unlikely(err))
18441 + err = au_test_empty(dentry, &whlist);
18442 + au_nhash_wh_free(&whlist);
18446 + if (bstart == au_dbtaildir(dentry))
18447 + return 0; /* success */
18449 + err = au_test_empty_lower(dentry);
18452 + if (err == -ENOTEMPTY) {
18453 + AuWarn1("renaming dir who has child(ren) on multiple branches,"
18454 + " is not supported\n");
18460 +/* side effect: sets whlist and h_dentry */
18461 +static int au_ren_may_dir(struct au_ren_args *a)
18464 + unsigned int rdhash;
18465 + struct dentry *d;
18467 + d = a->dst_dentry;
18468 + SiMustAnyLock(d->d_sb);
18471 + if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
18472 + rdhash = au_sbi(d->d_sb)->si_rdhash;
18474 + rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
18475 + err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
18476 + if (unlikely(err))
18479 + au_set_dbstart(d, a->dst_bstart);
18480 + err = may_rename_dstdir(d, &a->whlist);
18481 + au_set_dbstart(d, a->btgt);
18483 + a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
18484 + if (unlikely(err))
18487 + d = a->src_dentry;
18488 + a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
18489 + if (au_ftest_ren(a->flags, ISDIR)) {
18490 + err = may_rename_srcdir(d, a->btgt);
18491 + if (unlikely(err)) {
18492 + au_nhash_wh_free(&a->whlist);
18493 + a->whlist.nh_num = 0;
18500 +/* ---------------------------------------------------------------------- */
18503 + * simple tests for rename.
18504 + * following the checks in vfs, plus the parent-child relationship.
18506 +static int au_may_ren(struct au_ren_args *a)
18509 + struct inode *h_inode;
18511 + if (a->src_bstart == a->btgt) {
18512 + err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
18513 + au_ftest_ren(a->flags, ISDIR));
18514 + if (unlikely(err))
18517 + if (unlikely(a->src_h_dentry == a->h_trap))
18522 + if (a->dst_bstart != a->btgt)
18525 + err = -ENOTEMPTY;
18526 + if (unlikely(a->dst_h_dentry == a->h_trap))
18530 + h_inode = a->dst_h_dentry->d_inode;
18531 + isdir = !!au_ftest_ren(a->flags, ISDIR);
18532 + if (!a->dst_dentry->d_inode) {
18533 + if (unlikely(h_inode))
18535 + err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
18538 + if (unlikely(!h_inode || !h_inode->i_nlink))
18540 + err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
18542 + if (unlikely(err))
18547 + if (unlikely(err == -ENOENT || err == -EEXIST))
18553 +/* ---------------------------------------------------------------------- */
18558 + * - src_dir and dir by lock_rename()
18559 + * - inode if exitsts
18562 + * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
18564 + * + di_write_lock2_child()
18565 + * + di_write_lock_child()
18566 + * + ii_write_lock_child()
18567 + * + di_write_lock_child2()
18568 + * + ii_write_lock_child2()
18569 + * + src_parent and parent
18570 + * + di_write_lock_parent()
18571 + * + ii_write_lock_parent()
18572 + * + di_write_lock_parent2()
18573 + * + ii_write_lock_parent2()
18574 + * + lower src_dir and dir by vfsub_lock_rename()
18575 + * + verify the every relationships between child and parent. if any
18576 + * of them failed, unlock all and return -EBUSY.
18578 +static void au_ren_unlock(struct au_ren_args *a)
18580 + vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
18581 + a->dst_h_parent, a->dst_hdir);
18582 + if (au_ftest_ren(a->flags, MNT_WRITE))
18583 + vfsub_mnt_drop_write(au_br_mnt(a->br));
18586 +static int au_ren_lock(struct au_ren_args *a)
18589 + unsigned int udba;
18592 + a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
18593 + a->src_hdir = au_hi(a->src_dir, a->btgt);
18594 + a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
18595 + a->dst_hdir = au_hi(a->dst_dir, a->btgt);
18597 + err = vfsub_mnt_want_write(au_br_mnt(a->br));
18598 + if (unlikely(err))
18600 + au_fset_ren(a->flags, MNT_WRITE);
18601 + a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
18602 + a->dst_h_parent, a->dst_hdir);
18603 + udba = au_opt_udba(a->src_dentry->d_sb);
18604 + if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
18605 + || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
18606 + err = au_busy_or_stale();
18607 + if (!err && au_dbstart(a->src_dentry) == a->btgt)
18608 + err = au_h_verify(a->src_h_dentry, udba,
18609 + a->src_h_parent->d_inode, a->src_h_parent,
18611 + if (!err && au_dbstart(a->dst_dentry) == a->btgt)
18612 + err = au_h_verify(a->dst_h_dentry, udba,
18613 + a->dst_h_parent->d_inode, a->dst_h_parent,
18616 + goto out; /* success */
18618 + err = au_busy_or_stale();
18619 + au_ren_unlock(a);
18625 +/* ---------------------------------------------------------------------- */
18627 +static void au_ren_refresh_dir(struct au_ren_args *a)
18629 + struct inode *dir;
18631 + dir = a->dst_dir;
18632 + dir->i_version++;
18633 + if (au_ftest_ren(a->flags, ISDIR)) {
18634 + /* is this updating defined in POSIX? */
18635 + au_cpup_attr_timesizes(a->src_inode);
18636 + au_cpup_attr_nlink(dir, /*force*/1);
18639 + if (au_ibstart(dir) == a->btgt)
18640 + au_cpup_attr_timesizes(dir);
18642 + if (au_ftest_ren(a->flags, ISSAMEDIR))
18645 + dir = a->src_dir;
18646 + dir->i_version++;
18647 + if (au_ftest_ren(a->flags, ISDIR))
18648 + au_cpup_attr_nlink(dir, /*force*/1);
18649 + if (au_ibstart(dir) == a->btgt)
18650 + au_cpup_attr_timesizes(dir);
18653 +static void au_ren_refresh(struct au_ren_args *a)
18655 + aufs_bindex_t bend, bindex;
18656 + struct dentry *d, *h_d;
18657 + struct inode *i, *h_i;
18658 + struct super_block *sb;
18660 + d = a->dst_dentry;
18663 + /* already dget-ed by au_ren_or_cpup() */
18664 + au_set_h_dptr(d, a->btgt, a->h_dst);
18666 + i = a->dst_inode;
18668 + if (!au_ftest_ren(a->flags, ISDIR))
18669 + vfsub_drop_nlink(i);
18671 + vfsub_dead_dir(i);
18672 + au_cpup_attr_timesizes(i);
18674 + au_update_dbrange(d, /*do_put_zero*/1);
18677 + for (bindex = au_dbstart(d); bindex < bend; bindex++)
18678 + au_set_h_dptr(d, bindex, NULL);
18679 + bend = au_dbend(d);
18680 + for (bindex = a->btgt + 1; bindex <= bend; bindex++)
18681 + au_set_h_dptr(d, bindex, NULL);
18682 + au_update_dbrange(d, /*do_put_zero*/0);
18685 + d = a->src_dentry;
18686 + au_set_dbwh(d, -1);
18687 + bend = au_dbend(d);
18688 + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18689 + h_d = au_h_dptr(d, bindex);
18691 + au_set_h_dptr(d, bindex, NULL);
18693 + au_set_dbend(d, a->btgt);
18696 + i = a->src_inode;
18697 + if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
18698 + return; /* success */
18700 + bend = au_ibend(i);
18701 + for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18702 + h_i = au_h_iptr(i, bindex);
18704 + au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
18705 + /* ignore this error */
18706 + au_set_h_iptr(i, bindex, NULL, 0);
18709 + au_set_ibend(i, a->btgt);
18712 +/* ---------------------------------------------------------------------- */
18714 +/* mainly for link(2) and rename(2) */
18715 +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
18717 + aufs_bindex_t bdiropq, bwh;
18718 + struct dentry *parent;
18719 + struct au_branch *br;
18721 + parent = dentry->d_parent;
18722 + IMustLock(parent->d_inode); /* dir is locked */
18724 + bdiropq = au_dbdiropq(parent);
18725 + bwh = au_dbwh(dentry);
18726 + br = au_sbr(dentry->d_sb, btgt);
18727 + if (au_br_rdonly(br)
18728 + || (0 <= bdiropq && bdiropq < btgt)
18729 + || (0 <= bwh && bwh < btgt))
18732 + AuDbg("btgt %d\n", btgt);
18736 +/* sets src_bstart, dst_bstart and btgt */
18737 +static int au_ren_wbr(struct au_ren_args *a)
18740 + struct au_wr_dir_args wr_dir_args = {
18741 + /* .force_btgt = -1, */
18742 + .flags = AuWrDir_ADD_ENTRY
18745 + a->src_bstart = au_dbstart(a->src_dentry);
18746 + a->dst_bstart = au_dbstart(a->dst_dentry);
18747 + if (au_ftest_ren(a->flags, ISDIR))
18748 + au_fset_wrdir(wr_dir_args.flags, ISDIR);
18749 + wr_dir_args.force_btgt = a->src_bstart;
18750 + if (a->dst_inode && a->dst_bstart < a->src_bstart)
18751 + wr_dir_args.force_btgt = a->dst_bstart;
18752 + wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
18753 + err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
18759 +static void au_ren_dt(struct au_ren_args *a)
18761 + a->h_path.dentry = a->src_h_parent;
18762 + au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
18763 + if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
18764 + a->h_path.dentry = a->dst_h_parent;
18765 + au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
18768 + au_fclr_ren(a->flags, DT_DSTDIR);
18769 + if (!au_ftest_ren(a->flags, ISDIR))
18772 + a->h_path.dentry = a->src_h_dentry;
18773 + au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
18774 + if (a->dst_h_dentry->d_inode) {
18775 + au_fset_ren(a->flags, DT_DSTDIR);
18776 + a->h_path.dentry = a->dst_h_dentry;
18777 + au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
18781 +static void au_ren_rev_dt(int err, struct au_ren_args *a)
18783 + struct dentry *h_d;
18784 + struct mutex *h_mtx;
18786 + au_dtime_revert(a->src_dt + AuPARENT);
18787 + if (!au_ftest_ren(a->flags, ISSAMEDIR))
18788 + au_dtime_revert(a->dst_dt + AuPARENT);
18790 + if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
18791 + h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
18792 + h_mtx = &h_d->d_inode->i_mutex;
18793 + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18794 + au_dtime_revert(a->src_dt + AuCHILD);
18795 + mutex_unlock(h_mtx);
18797 + if (au_ftest_ren(a->flags, DT_DSTDIR)) {
18798 + h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
18799 + h_mtx = &h_d->d_inode->i_mutex;
18800 + mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18801 + au_dtime_revert(a->dst_dt + AuCHILD);
18802 + mutex_unlock(h_mtx);
18807 +/* ---------------------------------------------------------------------- */
18809 +int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
18810 + struct inode *_dst_dir, struct dentry *_dst_dentry)
18813 + /* reduce stack space */
18814 + struct au_ren_args *a;
18816 + AuDbg("%.*s, %.*s\n", AuDLNPair(_src_dentry), AuDLNPair(_dst_dentry));
18817 + IMustLock(_src_dir);
18818 + IMustLock(_dst_dir);
18821 + BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
18822 + a = kzalloc(sizeof(*a), GFP_NOFS);
18823 + if (unlikely(!a))
18826 + a->src_dir = _src_dir;
18827 + a->src_dentry = _src_dentry;
18828 + a->src_inode = a->src_dentry->d_inode;
18829 + a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
18830 + a->dst_dir = _dst_dir;
18831 + a->dst_dentry = _dst_dentry;
18832 + a->dst_inode = a->dst_dentry->d_inode;
18833 + a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
18834 + if (a->dst_inode) {
18835 + IMustLock(a->dst_inode);
18836 + au_igrab(a->dst_inode);
18840 + flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
18841 + if (S_ISDIR(a->src_inode->i_mode)) {
18842 + au_fset_ren(a->flags, ISDIR);
18843 + if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
18845 + err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18846 + AuLock_DIR | flags);
18848 + err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18850 + if (unlikely(err))
18853 + err = au_d_hashed_positive(a->src_dentry);
18854 + if (unlikely(err))
18857 + if (a->dst_inode) {
18859 + * If it is a dir, VFS unhash dst_dentry before this
18860 + * function. It means we cannot rely upon d_unhashed().
18862 + if (unlikely(!a->dst_inode->i_nlink))
18864 + if (!S_ISDIR(a->dst_inode->i_mode)) {
18865 + err = au_d_hashed_positive(a->dst_dentry);
18866 + if (unlikely(err))
18868 + } else if (unlikely(IS_DEADDIR(a->dst_inode)))
18870 + } else if (unlikely(d_unhashed(a->dst_dentry)))
18874 + * is it possible?
18875 + * yes, it happend (in linux-3.3-rcN) but I don't know why.
18876 + * there may exist a problem somewhere else.
18879 + if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
18882 + au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
18883 + di_write_lock_parent(a->dst_parent);
18885 + /* which branch we process */
18886 + err = au_ren_wbr(a);
18887 + if (unlikely(err < 0))
18889 + a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
18890 + a->h_path.mnt = au_br_mnt(a->br);
18892 + /* are they available to be renamed */
18893 + err = au_ren_may_dir(a);
18894 + if (unlikely(err))
18895 + goto out_children;
18897 + /* prepare the writable parent dir on the same branch */
18898 + if (a->dst_bstart == a->btgt) {
18899 + au_fset_ren(a->flags, WHDST);
18901 + err = au_cpup_dirs(a->dst_dentry, a->btgt);
18902 + if (unlikely(err))
18903 + goto out_children;
18906 + if (a->src_dir != a->dst_dir) {
18908 + * this temporary unlock is safe,
18909 + * because both dir->i_mutex are locked.
18911 + di_write_unlock(a->dst_parent);
18912 + di_write_lock_parent(a->src_parent);
18913 + err = au_wr_dir_need_wh(a->src_dentry,
18914 + au_ftest_ren(a->flags, ISDIR),
18916 + di_write_unlock(a->src_parent);
18917 + di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
18918 + au_fclr_ren(a->flags, ISSAMEDIR);
18920 + err = au_wr_dir_need_wh(a->src_dentry,
18921 + au_ftest_ren(a->flags, ISDIR),
18923 + if (unlikely(err < 0))
18924 + goto out_children;
18926 + au_fset_ren(a->flags, WHSRC);
18929 + if (a->src_bstart != a->btgt) {
18930 + struct au_pin pin;
18932 + err = au_pin(&pin, a->src_dentry, a->btgt,
18933 + au_opt_udba(a->src_dentry->d_sb),
18934 + AuPin_DI_LOCKED | AuPin_MNT_WRITE);
18936 + AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
18937 + err = au_sio_cpup_simple_h_open(a->src_dentry, a->btgt,
18938 + -1, AuCpup_DTIME, &pin,
18942 + if (unlikely(err))
18943 + goto out_children;
18944 + a->src_bstart = a->btgt;
18945 + a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
18946 + au_fset_ren(a->flags, WHSRC);
18949 + /* lock them all */
18950 + err = au_ren_lock(a);
18951 + if (unlikely(err))
18952 + /* leave the copied-up one */
18953 + goto out_children;
18955 + if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
18956 + err = au_may_ren(a);
18957 + else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
18958 + err = -ENAMETOOLONG;
18959 + if (unlikely(err))
18962 + /* store timestamps to be revertible */
18966 + err = do_rename(a);
18967 + if (unlikely(err))
18970 + /* update dir attributes */
18971 + au_ren_refresh_dir(a);
18973 + /* dput/iput all lower dentries */
18974 + au_ren_refresh(a);
18976 + goto out_hdir; /* success */
18979 + au_ren_rev_dt(err, a);
18981 + au_ren_unlock(a);
18983 + au_nhash_wh_free(&a->whlist);
18984 + if (err && a->dst_inode && a->dst_bstart != a->btgt) {
18985 + AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
18986 + au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
18987 + au_set_dbstart(a->dst_dentry, a->dst_bstart);
18991 + d_move(a->src_dentry, a->dst_dentry);
18993 + au_update_dbstart(a->dst_dentry);
18994 + if (!a->dst_inode)
18995 + d_drop(a->dst_dentry);
18997 + if (au_ftest_ren(a->flags, ISSAMEDIR))
18998 + di_write_unlock(a->dst_parent);
19000 + di_write_unlock2(a->src_parent, a->dst_parent);
19002 + aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
19004 + iput(a->dst_inode);
19006 + au_whtmp_rmdir_free(a->thargs);
19012 diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
19013 --- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
19014 +++ linux/fs/aufs/Kconfig 2013-07-06 13:20:47.736864659 +0200
19017 + tristate "Aufs (Advanced multi layered unification filesystem) support"
19019 + Aufs is a stackable unification filesystem such as Unionfs,
19020 + which unifies several directories and provides a merged single
19022 + In the early days, aufs was entirely re-designed and
19023 + re-implemented Unionfs Version 1.x series. Introducing many
19024 + original ideas, approaches and improvements, it becomes totally
19025 + different from Unionfs while keeping the basic features.
19029 + prompt "Maximum number of branches"
19030 + default AUFS_BRANCH_MAX_127
19032 + Specifies the maximum number of branches (or member directories)
19033 + in a single aufs. The larger value consumes more system
19034 + resources and has a minor impact to performance.
19035 +config AUFS_BRANCH_MAX_127
19038 + Specifies the maximum number of branches (or member directories)
19039 + in a single aufs. The larger value consumes more system
19040 + resources and has a minor impact to performance.
19041 +config AUFS_BRANCH_MAX_511
19044 + Specifies the maximum number of branches (or member directories)
19045 + in a single aufs. The larger value consumes more system
19046 + resources and has a minor impact to performance.
19047 +config AUFS_BRANCH_MAX_1023
19050 + Specifies the maximum number of branches (or member directories)
19051 + in a single aufs. The larger value consumes more system
19052 + resources and has a minor impact to performance.
19053 +config AUFS_BRANCH_MAX_32767
19056 + Specifies the maximum number of branches (or member directories)
19057 + in a single aufs. The larger value consumes more system
19058 + resources and has a minor impact to performance.
19061 +config AUFS_SBILIST
19063 + depends on AUFS_MAGIC_SYSRQ || PROC_FS
19066 + Automatic configuration for internal use.
19067 + When aufs supports Magic SysRq or /proc, enabled automatically.
19069 +config AUFS_HNOTIFY
19070 + bool "Detect direct branch access (bypassing aufs)"
19072 + If you want to modify files on branches directly, eg. bypassing aufs,
19073 + and want aufs to detect the changes of them fully, then enable this
19074 + option and use 'udba=notify' mount option.
19075 + Currently there is only one available configuration, "fsnotify".
19076 + It will have a negative impact to the performance.
19077 + See detail in aufs.5.
19080 + prompt "method" if AUFS_HNOTIFY
19081 + default AUFS_HFSNOTIFY
19082 +config AUFS_HFSNOTIFY
19087 +config AUFS_EXPORT
19088 + bool "NFS-exportable aufs"
19089 + depends on EXPORTFS
19091 + If you want to export your mounted aufs via NFS, then enable this
19092 + option. There are several requirements for this configuration.
19093 + See detail in aufs.5.
19095 +config AUFS_INO_T_64
19097 + depends on AUFS_EXPORT
19098 + depends on 64BIT && !(ALPHA || S390)
19101 + Automatic configuration for internal use.
19102 + /* typedef unsigned long/int __kernel_ino_t */
19103 + /* alpha and s390x are int */
19106 + bool "Readdir in userspace"
19108 + Aufs has two methods to provide a merged view for a directory,
19109 + by a user-space library and by kernel-space natively. The latter
19110 + is always enabled but sometimes large and slow.
19111 + If you enable this option, install the library in aufs2-util
19112 + package, and set some environment variables for your readdir(3),
19113 + then the work will be handled in user-space which generally
19114 + shows better performance in most cases.
19115 + See detail in aufs.5.
19117 +config AUFS_PROC_MAP
19118 + bool "support for /proc/maps and lsof(1)"
19119 + depends on PROC_FS
19121 + When you issue mmap(2) in aufs, it is actually a direct mmap(2)
19122 + call to the file on the branch fs since the file in aufs is
19123 + purely virtual. And the file path printed in /proc/maps (and
19124 + others) will be the path on the branch fs. In most cases, it
19125 + does no harm. But some utilities like lsof(1) may confuse since
19126 + the utility or user may expect the file path in aufs to be
19128 + To address this issue, aufs provides a patch which introduces a
19129 + new member called vm_prfile into struct vm_are_struct. The patch
19130 + is meaningless without enabling this configuration since nobody
19131 + sets the new vm_prfile member.
19132 + If you don't apply the patch, then enabling this configuration
19133 + will cause a compile error.
19134 + This approach is fragile since if someone else make some changes
19135 + around vm_file, then vm_prfile may not work anymore. As a
19136 + workaround such case, aufs provides this configuration. If you
19137 + disable it, then lsof(1) may produce incorrect result but the
19138 + problem will be gone even if the aufs patch is applied (I hope).
19140 +config AUFS_SP_IATTR
19141 + bool "Respect the attributes (mtime/ctime mainly) of special files"
19143 + When you write something to a special file, some attributes of it
19144 + (mtime/ctime mainly) may be updated. Generally such updates are
19145 + less important (actually some device drivers and NFS ignore
19146 + it). But some applications (such like test program) requires
19147 + such updates. If you need these updates, then enable this
19148 + configuration which introduces some overhead.
19149 + Currently this configuration handles FIFO only.
19152 + bool "Show whiteouts"
19154 + If you want to make the whiteouts in aufs visible, then enable
19155 + this option and specify 'shwh' mount option. Although it may
19156 + sounds like philosophy or something, but in technically it
19157 + simply shows the name of whiteout with keeping its behaviour.
19159 +config AUFS_BR_RAMFS
19160 + bool "Ramfs (initramfs/rootfs) as an aufs branch"
19162 + If you want to use ramfs as an aufs branch fs, then enable this
19163 + option. Generally tmpfs is recommended.
19164 + Aufs prohibited them to be a branch fs by default, because
19165 + initramfs becomes unusable after switch_root or something
19166 + generally. If you sets initramfs as an aufs branch and boot your
19167 + system by switch_root, you will meet a problem easily since the
19168 + files in initramfs may be inaccessible.
19169 + Unless you are going to use ramfs as an aufs branch fs without
19170 + switch_root or something, leave it N.
19172 +config AUFS_BR_FUSE
19173 + bool "Fuse fs as an aufs branch"
19174 + depends on FUSE_FS
19177 + If you want to use fuse-based userspace filesystem as an aufs
19178 + branch fs, then enable this option.
19179 + It implements the internal poll(2) operation which is
19180 + implemented by fuse only (curretnly).
19185 + Automatic configuration for internal use.
19187 +config AUFS_BR_HFSPLUS
19188 + bool "Hfsplus as an aufs branch"
19189 + depends on HFSPLUS_FS
19192 + If you want to use hfsplus fs as an aufs branch fs, then enable
19193 + this option. This option introduces a small overhead at
19194 + copying-up a file on hfsplus.
19196 +config AUFS_BDEV_LOOP
19198 + depends on BLK_DEV_LOOP
19201 + Automatic configuration for internal use.
19202 + Convert =[ym] into =y.
19205 + bool "Debug aufs"
19207 + Enable this to compile aufs internal debug code.
19208 + It will have a negative impact to the performance.
19210 +config AUFS_MAGIC_SYSRQ
19212 + depends on AUFS_DEBUG && MAGIC_SYSRQ
19215 + Automatic configuration for internal use.
19216 + When aufs supports Magic SysRq, enabled automatically.
19218 diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
19219 --- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
19220 +++ linux/fs/aufs/loop.c 2013-07-30 22:42:55.842946719 +0200
19223 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19225 + * This program, aufs is free software; you can redistribute it and/or modify
19226 + * it under the terms of the GNU General Public License as published by
19227 + * the Free Software Foundation; either version 2 of the License, or
19228 + * (at your option) any later version.
19230 + * This program is distributed in the hope that it will be useful,
19231 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19232 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19233 + * GNU General Public License for more details.
19235 + * You should have received a copy of the GNU General Public License
19236 + * along with this program; if not, write to the Free Software
19237 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19241 + * support for loopback block device as a branch
19244 +#include <linux/loop.h>
19248 + * test if two lower dentries have overlapping branches.
19250 +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
19252 + struct super_block *h_sb;
19253 + struct loop_device *l;
19255 + h_sb = h_adding->d_sb;
19256 + if (MAJOR(h_sb->s_dev) != LOOP_MAJOR)
19259 + l = h_sb->s_bdev->bd_disk->private_data;
19260 + h_adding = l->lo_backing_file->f_dentry;
19262 + * h_adding can be local NFS.
19263 + * in this case aufs cannot detect the loop.
19265 + if (unlikely(h_adding->d_sb == sb))
19267 + return !!au_test_subdir(h_adding, sb->s_root);
19270 +/* true if a kernel thread named 'loop[0-9].*' accesses a file */
19271 +int au_test_loopback_kthread(void)
19274 + struct task_struct *tsk = current;
19275 + char c, comm[sizeof(tsk->comm)];
19278 + if (tsk->flags & PF_KTHREAD) {
19279 + get_task_comm(comm, tsk);
19281 + ret = ('0' <= c && c <= '9'
19282 + && !strncmp(comm, "loop", 4));
19288 +/* ---------------------------------------------------------------------- */
19290 +#define au_warn_loopback_step 16
19291 +static int au_warn_loopback_nelem = au_warn_loopback_step;
19292 +static unsigned long *au_warn_loopback_array;
19294 +void au_warn_loopback(struct super_block *h_sb)
19296 + int i, new_nelem;
19297 + unsigned long *a, magic;
19298 + static DEFINE_SPINLOCK(spin);
19300 + magic = h_sb->s_magic;
19301 + spin_lock(&spin);
19302 + a = au_warn_loopback_array;
19303 + for (i = 0; i < au_warn_loopback_nelem && *a; i++)
19304 + if (a[i] == magic) {
19305 + spin_unlock(&spin);
19309 + /* h_sb is new to us, print it */
19310 + if (i < au_warn_loopback_nelem) {
19315 + /* expand the array */
19316 + new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
19317 + a = au_kzrealloc(au_warn_loopback_array,
19318 + au_warn_loopback_nelem * sizeof(unsigned long),
19319 + new_nelem * sizeof(unsigned long), GFP_ATOMIC);
19321 + au_warn_loopback_nelem = new_nelem;
19322 + au_warn_loopback_array = a;
19327 + spin_unlock(&spin);
19328 + AuWarn1("realloc failed, ignored\n");
19332 + spin_unlock(&spin);
19333 + pr_warn("you may want to try another patch for loopback file "
19334 + "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
19337 +int au_loopback_init(void)
19340 + struct super_block *sb __maybe_unused;
19342 + AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
19345 + au_warn_loopback_array = kcalloc(au_warn_loopback_step,
19346 + sizeof(unsigned long), GFP_NOFS);
19347 + if (unlikely(!au_warn_loopback_array))
19353 +void au_loopback_fin(void)
19355 + kfree(au_warn_loopback_array);
19357 diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
19358 --- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
19359 +++ linux/fs/aufs/loop.h 2013-07-30 22:42:55.842946719 +0200
19362 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19364 + * This program, aufs is free software; you can redistribute it and/or modify
19365 + * it under the terms of the GNU General Public License as published by
19366 + * the Free Software Foundation; either version 2 of the License, or
19367 + * (at your option) any later version.
19369 + * This program is distributed in the hope that it will be useful,
19370 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19371 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19372 + * GNU General Public License for more details.
19374 + * You should have received a copy of the GNU General Public License
19375 + * along with this program; if not, write to the Free Software
19376 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19380 + * support for loopback mount as a branch
19383 +#ifndef __AUFS_LOOP_H__
19384 +#define __AUFS_LOOP_H__
19389 +struct super_block;
19391 +#ifdef CONFIG_AUFS_BDEV_LOOP
19393 +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
19394 +int au_test_loopback_kthread(void);
19395 +void au_warn_loopback(struct super_block *h_sb);
19397 +int au_loopback_init(void);
19398 +void au_loopback_fin(void);
19400 +AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
19401 + struct dentry *h_adding)
19402 +AuStubInt0(au_test_loopback_kthread, void)
19403 +AuStubVoid(au_warn_loopback, struct super_block *h_sb)
19405 +AuStubInt0(au_loopback_init, void)
19406 +AuStubVoid(au_loopback_fin, void)
19407 +#endif /* BLK_DEV_LOOP */
19409 +#endif /* __KERNEL__ */
19410 +#endif /* __AUFS_LOOP_H__ */
19411 diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
19412 --- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
19413 +++ linux/fs/aufs/magic.mk 2013-07-06 13:20:47.750198454 +0200
19416 +# defined in ${srctree}/fs/fuse/inode.c
19418 +ifdef CONFIG_FUSE_FS
19419 +ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
19422 +# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
19424 +ifdef CONFIG_OCFS2_FS
19425 +ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
19428 +# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
19430 +ifdef CONFIG_OCFS2_FS_O2CB
19431 +ccflags-y += -DDLMFS_MAGIC=0x76a9f425
19434 +# defined in ${srctree}/fs/cifs/cifsfs.c
19436 +ifdef CONFIG_CIFS_FS
19437 +ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
19440 +# defined in ${srctree}/fs/xfs/xfs_sb.h
19442 +ifdef CONFIG_XFS_FS
19443 +ccflags-y += -DXFS_SB_MAGIC=0x58465342
19446 +# defined in ${srctree}/fs/configfs/mount.c
19448 +ifdef CONFIG_CONFIGFS_FS
19449 +ccflags-y += -DCONFIGFS_MAGIC=0x62656570
19452 +# defined in ${srctree}/fs/9p/v9fs.h
19454 +ifdef CONFIG_9P_FS
19455 +ccflags-y += -DV9FS_MAGIC=0x01021997
19458 +# defined in ${srctree}/fs/ubifs/ubifs.h
19460 +ifdef CONFIG_UBIFS_FS
19461 +ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
19464 +# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
19466 +ifdef CONFIG_HFSPLUS_FS
19467 +ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
19469 diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
19470 --- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
19471 +++ linux/fs/aufs/Makefile 2013-07-06 13:20:47.736864659 +0200
19474 +include ${src}/magic.mk
19475 +ifeq (${CONFIG_AUFS_FS},m)
19476 +include ${src}/conf.mk
19478 +-include ${src}/priv_def.mk
19480 +# cf. include/linux/kernel.h
19482 +ccflags-y += -DDEBUG
19483 +# sparse requires the full pathname
19485 +ccflags-y += -include ${M}/../../include/linux/aufs_type.h
19487 +ccflags-y += -include ${srctree}/include/linux/aufs_type.h
19490 +obj-$(CONFIG_AUFS_FS) += aufs.o
19491 +aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
19492 + wkq.o vfsub.o dcsub.o \
19493 + cpup.o whout.o wbr_policy.o \
19494 + dinfo.o dentry.o \
19496 + finfo.o file.o f_op.o \
19498 + iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
19502 +aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
19503 +aufs-$(CONFIG_SYSFS) += sysfs.o
19504 +aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
19505 +aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
19506 +aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
19507 +aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
19508 +aufs-$(CONFIG_AUFS_EXPORT) += export.o
19509 +aufs-$(CONFIG_AUFS_POLL) += poll.o
19510 +aufs-$(CONFIG_AUFS_RDU) += rdu.o
19511 +aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
19512 +aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
19513 +aufs-$(CONFIG_AUFS_DEBUG) += debug.o
19514 +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
19515 diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
19516 --- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
19517 +++ linux/fs/aufs/module.c 2013-07-06 13:20:47.750198454 +0200
19520 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19522 + * This program, aufs is free software; you can redistribute it and/or modify
19523 + * it under the terms of the GNU General Public License as published by
19524 + * the Free Software Foundation; either version 2 of the License, or
19525 + * (at your option) any later version.
19527 + * This program is distributed in the hope that it will be useful,
19528 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19529 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19530 + * GNU General Public License for more details.
19532 + * You should have received a copy of the GNU General Public License
19533 + * along with this program; if not, write to the Free Software
19534 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19538 + * module global variables and operations
19541 +#include <linux/module.h>
19542 +#include <linux/seq_file.h>
19545 +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
19547 + if (new_sz <= nused)
19550 + p = krealloc(p, new_sz, gfp);
19552 + memset(p + nused, 0, new_sz - nused);
19556 +/* ---------------------------------------------------------------------- */
19561 +struct kmem_cache *au_cachep[AuCache_Last];
19562 +static int __init au_cache_init(void)
19564 + au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
19565 + if (au_cachep[AuCache_DINFO])
19566 + /* SLAB_DESTROY_BY_RCU */
19567 + au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
19568 + au_icntnr_init_once);
19569 + if (au_cachep[AuCache_ICNTNR])
19570 + au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
19571 + au_fi_init_once);
19572 + if (au_cachep[AuCache_FINFO])
19573 + au_cachep[AuCache_VDIR] = AuCache(au_vdir);
19574 + if (au_cachep[AuCache_VDIR])
19575 + au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
19576 + if (au_cachep[AuCache_DEHSTR])
19582 +static void au_cache_fin(void)
19587 + * Make sure all delayed rcu free inodes are flushed before we
19592 + /* excluding AuCache_HNOTIFY */
19593 + BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
19594 + for (i = 0; i < AuCache_HNOTIFY; i++)
19595 + if (au_cachep[i]) {
19596 + kmem_cache_destroy(au_cachep[i]);
19597 + au_cachep[i] = NULL;
19601 +/* ---------------------------------------------------------------------- */
19603 +int au_dir_roflags;
19605 +#ifdef CONFIG_AUFS_SBILIST
19607 + * iterate_supers_type() doesn't protect us from
19608 + * remounting (branch management)
19610 +struct au_splhead au_sbilist;
19613 +struct lock_class_key au_lc_key[AuLcKey_Last];
19616 + * functions for module interface.
19618 +MODULE_LICENSE("GPL");
19619 +/* MODULE_LICENSE("GPL v2"); */
19620 +MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
19621 +MODULE_DESCRIPTION(AUFS_NAME
19622 + " -- Advanced multi layered unification filesystem");
19623 +MODULE_VERSION(AUFS_VERSION);
19624 +MODULE_ALIAS_FS(AUFS_NAME);
19626 +/* this module parameter has no meaning when SYSFS is disabled */
19627 +int sysaufs_brs = 1;
19628 +MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
19629 +module_param_named(brs, sysaufs_brs, int, S_IRUGO);
19631 +/* ---------------------------------------------------------------------- */
19633 +static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
19635 +int au_seq_path(struct seq_file *seq, struct path *path)
19637 + return seq_path(seq, path, au_esc_chars);
19640 +/* ---------------------------------------------------------------------- */
19642 +static int __init aufs_init(void)
19647 + p = au_esc_chars;
19648 + for (i = 1; i <= ' '; i++)
19654 + au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
19656 + au_sbilist_init();
19657 + sysaufs_brs_init();
19660 + err = sysaufs_init();
19661 + if (unlikely(err))
19663 + err = au_procfs_init();
19664 + if (unlikely(err))
19665 + goto out_sysaufs;
19666 + err = au_wkq_init();
19667 + if (unlikely(err))
19669 + err = au_loopback_init();
19670 + if (unlikely(err))
19672 + err = au_hnotify_init();
19673 + if (unlikely(err))
19674 + goto out_loopback;
19675 + err = au_sysrq_init();
19676 + if (unlikely(err))
19678 + err = au_cache_init();
19679 + if (unlikely(err))
19681 + err = register_filesystem(&aufs_fs_type);
19682 + if (unlikely(err))
19684 + /* since we define pr_fmt, call printk directly */
19685 + printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
19686 + goto out; /* success */
19693 + au_hnotify_fin();
19695 + au_loopback_fin();
19707 +static void __exit aufs_exit(void)
19709 + unregister_filesystem(&aufs_fs_type);
19712 + au_hnotify_fin();
19713 + au_loopback_fin();
19720 +module_init(aufs_init);
19721 +module_exit(aufs_exit);
19722 diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
19723 --- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
19724 +++ linux/fs/aufs/module.h 2013-07-06 13:20:47.750198454 +0200
19727 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19729 + * This program, aufs is free software; you can redistribute it and/or modify
19730 + * it under the terms of the GNU General Public License as published by
19731 + * the Free Software Foundation; either version 2 of the License, or
19732 + * (at your option) any later version.
19734 + * This program is distributed in the hope that it will be useful,
19735 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19736 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19737 + * GNU General Public License for more details.
19739 + * You should have received a copy of the GNU General Public License
19740 + * along with this program; if not, write to the Free Software
19741 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19745 + * module initialization and module-global
19748 +#ifndef __AUFS_MODULE_H__
19749 +#define __AUFS_MODULE_H__
19753 +#include <linux/slab.h>
19758 +/* module parameters */
19759 +extern int sysaufs_brs;
19761 +/* ---------------------------------------------------------------------- */
19763 +extern int au_dir_roflags;
19766 + AuLcNonDir_FIINFO,
19767 + AuLcNonDir_DIINFO,
19768 + AuLcNonDir_IIINFO,
19774 + AuLcSymlink_DIINFO,
19775 + AuLcSymlink_IIINFO,
19779 +extern struct lock_class_key au_lc_key[AuLcKey_Last];
19781 +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
19782 +int au_seq_path(struct seq_file *seq, struct path *path);
19784 +#ifdef CONFIG_PROC_FS
19786 +int __init au_procfs_init(void);
19787 +void au_procfs_fin(void);
19789 +AuStubInt0(au_procfs_init, void);
19790 +AuStubVoid(au_procfs_fin, void);
19793 +/* ---------------------------------------------------------------------- */
19802 + AuCache_HNOTIFY, /* must be last */
19806 +#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
19807 +#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
19808 +#define AuCacheCtor(type, ctor) \
19809 + kmem_cache_create(#type, sizeof(struct type), \
19810 + __alignof__(struct type), AuCacheFlags, ctor)
19812 +extern struct kmem_cache *au_cachep[];
19814 +#define AuCacheFuncs(name, index) \
19815 +static inline struct au_##name *au_cache_alloc_##name(void) \
19816 +{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
19817 +static inline void au_cache_free_##name(struct au_##name *p) \
19818 +{ kmem_cache_free(au_cachep[AuCache_##index], p); }
19820 +AuCacheFuncs(dinfo, DINFO);
19821 +AuCacheFuncs(icntnr, ICNTNR);
19822 +AuCacheFuncs(finfo, FINFO);
19823 +AuCacheFuncs(vdir, VDIR);
19824 +AuCacheFuncs(vdir_dehstr, DEHSTR);
19825 +#ifdef CONFIG_AUFS_HNOTIFY
19826 +AuCacheFuncs(hnotify, HNOTIFY);
19829 +#endif /* __KERNEL__ */
19830 +#endif /* __AUFS_MODULE_H__ */
19831 diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
19832 --- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
19833 +++ linux/fs/aufs/opts.c 2013-07-06 13:20:47.753531903 +0200
19836 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19838 + * This program, aufs is free software; you can redistribute it and/or modify
19839 + * it under the terms of the GNU General Public License as published by
19840 + * the Free Software Foundation; either version 2 of the License, or
19841 + * (at your option) any later version.
19843 + * This program is distributed in the hope that it will be useful,
19844 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19845 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19846 + * GNU General Public License for more details.
19848 + * You should have received a copy of the GNU General Public License
19849 + * along with this program; if not, write to the Free Software
19850 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19854 + * mount options/flags
19857 +#include <linux/namei.h>
19858 +#include <linux/types.h> /* a distribution requires */
19859 +#include <linux/parser.h>
19862 +/* ---------------------------------------------------------------------- */
19866 + Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
19867 + Opt_idel, Opt_imod, Opt_ireorder,
19868 + Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
19869 + Opt_rdblk_def, Opt_rdhash_def,
19870 + Opt_xino, Opt_zxino, Opt_noxino,
19871 + Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
19872 + Opt_trunc_xino_path, Opt_itrunc_xino,
19873 + Opt_trunc_xib, Opt_notrunc_xib,
19874 + Opt_shwh, Opt_noshwh,
19875 + Opt_plink, Opt_noplink, Opt_list_plink,
19877 + Opt_dio, Opt_nodio,
19878 + /* Opt_lock, Opt_unlock, */
19879 + Opt_cmd, Opt_cmd_args,
19880 + Opt_diropq_a, Opt_diropq_w,
19881 + Opt_warn_perm, Opt_nowarn_perm,
19882 + Opt_wbr_copyup, Opt_wbr_create,
19883 + Opt_refrof, Opt_norefrof,
19884 + Opt_verbose, Opt_noverbose,
19885 + Opt_sum, Opt_nosum, Opt_wsum,
19886 + Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
19889 +static match_table_t options = {
19890 + {Opt_br, "br=%s"},
19891 + {Opt_br, "br:%s"},
19893 + {Opt_add, "add=%d:%s"},
19894 + {Opt_add, "add:%d:%s"},
19895 + {Opt_add, "ins=%d:%s"},
19896 + {Opt_add, "ins:%d:%s"},
19897 + {Opt_append, "append=%s"},
19898 + {Opt_append, "append:%s"},
19899 + {Opt_prepend, "prepend=%s"},
19900 + {Opt_prepend, "prepend:%s"},
19902 + {Opt_del, "del=%s"},
19903 + {Opt_del, "del:%s"},
19904 + /* {Opt_idel, "idel:%d"}, */
19905 + {Opt_mod, "mod=%s"},
19906 + {Opt_mod, "mod:%s"},
19907 + /* {Opt_imod, "imod:%d:%s"}, */
19909 + {Opt_dirwh, "dirwh=%d"},
19911 + {Opt_xino, "xino=%s"},
19912 + {Opt_noxino, "noxino"},
19913 + {Opt_trunc_xino, "trunc_xino"},
19914 + {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
19915 + {Opt_notrunc_xino, "notrunc_xino"},
19916 + {Opt_trunc_xino_path, "trunc_xino=%s"},
19917 + {Opt_itrunc_xino, "itrunc_xino=%d"},
19918 + /* {Opt_zxino, "zxino=%s"}, */
19919 + {Opt_trunc_xib, "trunc_xib"},
19920 + {Opt_notrunc_xib, "notrunc_xib"},
19922 +#ifdef CONFIG_PROC_FS
19923 + {Opt_plink, "plink"},
19925 + {Opt_ignore_silent, "plink"},
19928 + {Opt_noplink, "noplink"},
19930 +#ifdef CONFIG_AUFS_DEBUG
19931 + {Opt_list_plink, "list_plink"},
19934 + {Opt_udba, "udba=%s"},
19936 + {Opt_dio, "dio"},
19937 + {Opt_nodio, "nodio"},
19939 + {Opt_diropq_a, "diropq=always"},
19940 + {Opt_diropq_a, "diropq=a"},
19941 + {Opt_diropq_w, "diropq=whiteouted"},
19942 + {Opt_diropq_w, "diropq=w"},
19944 + {Opt_warn_perm, "warn_perm"},
19945 + {Opt_nowarn_perm, "nowarn_perm"},
19947 + /* keep them temporary */
19948 + {Opt_ignore_silent, "coo=%s"},
19949 + {Opt_ignore_silent, "nodlgt"},
19950 + {Opt_ignore_silent, "nodirperm1"},
19951 + {Opt_ignore_silent, "clean_plink"},
19953 +#ifdef CONFIG_AUFS_SHWH
19954 + {Opt_shwh, "shwh"},
19956 + {Opt_noshwh, "noshwh"},
19958 + {Opt_rendir, "rendir=%d"},
19960 + {Opt_refrof, "refrof"},
19961 + {Opt_norefrof, "norefrof"},
19963 + {Opt_verbose, "verbose"},
19964 + {Opt_verbose, "v"},
19965 + {Opt_noverbose, "noverbose"},
19966 + {Opt_noverbose, "quiet"},
19967 + {Opt_noverbose, "q"},
19968 + {Opt_noverbose, "silent"},
19970 + {Opt_sum, "sum"},
19971 + {Opt_nosum, "nosum"},
19972 + {Opt_wsum, "wsum"},
19974 + {Opt_rdcache, "rdcache=%d"},
19975 + {Opt_rdblk, "rdblk=%d"},
19976 + {Opt_rdblk_def, "rdblk=def"},
19977 + {Opt_rdhash, "rdhash=%d"},
19978 + {Opt_rdhash_def, "rdhash=def"},
19980 + {Opt_wbr_create, "create=%s"},
19981 + {Opt_wbr_create, "create_policy=%s"},
19982 + {Opt_wbr_copyup, "cpup=%s"},
19983 + {Opt_wbr_copyup, "copyup=%s"},
19984 + {Opt_wbr_copyup, "copyup_policy=%s"},
19986 + /* internal use for the scripts */
19987 + {Opt_ignore_silent, "si=%s"},
19989 + {Opt_br, "dirs=%s"},
19990 + {Opt_ignore, "debug=%d"},
19991 + {Opt_ignore, "delete=whiteout"},
19992 + {Opt_ignore, "delete=all"},
19993 + {Opt_ignore, "imap=%s"},
19995 + /* temporary workaround, due to old mount(8)? */
19996 + {Opt_ignore_silent, "relatime"},
20001 +/* ---------------------------------------------------------------------- */
20003 +static const char *au_parser_pattern(int val, struct match_token *token)
20005 + while (token->pattern) {
20006 + if (token->token == val)
20007 + return token->pattern;
20014 +/* ---------------------------------------------------------------------- */
20016 +static match_table_t brperm = {
20017 + {AuBrPerm_RO, AUFS_BRPERM_RO},
20018 + {AuBrPerm_RR, AUFS_BRPERM_RR},
20019 + {AuBrPerm_RW, AUFS_BRPERM_RW},
20023 +static match_table_t brattr = {
20024 + {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
20025 + {AuBrRAttr_WH, AUFS_BRRATTR_WH},
20026 + {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
20030 +#define AuBrStr_LONGEST AUFS_BRPERM_RW \
20031 + "+" AUFS_BRATTR_UNPIN \
20032 + "+" AUFS_BRWATTR_NLWH
20034 +static int br_attr_val(char *str, match_table_t table, substring_t args[])
20041 + p = strchr(str, '+');
20044 + v = match_token(str, table, args);
20050 + pr_warn("ignored branch attribute %s\n", str);
20060 +static int noinline_for_stack br_perm_val(char *perm)
20064 + substring_t args[MAX_OPT_ARGS];
20066 + p = strchr(perm, '+');
20069 + val = match_token(perm, brperm, args);
20073 + pr_warn("ignored branch permission %s\n", perm);
20074 + val = AuBrPerm_RO;
20082 + q = strchr(p, '+');
20085 + val |= br_attr_val(p, brattr, args);
20092 + switch (val & AuBrPerm_Mask) {
20093 + case AuBrPerm_RO:
20094 + case AuBrPerm_RR:
20095 + if (unlikely(val & AuBrWAttr_NoLinkWH)) {
20096 + pr_warn("ignored branch attribute %s\n",
20097 + AUFS_BRWATTR_NLWH);
20098 + val &= ~AuBrWAttr_NoLinkWH;
20101 + case AuBrPerm_RW:
20102 + if (unlikely(val & AuBrRAttr_WH)) {
20103 + pr_warn("ignored branch attribute %s\n",
20104 + AUFS_BRRATTR_WH);
20105 + val &= ~AuBrRAttr_WH;
20114 +/* Caller should free the return value */
20115 +char *au_optstr_br_perm(int brperm)
20117 + char *p, a[sizeof(AuBrStr_LONGEST)];
20120 +#define SetPerm(str) do { \
20121 + sz = sizeof(str); \
20122 + memcpy(a, str, sz); \
20123 + p = a + sz - 1; \
20126 +#define AppendAttr(flag, str) do { \
20127 + if (brperm & flag) { \
20128 + sz = sizeof(str); \
20130 + memcpy(p, str, sz); \
20135 + switch (brperm & AuBrPerm_Mask) {
20136 + case AuBrPerm_RO:
20137 + SetPerm(AUFS_BRPERM_RO);
20139 + case AuBrPerm_RR:
20140 + SetPerm(AUFS_BRPERM_RR);
20142 + case AuBrPerm_RW:
20143 + SetPerm(AUFS_BRPERM_RW);
20149 + AppendAttr(AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN);
20150 + AppendAttr(AuBrRAttr_WH, AUFS_BRRATTR_WH);
20151 + AppendAttr(AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH);
20153 + AuDebugOn(strlen(a) >= sizeof(a));
20154 + return kstrdup(a, GFP_NOFS);
20159 +/* ---------------------------------------------------------------------- */
20161 +static match_table_t udbalevel = {
20162 + {AuOpt_UDBA_REVAL, "reval"},
20163 + {AuOpt_UDBA_NONE, "none"},
20164 +#ifdef CONFIG_AUFS_HNOTIFY
20165 + {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
20166 +#ifdef CONFIG_AUFS_HFSNOTIFY
20167 + {AuOpt_UDBA_HNOTIFY, "fsnotify"},
20173 +static int noinline_for_stack udba_val(char *str)
20175 + substring_t args[MAX_OPT_ARGS];
20177 + return match_token(str, udbalevel, args);
20180 +const char *au_optstr_udba(int udba)
20182 + return au_parser_pattern(udba, (void *)udbalevel);
20185 +/* ---------------------------------------------------------------------- */
20187 +static match_table_t au_wbr_create_policy = {
20188 + {AuWbrCreate_TDP, "tdp"},
20189 + {AuWbrCreate_TDP, "top-down-parent"},
20190 + {AuWbrCreate_RR, "rr"},
20191 + {AuWbrCreate_RR, "round-robin"},
20192 + {AuWbrCreate_MFS, "mfs"},
20193 + {AuWbrCreate_MFS, "most-free-space"},
20194 + {AuWbrCreate_MFSV, "mfs:%d"},
20195 + {AuWbrCreate_MFSV, "most-free-space:%d"},
20197 + {AuWbrCreate_MFSRR, "mfsrr:%d"},
20198 + {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
20199 + {AuWbrCreate_PMFS, "pmfs"},
20200 + {AuWbrCreate_PMFSV, "pmfs:%d"},
20206 + * cf. linux/lib/parser.c and cmdline.c
20207 + * gave up calling memparse() since it uses simple_strtoull() instead of
20210 +static int noinline_for_stack
20211 +au_match_ull(substring_t *s, unsigned long long *result)
20214 + unsigned int len;
20218 + len = s->to - s->from;
20219 + if (len + 1 <= sizeof(a)) {
20220 + memcpy(a, s->from, len);
20222 + err = kstrtoull(a, 0, result);
20227 +static int au_wbr_mfs_wmark(substring_t *arg, char *str,
20228 + struct au_opt_wbr_create *create)
20231 + unsigned long long ull;
20234 + if (!au_match_ull(arg, &ull))
20235 + create->mfsrr_watermark = ull;
20237 + pr_err("bad integer in %s\n", str);
20244 +static int au_wbr_mfs_sec(substring_t *arg, char *str,
20245 + struct au_opt_wbr_create *create)
20250 + if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
20251 + create->mfs_second = n;
20253 + pr_err("bad integer in %s\n", str);
20260 +static int noinline_for_stack
20261 +au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
20264 + substring_t args[MAX_OPT_ARGS];
20266 + err = match_token(str, au_wbr_create_policy, args);
20267 + create->wbr_create = err;
20269 + case AuWbrCreate_MFSRRV:
20270 + e = au_wbr_mfs_wmark(&args[0], str, create);
20272 + e = au_wbr_mfs_sec(&args[1], str, create);
20276 + case AuWbrCreate_MFSRR:
20277 + e = au_wbr_mfs_wmark(&args[0], str, create);
20278 + if (unlikely(e)) {
20283 + case AuWbrCreate_MFS:
20284 + case AuWbrCreate_PMFS:
20285 + create->mfs_second = AUFS_MFS_DEF_SEC;
20287 + case AuWbrCreate_MFSV:
20288 + case AuWbrCreate_PMFSV:
20289 + e = au_wbr_mfs_sec(&args[0], str, create);
20298 +const char *au_optstr_wbr_create(int wbr_create)
20300 + return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
20303 +static match_table_t au_wbr_copyup_policy = {
20304 + {AuWbrCopyup_TDP, "tdp"},
20305 + {AuWbrCopyup_TDP, "top-down-parent"},
20306 + {AuWbrCopyup_BUP, "bup"},
20307 + {AuWbrCopyup_BUP, "bottom-up-parent"},
20308 + {AuWbrCopyup_BU, "bu"},
20309 + {AuWbrCopyup_BU, "bottom-up"},
20313 +static int noinline_for_stack au_wbr_copyup_val(char *str)
20315 + substring_t args[MAX_OPT_ARGS];
20317 + return match_token(str, au_wbr_copyup_policy, args);
20320 +const char *au_optstr_wbr_copyup(int wbr_copyup)
20322 + return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
20325 +/* ---------------------------------------------------------------------- */
20327 +static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
20329 +static void dump_opts(struct au_opts *opts)
20331 +#ifdef CONFIG_AUFS_DEBUG
20332 + /* reduce stack space */
20334 + struct au_opt_add *add;
20335 + struct au_opt_del *del;
20336 + struct au_opt_mod *mod;
20337 + struct au_opt_xino *xino;
20338 + struct au_opt_xino_itrunc *xino_itrunc;
20339 + struct au_opt_wbr_create *create;
20341 + struct au_opt *opt;
20344 + while (opt->type != Opt_tail) {
20345 + switch (opt->type) {
20347 + u.add = &opt->add;
20348 + AuDbg("add {b%d, %s, 0x%x, %p}\n",
20349 + u.add->bindex, u.add->pathname, u.add->perm,
20350 + u.add->path.dentry);
20354 + u.del = &opt->del;
20355 + AuDbg("del {%s, %p}\n",
20356 + u.del->pathname, u.del->h_path.dentry);
20360 + u.mod = &opt->mod;
20361 + AuDbg("mod {%s, 0x%x, %p}\n",
20362 + u.mod->path, u.mod->perm, u.mod->h_root);
20365 + u.add = &opt->add;
20366 + AuDbg("append {b%d, %s, 0x%x, %p}\n",
20367 + u.add->bindex, u.add->pathname, u.add->perm,
20368 + u.add->path.dentry);
20370 + case Opt_prepend:
20371 + u.add = &opt->add;
20372 + AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
20373 + u.add->bindex, u.add->pathname, u.add->perm,
20374 + u.add->path.dentry);
20377 + AuDbg("dirwh %d\n", opt->dirwh);
20379 + case Opt_rdcache:
20380 + AuDbg("rdcache %d\n", opt->rdcache);
20383 + AuDbg("rdblk %u\n", opt->rdblk);
20385 + case Opt_rdblk_def:
20386 + AuDbg("rdblk_def\n");
20389 + AuDbg("rdhash %u\n", opt->rdhash);
20391 + case Opt_rdhash_def:
20392 + AuDbg("rdhash_def\n");
20395 + u.xino = &opt->xino;
20396 + AuDbg("xino {%s %.*s}\n",
20398 + AuDLNPair(u.xino->file->f_dentry));
20400 + case Opt_trunc_xino:
20401 + AuLabel(trunc_xino);
20403 + case Opt_notrunc_xino:
20404 + AuLabel(notrunc_xino);
20406 + case Opt_trunc_xino_path:
20407 + case Opt_itrunc_xino:
20408 + u.xino_itrunc = &opt->xino_itrunc;
20409 + AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
20415 + case Opt_trunc_xib:
20416 + AuLabel(trunc_xib);
20418 + case Opt_notrunc_xib:
20419 + AuLabel(notrunc_xib);
20430 + case Opt_noplink:
20431 + AuLabel(noplink);
20433 + case Opt_list_plink:
20434 + AuLabel(list_plink);
20437 + AuDbg("udba %d, %s\n",
20438 + opt->udba, au_optstr_udba(opt->udba));
20446 + case Opt_diropq_a:
20447 + AuLabel(diropq_a);
20449 + case Opt_diropq_w:
20450 + AuLabel(diropq_w);
20452 + case Opt_warn_perm:
20453 + AuLabel(warn_perm);
20455 + case Opt_nowarn_perm:
20456 + AuLabel(nowarn_perm);
20461 + case Opt_norefrof:
20462 + AuLabel(norefrof);
20464 + case Opt_verbose:
20465 + AuLabel(verbose);
20467 + case Opt_noverbose:
20468 + AuLabel(noverbose);
20479 + case Opt_wbr_create:
20480 + u.create = &opt->wbr_create;
20481 + AuDbg("create %d, %s\n", u.create->wbr_create,
20482 + au_optstr_wbr_create(u.create->wbr_create));
20483 + switch (u.create->wbr_create) {
20484 + case AuWbrCreate_MFSV:
20485 + case AuWbrCreate_PMFSV:
20486 + AuDbg("%d sec\n", u.create->mfs_second);
20488 + case AuWbrCreate_MFSRR:
20489 + AuDbg("%llu watermark\n",
20490 + u.create->mfsrr_watermark);
20492 + case AuWbrCreate_MFSRRV:
20493 + AuDbg("%llu watermark, %d sec\n",
20494 + u.create->mfsrr_watermark,
20495 + u.create->mfs_second);
20499 + case Opt_wbr_copyup:
20500 + AuDbg("copyup %d, %s\n", opt->wbr_copyup,
20501 + au_optstr_wbr_copyup(opt->wbr_copyup));
20511 +void au_opts_free(struct au_opts *opts)
20513 + struct au_opt *opt;
20516 + while (opt->type != Opt_tail) {
20517 + switch (opt->type) {
20520 + case Opt_prepend:
20521 + path_put(&opt->add.path);
20525 + path_put(&opt->del.h_path);
20529 + dput(opt->mod.h_root);
20532 + fput(opt->xino.file);
20539 +static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
20540 + aufs_bindex_t bindex)
20543 + struct au_opt_add *add = &opt->add;
20546 + add->bindex = bindex;
20547 + add->perm = AuBrPerm_RO;
20548 + add->pathname = opt_str;
20549 + p = strchr(opt_str, '=');
20553 + add->perm = br_perm_val(p);
20556 + err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
20559 + add->perm = AuBrPerm_RO;
20560 + if (au_test_fs_rr(add->path.dentry->d_sb))
20561 + add->perm = AuBrPerm_RR;
20562 + else if (!bindex && !(sb_flags & MS_RDONLY))
20563 + add->perm = AuBrPerm_RW;
20565 + opt->type = Opt_add;
20568 + pr_err("lookup failed %s (%d)\n", add->pathname, err);
20575 +static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
20579 + del->pathname = args[0].from;
20580 + AuDbg("del path %s\n", del->pathname);
20582 + err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
20583 + if (unlikely(err))
20584 + pr_err("lookup failed %s (%d)\n", del->pathname, err);
20589 +#if 0 /* reserved for future use */
20590 +static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
20591 + struct au_opt_del *del, substring_t args[])
20594 + struct dentry *root;
20597 + root = sb->s_root;
20598 + aufs_read_lock(root, AuLock_FLUSH);
20599 + if (bindex < 0 || au_sbend(sb) < bindex) {
20600 + pr_err("out of bounds, %d\n", bindex);
20605 + del->h_path.dentry = dget(au_h_dptr(root, bindex));
20606 + del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
20609 + aufs_read_unlock(root, !AuLock_IR);
20614 +static int noinline_for_stack
20615 +au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
20618 + struct path path;
20622 + mod->path = args[0].from;
20623 + p = strchr(mod->path, '=');
20624 + if (unlikely(!p)) {
20625 + pr_err("no permssion %s\n", args[0].from);
20630 + err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
20631 + if (unlikely(err)) {
20632 + pr_err("lookup failed %s (%d)\n", mod->path, err);
20636 + mod->perm = br_perm_val(p);
20637 + AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
20638 + mod->h_root = dget(path.dentry);
20645 +#if 0 /* reserved for future use */
20646 +static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
20647 + struct au_opt_mod *mod, substring_t args[])
20650 + struct dentry *root;
20653 + root = sb->s_root;
20654 + aufs_read_lock(root, AuLock_FLUSH);
20655 + if (bindex < 0 || au_sbend(sb) < bindex) {
20656 + pr_err("out of bounds, %d\n", bindex);
20661 + mod->perm = br_perm_val(args[1].from);
20662 + AuDbg("mod path %s, perm 0x%x, %s\n",
20663 + mod->path, mod->perm, args[1].from);
20664 + mod->h_root = dget(au_h_dptr(root, bindex));
20667 + aufs_read_unlock(root, !AuLock_IR);
20672 +static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
20673 + substring_t args[])
20676 + struct file *file;
20678 + file = au_xino_create(sb, args[0].from, /*silent*/0);
20679 + err = PTR_ERR(file);
20680 + if (IS_ERR(file))
20684 + if (unlikely(file->f_dentry->d_sb == sb)) {
20686 + pr_err("%s must be outside\n", args[0].from);
20691 + xino->file = file;
20692 + xino->path = args[0].from;
20698 +static int noinline_for_stack
20699 +au_opts_parse_xino_itrunc_path(struct super_block *sb,
20700 + struct au_opt_xino_itrunc *xino_itrunc,
20701 + substring_t args[])
20704 + aufs_bindex_t bend, bindex;
20705 + struct path path;
20706 + struct dentry *root;
20708 + err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
20709 + if (unlikely(err)) {
20710 + pr_err("lookup failed %s (%d)\n", args[0].from, err);
20714 + xino_itrunc->bindex = -1;
20715 + root = sb->s_root;
20716 + aufs_read_lock(root, AuLock_FLUSH);
20717 + bend = au_sbend(sb);
20718 + for (bindex = 0; bindex <= bend; bindex++) {
20719 + if (au_h_dptr(root, bindex) == path.dentry) {
20720 + xino_itrunc->bindex = bindex;
20724 + aufs_read_unlock(root, !AuLock_IR);
20727 + if (unlikely(xino_itrunc->bindex < 0)) {
20728 + pr_err("no such branch %s\n", args[0].from);
20736 +/* called without aufs lock */
20737 +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
20739 + int err, n, token;
20740 + aufs_bindex_t bindex;
20741 + unsigned char skipped;
20742 + struct dentry *root;
20743 + struct au_opt *opt, *opt_tail;
20745 + /* reduce the stack space */
20747 + struct au_opt_xino_itrunc *xino_itrunc;
20748 + struct au_opt_wbr_create *create;
20751 + substring_t args[MAX_OPT_ARGS];
20755 + a = kmalloc(sizeof(*a), GFP_NOFS);
20756 + if (unlikely(!a))
20759 + root = sb->s_root;
20763 + opt_tail = opt + opts->max_opt - 1;
20764 + opt->type = Opt_tail;
20765 + while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
20768 + token = match_token(opt_str, options, a->args);
20772 + while (!err && (opt_str = strsep(&a->args[0].from, ":"))
20774 + err = opt_add(opt, opt_str, opts->sb_flags,
20776 + if (unlikely(!err && ++opt > opt_tail)) {
20780 + opt->type = Opt_tail;
20785 + if (unlikely(match_int(&a->args[0], &n))) {
20786 + pr_err("bad integer in %s\n", opt_str);
20790 + err = opt_add(opt, a->args[1].from, opts->sb_flags,
20793 + opt->type = token;
20796 + err = opt_add(opt, a->args[0].from, opts->sb_flags,
20797 + /*dummy bindex*/1);
20799 + opt->type = token;
20801 + case Opt_prepend:
20802 + err = opt_add(opt, a->args[0].from, opts->sb_flags,
20805 + opt->type = token;
20808 + err = au_opts_parse_del(&opt->del, a->args);
20810 + opt->type = token;
20812 +#if 0 /* reserved for future use */
20814 + del->pathname = "(indexed)";
20815 + if (unlikely(match_int(&args[0], &n))) {
20816 + pr_err("bad integer in %s\n", opt_str);
20819 + err = au_opts_parse_idel(sb, n, &opt->del, a->args);
20821 + opt->type = token;
20825 + err = au_opts_parse_mod(&opt->mod, a->args);
20827 + opt->type = token;
20829 +#ifdef IMOD /* reserved for future use */
20831 + u.mod->path = "(indexed)";
20832 + if (unlikely(match_int(&a->args[0], &n))) {
20833 + pr_err("bad integer in %s\n", opt_str);
20836 + err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
20838 + opt->type = token;
20842 + err = au_opts_parse_xino(sb, &opt->xino, a->args);
20844 + opt->type = token;
20847 + case Opt_trunc_xino_path:
20848 + err = au_opts_parse_xino_itrunc_path
20849 + (sb, &opt->xino_itrunc, a->args);
20851 + opt->type = token;
20854 + case Opt_itrunc_xino:
20855 + u.xino_itrunc = &opt->xino_itrunc;
20856 + if (unlikely(match_int(&a->args[0], &n))) {
20857 + pr_err("bad integer in %s\n", opt_str);
20860 + u.xino_itrunc->bindex = n;
20861 + aufs_read_lock(root, AuLock_FLUSH);
20862 + if (n < 0 || au_sbend(sb) < n) {
20863 + pr_err("out of bounds, %d\n", n);
20864 + aufs_read_unlock(root, !AuLock_IR);
20867 + aufs_read_unlock(root, !AuLock_IR);
20869 + opt->type = token;
20873 + if (unlikely(match_int(&a->args[0], &opt->dirwh)))
20876 + opt->type = token;
20879 + case Opt_rdcache:
20880 + if (unlikely(match_int(&a->args[0], &n))) {
20881 + pr_err("bad integer in %s\n", opt_str);
20884 + if (unlikely(n > AUFS_RDCACHE_MAX)) {
20885 + pr_err("rdcache must be smaller than %d\n",
20886 + AUFS_RDCACHE_MAX);
20889 + opt->rdcache = n;
20891 + opt->type = token;
20894 + if (unlikely(match_int(&a->args[0], &n)
20896 + || n > KMALLOC_MAX_SIZE)) {
20897 + pr_err("bad integer in %s\n", opt_str);
20900 + if (unlikely(n && n < NAME_MAX)) {
20901 + pr_err("rdblk must be larger than %d\n",
20907 + opt->type = token;
20910 + if (unlikely(match_int(&a->args[0], &n)
20912 + || n * sizeof(struct hlist_head)
20913 + > KMALLOC_MAX_SIZE)) {
20914 + pr_err("bad integer in %s\n", opt_str);
20919 + opt->type = token;
20922 + case Opt_trunc_xino:
20923 + case Opt_notrunc_xino:
20925 + case Opt_trunc_xib:
20926 + case Opt_notrunc_xib:
20930 + case Opt_noplink:
20931 + case Opt_list_plink:
20934 + case Opt_diropq_a:
20935 + case Opt_diropq_w:
20936 + case Opt_warn_perm:
20937 + case Opt_nowarn_perm:
20939 + case Opt_norefrof:
20940 + case Opt_verbose:
20941 + case Opt_noverbose:
20945 + case Opt_rdblk_def:
20946 + case Opt_rdhash_def:
20948 + opt->type = token;
20952 + opt->udba = udba_val(a->args[0].from);
20953 + if (opt->udba >= 0) {
20955 + opt->type = token;
20957 + pr_err("wrong value, %s\n", opt_str);
20960 + case Opt_wbr_create:
20961 + u.create = &opt->wbr_create;
20962 + u.create->wbr_create
20963 + = au_wbr_create_val(a->args[0].from, u.create);
20964 + if (u.create->wbr_create >= 0) {
20966 + opt->type = token;
20968 + pr_err("wrong value, %s\n", opt_str);
20970 + case Opt_wbr_copyup:
20971 + opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
20972 + if (opt->wbr_copyup >= 0) {
20974 + opt->type = token;
20976 + pr_err("wrong value, %s\n", opt_str);
20980 + pr_warn("ignored %s\n", opt_str);
20982 + case Opt_ignore_silent:
20987 + pr_err("unknown option %s\n", opt_str);
20991 + if (!err && !skipped) {
20992 + if (unlikely(++opt > opt_tail)) {
20995 + opt->type = Opt_tail;
20998 + opt->type = Opt_tail;
21004 + if (unlikely(err))
21005 + au_opts_free(opts);
21011 +static int au_opt_wbr_create(struct super_block *sb,
21012 + struct au_opt_wbr_create *create)
21015 + struct au_sbinfo *sbinfo;
21017 + SiMustWriteLock(sb);
21019 + err = 1; /* handled */
21020 + sbinfo = au_sbi(sb);
21021 + if (sbinfo->si_wbr_create_ops->fin) {
21022 + err = sbinfo->si_wbr_create_ops->fin(sb);
21027 + sbinfo->si_wbr_create = create->wbr_create;
21028 + sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
21029 + switch (create->wbr_create) {
21030 + case AuWbrCreate_MFSRRV:
21031 + case AuWbrCreate_MFSRR:
21032 + sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
21034 + case AuWbrCreate_MFS:
21035 + case AuWbrCreate_MFSV:
21036 + case AuWbrCreate_PMFS:
21037 + case AuWbrCreate_PMFSV:
21038 + sbinfo->si_wbr_mfs.mfs_expire
21039 + = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
21043 + if (sbinfo->si_wbr_create_ops->init)
21044 + sbinfo->si_wbr_create_ops->init(sb); /* ignore */
21051 + * plus: processed without an error
21052 + * zero: unprocessed
21054 +static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
21055 + struct au_opts *opts)
21058 + struct au_sbinfo *sbinfo;
21060 + SiMustWriteLock(sb);
21062 + err = 1; /* handled */
21063 + sbinfo = au_sbi(sb);
21064 + switch (opt->type) {
21066 + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
21067 + sbinfo->si_mntflags |= opt->udba;
21068 + opts->given_udba |= opt->udba;
21072 + au_opt_set(sbinfo->si_mntflags, PLINK);
21074 + case Opt_noplink:
21075 + if (au_opt_test(sbinfo->si_mntflags, PLINK))
21076 + au_plink_put(sb, /*verbose*/1);
21077 + au_opt_clr(sbinfo->si_mntflags, PLINK);
21079 + case Opt_list_plink:
21080 + if (au_opt_test(sbinfo->si_mntflags, PLINK))
21081 + au_plink_list(sb);
21085 + au_opt_set(sbinfo->si_mntflags, DIO);
21086 + au_fset_opts(opts->flags, REFRESH_DYAOP);
21089 + au_opt_clr(sbinfo->si_mntflags, DIO);
21090 + au_fset_opts(opts->flags, REFRESH_DYAOP);
21093 + case Opt_diropq_a:
21094 + au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
21096 + case Opt_diropq_w:
21097 + au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
21100 + case Opt_warn_perm:
21101 + au_opt_set(sbinfo->si_mntflags, WARN_PERM);
21103 + case Opt_nowarn_perm:
21104 + au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
21108 + au_opt_set(sbinfo->si_mntflags, REFROF);
21110 + case Opt_norefrof:
21111 + au_opt_clr(sbinfo->si_mntflags, REFROF);
21114 + case Opt_verbose:
21115 + au_opt_set(sbinfo->si_mntflags, VERBOSE);
21117 + case Opt_noverbose:
21118 + au_opt_clr(sbinfo->si_mntflags, VERBOSE);
21122 + au_opt_set(sbinfo->si_mntflags, SUM);
21125 + au_opt_clr(sbinfo->si_mntflags, SUM);
21126 + au_opt_set(sbinfo->si_mntflags, SUM_W);
21128 + au_opt_clr(sbinfo->si_mntflags, SUM);
21129 + au_opt_clr(sbinfo->si_mntflags, SUM_W);
21132 + case Opt_wbr_create:
21133 + err = au_opt_wbr_create(sb, &opt->wbr_create);
21135 + case Opt_wbr_copyup:
21136 + sbinfo->si_wbr_copyup = opt->wbr_copyup;
21137 + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
21141 + sbinfo->si_dirwh = opt->dirwh;
21144 + case Opt_rdcache:
21145 + sbinfo->si_rdcache
21146 + = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
21149 + sbinfo->si_rdblk = opt->rdblk;
21151 + case Opt_rdblk_def:
21152 + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
21155 + sbinfo->si_rdhash = opt->rdhash;
21157 + case Opt_rdhash_def:
21158 + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
21162 + au_opt_set(sbinfo->si_mntflags, SHWH);
21165 + au_opt_clr(sbinfo->si_mntflags, SHWH);
21168 + case Opt_trunc_xino:
21169 + au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
21171 + case Opt_notrunc_xino:
21172 + au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
21175 + case Opt_trunc_xino_path:
21176 + case Opt_itrunc_xino:
21177 + err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
21182 + case Opt_trunc_xib:
21183 + au_fset_opts(opts->flags, TRUNC_XIB);
21185 + case Opt_notrunc_xib:
21186 + au_fclr_opts(opts->flags, TRUNC_XIB);
21198 + * returns tri-state.
21199 + * plus: processed without an error
21200 + * zero: unprocessed
21203 +static int au_opt_br(struct super_block *sb, struct au_opt *opt,
21204 + struct au_opts *opts)
21206 + int err, do_refresh;
21209 + switch (opt->type) {
21211 + opt->add.bindex = au_sbend(sb) + 1;
21212 + if (opt->add.bindex < 0)
21213 + opt->add.bindex = 0;
21215 + case Opt_prepend:
21216 + opt->add.bindex = 0;
21219 + err = au_br_add(sb, &opt->add,
21220 + au_ftest_opts(opts->flags, REMOUNT));
21223 + au_fset_opts(opts->flags, REFRESH);
21229 + err = au_br_del(sb, &opt->del,
21230 + au_ftest_opts(opts->flags, REMOUNT));
21233 + au_fset_opts(opts->flags, TRUNC_XIB);
21234 + au_fset_opts(opts->flags, REFRESH);
21240 + err = au_br_mod(sb, &opt->mod,
21241 + au_ftest_opts(opts->flags, REMOUNT),
21246 + au_fset_opts(opts->flags, REFRESH);
21254 +static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
21255 + struct au_opt_xino **opt_xino,
21256 + struct au_opts *opts)
21259 + aufs_bindex_t bend, bindex;
21260 + struct dentry *root, *parent, *h_root;
21263 + switch (opt->type) {
21265 + err = au_xino_set(sb, &opt->xino,
21266 + !!au_ftest_opts(opts->flags, REMOUNT));
21267 + if (unlikely(err))
21270 + *opt_xino = &opt->xino;
21271 + au_xino_brid_set(sb, -1);
21273 + /* safe d_parent access */
21274 + parent = opt->xino.file->f_dentry->d_parent;
21275 + root = sb->s_root;
21276 + bend = au_sbend(sb);
21277 + for (bindex = 0; bindex <= bend; bindex++) {
21278 + h_root = au_h_dptr(root, bindex);
21279 + if (h_root == parent) {
21280 + au_xino_brid_set(sb, au_sbr_id(sb, bindex));
21288 + au_xino_brid_set(sb, -1);
21289 + *opt_xino = (void *)-1;
21296 +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
21297 + unsigned int pending)
21300 + aufs_bindex_t bindex, bend;
21301 + unsigned char do_plink, skip, do_free;
21302 + struct au_branch *br;
21303 + struct au_wbr *wbr;
21304 + struct dentry *root;
21305 + struct inode *dir, *h_dir;
21306 + struct au_sbinfo *sbinfo;
21307 + struct au_hinode *hdir;
21309 + SiMustAnyLock(sb);
21311 + sbinfo = au_sbi(sb);
21312 + AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
21314 + if (!(sb_flags & MS_RDONLY)) {
21315 + if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
21316 + pr_warn("first branch should be rw\n");
21317 + if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
21318 + pr_warn("shwh should be used with ro\n");
21321 + if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
21322 + && !au_opt_test(sbinfo->si_mntflags, XINO))
21323 + pr_warn("udba=*notify requires xino\n");
21326 + root = sb->s_root;
21327 + dir = root->d_inode;
21328 + do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
21329 + bend = au_sbend(sb);
21330 + for (bindex = 0; !err && bindex <= bend; bindex++) {
21332 + h_dir = au_h_iptr(dir, bindex);
21333 + br = au_sbr(sb, bindex);
21336 + wbr = br->br_wbr;
21338 + wbr_wh_read_lock(wbr);
21340 + if (!au_br_writable(br->br_perm)) {
21343 + || (!wbr->wbr_whbase
21344 + && !wbr->wbr_plink
21345 + && !wbr->wbr_orph));
21346 + } else if (!au_br_wh_linkable(br->br_perm)) {
21347 + /* skip = (!br->br_whbase && !br->br_orph); */
21348 + skip = (!wbr || !wbr->wbr_whbase);
21349 + if (skip && wbr) {
21351 + skip = !!wbr->wbr_plink;
21353 + skip = !wbr->wbr_plink;
21356 + /* skip = (br->br_whbase && br->br_ohph); */
21357 + skip = (wbr && wbr->wbr_whbase);
21360 + skip = !!wbr->wbr_plink;
21362 + skip = !wbr->wbr_plink;
21366 + wbr_wh_read_unlock(wbr);
21371 + hdir = au_hi(dir, bindex);
21372 + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
21374 + wbr_wh_write_lock(wbr);
21375 + err = au_wh_init(br, sb);
21377 + wbr_wh_write_unlock(wbr);
21378 + au_hn_imtx_unlock(hdir);
21380 + if (!err && do_free) {
21382 + br->br_wbr = NULL;
21389 +int au_opts_mount(struct super_block *sb, struct au_opts *opts)
21392 + unsigned int tmp;
21393 + aufs_bindex_t bindex, bend;
21394 + struct au_opt *opt;
21395 + struct au_opt_xino *opt_xino, xino;
21396 + struct au_sbinfo *sbinfo;
21397 + struct au_branch *br;
21399 + SiMustWriteLock(sb);
21404 + while (err >= 0 && opt->type != Opt_tail)
21405 + err = au_opt_simple(sb, opt++, opts);
21408 + else if (unlikely(err < 0))
21411 + /* disable xino and udba temporary */
21412 + sbinfo = au_sbi(sb);
21413 + tmp = sbinfo->si_mntflags;
21414 + au_opt_clr(sbinfo->si_mntflags, XINO);
21415 + au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
21418 + while (err >= 0 && opt->type != Opt_tail)
21419 + err = au_opt_br(sb, opt++, opts);
21422 + else if (unlikely(err < 0))
21425 + bend = au_sbend(sb);
21426 + if (unlikely(bend < 0)) {
21428 + pr_err("no branches\n");
21432 + if (au_opt_test(tmp, XINO))
21433 + au_opt_set(sbinfo->si_mntflags, XINO);
21435 + while (!err && opt->type != Opt_tail)
21436 + err = au_opt_xino(sb, opt++, &opt_xino, opts);
21437 + if (unlikely(err))
21440 + err = au_opts_verify(sb, sb->s_flags, tmp);
21441 + if (unlikely(err))
21444 + /* restore xino */
21445 + if (au_opt_test(tmp, XINO) && !opt_xino) {
21446 + xino.file = au_xino_def(sb);
21447 + err = PTR_ERR(xino.file);
21448 + if (IS_ERR(xino.file))
21451 + err = au_xino_set(sb, &xino, /*remount*/0);
21453 + if (unlikely(err))
21457 + /* restore udba */
21458 + tmp &= AuOptMask_UDBA;
21459 + sbinfo->si_mntflags &= ~AuOptMask_UDBA;
21460 + sbinfo->si_mntflags |= tmp;
21461 + bend = au_sbend(sb);
21462 + for (bindex = 0; bindex <= bend; bindex++) {
21463 + br = au_sbr(sb, bindex);
21464 + err = au_hnotify_reset_br(tmp, br, br->br_perm);
21465 + if (unlikely(err))
21466 + AuIOErr("hnotify failed on br %d, %d, ignored\n",
21468 + /* go on even if err */
21470 + if (au_opt_test(tmp, UDBA_HNOTIFY)) {
21471 + struct inode *dir = sb->s_root->d_inode;
21472 + au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
21479 +int au_opts_remount(struct super_block *sb, struct au_opts *opts)
21482 + struct inode *dir;
21483 + struct au_opt_xino *opt_xino;
21484 + struct au_opt *opt;
21485 + struct au_sbinfo *sbinfo;
21487 + SiMustWriteLock(sb);
21489 + dir = sb->s_root->d_inode;
21490 + sbinfo = au_sbi(sb);
21494 + while (err >= 0 && opt->type != Opt_tail) {
21495 + err = au_opt_simple(sb, opt, opts);
21497 + err = au_opt_br(sb, opt, opts);
21499 + err = au_opt_xino(sb, opt, &opt_xino, opts);
21505 + /* go on even err */
21507 + rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
21508 + if (unlikely(rerr && !err))
21511 + if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
21512 + rerr = au_xib_trunc(sb);
21513 + if (unlikely(rerr && !err))
21517 + /* will be handled by the caller */
21518 + if (!au_ftest_opts(opts->flags, REFRESH)
21519 + && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
21520 + au_fset_opts(opts->flags, REFRESH);
21522 + AuDbg("status 0x%x\n", opts->flags);
21526 +/* ---------------------------------------------------------------------- */
21528 +unsigned int au_opt_udba(struct super_block *sb)
21530 + return au_mntflags(sb) & AuOptMask_UDBA;
21532 diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
21533 --- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
21534 +++ linux/fs/aufs/opts.h 2013-07-06 13:20:47.753531903 +0200
21537 + * Copyright (C) 2005-2013 Junjiro R. Okajima
21539 + * This program, aufs is free software; you can redistribute it and/or modify
21540 + * it under the terms of the GNU General Public License as published by
21541 + * the Free Software Foundation; either version 2 of the License, or
21542 + * (at your option) any later version.
21544 + * This program is distributed in the hope that it will be useful,
21545 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21546 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21547 + * GNU General Public License for more details.
21549 + * You should have received a copy of the GNU General Public License
21550 + * along with this program; if not, write to the Free Software
21551 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21555 + * mount options/flags
21558 +#ifndef __AUFS_OPTS_H__
21559 +#define __AUFS_OPTS_H__
21563 +#include <linux/path.h>
21566 +struct super_block;
21568 +/* ---------------------------------------------------------------------- */
21571 +#define AuOpt_XINO 1 /* external inode number bitmap
21572 + and translation table */
21573 +#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
21574 +#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
21575 +#define AuOpt_UDBA_REVAL (1 << 3)
21576 +#define AuOpt_UDBA_HNOTIFY (1 << 4)
21577 +#define AuOpt_SHWH (1 << 5) /* show whiteout */
21578 +#define AuOpt_PLINK (1 << 6) /* pseudo-link */
21579 +#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */
21580 +#define AuOpt_REFROF (1 << 8) /* unimplemented */
21581 +#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
21582 +#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
21583 +#define AuOpt_SUM_W (1 << 11) /* unimplemented */
21584 +#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
21585 +#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
21586 +#define AuOpt_DIO (1 << 14) /* direct io */
21588 +#ifndef CONFIG_AUFS_HNOTIFY
21589 +#undef AuOpt_UDBA_HNOTIFY
21590 +#define AuOpt_UDBA_HNOTIFY 0
21592 +#ifndef CONFIG_AUFS_SHWH
21594 +#define AuOpt_SHWH 0
21597 +#define AuOpt_Def (AuOpt_XINO \
21598 + | AuOpt_UDBA_REVAL \
21600 + /* | AuOpt_DIRPERM1 */ \
21601 + | AuOpt_WARN_PERM)
21602 +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
21603 + | AuOpt_UDBA_REVAL \
21604 + | AuOpt_UDBA_HNOTIFY)
21606 +#define au_opt_test(flags, name) (flags & AuOpt_##name)
21607 +#define au_opt_set(flags, name) do { \
21608 + BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
21609 + ((flags) |= AuOpt_##name); \
21611 +#define au_opt_set_udba(flags, name) do { \
21612 + (flags) &= ~AuOptMask_UDBA; \
21613 + ((flags) |= AuOpt_##name); \
21615 +#define au_opt_clr(flags, name) do { \
21616 + ((flags) &= ~AuOpt_##name); \
21619 +static inline unsigned int au_opts_plink(unsigned int mntflags)
21621 +#ifdef CONFIG_PROC_FS
21624 + return mntflags & ~AuOpt_PLINK;
21628 +/* ---------------------------------------------------------------------- */
21630 +/* policies to select one among multiple writable branches */
21632 + AuWbrCreate_TDP, /* top down parent */
21633 + AuWbrCreate_RR, /* round robin */
21634 + AuWbrCreate_MFS, /* most free space */
21635 + AuWbrCreate_MFSV, /* mfs with seconds */
21636 + AuWbrCreate_MFSRR, /* mfs then rr */
21637 + AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
21638 + AuWbrCreate_PMFS, /* parent and mfs */
21639 + AuWbrCreate_PMFSV, /* parent and mfs with seconds */
21641 + AuWbrCreate_Def = AuWbrCreate_TDP
21645 + AuWbrCopyup_TDP, /* top down parent */
21646 + AuWbrCopyup_BUP, /* bottom up parent */
21647 + AuWbrCopyup_BU, /* bottom up */
21649 + AuWbrCopyup_Def = AuWbrCopyup_TDP
21652 +/* ---------------------------------------------------------------------- */
21654 +struct au_opt_add {
21655 + aufs_bindex_t bindex;
21658 + struct path path;
21661 +struct au_opt_del {
21663 + struct path h_path;
21666 +struct au_opt_mod {
21669 + struct dentry *h_root;
21672 +struct au_opt_xino {
21674 + struct file *file;
21677 +struct au_opt_xino_itrunc {
21678 + aufs_bindex_t bindex;
21681 +struct au_opt_wbr_create {
21684 + unsigned long long mfsrr_watermark;
21690 + struct au_opt_xino xino;
21691 + struct au_opt_xino_itrunc xino_itrunc;
21692 + struct au_opt_add add;
21693 + struct au_opt_del del;
21694 + struct au_opt_mod mod;
21697 + unsigned int rdblk;
21698 + unsigned int rdhash;
21700 + struct au_opt_wbr_create wbr_create;
21706 +#define AuOpts_REMOUNT 1
21707 +#define AuOpts_REFRESH (1 << 1)
21708 +#define AuOpts_TRUNC_XIB (1 << 2)
21709 +#define AuOpts_REFRESH_DYAOP (1 << 3)
21710 +#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
21711 +#define au_fset_opts(flags, name) \
21712 + do { (flags) |= AuOpts_##name; } while (0)
21713 +#define au_fclr_opts(flags, name) \
21714 + do { (flags) &= ~AuOpts_##name; } while (0)
21717 + struct au_opt *opt;
21720 + unsigned int given_udba;
21721 + unsigned int flags;
21722 + unsigned long sb_flags;
21725 +/* ---------------------------------------------------------------------- */
21727 +char *au_optstr_br_perm(int brperm);
21728 +const char *au_optstr_udba(int udba);
21729 +const char *au_optstr_wbr_copyup(int wbr_copyup);
21730 +const char *au_optstr_wbr_create(int wbr_create);
21732 +void au_opts_free(struct au_opts *opts);
21733 +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
21734 +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
21735 + unsigned int pending);
21736 +int au_opts_mount(struct super_block *sb, struct au_opts *opts);
21737 +int au_opts_remount(struct super_block *sb, struct au_opts *opts);
21739 +unsigned int au_opt_udba(struct super_block *sb);
21741 +/* ---------------------------------------------------------------------- */
21743 +#endif /* __KERNEL__ */
21744 +#endif /* __AUFS_OPTS_H__ */
21745 diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
21746 --- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
21747 +++ linux/fs/aufs/plink.c 2013-07-06 13:20:47.753531903 +0200
21750 + * Copyright (C) 2005-2013 Junjiro R. Okajima
21752 + * This program, aufs is free software; you can redistribute it and/or modify
21753 + * it under the terms of the GNU General Public License as published by
21754 + * the Free Software Foundation; either version 2 of the License, or
21755 + * (at your option) any later version.
21757 + * This program is distributed in the hope that it will be useful,
21758 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21759 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21760 + * GNU General Public License for more details.
21762 + * You should have received a copy of the GNU General Public License
21763 + * along with this program; if not, write to the Free Software
21764 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21774 + * the pseudo-link maintenance mode.
21775 + * during a user process maintains the pseudo-links,
21776 + * prohibit adding a new plink and branch manipulation.
21780 + * For entry functions which will handle plink, and i_mutex is already held
21782 + * They cannot wait and should return an error at once.
21783 + * Callers has to check the error.
21785 + * For entry functions which will handle plink, but i_mutex is not held
21787 + * They can wait the plink maintenance mode to finish.
21789 + * They behave like F_SETLK and F_SETLKW.
21790 + * If the caller never handle plink, then both flags are unnecessary.
21793 +int au_plink_maint(struct super_block *sb, int flags)
21797 + struct au_sbinfo *sbi;
21799 + SiMustAnyLock(sb);
21802 + if (!au_opt_test(au_mntflags(sb), PLINK))
21805 + sbi = au_sbi(sb);
21806 + pid = sbi->si_plink_maint_pid;
21807 + if (!pid || pid == current->pid)
21810 + /* todo: it highly depends upon /sbin/mount.aufs */
21812 + ppid = task_pid_vnr(rcu_dereference(current->real_parent));
21813 + rcu_read_unlock();
21817 + if (au_ftest_lock(flags, NOPLMW)) {
21818 + /* if there is no i_mutex lock in VFS, we don't need to wait */
21819 + /* AuDebugOn(!lockdep_depth(current)); */
21820 + while (sbi->si_plink_maint_pid) {
21821 + si_read_unlock(sb);
21822 + /* gave up wake_up_bit() */
21823 + wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
21825 + if (au_ftest_lock(flags, FLUSH))
21826 + au_nwt_flush(&sbi->si_nowait);
21827 + si_noflush_read_lock(sb);
21829 + } else if (au_ftest_lock(flags, NOPLM)) {
21830 + AuDbg("ppid %d, pid %d\n", ppid, pid);
21838 +void au_plink_maint_leave(struct au_sbinfo *sbinfo)
21840 + spin_lock(&sbinfo->si_plink_maint_lock);
21841 + sbinfo->si_plink_maint_pid = 0;
21842 + spin_unlock(&sbinfo->si_plink_maint_lock);
21843 + wake_up_all(&sbinfo->si_plink_wq);
21846 +int au_plink_maint_enter(struct super_block *sb)
21849 + struct au_sbinfo *sbinfo;
21852 + sbinfo = au_sbi(sb);
21853 + /* make sure i am the only one in this fs */
21854 + si_write_lock(sb, AuLock_FLUSH);
21855 + if (au_opt_test(au_mntflags(sb), PLINK)) {
21856 + spin_lock(&sbinfo->si_plink_maint_lock);
21857 + if (!sbinfo->si_plink_maint_pid)
21858 + sbinfo->si_plink_maint_pid = current->pid;
21861 + spin_unlock(&sbinfo->si_plink_maint_lock);
21863 + si_write_unlock(sb);
21868 +/* ---------------------------------------------------------------------- */
21870 +#ifdef CONFIG_AUFS_DEBUG
21871 +void au_plink_list(struct super_block *sb)
21874 + struct au_sbinfo *sbinfo;
21875 + struct hlist_head *plink_hlist;
21876 + struct pseudo_link *plink;
21878 + SiMustAnyLock(sb);
21880 + sbinfo = au_sbi(sb);
21881 + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
21882 + AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
21884 + for (i = 0; i < AuPlink_NHASH; i++) {
21885 + plink_hlist = &sbinfo->si_plink[i].head;
21887 + hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
21888 + AuDbg("%lu\n", plink->inode->i_ino);
21889 + rcu_read_unlock();
21894 +/* is the inode pseudo-linked? */
21895 +int au_plink_test(struct inode *inode)
21898 + struct au_sbinfo *sbinfo;
21899 + struct hlist_head *plink_hlist;
21900 + struct pseudo_link *plink;
21902 + sbinfo = au_sbi(inode->i_sb);
21903 + AuRwMustAnyLock(&sbinfo->si_rwsem);
21904 + AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
21905 + AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
21908 + i = au_plink_hash(inode->i_ino);
21909 + plink_hlist = &sbinfo->si_plink[i].head;
21911 + hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
21912 + if (plink->inode == inode) {
21916 + rcu_read_unlock();
21920 +/* ---------------------------------------------------------------------- */
21923 + * generate a name for plink.
21924 + * the file will be stored under AUFS_WH_PLINKDIR.
21926 +/* 20 is max digits length of ulong 64 */
21927 +#define PLINK_NAME_LEN ((20 + 1) * 2)
21929 +static int plink_name(char *name, int len, struct inode *inode,
21930 + aufs_bindex_t bindex)
21933 + struct inode *h_inode;
21935 + h_inode = au_h_iptr(inode, bindex);
21936 + rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
21940 +struct au_do_plink_lkup_args {
21941 + struct dentry **errp;
21942 + struct qstr *tgtname;
21943 + struct dentry *h_parent;
21944 + struct au_branch *br;
21947 +static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
21948 + struct dentry *h_parent,
21949 + struct au_branch *br)
21951 + struct dentry *h_dentry;
21952 + struct mutex *h_mtx;
21954 + h_mtx = &h_parent->d_inode->i_mutex;
21955 + mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
21956 + h_dentry = vfsub_lkup_one(tgtname, h_parent);
21957 + mutex_unlock(h_mtx);
21961 +static void au_call_do_plink_lkup(void *args)
21963 + struct au_do_plink_lkup_args *a = args;
21964 + *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
21967 +/* lookup the plink-ed @inode under the branch at @bindex */
21968 +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
21970 + struct dentry *h_dentry, *h_parent;
21971 + struct au_branch *br;
21972 + struct inode *h_dir;
21974 + char a[PLINK_NAME_LEN];
21975 + struct qstr tgtname = QSTR_INIT(a, 0);
21977 + AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
21979 + br = au_sbr(inode->i_sb, bindex);
21980 + h_parent = br->br_wbr->wbr_plink;
21981 + h_dir = h_parent->d_inode;
21982 + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
21984 + if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
21985 + struct au_do_plink_lkup_args args = {
21986 + .errp = &h_dentry,
21987 + .tgtname = &tgtname,
21988 + .h_parent = h_parent,
21992 + wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
21993 + if (unlikely(wkq_err))
21994 + h_dentry = ERR_PTR(wkq_err);
21996 + h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
22001 +/* create a pseudo-link */
22002 +static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
22003 + struct dentry *h_dentry, struct au_branch *br)
22006 + struct path h_path = {
22007 + .mnt = au_br_mnt(br)
22009 + struct inode *h_dir;
22011 + h_dir = h_parent->d_inode;
22012 + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
22014 + h_path.dentry = vfsub_lkup_one(tgt, h_parent);
22015 + err = PTR_ERR(h_path.dentry);
22016 + if (IS_ERR(h_path.dentry))
22020 + /* wh.plink dir is not monitored */
22021 + /* todo: is it really safe? */
22022 + if (h_path.dentry->d_inode
22023 + && h_path.dentry->d_inode != h_dentry->d_inode) {
22024 + err = vfsub_unlink(h_dir, &h_path, /*force*/0);
22025 + dput(h_path.dentry);
22026 + h_path.dentry = NULL;
22030 + if (!err && !h_path.dentry->d_inode)
22031 + err = vfsub_link(h_dentry, h_dir, &h_path);
22032 + dput(h_path.dentry);
22035 + mutex_unlock(&h_dir->i_mutex);
22039 +struct do_whplink_args {
22041 + struct qstr *tgt;
22042 + struct dentry *h_parent;
22043 + struct dentry *h_dentry;
22044 + struct au_branch *br;
22047 +static void call_do_whplink(void *args)
22049 + struct do_whplink_args *a = args;
22050 + *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
22053 +static int whplink(struct dentry *h_dentry, struct inode *inode,
22054 + aufs_bindex_t bindex, struct au_branch *br)
22056 + int err, wkq_err;
22057 + struct au_wbr *wbr;
22058 + struct dentry *h_parent;
22059 + struct inode *h_dir;
22060 + char a[PLINK_NAME_LEN];
22061 + struct qstr tgtname = QSTR_INIT(a, 0);
22063 + wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
22064 + h_parent = wbr->wbr_plink;
22065 + h_dir = h_parent->d_inode;
22066 + tgtname.len = plink_name(a, sizeof(a), inode, bindex);
22068 + /* always superio. */
22069 + if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
22070 + struct do_whplink_args args = {
22073 + .h_parent = h_parent,
22074 + .h_dentry = h_dentry,
22077 + wkq_err = au_wkq_wait(call_do_whplink, &args);
22078 + if (unlikely(wkq_err))
22081 + err = do_whplink(&tgtname, h_parent, h_dentry, br);
22086 +/* free a single plink */
22087 +static void do_put_plink(struct pseudo_link *plink, int do_del)
22090 + hlist_del(&plink->hlist);
22091 + iput(plink->inode);
22095 +static void do_put_plink_rcu(struct rcu_head *rcu)
22097 + struct pseudo_link *plink;
22099 + plink = container_of(rcu, struct pseudo_link, rcu);
22100 + iput(plink->inode);
22105 + * create a new pseudo-link for @h_dentry on @bindex.
22106 + * the linked inode is held in aufs @inode.
22108 +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
22109 + struct dentry *h_dentry)
22111 + struct super_block *sb;
22112 + struct au_sbinfo *sbinfo;
22113 + struct hlist_head *plink_hlist;
22114 + struct pseudo_link *plink, *tmp;
22115 + struct au_sphlhead *sphl;
22116 + int found, err, cnt, i;
22118 + sb = inode->i_sb;
22119 + sbinfo = au_sbi(sb);
22120 + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
22121 + AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
22123 + found = au_plink_test(inode);
22127 + i = au_plink_hash(inode->i_ino);
22128 + sphl = sbinfo->si_plink + i;
22129 + plink_hlist = &sphl->head;
22130 + tmp = kmalloc(sizeof(*plink), GFP_NOFS);
22132 + tmp->inode = au_igrab(inode);
22138 + spin_lock(&sphl->spin);
22139 + hlist_for_each_entry(plink, plink_hlist, hlist) {
22140 + if (plink->inode == inode) {
22146 + hlist_add_head_rcu(&tmp->hlist, plink_hlist);
22147 + spin_unlock(&sphl->spin);
22149 + cnt = au_sphl_count(sphl);
22150 +#define msg "unexpectedly unblanced or too many pseudo-links"
22151 + if (cnt > AUFS_PLINK_WARN)
22152 + AuWarn1(msg ", %d\n", cnt);
22154 + err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
22156 + do_put_plink(tmp, 0);
22161 + if (unlikely(err)) {
22162 + pr_warn("err %d, damaged pseudo link.\n", err);
22164 + au_sphl_del_rcu(&tmp->hlist, sphl);
22165 + call_rcu(&tmp->rcu, do_put_plink_rcu);
22170 +/* free all plinks */
22171 +void au_plink_put(struct super_block *sb, int verbose)
22174 + struct au_sbinfo *sbinfo;
22175 + struct hlist_head *plink_hlist;
22176 + struct hlist_node *tmp;
22177 + struct pseudo_link *plink;
22179 + SiMustWriteLock(sb);
22181 + sbinfo = au_sbi(sb);
22182 + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
22183 + AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
22185 + /* no spin_lock since sbinfo is write-locked */
22187 + for (i = 0; i < AuPlink_NHASH; i++) {
22188 + plink_hlist = &sbinfo->si_plink[i].head;
22189 + if (!warned && verbose && !hlist_empty(plink_hlist)) {
22190 + pr_warn("pseudo-link is not flushed");
22193 + hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
22194 + do_put_plink(plink, 0);
22195 + INIT_HLIST_HEAD(plink_hlist);
22199 +void au_plink_clean(struct super_block *sb, int verbose)
22201 + struct dentry *root;
22203 + root = sb->s_root;
22204 + aufs_write_lock(root);
22205 + if (au_opt_test(au_mntflags(sb), PLINK))
22206 + au_plink_put(sb, verbose);
22207 + aufs_write_unlock(root);
22210 +static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
22213 + aufs_bindex_t bstart, bend, bindex;
22216 + bstart = au_ibstart(inode);
22217 + bend = au_ibend(inode);
22218 + if (bstart >= 0) {
22219 + for (bindex = bstart; bindex <= bend; bindex++) {
22220 + if (!au_h_iptr(inode, bindex)
22221 + || au_ii_br_id(inode, bindex) != br_id)
22223 + au_set_h_iptr(inode, bindex, NULL, 0);
22228 + for (bindex = bstart; bindex <= bend; bindex++)
22229 + if (au_h_iptr(inode, bindex)) {
22239 +/* free the plinks on a branch specified by @br_id */
22240 +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
22242 + struct au_sbinfo *sbinfo;
22243 + struct hlist_head *plink_hlist;
22244 + struct hlist_node *tmp;
22245 + struct pseudo_link *plink;
22246 + struct inode *inode;
22249 + SiMustWriteLock(sb);
22251 + sbinfo = au_sbi(sb);
22252 + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
22253 + AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
22255 + /* no spin_lock since sbinfo is write-locked */
22256 + for (i = 0; i < AuPlink_NHASH; i++) {
22257 + plink_hlist = &sbinfo->si_plink[i].head;
22258 + hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
22259 + inode = au_igrab(plink->inode);
22260 + ii_write_lock_child(inode);
22261 + do_put = au_plink_do_half_refresh(inode, br_id);
22263 + do_put_plink(plink, 1);
22264 + ii_write_unlock(inode);
22269 diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
22270 --- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
22271 +++ linux/fs/aufs/poll.c 2013-07-06 13:20:47.753531903 +0200
22274 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22276 + * This program, aufs is free software; you can redistribute it and/or modify
22277 + * it under the terms of the GNU General Public License as published by
22278 + * the Free Software Foundation; either version 2 of the License, or
22279 + * (at your option) any later version.
22281 + * This program is distributed in the hope that it will be useful,
22282 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22283 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22284 + * GNU General Public License for more details.
22286 + * You should have received a copy of the GNU General Public License
22287 + * along with this program; if not, write to the Free Software
22288 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22293 + * There is only one filesystem which implements ->poll operation, currently.
22298 +unsigned int aufs_poll(struct file *file, poll_table *wait)
22300 + unsigned int mask;
22302 + struct file *h_file;
22303 + struct dentry *dentry;
22304 + struct super_block *sb;
22306 + /* We should pretend an error happened. */
22307 + mask = POLLERR /* | POLLIN | POLLOUT */;
22308 + dentry = file->f_dentry;
22309 + sb = dentry->d_sb;
22310 + si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
22311 + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
22312 + if (unlikely(err))
22315 + /* it is not an error if h_file has no operation */
22316 + mask = DEFAULT_POLLMASK;
22317 + h_file = au_hf_top(file);
22318 + if (h_file->f_op && h_file->f_op->poll)
22319 + mask = h_file->f_op->poll(h_file, wait);
22321 + di_read_unlock(dentry, AuLock_IR);
22322 + fi_read_unlock(file);
22325 + si_read_unlock(sb);
22326 + AuTraceErr((int)mask);
22329 diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
22330 --- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
22331 +++ linux/fs/aufs/procfs.c 2013-07-06 13:20:47.753531903 +0200
22334 + * Copyright (C) 2010-2013 Junjiro R. Okajima
22336 + * This program, aufs is free software; you can redistribute it and/or modify
22337 + * it under the terms of the GNU General Public License as published by
22338 + * the Free Software Foundation; either version 2 of the License, or
22339 + * (at your option) any later version.
22341 + * This program is distributed in the hope that it will be useful,
22342 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22343 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22344 + * GNU General Public License for more details.
22346 + * You should have received a copy of the GNU General Public License
22347 + * along with this program; if not, write to the Free Software
22348 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22352 + * procfs interfaces
22355 +#include <linux/proc_fs.h>
22358 +static int au_procfs_plm_release(struct inode *inode, struct file *file)
22360 + struct au_sbinfo *sbinfo;
22362 + sbinfo = file->private_data;
22364 + au_plink_maint_leave(sbinfo);
22365 + kobject_put(&sbinfo->si_kobj);
22371 +static void au_procfs_plm_write_clean(struct file *file)
22373 + struct au_sbinfo *sbinfo;
22375 + sbinfo = file->private_data;
22377 + au_plink_clean(sbinfo->si_sb, /*verbose*/0);
22380 +static int au_procfs_plm_write_si(struct file *file, unsigned long id)
22383 + struct super_block *sb;
22384 + struct au_sbinfo *sbinfo;
22387 + if (unlikely(file->private_data))
22391 + /* don't use au_sbilist_lock() here */
22392 + spin_lock(&au_sbilist.spin);
22393 + list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
22394 + if (id == sysaufs_si_id(sbinfo)) {
22395 + kobject_get(&sbinfo->si_kobj);
22396 + sb = sbinfo->si_sb;
22399 + spin_unlock(&au_sbilist.spin);
22402 + if (unlikely(!sb))
22405 + err = au_plink_maint_enter(sb);
22407 + /* keep kobject_get() */
22408 + file->private_data = sbinfo;
22410 + kobject_put(&sbinfo->si_kobj);
22416 + * Accept a valid "si=xxxx" only.
22417 + * Once it is accepted successfully, accept "clean" too.
22419 +static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
22420 + size_t count, loff_t *ppos)
22423 + unsigned long id;
22424 + /* last newline is allowed */
22425 + char buf[3 + sizeof(unsigned long) * 2 + 1];
22428 + if (unlikely(!capable(CAP_SYS_ADMIN)))
22432 + if (unlikely(count > sizeof(buf)))
22435 + err = copy_from_user(buf, ubuf, count);
22436 + if (unlikely(err)) {
22443 + if (!strcmp("clean", buf)) {
22444 + au_procfs_plm_write_clean(file);
22445 + goto out_success;
22446 + } else if (unlikely(strncmp("si=", buf, 3)))
22449 + err = kstrtoul(buf + 3, 16, &id);
22450 + if (unlikely(err))
22453 + err = au_procfs_plm_write_si(file, id);
22454 + if (unlikely(err))
22458 + err = count; /* success */
22463 +static const struct file_operations au_procfs_plm_fop = {
22464 + .write = au_procfs_plm_write,
22465 + .release = au_procfs_plm_release,
22466 + .owner = THIS_MODULE
22469 +/* ---------------------------------------------------------------------- */
22471 +static struct proc_dir_entry *au_procfs_dir;
22473 +void au_procfs_fin(void)
22475 + remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
22476 + remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
22479 +int __init au_procfs_init(void)
22482 + struct proc_dir_entry *entry;
22485 + au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
22486 + if (unlikely(!au_procfs_dir))
22489 + entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
22490 + au_procfs_dir, &au_procfs_plm_fop);
22491 + if (unlikely(!entry))
22495 + goto out; /* success */
22499 + remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
22503 diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
22504 --- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
22505 +++ linux/fs/aufs/rdu.c 2013-07-30 22:42:55.842946719 +0200
22508 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22510 + * This program, aufs is free software; you can redistribute it and/or modify
22511 + * it under the terms of the GNU General Public License as published by
22512 + * the Free Software Foundation; either version 2 of the License, or
22513 + * (at your option) any later version.
22515 + * This program is distributed in the hope that it will be useful,
22516 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22517 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22518 + * GNU General Public License for more details.
22520 + * You should have received a copy of the GNU General Public License
22521 + * along with this program; if not, write to the Free Software
22522 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22526 + * readdir in userspace.
22529 +#include <linux/compat.h>
22530 +#include <linux/fs_stack.h>
22531 +#include <linux/security.h>
22534 +/* bits for struct aufs_rdu.flags */
22535 +#define AuRdu_CALLED 1
22536 +#define AuRdu_CONT (1 << 1)
22537 +#define AuRdu_FULL (1 << 2)
22538 +#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
22539 +#define au_fset_rdu(flags, name) \
22540 + do { (flags) |= AuRdu_##name; } while (0)
22541 +#define au_fclr_rdu(flags, name) \
22542 + do { (flags) &= ~AuRdu_##name; } while (0)
22544 +struct au_rdu_arg {
22545 + struct aufs_rdu *rdu;
22546 + union au_rdu_ent_ul ent;
22547 + unsigned long end;
22549 + struct super_block *sb;
22553 +static int au_rdu_fill(void *__arg, const char *name, int nlen,
22554 + loff_t offset, u64 h_ino, unsigned int d_type)
22557 + struct au_rdu_arg *arg = __arg;
22558 + struct aufs_rdu *rdu = arg->rdu;
22559 + struct au_rdu_ent ent;
22563 + au_fset_rdu(rdu->cookie.flags, CALLED);
22564 + len = au_rdu_len(nlen);
22565 + if (arg->ent.ul + len < arg->end) {
22567 + ent.bindex = rdu->cookie.bindex;
22568 + ent.type = d_type;
22570 + if (unlikely(nlen > AUFS_MAX_NAMELEN))
22571 + ent.type = DT_UNKNOWN;
22573 + /* unnecessary to support mmap_sem since this is a dir */
22575 + if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
22577 + if (copy_to_user(arg->ent.e->name, name, nlen))
22579 + /* the terminating NULL */
22580 + if (__put_user(0, arg->ent.e->name + nlen))
22583 + /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
22584 + arg->ent.ul += len;
22588 + au_fset_rdu(rdu->cookie.flags, FULL);
22590 + rdu->tail = arg->ent;
22594 + /* AuTraceErr(err); */
22598 +static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
22602 + struct au_rdu_cookie *cookie = &arg->rdu->cookie;
22604 + /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
22605 + offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
22607 + if (unlikely(offset != cookie->h_pos))
22613 + au_fclr_rdu(cookie->flags, CALLED);
22615 + err = vfsub_readdir(h_file, au_rdu_fill, arg);
22619 + && au_ftest_rdu(cookie->flags, CALLED)
22620 + && !au_ftest_rdu(cookie->flags, FULL));
22621 + cookie->h_pos = h_file->f_pos;
22628 +static int au_rdu(struct file *file, struct aufs_rdu *rdu)
22631 + aufs_bindex_t bend;
22632 + struct au_rdu_arg arg;
22633 + struct dentry *dentry;
22634 + struct inode *inode;
22635 + struct file *h_file;
22636 + struct au_rdu_cookie *cookie = &rdu->cookie;
22638 + err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
22639 + if (unlikely(err)) {
22645 + rdu->tail = rdu->ent;
22648 + arg.ent = rdu->ent;
22649 + arg.end = arg.ent.ul;
22650 + arg.end += rdu->sz;
22653 + if (unlikely(!file->f_op || !file->f_op->readdir))
22656 + err = security_file_permission(file, MAY_READ);
22658 + if (unlikely(err))
22661 + dentry = file->f_dentry;
22662 + inode = dentry->d_inode;
22664 + mutex_lock(&inode->i_mutex);
22666 + err = mutex_lock_killable(&inode->i_mutex);
22668 + if (unlikely(err))
22672 + arg.sb = inode->i_sb;
22673 + err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
22674 + if (unlikely(err))
22676 + err = au_alive_dir(dentry);
22677 + if (unlikely(err))
22679 + /* todo: reval? */
22680 + fi_read_lock(file);
22683 + if (unlikely(au_ftest_rdu(cookie->flags, CONT)
22684 + && cookie->generation != au_figen(file)))
22689 + rdu->blk = au_sbi(arg.sb)->si_rdblk;
22691 + rdu->blk = au_dir_size(file, /*dentry*/NULL);
22693 + bend = au_fbstart(file);
22694 + if (cookie->bindex < bend)
22695 + cookie->bindex = bend;
22696 + bend = au_fbend_dir(file);
22697 + /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
22698 + for (; !err && cookie->bindex <= bend;
22699 + cookie->bindex++, cookie->h_pos = 0) {
22700 + h_file = au_hf_dir(file, cookie->bindex);
22704 + au_fclr_rdu(cookie->flags, FULL);
22705 + err = au_rdu_do(h_file, &arg);
22707 + if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
22710 + AuDbg("rent %llu\n", rdu->rent);
22712 + if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
22713 + rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
22714 + au_fset_rdu(cookie->flags, CONT);
22715 + cookie->generation = au_figen(file);
22718 + ii_read_lock_child(inode);
22719 + fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
22720 + ii_read_unlock(inode);
22723 + fi_read_unlock(file);
22725 + si_read_unlock(arg.sb);
22727 + mutex_unlock(&inode->i_mutex);
22733 +static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
22737 + unsigned long long nent;
22738 + union au_rdu_ent_ul *u;
22739 + struct au_rdu_ent ent;
22740 + struct super_block *sb;
22743 + nent = rdu->nent;
22745 + sb = file->f_dentry->d_sb;
22746 + si_read_lock(sb, AuLock_FLUSH);
22747 + while (nent-- > 0) {
22748 + /* unnecessary to support mmap_sem since this is a dir */
22749 + err = copy_from_user(&ent, u->e, sizeof(ent));
22751 + err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
22752 + if (unlikely(err)) {
22758 + /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
22760 + err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
22762 + err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
22764 + if (unlikely(err)) {
22769 + err = __put_user(ino, &u->e->ino);
22770 + if (unlikely(err)) {
22775 + u->ul += au_rdu_len(ent.nlen);
22777 + si_read_unlock(sb);
22782 +/* ---------------------------------------------------------------------- */
22784 +static int au_rdu_verify(struct aufs_rdu *rdu)
22786 + AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
22787 + "%llu, b%d, 0x%x, g%u}\n",
22788 + rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
22790 + rdu->rent, rdu->shwh, rdu->full,
22791 + rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
22792 + rdu->cookie.generation);
22794 + if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
22798 + rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
22802 +long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
22805 + struct aufs_rdu rdu;
22806 + void __user *p = (void __user *)arg;
22808 + err = copy_from_user(&rdu, p, sizeof(rdu));
22809 + if (unlikely(err)) {
22814 + err = au_rdu_verify(&rdu);
22815 + if (unlikely(err))
22819 + case AUFS_CTL_RDU:
22820 + err = au_rdu(file, &rdu);
22821 + if (unlikely(err))
22824 + e = copy_to_user(p, &rdu, sizeof(rdu));
22825 + if (unlikely(e)) {
22830 + case AUFS_CTL_RDU_INO:
22831 + err = au_rdu_ino(file, &rdu);
22835 + /* err = -ENOTTY; */
22844 +#ifdef CONFIG_COMPAT
22845 +long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
22848 + struct aufs_rdu rdu;
22849 + void __user *p = compat_ptr(arg);
22851 + /* todo: get_user()? */
22852 + err = copy_from_user(&rdu, p, sizeof(rdu));
22853 + if (unlikely(err)) {
22858 + rdu.ent.e = compat_ptr(rdu.ent.ul);
22859 + err = au_rdu_verify(&rdu);
22860 + if (unlikely(err))
22864 + case AUFS_CTL_RDU:
22865 + err = au_rdu(file, &rdu);
22866 + if (unlikely(err))
22869 + rdu.ent.ul = ptr_to_compat(rdu.ent.e);
22870 + rdu.tail.ul = ptr_to_compat(rdu.tail.e);
22871 + e = copy_to_user(p, &rdu, sizeof(rdu));
22872 + if (unlikely(e)) {
22877 + case AUFS_CTL_RDU_INO:
22878 + err = au_rdu_ino(file, &rdu);
22882 + /* err = -ENOTTY; */
22891 diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
22892 --- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
22893 +++ linux/fs/aufs/rwsem.h 2013-07-06 13:20:47.753531903 +0200
22896 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22898 + * This program, aufs is free software; you can redistribute it and/or modify
22899 + * it under the terms of the GNU General Public License as published by
22900 + * the Free Software Foundation; either version 2 of the License, or
22901 + * (at your option) any later version.
22903 + * This program is distributed in the hope that it will be useful,
22904 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22905 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22906 + * GNU General Public License for more details.
22908 + * You should have received a copy of the GNU General Public License
22909 + * along with this program; if not, write to the Free Software
22910 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22914 + * simple read-write semaphore wrappers
22917 +#ifndef __AUFS_RWSEM_H__
22918 +#define __AUFS_RWSEM_H__
22922 +#include "debug.h"
22925 + struct rw_semaphore rwsem;
22926 +#ifdef CONFIG_AUFS_DEBUG
22927 + /* just for debugging, not almighty counter */
22928 + atomic_t rcnt, wcnt;
22932 +#ifdef CONFIG_AUFS_DEBUG
22933 +#define AuDbgCntInit(rw) do { \
22934 + atomic_set(&(rw)->rcnt, 0); \
22935 + atomic_set(&(rw)->wcnt, 0); \
22936 + smp_mb(); /* atomic set */ \
22939 +#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
22940 +#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
22941 +#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
22942 +#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
22944 +#define AuDbgCntInit(rw) do {} while (0)
22945 +#define AuDbgRcntInc(rw) do {} while (0)
22946 +#define AuDbgRcntDec(rw) do {} while (0)
22947 +#define AuDbgWcntInc(rw) do {} while (0)
22948 +#define AuDbgWcntDec(rw) do {} while (0)
22949 +#endif /* CONFIG_AUFS_DEBUG */
22951 +/* to debug easier, do not make them inlined functions */
22952 +#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
22953 +/* rwsem_is_locked() is unusable */
22954 +#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
22955 +#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
22956 +#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
22957 + && atomic_read(&(rw)->wcnt) <= 0)
22958 +#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
22959 + || atomic_read(&(rw)->wcnt))
22961 +#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
22963 +static inline void au_rw_init(struct au_rwsem *rw)
22965 + AuDbgCntInit(rw);
22966 + init_rwsem(&rw->rwsem);
22969 +static inline void au_rw_init_wlock(struct au_rwsem *rw)
22972 + down_write(&rw->rwsem);
22973 + AuDbgWcntInc(rw);
22976 +static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
22977 + unsigned int lsc)
22980 + down_write_nested(&rw->rwsem, lsc);
22981 + AuDbgWcntInc(rw);
22984 +static inline void au_rw_read_lock(struct au_rwsem *rw)
22986 + down_read(&rw->rwsem);
22987 + AuDbgRcntInc(rw);
22990 +static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
22992 + down_read_nested(&rw->rwsem, lsc);
22993 + AuDbgRcntInc(rw);
22996 +static inline void au_rw_read_unlock(struct au_rwsem *rw)
22998 + AuRwMustReadLock(rw);
22999 + AuDbgRcntDec(rw);
23000 + up_read(&rw->rwsem);
23003 +static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
23005 + AuRwMustWriteLock(rw);
23006 + AuDbgRcntInc(rw);
23007 + AuDbgWcntDec(rw);
23008 + downgrade_write(&rw->rwsem);
23011 +static inline void au_rw_write_lock(struct au_rwsem *rw)
23013 + down_write(&rw->rwsem);
23014 + AuDbgWcntInc(rw);
23017 +static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
23018 + unsigned int lsc)
23020 + down_write_nested(&rw->rwsem, lsc);
23021 + AuDbgWcntInc(rw);
23024 +static inline void au_rw_write_unlock(struct au_rwsem *rw)
23026 + AuRwMustWriteLock(rw);
23027 + AuDbgWcntDec(rw);
23028 + up_write(&rw->rwsem);
23031 +/* why is not _nested version defined */
23032 +static inline int au_rw_read_trylock(struct au_rwsem *rw)
23034 + int ret = down_read_trylock(&rw->rwsem);
23036 + AuDbgRcntInc(rw);
23040 +static inline int au_rw_write_trylock(struct au_rwsem *rw)
23042 + int ret = down_write_trylock(&rw->rwsem);
23044 + AuDbgWcntInc(rw);
23048 +#undef AuDbgCntInit
23049 +#undef AuDbgRcntInc
23050 +#undef AuDbgRcntDec
23051 +#undef AuDbgWcntInc
23052 +#undef AuDbgWcntDec
23054 +#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
23055 +static inline void prefix##_read_lock(param) \
23056 +{ au_rw_read_lock(rwsem); } \
23057 +static inline void prefix##_write_lock(param) \
23058 +{ au_rw_write_lock(rwsem); } \
23059 +static inline int prefix##_read_trylock(param) \
23060 +{ return au_rw_read_trylock(rwsem); } \
23061 +static inline int prefix##_write_trylock(param) \
23062 +{ return au_rw_write_trylock(rwsem); }
23063 +/* why is not _nested version defined */
23064 +/* static inline void prefix##_read_trylock_nested(param, lsc)
23065 +{ au_rw_read_trylock_nested(rwsem, lsc)); }
23066 +static inline void prefix##_write_trylock_nestd(param, lsc)
23067 +{ au_rw_write_trylock_nested(rwsem, lsc); } */
23069 +#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
23070 +static inline void prefix##_read_unlock(param) \
23071 +{ au_rw_read_unlock(rwsem); } \
23072 +static inline void prefix##_write_unlock(param) \
23073 +{ au_rw_write_unlock(rwsem); } \
23074 +static inline void prefix##_downgrade_lock(param) \
23075 +{ au_rw_dgrade_lock(rwsem); }
23077 +#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
23078 + AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
23079 + AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
23081 +#endif /* __KERNEL__ */
23082 +#endif /* __AUFS_RWSEM_H__ */
23083 diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
23084 --- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
23085 +++ linux/fs/aufs/sbinfo.c 2013-07-06 13:20:47.753531903 +0200
23088 + * Copyright (C) 2005-2013 Junjiro R. Okajima
23090 + * This program, aufs is free software; you can redistribute it and/or modify
23091 + * it under the terms of the GNU General Public License as published by
23092 + * the Free Software Foundation; either version 2 of the License, or
23093 + * (at your option) any later version.
23095 + * This program is distributed in the hope that it will be useful,
23096 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23097 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23098 + * GNU General Public License for more details.
23100 + * You should have received a copy of the GNU General Public License
23101 + * along with this program; if not, write to the Free Software
23102 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23106 + * superblock private data
23112 + * they are necessary regardless sysfs is disabled.
23114 +void au_si_free(struct kobject *kobj)
23117 + struct au_sbinfo *sbinfo;
23118 + char *locked __maybe_unused; /* debug only */
23120 + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
23121 + for (i = 0; i < AuPlink_NHASH; i++)
23122 + AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
23123 + AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
23125 + au_rw_write_lock(&sbinfo->si_rwsem);
23126 + au_br_free(sbinfo);
23127 + au_rw_write_unlock(&sbinfo->si_rwsem);
23129 + AuDebugOn(radix_tree_gang_lookup
23130 + (&sbinfo->au_si_pid.tree, (void **)&locked,
23131 + /*first_index*/PID_MAX_DEFAULT - 1,
23132 + /*max_items*/sizeof(locked)/sizeof(*locked)));
23134 + kfree(sbinfo->si_branch);
23135 + kfree(sbinfo->au_si_pid.bitmap);
23136 + mutex_destroy(&sbinfo->si_xib_mtx);
23137 + AuRwDestroy(&sbinfo->si_rwsem);
23142 +int au_si_alloc(struct super_block *sb)
23145 + struct au_sbinfo *sbinfo;
23146 + static struct lock_class_key aufs_si;
23149 + sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
23150 + if (unlikely(!sbinfo))
23153 + BUILD_BUG_ON(sizeof(unsigned long) !=
23154 + sizeof(*sbinfo->au_si_pid.bitmap));
23155 + sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
23156 + sizeof(*sbinfo->au_si_pid.bitmap),
23158 + if (unlikely(!sbinfo->au_si_pid.bitmap))
23161 + /* will be reallocated separately */
23162 + sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
23163 + if (unlikely(!sbinfo->si_branch))
23166 + err = sysaufs_si_init(sbinfo);
23167 + if (unlikely(err))
23170 + au_nwt_init(&sbinfo->si_nowait);
23171 + au_rw_init_wlock(&sbinfo->si_rwsem);
23172 + au_rw_class(&sbinfo->si_rwsem, &aufs_si);
23173 + spin_lock_init(&sbinfo->au_si_pid.tree_lock);
23174 + INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
23176 + atomic_long_set(&sbinfo->si_ninodes, 0);
23177 + atomic_long_set(&sbinfo->si_nfiles, 0);
23179 + sbinfo->si_bend = -1;
23181 + sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
23182 + sbinfo->si_wbr_create = AuWbrCreate_Def;
23183 + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
23184 + sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
23186 + sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
23188 + mutex_init(&sbinfo->si_xib_mtx);
23189 + sbinfo->si_xino_brid = -1;
23190 + /* leave si_xib_last_pindex and si_xib_next_bit */
23192 + sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
23193 + sbinfo->si_rdblk = AUFS_RDBLK_DEF;
23194 + sbinfo->si_rdhash = AUFS_RDHASH_DEF;
23195 + sbinfo->si_dirwh = AUFS_DIRWH_DEF;
23197 + for (i = 0; i < AuPlink_NHASH; i++)
23198 + au_sphl_init(sbinfo->si_plink + i);
23199 + init_waitqueue_head(&sbinfo->si_plink_wq);
23200 + spin_lock_init(&sbinfo->si_plink_maint_lock);
23202 + /* leave other members for sysaufs and si_mnt. */
23203 + sbinfo->si_sb = sb;
23204 + sb->s_fs_info = sbinfo;
23206 + au_debug_sbinfo_init(sbinfo);
23207 + return 0; /* success */
23210 + kfree(sbinfo->si_branch);
23212 + kfree(sbinfo->au_si_pid.bitmap);
23219 +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
23222 + struct au_branch **brp;
23224 + AuRwMustWriteLock(&sbinfo->si_rwsem);
23227 + sz = sizeof(*brp) * (sbinfo->si_bend + 1);
23228 + if (unlikely(!sz))
23229 + sz = sizeof(*brp);
23230 + brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
23232 + sbinfo->si_branch = brp;
23239 +/* ---------------------------------------------------------------------- */
23241 +unsigned int au_sigen_inc(struct super_block *sb)
23243 + unsigned int gen;
23245 + SiMustWriteLock(sb);
23247 + gen = ++au_sbi(sb)->si_generation;
23248 + au_update_digen(sb->s_root);
23249 + au_update_iigen(sb->s_root->d_inode, /*half*/0);
23250 + sb->s_root->d_inode->i_version++;
23254 +aufs_bindex_t au_new_br_id(struct super_block *sb)
23256 + aufs_bindex_t br_id;
23258 + struct au_sbinfo *sbinfo;
23260 + SiMustWriteLock(sb);
23262 + sbinfo = au_sbi(sb);
23263 + for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
23264 + br_id = ++sbinfo->si_last_br_id;
23265 + AuDebugOn(br_id < 0);
23266 + if (br_id && au_br_index(sb, br_id) < 0)
23273 +/* ---------------------------------------------------------------------- */
23275 +/* it is ok that new 'nwt' tasks are appended while we are sleeping */
23276 +int si_read_lock(struct super_block *sb, int flags)
23281 + if (au_ftest_lock(flags, FLUSH))
23282 + au_nwt_flush(&au_sbi(sb)->si_nowait);
23284 + si_noflush_read_lock(sb);
23285 + err = au_plink_maint(sb, flags);
23286 + if (unlikely(err))
23287 + si_read_unlock(sb);
23292 +int si_write_lock(struct super_block *sb, int flags)
23296 + if (au_ftest_lock(flags, FLUSH))
23297 + au_nwt_flush(&au_sbi(sb)->si_nowait);
23299 + si_noflush_write_lock(sb);
23300 + err = au_plink_maint(sb, flags);
23301 + if (unlikely(err))
23302 + si_write_unlock(sb);
23307 +/* dentry and super_block lock. call at entry point */
23308 +int aufs_read_lock(struct dentry *dentry, int flags)
23311 + struct super_block *sb;
23313 + sb = dentry->d_sb;
23314 + err = si_read_lock(sb, flags);
23315 + if (unlikely(err))
23318 + if (au_ftest_lock(flags, DW))
23319 + di_write_lock_child(dentry);
23321 + di_read_lock_child(dentry, flags);
23323 + if (au_ftest_lock(flags, GEN)) {
23324 + err = au_digen_test(dentry, au_sigen(sb));
23325 + AuDebugOn(!err && au_dbrange_test(dentry));
23326 + if (unlikely(err))
23327 + aufs_read_unlock(dentry, flags);
23334 +void aufs_read_unlock(struct dentry *dentry, int flags)
23336 + if (au_ftest_lock(flags, DW))
23337 + di_write_unlock(dentry);
23339 + di_read_unlock(dentry, flags);
23340 + si_read_unlock(dentry->d_sb);
23343 +void aufs_write_lock(struct dentry *dentry)
23345 + si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
23346 + di_write_lock_child(dentry);
23349 +void aufs_write_unlock(struct dentry *dentry)
23351 + di_write_unlock(dentry);
23352 + si_write_unlock(dentry->d_sb);
23355 +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
23358 + unsigned int sigen;
23359 + struct super_block *sb;
23362 + err = si_read_lock(sb, flags);
23363 + if (unlikely(err))
23366 + di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
23368 + if (au_ftest_lock(flags, GEN)) {
23369 + sigen = au_sigen(sb);
23370 + err = au_digen_test(d1, sigen);
23371 + AuDebugOn(!err && au_dbrange_test(d1));
23373 + err = au_digen_test(d2, sigen);
23374 + AuDebugOn(!err && au_dbrange_test(d2));
23376 + if (unlikely(err))
23377 + aufs_read_and_write_unlock2(d1, d2);
23384 +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
23386 + di_write_unlock2(d1, d2);
23387 + si_read_unlock(d1->d_sb);
23390 +/* ---------------------------------------------------------------------- */
23392 +int si_pid_test_slow(struct super_block *sb)
23397 + p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
23398 + rcu_read_unlock();
23400 + return (long)!!p;
23403 +void si_pid_set_slow(struct super_block *sb)
23406 + struct au_sbinfo *sbinfo;
23408 + AuDebugOn(si_pid_test_slow(sb));
23410 + sbinfo = au_sbi(sb);
23411 + err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
23413 + spin_lock(&sbinfo->au_si_pid.tree_lock);
23414 + err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
23415 + /*any valid ptr*/sb);
23416 + spin_unlock(&sbinfo->au_si_pid.tree_lock);
23418 + radix_tree_preload_end();
23421 +void si_pid_clr_slow(struct super_block *sb)
23424 + struct au_sbinfo *sbinfo;
23426 + AuDebugOn(!si_pid_test_slow(sb));
23428 + sbinfo = au_sbi(sb);
23429 + spin_lock(&sbinfo->au_si_pid.tree_lock);
23430 + p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
23431 + spin_unlock(&sbinfo->au_si_pid.tree_lock);
23433 diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
23434 --- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
23435 +++ linux/fs/aufs/spl.h 2013-07-06 13:20:47.753531903 +0200
23438 + * Copyright (C) 2005-2013 Junjiro R. Okajima
23440 + * This program, aufs is free software; you can redistribute it and/or modify
23441 + * it under the terms of the GNU General Public License as published by
23442 + * the Free Software Foundation; either version 2 of the License, or
23443 + * (at your option) any later version.
23445 + * This program is distributed in the hope that it will be useful,
23446 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23447 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23448 + * GNU General Public License for more details.
23450 + * You should have received a copy of the GNU General Public License
23451 + * along with this program; if not, write to the Free Software
23452 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23456 + * simple list protected by a spinlock
23459 +#ifndef __AUFS_SPL_H__
23460 +#define __AUFS_SPL_H__
23464 +struct au_splhead {
23466 + struct list_head head;
23469 +static inline void au_spl_init(struct au_splhead *spl)
23471 + spin_lock_init(&spl->spin);
23472 + INIT_LIST_HEAD(&spl->head);
23475 +static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
23477 + spin_lock(&spl->spin);
23478 + list_add(list, &spl->head);
23479 + spin_unlock(&spl->spin);
23482 +static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
23484 + spin_lock(&spl->spin);
23486 + spin_unlock(&spl->spin);
23489 +static inline void au_spl_del_rcu(struct list_head *list,
23490 + struct au_splhead *spl)
23492 + spin_lock(&spl->spin);
23493 + list_del_rcu(list);
23494 + spin_unlock(&spl->spin);
23497 +/* ---------------------------------------------------------------------- */
23499 +struct au_sphlhead {
23501 + struct hlist_head head;
23504 +static inline void au_sphl_init(struct au_sphlhead *sphl)
23506 + spin_lock_init(&sphl->spin);
23507 + INIT_HLIST_HEAD(&sphl->head);
23510 +static inline void au_sphl_add(struct hlist_node *hlist,
23511 + struct au_sphlhead *sphl)
23513 + spin_lock(&sphl->spin);
23514 + hlist_add_head(hlist, &sphl->head);
23515 + spin_unlock(&sphl->spin);
23518 +static inline void au_sphl_del(struct hlist_node *hlist,
23519 + struct au_sphlhead *sphl)
23521 + spin_lock(&sphl->spin);
23522 + hlist_del(hlist);
23523 + spin_unlock(&sphl->spin);
23526 +static inline void au_sphl_del_rcu(struct hlist_node *hlist,
23527 + struct au_sphlhead *sphl)
23529 + spin_lock(&sphl->spin);
23530 + hlist_del_rcu(hlist);
23531 + spin_unlock(&sphl->spin);
23534 +static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
23536 + unsigned long cnt;
23537 + struct hlist_node *pos;
23540 + spin_lock(&sphl->spin);
23541 + hlist_for_each(pos, &sphl->head)
23543 + spin_unlock(&sphl->spin);
23547 +#endif /* __KERNEL__ */
23548 +#endif /* __AUFS_SPL_H__ */
23549 diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
23550 --- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
23551 +++ linux/fs/aufs/super.c 2013-07-06 13:20:47.753531903 +0200
23554 + * Copyright (C) 2005-2013 Junjiro R. Okajima
23556 + * This program, aufs is free software; you can redistribute it and/or modify
23557 + * it under the terms of the GNU General Public License as published by
23558 + * the Free Software Foundation; either version 2 of the License, or
23559 + * (at your option) any later version.
23561 + * This program is distributed in the hope that it will be useful,
23562 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23563 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23564 + * GNU General Public License for more details.
23566 + * You should have received a copy of the GNU General Public License
23567 + * along with this program; if not, write to the Free Software
23568 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23572 + * mount and super_block operations
23575 +#include <linux/mm.h>
23576 +#include <linux/module.h>
23577 +#include <linux/seq_file.h>
23578 +#include <linux/statfs.h>
23579 +#include <linux/vmalloc.h>
23580 +#include <linux/writeback.h>
23584 + * super_operations
23586 +static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
23588 + struct au_icntnr *c;
23590 + c = au_cache_alloc_icntnr();
23592 + au_icntnr_init(c);
23593 + c->vfs_inode.i_version = 1; /* sigen(sb); */
23594 + c->iinfo.ii_hinode = NULL;
23595 + return &c->vfs_inode;
23600 +static void aufs_destroy_inode_cb(struct rcu_head *head)
23602 + struct inode *inode = container_of(head, struct inode, i_rcu);
23604 + INIT_HLIST_HEAD(&inode->i_dentry);
23605 + au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
23608 +static void aufs_destroy_inode(struct inode *inode)
23610 + au_iinfo_fin(inode);
23611 + call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
23614 +struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
23616 + struct inode *inode;
23619 + inode = iget_locked(sb, ino);
23620 + if (unlikely(!inode)) {
23621 + inode = ERR_PTR(-ENOMEM);
23624 + if (!(inode->i_state & I_NEW))
23627 + err = au_xigen_new(inode);
23629 + err = au_iinfo_init(inode);
23631 + inode->i_version++;
23633 + iget_failed(inode);
23634 + inode = ERR_PTR(err);
23638 + /* never return NULL */
23639 + AuDebugOn(!inode);
23640 + AuTraceErrPtr(inode);
23644 +/* lock free root dinfo */
23645 +static int au_show_brs(struct seq_file *seq, struct super_block *sb)
23648 + aufs_bindex_t bindex, bend;
23649 + struct path path;
23650 + struct au_hdentry *hdp;
23651 + struct au_branch *br;
23655 + bend = au_sbend(sb);
23656 + hdp = au_di(sb->s_root)->di_hdentry;
23657 + for (bindex = 0; !err && bindex <= bend; bindex++) {
23658 + br = au_sbr(sb, bindex);
23659 + path.mnt = au_br_mnt(br);
23660 + path.dentry = hdp[bindex].hd_dentry;
23661 + err = au_seq_path(seq, &path);
23663 + perm = au_optstr_br_perm(br->br_perm);
23665 + err = seq_printf(seq, "=%s", perm);
23672 + if (!err && bindex != bend)
23673 + err = seq_putc(seq, ':');
23679 +static void au_show_wbr_create(struct seq_file *m, int v,
23680 + struct au_sbinfo *sbinfo)
23684 + AuRwMustAnyLock(&sbinfo->si_rwsem);
23686 + seq_printf(m, ",create=");
23687 + pat = au_optstr_wbr_create(v);
23689 + case AuWbrCreate_TDP:
23690 + case AuWbrCreate_RR:
23691 + case AuWbrCreate_MFS:
23692 + case AuWbrCreate_PMFS:
23693 + seq_printf(m, pat);
23695 + case AuWbrCreate_MFSV:
23696 + seq_printf(m, /*pat*/"mfs:%lu",
23697 + jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23700 + case AuWbrCreate_PMFSV:
23701 + seq_printf(m, /*pat*/"pmfs:%lu",
23702 + jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23705 + case AuWbrCreate_MFSRR:
23706 + seq_printf(m, /*pat*/"mfsrr:%llu",
23707 + sbinfo->si_wbr_mfs.mfsrr_watermark);
23709 + case AuWbrCreate_MFSRRV:
23710 + seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
23711 + sbinfo->si_wbr_mfs.mfsrr_watermark,
23712 + jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23718 +static int au_show_xino(struct seq_file *seq, struct super_block *sb)
23720 +#ifdef CONFIG_SYSFS
23724 + const int len = sizeof(AUFS_XINO_FNAME) - 1;
23725 + aufs_bindex_t bindex, brid;
23726 + struct qstr *name;
23728 + struct dentry *d, *h_root;
23729 + struct au_hdentry *hdp;
23731 + AuRwMustAnyLock(&sbinfo->si_rwsem);
23734 + f = au_sbi(sb)->si_xib;
23738 + /* stop printing the default xino path on the first writable branch */
23740 + brid = au_xino_brid(sb);
23742 + bindex = au_br_index(sb, brid);
23743 + hdp = au_di(sb->s_root)->di_hdentry;
23744 + h_root = hdp[0 + bindex].hd_dentry;
23747 + name = &d->d_name;
23748 + /* safe ->d_parent because the file is unlinked */
23749 + if (d->d_parent == h_root
23750 + && name->len == len
23751 + && !memcmp(name->name, AUFS_XINO_FNAME, len))
23754 + seq_puts(seq, ",xino=");
23755 + err = au_xino_path(seq, f);
23762 +/* seq_file will re-call me in case of too long string */
23763 +static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
23766 + unsigned int mnt_flags, v;
23767 + struct super_block *sb;
23768 + struct au_sbinfo *sbinfo;
23770 +#define AuBool(name, str) do { \
23771 + v = au_opt_test(mnt_flags, name); \
23772 + if (v != au_opt_test(AuOpt_Def, name)) \
23773 + seq_printf(m, ",%s" #str, v ? "" : "no"); \
23776 +#define AuStr(name, str) do { \
23777 + v = mnt_flags & AuOptMask_##name; \
23778 + if (v != (AuOpt_Def & AuOptMask_##name)) \
23779 + seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
23782 +#define AuUInt(name, str, val) do { \
23783 + if (val != AUFS_##name##_DEF) \
23784 + seq_printf(m, "," #str "=%u", val); \
23787 + /* lock free root dinfo */
23788 + sb = dentry->d_sb;
23789 + si_noflush_read_lock(sb);
23790 + sbinfo = au_sbi(sb);
23791 + seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
23793 + mnt_flags = au_mntflags(sb);
23794 + if (au_opt_test(mnt_flags, XINO)) {
23795 + err = au_show_xino(m, sb);
23796 + if (unlikely(err))
23799 + seq_puts(m, ",noxino");
23801 + AuBool(TRUNC_XINO, trunc_xino);
23802 + AuStr(UDBA, udba);
23803 + AuBool(SHWH, shwh);
23804 + AuBool(PLINK, plink);
23805 + AuBool(DIO, dio);
23806 + /* AuBool(DIRPERM1, dirperm1); */
23807 + /* AuBool(REFROF, refrof); */
23809 + v = sbinfo->si_wbr_create;
23810 + if (v != AuWbrCreate_Def)
23811 + au_show_wbr_create(m, v, sbinfo);
23813 + v = sbinfo->si_wbr_copyup;
23814 + if (v != AuWbrCopyup_Def)
23815 + seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
23817 + v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
23818 + if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
23819 + seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
23821 + AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
23823 + v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
23824 + AuUInt(RDCACHE, rdcache, v);
23826 + AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
23827 + AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
23829 + AuBool(SUM, sum);
23830 + /* AuBool(SUM_W, wsum); */
23831 + AuBool(WARN_PERM, warn_perm);
23832 + AuBool(VERBOSE, verbose);
23835 + /* be sure to print "br:" last */
23836 + if (!sysaufs_brs) {
23837 + seq_puts(m, ",br:");
23838 + au_show_brs(m, sb);
23840 + si_read_unlock(sb);
23848 +/* ---------------------------------------------------------------------- */
23850 +/* sum mode which returns the summation for statfs(2) */
23852 +static u64 au_add_till_max(u64 a, u64 b)
23860 + return ULLONG_MAX;
23863 +static u64 au_mul_till_max(u64 a, long mul)
23871 + return ULLONG_MAX;
23874 +static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
23877 + long bsize, factor;
23878 + u64 blocks, bfree, bavail, files, ffree;
23879 + aufs_bindex_t bend, bindex, i;
23880 + unsigned char shared;
23881 + struct path h_path;
23882 + struct super_block *h_sb;
23885 + bsize = LONG_MAX;
23891 + bend = au_sbend(sb);
23892 + for (bindex = 0; bindex <= bend; bindex++) {
23893 + h_path.mnt = au_sbr_mnt(sb, bindex);
23894 + h_sb = h_path.mnt->mnt_sb;
23896 + for (i = 0; !shared && i < bindex; i++)
23897 + shared = (au_sbr_sb(sb, i) == h_sb);
23901 + /* sb->s_root for NFS is unreliable */
23902 + h_path.dentry = h_path.mnt->mnt_root;
23903 + err = vfs_statfs(&h_path, buf);
23904 + if (unlikely(err))
23907 + if (bsize > buf->f_bsize) {
23909 + * we will reduce bsize, so we have to expand blocks
23910 + * etc. to match them again
23912 + factor = (bsize / buf->f_bsize);
23913 + blocks = au_mul_till_max(blocks, factor);
23914 + bfree = au_mul_till_max(bfree, factor);
23915 + bavail = au_mul_till_max(bavail, factor);
23916 + bsize = buf->f_bsize;
23919 + factor = (buf->f_bsize / bsize);
23920 + blocks = au_add_till_max(blocks,
23921 + au_mul_till_max(buf->f_blocks, factor));
23922 + bfree = au_add_till_max(bfree,
23923 + au_mul_till_max(buf->f_bfree, factor));
23924 + bavail = au_add_till_max(bavail,
23925 + au_mul_till_max(buf->f_bavail, factor));
23926 + files = au_add_till_max(files, buf->f_files);
23927 + ffree = au_add_till_max(ffree, buf->f_ffree);
23930 + buf->f_bsize = bsize;
23931 + buf->f_blocks = blocks;
23932 + buf->f_bfree = bfree;
23933 + buf->f_bavail = bavail;
23934 + buf->f_files = files;
23935 + buf->f_ffree = ffree;
23936 + buf->f_frsize = 0;
23942 +static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
23945 + struct path h_path;
23946 + struct super_block *sb;
23948 + /* lock free root dinfo */
23949 + sb = dentry->d_sb;
23950 + si_noflush_read_lock(sb);
23951 + if (!au_opt_test(au_mntflags(sb), SUM)) {
23952 + /* sb->s_root for NFS is unreliable */
23953 + h_path.mnt = au_sbr_mnt(sb, 0);
23954 + h_path.dentry = h_path.mnt->mnt_root;
23955 + err = vfs_statfs(&h_path, buf);
23957 + err = au_statfs_sum(sb, buf);
23958 + si_read_unlock(sb);
23961 + buf->f_type = AUFS_SUPER_MAGIC;
23962 + buf->f_namelen = AUFS_MAX_NAMELEN;
23963 + memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
23965 + /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
23970 +/* ---------------------------------------------------------------------- */
23972 +static int aufs_sync_fs(struct super_block *sb, int wait)
23975 + aufs_bindex_t bend, bindex;
23976 + struct au_branch *br;
23977 + struct super_block *h_sb;
23980 + si_noflush_read_lock(sb);
23981 + bend = au_sbend(sb);
23982 + for (bindex = 0; bindex <= bend; bindex++) {
23983 + br = au_sbr(sb, bindex);
23984 + if (!au_br_writable(br->br_perm))
23987 + h_sb = au_sbr_sb(sb, bindex);
23988 + if (h_sb->s_op->sync_fs) {
23989 + e = h_sb->s_op->sync_fs(h_sb, wait);
23990 + if (unlikely(e && !err))
23992 + /* go on even if an error happens */
23995 + si_read_unlock(sb);
24000 +/* ---------------------------------------------------------------------- */
24002 +/* final actions when unmounting a file system */
24003 +static void aufs_put_super(struct super_block *sb)
24005 + struct au_sbinfo *sbinfo;
24007 + sbinfo = au_sbi(sb);
24011 + dbgaufs_si_fin(sbinfo);
24012 + kobject_put(&sbinfo->si_kobj);
24015 +/* ---------------------------------------------------------------------- */
24017 +void au_array_free(void *array)
24020 + if (!is_vmalloc_addr(array))
24027 +void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
24030 + unsigned long long n;
24037 + if (*hint > ULLONG_MAX / sizeof(array)) {
24038 + array = ERR_PTR(-EMFILE);
24039 + pr_err("hint %llu\n", *hint);
24043 + array = kmalloc(sizeof(array) * *hint, GFP_NOFS);
24044 + if (unlikely(!array))
24045 + array = vmalloc(sizeof(array) * *hint);
24046 + if (unlikely(!array)) {
24047 + array = ERR_PTR(-ENOMEM);
24051 + n = cb(array, *hint, arg);
24052 + AuDebugOn(n > *hint);
24059 +static unsigned long long au_iarray_cb(void *a,
24060 + unsigned long long max __maybe_unused,
24063 + unsigned long long n;
24064 + struct inode **p, *inode;
24065 + struct list_head *head;
24070 + spin_lock(&inode_sb_list_lock);
24071 + list_for_each_entry(inode, head, i_sb_list) {
24072 + if (!is_bad_inode(inode)
24073 + && au_ii(inode)->ii_bstart >= 0) {
24074 + spin_lock(&inode->i_lock);
24075 + if (atomic_read(&inode->i_count)) {
24079 + AuDebugOn(n > max);
24081 + spin_unlock(&inode->i_lock);
24084 + spin_unlock(&inode_sb_list_lock);
24089 +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
24091 + *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
24092 + return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
24095 +void au_iarray_free(struct inode **a, unsigned long long max)
24097 + unsigned long long ull;
24099 + for (ull = 0; ull < max; ull++)
24101 + au_array_free(a);
24104 +/* ---------------------------------------------------------------------- */
24107 + * refresh dentry and inode at remount time.
24109 +/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
24110 +static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
24111 + struct dentry *parent)
24115 + di_write_lock_child(dentry);
24116 + di_read_lock_parent(parent, AuLock_IR);
24117 + err = au_refresh_dentry(dentry, parent);
24118 + if (!err && dir_flags)
24119 + au_hn_reset(dentry->d_inode, dir_flags);
24120 + di_read_unlock(parent, AuLock_IR);
24121 + di_write_unlock(dentry);
24126 +static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
24127 + struct au_sbinfo *sbinfo,
24128 + const unsigned int dir_flags)
24131 + struct dentry *parent;
24132 + struct inode *inode;
24135 + parent = dget_parent(dentry);
24136 + if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
24137 + inode = dentry->d_inode;
24139 + if (!S_ISDIR(inode->i_mode))
24140 + err = au_do_refresh(dentry, /*dir_flags*/0,
24143 + err = au_do_refresh(dentry, dir_flags, parent);
24144 + if (unlikely(err))
24145 + au_fset_si(sbinfo, FAILED_REFRESH_DIR);
24148 + err = au_do_refresh(dentry, /*dir_flags*/0, parent);
24149 + AuDbgDentry(dentry);
24157 +static int au_refresh_d(struct super_block *sb)
24159 + int err, i, j, ndentry, e;
24160 + unsigned int sigen;
24161 + struct au_dcsub_pages dpages;
24162 + struct au_dpage *dpage;
24163 + struct dentry **dentries, *d;
24164 + struct au_sbinfo *sbinfo;
24165 + struct dentry *root = sb->s_root;
24166 + const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
24168 + err = au_dpages_init(&dpages, GFP_NOFS);
24169 + if (unlikely(err))
24171 + err = au_dcsub_pages(&dpages, root, NULL, NULL);
24172 + if (unlikely(err))
24175 + sigen = au_sigen(sb);
24176 + sbinfo = au_sbi(sb);
24177 + for (i = 0; i < dpages.ndpage; i++) {
24178 + dpage = dpages.dpages + i;
24179 + dentries = dpage->dentries;
24180 + ndentry = dpage->ndentry;
24181 + for (j = 0; j < ndentry; j++) {
24183 + e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
24184 + if (unlikely(e && !err))
24186 + /* go on even err */
24191 + au_dpages_free(&dpages);
24196 +static int au_refresh_i(struct super_block *sb)
24199 + unsigned int sigen;
24200 + unsigned long long max, ull;
24201 + struct inode *inode, **array;
24203 + array = au_iarray_alloc(sb, &max);
24204 + err = PTR_ERR(array);
24205 + if (IS_ERR(array))
24209 + sigen = au_sigen(sb);
24210 + for (ull = 0; ull < max; ull++) {
24211 + inode = array[ull];
24212 + if (au_iigen(inode, NULL) != sigen) {
24213 + ii_write_lock_child(inode);
24214 + e = au_refresh_hinode_self(inode);
24215 + ii_write_unlock(inode);
24216 + if (unlikely(e)) {
24217 + pr_err("error %d, i%lu\n", e, inode->i_ino);
24220 + /* go on even if err */
24225 + au_iarray_free(array, max);
24231 +static void au_remount_refresh(struct super_block *sb)
24234 + unsigned int udba;
24235 + aufs_bindex_t bindex, bend;
24236 + struct dentry *root;
24237 + struct inode *inode;
24238 + struct au_branch *br;
24240 + au_sigen_inc(sb);
24241 + au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
24243 + root = sb->s_root;
24244 + DiMustNoWaiters(root);
24245 + inode = root->d_inode;
24246 + IiMustNoWaiters(inode);
24248 + udba = au_opt_udba(sb);
24249 + bend = au_sbend(sb);
24250 + for (bindex = 0; bindex <= bend; bindex++) {
24251 + br = au_sbr(sb, bindex);
24252 + err = au_hnotify_reset_br(udba, br, br->br_perm);
24253 + if (unlikely(err))
24254 + AuIOErr("hnotify failed on br %d, %d, ignored\n",
24256 + /* go on even if err */
24258 + au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
24260 + di_write_unlock(root);
24261 + err = au_refresh_d(sb);
24262 + e = au_refresh_i(sb);
24263 + if (unlikely(e && !err))
24265 + /* aufs_write_lock() calls ..._child() */
24266 + di_write_lock_child(root);
24268 + au_cpup_attr_all(inode, /*force*/1);
24270 + if (unlikely(err))
24271 + AuIOErr("refresh failed, ignored, %d\n", err);
24274 +/* stop extra interpretation of errno in mount(8), and strange error messages */
24275 +static int cvt_err(int err)
24289 +static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
24292 + unsigned int mntflags;
24293 + struct au_opts opts;
24294 + struct dentry *root;
24295 + struct inode *inode;
24296 + struct au_sbinfo *sbinfo;
24299 + root = sb->s_root;
24300 + if (!data || !*data) {
24301 + err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
24303 + di_write_lock_child(root);
24304 + err = au_opts_verify(sb, *flags, /*pending*/0);
24305 + aufs_write_unlock(root);
24311 + memset(&opts, 0, sizeof(opts));
24312 + opts.opt = (void *)__get_free_page(GFP_NOFS);
24313 + if (unlikely(!opts.opt))
24315 + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
24316 + opts.flags = AuOpts_REMOUNT;
24317 + opts.sb_flags = *flags;
24319 + /* parse it before aufs lock */
24320 + err = au_opts_parse(sb, data, &opts);
24321 + if (unlikely(err))
24324 + sbinfo = au_sbi(sb);
24325 + inode = root->d_inode;
24326 + mutex_lock(&inode->i_mutex);
24327 + err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
24328 + if (unlikely(err))
24330 + di_write_lock_child(root);
24332 + /* au_opts_remount() may return an error */
24333 + err = au_opts_remount(sb, &opts);
24334 + au_opts_free(&opts);
24336 + if (au_ftest_opts(opts.flags, REFRESH))
24337 + au_remount_refresh(sb);
24339 + if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
24340 + mntflags = au_mntflags(sb);
24341 + do_dx = !!au_opt_test(mntflags, DIO);
24342 + au_dy_arefresh(do_dx);
24345 + aufs_write_unlock(root);
24348 + mutex_unlock(&inode->i_mutex);
24350 + free_page((unsigned long)opts.opt);
24352 + err = cvt_err(err);
24357 +static const struct super_operations aufs_sop = {
24358 + .alloc_inode = aufs_alloc_inode,
24359 + .destroy_inode = aufs_destroy_inode,
24360 + /* always deleting, no clearing */
24361 + .drop_inode = generic_delete_inode,
24362 + .show_options = aufs_show_options,
24363 + .statfs = aufs_statfs,
24364 + .put_super = aufs_put_super,
24365 + .sync_fs = aufs_sync_fs,
24366 + .remount_fs = aufs_remount_fs
24369 +/* ---------------------------------------------------------------------- */
24371 +static int alloc_root(struct super_block *sb)
24374 + struct inode *inode;
24375 + struct dentry *root;
24378 + inode = au_iget_locked(sb, AUFS_ROOT_INO);
24379 + err = PTR_ERR(inode);
24380 + if (IS_ERR(inode))
24383 + inode->i_op = &aufs_dir_iop;
24384 + inode->i_fop = &aufs_dir_fop;
24385 + inode->i_mode = S_IFDIR;
24386 + set_nlink(inode, 2);
24387 + unlock_new_inode(inode);
24389 + root = d_make_root(inode);
24390 + if (unlikely(!root))
24392 + err = PTR_ERR(root);
24393 + if (IS_ERR(root))
24396 + err = au_di_init(root);
24398 + sb->s_root = root;
24399 + return 0; /* success */
24407 +static int aufs_fill_super(struct super_block *sb, void *raw_data,
24408 + int silent __maybe_unused)
24411 + struct au_opts opts;
24412 + struct dentry *root;
24413 + struct inode *inode;
24414 + char *arg = raw_data;
24416 + if (unlikely(!arg || !*arg)) {
24418 + pr_err("no arg\n");
24423 + memset(&opts, 0, sizeof(opts));
24424 + opts.opt = (void *)__get_free_page(GFP_NOFS);
24425 + if (unlikely(!opts.opt))
24427 + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
24428 + opts.sb_flags = sb->s_flags;
24430 + err = au_si_alloc(sb);
24431 + if (unlikely(err))
24434 + /* all timestamps always follow the ones on the branch */
24435 + sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
24436 + sb->s_op = &aufs_sop;
24437 + sb->s_d_op = &aufs_dop;
24438 + sb->s_magic = AUFS_SUPER_MAGIC;
24439 + sb->s_maxbytes = 0;
24440 + au_export_init(sb);
24442 + err = alloc_root(sb);
24443 + if (unlikely(err)) {
24444 + si_write_unlock(sb);
24447 + root = sb->s_root;
24448 + inode = root->d_inode;
24451 + * actually we can parse options regardless aufs lock here.
24452 + * but at remount time, parsing must be done before aufs lock.
24453 + * so we follow the same rule.
24455 + ii_write_lock_parent(inode);
24456 + aufs_write_unlock(root);
24457 + err = au_opts_parse(sb, arg, &opts);
24458 + if (unlikely(err))
24461 + /* lock vfs_inode first, then aufs. */
24462 + mutex_lock(&inode->i_mutex);
24463 + aufs_write_lock(root);
24464 + err = au_opts_mount(sb, &opts);
24465 + au_opts_free(&opts);
24466 + aufs_write_unlock(root);
24467 + mutex_unlock(&inode->i_mutex);
24469 + goto out_opts; /* success */
24473 + sb->s_root = NULL;
24475 + dbgaufs_si_fin(au_sbi(sb));
24476 + kobject_put(&au_sbi(sb)->si_kobj);
24477 + sb->s_fs_info = NULL;
24479 + free_page((unsigned long)opts.opt);
24482 + err = cvt_err(err);
24487 +/* ---------------------------------------------------------------------- */
24489 +static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
24490 + const char *dev_name __maybe_unused,
24493 + struct dentry *root;
24494 + struct super_block *sb;
24496 + /* all timestamps always follow the ones on the branch */
24497 + /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
24498 + root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
24499 + if (IS_ERR(root))
24503 + si_write_lock(sb, !AuLock_FLUSH);
24504 + sysaufs_brs_add(sb, 0);
24505 + si_write_unlock(sb);
24506 + au_sbilist_add(sb);
24512 +static void aufs_kill_sb(struct super_block *sb)
24514 + struct au_sbinfo *sbinfo;
24516 + sbinfo = au_sbi(sb);
24518 + au_sbilist_del(sb);
24519 + aufs_write_lock(sb->s_root);
24520 + if (sbinfo->si_wbr_create_ops->fin)
24521 + sbinfo->si_wbr_create_ops->fin(sb);
24522 + if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
24523 + au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
24524 + au_remount_refresh(sb);
24526 + if (au_opt_test(sbinfo->si_mntflags, PLINK))
24527 + au_plink_put(sb, /*verbose*/1);
24529 + sbinfo->si_sb = NULL;
24530 + aufs_write_unlock(sb->s_root);
24531 + au_nwt_flush(&sbinfo->si_nowait);
24533 + generic_shutdown_super(sb);
24536 +struct file_system_type aufs_fs_type = {
24537 + .name = AUFS_FSTYPE,
24538 + /* a race between rename and others */
24539 + .fs_flags = FS_RENAME_DOES_D_MOVE,
24540 + .mount = aufs_mount,
24541 + .kill_sb = aufs_kill_sb,
24542 + /* no need to __module_get() and module_put(). */
24543 + .owner = THIS_MODULE,
24545 diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
24546 --- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
24547 +++ linux/fs/aufs/super.h 2013-07-06 13:20:47.753531903 +0200
24550 + * Copyright (C) 2005-2013 Junjiro R. Okajima
24552 + * This program, aufs is free software; you can redistribute it and/or modify
24553 + * it under the terms of the GNU General Public License as published by
24554 + * the Free Software Foundation; either version 2 of the License, or
24555 + * (at your option) any later version.
24557 + * This program is distributed in the hope that it will be useful,
24558 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24559 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24560 + * GNU General Public License for more details.
24562 + * You should have received a copy of the GNU General Public License
24563 + * along with this program; if not, write to the Free Software
24564 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24568 + * super_block operations
24571 +#ifndef __AUFS_SUPER_H__
24572 +#define __AUFS_SUPER_H__
24576 +#include <linux/fs.h>
24577 +#include "rwsem.h"
24581 +typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
24582 +typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
24585 +/* policies to select one among multiple writable branches */
24586 +struct au_wbr_copyup_operations {
24587 + int (*copyup)(struct dentry *dentry);
24590 +struct au_wbr_create_operations {
24591 + int (*create)(struct dentry *dentry, int isdir);
24592 + int (*init)(struct super_block *sb);
24593 + int (*fin)(struct super_block *sb);
24596 +struct au_wbr_mfs {
24597 + struct mutex mfs_lock; /* protect this structure */
24598 + unsigned long mfs_jiffy;
24599 + unsigned long mfs_expire;
24600 + aufs_bindex_t mfs_bindex;
24602 + unsigned long long mfsrr_bytes;
24603 + unsigned long long mfsrr_watermark;
24606 +struct pseudo_link {
24608 + struct hlist_node hlist;
24609 + struct rcu_head rcu;
24611 + struct inode *inode;
24614 +#define AuPlink_NHASH 100
24615 +static inline int au_plink_hash(ino_t ino)
24617 + return ino % AuPlink_NHASH;
24621 +struct au_sbinfo {
24622 + /* nowait tasks in the system-wide workqueue */
24623 + struct au_nowait_tasks si_nowait;
24626 + * tried sb->s_umount, but failed due to the dependecy between i_mutex.
24627 + * rwsem for au_sbinfo is necessary.
24629 + struct au_rwsem si_rwsem;
24631 + /* prevent recursive locking in deleting inode */
24633 + unsigned long *bitmap;
24634 + spinlock_t tree_lock;
24635 + struct radix_tree_root tree;
24639 + * dirty approach to protect sb->sb_inodes and ->s_files from remount.
24641 + atomic_long_t si_ninodes, si_nfiles;
24643 + /* branch management */
24644 + unsigned int si_generation;
24646 + /* see above flags */
24647 + unsigned char au_si_status;
24649 + aufs_bindex_t si_bend;
24651 + /* dirty trick to keep br_id plus */
24652 + unsigned int si_last_br_id :
24653 + sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
24654 + struct au_branch **si_branch;
24656 + /* policy to select a writable branch */
24657 + unsigned char si_wbr_copyup;
24658 + unsigned char si_wbr_create;
24659 + struct au_wbr_copyup_operations *si_wbr_copyup_ops;
24660 + struct au_wbr_create_operations *si_wbr_create_ops;
24662 + /* round robin */
24663 + atomic_t si_wbr_rr_next;
24665 + /* most free space */
24666 + struct au_wbr_mfs si_wbr_mfs;
24668 + /* mount flags */
24669 + /* include/asm-ia64/siginfo.h defines a macro named si_flags */
24670 + unsigned int si_mntflags;
24672 + /* external inode number (bitmap and translation table) */
24673 + au_readf_t si_xread;
24674 + au_writef_t si_xwrite;
24675 + struct file *si_xib;
24676 + struct mutex si_xib_mtx; /* protect xib members */
24677 + unsigned long *si_xib_buf;
24678 + unsigned long si_xib_last_pindex;
24679 + int si_xib_next_bit;
24680 + aufs_bindex_t si_xino_brid;
24681 + /* reserved for future use */
24682 + /* unsigned long long si_xib_limit; */ /* Max xib file size */
24684 +#ifdef CONFIG_AUFS_EXPORT
24685 + /* i_generation */
24686 + struct file *si_xigen;
24687 + atomic_t si_xigen_next;
24690 + /* vdir parameters */
24691 + unsigned long si_rdcache; /* max cache time in jiffies */
24692 + unsigned int si_rdblk; /* deblk size */
24693 + unsigned int si_rdhash; /* hash size */
24696 + * If the number of whiteouts are larger than si_dirwh, leave all of
24697 + * them after au_whtmp_ren to reduce the cost of rmdir(2).
24698 + * future fsck.aufs or kernel thread will remove them later.
24699 + * Otherwise, remove all whiteouts and the dir in rmdir(2).
24701 + unsigned int si_dirwh;
24704 + * rename(2) a directory with all children.
24706 + /* reserved for future use */
24707 + /* int si_rendir; */
24709 + /* pseudo_link list */
24710 + struct au_sphlhead si_plink[AuPlink_NHASH];
24711 + wait_queue_head_t si_plink_wq;
24712 + spinlock_t si_plink_maint_lock;
24713 + pid_t si_plink_maint_pid;
24716 + * sysfs and lifetime management.
24717 + * this is not a small structure and it may be a waste of memory in case
24718 + * of sysfs is disabled, particulary when many aufs-es are mounted.
24719 + * but using sysfs is majority.
24721 + struct kobject si_kobj;
24722 +#ifdef CONFIG_DEBUG_FS
24723 + struct dentry *si_dbgaufs;
24724 + struct dentry *si_dbgaufs_plink;
24725 + struct dentry *si_dbgaufs_xib;
24726 +#ifdef CONFIG_AUFS_EXPORT
24727 + struct dentry *si_dbgaufs_xigen;
24731 +#ifdef CONFIG_AUFS_SBILIST
24732 + struct list_head si_list;
24735 + /* dirty, necessary for unmounting, sysfs and sysrq */
24736 + struct super_block *si_sb;
24739 +/* sbinfo status flags */
24741 + * set true when refresh_dirs() failed at remount time.
24742 + * then try refreshing dirs at access time again.
24743 + * if it is false, refreshing dirs at access time is unnecesary
24745 +#define AuSi_FAILED_REFRESH_DIR 1
24746 +static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
24747 + unsigned int flag)
24749 + AuRwMustAnyLock(&sbi->si_rwsem);
24750 + return sbi->au_si_status & flag;
24752 +#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
24753 +#define au_fset_si(sbinfo, name) do { \
24754 + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
24755 + (sbinfo)->au_si_status |= AuSi_##name; \
24757 +#define au_fclr_si(sbinfo, name) do { \
24758 + AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
24759 + (sbinfo)->au_si_status &= ~AuSi_##name; \
24762 +/* ---------------------------------------------------------------------- */
24764 +/* policy to select one among writable branches */
24765 +#define AuWbrCopyup(sbinfo, ...) \
24766 + ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
24767 +#define AuWbrCreate(sbinfo, ...) \
24768 + ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
24770 +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
24771 +#define AuLock_DW 1 /* write-lock dentry */
24772 +#define AuLock_IR (1 << 1) /* read-lock inode */
24773 +#define AuLock_IW (1 << 2) /* write-lock inode */
24774 +#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
24775 +#define AuLock_DIR (1 << 4) /* target is a dir */
24776 +#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
24777 +#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
24778 +#define AuLock_GEN (1 << 7) /* test digen/iigen */
24779 +#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
24780 +#define au_fset_lock(flags, name) \
24781 + do { (flags) |= AuLock_##name; } while (0)
24782 +#define au_fclr_lock(flags, name) \
24783 + do { (flags) &= ~AuLock_##name; } while (0)
24785 +/* ---------------------------------------------------------------------- */
24788 +extern struct file_system_type aufs_fs_type;
24789 +struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
24790 +typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
24792 +void au_array_free(void *array);
24793 +void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
24794 +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
24795 +void au_iarray_free(struct inode **a, unsigned long long max);
24798 +void au_si_free(struct kobject *kobj);
24799 +int au_si_alloc(struct super_block *sb);
24800 +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
24802 +unsigned int au_sigen_inc(struct super_block *sb);
24803 +aufs_bindex_t au_new_br_id(struct super_block *sb);
24805 +int si_read_lock(struct super_block *sb, int flags);
24806 +int si_write_lock(struct super_block *sb, int flags);
24807 +int aufs_read_lock(struct dentry *dentry, int flags);
24808 +void aufs_read_unlock(struct dentry *dentry, int flags);
24809 +void aufs_write_lock(struct dentry *dentry);
24810 +void aufs_write_unlock(struct dentry *dentry);
24811 +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
24812 +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
24814 +int si_pid_test_slow(struct super_block *sb);
24815 +void si_pid_set_slow(struct super_block *sb);
24816 +void si_pid_clr_slow(struct super_block *sb);
24818 +/* wbr_policy.c */
24819 +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
24820 +extern struct au_wbr_create_operations au_wbr_create_ops[];
24821 +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
24823 +/* ---------------------------------------------------------------------- */
24825 +static inline struct au_sbinfo *au_sbi(struct super_block *sb)
24827 + return sb->s_fs_info;
24830 +/* ---------------------------------------------------------------------- */
24832 +#ifdef CONFIG_AUFS_EXPORT
24833 +int au_test_nfsd(void);
24834 +void au_export_init(struct super_block *sb);
24835 +void au_xigen_inc(struct inode *inode);
24836 +int au_xigen_new(struct inode *inode);
24837 +int au_xigen_set(struct super_block *sb, struct file *base);
24838 +void au_xigen_clr(struct super_block *sb);
24840 +static inline int au_busy_or_stale(void)
24842 + if (!au_test_nfsd())
24847 +AuStubInt0(au_test_nfsd, void)
24848 +AuStubVoid(au_export_init, struct super_block *sb)
24849 +AuStubVoid(au_xigen_inc, struct inode *inode)
24850 +AuStubInt0(au_xigen_new, struct inode *inode)
24851 +AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
24852 +AuStubVoid(au_xigen_clr, struct super_block *sb)
24853 +static inline int au_busy_or_stale(void)
24857 +#endif /* CONFIG_AUFS_EXPORT */
24859 +/* ---------------------------------------------------------------------- */
24861 +#ifdef CONFIG_AUFS_SBILIST
24863 +extern struct au_splhead au_sbilist;
24865 +static inline void au_sbilist_init(void)
24867 + au_spl_init(&au_sbilist);
24870 +static inline void au_sbilist_add(struct super_block *sb)
24872 + au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
24875 +static inline void au_sbilist_del(struct super_block *sb)
24877 + au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
24880 +#ifdef CONFIG_AUFS_MAGIC_SYSRQ
24881 +static inline void au_sbilist_lock(void)
24883 + spin_lock(&au_sbilist.spin);
24886 +static inline void au_sbilist_unlock(void)
24888 + spin_unlock(&au_sbilist.spin);
24890 +#define AuGFP_SBILIST GFP_ATOMIC
24892 +AuStubVoid(au_sbilist_lock, void)
24893 +AuStubVoid(au_sbilist_unlock, void)
24894 +#define AuGFP_SBILIST GFP_NOFS
24895 +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
24897 +AuStubVoid(au_sbilist_init, void)
24898 +AuStubVoid(au_sbilist_add, struct super_block*)
24899 +AuStubVoid(au_sbilist_del, struct super_block*)
24900 +AuStubVoid(au_sbilist_lock, void)
24901 +AuStubVoid(au_sbilist_unlock, void)
24902 +#define AuGFP_SBILIST GFP_NOFS
24905 +/* ---------------------------------------------------------------------- */
24907 +static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
24910 + * This function is a dynamic '__init' fucntion actually,
24911 + * so the tiny check for si_rwsem is unnecessary.
24913 + /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
24914 +#ifdef CONFIG_DEBUG_FS
24915 + sbinfo->si_dbgaufs = NULL;
24916 + sbinfo->si_dbgaufs_plink = NULL;
24917 + sbinfo->si_dbgaufs_xib = NULL;
24918 +#ifdef CONFIG_AUFS_EXPORT
24919 + sbinfo->si_dbgaufs_xigen = NULL;
24924 +/* ---------------------------------------------------------------------- */
24926 +static inline pid_t si_pid_bit(void)
24928 + /* the origin of pid is 1, but the bitmap's is 0 */
24929 + return current->pid - 1;
24932 +static inline int si_pid_test(struct super_block *sb)
24934 + pid_t bit = si_pid_bit();
24935 + if (bit < PID_MAX_DEFAULT)
24936 + return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24938 + return si_pid_test_slow(sb);
24941 +static inline void si_pid_set(struct super_block *sb)
24943 + pid_t bit = si_pid_bit();
24944 + if (bit < PID_MAX_DEFAULT) {
24945 + AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
24946 + set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24949 + si_pid_set_slow(sb);
24952 +static inline void si_pid_clr(struct super_block *sb)
24954 + pid_t bit = si_pid_bit();
24955 + if (bit < PID_MAX_DEFAULT) {
24956 + AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
24957 + clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24960 + si_pid_clr_slow(sb);
24963 +/* ---------------------------------------------------------------------- */
24965 +/* lock superblock. mainly for entry point functions */
24967 + * __si_read_lock, __si_write_lock,
24968 + * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
24970 +AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
24972 +#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
24973 +#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
24974 +#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
24976 +static inline void si_noflush_read_lock(struct super_block *sb)
24978 + __si_read_lock(sb);
24982 +static inline int si_noflush_read_trylock(struct super_block *sb)
24984 + int locked = __si_read_trylock(sb);
24990 +static inline void si_noflush_write_lock(struct super_block *sb)
24992 + __si_write_lock(sb);
24996 +static inline int si_noflush_write_trylock(struct super_block *sb)
24998 + int locked = __si_write_trylock(sb);
25004 +#if 0 /* unused */
25005 +static inline int si_read_trylock(struct super_block *sb, int flags)
25007 + if (au_ftest_lock(flags, FLUSH))
25008 + au_nwt_flush(&au_sbi(sb)->si_nowait);
25009 + return si_noflush_read_trylock(sb);
25013 +static inline void si_read_unlock(struct super_block *sb)
25016 + __si_read_unlock(sb);
25019 +#if 0 /* unused */
25020 +static inline int si_write_trylock(struct super_block *sb, int flags)
25022 + if (au_ftest_lock(flags, FLUSH))
25023 + au_nwt_flush(&au_sbi(sb)->si_nowait);
25024 + return si_noflush_write_trylock(sb);
25028 +static inline void si_write_unlock(struct super_block *sb)
25031 + __si_write_unlock(sb);
25034 +#if 0 /* unused */
25035 +static inline void si_downgrade_lock(struct super_block *sb)
25037 + __si_downgrade_lock(sb);
25041 +/* ---------------------------------------------------------------------- */
25043 +static inline aufs_bindex_t au_sbend(struct super_block *sb)
25045 + SiMustAnyLock(sb);
25046 + return au_sbi(sb)->si_bend;
25049 +static inline unsigned int au_mntflags(struct super_block *sb)
25051 + SiMustAnyLock(sb);
25052 + return au_sbi(sb)->si_mntflags;
25055 +static inline unsigned int au_sigen(struct super_block *sb)
25057 + SiMustAnyLock(sb);
25058 + return au_sbi(sb)->si_generation;
25061 +static inline void au_ninodes_inc(struct super_block *sb)
25063 + atomic_long_inc(&au_sbi(sb)->si_ninodes);
25066 +static inline void au_ninodes_dec(struct super_block *sb)
25068 + AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
25069 + atomic_long_dec(&au_sbi(sb)->si_ninodes);
25072 +static inline void au_nfiles_inc(struct super_block *sb)
25074 + atomic_long_inc(&au_sbi(sb)->si_nfiles);
25077 +static inline void au_nfiles_dec(struct super_block *sb)
25079 + AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
25080 + atomic_long_dec(&au_sbi(sb)->si_nfiles);
25083 +static inline struct au_branch *au_sbr(struct super_block *sb,
25084 + aufs_bindex_t bindex)
25086 + SiMustAnyLock(sb);
25087 + return au_sbi(sb)->si_branch[0 + bindex];
25090 +static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
25092 + SiMustWriteLock(sb);
25093 + au_sbi(sb)->si_xino_brid = brid;
25096 +static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
25098 + SiMustAnyLock(sb);
25099 + return au_sbi(sb)->si_xino_brid;
25102 +#endif /* __KERNEL__ */
25103 +#endif /* __AUFS_SUPER_H__ */
25104 diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
25105 --- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
25106 +++ linux/fs/aufs/sysaufs.c 2013-07-06 13:20:47.753531903 +0200
25109 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25111 + * This program, aufs is free software; you can redistribute it and/or modify
25112 + * it under the terms of the GNU General Public License as published by
25113 + * the Free Software Foundation; either version 2 of the License, or
25114 + * (at your option) any later version.
25116 + * This program is distributed in the hope that it will be useful,
25117 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25118 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25119 + * GNU General Public License for more details.
25121 + * You should have received a copy of the GNU General Public License
25122 + * along with this program; if not, write to the Free Software
25123 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25127 + * sysfs interface and lifetime management
25128 + * they are necessary regardless sysfs is disabled.
25131 +#include <linux/random.h>
25134 +unsigned long sysaufs_si_mask;
25135 +struct kset *sysaufs_kset;
25137 +#define AuSiAttr(_name) { \
25138 + .attr = { .name = __stringify(_name), .mode = 0444 }, \
25139 + .show = sysaufs_si_##_name, \
25142 +static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
25143 +struct attribute *sysaufs_si_attrs[] = {
25144 + &sysaufs_si_attr_xi_path.attr,
25148 +static const struct sysfs_ops au_sbi_ops = {
25149 + .show = sysaufs_si_show
25152 +static struct kobj_type au_sbi_ktype = {
25153 + .release = au_si_free,
25154 + .sysfs_ops = &au_sbi_ops,
25155 + .default_attrs = sysaufs_si_attrs
25158 +/* ---------------------------------------------------------------------- */
25160 +int sysaufs_si_init(struct au_sbinfo *sbinfo)
25164 + sbinfo->si_kobj.kset = sysaufs_kset;
25165 + /* cf. sysaufs_name() */
25166 + err = kobject_init_and_add
25167 + (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
25168 + SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
25170 + dbgaufs_si_null(sbinfo);
25172 + err = dbgaufs_si_init(sbinfo);
25173 + if (unlikely(err))
25174 + kobject_put(&sbinfo->si_kobj);
25179 +void sysaufs_fin(void)
25182 + sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
25183 + kset_unregister(sysaufs_kset);
25186 +int __init sysaufs_init(void)
25191 + get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
25192 + } while (!sysaufs_si_mask);
25195 + sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
25196 + if (unlikely(!sysaufs_kset))
25198 + err = PTR_ERR(sysaufs_kset);
25199 + if (IS_ERR(sysaufs_kset))
25201 + err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
25202 + if (unlikely(err)) {
25203 + kset_unregister(sysaufs_kset);
25207 + err = dbgaufs_init();
25208 + if (unlikely(err))
25213 diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
25214 --- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
25215 +++ linux/fs/aufs/sysaufs.h 2013-07-06 13:20:47.753531903 +0200
25218 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25220 + * This program, aufs is free software; you can redistribute it and/or modify
25221 + * it under the terms of the GNU General Public License as published by
25222 + * the Free Software Foundation; either version 2 of the License, or
25223 + * (at your option) any later version.
25225 + * This program is distributed in the hope that it will be useful,
25226 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25227 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25228 + * GNU General Public License for more details.
25230 + * You should have received a copy of the GNU General Public License
25231 + * along with this program; if not, write to the Free Software
25232 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25236 + * sysfs interface and mount lifetime management
25239 +#ifndef __SYSAUFS_H__
25240 +#define __SYSAUFS_H__
25244 +#include <linux/sysfs.h>
25245 +#include "module.h"
25247 +struct super_block;
25250 +struct sysaufs_si_attr {
25251 + struct attribute attr;
25252 + int (*show)(struct seq_file *seq, struct super_block *sb);
25255 +/* ---------------------------------------------------------------------- */
25258 +extern unsigned long sysaufs_si_mask;
25259 +extern struct kset *sysaufs_kset;
25260 +extern struct attribute *sysaufs_si_attrs[];
25261 +int sysaufs_si_init(struct au_sbinfo *sbinfo);
25262 +int __init sysaufs_init(void);
25263 +void sysaufs_fin(void);
25265 +/* ---------------------------------------------------------------------- */
25267 +/* some people doesn't like to show a pointer in kernel */
25268 +static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
25270 + return sysaufs_si_mask ^ (unsigned long)sbinfo;
25273 +#define SysaufsSiNamePrefix "si_"
25274 +#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
25275 +static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
25277 + snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
25278 + sysaufs_si_id(sbinfo));
25282 +#ifdef CONFIG_SYSFS
25284 +extern struct attribute_group *sysaufs_attr_group;
25286 +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
25287 +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
25290 +void sysaufs_br_init(struct au_branch *br);
25291 +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
25292 +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
25294 +#define sysaufs_brs_init() do {} while (0)
25297 +#define sysaufs_attr_group NULL
25299 +AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
25302 +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
25308 +AuStubVoid(sysaufs_br_init, struct au_branch *br)
25309 +AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
25310 +AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
25312 +static inline void sysaufs_brs_init(void)
25317 +#endif /* CONFIG_SYSFS */
25319 +#endif /* __KERNEL__ */
25320 +#endif /* __SYSAUFS_H__ */
25321 diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
25322 --- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
25323 +++ linux/fs/aufs/sysfs.c 2013-07-06 13:20:47.753531903 +0200
25326 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25328 + * This program, aufs is free software; you can redistribute it and/or modify
25329 + * it under the terms of the GNU General Public License as published by
25330 + * the Free Software Foundation; either version 2 of the License, or
25331 + * (at your option) any later version.
25333 + * This program is distributed in the hope that it will be useful,
25334 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25335 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25336 + * GNU General Public License for more details.
25338 + * You should have received a copy of the GNU General Public License
25339 + * along with this program; if not, write to the Free Software
25340 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25344 + * sysfs interface
25347 +#include <linux/seq_file.h>
25350 +#ifdef CONFIG_AUFS_FS_MODULE
25351 +/* this entry violates the "one line per file" policy of sysfs */
25352 +static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
25356 + static char *conf =
25357 +/* this file is generated at compiling */
25358 +#include "conf.str"
25361 + err = snprintf(buf, PAGE_SIZE, conf);
25362 + if (unlikely(err >= PAGE_SIZE))
25367 +static struct kobj_attribute au_config_attr = __ATTR_RO(config);
25370 +static struct attribute *au_attr[] = {
25371 +#ifdef CONFIG_AUFS_FS_MODULE
25372 + &au_config_attr.attr,
25374 + NULL, /* need to NULL terminate the list of attributes */
25377 +static struct attribute_group sysaufs_attr_group_body = {
25381 +struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
25383 +/* ---------------------------------------------------------------------- */
25385 +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
25389 + SiMustAnyLock(sb);
25392 + if (au_opt_test(au_mntflags(sb), XINO)) {
25393 + err = au_xino_path(seq, au_sbi(sb)->si_xib);
25394 + seq_putc(seq, '\n');
25400 + * the lifetime of branch is independent from the entry under sysfs.
25401 + * sysfs handles the lifetime of the entry, and never call ->show() after it is
25404 +static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
25405 + aufs_bindex_t bindex)
25408 + struct path path;
25409 + struct dentry *root;
25410 + struct au_branch *br;
25413 + AuDbg("b%d\n", bindex);
25416 + root = sb->s_root;
25417 + di_read_lock_parent(root, !AuLock_IR);
25418 + br = au_sbr(sb, bindex);
25419 + path.mnt = au_br_mnt(br);
25420 + path.dentry = au_h_dptr(root, bindex);
25421 + au_seq_path(seq, &path);
25422 + di_read_unlock(root, !AuLock_IR);
25423 + perm = au_optstr_br_perm(br->br_perm);
25425 + err = seq_printf(seq, "=%s\n", perm);
25434 +/* ---------------------------------------------------------------------- */
25436 +static struct seq_file *au_seq(char *p, ssize_t len)
25438 + struct seq_file *seq;
25440 + seq = kzalloc(sizeof(*seq), GFP_NOFS);
25442 + /* mutex_init(&seq.lock); */
25445 + return seq; /* success */
25448 + seq = ERR_PTR(-ENOMEM);
25452 +#define SysaufsBr_PREFIX "br"
25454 +/* todo: file size may exceed PAGE_SIZE */
25455 +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
25460 + aufs_bindex_t bend;
25461 + struct au_sbinfo *sbinfo;
25462 + struct super_block *sb;
25463 + struct seq_file *seq;
25465 + struct attribute **cattr;
25467 + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
25468 + sb = sbinfo->si_sb;
25471 + * prevent a race condition between sysfs and aufs.
25472 + * for instance, sysfs_file_read() calls sysfs_get_active_two() which
25473 + * prohibits maintaining the sysfs entries.
25474 + * hew we acquire read lock after sysfs_get_active_two().
25475 + * on the other hand, the remount process may maintain the sysfs/aufs
25476 + * entries after acquiring write lock.
25477 + * it can cause a deadlock.
25478 + * simply we gave up processing read here.
25481 + if (unlikely(!si_noflush_read_trylock(sb)))
25484 + seq = au_seq(buf, PAGE_SIZE);
25485 + err = PTR_ERR(seq);
25489 + name = (void *)attr->name;
25490 + cattr = sysaufs_si_attrs;
25492 + if (!strcmp(name, (*cattr)->name)) {
25493 + err = container_of(*cattr, struct sysaufs_si_attr, attr)
25500 + bend = au_sbend(sb);
25501 + if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) {
25502 + name += sizeof(SysaufsBr_PREFIX) - 1;
25503 + err = kstrtol(name, 10, &l);
25506 + err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l);
25516 + err = seq->count;
25517 + /* sysfs limit */
25518 + if (unlikely(err == PAGE_SIZE))
25523 + si_read_unlock(sb);
25528 +/* ---------------------------------------------------------------------- */
25530 +void sysaufs_br_init(struct au_branch *br)
25532 + struct attribute *attr = &br->br_attr;
25534 + sysfs_attr_init(attr);
25535 + attr->name = br->br_name;
25536 + attr->mode = S_IRUGO;
25539 +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
25541 + struct au_branch *br;
25542 + struct kobject *kobj;
25543 + aufs_bindex_t bend;
25545 + dbgaufs_brs_del(sb, bindex);
25547 + if (!sysaufs_brs)
25550 + kobj = &au_sbi(sb)->si_kobj;
25551 + bend = au_sbend(sb);
25552 + for (; bindex <= bend; bindex++) {
25553 + br = au_sbr(sb, bindex);
25554 + sysfs_remove_file(kobj, &br->br_attr);
25558 +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
25561 + aufs_bindex_t bend;
25562 + struct kobject *kobj;
25563 + struct au_branch *br;
25565 + dbgaufs_brs_add(sb, bindex);
25567 + if (!sysaufs_brs)
25570 + kobj = &au_sbi(sb)->si_kobj;
25571 + bend = au_sbend(sb);
25572 + for (; bindex <= bend; bindex++) {
25573 + br = au_sbr(sb, bindex);
25574 + snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX
25576 + err = sysfs_create_file(kobj, &br->br_attr);
25577 + if (unlikely(err))
25578 + pr_warn("failed %s under sysfs(%d)\n",
25579 + br->br_name, err);
25582 diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
25583 --- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
25584 +++ linux/fs/aufs/sysrq.c 2013-07-06 13:20:47.753531903 +0200
25587 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25589 + * This program, aufs is free software; you can redistribute it and/or modify
25590 + * it under the terms of the GNU General Public License as published by
25591 + * the Free Software Foundation; either version 2 of the License, or
25592 + * (at your option) any later version.
25594 + * This program is distributed in the hope that it will be useful,
25595 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25596 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25597 + * GNU General Public License for more details.
25599 + * You should have received a copy of the GNU General Public License
25600 + * along with this program; if not, write to the Free Software
25601 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25605 + * magic sysrq hanlder
25608 +/* #include <linux/sysrq.h> */
25609 +#include <linux/writeback.h>
25612 +/* ---------------------------------------------------------------------- */
25614 +static void sysrq_sb(struct super_block *sb)
25617 + struct au_sbinfo *sbinfo;
25618 + struct file *file;
25620 + plevel = au_plevel;
25621 + au_plevel = KERN_WARNING;
25623 + /* since we define pr_fmt, call printk directly */
25624 +#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
25626 + sbinfo = au_sbi(sb);
25627 + printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
25628 + pr("superblock\n");
25632 + pr("root dentry\n");
25633 + au_dpri_dentry(sb->s_root);
25634 + pr("root inode\n");
25635 + au_dpri_inode(sb->s_root->d_inode);
25640 + int err, i, j, ndentry;
25641 + struct au_dcsub_pages dpages;
25642 + struct au_dpage *dpage;
25644 + err = au_dpages_init(&dpages, GFP_ATOMIC);
25645 + if (unlikely(err))
25647 + err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
25649 + for (i = 0; i < dpages.ndpage; i++) {
25650 + dpage = dpages.dpages + i;
25651 + ndentry = dpage->ndentry;
25652 + for (j = 0; j < ndentry; j++)
25653 + au_dpri_dentry(dpage->dentries[j]);
25655 + au_dpages_free(&dpages);
25662 + pr("isolated inode\n");
25663 + spin_lock(&inode_sb_list_lock);
25664 + list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
25665 + spin_lock(&i->i_lock);
25666 + if (1 || hlist_empty(&i->i_dentry))
25667 + au_dpri_inode(i);
25668 + spin_unlock(&i->i_lock);
25670 + spin_unlock(&inode_sb_list_lock);
25674 + lg_global_lock(&files_lglock);
25675 + do_file_list_for_each_entry(sb, file) {
25677 + mode = file_inode(file)->i_mode;
25678 + if (!special_file(mode) || au_special_file(mode))
25679 + au_dpri_file(file);
25680 + } while_file_list_for_each_entry;
25681 + lg_global_unlock(&files_lglock);
25685 + au_plevel = plevel;
25688 +/* ---------------------------------------------------------------------- */
25690 +/* module parameter */
25691 +static char *aufs_sysrq_key = "a";
25692 +module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
25693 +MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
25695 +static void au_sysrq(int key __maybe_unused)
25697 + struct au_sbinfo *sbinfo;
25700 + au_sbilist_lock();
25701 + list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
25702 + sysrq_sb(sbinfo->si_sb);
25703 + au_sbilist_unlock();
25707 +static struct sysrq_key_op au_sysrq_op = {
25708 + .handler = au_sysrq,
25709 + .help_msg = "Aufs",
25710 + .action_msg = "Aufs",
25711 + .enable_mask = SYSRQ_ENABLE_DUMP
25714 +/* ---------------------------------------------------------------------- */
25716 +int __init au_sysrq_init(void)
25722 + key = *aufs_sysrq_key;
25723 + if ('a' <= key && key <= 'z')
25724 + err = register_sysrq_key(key, &au_sysrq_op);
25725 + if (unlikely(err))
25726 + pr_err("err %d, sysrq=%c\n", err, key);
25730 +void au_sysrq_fin(void)
25733 + err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
25734 + if (unlikely(err))
25735 + pr_err("err %d (ignored)\n", err);
25737 diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
25738 --- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
25739 +++ linux/fs/aufs/vdir.c 2013-07-30 22:42:55.842946719 +0200
25742 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25744 + * This program, aufs is free software; you can redistribute it and/or modify
25745 + * it under the terms of the GNU General Public License as published by
25746 + * the Free Software Foundation; either version 2 of the License, or
25747 + * (at your option) any later version.
25749 + * This program is distributed in the hope that it will be useful,
25750 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25751 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25752 + * GNU General Public License for more details.
25754 + * You should have received a copy of the GNU General Public License
25755 + * along with this program; if not, write to the Free Software
25756 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25760 + * virtual or vertical directory
25765 +static unsigned int calc_size(int nlen)
25767 + return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
25770 +static int set_deblk_end(union au_vdir_deblk_p *p,
25771 + union au_vdir_deblk_p *deblk_end)
25773 + if (calc_size(0) <= deblk_end->deblk - p->deblk) {
25774 + p->de->de_str.len = 0;
25778 + return -1; /* error */
25781 +/* returns true or false */
25782 +static int is_deblk_end(union au_vdir_deblk_p *p,
25783 + union au_vdir_deblk_p *deblk_end)
25785 + if (calc_size(0) <= deblk_end->deblk - p->deblk)
25786 + return !p->de->de_str.len;
25790 +static unsigned char *last_deblk(struct au_vdir *vdir)
25792 + return vdir->vd_deblk[vdir->vd_nblk - 1];
25795 +/* ---------------------------------------------------------------------- */
25797 +/* estimate the apropriate size for name hash table */
25798 +unsigned int au_rdhash_est(loff_t sz)
25806 + if (sz < AUFS_RDHASH_DEF)
25807 + n = AUFS_RDHASH_DEF;
25808 + /* pr_info("n %u\n", n); */
25813 + * the allocated memory has to be freed by
25814 + * au_nhash_wh_free() or au_nhash_de_free().
25816 +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
25818 + struct hlist_head *head;
25821 + head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
25823 + nhash->nh_num = num_hash;
25824 + nhash->nh_head = head;
25825 + for (u = 0; u < num_hash; u++)
25826 + INIT_HLIST_HEAD(head++);
25827 + return 0; /* success */
25833 +static void nhash_count(struct hlist_head *head)
25837 + struct hlist_node *pos;
25840 + hlist_for_each(pos, head)
25842 + pr_info("%lu\n", n);
25846 +static void au_nhash_wh_do_free(struct hlist_head *head)
25848 + struct au_vdir_wh *pos;
25849 + struct hlist_node *node;
25851 + hlist_for_each_entry_safe(pos, node, head, wh_hash)
25855 +static void au_nhash_de_do_free(struct hlist_head *head)
25857 + struct au_vdir_dehstr *pos;
25858 + struct hlist_node *node;
25860 + hlist_for_each_entry_safe(pos, node, head, hash)
25861 + au_cache_free_vdir_dehstr(pos);
25864 +static void au_nhash_do_free(struct au_nhash *nhash,
25865 + void (*free)(struct hlist_head *head))
25868 + struct hlist_head *head;
25870 + n = nhash->nh_num;
25874 + head = nhash->nh_head;
25875 + while (n-- > 0) {
25876 + nhash_count(head);
25879 + kfree(nhash->nh_head);
25882 +void au_nhash_wh_free(struct au_nhash *whlist)
25884 + au_nhash_do_free(whlist, au_nhash_wh_do_free);
25887 +static void au_nhash_de_free(struct au_nhash *delist)
25889 + au_nhash_do_free(delist, au_nhash_de_do_free);
25892 +/* ---------------------------------------------------------------------- */
25894 +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
25898 + unsigned int u, n;
25899 + struct hlist_head *head;
25900 + struct au_vdir_wh *pos;
25903 + n = whlist->nh_num;
25904 + head = whlist->nh_head;
25905 + for (u = 0; u < n; u++, head++)
25906 + hlist_for_each_entry(pos, head, wh_hash)
25907 + if (pos->wh_bindex == btgt && ++num > limit)
25912 +static struct hlist_head *au_name_hash(struct au_nhash *nhash,
25913 + unsigned char *name,
25914 + unsigned int len)
25917 + /* const unsigned int magic_bit = 12; */
25919 + AuDebugOn(!nhash->nh_num || !nhash->nh_head);
25924 + /* v = hash_long(v, magic_bit); */
25925 + v %= nhash->nh_num;
25926 + return nhash->nh_head + v;
25929 +static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
25932 + return str->len == nlen && !memcmp(str->name, name, nlen);
25935 +/* returns found or not */
25936 +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
25938 + struct hlist_head *head;
25939 + struct au_vdir_wh *pos;
25940 + struct au_vdir_destr *str;
25942 + head = au_name_hash(whlist, name, nlen);
25943 + hlist_for_each_entry(pos, head, wh_hash) {
25944 + str = &pos->wh_str;
25945 + AuDbg("%.*s\n", str->len, str->name);
25946 + if (au_nhash_test_name(str, name, nlen))
25952 +/* returns found(true) or not */
25953 +static int test_known(struct au_nhash *delist, char *name, int nlen)
25955 + struct hlist_head *head;
25956 + struct au_vdir_dehstr *pos;
25957 + struct au_vdir_destr *str;
25959 + head = au_name_hash(delist, name, nlen);
25960 + hlist_for_each_entry(pos, head, hash) {
25962 + AuDbg("%.*s\n", str->len, str->name);
25963 + if (au_nhash_test_name(str, name, nlen))
25969 +static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
25970 + unsigned char d_type)
25972 +#ifdef CONFIG_AUFS_SHWH
25973 + wh->wh_ino = ino;
25974 + wh->wh_type = d_type;
25978 +/* ---------------------------------------------------------------------- */
25980 +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
25981 + unsigned int d_type, aufs_bindex_t bindex,
25982 + unsigned char shwh)
25985 + struct au_vdir_destr *str;
25986 + struct au_vdir_wh *wh;
25988 + AuDbg("%.*s\n", nlen, name);
25989 + AuDebugOn(!whlist->nh_num || !whlist->nh_head);
25992 + wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
25993 + if (unlikely(!wh))
25997 + wh->wh_bindex = bindex;
25999 + au_shwh_init_wh(wh, ino, d_type);
26000 + str = &wh->wh_str;
26002 + memcpy(str->name, name, nlen);
26003 + hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
26010 +static int append_deblk(struct au_vdir *vdir)
26013 + unsigned long ul;
26014 + const unsigned int deblk_sz = vdir->vd_deblk_sz;
26015 + union au_vdir_deblk_p p, deblk_end;
26016 + unsigned char **o;
26019 + o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
26021 + if (unlikely(!o))
26024 + vdir->vd_deblk = o;
26025 + p.deblk = kmalloc(deblk_sz, GFP_NOFS);
26027 + ul = vdir->vd_nblk++;
26028 + vdir->vd_deblk[ul] = p.deblk;
26029 + vdir->vd_last.ul = ul;
26030 + vdir->vd_last.p.deblk = p.deblk;
26031 + deblk_end.deblk = p.deblk + deblk_sz;
26032 + err = set_deblk_end(&p, &deblk_end);
26039 +static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
26040 + unsigned int d_type, struct au_nhash *delist)
26044 + const unsigned int deblk_sz = vdir->vd_deblk_sz;
26045 + union au_vdir_deblk_p p, *room, deblk_end;
26046 + struct au_vdir_dehstr *dehstr;
26048 + p.deblk = last_deblk(vdir);
26049 + deblk_end.deblk = p.deblk + deblk_sz;
26050 + room = &vdir->vd_last.p;
26051 + AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
26052 + || !is_deblk_end(room, &deblk_end));
26054 + sz = calc_size(nlen);
26055 + if (unlikely(sz > deblk_end.deblk - room->deblk)) {
26056 + err = append_deblk(vdir);
26057 + if (unlikely(err))
26060 + p.deblk = last_deblk(vdir);
26061 + deblk_end.deblk = p.deblk + deblk_sz;
26063 + AuDebugOn(room->deblk != p.deblk);
26067 + dehstr = au_cache_alloc_vdir_dehstr();
26068 + if (unlikely(!dehstr))
26071 + dehstr->str = &room->de->de_str;
26072 + hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
26073 + room->de->de_ino = ino;
26074 + room->de->de_type = d_type;
26075 + room->de->de_str.len = nlen;
26076 + memcpy(room->de->de_str.name, name, nlen);
26079 + room->deblk += sz;
26080 + if (unlikely(set_deblk_end(room, &deblk_end)))
26081 + err = append_deblk(vdir);
26088 +/* ---------------------------------------------------------------------- */
26090 +void au_vdir_free(struct au_vdir *vdir)
26092 + unsigned char **deblk;
26094 + deblk = vdir->vd_deblk;
26095 + while (vdir->vd_nblk--)
26097 + kfree(vdir->vd_deblk);
26098 + au_cache_free_vdir(vdir);
26101 +static struct au_vdir *alloc_vdir(struct file *file)
26103 + struct au_vdir *vdir;
26104 + struct super_block *sb;
26107 + sb = file->f_dentry->d_sb;
26108 + SiMustAnyLock(sb);
26111 + vdir = au_cache_alloc_vdir();
26112 + if (unlikely(!vdir))
26115 + vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
26116 + if (unlikely(!vdir->vd_deblk))
26119 + vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
26120 + if (!vdir->vd_deblk_sz) {
26121 + /* estimate the apropriate size for deblk */
26122 + vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
26123 + /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
26125 + vdir->vd_nblk = 0;
26126 + vdir->vd_version = 0;
26127 + vdir->vd_jiffy = 0;
26128 + err = append_deblk(vdir);
26130 + return vdir; /* success */
26132 + kfree(vdir->vd_deblk);
26135 + au_cache_free_vdir(vdir);
26137 + vdir = ERR_PTR(err);
26141 +static int reinit_vdir(struct au_vdir *vdir)
26144 + union au_vdir_deblk_p p, deblk_end;
26146 + while (vdir->vd_nblk > 1) {
26147 + kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
26148 + /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
26151 + p.deblk = vdir->vd_deblk[0];
26152 + deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
26153 + err = set_deblk_end(&p, &deblk_end);
26154 + /* keep vd_dblk_sz */
26155 + vdir->vd_last.ul = 0;
26156 + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
26157 + vdir->vd_version = 0;
26158 + vdir->vd_jiffy = 0;
26163 +/* ---------------------------------------------------------------------- */
26165 +#define AuFillVdir_CALLED 1
26166 +#define AuFillVdir_WHABLE (1 << 1)
26167 +#define AuFillVdir_SHWH (1 << 2)
26168 +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
26169 +#define au_fset_fillvdir(flags, name) \
26170 + do { (flags) |= AuFillVdir_##name; } while (0)
26171 +#define au_fclr_fillvdir(flags, name) \
26172 + do { (flags) &= ~AuFillVdir_##name; } while (0)
26174 +#ifndef CONFIG_AUFS_SHWH
26175 +#undef AuFillVdir_SHWH
26176 +#define AuFillVdir_SHWH 0
26179 +struct fillvdir_arg {
26180 + struct file *file;
26181 + struct au_vdir *vdir;
26182 + struct au_nhash delist;
26183 + struct au_nhash whlist;
26184 + aufs_bindex_t bindex;
26185 + unsigned int flags;
26189 +static int fillvdir(void *__arg, const char *__name, int nlen,
26190 + loff_t offset __maybe_unused, u64 h_ino,
26191 + unsigned int d_type)
26193 + struct fillvdir_arg *arg = __arg;
26194 + char *name = (void *)__name;
26195 + struct super_block *sb;
26197 + const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
26200 + sb = arg->file->f_dentry->d_sb;
26201 + au_fset_fillvdir(arg->flags, CALLED);
26203 + if (nlen <= AUFS_WH_PFX_LEN
26204 + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
26205 + if (test_known(&arg->delist, name, nlen)
26206 + || au_nhash_test_known_wh(&arg->whlist, name, nlen))
26207 + goto out; /* already exists or whiteouted */
26209 + sb = arg->file->f_dentry->d_sb;
26210 + arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
26212 + if (unlikely(nlen > AUFS_MAX_NAMELEN))
26213 + d_type = DT_UNKNOWN;
26214 + arg->err = append_de(arg->vdir, name, nlen, ino,
26215 + d_type, &arg->delist);
26217 + } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
26218 + name += AUFS_WH_PFX_LEN;
26219 + nlen -= AUFS_WH_PFX_LEN;
26220 + if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
26221 + goto out; /* already whiteouted */
26224 + arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
26227 + if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
26228 + d_type = DT_UNKNOWN;
26229 + arg->err = au_nhash_append_wh
26230 + (&arg->whlist, name, nlen, ino, d_type,
26231 + arg->bindex, shwh);
26237 + arg->vdir->vd_jiffy = jiffies;
26239 + AuTraceErr(arg->err);
26243 +static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
26244 + struct au_nhash *whlist, struct au_nhash *delist)
26246 +#ifdef CONFIG_AUFS_SHWH
26248 + unsigned int nh, u;
26249 + struct hlist_head *head;
26250 + struct au_vdir_wh *pos;
26251 + struct hlist_node *n;
26253 + struct au_vdir_destr *destr;
26255 + AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
26258 + o = p = (void *)__get_free_page(GFP_NOFS);
26259 + if (unlikely(!p))
26263 + nh = whlist->nh_num;
26264 + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
26265 + p += AUFS_WH_PFX_LEN;
26266 + for (u = 0; u < nh; u++) {
26267 + head = whlist->nh_head + u;
26268 + hlist_for_each_entry_safe(pos, n, head, wh_hash) {
26269 + destr = &pos->wh_str;
26270 + memcpy(p, destr->name, destr->len);
26271 + err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
26272 + pos->wh_ino, pos->wh_type, delist);
26273 + if (unlikely(err))
26278 + free_page((unsigned long)o);
26288 +static int au_do_read_vdir(struct fillvdir_arg *arg)
26291 + unsigned int rdhash;
26293 + aufs_bindex_t bend, bindex, bstart;
26294 + unsigned char shwh;
26295 + struct file *hf, *file;
26296 + struct super_block *sb;
26298 + file = arg->file;
26299 + sb = file->f_dentry->d_sb;
26300 + SiMustAnyLock(sb);
26302 + rdhash = au_sbi(sb)->si_rdhash;
26304 + rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
26305 + err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
26306 + if (unlikely(err))
26308 + err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
26309 + if (unlikely(err))
26315 + if (au_opt_test(au_mntflags(sb), SHWH)) {
26317 + au_fset_fillvdir(arg->flags, SHWH);
26319 + bstart = au_fbstart(file);
26320 + bend = au_fbend_dir(file);
26321 + for (bindex = bstart; !err && bindex <= bend; bindex++) {
26322 + hf = au_hf_dir(file, bindex);
26326 + offset = vfsub_llseek(hf, 0, SEEK_SET);
26328 + if (unlikely(offset))
26331 + arg->bindex = bindex;
26332 + au_fclr_fillvdir(arg->flags, WHABLE);
26334 + || (bindex != bend
26335 + && au_br_whable(au_sbr_perm(sb, bindex))))
26336 + au_fset_fillvdir(arg->flags, WHABLE);
26339 + au_fclr_fillvdir(arg->flags, CALLED);
26341 + err = vfsub_readdir(hf, fillvdir, arg);
26344 + } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
26347 + if (!err && shwh)
26348 + err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
26350 + au_nhash_wh_free(&arg->whlist);
26353 + au_nhash_de_free(&arg->delist);
26358 +static int read_vdir(struct file *file, int may_read)
26361 + unsigned long expire;
26362 + unsigned char do_read;
26363 + struct fillvdir_arg arg;
26364 + struct inode *inode;
26365 + struct au_vdir *vdir, *allocated;
26368 + inode = file_inode(file);
26369 + IMustLock(inode);
26370 + SiMustAnyLock(inode->i_sb);
26372 + allocated = NULL;
26374 + expire = au_sbi(inode->i_sb)->si_rdcache;
26375 + vdir = au_ivdir(inode);
26378 + vdir = alloc_vdir(file);
26379 + err = PTR_ERR(vdir);
26380 + if (IS_ERR(vdir))
26383 + allocated = vdir;
26384 + } else if (may_read
26385 + && (inode->i_version != vdir->vd_version
26386 + || time_after(jiffies, vdir->vd_jiffy + expire))) {
26388 + err = reinit_vdir(vdir);
26389 + if (unlikely(err))
26394 + return 0; /* success */
26398 + err = au_do_read_vdir(&arg);
26400 + /* file->f_pos = 0; */
26401 + vdir->vd_version = inode->i_version;
26402 + vdir->vd_last.ul = 0;
26403 + vdir->vd_last.p.deblk = vdir->vd_deblk[0];
26405 + au_set_ivdir(inode, allocated);
26406 + } else if (allocated)
26407 + au_vdir_free(allocated);
26413 +static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
26416 + unsigned long ul, n;
26417 + const unsigned int deblk_sz = src->vd_deblk_sz;
26419 + AuDebugOn(tgt->vd_nblk != 1);
26422 + if (tgt->vd_nblk < src->vd_nblk) {
26423 + unsigned char **p;
26425 + p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
26427 + if (unlikely(!p))
26429 + tgt->vd_deblk = p;
26432 + if (tgt->vd_deblk_sz != deblk_sz) {
26433 + unsigned char *p;
26435 + tgt->vd_deblk_sz = deblk_sz;
26436 + p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
26437 + if (unlikely(!p))
26439 + tgt->vd_deblk[0] = p;
26441 + memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
26442 + tgt->vd_version = src->vd_version;
26443 + tgt->vd_jiffy = src->vd_jiffy;
26445 + n = src->vd_nblk;
26446 + for (ul = 1; ul < n; ul++) {
26447 + tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
26449 + if (unlikely(!tgt->vd_deblk[ul]))
26453 + tgt->vd_nblk = n;
26454 + tgt->vd_last.ul = tgt->vd_last.ul;
26455 + tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
26456 + tgt->vd_last.p.deblk += src->vd_last.p.deblk
26457 + - src->vd_deblk[src->vd_last.ul];
26459 + return 0; /* success */
26462 + rerr = reinit_vdir(tgt);
26467 +int au_vdir_init(struct file *file)
26470 + struct inode *inode;
26471 + struct au_vdir *vdir_cache, *allocated;
26473 + err = read_vdir(file, !file->f_pos);
26474 + if (unlikely(err))
26477 + allocated = NULL;
26478 + vdir_cache = au_fvdir_cache(file);
26479 + if (!vdir_cache) {
26480 + vdir_cache = alloc_vdir(file);
26481 + err = PTR_ERR(vdir_cache);
26482 + if (IS_ERR(vdir_cache))
26484 + allocated = vdir_cache;
26485 + } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
26486 + err = reinit_vdir(vdir_cache);
26487 + if (unlikely(err))
26490 + return 0; /* success */
26492 + inode = file_inode(file);
26493 + err = copy_vdir(vdir_cache, au_ivdir(inode));
26495 + file->f_version = inode->i_version;
26497 + au_set_fvdir_cache(file, allocated);
26498 + } else if (allocated)
26499 + au_vdir_free(allocated);
26505 +static loff_t calc_offset(struct au_vdir *vdir)
26508 + union au_vdir_deblk_p p;
26510 + p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
26511 + offset = vdir->vd_last.p.deblk - p.deblk;
26512 + offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
26516 +/* returns true or false */
26517 +static int seek_vdir(struct file *file)
26520 + unsigned int deblk_sz;
26521 + unsigned long ul, n;
26523 + union au_vdir_deblk_p p, deblk_end;
26524 + struct au_vdir *vdir_cache;
26527 + vdir_cache = au_fvdir_cache(file);
26528 + offset = calc_offset(vdir_cache);
26529 + AuDbg("offset %lld\n", offset);
26530 + if (file->f_pos == offset)
26533 + vdir_cache->vd_last.ul = 0;
26534 + vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
26535 + if (!file->f_pos)
26539 + deblk_sz = vdir_cache->vd_deblk_sz;
26540 + ul = div64_u64(file->f_pos, deblk_sz);
26541 + AuDbg("ul %lu\n", ul);
26542 + if (ul >= vdir_cache->vd_nblk)
26545 + n = vdir_cache->vd_nblk;
26546 + for (; ul < n; ul++) {
26547 + p.deblk = vdir_cache->vd_deblk[ul];
26548 + deblk_end.deblk = p.deblk + deblk_sz;
26550 + offset *= deblk_sz;
26551 + while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) {
26554 + l = calc_size(p.de->de_str.len);
26558 + if (!is_deblk_end(&p, &deblk_end)) {
26560 + vdir_cache->vd_last.ul = ul;
26561 + vdir_cache->vd_last.p = p;
26568 + AuTraceErr(!valid);
26572 +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir)
26575 + unsigned int l, deblk_sz;
26576 + union au_vdir_deblk_p deblk_end;
26577 + struct au_vdir *vdir_cache;
26578 + struct au_vdir_de *de;
26580 + vdir_cache = au_fvdir_cache(file);
26581 + if (!seek_vdir(file))
26584 + deblk_sz = vdir_cache->vd_deblk_sz;
26586 + deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
26587 + deblk_end.deblk += deblk_sz;
26588 + while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
26589 + de = vdir_cache->vd_last.p.de;
26590 + AuDbg("%.*s, off%lld, i%lu, dt%d\n",
26591 + de->de_str.len, de->de_str.name, file->f_pos,
26592 + (unsigned long)de->de_ino, de->de_type);
26593 + err = filldir(dirent, de->de_str.name, de->de_str.len,
26594 + file->f_pos, de->de_ino, de->de_type);
26595 + if (unlikely(err)) {
26597 + /* todo: ignore the error caused by udba? */
26598 + /* return err; */
26602 + l = calc_size(de->de_str.len);
26603 + vdir_cache->vd_last.p.deblk += l;
26604 + file->f_pos += l;
26606 + if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
26607 + vdir_cache->vd_last.ul++;
26608 + vdir_cache->vd_last.p.deblk
26609 + = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
26610 + file->f_pos = deblk_sz * vdir_cache->vd_last.ul;
26619 diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
26620 --- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
26621 +++ linux/fs/aufs/vfsub.c 2013-07-30 22:42:55.842946719 +0200
26624 + * Copyright (C) 2005-2013 Junjiro R. Okajima
26626 + * This program, aufs is free software; you can redistribute it and/or modify
26627 + * it under the terms of the GNU General Public License as published by
26628 + * the Free Software Foundation; either version 2 of the License, or
26629 + * (at your option) any later version.
26631 + * This program is distributed in the hope that it will be useful,
26632 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
26633 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26634 + * GNU General Public License for more details.
26636 + * You should have received a copy of the GNU General Public License
26637 + * along with this program; if not, write to the Free Software
26638 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26642 + * sub-routines for VFS
26645 +#include <linux/ima.h>
26646 +#include <linux/namei.h>
26647 +#include <linux/security.h>
26648 +#include <linux/splice.h>
26651 +int vfsub_update_h_iattr(struct path *h_path, int *did)
26655 + struct super_block *h_sb;
26657 + /* for remote fs, leave work for its getattr or d_revalidate */
26658 + /* for bad i_attr fs, handle them in aufs_getattr() */
26659 + /* still some fs may acquire i_mutex. we need to skip them */
26663 + h_sb = h_path->dentry->d_sb;
26664 + *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
26666 + err = vfs_getattr(h_path, &st);
26671 +/* ---------------------------------------------------------------------- */
26673 +struct file *vfsub_dentry_open(struct path *path, int flags)
26675 + struct file *file;
26677 + file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
26679 + if (!IS_ERR_OR_NULL(file)
26680 + && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
26681 + i_readcount_inc(path->dentry->d_inode);
26686 +struct file *vfsub_filp_open(const char *path, int oflags, int mode)
26688 + struct file *file;
26691 + file = filp_open(path,
26692 + oflags /* | __FMODE_NONOTIFY */,
26695 + if (IS_ERR(file))
26697 + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26703 +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
26707 + err = kern_path(name, flags, path);
26708 + if (!err && path->dentry->d_inode)
26709 + vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
26713 +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
26716 + struct path path = {
26720 + /* VFS checks it too, but by WARN_ON_ONCE() */
26721 + IMustLock(parent->d_inode);
26723 + path.dentry = lookup_one_len(name, parent, len);
26724 + if (IS_ERR(path.dentry))
26726 + if (path.dentry->d_inode)
26727 + vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
26730 + AuTraceErrPtr(path.dentry);
26731 + return path.dentry;
26734 +void vfsub_call_lkup_one(void *args)
26736 + struct vfsub_lkup_one_args *a = args;
26737 + *a->errp = vfsub_lkup_one(a->name, a->parent);
26740 +/* ---------------------------------------------------------------------- */
26742 +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
26743 + struct dentry *d2, struct au_hinode *hdir2)
26745 + struct dentry *d;
26748 + d = lock_rename(d1, d2);
26750 + au_hn_suspend(hdir1);
26751 + if (hdir1 != hdir2)
26752 + au_hn_suspend(hdir2);
26757 +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
26758 + struct dentry *d2, struct au_hinode *hdir2)
26760 + au_hn_resume(hdir1);
26761 + if (hdir1 != hdir2)
26762 + au_hn_resume(hdir2);
26764 + unlock_rename(d1, d2);
26768 +/* ---------------------------------------------------------------------- */
26770 +int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
26773 + struct dentry *d;
26777 + d = path->dentry;
26778 + path->dentry = d->d_parent;
26779 + err = security_path_mknod(path, d, mode, 0);
26780 + path->dentry = d;
26781 + if (unlikely(err))
26784 + err = vfs_create(dir, path->dentry, mode, want_excl);
26786 + struct path tmp = *path;
26789 + vfsub_update_h_iattr(&tmp, &did);
26791 + tmp.dentry = path->dentry->d_parent;
26792 + vfsub_update_h_iattr(&tmp, /*did*/NULL);
26801 +int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
26804 + struct dentry *d;
26808 + d = path->dentry;
26809 + path->dentry = d->d_parent;
26810 + err = security_path_symlink(path, d, symname);
26811 + path->dentry = d;
26812 + if (unlikely(err))
26815 + err = vfs_symlink(dir, path->dentry, symname);
26817 + struct path tmp = *path;
26820 + vfsub_update_h_iattr(&tmp, &did);
26822 + tmp.dentry = path->dentry->d_parent;
26823 + vfsub_update_h_iattr(&tmp, /*did*/NULL);
26832 +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
26835 + struct dentry *d;
26839 + d = path->dentry;
26840 + path->dentry = d->d_parent;
26841 + err = security_path_mknod(path, d, mode, new_encode_dev(dev));
26842 + path->dentry = d;
26843 + if (unlikely(err))
26846 + err = vfs_mknod(dir, path->dentry, mode, dev);
26848 + struct path tmp = *path;
26851 + vfsub_update_h_iattr(&tmp, &did);
26853 + tmp.dentry = path->dentry->d_parent;
26854 + vfsub_update_h_iattr(&tmp, /*did*/NULL);
26863 +static int au_test_nlink(struct inode *inode)
26865 + const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
26867 + if (!au_test_fs_no_limit_nlink(inode->i_sb)
26868 + || inode->i_nlink < link_max)
26873 +int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
26876 + struct dentry *d;
26880 + err = au_test_nlink(src_dentry->d_inode);
26881 + if (unlikely(err))
26884 + /* we don't call may_linkat() */
26885 + d = path->dentry;
26886 + path->dentry = d->d_parent;
26887 + err = security_path_link(src_dentry, path, d);
26888 + path->dentry = d;
26889 + if (unlikely(err))
26893 + err = vfs_link(src_dentry, dir, path->dentry);
26896 + struct path tmp = *path;
26899 + /* fuse has different memory inode for the same inumber */
26900 + vfsub_update_h_iattr(&tmp, &did);
26902 + tmp.dentry = path->dentry->d_parent;
26903 + vfsub_update_h_iattr(&tmp, /*did*/NULL);
26904 + tmp.dentry = src_dentry;
26905 + vfsub_update_h_iattr(&tmp, /*did*/NULL);
26914 +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
26915 + struct inode *dir, struct path *path)
26918 + struct path tmp = {
26921 + struct dentry *d;
26924 + IMustLock(src_dir);
26926 + d = path->dentry;
26927 + path->dentry = d->d_parent;
26928 + tmp.dentry = src_dentry->d_parent;
26929 + err = security_path_rename(&tmp, src_dentry, path, d);
26930 + path->dentry = d;
26931 + if (unlikely(err))
26935 + err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
26940 + tmp.dentry = d->d_parent;
26941 + vfsub_update_h_iattr(&tmp, &did);
26943 + tmp.dentry = src_dentry;
26944 + vfsub_update_h_iattr(&tmp, /*did*/NULL);
26945 + tmp.dentry = src_dentry->d_parent;
26946 + vfsub_update_h_iattr(&tmp, /*did*/NULL);
26955 +int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
26958 + struct dentry *d;
26962 + d = path->dentry;
26963 + path->dentry = d->d_parent;
26964 + err = security_path_mkdir(path, d, mode);
26965 + path->dentry = d;
26966 + if (unlikely(err))
26969 + err = vfs_mkdir(dir, path->dentry, mode);
26971 + struct path tmp = *path;
26974 + vfsub_update_h_iattr(&tmp, &did);
26976 + tmp.dentry = path->dentry->d_parent;
26977 + vfsub_update_h_iattr(&tmp, /*did*/NULL);
26986 +int vfsub_rmdir(struct inode *dir, struct path *path)
26989 + struct dentry *d;
26993 + d = path->dentry;
26994 + path->dentry = d->d_parent;
26995 + err = security_path_rmdir(path, d);
26996 + path->dentry = d;
26997 + if (unlikely(err))
27001 + err = vfs_rmdir(dir, path->dentry);
27004 + struct path tmp = {
27005 + .dentry = path->dentry->d_parent,
27009 + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
27016 +/* ---------------------------------------------------------------------- */
27018 +/* todo: support mmap_sem? */
27019 +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
27025 + err = vfs_read(file, ubuf, count, ppos);
27028 + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27032 +/* todo: kernel_read()? */
27033 +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
27037 + mm_segment_t oldfs;
27044 + oldfs = get_fs();
27045 + set_fs(KERNEL_DS);
27046 + err = vfsub_read_u(file, buf.u, count, ppos);
27051 +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
27057 + err = vfs_write(file, ubuf, count, ppos);
27060 + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27064 +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
27067 + mm_segment_t oldfs;
27070 + const char __user *u;
27074 + oldfs = get_fs();
27075 + set_fs(KERNEL_DS);
27076 + err = vfsub_write_u(file, buf.u, count, ppos);
27081 +int vfsub_flush(struct file *file, fl_owner_t id)
27086 + if (file->f_op && file->f_op->flush) {
27087 + if (!au_test_nfs(file->f_dentry->d_sb))
27088 + err = file->f_op->flush(file, id);
27091 + err = file->f_op->flush(file, id);
27095 + vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
27101 +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
27106 + err = vfs_readdir(file, filldir, arg);
27109 + vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27113 +long vfsub_splice_to(struct file *in, loff_t *ppos,
27114 + struct pipe_inode_info *pipe, size_t len,
27115 + unsigned int flags)
27120 + err = do_splice_to(in, ppos, pipe, len, flags);
27122 + file_accessed(in);
27124 + vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
27128 +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
27129 + loff_t *ppos, size_t len, unsigned int flags)
27134 + err = do_splice_from(pipe, out, ppos, len, flags);
27137 + vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
27141 +int vfsub_fsync(struct file *file, struct path *path, int datasync)
27145 + /* file can be NULL */
27147 + err = vfs_fsync(file, datasync);
27151 + AuDebugOn(!file);
27152 + path = &file->f_path;
27154 + vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
27159 +/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
27160 +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
27161 + struct file *h_file)
27164 + struct inode *h_inode;
27165 + struct super_block *h_sb;
27168 + err = vfsub_truncate(h_path, length);
27172 + h_inode = h_path->dentry->d_inode;
27173 + h_sb = h_inode->i_sb;
27175 + sb_start_write(h_sb);
27177 + err = locks_verify_truncate(h_inode, h_file, length);
27179 + err = security_path_truncate(h_path);
27182 + err = do_truncate(h_path->dentry, length, attr, h_file);
27186 + sb_end_write(h_sb);
27193 +/* ---------------------------------------------------------------------- */
27195 +struct au_vfsub_mkdir_args {
27197 + struct inode *dir;
27198 + struct path *path;
27202 +static void au_call_vfsub_mkdir(void *args)
27204 + struct au_vfsub_mkdir_args *a = args;
27205 + *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
27208 +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
27210 + int err, do_sio, wkq_err;
27212 + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
27214 + err = vfsub_mkdir(dir, path, mode);
27216 + struct au_vfsub_mkdir_args args = {
27222 + wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
27223 + if (unlikely(wkq_err))
27230 +struct au_vfsub_rmdir_args {
27232 + struct inode *dir;
27233 + struct path *path;
27236 +static void au_call_vfsub_rmdir(void *args)
27238 + struct au_vfsub_rmdir_args *a = args;
27239 + *a->errp = vfsub_rmdir(a->dir, a->path);
27242 +int vfsub_sio_rmdir(struct inode *dir, struct path *path)
27244 + int err, do_sio, wkq_err;
27246 + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
27248 + err = vfsub_rmdir(dir, path);
27250 + struct au_vfsub_rmdir_args args = {
27255 + wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
27256 + if (unlikely(wkq_err))
27263 +/* ---------------------------------------------------------------------- */
27265 +struct notify_change_args {
27267 + struct path *path;
27268 + struct iattr *ia;
27271 +static void call_notify_change(void *args)
27273 + struct notify_change_args *a = args;
27274 + struct inode *h_inode;
27276 + h_inode = a->path->dentry->d_inode;
27277 + IMustLock(h_inode);
27279 + *a->errp = -EPERM;
27280 + if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
27281 + *a->errp = notify_change(a->path->dentry, a->ia);
27283 + vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
27285 + AuTraceErr(*a->errp);
27288 +int vfsub_notify_change(struct path *path, struct iattr *ia)
27291 + struct notify_change_args args = {
27297 + call_notify_change(&args);
27302 +int vfsub_sio_notify_change(struct path *path, struct iattr *ia)
27304 + int err, wkq_err;
27305 + struct notify_change_args args = {
27311 + wkq_err = au_wkq_wait(call_notify_change, &args);
27312 + if (unlikely(wkq_err))
27318 +/* ---------------------------------------------------------------------- */
27320 +struct unlink_args {
27322 + struct inode *dir;
27323 + struct path *path;
27326 +static void call_unlink(void *args)
27328 + struct unlink_args *a = args;
27329 + struct dentry *d = a->path->dentry;
27330 + struct inode *h_inode;
27331 + const int stop_sillyrename = (au_test_nfs(d->d_sb)
27332 + && d->d_count == 1);
27334 + IMustLock(a->dir);
27336 + a->path->dentry = d->d_parent;
27337 + *a->errp = security_path_unlink(a->path, d);
27338 + a->path->dentry = d;
27339 + if (unlikely(*a->errp))
27342 + if (!stop_sillyrename)
27344 + h_inode = d->d_inode;
27349 + *a->errp = vfs_unlink(a->dir, d);
27352 + struct path tmp = {
27353 + .dentry = d->d_parent,
27354 + .mnt = a->path->mnt
27356 + vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
27359 + if (!stop_sillyrename)
27364 + AuTraceErr(*a->errp);
27368 + * @dir: must be locked.
27369 + * @dentry: target dentry.
27371 +int vfsub_unlink(struct inode *dir, struct path *path, int force)
27374 + struct unlink_args args = {
27381 + call_unlink(&args);
27385 + wkq_err = au_wkq_wait(call_unlink, &args);
27386 + if (unlikely(wkq_err))
27392 diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
27393 --- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
27394 +++ linux/fs/aufs/vfsub.h 2013-07-30 22:42:55.842946719 +0200
27397 + * Copyright (C) 2005-2013 Junjiro R. Okajima
27399 + * This program, aufs is free software; you can redistribute it and/or modify
27400 + * it under the terms of the GNU General Public License as published by
27401 + * the Free Software Foundation; either version 2 of the License, or
27402 + * (at your option) any later version.
27404 + * This program is distributed in the hope that it will be useful,
27405 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27406 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27407 + * GNU General Public License for more details.
27409 + * You should have received a copy of the GNU General Public License
27410 + * along with this program; if not, write to the Free Software
27411 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27415 + * sub-routines for VFS
27418 +#ifndef __AUFS_VFSUB_H__
27419 +#define __AUFS_VFSUB_H__
27423 +#include <linux/fs.h>
27424 +#include <linux/lglock.h>
27425 +#include <linux/mount.h>
27426 +#include "debug.h"
27428 +/* copied from linux/fs/internal.h */
27429 +/* todo: BAD approach!! */
27430 +extern struct lglock vfsmount_lock;
27431 +extern void __mnt_drop_write(struct vfsmount *);
27432 +extern spinlock_t inode_sb_list_lock;
27434 +/* copied from linux/fs/file_table.c */
27435 +extern struct lglock files_lglock;
27438 + * These macros iterate all files on all CPUs for a given superblock.
27439 + * files_lglock must be held globally.
27441 +#define do_file_list_for_each_entry(__sb, __file) \
27444 + for_each_possible_cpu(i) { \
27445 + struct list_head *list; \
27446 + list = per_cpu_ptr((__sb)->s_files, i); \
27447 + list_for_each_entry((__file), list, f_u.fu_list)
27449 +#define while_file_list_for_each_entry \
27455 +#define do_file_list_for_each_entry(__sb, __file) \
27457 + struct list_head *list; \
27458 + list = &(sb)->s_files; \
27459 + list_for_each_entry((__file), list, f_u.fu_list)
27461 +#define while_file_list_for_each_entry \
27465 +/* ---------------------------------------------------------------------- */
27467 +/* lock subclass for lower inode */
27468 +/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
27469 +/* reduce? gave up. */
27471 + AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
27472 + AuLsc_I_PARENT, /* lower inode, parent first */
27473 + AuLsc_I_PARENT2, /* copyup dirs */
27474 + AuLsc_I_PARENT3, /* copyup wh */
27480 +/* to debug easier, do not make them inlined functions */
27481 +#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
27482 +#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
27484 +/* ---------------------------------------------------------------------- */
27486 +static inline void vfsub_drop_nlink(struct inode *inode)
27488 + AuDebugOn(!inode->i_nlink);
27489 + drop_nlink(inode);
27492 +static inline void vfsub_dead_dir(struct inode *inode)
27494 + AuDebugOn(!S_ISDIR(inode->i_mode));
27495 + inode->i_flags |= S_DEAD;
27496 + clear_nlink(inode);
27499 +/* ---------------------------------------------------------------------- */
27501 +int vfsub_update_h_iattr(struct path *h_path, int *did);
27502 +struct file *vfsub_dentry_open(struct path *path, int flags);
27503 +struct file *vfsub_filp_open(const char *path, int oflags, int mode);
27504 +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
27506 +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
27509 +struct vfsub_lkup_one_args {
27510 + struct dentry **errp;
27511 + struct qstr *name;
27512 + struct dentry *parent;
27515 +static inline struct dentry *vfsub_lkup_one(struct qstr *name,
27516 + struct dentry *parent)
27518 + return vfsub_lookup_one_len(name->name, parent, name->len);
27521 +void vfsub_call_lkup_one(void *args);
27523 +/* ---------------------------------------------------------------------- */
27525 +static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
27529 + err = mnt_want_write(mnt);
27534 +static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
27537 + mnt_drop_write(mnt);
27541 +static inline void vfsub_mnt_drop_write_file(struct file *file)
27544 + mnt_drop_write_file(file);
27548 +/* ---------------------------------------------------------------------- */
27551 +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
27552 + struct dentry *d2, struct au_hinode *hdir2);
27553 +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
27554 + struct dentry *d2, struct au_hinode *hdir2);
27556 +int vfsub_create(struct inode *dir, struct path *path, int mode,
27558 +int vfsub_symlink(struct inode *dir, struct path *path,
27559 + const char *symname);
27560 +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
27561 +int vfsub_link(struct dentry *src_dentry, struct inode *dir,
27562 + struct path *path);
27563 +int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
27564 + struct inode *hdir, struct path *path);
27565 +int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
27566 +int vfsub_rmdir(struct inode *dir, struct path *path);
27568 +/* ---------------------------------------------------------------------- */
27570 +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
27572 +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
27574 +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
27576 +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
27578 +int vfsub_flush(struct file *file, fl_owner_t id);
27579 +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
27581 +static inline loff_t vfsub_f_size_read(struct file *file)
27583 + return i_size_read(file_inode(file));
27586 +static inline unsigned int vfsub_file_flags(struct file *file)
27588 + unsigned int flags;
27590 + spin_lock(&file->f_lock);
27591 + flags = file->f_flags;
27592 + spin_unlock(&file->f_lock);
27597 +static inline void vfsub_file_accessed(struct file *h_file)
27599 + file_accessed(h_file);
27600 + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
27603 +static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
27604 + struct dentry *h_dentry)
27606 + struct path h_path = {
27607 + .dentry = h_dentry,
27610 + touch_atime(&h_path);
27611 + vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
27614 +static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
27617 + return update_time(h_inode, ts, flags);
27618 + /* no vfsub_update_h_iattr() since we don't have struct path */
27621 +long vfsub_splice_to(struct file *in, loff_t *ppos,
27622 + struct pipe_inode_info *pipe, size_t len,
27623 + unsigned int flags);
27624 +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
27625 + loff_t *ppos, size_t len, unsigned int flags);
27627 +static inline long vfsub_truncate(struct path *path, loff_t length)
27631 + err = vfs_truncate(path, length);
27636 +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
27637 + struct file *h_file);
27638 +int vfsub_fsync(struct file *file, struct path *path, int datasync);
27640 +/* ---------------------------------------------------------------------- */
27642 +static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
27647 + err = vfs_llseek(file, offset, origin);
27652 +/* ---------------------------------------------------------------------- */
27654 +/* dirty workaround for strict type of fmode_t */
27660 +static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
27662 + union vfsub_fmu u = {
27666 + BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
27671 +static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
27673 + union vfsub_fmu u = {
27680 +/* ---------------------------------------------------------------------- */
27682 +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
27683 +int vfsub_sio_rmdir(struct inode *dir, struct path *path);
27684 +int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
27685 +int vfsub_notify_change(struct path *path, struct iattr *ia);
27686 +int vfsub_unlink(struct inode *dir, struct path *path, int force);
27688 +#endif /* __KERNEL__ */
27689 +#endif /* __AUFS_VFSUB_H__ */
27690 diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
27691 --- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
27692 +++ linux/fs/aufs/wbr_policy.c 2013-07-06 13:20:47.753531903 +0200
27695 + * Copyright (C) 2005-2013 Junjiro R. Okajima
27697 + * This program, aufs is free software; you can redistribute it and/or modify
27698 + * it under the terms of the GNU General Public License as published by
27699 + * the Free Software Foundation; either version 2 of the License, or
27700 + * (at your option) any later version.
27702 + * This program is distributed in the hope that it will be useful,
27703 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27704 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27705 + * GNU General Public License for more details.
27707 + * You should have received a copy of the GNU General Public License
27708 + * along with this program; if not, write to the Free Software
27709 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27713 + * policies for selecting one among multiple writable branches
27716 +#include <linux/statfs.h>
27719 +/* subset of cpup_attr() */
27720 +static noinline_for_stack
27721 +int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
27725 + struct inode *h_isrc;
27727 + h_isrc = h_src->d_inode;
27728 + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
27729 + ia.ia_mode = h_isrc->i_mode;
27730 + ia.ia_uid = h_isrc->i_uid;
27731 + ia.ia_gid = h_isrc->i_gid;
27732 + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
27733 + au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
27734 + err = vfsub_sio_notify_change(h_path, &ia);
27736 + /* is this nfs only? */
27737 + if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
27738 + ia.ia_valid = ATTR_FORCE | ATTR_MODE;
27739 + ia.ia_mode = h_isrc->i_mode;
27740 + err = vfsub_sio_notify_change(h_path, &ia);
27746 +#define AuCpdown_PARENT_OPQ 1
27747 +#define AuCpdown_WHED (1 << 1)
27748 +#define AuCpdown_MADE_DIR (1 << 2)
27749 +#define AuCpdown_DIROPQ (1 << 3)
27750 +#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
27751 +#define au_fset_cpdown(flags, name) \
27752 + do { (flags) |= AuCpdown_##name; } while (0)
27753 +#define au_fclr_cpdown(flags, name) \
27754 + do { (flags) &= ~AuCpdown_##name; } while (0)
27756 +struct au_cpdown_dir_args {
27757 + struct dentry *parent;
27758 + unsigned int flags;
27761 +static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
27762 + struct au_cpdown_dir_args *a)
27765 + struct dentry *opq_dentry;
27767 + opq_dentry = au_diropq_create(dentry, bdst);
27768 + err = PTR_ERR(opq_dentry);
27769 + if (IS_ERR(opq_dentry))
27771 + dput(opq_dentry);
27772 + au_fset_cpdown(a->flags, DIROPQ);
27778 +static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
27779 + struct inode *dir, aufs_bindex_t bdst)
27782 + struct path h_path;
27783 + struct au_branch *br;
27785 + br = au_sbr(dentry->d_sb, bdst);
27786 + h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
27787 + err = PTR_ERR(h_path.dentry);
27788 + if (IS_ERR(h_path.dentry))
27792 + if (h_path.dentry->d_inode) {
27793 + h_path.mnt = au_br_mnt(br);
27794 + err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
27797 + dput(h_path.dentry);
27803 +static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
27804 + struct au_pin *pin,
27805 + struct dentry *h_parent, void *arg)
27808 + aufs_bindex_t bopq, bstart;
27809 + struct path h_path;
27810 + struct dentry *parent;
27811 + struct inode *h_dir, *h_inode, *inode, *dir;
27812 + struct au_cpdown_dir_args *args = arg;
27814 + bstart = au_dbstart(dentry);
27815 + /* dentry is di-locked */
27816 + parent = dget_parent(dentry);
27817 + dir = parent->d_inode;
27818 + h_dir = h_parent->d_inode;
27819 + AuDebugOn(h_dir != au_h_iptr(dir, bdst));
27820 + IMustLock(h_dir);
27822 + err = au_lkup_neg(dentry, bdst, /*wh*/0);
27823 + if (unlikely(err < 0))
27825 + h_path.dentry = au_h_dptr(dentry, bdst);
27826 + h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
27827 + err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
27828 + S_IRWXU | S_IRUGO | S_IXUGO);
27829 + if (unlikely(err))
27831 + au_fset_cpdown(args->flags, MADE_DIR);
27833 + bopq = au_dbdiropq(dentry);
27834 + au_fclr_cpdown(args->flags, WHED);
27835 + au_fclr_cpdown(args->flags, DIROPQ);
27836 + if (au_dbwh(dentry) == bdst)
27837 + au_fset_cpdown(args->flags, WHED);
27838 + if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst)
27839 + au_fset_cpdown(args->flags, PARENT_OPQ);
27840 + h_inode = h_path.dentry->d_inode;
27841 + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
27842 + if (au_ftest_cpdown(args->flags, WHED)) {
27843 + err = au_cpdown_dir_opq(dentry, bdst, args);
27844 + if (unlikely(err)) {
27845 + mutex_unlock(&h_inode->i_mutex);
27850 + err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
27851 + mutex_unlock(&h_inode->i_mutex);
27852 + if (unlikely(err))
27855 + if (au_ftest_cpdown(args->flags, WHED)) {
27856 + err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
27857 + if (unlikely(err))
27861 + inode = dentry->d_inode;
27862 + if (au_ibend(inode) < bdst)
27863 + au_set_ibend(inode, bdst);
27864 + au_set_h_iptr(inode, bdst, au_igrab(h_inode),
27865 + au_hi_flags(inode, /*isdir*/1));
27866 + goto out; /* success */
27870 + if (au_ftest_cpdown(args->flags, DIROPQ)) {
27871 + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
27872 + rerr = au_diropq_remove(dentry, bdst);
27873 + mutex_unlock(&h_inode->i_mutex);
27874 + if (unlikely(rerr)) {
27875 + AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
27876 + AuDLNPair(dentry), bdst, rerr);
27882 + if (au_ftest_cpdown(args->flags, MADE_DIR)) {
27883 + rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
27884 + if (unlikely(rerr)) {
27885 + AuIOErr("failed removing %.*s b%d (%d)\n",
27886 + AuDLNPair(dentry), bdst, rerr);
27891 + au_set_h_dptr(dentry, bdst, NULL);
27892 + if (au_dbend(dentry) == bdst)
27893 + au_update_dbend(dentry);
27899 +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
27902 + struct au_cpdown_dir_args args = {
27903 + .parent = dget_parent(dentry),
27907 + err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args);
27908 + dput(args.parent);
27913 +/* ---------------------------------------------------------------------- */
27915 +/* policies for create */
27917 +static int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
27919 + int err, i, j, ndentry;
27920 + aufs_bindex_t bopq;
27921 + struct au_dcsub_pages dpages;
27922 + struct au_dpage *dpage;
27923 + struct dentry **dentries, *parent, *d;
27925 + err = au_dpages_init(&dpages, GFP_NOFS);
27926 + if (unlikely(err))
27928 + parent = dget_parent(dentry);
27929 + err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
27930 + if (unlikely(err))
27934 + for (i = 0; i < dpages.ndpage; i++) {
27935 + dpage = dpages.dpages + i;
27936 + dentries = dpage->dentries;
27937 + ndentry = dpage->ndentry;
27938 + for (j = 0; j < ndentry; j++) {
27940 + di_read_lock_parent2(d, !AuLock_IR);
27941 + bopq = au_dbdiropq(d);
27942 + di_read_unlock(d, !AuLock_IR);
27943 + if (bopq >= 0 && bopq < err)
27950 + au_dpages_free(&dpages);
27955 +static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
27957 + for (; bindex >= 0; bindex--)
27958 + if (!au_br_rdonly(au_sbr(sb, bindex)))
27963 +/* top down parent */
27964 +static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused)
27967 + aufs_bindex_t bstart, bindex;
27968 + struct super_block *sb;
27969 + struct dentry *parent, *h_parent;
27971 + sb = dentry->d_sb;
27972 + bstart = au_dbstart(dentry);
27974 + if (!au_br_rdonly(au_sbr(sb, bstart)))
27978 + parent = dget_parent(dentry);
27979 + for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
27980 + h_parent = au_h_dptr(parent, bindex);
27981 + if (!h_parent || !h_parent->d_inode)
27984 + if (!au_br_rdonly(au_sbr(sb, bindex))) {
27991 + /* bottom up here */
27992 + if (unlikely(err < 0)) {
27993 + err = au_wbr_bu(sb, bstart - 1);
27995 + err = au_wbr_nonopq(dentry, err);
27999 + AuDbg("b%d\n", err);
28003 +/* ---------------------------------------------------------------------- */
28005 +/* an exception for the policy other than tdp */
28006 +static int au_wbr_create_exp(struct dentry *dentry)
28009 + aufs_bindex_t bwh, bdiropq;
28010 + struct dentry *parent;
28013 + bwh = au_dbwh(dentry);
28014 + parent = dget_parent(dentry);
28015 + bdiropq = au_dbdiropq(parent);
28017 + if (bdiropq >= 0)
28018 + err = min(bdiropq, bwh);
28021 + AuDbg("%d\n", err);
28022 + } else if (bdiropq >= 0) {
28024 + AuDbg("%d\n", err);
28029 + err = au_wbr_nonopq(dentry, err);
28031 + if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
28034 + AuDbg("%d\n", err);
28038 +/* ---------------------------------------------------------------------- */
28041 +static int au_wbr_create_init_rr(struct super_block *sb)
28045 + err = au_wbr_bu(sb, au_sbend(sb));
28046 + atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
28049 + AuDbg("b%d\n", err);
28053 +static int au_wbr_create_rr(struct dentry *dentry, int isdir)
28057 + aufs_bindex_t bindex, bend;
28058 + struct super_block *sb;
28061 + err = au_wbr_create_exp(dentry);
28065 + sb = dentry->d_sb;
28066 + next = &au_sbi(sb)->si_wbr_rr_next;
28067 + bend = au_sbend(sb);
28069 + for (bindex = 0; bindex <= bend; bindex++) {
28071 + err = atomic_dec_return(next) + 1;
28072 + /* modulo for 0 is meaningless */
28073 + if (unlikely(!err))
28074 + err = atomic_dec_return(next) + 1;
28076 + err = atomic_read(next);
28077 + AuDbg("%d\n", err);
28080 + AuDbg("%d\n", err);
28081 + if (!au_br_rdonly(au_sbr(sb, err)))
28087 + err = au_wbr_nonopq(dentry, err);
28090 + AuDbg("%d\n", err);
28094 +/* ---------------------------------------------------------------------- */
28096 +/* most free space */
28097 +static void au_mfs(struct dentry *dentry)
28099 + struct super_block *sb;
28100 + struct au_branch *br;
28101 + struct au_wbr_mfs *mfs;
28102 + aufs_bindex_t bindex, bend;
28104 + unsigned long long b, bavail;
28105 + struct path h_path;
28106 + /* reduce the stack usage */
28107 + struct kstatfs *st;
28109 + st = kmalloc(sizeof(*st), GFP_NOFS);
28110 + if (unlikely(!st)) {
28111 + AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
28116 + sb = dentry->d_sb;
28117 + mfs = &au_sbi(sb)->si_wbr_mfs;
28118 + MtxMustLock(&mfs->mfs_lock);
28119 + mfs->mfs_bindex = -EROFS;
28120 + mfs->mfsrr_bytes = 0;
28121 + bend = au_sbend(sb);
28122 + for (bindex = 0; bindex <= bend; bindex++) {
28123 + br = au_sbr(sb, bindex);
28124 + if (au_br_rdonly(br))
28127 + /* sb->s_root for NFS is unreliable */
28128 + h_path.mnt = au_br_mnt(br);
28129 + h_path.dentry = h_path.mnt->mnt_root;
28130 + err = vfs_statfs(&h_path, st);
28131 + if (unlikely(err)) {
28132 + AuWarn1("failed statfs, b%d, %d\n", bindex, err);
28136 + /* when the available size is equal, select the lower one */
28137 + BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
28138 + || sizeof(b) < sizeof(st->f_bsize));
28139 + b = st->f_bavail * st->f_bsize;
28140 + br->br_wbr->wbr_bytes = b;
28141 + if (b >= bavail) {
28143 + mfs->mfs_bindex = bindex;
28144 + mfs->mfs_jiffy = jiffies;
28148 + mfs->mfsrr_bytes = bavail;
28149 + AuDbg("b%d\n", mfs->mfs_bindex);
28153 +static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused)
28156 + struct super_block *sb;
28157 + struct au_wbr_mfs *mfs;
28159 + err = au_wbr_create_exp(dentry);
28163 + sb = dentry->d_sb;
28164 + mfs = &au_sbi(sb)->si_wbr_mfs;
28165 + mutex_lock(&mfs->mfs_lock);
28166 + if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
28167 + || mfs->mfs_bindex < 0
28168 + || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
28170 + mutex_unlock(&mfs->mfs_lock);
28171 + err = mfs->mfs_bindex;
28174 + err = au_wbr_nonopq(dentry, err);
28177 + AuDbg("b%d\n", err);
28181 +static int au_wbr_create_init_mfs(struct super_block *sb)
28183 + struct au_wbr_mfs *mfs;
28185 + mfs = &au_sbi(sb)->si_wbr_mfs;
28186 + mutex_init(&mfs->mfs_lock);
28187 + mfs->mfs_jiffy = 0;
28188 + mfs->mfs_bindex = -EROFS;
28193 +static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
28195 + mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
28199 +/* ---------------------------------------------------------------------- */
28201 +/* most free space and then round robin */
28202 +static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir)
28205 + struct au_wbr_mfs *mfs;
28207 + err = au_wbr_create_mfs(dentry, isdir);
28209 + mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
28210 + mutex_lock(&mfs->mfs_lock);
28211 + if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
28212 + err = au_wbr_create_rr(dentry, isdir);
28213 + mutex_unlock(&mfs->mfs_lock);
28216 + AuDbg("b%d\n", err);
28220 +static int au_wbr_create_init_mfsrr(struct super_block *sb)
28224 + au_wbr_create_init_mfs(sb); /* ignore */
28225 + err = au_wbr_create_init_rr(sb);
28230 +/* ---------------------------------------------------------------------- */
28232 +/* top down parent and most free space */
28233 +static int au_wbr_create_pmfs(struct dentry *dentry, int isdir)
28236 + unsigned long long b;
28237 + aufs_bindex_t bindex, bstart, bend;
28238 + struct super_block *sb;
28239 + struct dentry *parent, *h_parent;
28240 + struct au_branch *br;
28242 + err = au_wbr_create_tdp(dentry, isdir);
28243 + if (unlikely(err < 0))
28245 + parent = dget_parent(dentry);
28246 + bstart = au_dbstart(parent);
28247 + bend = au_dbtaildir(parent);
28248 + if (bstart == bend)
28249 + goto out_parent; /* success */
28251 + e2 = au_wbr_create_mfs(dentry, isdir);
28253 + goto out_parent; /* success */
28255 + /* when the available size is equal, select upper one */
28256 + sb = dentry->d_sb;
28257 + br = au_sbr(sb, err);
28258 + b = br->br_wbr->wbr_bytes;
28259 + AuDbg("b%d, %llu\n", err, b);
28261 + for (bindex = bstart; bindex <= bend; bindex++) {
28262 + h_parent = au_h_dptr(parent, bindex);
28263 + if (!h_parent || !h_parent->d_inode)
28266 + br = au_sbr(sb, bindex);
28267 + if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
28268 + b = br->br_wbr->wbr_bytes;
28270 + AuDbg("b%d, %llu\n", err, b);
28275 + err = au_wbr_nonopq(dentry, err);
28280 + AuDbg("b%d\n", err);
28284 +/* ---------------------------------------------------------------------- */
28286 +/* policies for copyup */
28288 +/* top down parent */
28289 +static int au_wbr_copyup_tdp(struct dentry *dentry)
28291 + return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0);
28294 +/* bottom up parent */
28295 +static int au_wbr_copyup_bup(struct dentry *dentry)
28298 + aufs_bindex_t bindex, bstart;
28299 + struct dentry *parent, *h_parent;
28300 + struct super_block *sb;
28303 + sb = dentry->d_sb;
28304 + parent = dget_parent(dentry);
28305 + bstart = au_dbstart(parent);
28306 + for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
28307 + h_parent = au_h_dptr(parent, bindex);
28308 + if (!h_parent || !h_parent->d_inode)
28311 + if (!au_br_rdonly(au_sbr(sb, bindex))) {
28318 + /* bottom up here */
28319 + if (unlikely(err < 0))
28320 + err = au_wbr_bu(sb, bstart - 1);
28322 + AuDbg("b%d\n", err);
28327 +static int au_wbr_copyup_bu(struct dentry *dentry)
28330 + aufs_bindex_t bstart;
28332 + bstart = au_dbstart(dentry);
28333 + err = au_wbr_bu(dentry->d_sb, bstart);
28334 + AuDbg("b%d\n", err);
28335 + if (err > bstart)
28336 + err = au_wbr_nonopq(dentry, err);
28338 + AuDbg("b%d\n", err);
28342 +/* ---------------------------------------------------------------------- */
28344 +struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
28345 + [AuWbrCopyup_TDP] = {
28346 + .copyup = au_wbr_copyup_tdp
28348 + [AuWbrCopyup_BUP] = {
28349 + .copyup = au_wbr_copyup_bup
28351 + [AuWbrCopyup_BU] = {
28352 + .copyup = au_wbr_copyup_bu
28356 +struct au_wbr_create_operations au_wbr_create_ops[] = {
28357 + [AuWbrCreate_TDP] = {
28358 + .create = au_wbr_create_tdp
28360 + [AuWbrCreate_RR] = {
28361 + .create = au_wbr_create_rr,
28362 + .init = au_wbr_create_init_rr
28364 + [AuWbrCreate_MFS] = {
28365 + .create = au_wbr_create_mfs,
28366 + .init = au_wbr_create_init_mfs,
28367 + .fin = au_wbr_create_fin_mfs
28369 + [AuWbrCreate_MFSV] = {
28370 + .create = au_wbr_create_mfs,
28371 + .init = au_wbr_create_init_mfs,
28372 + .fin = au_wbr_create_fin_mfs
28374 + [AuWbrCreate_MFSRR] = {
28375 + .create = au_wbr_create_mfsrr,
28376 + .init = au_wbr_create_init_mfsrr,
28377 + .fin = au_wbr_create_fin_mfs
28379 + [AuWbrCreate_MFSRRV] = {
28380 + .create = au_wbr_create_mfsrr,
28381 + .init = au_wbr_create_init_mfsrr,
28382 + .fin = au_wbr_create_fin_mfs
28384 + [AuWbrCreate_PMFS] = {
28385 + .create = au_wbr_create_pmfs,
28386 + .init = au_wbr_create_init_mfs,
28387 + .fin = au_wbr_create_fin_mfs
28389 + [AuWbrCreate_PMFSV] = {
28390 + .create = au_wbr_create_pmfs,
28391 + .init = au_wbr_create_init_mfs,
28392 + .fin = au_wbr_create_fin_mfs
28395 diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
28396 --- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
28397 +++ linux/fs/aufs/whout.c 2013-07-06 13:20:47.760198800 +0200
28400 + * Copyright (C) 2005-2013 Junjiro R. Okajima
28402 + * This program, aufs is free software; you can redistribute it and/or modify
28403 + * it under the terms of the GNU General Public License as published by
28404 + * the Free Software Foundation; either version 2 of the License, or
28405 + * (at your option) any later version.
28407 + * This program is distributed in the hope that it will be useful,
28408 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28409 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28410 + * GNU General Public License for more details.
28412 + * You should have received a copy of the GNU General Public License
28413 + * along with this program; if not, write to the Free Software
28414 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28418 + * whiteout for logical deletion and opaque directory
28423 +#define WH_MASK S_IRUGO
28426 + * If a directory contains this file, then it is opaque. We start with the
28427 + * .wh. flag so that it is blocked by lookup.
28429 +static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
28430 + sizeof(AUFS_WH_DIROPQ) - 1);
28433 + * generate whiteout name, which is NOT terminated by NULL.
28434 + * @name: original d_name.name
28435 + * @len: original d_name.len
28436 + * @wh: whiteout qstr
28437 + * returns zero when succeeds, otherwise error.
28438 + * succeeded value as wh->name should be freed by kfree().
28440 +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
28444 + if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
28445 + return -ENAMETOOLONG;
28447 + wh->len = name->len + AUFS_WH_PFX_LEN;
28448 + p = kmalloc(wh->len, GFP_NOFS);
28451 + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
28452 + memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
28459 +/* ---------------------------------------------------------------------- */
28462 + * test if the @wh_name exists under @h_parent.
28463 + * @try_sio specifies the necessary of super-io.
28465 +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
28466 + struct au_branch *br, int try_sio)
28469 + struct dentry *wh_dentry;
28472 + wh_dentry = vfsub_lkup_one(wh_name, h_parent);
28474 + wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
28475 + err = PTR_ERR(wh_dentry);
28476 + if (IS_ERR(wh_dentry))
28480 + if (!wh_dentry->d_inode)
28481 + goto out_wh; /* success */
28484 + if (S_ISREG(wh_dentry->d_inode->i_mode))
28485 + goto out_wh; /* success */
28488 + AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
28489 + AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
28498 + * test if the @h_dentry sets opaque or not.
28500 +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
28503 + struct inode *h_dir;
28505 + h_dir = h_dentry->d_inode;
28506 + err = au_wh_test(h_dentry, &diropq_name, br,
28507 + au_test_h_perm_sio(h_dir, MAY_EXEC));
28512 + * returns a negative dentry whose name is unique and temporary.
28514 +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
28515 + struct qstr *prefix)
28517 + struct dentry *dentry;
28519 + char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
28521 + /* strict atomic_t is unnecessary here */
28522 + static unsigned short cnt;
28525 + BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
28528 + qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
28529 + if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
28530 + dentry = ERR_PTR(-ENAMETOOLONG);
28531 + if (unlikely(qs.len > NAME_MAX))
28533 + dentry = ERR_PTR(-ENOMEM);
28534 + name = kmalloc(qs.len + 1, GFP_NOFS);
28535 + if (unlikely(!name))
28539 + /* doubly whiteout-ed */
28540 + memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
28541 + p = name + AUFS_WH_PFX_LEN * 2;
28542 + memcpy(p, prefix->name, prefix->len);
28543 + p += prefix->len;
28545 + AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
28548 + for (i = 0; i < 3; i++) {
28549 + sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
28550 + dentry = au_sio_lkup_one(&qs, h_parent, br);
28551 + if (IS_ERR(dentry) || !dentry->d_inode)
28555 + /* pr_warn("could not get random name\n"); */
28556 + dentry = ERR_PTR(-EEXIST);
28557 + AuDbg("%.*s\n", AuLNPair(&qs));
28561 + if (name != defname)
28564 + AuTraceErrPtr(dentry);
28569 + * rename the @h_dentry on @br to the whiteouted temporary name.
28571 +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
28574 + struct path h_path = {
28575 + .mnt = au_br_mnt(br)
28577 + struct inode *h_dir;
28578 + struct dentry *h_parent;
28580 + h_parent = h_dentry->d_parent; /* dir inode is locked */
28581 + h_dir = h_parent->d_inode;
28582 + IMustLock(h_dir);
28584 + h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
28585 + err = PTR_ERR(h_path.dentry);
28586 + if (IS_ERR(h_path.dentry))
28589 + /* under the same dir, no need to lock_rename() */
28590 + err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
28592 + dput(h_path.dentry);
28599 +/* ---------------------------------------------------------------------- */
28601 + * functions for removing a whiteout
28604 +static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
28609 + * forces superio when the dir has a sticky bit.
28610 + * this may be a violation of unix fs semantics.
28612 + force = (h_dir->i_mode & S_ISVTX)
28613 + && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
28614 + return vfsub_unlink(h_dir, h_path, force);
28617 +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
28618 + struct dentry *dentry)
28622 + err = do_unlink_wh(h_dir, h_path);
28623 + if (!err && dentry)
28624 + au_set_dbwh(dentry, -1);
28629 +static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
28630 + struct au_branch *br)
28633 + struct path h_path = {
28634 + .mnt = au_br_mnt(br)
28638 + h_path.dentry = vfsub_lkup_one(wh, h_parent);
28639 + if (IS_ERR(h_path.dentry))
28640 + err = PTR_ERR(h_path.dentry);
28642 + if (h_path.dentry->d_inode
28643 + && S_ISREG(h_path.dentry->d_inode->i_mode))
28644 + err = do_unlink_wh(h_parent->d_inode, &h_path);
28645 + dput(h_path.dentry);
28651 +/* ---------------------------------------------------------------------- */
28653 + * initialize/clean whiteout for a branch
28656 +static void au_wh_clean(struct inode *h_dir, struct path *whpath,
28661 + if (!whpath->dentry->d_inode)
28665 + err = vfsub_rmdir(h_dir, whpath);
28667 + err = vfsub_unlink(h_dir, whpath, /*force*/0);
28668 + if (unlikely(err))
28669 + pr_warn("failed removing %.*s (%d), ignored.\n",
28670 + AuDLNPair(whpath->dentry), err);
28673 +static int test_linkable(struct dentry *h_root)
28675 + struct inode *h_dir = h_root->d_inode;
28677 + if (h_dir->i_op->link)
28680 + pr_err("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
28681 + AuDLNPair(h_root), au_sbtype(h_root->d_sb));
28685 +/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
28686 +static int au_whdir(struct inode *h_dir, struct path *path)
28691 + if (!path->dentry->d_inode) {
28692 + int mode = S_IRWXU;
28694 + if (au_test_nfs(path->dentry->d_sb))
28696 + err = vfsub_mkdir(h_dir, path, mode);
28697 + } else if (S_ISDIR(path->dentry->d_inode->i_mode))
28700 + pr_err("unknown %.*s exists\n", AuDLNPair(path->dentry));
28705 +struct au_wh_base {
28706 + const struct qstr *name;
28707 + struct dentry *dentry;
28710 +static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
28711 + struct path *h_path)
28713 + h_path->dentry = base[AuBrWh_BASE].dentry;
28714 + au_wh_clean(h_dir, h_path, /*isdir*/0);
28715 + h_path->dentry = base[AuBrWh_PLINK].dentry;
28716 + au_wh_clean(h_dir, h_path, /*isdir*/1);
28717 + h_path->dentry = base[AuBrWh_ORPH].dentry;
28718 + au_wh_clean(h_dir, h_path, /*isdir*/1);
28722 + * returns tri-state,
28723 + * minus: error, caller should print the mesage
28725 + * plus: error, caller should NOT print the mesage
28727 +static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
28728 + int do_plink, struct au_wh_base base[],
28729 + struct path *h_path)
28732 + struct inode *h_dir;
28734 + h_dir = h_root->d_inode;
28735 + h_path->dentry = base[AuBrWh_BASE].dentry;
28736 + au_wh_clean(h_dir, h_path, /*isdir*/0);
28737 + h_path->dentry = base[AuBrWh_PLINK].dentry;
28739 + err = test_linkable(h_root);
28740 + if (unlikely(err)) {
28745 + err = au_whdir(h_dir, h_path);
28746 + if (unlikely(err))
28748 + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
28750 + au_wh_clean(h_dir, h_path, /*isdir*/1);
28751 + h_path->dentry = base[AuBrWh_ORPH].dentry;
28752 + err = au_whdir(h_dir, h_path);
28753 + if (unlikely(err))
28755 + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
28762 + * for the moment, aufs supports the branch filesystem which does not support
28763 + * link(2). testing on FAT which does not support i_op->setattr() fully either,
28764 + * copyup failed. finally, such filesystem will not be used as the writable
28767 + * returns tri-state, see above.
28769 +static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
28770 + int do_plink, struct au_wh_base base[],
28771 + struct path *h_path)
28774 + struct inode *h_dir;
28776 + WbrWhMustWriteLock(wbr);
28778 + err = test_linkable(h_root);
28779 + if (unlikely(err)) {
28785 + * todo: should this create be done in /sbin/mount.aufs helper?
28788 + h_dir = h_root->d_inode;
28789 + if (!base[AuBrWh_BASE].dentry->d_inode) {
28790 + h_path->dentry = base[AuBrWh_BASE].dentry;
28791 + err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
28792 + } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
28795 + pr_err("unknown %.*s/%.*s exists\n",
28796 + AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
28797 + if (unlikely(err))
28800 + h_path->dentry = base[AuBrWh_PLINK].dentry;
28802 + err = au_whdir(h_dir, h_path);
28803 + if (unlikely(err))
28805 + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
28807 + au_wh_clean(h_dir, h_path, /*isdir*/1);
28808 + wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
28810 + h_path->dentry = base[AuBrWh_ORPH].dentry;
28811 + err = au_whdir(h_dir, h_path);
28812 + if (unlikely(err))
28814 + wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
28821 + * initialize the whiteout base file/dir for @br.
28823 +int au_wh_init(struct au_branch *br, struct super_block *sb)
28826 + const unsigned char do_plink
28827 + = !!au_opt_test(au_mntflags(sb), PLINK);
28828 + struct inode *h_dir;
28829 + struct path path = br->br_path;
28830 + struct dentry *h_root = path.dentry;
28831 + struct au_wbr *wbr = br->br_wbr;
28832 + static const struct qstr base_name[] = {
28833 + [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
28834 + sizeof(AUFS_BASE_NAME) - 1),
28835 + [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
28836 + sizeof(AUFS_PLINKDIR_NAME) - 1),
28837 + [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
28838 + sizeof(AUFS_ORPHDIR_NAME) - 1)
28840 + struct au_wh_base base[] = {
28841 + [AuBrWh_BASE] = {
28842 + .name = base_name + AuBrWh_BASE,
28845 + [AuBrWh_PLINK] = {
28846 + .name = base_name + AuBrWh_PLINK,
28849 + [AuBrWh_ORPH] = {
28850 + .name = base_name + AuBrWh_ORPH,
28856 + WbrWhMustWriteLock(wbr);
28858 + for (i = 0; i < AuBrWh_Last; i++) {
28859 + /* doubly whiteouted */
28860 + struct dentry *d;
28862 + d = au_wh_lkup(h_root, (void *)base[i].name, br);
28863 + err = PTR_ERR(d);
28867 + base[i].dentry = d;
28869 + && wbr->wbr_wh[i]
28870 + && wbr->wbr_wh[i] != base[i].dentry);
28874 + for (i = 0; i < AuBrWh_Last; i++) {
28875 + dput(wbr->wbr_wh[i]);
28876 + wbr->wbr_wh[i] = NULL;
28880 + if (!au_br_writable(br->br_perm)) {
28881 + h_dir = h_root->d_inode;
28882 + au_wh_init_ro(h_dir, base, &path);
28883 + } else if (!au_br_wh_linkable(br->br_perm)) {
28884 + err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
28890 + err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
28896 + goto out; /* success */
28899 + pr_err("an error(%d) on the writable branch %.*s(%s)\n",
28900 + err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
28902 + for (i = 0; i < AuBrWh_Last; i++)
28903 + dput(base[i].dentry);
28907 +/* ---------------------------------------------------------------------- */
28909 + * whiteouts are all hard-linked usually.
28910 + * when its link count reaches a ceiling, we create a new whiteout base
28911 + * asynchronously.
28914 +struct reinit_br_wh {
28915 + struct super_block *sb;
28916 + struct au_branch *br;
28919 +static void reinit_br_wh(void *arg)
28922 + aufs_bindex_t bindex;
28923 + struct path h_path;
28924 + struct reinit_br_wh *a = arg;
28925 + struct au_wbr *wbr;
28926 + struct inode *dir;
28927 + struct dentry *h_root;
28928 + struct au_hinode *hdir;
28931 + wbr = a->br->br_wbr;
28932 + /* big aufs lock */
28933 + si_noflush_write_lock(a->sb);
28934 + if (!au_br_writable(a->br->br_perm))
28936 + bindex = au_br_index(a->sb, a->br->br_id);
28937 + if (unlikely(bindex < 0))
28940 + di_read_lock_parent(a->sb->s_root, AuLock_IR);
28941 + dir = a->sb->s_root->d_inode;
28942 + hdir = au_hi(dir, bindex);
28943 + h_root = au_h_dptr(a->sb->s_root, bindex);
28944 + AuDebugOn(h_root != au_br_dentry(a->br));
28946 + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
28947 + wbr_wh_write_lock(wbr);
28948 + err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
28951 + h_path.dentry = wbr->wbr_whbase;
28952 + h_path.mnt = au_br_mnt(a->br);
28953 + err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
28955 + pr_warn("%.*s is moved, ignored\n",
28956 + AuDLNPair(wbr->wbr_whbase));
28959 + dput(wbr->wbr_whbase);
28960 + wbr->wbr_whbase = NULL;
28962 + err = au_wh_init(a->br, a->sb);
28963 + wbr_wh_write_unlock(wbr);
28964 + au_hn_imtx_unlock(hdir);
28965 + di_read_unlock(a->sb->s_root, AuLock_IR);
28969 + atomic_dec(&wbr->wbr_wh_running);
28970 + atomic_dec(&a->br->br_count);
28971 + si_write_unlock(a->sb);
28972 + au_nwt_done(&au_sbi(a->sb)->si_nowait);
28974 + if (unlikely(err))
28975 + AuIOErr("err %d\n", err);
28978 +static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
28980 + int do_dec, wkq_err;
28981 + struct reinit_br_wh *arg;
28984 + if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
28987 + /* ignore ENOMEM */
28988 + arg = kmalloc(sizeof(*arg), GFP_NOFS);
28991 + * dec(wh_running), kfree(arg) and dec(br_count)
28992 + * in reinit function
28996 + atomic_inc(&br->br_count);
28997 + wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
28998 + if (unlikely(wkq_err)) {
28999 + atomic_dec(&br->br_wbr->wbr_wh_running);
29000 + atomic_dec(&br->br_count);
29008 + atomic_dec(&br->br_wbr->wbr_wh_running);
29011 +/* ---------------------------------------------------------------------- */
29014 + * create the whiteout @wh.
29016 +static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
29017 + struct dentry *wh)
29020 + struct path h_path = {
29023 + struct au_branch *br;
29024 + struct au_wbr *wbr;
29025 + struct dentry *h_parent;
29026 + struct inode *h_dir;
29028 + h_parent = wh->d_parent; /* dir inode is locked */
29029 + h_dir = h_parent->d_inode;
29030 + IMustLock(h_dir);
29032 + br = au_sbr(sb, bindex);
29033 + h_path.mnt = au_br_mnt(br);
29034 + wbr = br->br_wbr;
29035 + wbr_wh_read_lock(wbr);
29036 + if (wbr->wbr_whbase) {
29037 + err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
29038 + if (!err || err != -EMLINK)
29041 + /* link count full. re-initialize br_whbase. */
29042 + kick_reinit_br_wh(sb, br);
29045 + /* return this error in this context */
29046 + err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
29049 + wbr_wh_read_unlock(wbr);
29053 +/* ---------------------------------------------------------------------- */
29056 + * create or remove the diropq.
29058 +static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
29059 + unsigned int flags)
29061 + struct dentry *opq_dentry, *h_dentry;
29062 + struct super_block *sb;
29063 + struct au_branch *br;
29066 + sb = dentry->d_sb;
29067 + br = au_sbr(sb, bindex);
29068 + h_dentry = au_h_dptr(dentry, bindex);
29069 + opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
29070 + if (IS_ERR(opq_dentry))
29073 + if (au_ftest_diropq(flags, CREATE)) {
29074 + err = link_or_create_wh(sb, bindex, opq_dentry);
29076 + au_set_dbdiropq(dentry, bindex);
29077 + goto out; /* success */
29080 + struct path tmp = {
29081 + .dentry = opq_dentry,
29082 + .mnt = au_br_mnt(br)
29084 + err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
29086 + au_set_dbdiropq(dentry, -1);
29088 + dput(opq_dentry);
29089 + opq_dentry = ERR_PTR(err);
29092 + return opq_dentry;
29095 +struct do_diropq_args {
29096 + struct dentry **errp;
29097 + struct dentry *dentry;
29098 + aufs_bindex_t bindex;
29099 + unsigned int flags;
29102 +static void call_do_diropq(void *args)
29104 + struct do_diropq_args *a = args;
29105 + *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
29108 +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
29109 + unsigned int flags)
29111 + struct dentry *diropq, *h_dentry;
29113 + h_dentry = au_h_dptr(dentry, bindex);
29114 + if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
29115 + diropq = do_diropq(dentry, bindex, flags);
29118 + struct do_diropq_args args = {
29120 + .dentry = dentry,
29121 + .bindex = bindex,
29125 + wkq_err = au_wkq_wait(call_do_diropq, &args);
29126 + if (unlikely(wkq_err))
29127 + diropq = ERR_PTR(wkq_err);
29133 +/* ---------------------------------------------------------------------- */
29136 + * lookup whiteout dentry.
29137 + * @h_parent: lower parent dentry which must exist and be locked
29138 + * @base_name: name of dentry which will be whiteouted
29139 + * returns dentry for whiteout.
29141 +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
29142 + struct au_branch *br)
29145 + struct qstr wh_name;
29146 + struct dentry *wh_dentry;
29148 + err = au_wh_name_alloc(&wh_name, base_name);
29149 + wh_dentry = ERR_PTR(err);
29151 + wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
29152 + kfree(wh_name.name);
29154 + return wh_dentry;
29158 + * link/create a whiteout for @dentry on @bindex.
29160 +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
29161 + struct dentry *h_parent)
29163 + struct dentry *wh_dentry;
29164 + struct super_block *sb;
29167 + sb = dentry->d_sb;
29168 + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
29169 + if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
29170 + err = link_or_create_wh(sb, bindex, wh_dentry);
29172 + au_set_dbwh(dentry, bindex);
29175 + wh_dentry = ERR_PTR(err);
29179 + return wh_dentry;
29182 +/* ---------------------------------------------------------------------- */
29184 +/* Delete all whiteouts in this directory on branch bindex. */
29185 +static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
29186 + aufs_bindex_t bindex, struct au_branch *br)
29189 + unsigned long ul, n;
29190 + struct qstr wh_name;
29192 + struct hlist_head *head;
29193 + struct au_vdir_wh *pos;
29194 + struct au_vdir_destr *str;
29197 + p = (void *)__get_free_page(GFP_NOFS);
29198 + wh_name.name = p;
29199 + if (unlikely(!wh_name.name))
29203 + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
29204 + p += AUFS_WH_PFX_LEN;
29205 + n = whlist->nh_num;
29206 + head = whlist->nh_head;
29207 + for (ul = 0; !err && ul < n; ul++, head++) {
29208 + hlist_for_each_entry(pos, head, wh_hash) {
29209 + if (pos->wh_bindex != bindex)
29212 + str = &pos->wh_str;
29213 + if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
29214 + memcpy(p, str->name, str->len);
29215 + wh_name.len = AUFS_WH_PFX_LEN + str->len;
29216 + err = unlink_wh_name(h_dentry, &wh_name, br);
29221 + AuIOErr("whiteout name too long %.*s\n",
29222 + str->len, str->name);
29227 + free_page((unsigned long)wh_name.name);
29233 +struct del_wh_children_args {
29235 + struct dentry *h_dentry;
29236 + struct au_nhash *whlist;
29237 + aufs_bindex_t bindex;
29238 + struct au_branch *br;
29241 +static void call_del_wh_children(void *args)
29243 + struct del_wh_children_args *a = args;
29244 + *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
29247 +/* ---------------------------------------------------------------------- */
29249 +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
29251 + struct au_whtmp_rmdir *whtmp;
29253 + unsigned int rdhash;
29255 + SiMustAnyLock(sb);
29257 + whtmp = kmalloc(sizeof(*whtmp), gfp);
29258 + if (unlikely(!whtmp)) {
29259 + whtmp = ERR_PTR(-ENOMEM);
29263 + whtmp->dir = NULL;
29264 + whtmp->br = NULL;
29265 + whtmp->wh_dentry = NULL;
29266 + /* no estimation for dir size */
29267 + rdhash = au_sbi(sb)->si_rdhash;
29269 + rdhash = AUFS_RDHASH_DEF;
29270 + err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
29271 + if (unlikely(err)) {
29273 + whtmp = ERR_PTR(err);
29280 +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
29283 + atomic_dec(&whtmp->br->br_count);
29284 + dput(whtmp->wh_dentry);
29285 + iput(whtmp->dir);
29286 + au_nhash_wh_free(&whtmp->whlist);
29291 + * rmdir the whiteouted temporary named dir @h_dentry.
29292 + * @whlist: whiteouted children.
29294 +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
29295 + struct dentry *wh_dentry, struct au_nhash *whlist)
29298 + struct path h_tmp;
29299 + struct inode *wh_inode, *h_dir;
29300 + struct au_branch *br;
29302 + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
29303 + IMustLock(h_dir);
29305 + br = au_sbr(dir->i_sb, bindex);
29306 + wh_inode = wh_dentry->d_inode;
29307 + mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
29310 + * someone else might change some whiteouts while we were sleeping.
29311 + * it means this whlist may have an obsoleted entry.
29313 + if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
29314 + err = del_wh_children(wh_dentry, whlist, bindex, br);
29317 + struct del_wh_children_args args = {
29319 + .h_dentry = wh_dentry,
29320 + .whlist = whlist,
29321 + .bindex = bindex,
29325 + wkq_err = au_wkq_wait(call_del_wh_children, &args);
29326 + if (unlikely(wkq_err))
29329 + mutex_unlock(&wh_inode->i_mutex);
29332 + h_tmp.dentry = wh_dentry;
29333 + h_tmp.mnt = au_br_mnt(br);
29334 + err = vfsub_rmdir(h_dir, &h_tmp);
29338 + if (au_ibstart(dir) == bindex) {
29339 + /* todo: dir->i_mutex is necessary */
29340 + au_cpup_attr_timesizes(dir);
29341 + vfsub_drop_nlink(dir);
29343 + return 0; /* success */
29346 + pr_warn("failed removing %.*s(%d), ignored\n",
29347 + AuDLNPair(wh_dentry), err);
29351 +static void call_rmdir_whtmp(void *args)
29354 + aufs_bindex_t bindex;
29355 + struct au_whtmp_rmdir *a = args;
29356 + struct super_block *sb;
29357 + struct dentry *h_parent;
29358 + struct inode *h_dir;
29359 + struct au_hinode *hdir;
29361 + /* rmdir by nfsd may cause deadlock with this i_mutex */
29362 + /* mutex_lock(&a->dir->i_mutex); */
29364 + sb = a->dir->i_sb;
29365 + si_read_lock(sb, !AuLock_FLUSH);
29366 + if (!au_br_writable(a->br->br_perm))
29368 + bindex = au_br_index(sb, a->br->br_id);
29369 + if (unlikely(bindex < 0))
29373 + ii_write_lock_parent(a->dir);
29374 + h_parent = dget_parent(a->wh_dentry);
29375 + h_dir = h_parent->d_inode;
29376 + hdir = au_hi(a->dir, bindex);
29377 + err = vfsub_mnt_want_write(au_br_mnt(a->br));
29378 + if (unlikely(err))
29380 + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
29381 + err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
29384 + err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
29385 + au_hn_imtx_unlock(hdir);
29386 + vfsub_mnt_drop_write(au_br_mnt(a->br));
29390 + ii_write_unlock(a->dir);
29392 + /* mutex_unlock(&a->dir->i_mutex); */
29393 + au_whtmp_rmdir_free(a);
29394 + si_read_unlock(sb);
29395 + au_nwt_done(&au_sbi(sb)->si_nowait);
29396 + if (unlikely(err))
29397 + AuIOErr("err %d\n", err);
29400 +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
29401 + struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
29404 + struct super_block *sb;
29408 + /* all post-process will be done in do_rmdir_whtmp(). */
29410 + args->dir = au_igrab(dir);
29411 + args->br = au_sbr(sb, bindex);
29412 + atomic_inc(&args->br->br_count);
29413 + args->wh_dentry = dget(wh_dentry);
29414 + wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
29415 + if (unlikely(wkq_err)) {
29416 + pr_warn("rmdir error %.*s (%d), ignored\n",
29417 + AuDLNPair(wh_dentry), wkq_err);
29418 + au_whtmp_rmdir_free(args);
29421 diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
29422 --- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
29423 +++ linux/fs/aufs/whout.h 2013-07-06 13:20:47.760198800 +0200
29426 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29428 + * This program, aufs is free software; you can redistribute it and/or modify
29429 + * it under the terms of the GNU General Public License as published by
29430 + * the Free Software Foundation; either version 2 of the License, or
29431 + * (at your option) any later version.
29433 + * This program is distributed in the hope that it will be useful,
29434 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29435 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29436 + * GNU General Public License for more details.
29438 + * You should have received a copy of the GNU General Public License
29439 + * along with this program; if not, write to the Free Software
29440 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29444 + * whiteout for logical deletion and opaque directory
29447 +#ifndef __AUFS_WHOUT_H__
29448 +#define __AUFS_WHOUT_H__
29455 +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
29457 +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
29458 + struct au_branch *br, int try_sio);
29459 +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
29460 +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
29461 + struct qstr *prefix);
29462 +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
29463 +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
29464 + struct dentry *dentry);
29465 +int au_wh_init(struct au_branch *br, struct super_block *sb);
29467 +/* diropq flags */
29468 +#define AuDiropq_CREATE 1
29469 +#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
29470 +#define au_fset_diropq(flags, name) \
29471 + do { (flags) |= AuDiropq_##name; } while (0)
29472 +#define au_fclr_diropq(flags, name) \
29473 + do { (flags) &= ~AuDiropq_##name; } while (0)
29475 +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
29476 + unsigned int flags);
29477 +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
29478 + struct au_branch *br);
29479 +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
29480 + struct dentry *h_parent);
29482 +/* real rmdir for the whiteout-ed dir */
29483 +struct au_whtmp_rmdir {
29484 + struct inode *dir;
29485 + struct au_branch *br;
29486 + struct dentry *wh_dentry;
29487 + struct au_nhash whlist;
29490 +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
29491 +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
29492 +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
29493 + struct dentry *wh_dentry, struct au_nhash *whlist);
29494 +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
29495 + struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
29497 +/* ---------------------------------------------------------------------- */
29499 +static inline struct dentry *au_diropq_create(struct dentry *dentry,
29500 + aufs_bindex_t bindex)
29502 + return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
29505 +static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
29507 + return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
29510 +#endif /* __KERNEL__ */
29511 +#endif /* __AUFS_WHOUT_H__ */
29512 diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
29513 --- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
29514 +++ linux/fs/aufs/wkq.c 2013-07-06 13:20:47.760198800 +0200
29517 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29519 + * This program, aufs is free software; you can redistribute it and/or modify
29520 + * it under the terms of the GNU General Public License as published by
29521 + * the Free Software Foundation; either version 2 of the License, or
29522 + * (at your option) any later version.
29524 + * This program is distributed in the hope that it will be useful,
29525 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29526 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29527 + * GNU General Public License for more details.
29529 + * You should have received a copy of the GNU General Public License
29530 + * along with this program; if not, write to the Free Software
29531 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29535 + * workqueue for asynchronous/super-io operations
29536 + * todo: try new dredential scheme
29539 +#include <linux/module.h>
29542 +/* internal workqueue named AUFS_WKQ_NAME */
29544 +static struct workqueue_struct *au_wkq;
29546 +struct au_wkinfo {
29547 + struct work_struct wk;
29548 + struct kobject *kobj;
29550 + unsigned int flags; /* see wkq.h */
29552 + au_wkq_func_t func;
29555 + struct completion *comp;
29558 +/* ---------------------------------------------------------------------- */
29560 +static void wkq_func(struct work_struct *wk)
29562 + struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
29564 + AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
29565 + AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
29567 + wkinfo->func(wkinfo->args);
29568 + if (au_ftest_wkq(wkinfo->flags, WAIT))
29569 + complete(wkinfo->comp);
29571 + kobject_put(wkinfo->kobj);
29572 + module_put(THIS_MODULE); /* todo: ?? */
29578 + * Since struct completion is large, try allocating it dynamically.
29580 +#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS)
29581 +#define AuWkqCompDeclare(name) struct completion *comp = NULL
29583 +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
29585 + *comp = kmalloc(sizeof(**comp), GFP_NOFS);
29587 + init_completion(*comp);
29588 + wkinfo->comp = *comp;
29594 +static void au_wkq_comp_free(struct completion *comp)
29602 +#define AuWkqCompDeclare(name) \
29603 + DECLARE_COMPLETION_ONSTACK(_ ## name); \
29604 + struct completion *comp = &_ ## name
29606 +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
29608 + wkinfo->comp = *comp;
29612 +static void au_wkq_comp_free(struct completion *comp __maybe_unused)
29616 +#endif /* 4KSTACKS */
29618 +static void au_wkq_run(struct au_wkinfo *wkinfo)
29620 + if (au_ftest_wkq(wkinfo->flags, NEST)) {
29621 + if (au_wkq_test()) {
29622 + AuWarn1("wkq from wkq, due to a dead dir by UDBA?\n");
29623 + AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
29626 + au_dbg_verify_kthread();
29628 + if (au_ftest_wkq(wkinfo->flags, WAIT)) {
29629 + INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
29630 + queue_work(au_wkq, &wkinfo->wk);
29632 + INIT_WORK(&wkinfo->wk, wkq_func);
29633 + schedule_work(&wkinfo->wk);
29638 + * Be careful. It is easy to make deadlock happen.
29639 + * processA: lock, wkq and wait
29640 + * processB: wkq and wait, lock in wkq
29643 +int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
29646 + AuWkqCompDeclare(comp);
29647 + struct au_wkinfo wkinfo = {
29653 + err = au_wkq_comp_alloc(&wkinfo, &comp);
29655 + au_wkq_run(&wkinfo);
29656 + /* no timeout, no interrupt */
29657 + wait_for_completion(wkinfo.comp);
29658 + au_wkq_comp_free(comp);
29659 + destroy_work_on_stack(&wkinfo.wk);
29667 + * Note: dget/dput() in func for aufs dentries are not supported. It will be a
29668 + * problem in a concurrent umounting.
29670 +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
29671 + unsigned int flags)
29674 + struct au_wkinfo *wkinfo;
29676 + atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
29679 + * wkq_func() must free this wkinfo.
29680 + * it highly depends upon the implementation of workqueue.
29683 + wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
29685 + wkinfo->kobj = &au_sbi(sb)->si_kobj;
29686 + wkinfo->flags = flags & ~AuWkq_WAIT;
29687 + wkinfo->func = func;
29688 + wkinfo->args = args;
29689 + wkinfo->comp = NULL;
29690 + kobject_get(wkinfo->kobj);
29691 + __module_get(THIS_MODULE); /* todo: ?? */
29693 + au_wkq_run(wkinfo);
29696 + au_nwt_done(&au_sbi(sb)->si_nowait);
29702 +/* ---------------------------------------------------------------------- */
29704 +void au_nwt_init(struct au_nowait_tasks *nwt)
29706 + atomic_set(&nwt->nw_len, 0);
29707 + /* smp_mb(); */ /* atomic_set */
29708 + init_waitqueue_head(&nwt->nw_wq);
29711 +void au_wkq_fin(void)
29713 + destroy_workqueue(au_wkq);
29716 +int __init au_wkq_init(void)
29721 + au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
29722 + if (IS_ERR(au_wkq))
29723 + err = PTR_ERR(au_wkq);
29724 + else if (!au_wkq)
29729 diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
29730 --- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
29731 +++ linux/fs/aufs/wkq.h 2013-07-06 13:20:47.760198800 +0200
29734 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29736 + * This program, aufs is free software; you can redistribute it and/or modify
29737 + * it under the terms of the GNU General Public License as published by
29738 + * the Free Software Foundation; either version 2 of the License, or
29739 + * (at your option) any later version.
29741 + * This program is distributed in the hope that it will be useful,
29742 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29743 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29744 + * GNU General Public License for more details.
29746 + * You should have received a copy of the GNU General Public License
29747 + * along with this program; if not, write to the Free Software
29748 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29752 + * workqueue for asynchronous/super-io operations
29753 + * todo: try new credentials management scheme
29756 +#ifndef __AUFS_WKQ_H__
29757 +#define __AUFS_WKQ_H__
29761 +struct super_block;
29763 +/* ---------------------------------------------------------------------- */
29766 + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
29768 +struct au_nowait_tasks {
29770 + wait_queue_head_t nw_wq;
29773 +/* ---------------------------------------------------------------------- */
29775 +typedef void (*au_wkq_func_t)(void *args);
29778 +#define AuWkq_WAIT 1
29779 +#define AuWkq_NEST (1 << 1)
29780 +#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
29781 +#define au_fset_wkq(flags, name) \
29782 + do { (flags) |= AuWkq_##name; } while (0)
29783 +#define au_fclr_wkq(flags, name) \
29784 + do { (flags) &= ~AuWkq_##name; } while (0)
29786 +#ifndef CONFIG_AUFS_HNOTIFY
29788 +#define AuWkq_NEST 0
29792 +int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
29793 +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
29794 + unsigned int flags);
29795 +void au_nwt_init(struct au_nowait_tasks *nwt);
29796 +int __init au_wkq_init(void);
29797 +void au_wkq_fin(void);
29799 +/* ---------------------------------------------------------------------- */
29801 +static inline int au_wkq_test(void)
29803 + return current->flags & PF_WQ_WORKER;
29806 +static inline int au_wkq_wait(au_wkq_func_t func, void *args)
29808 + return au_wkq_do_wait(AuWkq_WAIT, func, args);
29811 +static inline void au_nwt_done(struct au_nowait_tasks *nwt)
29813 + if (atomic_dec_and_test(&nwt->nw_len))
29814 + wake_up_all(&nwt->nw_wq);
29817 +static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
29819 + wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
29823 +#endif /* __KERNEL__ */
29824 +#endif /* __AUFS_WKQ_H__ */
29825 diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
29826 --- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
29827 +++ linux/fs/aufs/xino.c 2013-07-06 13:20:47.760198800 +0200
29830 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29832 + * This program, aufs is free software; you can redistribute it and/or modify
29833 + * it under the terms of the GNU General Public License as published by
29834 + * the Free Software Foundation; either version 2 of the License, or
29835 + * (at your option) any later version.
29837 + * This program is distributed in the hope that it will be useful,
29838 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29839 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29840 + * GNU General Public License for more details.
29842 + * You should have received a copy of the GNU General Public License
29843 + * along with this program; if not, write to the Free Software
29844 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29848 + * external inode number translation table and bitmap
29851 +#include <linux/seq_file.h>
29854 +/* todo: unnecessary to support mmap_sem since kernel-space? */
29855 +ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
29859 + mm_segment_t oldfs;
29866 + oldfs = get_fs();
29867 + set_fs(KERNEL_DS);
29869 + /* todo: signal_pending? */
29870 + err = func(file, buf.u, size, pos);
29871 + } while (err == -EAGAIN || err == -EINTR);
29874 +#if 0 /* reserved for future use */
29876 + fsnotify_access(file->f_dentry);
29882 +/* ---------------------------------------------------------------------- */
29884 +static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
29885 + size_t size, loff_t *pos)
29888 + mm_segment_t oldfs;
29891 + const char __user *u;
29895 + oldfs = get_fs();
29896 + set_fs(KERNEL_DS);
29898 + /* todo: signal_pending? */
29899 + err = func(file, buf.u, size, pos);
29900 + } while (err == -EAGAIN || err == -EINTR);
29903 +#if 0 /* reserved for future use */
29905 + fsnotify_modify(file->f_dentry);
29911 +struct do_xino_fwrite_args {
29913 + au_writef_t func;
29914 + struct file *file;
29920 +static void call_do_xino_fwrite(void *args)
29922 + struct do_xino_fwrite_args *a = args;
29923 + *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
29926 +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
29931 + /* todo: signal block and no wkq? */
29932 + if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
29934 + err = do_xino_fwrite(func, file, buf, size, pos);
29938 + * it breaks RLIMIT_FSIZE and normal user's limit,
29939 + * users should care about quota and real 'filesystem full.'
29942 + struct do_xino_fwrite_args args = {
29951 + wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
29952 + if (unlikely(wkq_err))
29959 +/* ---------------------------------------------------------------------- */
29962 + * create a new xinofile at the same place/path as @base_file.
29964 +struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
29966 + struct file *file;
29967 + struct dentry *base, *parent;
29968 + struct inode *dir;
29969 + struct qstr *name;
29970 + struct path path;
29973 + base = base_file->f_dentry;
29974 + parent = base->d_parent; /* dir inode is locked */
29975 + dir = parent->d_inode;
29978 + file = ERR_PTR(-EINVAL);
29979 + name = &base->d_name;
29980 + path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
29981 + if (IS_ERR(path.dentry)) {
29982 + file = (void *)path.dentry;
29983 + pr_err("%.*s lookup err %ld\n",
29984 + AuLNPair(name), PTR_ERR(path.dentry));
29988 + /* no need to mnt_want_write() since we call dentry_open() later */
29989 + err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
29990 + if (unlikely(err)) {
29991 + file = ERR_PTR(err);
29992 + pr_err("%.*s create err %d\n", AuLNPair(name), err);
29996 + path.mnt = base_file->f_path.mnt;
29997 + file = vfsub_dentry_open(&path,
29998 + O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
29999 + /* | __FMODE_NONOTIFY */);
30000 + if (IS_ERR(file)) {
30001 + pr_err("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
30005 + err = vfsub_unlink(dir, &file->f_path, /*force*/0);
30006 + if (unlikely(err)) {
30007 + pr_err("%.*s unlink err %d\n", AuLNPair(name), err);
30012 + /* no one can touch copy_src xino */
30013 + err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
30014 + if (unlikely(err)) {
30015 + pr_err("%.*s copy err %d\n", AuLNPair(name), err);
30019 + goto out_dput; /* success */
30023 + file = ERR_PTR(err);
30025 + dput(path.dentry);
30030 +struct au_xino_lock_dir {
30031 + struct au_hinode *hdir;
30032 + struct dentry *parent;
30033 + struct mutex *mtx;
30036 +static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
30037 + struct au_xino_lock_dir *ldir)
30039 + aufs_bindex_t brid, bindex;
30041 + ldir->hdir = NULL;
30043 + brid = au_xino_brid(sb);
30045 + bindex = au_br_index(sb, brid);
30046 + if (bindex >= 0) {
30047 + ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
30048 + au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
30050 + ldir->parent = dget_parent(xino->f_dentry);
30051 + ldir->mtx = &ldir->parent->d_inode->i_mutex;
30052 + mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
30056 +static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
30059 + au_hn_imtx_unlock(ldir->hdir);
30061 + mutex_unlock(ldir->mtx);
30062 + dput(ldir->parent);
30066 +/* ---------------------------------------------------------------------- */
30068 +/* trucate xino files asynchronously */
30070 +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
30073 + aufs_bindex_t bi, bend;
30074 + struct au_branch *br;
30075 + struct file *new_xino, *file;
30076 + struct super_block *h_sb;
30077 + struct au_xino_lock_dir ldir;
30080 + bend = au_sbend(sb);
30081 + if (unlikely(bindex < 0 || bend < bindex))
30083 + br = au_sbr(sb, bindex);
30084 + file = br->br_xino.xi_file;
30088 + au_xino_lock_dir(sb, file, &ldir);
30089 + /* mnt_want_write() is unnecessary here */
30090 + new_xino = au_xino_create2(file, file);
30091 + au_xino_unlock_dir(&ldir);
30092 + err = PTR_ERR(new_xino);
30093 + if (IS_ERR(new_xino))
30097 + br->br_xino.xi_file = new_xino;
30099 + h_sb = au_br_sb(br);
30100 + for (bi = 0; bi <= bend; bi++) {
30101 + if (unlikely(bi == bindex))
30103 + br = au_sbr(sb, bi);
30104 + if (au_br_sb(br) != h_sb)
30107 + fput(br->br_xino.xi_file);
30108 + br->br_xino.xi_file = new_xino;
30109 + get_file(new_xino);
30116 +struct xino_do_trunc_args {
30117 + struct super_block *sb;
30118 + struct au_branch *br;
30121 +static void xino_do_trunc(void *_args)
30123 + struct xino_do_trunc_args *args = _args;
30124 + struct super_block *sb;
30125 + struct au_branch *br;
30126 + struct inode *dir;
30128 + aufs_bindex_t bindex;
30132 + dir = sb->s_root->d_inode;
30135 + si_noflush_write_lock(sb);
30136 + ii_read_lock_parent(dir);
30137 + bindex = au_br_index(sb, br->br_id);
30138 + err = au_xino_trunc(sb, bindex);
30140 + && file_inode(br->br_xino.xi_file)->i_blocks
30141 + >= br->br_xino_upper)
30142 + br->br_xino_upper += AUFS_XINO_TRUNC_STEP;
30144 + ii_read_unlock(dir);
30145 + if (unlikely(err))
30146 + pr_warn("err b%d, upper %llu, (%d)\n",
30147 + bindex, (unsigned long long)br->br_xino_upper, err);
30148 + atomic_dec(&br->br_xino_running);
30149 + atomic_dec(&br->br_count);
30150 + si_write_unlock(sb);
30151 + au_nwt_done(&au_sbi(sb)->si_nowait);
30155 +static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
30157 + struct xino_do_trunc_args *args;
30160 + if (file_inode(br->br_xino.xi_file)->i_blocks
30161 + < br->br_xino_upper)
30164 + if (atomic_inc_return(&br->br_xino_running) > 1)
30167 + /* lock and kfree() will be called in trunc_xino() */
30168 + args = kmalloc(sizeof(*args), GFP_NOFS);
30169 + if (unlikely(!args)) {
30170 + AuErr1("no memory\n");
30174 + atomic_inc(&br->br_count);
30177 + wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
30179 + return; /* success */
30181 + pr_err("wkq %d\n", wkq_err);
30182 + atomic_dec(&br->br_count);
30187 + atomic_dec(&br->br_xino_running);
30190 +/* ---------------------------------------------------------------------- */
30192 +static int au_xino_do_write(au_writef_t write, struct file *file,
30193 + ino_t h_ino, ino_t ino)
30199 + if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
30200 + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
30203 + pos *= sizeof(ino);
30204 + sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
30205 + if (sz == sizeof(ino))
30206 + return 0; /* success */
30208 + AuIOErr("write failed (%zd)\n", sz);
30213 + * write @ino to the xinofile for the specified branch{@sb, @bindex}
30214 + * at the position of @h_ino.
30215 + * even if @ino is zero, it is written to the xinofile and means no entry.
30216 + * if the size of the xino file on a specific filesystem exceeds the watermark,
30217 + * try truncating it.
30219 +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
30223 + unsigned int mnt_flags;
30224 + struct au_branch *br;
30226 + BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
30227 + || ((loff_t)-1) > 0);
30228 + SiMustAnyLock(sb);
30230 + mnt_flags = au_mntflags(sb);
30231 + if (!au_opt_test(mnt_flags, XINO))
30234 + br = au_sbr(sb, bindex);
30235 + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
30238 + if (au_opt_test(mnt_flags, TRUNC_XINO)
30239 + && au_test_fs_trunc_xino(au_br_sb(br)))
30240 + xino_try_trunc(sb, br);
30241 + return 0; /* success */
30244 + AuIOErr("write failed (%d)\n", err);
30248 +/* ---------------------------------------------------------------------- */
30250 +/* aufs inode number bitmap */
30252 +static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
30253 +static ino_t xib_calc_ino(unsigned long pindex, int bit)
30257 + AuDebugOn(bit < 0 || page_bits <= bit);
30258 + ino = AUFS_FIRST_INO + pindex * page_bits + bit;
30262 +static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
30264 + AuDebugOn(ino < AUFS_FIRST_INO);
30265 + ino -= AUFS_FIRST_INO;
30266 + *pindex = ino / page_bits;
30267 + *bit = ino % page_bits;
30270 +static int xib_pindex(struct super_block *sb, unsigned long pindex)
30275 + struct au_sbinfo *sbinfo;
30276 + struct file *xib;
30277 + unsigned long *p;
30279 + sbinfo = au_sbi(sb);
30280 + MtxMustLock(&sbinfo->si_xib_mtx);
30281 + AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
30282 + || !au_opt_test(sbinfo->si_mntflags, XINO));
30284 + if (pindex == sbinfo->si_xib_last_pindex)
30287 + xib = sbinfo->si_xib;
30288 + p = sbinfo->si_xib_buf;
30289 + pos = sbinfo->si_xib_last_pindex;
30290 + pos *= PAGE_SIZE;
30291 + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
30292 + if (unlikely(sz != PAGE_SIZE))
30296 + pos *= PAGE_SIZE;
30297 + if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
30298 + sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
30300 + memset(p, 0, PAGE_SIZE);
30301 + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
30303 + if (sz == PAGE_SIZE) {
30304 + sbinfo->si_xib_last_pindex = pindex;
30305 + return 0; /* success */
30309 + AuIOErr1("write failed (%zd)\n", sz);
30316 +/* ---------------------------------------------------------------------- */
30318 +static void au_xib_clear_bit(struct inode *inode)
30321 + unsigned long pindex;
30322 + struct super_block *sb;
30323 + struct au_sbinfo *sbinfo;
30325 + AuDebugOn(inode->i_nlink);
30327 + sb = inode->i_sb;
30328 + xib_calc_bit(inode->i_ino, &pindex, &bit);
30329 + AuDebugOn(page_bits <= bit);
30330 + sbinfo = au_sbi(sb);
30331 + mutex_lock(&sbinfo->si_xib_mtx);
30332 + err = xib_pindex(sb, pindex);
30334 + clear_bit(bit, sbinfo->si_xib_buf);
30335 + sbinfo->si_xib_next_bit = bit;
30337 + mutex_unlock(&sbinfo->si_xib_mtx);
30340 +/* for s_op->delete_inode() */
30341 +void au_xino_delete_inode(struct inode *inode, const int unlinked)
30344 + unsigned int mnt_flags;
30345 + aufs_bindex_t bindex, bend, bi;
30346 + unsigned char try_trunc;
30347 + struct au_iinfo *iinfo;
30348 + struct super_block *sb;
30349 + struct au_hinode *hi;
30350 + struct inode *h_inode;
30351 + struct au_branch *br;
30352 + au_writef_t xwrite;
30354 + sb = inode->i_sb;
30355 + mnt_flags = au_mntflags(sb);
30356 + if (!au_opt_test(mnt_flags, XINO)
30357 + || inode->i_ino == AUFS_ROOT_INO)
30361 + au_xigen_inc(inode);
30362 + au_xib_clear_bit(inode);
30365 + iinfo = au_ii(inode);
30369 + bindex = iinfo->ii_bstart;
30373 + xwrite = au_sbi(sb)->si_xwrite;
30374 + try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
30375 + hi = iinfo->ii_hinode + bindex;
30376 + bend = iinfo->ii_bend;
30377 + for (; bindex <= bend; bindex++, hi++) {
30378 + h_inode = hi->hi_inode;
30380 + || (!unlinked && h_inode->i_nlink))
30383 + /* inode may not be revalidated */
30384 + bi = au_br_index(sb, hi->hi_id);
30388 + br = au_sbr(sb, bi);
30389 + err = au_xino_do_write(xwrite, br->br_xino.xi_file,
30390 + h_inode->i_ino, /*ino*/0);
30391 + if (!err && try_trunc
30392 + && au_test_fs_trunc_xino(au_br_sb(br)))
30393 + xino_try_trunc(sb, br);
30397 +/* get an unused inode number from bitmap */
30398 +ino_t au_xino_new_ino(struct super_block *sb)
30401 + unsigned long *p, pindex, ul, pend;
30402 + struct au_sbinfo *sbinfo;
30403 + struct file *file;
30404 + int free_bit, err;
30406 + if (!au_opt_test(au_mntflags(sb), XINO))
30407 + return iunique(sb, AUFS_FIRST_INO);
30409 + sbinfo = au_sbi(sb);
30410 + mutex_lock(&sbinfo->si_xib_mtx);
30411 + p = sbinfo->si_xib_buf;
30412 + free_bit = sbinfo->si_xib_next_bit;
30413 + if (free_bit < page_bits && !test_bit(free_bit, p))
30414 + goto out; /* success */
30415 + free_bit = find_first_zero_bit(p, page_bits);
30416 + if (free_bit < page_bits)
30417 + goto out; /* success */
30419 + pindex = sbinfo->si_xib_last_pindex;
30420 + for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
30421 + err = xib_pindex(sb, ul);
30422 + if (unlikely(err))
30424 + free_bit = find_first_zero_bit(p, page_bits);
30425 + if (free_bit < page_bits)
30426 + goto out; /* success */
30429 + file = sbinfo->si_xib;
30430 + pend = vfsub_f_size_read(file) / PAGE_SIZE;
30431 + for (ul = pindex + 1; ul <= pend; ul++) {
30432 + err = xib_pindex(sb, ul);
30433 + if (unlikely(err))
30435 + free_bit = find_first_zero_bit(p, page_bits);
30436 + if (free_bit < page_bits)
30437 + goto out; /* success */
30442 + set_bit(free_bit, p);
30443 + sbinfo->si_xib_next_bit = free_bit + 1;
30444 + pindex = sbinfo->si_xib_last_pindex;
30445 + mutex_unlock(&sbinfo->si_xib_mtx);
30446 + ino = xib_calc_ino(pindex, free_bit);
30447 + AuDbg("i%lu\n", (unsigned long)ino);
30450 + mutex_unlock(&sbinfo->si_xib_mtx);
30456 + * read @ino from xinofile for the specified branch{@sb, @bindex}
30457 + * at the position of @h_ino.
30458 + * if @ino does not exist and @do_new is true, get new one.
30460 +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
30466 + struct file *file;
30467 + struct au_sbinfo *sbinfo;
30470 + if (!au_opt_test(au_mntflags(sb), XINO))
30471 + return 0; /* no xino */
30474 + sbinfo = au_sbi(sb);
30476 + if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
30477 + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
30480 + pos *= sizeof(*ino);
30482 + file = au_sbr(sb, bindex)->br_xino.xi_file;
30483 + if (vfsub_f_size_read(file) < pos + sizeof(*ino))
30484 + return 0; /* no ino */
30486 + sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
30487 + if (sz == sizeof(*ino))
30488 + return 0; /* success */
30491 + if (unlikely(sz >= 0)) {
30493 + AuIOErr("xino read error (%zd)\n", sz);
30499 +/* ---------------------------------------------------------------------- */
30501 +/* create and set a new xino file */
30503 +struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
30505 + struct file *file;
30506 + struct dentry *h_parent, *d;
30507 + struct inode *h_dir;
30511 + * at mount-time, and the xino file is the default path,
30512 + * hnotify is disabled so we have no notify events to ignore.
30513 + * when a user specified the xino, we cannot get au_hdir to be ignored.
30515 + file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
30516 + /* | __FMODE_NONOTIFY */,
30517 + S_IRUGO | S_IWUGO);
30518 + if (IS_ERR(file)) {
30520 + pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
30524 + /* keep file count */
30525 + h_parent = dget_parent(file->f_dentry);
30526 + h_dir = h_parent->d_inode;
30527 + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
30528 + /* mnt_want_write() is unnecessary here */
30529 + err = vfsub_unlink(h_dir, &file->f_path, /*force*/0);
30530 + mutex_unlock(&h_dir->i_mutex);
30532 + if (unlikely(err)) {
30534 + pr_err("unlink %s(%d)\n", fname, err);
30539 + d = file->f_dentry;
30540 + if (unlikely(sb == d->d_sb)) {
30542 + pr_err("%s must be outside\n", fname);
30545 + if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
30547 + pr_err("xino doesn't support %s(%s)\n",
30548 + fname, au_sbtype(d->d_sb));
30551 + return file; /* success */
30555 + file = ERR_PTR(err);
30560 + * find another branch who is on the same filesystem of the specified
30561 + * branch{@btgt}. search until @bend.
30563 +static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
30564 + aufs_bindex_t bend)
30566 + aufs_bindex_t bindex;
30567 + struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
30569 + for (bindex = 0; bindex < btgt; bindex++)
30570 + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
30572 + for (bindex++; bindex <= bend; bindex++)
30573 + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
30578 +/* ---------------------------------------------------------------------- */
30581 + * initialize the xinofile for the specified branch @br
30582 + * at the place/path where @base_file indicates.
30583 + * test whether another branch is on the same filesystem or not,
30584 + * if @do_test is true.
30586 +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
30587 + struct file *base_file, int do_test)
30591 + aufs_bindex_t bend, bindex;
30592 + struct au_branch *shared_br, *b;
30593 + struct file *file;
30594 + struct super_block *tgt_sb;
30596 + shared_br = NULL;
30597 + bend = au_sbend(sb);
30599 + tgt_sb = au_br_sb(br);
30600 + for (bindex = 0; bindex <= bend; bindex++) {
30601 + b = au_sbr(sb, bindex);
30602 + if (tgt_sb == au_br_sb(b)) {
30609 + if (!shared_br || !shared_br->br_xino.xi_file) {
30610 + struct au_xino_lock_dir ldir;
30612 + au_xino_lock_dir(sb, base_file, &ldir);
30613 + /* mnt_want_write() is unnecessary here */
30614 + file = au_xino_create2(base_file, NULL);
30615 + au_xino_unlock_dir(&ldir);
30616 + err = PTR_ERR(file);
30617 + if (IS_ERR(file))
30619 + br->br_xino.xi_file = file;
30621 + br->br_xino.xi_file = shared_br->br_xino.xi_file;
30622 + get_file(br->br_xino.xi_file);
30625 + ino = AUFS_ROOT_INO;
30626 + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
30628 + if (unlikely(err)) {
30629 + fput(br->br_xino.xi_file);
30630 + br->br_xino.xi_file = NULL;
30637 +/* ---------------------------------------------------------------------- */
30639 +/* trucate a xino bitmap file */
30642 +static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
30646 + unsigned long pindex;
30647 + loff_t pos, pend;
30648 + struct au_sbinfo *sbinfo;
30651 + unsigned long *p;
30654 + sbinfo = au_sbi(sb);
30655 + MtxMustLock(&sbinfo->si_xib_mtx);
30656 + p = sbinfo->si_xib_buf;
30657 + func = sbinfo->si_xread;
30658 + pend = vfsub_f_size_read(file);
30660 + while (pos < pend) {
30661 + sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
30663 + if (unlikely(sz <= 0))
30667 + for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
30668 + if (unlikely(*ino < AUFS_FIRST_INO))
30671 + xib_calc_bit(*ino, &pindex, &bit);
30672 + AuDebugOn(page_bits <= bit);
30673 + err = xib_pindex(sb, pindex);
30685 +static int xib_restore(struct super_block *sb)
30688 + aufs_bindex_t bindex, bend;
30692 + page = (void *)__get_free_page(GFP_NOFS);
30693 + if (unlikely(!page))
30697 + bend = au_sbend(sb);
30698 + for (bindex = 0; !err && bindex <= bend; bindex++)
30699 + if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
30700 + err = do_xib_restore
30701 + (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
30703 + AuDbg("b%d\n", bindex);
30704 + free_page((unsigned long)page);
30710 +int au_xib_trunc(struct super_block *sb)
30715 + struct au_xino_lock_dir ldir;
30716 + struct au_sbinfo *sbinfo;
30717 + unsigned long *p;
30718 + struct file *file;
30720 + SiMustWriteLock(sb);
30723 + sbinfo = au_sbi(sb);
30724 + if (!au_opt_test(sbinfo->si_mntflags, XINO))
30727 + file = sbinfo->si_xib;
30728 + if (vfsub_f_size_read(file) <= PAGE_SIZE)
30731 + au_xino_lock_dir(sb, file, &ldir);
30732 + /* mnt_want_write() is unnecessary here */
30733 + file = au_xino_create2(sbinfo->si_xib, NULL);
30734 + au_xino_unlock_dir(&ldir);
30735 + err = PTR_ERR(file);
30736 + if (IS_ERR(file))
30738 + fput(sbinfo->si_xib);
30739 + sbinfo->si_xib = file;
30741 + p = sbinfo->si_xib_buf;
30742 + memset(p, 0, PAGE_SIZE);
30744 + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
30745 + if (unlikely(sz != PAGE_SIZE)) {
30747 + AuIOErr("err %d\n", err);
30753 + mutex_lock(&sbinfo->si_xib_mtx);
30754 + /* mnt_want_write() is unnecessary here */
30755 + err = xib_restore(sb);
30756 + mutex_unlock(&sbinfo->si_xib_mtx);
30762 +/* ---------------------------------------------------------------------- */
30765 + * xino mount option handlers
30767 +static au_readf_t find_readf(struct file *h_file)
30769 + const struct file_operations *fop = h_file->f_op;
30773 + return fop->read;
30774 + if (fop->aio_read)
30775 + return do_sync_read;
30777 + return ERR_PTR(-ENOSYS);
30780 +static au_writef_t find_writef(struct file *h_file)
30782 + const struct file_operations *fop = h_file->f_op;
30786 + return fop->write;
30787 + if (fop->aio_write)
30788 + return do_sync_write;
30790 + return ERR_PTR(-ENOSYS);
30794 +static void xino_clear_xib(struct super_block *sb)
30796 + struct au_sbinfo *sbinfo;
30798 + SiMustWriteLock(sb);
30800 + sbinfo = au_sbi(sb);
30801 + sbinfo->si_xread = NULL;
30802 + sbinfo->si_xwrite = NULL;
30803 + if (sbinfo->si_xib)
30804 + fput(sbinfo->si_xib);
30805 + sbinfo->si_xib = NULL;
30806 + free_page((unsigned long)sbinfo->si_xib_buf);
30807 + sbinfo->si_xib_buf = NULL;
30810 +static int au_xino_set_xib(struct super_block *sb, struct file *base)
30814 + struct au_sbinfo *sbinfo;
30815 + struct file *file;
30817 + SiMustWriteLock(sb);
30819 + sbinfo = au_sbi(sb);
30820 + file = au_xino_create2(base, sbinfo->si_xib);
30821 + err = PTR_ERR(file);
30822 + if (IS_ERR(file))
30824 + if (sbinfo->si_xib)
30825 + fput(sbinfo->si_xib);
30826 + sbinfo->si_xib = file;
30827 + sbinfo->si_xread = find_readf(file);
30828 + sbinfo->si_xwrite = find_writef(file);
30831 + if (!sbinfo->si_xib_buf)
30832 + sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
30833 + if (unlikely(!sbinfo->si_xib_buf))
30836 + sbinfo->si_xib_last_pindex = 0;
30837 + sbinfo->si_xib_next_bit = 0;
30838 + if (vfsub_f_size_read(file) < PAGE_SIZE) {
30840 + err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
30841 + PAGE_SIZE, &pos);
30842 + if (unlikely(err != PAGE_SIZE))
30846 + goto out; /* success */
30849 + free_page((unsigned long)sbinfo->si_xib_buf);
30850 + sbinfo->si_xib_buf = NULL;
30854 + fput(sbinfo->si_xib);
30855 + sbinfo->si_xib = NULL;
30856 + sbinfo->si_xread = NULL;
30857 + sbinfo->si_xwrite = NULL;
30862 +/* xino for each branch */
30863 +static void xino_clear_br(struct super_block *sb)
30865 + aufs_bindex_t bindex, bend;
30866 + struct au_branch *br;
30868 + bend = au_sbend(sb);
30869 + for (bindex = 0; bindex <= bend; bindex++) {
30870 + br = au_sbr(sb, bindex);
30871 + if (!br || !br->br_xino.xi_file)
30874 + fput(br->br_xino.xi_file);
30875 + br->br_xino.xi_file = NULL;
30879 +static int au_xino_set_br(struct super_block *sb, struct file *base)
30883 + aufs_bindex_t bindex, bend, bshared;
30885 + struct file *old, *new;
30887 + struct au_branch *br;
30888 + struct inode *inode;
30889 + au_writef_t writef;
30891 + SiMustWriteLock(sb);
30894 + bend = au_sbend(sb);
30895 + fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
30896 + if (unlikely(!fpair))
30899 + inode = sb->s_root->d_inode;
30900 + ino = AUFS_ROOT_INO;
30901 + writef = au_sbi(sb)->si_xwrite;
30902 + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
30903 + br = au_sbr(sb, bindex);
30904 + bshared = is_sb_shared(sb, bindex, bindex - 1);
30905 + if (bshared >= 0) {
30906 + /* shared xino */
30907 + *p = fpair[bshared];
30908 + get_file(p->new);
30913 + p->old = br->br_xino.xi_file;
30914 + p->new = au_xino_create2(base, br->br_xino.xi_file);
30915 + err = PTR_ERR(p->new);
30916 + if (IS_ERR(p->new)) {
30922 + err = au_xino_do_write(writef, p->new,
30923 + au_h_iptr(inode, bindex)->i_ino, ino);
30924 + if (unlikely(err))
30928 + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
30929 + br = au_sbr(sb, bindex);
30930 + if (br->br_xino.xi_file)
30931 + fput(br->br_xino.xi_file);
30932 + get_file(p->new);
30933 + br->br_xino.xi_file = p->new;
30937 + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
30947 +void au_xino_clr(struct super_block *sb)
30949 + struct au_sbinfo *sbinfo;
30951 + au_xigen_clr(sb);
30952 + xino_clear_xib(sb);
30953 + xino_clear_br(sb);
30954 + sbinfo = au_sbi(sb);
30955 + /* lvalue, do not call au_mntflags() */
30956 + au_opt_clr(sbinfo->si_mntflags, XINO);
30959 +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
30962 + struct dentry *parent, *cur_parent;
30963 + struct qstr *dname, *cur_name;
30964 + struct file *cur_xino;
30965 + struct inode *dir;
30966 + struct au_sbinfo *sbinfo;
30968 + SiMustWriteLock(sb);
30971 + sbinfo = au_sbi(sb);
30972 + parent = dget_parent(xino->file->f_dentry);
30975 + dname = &xino->file->f_dentry->d_name;
30976 + cur_xino = sbinfo->si_xib;
30978 + cur_parent = dget_parent(cur_xino->f_dentry);
30979 + cur_name = &cur_xino->f_dentry->d_name;
30980 + skip = (cur_parent == parent
30981 + && dname->len == cur_name->len
30982 + && !memcmp(dname->name, cur_name->name,
30984 + dput(cur_parent);
30990 + au_opt_set(sbinfo->si_mntflags, XINO);
30991 + dir = parent->d_inode;
30992 + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
30993 + /* mnt_want_write() is unnecessary here */
30994 + err = au_xino_set_xib(sb, xino->file);
30996 + err = au_xigen_set(sb, xino->file);
30998 + err = au_xino_set_br(sb, xino->file);
30999 + mutex_unlock(&dir->i_mutex);
31001 + goto out; /* success */
31004 + AuIOErr("failed creating xino(%d).\n", err);
31011 +/* ---------------------------------------------------------------------- */
31014 + * create a xinofile at the default place/path.
31016 +struct file *au_xino_def(struct super_block *sb)
31018 + struct file *file;
31020 + struct au_branch *br;
31021 + struct super_block *h_sb;
31022 + struct path path;
31023 + aufs_bindex_t bend, bindex, bwr;
31026 + bend = au_sbend(sb);
31028 + for (bindex = 0; bindex <= bend; bindex++) {
31029 + br = au_sbr(sb, bindex);
31030 + if (au_br_writable(br->br_perm)
31031 + && !au_test_fs_bad_xino(au_br_sb(br))) {
31038 + file = ERR_PTR(-ENOMEM);
31039 + page = (void *)__get_free_page(GFP_NOFS);
31040 + if (unlikely(!page))
31042 + path.mnt = au_br_mnt(br);
31043 + path.dentry = au_h_dptr(sb->s_root, bwr);
31044 + p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
31045 + file = (void *)p;
31046 + if (!IS_ERR(p)) {
31047 + strcat(p, "/" AUFS_XINO_FNAME);
31048 + AuDbg("%s\n", p);
31049 + file = au_xino_create(sb, p, /*silent*/0);
31050 + if (!IS_ERR(file))
31051 + au_xino_brid_set(sb, br->br_id);
31053 + free_page((unsigned long)page);
31055 + file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
31056 + if (IS_ERR(file))
31058 + h_sb = file->f_dentry->d_sb;
31059 + if (unlikely(au_test_fs_bad_xino(h_sb))) {
31060 + pr_err("xino doesn't support %s(%s)\n",
31061 + AUFS_XINO_DEFPATH, au_sbtype(h_sb));
31063 + file = ERR_PTR(-EINVAL);
31065 + if (!IS_ERR(file))
31066 + au_xino_brid_set(sb, -1);
31073 +/* ---------------------------------------------------------------------- */
31075 +int au_xino_path(struct seq_file *seq, struct file *file)
31079 + err = au_seq_path(seq, &file->f_path);
31080 + if (unlikely(err < 0))
31084 +#define Deleted "\\040(deleted)"
31085 + seq->count -= sizeof(Deleted) - 1;
31086 + AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
31087 + sizeof(Deleted) - 1));
31093 diff -urN /usr/share/empty/include/linux/aufs_type.h linux/include/linux/aufs_type.h
31094 --- /usr/share/empty/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
31095 +++ linux/include/linux/aufs_type.h 2013-07-06 13:20:47.760198800 +0200
31098 + * Copyright (C) 2012-2013 Junjiro R. Okajima
31100 + * This program, aufs is free software; you can redistribute it and/or modify
31101 + * it under the terms of the GNU General Public License as published by
31102 + * the Free Software Foundation; either version 2 of the License, or
31103 + * (at your option) any later version.
31105 + * This program is distributed in the hope that it will be useful,
31106 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31107 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31108 + * GNU General Public License for more details.
31110 + * You should have received a copy of the GNU General Public License
31111 + * along with this program; if not, write to the Free Software
31112 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31115 +#include <uapi/linux/aufs_type.h>
31116 diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
31117 --- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
31118 +++ linux/include/uapi/linux/aufs_type.h 2013-07-30 22:42:55.842946719 +0200
31121 + * Copyright (C) 2005-2013 Junjiro R. Okajima
31123 + * This program, aufs is free software; you can redistribute it and/or modify
31124 + * it under the terms of the GNU General Public License as published by
31125 + * the Free Software Foundation; either version 2 of the License, or
31126 + * (at your option) any later version.
31128 + * This program is distributed in the hope that it will be useful,
31129 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31130 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31131 + * GNU General Public License for more details.
31133 + * You should have received a copy of the GNU General Public License
31134 + * along with this program; if not, write to the Free Software
31135 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31138 +#ifndef __AUFS_TYPE_H__
31139 +#define __AUFS_TYPE_H__
31141 +#define AUFS_NAME "aufs"
31145 + * define it before including all other headers.
31146 + * sched.h may use pr_* macros before defining "current", so define the
31147 + * no-current version first, and re-define later.
31149 +#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
31150 +#include <linux/sched.h>
31152 +#define pr_fmt(fmt) \
31153 + AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
31154 + (int)sizeof(current->comm), current->comm, current->pid
31156 +#include <stdint.h>
31157 +#include <sys/types.h>
31158 +#endif /* __KERNEL__ */
31160 +#include <linux/limits.h>
31162 +#define AUFS_VERSION "3.10-20130722"
31164 +/* todo? move this to linux-2.6.19/include/magic.h */
31165 +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
31167 +/* ---------------------------------------------------------------------- */
31169 +#ifdef CONFIG_AUFS_BRANCH_MAX_127
31170 +typedef int8_t aufs_bindex_t;
31171 +#define AUFS_BRANCH_MAX 127
31173 +typedef int16_t aufs_bindex_t;
31174 +#ifdef CONFIG_AUFS_BRANCH_MAX_511
31175 +#define AUFS_BRANCH_MAX 511
31176 +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
31177 +#define AUFS_BRANCH_MAX 1023
31178 +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
31179 +#define AUFS_BRANCH_MAX 32767
31184 +#ifndef AUFS_BRANCH_MAX
31185 +#error unknown CONFIG_AUFS_BRANCH_MAX value
31187 +#endif /* __KERNEL__ */
31189 +/* ---------------------------------------------------------------------- */
31191 +#define AUFS_FSTYPE AUFS_NAME
31193 +#define AUFS_ROOT_INO 2
31194 +#define AUFS_FIRST_INO 11
31196 +#define AUFS_WH_PFX ".wh."
31197 +#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
31198 +#define AUFS_WH_TMP_LEN 4
31199 +/* a limit for rmdir/rename a dir and copyup */
31200 +#define AUFS_MAX_NAMELEN (NAME_MAX \
31201 + - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
31203 + - AUFS_WH_TMP_LEN) /* hex */
31204 +#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
31205 +#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
31206 +#define AUFS_XINO_TRUNC_INIT 64 /* blocks */
31207 +#define AUFS_XINO_TRUNC_STEP 4 /* blocks */
31208 +#define AUFS_DIRWH_DEF 3
31209 +#define AUFS_RDCACHE_DEF 10 /* seconds */
31210 +#define AUFS_RDCACHE_MAX 3600 /* seconds */
31211 +#define AUFS_RDBLK_DEF 512 /* bytes */
31212 +#define AUFS_RDHASH_DEF 32
31213 +#define AUFS_WKQ_NAME AUFS_NAME "d"
31214 +#define AUFS_MFS_DEF_SEC 30 /* seconds */
31215 +#define AUFS_MFS_MAX_SEC 3600 /* seconds */
31216 +#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
31218 +/* pseudo-link maintenace under /proc */
31219 +#define AUFS_PLINK_MAINT_NAME "plink_maint"
31220 +#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
31221 +#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
31223 +#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
31224 +#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
31226 +#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
31227 +#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
31228 +#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
31230 +/* doubly whiteouted */
31231 +#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
31232 +#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
31233 +#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
31235 +/* branch permissions and attributes */
31236 +#define AUFS_BRPERM_RW "rw"
31237 +#define AUFS_BRPERM_RO "ro"
31238 +#define AUFS_BRPERM_RR "rr"
31239 +#define AUFS_BRRATTR_WH "wh"
31240 +#define AUFS_BRWATTR_NLWH "nolwh"
31241 +#define AUFS_BRATTR_UNPIN "unpin"
31243 +/* ---------------------------------------------------------------------- */
31247 + /* readdir in userspace */
31251 + /* pathconf wrapper */
31258 +/* borrowed from linux/include/linux/kernel.h */
31260 +#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
31261 +#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
31264 +/* borrowed from linux/include/linux/compiler-gcc3.h */
31266 +#define __aligned(x) __attribute__((aligned(x)))
31271 +#define __packed __attribute__((packed))
31275 +struct au_rdu_cookie {
31280 + uint32_t generation;
31283 +struct au_rdu_ent {
31292 +static inline int au_rdu_len(int nlen)
31294 + /* include the terminating NULL */
31295 + return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
31296 + sizeof(uint64_t));
31299 +union au_rdu_ent_ul {
31300 + struct au_rdu_ent __user *e;
31312 + uint64_t sz; /* AuCtl_RDU */
31313 + uint64_t nent; /* AuCtl_RDU_INO */
31315 + union au_rdu_ent_ul ent;
31316 + uint16_t verify[AufsCtlRduV_End];
31318 + /* input/output */
31322 + union au_rdu_ent_ul tail;
31323 + /* number of entries which were added in a single call */
31328 + struct au_rdu_cookie cookie;
31331 +/* ---------------------------------------------------------------------- */
31333 +struct aufs_wbr_fd {
31338 +/* ---------------------------------------------------------------------- */
31340 +struct aufs_ibusy {
31341 + uint64_t ino, h_ino;
31345 +/* ---------------------------------------------------------------------- */
31347 +#define AuCtlType 'A'
31348 +#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
31349 +#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
31350 +#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
31351 + struct aufs_wbr_fd)
31352 +#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
31354 +#endif /* __AUFS_TYPE_H__ */