]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-aufs3.patch
64d4a4b61b69c9c47e2d7d24e16a3459f79bfd16
[packages/kernel.git] / kernel-aufs3.patch
1 aufs3.7 kbuild patch
2
3 diff --git a/fs/Kconfig b/fs/Kconfig
4 index f95ae3a..6d8a9a5 100644
5 --- a/fs/Kconfig
6 +++ b/fs/Kconfig
7 @@ -220,6 +220,7 @@ source "fs/pstore/Kconfig"
8  source "fs/sysv/Kconfig"
9  source "fs/ufs/Kconfig"
10  source "fs/exofs/Kconfig"
11 +source "fs/aufs/Kconfig"
12  
13  endif # MISC_FILESYSTEMS
14  
15 diff --git a/fs/Makefile b/fs/Makefile
16 index 1d7af79..06db6eb 100644
17 --- a/fs/Makefile
18 +++ b/fs/Makefile
19 @@ -126,3 +126,4 @@ obj-$(CONFIG_GFS2_FS)           += gfs2/
20  obj-y                          += exofs/ # Multiple modules
21  obj-$(CONFIG_CEPH_FS)          += ceph/
22  obj-$(CONFIG_PSTORE)           += pstore/
23 +obj-$(CONFIG_AUFS_FS)           += aufs/
24 aufs3.7 base patch
25
26 diff --git a/fs/file_table.c b/fs/file_table.c
27 index a72bf9d..dac6792 100644
28 --- a/fs/file_table.c
29 +++ b/fs/file_table.c
30 @@ -36,7 +36,7 @@ struct files_stat_struct files_stat = {
31         .max_files = NR_FILE
32  };
33  
34 -DEFINE_STATIC_LGLOCK(files_lglock);
35 +DEFINE_LGLOCK(files_lglock);
36  
37  /* SLAB cache for file structures */
38  static struct kmem_cache *filp_cachep __read_mostly;
39 diff --git a/fs/inode.c b/fs/inode.c
40 index 64999f1..ad73fc3 100644
41 --- a/fs/inode.c
42 +++ b/fs/inode.c
43 @@ -1503,7 +1503,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
44   * This does the actual work of updating an inodes time or version.  Must have
45   * had called mnt_want_write() before calling this.
46   */
47 -static int update_time(struct inode *inode, struct timespec *time, int flags)
48 +int update_time(struct inode *inode, struct timespec *time, int flags)
49  {
50         if (inode->i_op->update_time)
51                 return inode->i_op->update_time(inode, time, flags);
52 diff --git a/fs/splice.c b/fs/splice.c
53 index 13e5b47..f185c6c 100644
54 --- a/fs/splice.c
55 +++ b/fs/splice.c
56 @@ -1093,8 +1093,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
57  /*
58   * Attempt to initiate a splice from pipe to file.
59   */
60 -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
61 -                          loff_t *ppos, size_t len, unsigned int flags)
62 +long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
63 +                   loff_t *ppos, size_t len, unsigned int flags)
64  {
65         ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
66                                 loff_t *, size_t, unsigned int);
67 @@ -1121,9 +1121,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
68  /*
69   * Attempt to initiate a splice from a file to a pipe.
70   */
71 -static long do_splice_to(struct file *in, loff_t *ppos,
72 -                        struct pipe_inode_info *pipe, size_t len,
73 -                        unsigned int flags)
74 +long do_splice_to(struct file *in, loff_t *ppos,
75 +                 struct pipe_inode_info *pipe, size_t len,
76 +                 unsigned int flags)
77  {
78         ssize_t (*splice_read)(struct file *, loff_t *,
79                                struct pipe_inode_info *, size_t, unsigned int);
80 diff --git a/include/linux/fs.h b/include/linux/fs.h
81 index 75fe9a1..70a766ae 100644
82 --- a/include/linux/fs.h
83 +++ b/include/linux/fs.h
84 @@ -2553,6 +2553,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
85  extern int inode_newsize_ok(const struct inode *, loff_t offset);
86  extern void setattr_copy(struct inode *inode, const struct iattr *attr);
87  
88 +extern int update_time(struct inode *, struct timespec *, int);
89  extern int file_update_time(struct file *file);
90  
91  extern int generic_show_options(struct seq_file *m, struct dentry *root);
92 diff --git a/include/linux/splice.h b/include/linux/splice.h
93 index 09a545a..1ac5727 100644
94 --- a/include/linux/splice.h
95 +++ b/include/linux/splice.h
96 @@ -91,4 +91,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
97  extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
98  
99  extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
100 +
101 +extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
102 +                          loff_t *ppos, size_t len, unsigned int flags);
103 +extern long do_splice_to(struct file *in, loff_t *ppos,
104 +                        struct pipe_inode_info *pipe, size_t len,
105 +                        unsigned int flags);
106  #endif
107 aufs3.7 standalone patch
108
109 diff --git a/fs/file_table.c b/fs/file_table.c
110 index dac6792..e3f2c15 100644
111 --- a/fs/file_table.c
112 +++ b/fs/file_table.c
113 @@ -37,6 +37,7 @@ struct files_stat_struct files_stat = {
114  };
115  
116  DEFINE_LGLOCK(files_lglock);
117 +EXPORT_SYMBOL(files_lglock);
118  
119  /* SLAB cache for file structures */
120  static struct kmem_cache *filp_cachep __read_mostly;
121 @@ -403,6 +404,8 @@ void file_sb_list_del(struct file *file)
122         }
123  }
124  
125 +EXPORT_SYMBOL(file_sb_list_del);
126 +
127  #ifdef CONFIG_SMP
128  
129  /*
130 diff --git a/fs/inode.c b/fs/inode.c
131 index ad73fc3..108ff2b 100644
132 --- a/fs/inode.c
133 +++ b/fs/inode.c
134 @@ -56,6 +56,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
135  static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
136  
137  __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
138 +EXPORT_SYMBOL(inode_sb_list_lock);
139  
140  /*
141   * Empty aops. Can be used for the cases where the user does not
142 @@ -1519,6 +1520,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
143         mark_inode_dirty_sync(inode);
144         return 0;
145  }
146 +EXPORT_SYMBOL(update_time);
147  
148  /**
149   *     touch_atime     -       update the access time
150 diff --git a/fs/namespace.c b/fs/namespace.c
151 index 2496062..3e66a90 100644
152 --- a/fs/namespace.c
153 +++ b/fs/namespace.c
154 @@ -50,6 +50,7 @@ EXPORT_SYMBOL_GPL(fs_kobj);
155   * tree or hash is modified or when a vfsmount structure is modified.
156   */
157  DEFINE_BRLOCK(vfsmount_lock);
158 +EXPORT_SYMBOL(vfsmount_lock);
159  
160  static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
161  {
162 @@ -1401,6 +1402,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
163         }
164         return 0;
165  }
166 +EXPORT_SYMBOL(iterate_mounts);
167  
168  static void cleanup_group_ids(struct mount *mnt, struct mount *end)
169  {
170 diff --git a/fs/notify/group.c b/fs/notify/group.c
171 index 63fc294..6f4adca 100644
172 --- a/fs/notify/group.c
173 +++ b/fs/notify/group.c
174 @@ -22,6 +22,7 @@
175  #include <linux/srcu.h>
176  #include <linux/rculist.h>
177  #include <linux/wait.h>
178 +#include <linux/module.h>
179  
180  #include <linux/fsnotify_backend.h>
181  #include "fsnotify.h"
182 @@ -70,6 +71,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
183         if (atomic_dec_and_test(&group->refcnt))
184                 fsnotify_destroy_group(group);
185  }
186 +EXPORT_SYMBOL(fsnotify_put_group);
187  
188  /*
189   * Create a new fsnotify_group and hold a reference for the group returned.
190 @@ -102,3 +104,4 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
191  
192         return group;
193  }
194 +EXPORT_SYMBOL(fsnotify_alloc_group);
195 diff --git a/fs/notify/mark.c b/fs/notify/mark.c
196 index f104d56..54f36db 100644
197 --- a/fs/notify/mark.c
198 +++ b/fs/notify/mark.c
199 @@ -112,6 +112,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
200         if (atomic_dec_and_test(&mark->refcnt))
201                 mark->free_mark(mark);
202  }
203 +EXPORT_SYMBOL(fsnotify_put_mark);
204  
205  /*
206   * Any time a mark is getting freed we end up here.
207 @@ -191,6 +192,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
208         if (unlikely(atomic_dec_and_test(&group->num_marks)))
209                 fsnotify_final_destroy_group(group);
210  }
211 +EXPORT_SYMBOL(fsnotify_destroy_mark);
212  
213  void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
214  {
215 @@ -278,6 +280,7 @@ err:
216  
217         return ret;
218  }
219 +EXPORT_SYMBOL(fsnotify_add_mark);
220  
221  /*
222   * clear any marks in a group in which mark->flags & flags is true
223 @@ -333,6 +336,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
224         atomic_set(&mark->refcnt, 1);
225         mark->free_mark = free_mark;
226  }
227 +EXPORT_SYMBOL(fsnotify_init_mark);
228  
229  static int fsnotify_mark_destroy(void *ignored)
230  {
231 diff --git a/fs/open.c b/fs/open.c
232 index 59071f5..7e4c856 100644
233 --- a/fs/open.c
234 +++ b/fs/open.c
235 @@ -60,6 +60,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
236         mutex_unlock(&dentry->d_inode->i_mutex);
237         return ret;
238  }
239 +EXPORT_SYMBOL(do_truncate);
240  
241  static long do_sys_truncate(const char __user *pathname, loff_t length)
242  {
243 diff --git a/fs/splice.c b/fs/splice.c
244 index f185c6c..f3d89da 100644
245 --- a/fs/splice.c
246 +++ b/fs/splice.c
247 @@ -1117,6 +1117,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
248  
249         return splice_write(pipe, out, ppos, len, flags);
250  }
251 +EXPORT_SYMBOL(do_splice_from);
252  
253  /*
254   * Attempt to initiate a splice from a file to a pipe.
255 @@ -1143,6 +1144,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
256  
257         return splice_read(in, ppos, pipe, len, flags);
258  }
259 +EXPORT_SYMBOL(do_splice_to);
260  
261  /**
262   * splice_direct_to_actor - splices data directly between two non-pipes
263 diff --git a/security/commoncap.c b/security/commoncap.c
264 index 6dbae46..9f4f29a 100644
265 --- a/security/commoncap.c
266 +++ b/security/commoncap.c
267 @@ -979,9 +979,11 @@ int cap_mmap_addr(unsigned long addr)
268         }
269         return ret;
270  }
271 +EXPORT_SYMBOL(cap_mmap_addr);
272  
273  int cap_mmap_file(struct file *file, unsigned long reqprot,
274                   unsigned long prot, unsigned long flags)
275  {
276         return 0;
277  }
278 +EXPORT_SYMBOL(cap_mmap_file);
279 diff --git a/security/device_cgroup.c b/security/device_cgroup.c
280 index b08d20c..a90420b 100644
281 --- a/security/device_cgroup.c
282 +++ b/security/device_cgroup.c
283 @@ -7,6 +7,7 @@
284  #include <linux/device_cgroup.h>
285  #include <linux/cgroup.h>
286  #include <linux/ctype.h>
287 +#include <linux/export.h>
288  #include <linux/list.h>
289  #include <linux/uaccess.h>
290  #include <linux/seq_file.h>
291 @@ -617,6 +618,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
292         return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
293                         access);
294  }
295 +EXPORT_SYMBOL(__devcgroup_inode_permission);
296  
297  int devcgroup_inode_mknod(int mode, dev_t dev)
298  {
299 diff --git a/security/security.c b/security/security.c
300 index 8dcd4ae..6efe561 100644
301 --- a/security/security.c
302 +++ b/security/security.c
303 @@ -396,6 +396,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
304                 return 0;
305         return security_ops->path_rmdir(dir, dentry);
306  }
307 +EXPORT_SYMBOL(security_path_rmdir);
308  
309  int security_path_unlink(struct path *dir, struct dentry *dentry)
310  {
311 @@ -412,6 +413,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
312                 return 0;
313         return security_ops->path_symlink(dir, dentry, old_name);
314  }
315 +EXPORT_SYMBOL(security_path_symlink);
316  
317  int security_path_link(struct dentry *old_dentry, struct path *new_dir,
318                        struct dentry *new_dentry)
319 @@ -420,6 +422,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
320                 return 0;
321         return security_ops->path_link(old_dentry, new_dir, new_dentry);
322  }
323 +EXPORT_SYMBOL(security_path_link);
324  
325  int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
326                          struct path *new_dir, struct dentry *new_dentry)
327 @@ -438,6 +441,7 @@ int security_path_truncate(struct path *path)
328                 return 0;
329         return security_ops->path_truncate(path);
330  }
331 +EXPORT_SYMBOL(security_path_truncate);
332  
333  int security_path_chmod(struct path *path, umode_t mode)
334  {
335 @@ -445,6 +449,7 @@ int security_path_chmod(struct path *path, umode_t mode)
336                 return 0;
337         return security_ops->path_chmod(path, mode);
338  }
339 +EXPORT_SYMBOL(security_path_chmod);
340  
341  int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
342  {
343 @@ -452,6 +457,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
344                 return 0;
345         return security_ops->path_chown(path, uid, gid);
346  }
347 +EXPORT_SYMBOL(security_path_chown);
348  
349  int security_path_chroot(struct path *path)
350  {
351 @@ -528,6 +534,7 @@ int security_inode_readlink(struct dentry *dentry)
352                 return 0;
353         return security_ops->inode_readlink(dentry);
354  }
355 +EXPORT_SYMBOL(security_inode_readlink);
356  
357  int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
358  {
359 @@ -542,6 +549,7 @@ int security_inode_permission(struct inode *inode, int mask)
360                 return 0;
361         return security_ops->inode_permission(inode, mask);
362  }
363 +EXPORT_SYMBOL(security_inode_permission);
364  
365  int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
366  {
367 @@ -663,6 +671,7 @@ int security_file_permission(struct file *file, int mask)
368  
369         return fsnotify_perm(file, mask);
370  }
371 +EXPORT_SYMBOL(security_file_permission);
372  
373  int security_file_alloc(struct file *file)
374  {
375 @@ -723,6 +732,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
376                 return ret;
377         return ima_file_mmap(file, prot);
378  }
379 +EXPORT_SYMBOL(security_mmap_file);
380  
381  int security_mmap_addr(unsigned long addr)
382  {
383 diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
384 --- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs     1970-01-01 01:00:00.000000000 +0100
385 +++ linux/Documentation/ABI/testing/debugfs-aufs        2012-08-26 08:39:00.753841216 +0200
386 @@ -0,0 +1,37 @@
387 +What:          /debug/aufs/si_<id>/
388 +Date:          March 2009
389 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
390 +Description:
391 +               Under /debug/aufs, a directory named si_<id> is created
392 +               per aufs mount, where <id> is a unique id generated
393 +               internally.
394 +
395 +What:          /debug/aufs/si_<id>/xib
396 +Date:          March 2009
397 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
398 +Description:
399 +               It shows the consumed blocks by xib (External Inode Number
400 +               Bitmap), its block size and file size.
401 +               When the aufs mount option 'noxino' is specified, it
402 +               will be empty. About XINO files, see the aufs manual.
403 +
404 +What:          /debug/aufs/si_<id>/xino0, xino1 ... xinoN
405 +Date:          March 2009
406 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
407 +Description:
408 +               It shows the consumed blocks by xino (External Inode Number
409 +               Translation Table), its link count, block size and file
410 +               size.
411 +               When the aufs mount option 'noxino' is specified, it
412 +               will be empty. About XINO files, see the aufs manual.
413 +
414 +What:          /debug/aufs/si_<id>/xigen
415 +Date:          March 2009
416 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
417 +Description:
418 +               It shows the consumed blocks by xigen (External Inode
419 +               Generation Table), its block size and file size.
420 +               If CONFIG_AUFS_EXPORT is disabled, this entry will not
421 +               be created.
422 +               When the aufs mount option 'noxino' is specified, it
423 +               will be empty. About XINO files, see the aufs manual.
424 diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
425 --- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs       1970-01-01 01:00:00.000000000 +0100
426 +++ linux/Documentation/ABI/testing/sysfs-aufs  2012-08-26 08:39:00.753841216 +0200
427 @@ -0,0 +1,24 @@
428 +What:          /sys/fs/aufs/si_<id>/
429 +Date:          March 2009
430 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
431 +Description:
432 +               Under /sys/fs/aufs, a directory named si_<id> is created
433 +               per aufs mount, where <id> is a unique id generated
434 +               internally.
435 +
436 +What:          /sys/fs/aufs/si_<id>/br0, br1 ... brN
437 +Date:          March 2009
438 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
439 +Description:
440 +               It shows the abolute path of a member directory (which
441 +               is called branch) in aufs, and its permission.
442 +
443 +What:          /sys/fs/aufs/si_<id>/xi_path
444 +Date:          March 2009
445 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
446 +Description:
447 +               It shows the abolute path of XINO (External Inode Number
448 +               Bitmap, Translation Table and Generation Table) file
449 +               even if it is the default path.
450 +               When the aufs mount option 'noxino' is specified, it
451 +               will be empty. About XINO files, see the aufs manual.
452 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
453 --- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt  1970-01-01 01:00:00.000000000 +0100
454 +++ linux/Documentation/filesystems/aufs/design/01intro.txt     2013-01-11 19:46:12.632614518 +0100
455 @@ -0,0 +1,162 @@
456 +
457 +# Copyright (C) 2005-2013 Junjiro R. Okajima
458 +# 
459 +# This program is free software; you can redistribute it and/or modify
460 +# it under the terms of the GNU General Public License as published by
461 +# the Free Software Foundation; either version 2 of the License, or
462 +# (at your option) any later version.
463 +# 
464 +# This program is distributed in the hope that it will be useful,
465 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
466 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
467 +# GNU General Public License for more details.
468 +# 
469 +# You should have received a copy of the GNU General Public License
470 +# along with this program; if not, write to the Free Software
471 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
472 +
473 +Introduction
474 +----------------------------------------
475 +
476 +aufs [ei ju: ef es] | [a u f s]
477 +1. abbrev. for "advanced multi-layered unification filesystem".
478 +2. abbrev. for "another unionfs".
479 +3. abbrev. for "auf das" in German which means "on the" in English.
480 +   Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
481 +   But "Filesystem aufs Filesystem" is hard to understand.
482 +
483 +AUFS is a filesystem with features:
484 +- multi layered stackable unification filesystem, the member directory
485 +  is called as a branch.
486 +- branch permission and attribute, 'readonly', 'real-readonly',
487 +  'readwrite', 'whiteout-able', 'link-able whiteout' and their
488 +  combination.
489 +- internal "file copy-on-write".
490 +- logical deletion, whiteout.
491 +- dynamic branch manipulation, adding, deleting and changing permission.
492 +- allow bypassing aufs, user's direct branch access.
493 +- external inode number translation table and bitmap which maintains the
494 +  persistent aufs inode number.
495 +- seekable directory, including NFS readdir.
496 +- file mapping, mmap and sharing pages.
497 +- pseudo-link, hardlink over branches.
498 +- loopback mounted filesystem as a branch.
499 +- several policies to select one among multiple writable branches.
500 +- revert a single systemcall when an error occurs in aufs.
501 +- and more...
502 +
503 +
504 +Multi Layered Stackable Unification Filesystem
505 +----------------------------------------------------------------------
506 +Most people already knows what it is.
507 +It is a filesystem which unifies several directories and provides a
508 +merged single directory. When users access a file, the access will be
509 +passed/re-directed/converted (sorry, I am not sure which English word is
510 +correct) to the real file on the member filesystem. The member
511 +filesystem is called 'lower filesystem' or 'branch' and has a mode
512 +'readonly' and 'readwrite.' And the deletion for a file on the lower
513 +readonly branch is handled by creating 'whiteout' on the upper writable
514 +branch.
515 +
516 +On LKML, there have been discussions about UnionMount (Jan Blunck,
517 +Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
518 +different approaches to implement the merged-view.
519 +The former tries putting it into VFS, and the latter implements as a
520 +separate filesystem.
521 +(If I misunderstand about these implementations, please let me know and
522 +I shall correct it. Because it is a long time ago when I read their
523 +source files last time).
524 +
525 +UnionMount's approach will be able to small, but may be hard to share
526 +branches between several UnionMount since the whiteout in it is
527 +implemented in the inode on branch filesystem and always
528 +shared. According to Bharata's post, readdir does not seems to be
529 +finished yet.
530 +There are several missing features known in this implementations such as
531 +- for users, the inode number may change silently. eg. copy-up.
532 +- link(2) may break by copy-up.
533 +- read(2) may get an obsoleted filedata (fstat(2) too).
534 +- fcntl(F_SETLK) may be broken by copy-up.
535 +- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
536 +  open(O_RDWR).
537 +
538 +Unionfs has a longer history. When I started implementing a stacking filesystem
539 +(Aug 2005), it already existed. It has virtual super_block, inode,
540 +dentry and file objects and they have an array pointing lower same kind
541 +objects. After contributing many patches for Unionfs, I re-started my
542 +project AUFS (Jun 2006).
543 +
544 +In AUFS, the structure of filesystem resembles to Unionfs, but I
545 +implemented my own ideas, approaches and enhancements and it became
546 +totally different one.
547 +
548 +Comparing DM snapshot and fs based implementation
549 +- the number of bytes to be copied between devices is much smaller.
550 +- the type of filesystem must be one and only.
551 +- the fs must be writable, no readonly fs, even for the lower original
552 +  device. so the compression fs will not be usable. but if we use
553 +  loopback mount, we may address this issue.
554 +  for instance,
555 +       mount /cdrom/squashfs.img /sq
556 +       losetup /sq/ext2.img
557 +       losetup /somewhere/cow
558 +       dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
559 +- it will be difficult (or needs more operations) to extract the
560 +  difference between the original device and COW.
561 +- DM snapshot-merge may help a lot when users try merging. in the
562 +  fs-layer union, users will use rsync(1).
563 +
564 +
565 +Several characters/aspects of aufs
566 +----------------------------------------------------------------------
567 +
568 +Aufs has several characters or aspects.
569 +1. a filesystem, callee of VFS helper
570 +2. sub-VFS, caller of VFS helper for branches
571 +3. a virtual filesystem which maintains persistent inode number
572 +4. reader/writer of files on branches such like an application
573 +
574 +1. Callee of VFS Helper
575 +As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
576 +unlink(2) from an application reaches sys_unlink() kernel function and
577 +then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
578 +calls filesystem specific unlink operation. Actually aufs implements the
579 +unlink operation but it behaves like a redirector.
580 +
581 +2. Caller of VFS Helper for Branches
582 +aufs_unlink() passes the unlink request to the branch filesystem as if
583 +it were called from VFS. So the called unlink operation of the branch
584 +filesystem acts as usual. As a caller of VFS helper, aufs should handle
585 +every necessary pre/post operation for the branch filesystem.
586 +- acquire the lock for the parent dir on a branch
587 +- lookup in a branch
588 +- revalidate dentry on a branch
589 +- mnt_want_write() for a branch
590 +- vfs_unlink() for a branch
591 +- mnt_drop_write() for a branch
592 +- release the lock on a branch
593 +
594 +3. Persistent Inode Number
595 +One of the most important issue for a filesystem is to maintain inode
596 +numbers. This is particularly important to support exporting a
597 +filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
598 +backend block device for its own. But some storage is necessary to
599 +maintain inode number. It may be a large space and may not suit to keep
600 +in memory. Aufs rents some space from its first writable branch
601 +filesystem (by default) and creates file(s) on it. These files are
602 +created by aufs internally and removed soon (currently) keeping opened.
603 +Note: Because these files are removed, they are totally gone after
604 +      unmounting aufs. It means the inode numbers are not persistent
605 +      across unmount or reboot. I have a plan to make them really
606 +      persistent which will be important for aufs on NFS server.
607 +
608 +4. Read/Write Files Internally (copy-on-write)
609 +Because a branch can be readonly, when you write a file on it, aufs will
610 +"copy-up" it to the upper writable branch internally. And then write the
611 +originally requested thing to the file. Generally kernel doesn't
612 +open/read/write file actively. In aufs, even a single write may cause a
613 +internal "file copy". This behaviour is very similar to cp(1) command.
614 +
615 +Some people may think it is better to pass such work to user space
616 +helper, instead of doing in kernel space. Actually I am still thinking
617 +about it. But currently I have implemented it in kernel space.
618 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
619 --- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
620 +++ linux/Documentation/filesystems/aufs/design/02struct.txt    2013-01-11 19:46:12.632614518 +0100
621 @@ -0,0 +1,226 @@
622 +
623 +# Copyright (C) 2005-2013 Junjiro R. Okajima
624 +# 
625 +# This program is free software; you can redistribute it and/or modify
626 +# it under the terms of the GNU General Public License as published by
627 +# the Free Software Foundation; either version 2 of the License, or
628 +# (at your option) any later version.
629 +# 
630 +# This program is distributed in the hope that it will be useful,
631 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
632 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
633 +# GNU General Public License for more details.
634 +# 
635 +# You should have received a copy of the GNU General Public License
636 +# along with this program; if not, write to the Free Software
637 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
638 +
639 +Basic Aufs Internal Structure
640 +
641 +Superblock/Inode/Dentry/File Objects
642 +----------------------------------------------------------------------
643 +As like an ordinary filesystem, aufs has its own
644 +superblock/inode/dentry/file objects. All these objects have a
645 +dynamically allocated array and store the same kind of pointers to the
646 +lower filesystem, branch.
647 +For example, when you build a union with one readwrite branch and one
648 +readonly, mounted /au, /rw and /ro respectively.
649 +- /au = /rw + /ro
650 +- /ro/fileA exists but /rw/fileA
651 +
652 +Aufs lookup operation finds /ro/fileA and gets dentry for that. These
653 +pointers are stored in a aufs dentry. The array in aufs dentry will be,
654 +- [0] = NULL
655 +- [1] = /ro/fileA
656 +
657 +This style of an array is essentially same to the aufs
658 +superblock/inode/dentry/file objects.
659 +
660 +Because aufs supports manipulating branches, ie. add/delete/change
661 +dynamically, these objects has its own generation. When branches are
662 +changed, the generation in aufs superblock is incremented. And a
663 +generation in other object are compared when it is accessed.
664 +When a generation in other objects are obsoleted, aufs refreshes the
665 +internal array.
666 +
667 +
668 +Superblock
669 +----------------------------------------------------------------------
670 +Additionally aufs superblock has some data for policies to select one
671 +among multiple writable branches, XIB files, pseudo-links and kobject.
672 +See below in detail.
673 +About the policies which supports copy-down a directory, see policy.txt
674 +too.
675 +
676 +
677 +Branch and XINO(External Inode Number Translation Table)
678 +----------------------------------------------------------------------
679 +Every branch has its own xino (external inode number translation table)
680 +file. The xino file is created and unlinked by aufs internally. When two
681 +members of a union exist on the same filesystem, they share the single
682 +xino file.
683 +The struct of a xino file is simple, just a sequence of aufs inode
684 +numbers which is indexed by the lower inode number.
685 +In the above sample, assume the inode number of /ro/fileA is i111 and
686 +aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
687 +4(8) bytes at 111 * 4(8) bytes offset in the xino file.
688 +
689 +When the inode numbers are not contiguous, the xino file will be sparse
690 +which has a hole in it and doesn't consume as much disk space as it
691 +might appear. If your branch filesystem consumes disk space for such
692 +holes, then you should specify 'xino=' option at mounting aufs.
693 +
694 +Also a writable branch has three kinds of "whiteout bases". All these
695 +are existed when the branch is joined to aufs and the names are
696 +whiteout-ed doubly, so that users will never see their names in aufs
697 +hierarchy.
698 +1. a regular file which will be linked to all whiteouts.
699 +2. a directory to store a pseudo-link.
700 +3. a directory to store an "orphan-ed" file temporary.
701 +
702 +1. Whiteout Base
703 +   When you remove a file on a readonly branch, aufs handles it as a
704 +   logical deletion and creates a whiteout on the upper writable branch
705 +   as a hardlink of this file in order not to consume inode on the
706 +   writable branch.
707 +2. Pseudo-link Dir
708 +   See below, Pseudo-link.
709 +3. Step-Parent Dir
710 +   When "fileC" exists on the lower readonly branch only and it is
711 +   opened and removed with its parent dir, and then user writes
712 +   something into it, then aufs copies-up fileC to this
713 +   directory. Because there is no other dir to store fileC. After
714 +   creating a file under this dir, the file is unlinked.
715 +
716 +Because aufs supports manipulating branches, ie. add/delete/change
717 +dynamically, a branch has its own id. When the branch order changes, aufs
718 +finds the new index by searching the branch id.
719 +
720 +
721 +Pseudo-link
722 +----------------------------------------------------------------------
723 +Assume "fileA" exists on the lower readonly branch only and it is
724 +hardlinked to "fileB" on the branch. When you write something to fileA,
725 +aufs copies-up it to the upper writable branch. Additionally aufs
726 +creates a hardlink under the Pseudo-link Directory of the writable
727 +branch. The inode of a pseudo-link is kept in aufs super_block as a
728 +simple list. If fileB is read after unlinking fileA, aufs returns
729 +filedata from the pseudo-link instead of the lower readonly
730 +branch. Because the pseudo-link is based upon the inode, to keep the
731 +inode number by xino (see above) is important.
732 +
733 +All the hardlinks under the Pseudo-link Directory of the writable branch
734 +should be restored in a proper location later. Aufs provides a utility
735 +to do this. The userspace helpers executed at remounting and unmounting
736 +aufs by default.
737 +During this utility is running, it puts aufs into the pseudo-link
738 +maintenance mode. In this mode, only the process which began the
739 +maintenance mode (and its child processes) is allowed to operate in
740 +aufs. Some other processes which are not related to the pseudo-link will
741 +be allowed to run too, but the rest have to return an error or wait
742 +until the maintenance mode ends. If a process already acquires an inode
743 +mutex (in VFS), it has to return an error.
744 +
745 +
746 +XIB(external inode number bitmap)
747 +----------------------------------------------------------------------
748 +Addition to the xino file per a branch, aufs has an external inode number
749 +bitmap in a superblock object. It is also a file such like a xino file.
750 +It is a simple bitmap to mark whether the aufs inode number is in-use or
751 +not.
752 +To reduce the file I/O, aufs prepares a single memory page to cache xib.
753 +
754 +Aufs implements a feature to truncate/refresh both of xino and xib to
755 +reduce the number of consumed disk blocks for these files.
756 +
757 +
758 +Virtual or Vertical Dir, and Readdir in Userspace
759 +----------------------------------------------------------------------
760 +In order to support multiple layers (branches), aufs readdir operation
761 +constructs a virtual dir block on memory. For readdir, aufs calls
762 +vfs_readdir() internally for each dir on branches, merges their entries
763 +with eliminating the whiteout-ed ones, and sets it to file (dir)
764 +object. So the file object has its entry list until it is closed. The
765 +entry list will be updated when the file position is zero and becomes
766 +old. This decision is made in aufs automatically.
767 +
768 +The dynamically allocated memory block for the name of entries has a
769 +unit of 512 bytes (by default) and stores the names contiguously (no
770 +padding). Another block for each entry is handled by kmem_cache too.
771 +During building dir blocks, aufs creates hash list and judging whether
772 +the entry is whiteouted by its upper branch or already listed.
773 +The merged result is cached in the corresponding inode object and
774 +maintained by a customizable life-time option.
775 +
776 +Some people may call it can be a security hole or invite DoS attack
777 +since the opened and once readdir-ed dir (file object) holds its entry
778 +list and becomes a pressure for system memory. But I'd say it is similar
779 +to files under /proc or /sys. The virtual files in them also holds a
780 +memory page (generally) while they are opened. When an idea to reduce
781 +memory for them is introduced, it will be applied to aufs too.
782 +For those who really hate this situation, I've developed readdir(3)
783 +library which operates this merging in userspace. You just need to set
784 +LD_PRELOAD environment variable, and aufs will not consume no memory in
785 +kernel space for readdir(3).
786 +
787 +
788 +Workqueue
789 +----------------------------------------------------------------------
790 +Aufs sometimes requires privilege access to a branch. For instance,
791 +in copy-up/down operation. When a user process is going to make changes
792 +to a file which exists in the lower readonly branch only, and the mode
793 +of one of ancestor directories may not be writable by a user
794 +process. Here aufs copy-up the file with its ancestors and they may
795 +require privilege to set its owner/group/mode/etc.
796 +This is a typical case of a application character of aufs (see
797 +Introduction).
798 +
799 +Aufs uses workqueue synchronously for this case. It creates its own
800 +workqueue. The workqueue is a kernel thread and has privilege. Aufs
801 +passes the request to call mkdir or write (for example), and wait for
802 +its completion. This approach solves a problem of a signal handler
803 +simply.
804 +If aufs didn't adopt the workqueue and changed the privilege of the
805 +process, and if the mkdir/write call arises SIGXFSZ or other signal,
806 +then the user process might gain a privilege or the generated core file
807 +was owned by a superuser.
808 +
809 +Also aufs uses the system global workqueue ("events" kernel thread) too
810 +for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
811 +whiteout base and etc. This is unrelated to a privilege.
812 +Most of aufs operation tries acquiring a rw_semaphore for aufs
813 +superblock at the beginning, at the same time waits for the completion
814 +of all queued asynchronous tasks.
815 +
816 +
817 +Whiteout
818 +----------------------------------------------------------------------
819 +The whiteout in aufs is very similar to Unionfs's. That is represented
820 +by its filename. UnionMount takes an approach of a file mode, but I am
821 +afraid several utilities (find(1) or something) will have to support it.
822 +
823 +Basically the whiteout represents "logical deletion" which stops aufs to
824 +lookup further, but also it represents "dir is opaque" which also stop
825 +lookup.
826 +
827 +In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
828 +In order to make several functions in a single systemcall to be
829 +revertible, aufs adopts an approach to rename a directory to a temporary
830 +unique whiteouted name.
831 +For example, in rename(2) dir where the target dir already existed, aufs
832 +renames the target dir to a temporary unique whiteouted name before the
833 +actual rename on a branch and then handles other actions (make it opaque,
834 +update the attributes, etc). If an error happens in these actions, aufs
835 +simply renames the whiteouted name back and returns an error. If all are
836 +succeeded, aufs registers a function to remove the whiteouted unique
837 +temporary name completely and asynchronously to the system global
838 +workqueue.
839 +
840 +
841 +Copy-up
842 +----------------------------------------------------------------------
843 +It is a well-known feature or concept.
844 +When user modifies a file on a readonly branch, aufs operate "copy-up"
845 +internally and makes change to the new file on the upper writable branch.
846 +When the trigger systemcall does not update the timestamps of the parent
847 +dir, aufs reverts it after copy-up.
848 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
849 --- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
850 +++ linux/Documentation/filesystems/aufs/design/03lookup.txt    2013-01-11 19:46:12.632614518 +0100
851 @@ -0,0 +1,106 @@
852 +
853 +# Copyright (C) 2005-2013 Junjiro R. Okajima
854 +# 
855 +# This program is free software; you can redistribute it and/or modify
856 +# it under the terms of the GNU General Public License as published by
857 +# the Free Software Foundation; either version 2 of the License, or
858 +# (at your option) any later version.
859 +# 
860 +# This program is distributed in the hope that it will be useful,
861 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
862 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
863 +# GNU General Public License for more details.
864 +# 
865 +# You should have received a copy of the GNU General Public License
866 +# along with this program; if not, write to the Free Software
867 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
868 +
869 +Lookup in a Branch
870 +----------------------------------------------------------------------
871 +Since aufs has a character of sub-VFS (see Introduction), it operates
872 +lookup for branches as VFS does. It may be a heavy work. Generally
873 +speaking struct nameidata is a bigger structure and includes many
874 +information. But almost all lookup operation in aufs is the simplest
875 +case, ie. lookup only an entry directly connected to its parent. Digging
876 +down the directory hierarchy is unnecessary.
877 +
878 +VFS has a function lookup_one_len() for that use, but it is not usable
879 +for a branch filesystem which requires struct nameidata. So aufs
880 +implements a simple lookup wrapper function. When a branch filesystem
881 +allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
882 +a simplest nameidata and calls lookup_hash().
883 +Here aufs applies "a principle in NFSD", ie. if the filesystem supports
884 +NFS-export, then it has to support NULL as a nameidata parameter for
885 +->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
886 +aufs tests if ->s_export_op in the branch is NULL or not.
887 +
888 +When a branch is a remote filesystem, aufs basically trusts its
889 +->d_revalidate(), also aufs forces the hardest revalidate tests for
890 +them.
891 +For d_revalidate, aufs implements three levels of revalidate tests. See
892 +"Revalidate Dentry and UDBA" in detail.
893 +
894 +
895 +Loopback Mount
896 +----------------------------------------------------------------------
897 +Basically aufs supports any type of filesystem and block device for a
898 +branch (actually there are some exceptions). But it is prohibited to add
899 +a loopback mounted one whose backend file exists in a filesystem which is
900 +already added to aufs. The reason is to protect aufs from a recursive
901 +lookup. If it was allowed, the aufs lookup operation might re-enter a
902 +lookup for the loopback mounted branch in the same context, and will
903 +cause a deadlock.
904 +
905 +
906 +Revalidate Dentry and UDBA (User's Direct Branch Access)
907 +----------------------------------------------------------------------
908 +Generally VFS helpers re-validate a dentry as a part of lookup.
909 +0. digging down the directory hierarchy.
910 +1. lock the parent dir by its i_mutex.
911 +2. lookup the final (child) entry.
912 +3. revalidate it.
913 +4. call the actual operation (create, unlink, etc.)
914 +5. unlock the parent dir
915 +
916 +If the filesystem implements its ->d_revalidate() (step 3), then it is
917 +called. Actually aufs implements it and checks the dentry on a branch is
918 +still valid.
919 +But it is not enough. Because aufs has to release the lock for the
920 +parent dir on a branch at the end of ->lookup() (step 2) and
921 +->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
922 +held by VFS.
923 +If the file on a branch is changed directly, eg. bypassing aufs, after
924 +aufs released the lock, then the subsequent operation may cause
925 +something unpleasant result.
926 +
927 +This situation is a result of VFS architecture, ->lookup() and
928 +->d_revalidate() is separated. But I never say it is wrong. It is a good
929 +design from VFS's point of view. It is just not suitable for sub-VFS
930 +character in aufs.
931 +
932 +Aufs supports such case by three level of revalidation which is
933 +selectable by user.
934 +1. Simple Revalidate
935 +   Addition to the native flow in VFS's, confirm the child-parent
936 +   relationship on the branch just after locking the parent dir on the
937 +   branch in the "actual operation" (step 4). When this validation
938 +   fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
939 +   checks the validation of the dentry on branches.
940 +2. Monitor Changes Internally by Inotify/Fsnotify
941 +   Addition to above, in the "actual operation" (step 4) aufs re-lookup
942 +   the dentry on the branch, and returns EBUSY if it finds different
943 +   dentry.
944 +   Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
945 +   during it is in cache. When the event is notified, aufs registers a
946 +   function to kernel 'events' thread by schedule_work(). And the
947 +   function sets some special status to the cached aufs dentry and inode
948 +   private data. If they are not cached, then aufs has nothing to
949 +   do. When the same file is accessed through aufs (step 0-3) later,
950 +   aufs will detect the status and refresh all necessary data.
951 +   In this mode, aufs has to ignore the event which is fired by aufs
952 +   itself.
953 +3. No Extra Validation
954 +   This is the simplest test and doesn't add any additional revalidation
955 +   test, and skip therevalidatin in step 4. It is useful and improves
956 +   aufs performance when system surely hide the aufs branches from user,
957 +   by over-mounting something (or another method).
958 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
959 --- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
960 +++ linux/Documentation/filesystems/aufs/design/04branch.txt    2013-01-11 19:46:12.632614518 +0100
961 @@ -0,0 +1,76 @@
962 +
963 +# Copyright (C) 2005-2013 Junjiro R. Okajima
964 +# 
965 +# This program is free software; you can redistribute it and/or modify
966 +# it under the terms of the GNU General Public License as published by
967 +# the Free Software Foundation; either version 2 of the License, or
968 +# (at your option) any later version.
969 +# 
970 +# This program is distributed in the hope that it will be useful,
971 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
972 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
973 +# GNU General Public License for more details.
974 +# 
975 +# You should have received a copy of the GNU General Public License
976 +# along with this program; if not, write to the Free Software
977 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
978 +
979 +Branch Manipulation
980 +
981 +Since aufs supports dynamic branch manipulation, ie. add/remove a branch
982 +and changing its permission/attribute, there are a lot of works to do.
983 +
984 +
985 +Add a Branch
986 +----------------------------------------------------------------------
987 +o Confirm the adding dir exists outside of aufs, including loopback
988 +  mount.
989 +- and other various attributes...
990 +o Initialize the xino file and whiteout bases if necessary.
991 +  See struct.txt.
992 +
993 +o Check the owner/group/mode of the directory
994 +  When the owner/group/mode of the adding directory differs from the
995 +  existing branch, aufs issues a warning because it may impose a
996 +  security risk.
997 +  For example, when a upper writable branch has a world writable empty
998 +  top directory, a malicious user can create any files on the writable
999 +  branch directly, like copy-up and modify manually. If something like
1000 +  /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1001 +  writable branch, and the writable branch is world-writable, then a
1002 +  malicious guy may create /etc/passwd on the writable branch directly
1003 +  and the infected file will be valid in aufs.
1004 +  I am afraid it can be a security issue, but nothing to do except
1005 +  producing a warning.
1006 +
1007 +
1008 +Delete a Branch
1009 +----------------------------------------------------------------------
1010 +o Confirm the deleting branch is not busy
1011 +  To be general, there is one merit to adopt "remount" interface to
1012 +  manipulate branches. It is to discard caches. At deleting a branch,
1013 +  aufs checks the still cached (and connected) dentries and inodes. If
1014 +  there are any, then they are all in-use. An inode without its
1015 +  corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1016 +
1017 +  For the cached one, aufs checks whether the same named entry exists on
1018 +  other branches.
1019 +  If the cached one is a directory, because aufs provides a merged view
1020 +  to users, as long as one dir is left on any branch aufs can show the
1021 +  dir to users. In this case, the branch can be removed from aufs.
1022 +  Otherwise aufs rejects deleting the branch.
1023 +
1024 +  If any file on the deleting branch is opened by aufs, then aufs
1025 +  rejects deleting.
1026 +
1027 +
1028 +Modify the Permission of a Branch
1029 +----------------------------------------------------------------------
1030 +o Re-initialize or remove the xino file and whiteout bases if necessary.
1031 +  See struct.txt.
1032 +
1033 +o rw --> ro: Confirm the modifying branch is not busy
1034 +  Aufs rejects the request if any of these conditions are true.
1035 +  - a file on the branch is mmap-ed.
1036 +  - a regular file on the branch is opened for write and there is no
1037 +    same named entry on the upper branch.
1038 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1039 --- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt     1970-01-01 01:00:00.000000000 +0100
1040 +++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt        2013-01-11 19:46:12.632614518 +0100
1041 @@ -0,0 +1,65 @@
1042 +
1043 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1044 +# 
1045 +# This program is free software; you can redistribute it and/or modify
1046 +# it under the terms of the GNU General Public License as published by
1047 +# the Free Software Foundation; either version 2 of the License, or
1048 +# (at your option) any later version.
1049 +# 
1050 +# This program is distributed in the hope that it will be useful,
1051 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1052 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1053 +# GNU General Public License for more details.
1054 +# 
1055 +# You should have received a copy of the GNU General Public License
1056 +# along with this program; if not, write to the Free Software
1057 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1058 +
1059 +Policies to Select One among Multiple Writable Branches
1060 +----------------------------------------------------------------------
1061 +When the number of writable branch is more than one, aufs has to decide
1062 +the target branch for file creation or copy-up. By default, the highest
1063 +writable branch which has the parent (or ancestor) dir of the target
1064 +file is chosen (top-down-parent policy).
1065 +By user's request, aufs implements some other policies to select the
1066 +writable branch, for file creation two policies, round-robin and
1067 +most-free-space policies. For copy-up three policies, top-down-parent,
1068 +bottom-up-parent and bottom-up policies.
1069 +
1070 +As expected, the round-robin policy selects the branch in circular. When
1071 +you have two writable branches and creates 10 new files, 5 files will be
1072 +created for each branch. mkdir(2) systemcall is an exception. When you
1073 +create 10 new directories, all will be created on the same branch.
1074 +And the most-free-space policy selects the one which has most free
1075 +space among the writable branches. The amount of free space will be
1076 +checked by aufs internally, and users can specify its time interval.
1077 +
1078 +The policies for copy-up is more simple,
1079 +top-down-parent is equivalent to the same named on in create policy,
1080 +bottom-up-parent selects the writable branch where the parent dir
1081 +exists and the nearest upper one from the copyup-source,
1082 +bottom-up selects the nearest upper writable branch from the
1083 +copyup-source, regardless the existence of the parent dir.
1084 +
1085 +There are some rules or exceptions to apply these policies.
1086 +- If there is a readonly branch above the policy-selected branch and
1087 +  the parent dir is marked as opaque (a variation of whiteout), or the
1088 +  target (creating) file is whiteout-ed on the upper readonly branch,
1089 +  then the result of the policy is ignored and the target file will be
1090 +  created on the nearest upper writable branch than the readonly branch.
1091 +- If there is a writable branch above the policy-selected branch and
1092 +  the parent dir is marked as opaque or the target file is whiteouted
1093 +  on the branch, then the result of the policy is ignored and the target
1094 +  file will be created on the highest one among the upper writable
1095 +  branches who has diropq or whiteout. In case of whiteout, aufs removes
1096 +  it as usual.
1097 +- link(2) and rename(2) systemcalls are exceptions in every policy.
1098 +  They try selecting the branch where the source exists as possible
1099 +  since copyup a large file will take long time. If it can't be,
1100 +  ie. the branch where the source exists is readonly, then they will
1101 +  follow the copyup policy.
1102 +- There is an exception for rename(2) when the target exists.
1103 +  If the rename target exists, aufs compares the index of the branches
1104 +  where the source and the target exists and selects the higher
1105 +  one. If the selected branch is readonly, then aufs follows the
1106 +  copyup policy.
1107 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1108 --- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt   1970-01-01 01:00:00.000000000 +0100
1109 +++ linux/Documentation/filesystems/aufs/design/06mmap.txt      2013-01-11 19:46:12.632614518 +0100
1110 @@ -0,0 +1,47 @@
1111 +
1112 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1113 +# 
1114 +# This program is free software; you can redistribute it and/or modify
1115 +# it under the terms of the GNU General Public License as published by
1116 +# the Free Software Foundation; either version 2 of the License, or
1117 +# (at your option) any later version.
1118 +# 
1119 +# This program is distributed in the hope that it will be useful,
1120 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1121 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1122 +# GNU General Public License for more details.
1123 +# 
1124 +# You should have received a copy of the GNU General Public License
1125 +# along with this program; if not, write to the Free Software
1126 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1127 +
1128 +mmap(2) -- File Memory Mapping
1129 +----------------------------------------------------------------------
1130 +In aufs, the file-mapped pages are handled by a branch fs directly, no
1131 +interaction with aufs. It means aufs_mmap() calls the branch fs's
1132 +->mmap().
1133 +This approach is simple and good, but there is one problem.
1134 +Under /proc, several entries show the mmap-ped files by its path (with
1135 +device and inode number), and the printed path will be the path on the
1136 +branch fs's instead of virtual aufs's.
1137 +This is not a problem in most cases, but some utilities lsof(1) (and its
1138 +user) may expect the path on aufs.
1139 +
1140 +To address this issue, aufs adds a new member called vm_prfile in struct
1141 +vm_area_struct (and struct vm_region). The original vm_file points to
1142 +the file on the branch fs in order to handle everything correctly as
1143 +usual. The new vm_prfile points to a virtual file in aufs, and the
1144 +show-functions in procfs refers to vm_prfile if it is set.
1145 +Also we need to maintain several other places where touching vm_file
1146 +such like
1147 +- fork()/clone() copies vma and the reference count of vm_file is
1148 +  incremented.
1149 +- merging vma maintains the ref count too.
1150 +
1151 +This is not a good approach. It just faking the printed path. But it
1152 +leaves all behaviour around f_mapping unchanged. This is surely an
1153 +advantage.
1154 +Actually aufs had adopted another complicated approach which calls
1155 +generic_file_mmap() and handles struct vm_operations_struct. In this
1156 +approach, aufs met a hard problem and I could not solve it without
1157 +switching the approach.
1158 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1159 --- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
1160 +++ linux/Documentation/filesystems/aufs/design/07export.txt    2013-01-11 19:46:12.632614518 +0100
1161 @@ -0,0 +1,59 @@
1162 +
1163 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1164 +# 
1165 +# This program is free software; you can redistribute it and/or modify
1166 +# it under the terms of the GNU General Public License as published by
1167 +# the Free Software Foundation; either version 2 of the License, or
1168 +# (at your option) any later version.
1169 +# 
1170 +# This program is distributed in the hope that it will be useful,
1171 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1172 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1173 +# GNU General Public License for more details.
1174 +# 
1175 +# You should have received a copy of the GNU General Public License
1176 +# along with this program; if not, write to the Free Software
1177 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1178 +
1179 +Export Aufs via NFS
1180 +----------------------------------------------------------------------
1181 +Here is an approach.
1182 +- like xino/xib, add a new file 'xigen' which stores aufs inode
1183 +  generation.
1184 +- iget_locked(): initialize aufs inode generation for a new inode, and
1185 +  store it in xigen file.
1186 +- destroy_inode(): increment aufs inode generation and store it in xigen
1187 +  file. it is necessary even if it is not unlinked, because any data of
1188 +  inode may be changed by UDBA.
1189 +- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
1190 +  build file handle by
1191 +  + branch id (4 bytes)
1192 +  + superblock generation (4 bytes)
1193 +  + inode number (4 or 8 bytes)
1194 +  + parent dir inode number (4 or 8 bytes)
1195 +  + inode generation (4 bytes))
1196 +  + return value of exportfs_encode_fh() for the parent on a branch (4
1197 +    bytes)
1198 +  + file handle for a branch (by exportfs_encode_fh())
1199 +- fh_to_dentry():
1200 +  + find the index of a branch from its id in handle, and check it is
1201 +    still exist in aufs.
1202 +  + 1st level: get the inode number from handle and search it in cache.
1203 +  + 2nd level: if not found, get the parent inode number from handle and
1204 +    search it in cache. and then open the parent dir, find the matching
1205 +    inode number by vfs_readdir() and get its name, and call
1206 +    lookup_one_len() for the target dentry.
1207 +  + 3rd level: if the parent dir is not cached, call
1208 +    exportfs_decode_fh() for a branch and get the parent on a branch,
1209 +    build a pathname of it, convert it a pathname in aufs, call
1210 +    path_lookup(). now aufs gets a parent dir dentry, then handle it as
1211 +    the 2nd level.
1212 +  + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
1213 +    for every branch, but not itself. to get this, (currently) aufs
1214 +    searches in current->nsproxy->mnt_ns list. it may not be a good
1215 +    idea, but I didn't get other approach.
1216 +  + test the generation of the gotten inode.
1217 +- every inode operation: they may get EBUSY due to UDBA. in this case,
1218 +  convert it into ESTALE for NFSD.
1219 +- readdir(): call lockdep_on/off() because filldir in NFSD calls
1220 +  lookup_one_len(), vfs_getattr(), encode_fh() and others.
1221 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
1222 --- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt   1970-01-01 01:00:00.000000000 +0100
1223 +++ linux/Documentation/filesystems/aufs/design/08shwh.txt      2013-01-11 19:46:12.632614518 +0100
1224 @@ -0,0 +1,53 @@
1225 +
1226 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1227 +# 
1228 +# This program is free software; you can redistribute it and/or modify
1229 +# it under the terms of the GNU General Public License as published by
1230 +# the Free Software Foundation; either version 2 of the License, or
1231 +# (at your option) any later version.
1232 +# 
1233 +# This program is distributed in the hope that it will be useful,
1234 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1235 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1236 +# GNU General Public License for more details.
1237 +# 
1238 +# You should have received a copy of the GNU General Public License
1239 +# along with this program; if not, write to the Free Software
1240 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1241 +
1242 +Show Whiteout Mode (shwh)
1243 +----------------------------------------------------------------------
1244 +Generally aufs hides the name of whiteouts. But in some cases, to show
1245 +them is very useful for users. For instance, creating a new middle layer
1246 +(branch) by merging existing layers.
1247 +
1248 +(borrowing aufs1 HOW-TO from a user, Michael Towers)
1249 +When you have three branches,
1250 +- Bottom: 'system', squashfs (underlying base system), read-only
1251 +- Middle: 'mods', squashfs, read-only
1252 +- Top: 'overlay', ram (tmpfs), read-write
1253 +
1254 +The top layer is loaded at boot time and saved at shutdown, to preserve
1255 +the changes made to the system during the session.
1256 +When larger changes have been made, or smaller changes have accumulated,
1257 +the size of the saved top layer data grows. At this point, it would be
1258 +nice to be able to merge the two overlay branches ('mods' and 'overlay')
1259 +and rewrite the 'mods' squashfs, clearing the top layer and thus
1260 +restoring save and load speed.
1261 +
1262 +This merging is simplified by the use of another aufs mount, of just the
1263 +two overlay branches using the 'shwh' option.
1264 +# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
1265 +       aufs /livesys/merge_union
1266 +
1267 +A merged view of these two branches is then available at
1268 +/livesys/merge_union, and the new feature is that the whiteouts are
1269 +visible!
1270 +Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
1271 +writing to all branches. Also the default mode for all branches is 'ro'.
1272 +It is now possible to save the combined contents of the two overlay
1273 +branches to a new squashfs, e.g.:
1274 +# mksquashfs /livesys/merge_union /path/to/newmods.squash
1275 +
1276 +This new squashfs archive can be stored on the boot device and the
1277 +initramfs will use it to replace the old one at the next boot.
1278 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
1279 --- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt  1970-01-01 01:00:00.000000000 +0100
1280 +++ linux/Documentation/filesystems/aufs/design/10dynop.txt     2013-01-11 19:46:12.632614518 +0100
1281 @@ -0,0 +1,47 @@
1282 +
1283 +# Copyright (C) 2010-2013 Junjiro R. Okajima
1284 +#
1285 +# This program is free software; you can redistribute it and/or modify
1286 +# it under the terms of the GNU General Public License as published by
1287 +# the Free Software Foundation; either version 2 of the License, or
1288 +# (at your option) any later version.
1289 +#
1290 +# This program is distributed in the hope that it will be useful,
1291 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1292 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1293 +# GNU General Public License for more details.
1294 +#
1295 +# You should have received a copy of the GNU General Public License
1296 +# along with this program; if not, write to the Free Software
1297 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1298 +
1299 +Dynamically customizable FS operations
1300 +----------------------------------------------------------------------
1301 +Generally FS operations (struct inode_operations, struct
1302 +address_space_operations, struct file_operations, etc.) are defined as
1303 +"static const", but it never means that FS have only one set of
1304 +operation. Some FS have multiple sets of them. For instance, ext2 has
1305 +three sets, one for XIP, for NOBH, and for normal.
1306 +Since aufs overrides and redirects these operations, sometimes aufs has
1307 +to change its behaviour according to the branch FS type. More imporantly
1308 +VFS acts differently if a function (member in the struct) is set or
1309 +not. It means aufs should have several sets of operations and select one
1310 +among them according to the branch FS definition.
1311 +
1312 +In order to solve this problem and not to affect the behavour of VFS,
1313 +aufs defines these operations dynamically. For instance, aufs defines
1314 +aio_read function for struct file_operations, but it may not be set to
1315 +the file_operations. When the branch FS doesn't have it, aufs doesn't
1316 +set it to its file_operations while the function definition itself is
1317 +still alive. So the behaviour of io_submit(2) will not change, and it
1318 +will return an error when aio_read is not defined.
1319 +
1320 +The lifetime of these dynamically generated operation object is
1321 +maintained by aufs branch object. When the branch is removed from aufs,
1322 +the reference counter of the object is decremented. When it reaches
1323 +zero, the dynamically generated operation object will be freed.
1324 +
1325 +This approach is designed to support AIO (io_submit), Direcit I/O and
1326 +XIP mainly.
1327 +Currently this approach is applied to file_operations and
1328 +vm_operations_struct for regular files only.
1329 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
1330 --- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt   1970-01-01 01:00:00.000000000 +0100
1331 +++ linux/Documentation/filesystems/aufs/design/99plan.txt      2013-01-11 19:46:12.632614518 +0100
1332 @@ -0,0 +1,96 @@
1333 +
1334 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1335 +# 
1336 +# This program is free software; you can redistribute it and/or modify
1337 +# it under the terms of the GNU General Public License as published by
1338 +# the Free Software Foundation; either version 2 of the License, or
1339 +# (at your option) any later version.
1340 +# 
1341 +# This program is distributed in the hope that it will be useful,
1342 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1343 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1344 +# GNU General Public License for more details.
1345 +# 
1346 +# You should have received a copy of the GNU General Public License
1347 +# along with this program; if not, write to the Free Software
1348 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1349 +
1350 +Plan
1351 +
1352 +Restoring some features which was implemented in aufs1.
1353 +They were dropped in aufs2 in order to make source files simpler and
1354 +easier to be reviewed.
1355 +
1356 +
1357 +Test Only the Highest One for the Directory Permission (dirperm1 option)
1358 +----------------------------------------------------------------------
1359 +Let's try case study.
1360 +- aufs has two branches, upper readwrite and lower readonly.
1361 +  /au = /rw + /ro
1362 +- "dirA" exists under /ro, but /rw. and its mode is 0700.
1363 +- user invoked "chmod a+rx /au/dirA"
1364 +- then "dirA" becomes world readable?
1365 +
1366 +In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1367 +or it may be a natively readonly filesystem. If aufs respects the lower
1368 +branch, it should not respond readdir request from other users. But user
1369 +allowed it by chmod. Should really aufs rejects showing the entries
1370 +under /ro/dirA?
1371 +
1372 +To be honest, I don't have a best solution for this case. So I
1373 +implemented 'dirperm1' and 'nodirperm1' option in aufs1, and leave it to
1374 +users.
1375 +When dirperm1 is specified, aufs checks only the highest one for the
1376 +directory permission, and shows the entries. Otherwise, as usual, checks
1377 +every dir existing on all branches and rejects the request.
1378 +
1379 +As a side effect, dirperm1 option improves the performance of aufs
1380 +because the number of permission check is reduced.
1381 +
1382 +
1383 +Being Another Aufs's Readonly Branch (robr)
1384 +----------------------------------------------------------------------
1385 +Aufs1 allows aufs to be another aufs's readonly branch.
1386 +This feature was developed by a user's request. But it may not be used
1387 +currecnly.
1388 +
1389 +
1390 +Copy-up on Open (coo=)
1391 +----------------------------------------------------------------------
1392 +By default the internal copy-up is executed when it is really necessary.
1393 +It is not done when a file is opened for writing, but when write(2) is
1394 +done. Users who have many (over 100) branches want to know and analyse
1395 +when and what file is copied-up. To insert a new upper branch which
1396 +contains such files only may improve the performance of aufs.
1397 +
1398 +Aufs1 implemented "coo=none | leaf | all" option.
1399 +
1400 +
1401 +Refresh the Opened File (refrof)
1402 +----------------------------------------------------------------------
1403 +This option is implemented in aufs1 but incomplete.
1404 +
1405 +When user reads from a file, he expects to get its latest filedata
1406 +generally. If the file is removed and a new same named file is created,
1407 +the content he gets is unchanged, ie. the unlinked filedata.
1408 +
1409 +Let's try case study again.
1410 +- aufs has two branches.
1411 +  /au = /rw + /ro
1412 +- "fileA" exists under /ro, but /rw.
1413 +- user opened "/au/fileA".
1414 +- he or someone else inserts a branch (/new) between /rw and /ro.
1415 +  /au = /rw + /new + /ro
1416 +- the new branch has "fileA".
1417 +- user reads from the opened "fileA"
1418 +- which filedata should aufs return, from /ro or /new?
1419 +
1420 +Some people says it has to be "from /ro" and it is a semantics of Unix.
1421 +The others say it should be "from /new" because the file is not removed
1422 +and it is equivalent to the case of someone else modifies the file.
1423 +
1424 +Here again I don't have a best and final answer. I got an idea to
1425 +implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
1426 +Opened File) is specified (by default), aufs returns the filedata from
1427 +/new.
1428 +Otherwise from /new.
1429 diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
1430 --- /usr/share/empty/Documentation/filesystems/aufs/README      1970-01-01 01:00:00.000000000 +0100
1431 +++ linux/Documentation/filesystems/aufs/README 2013-01-11 19:46:28.699667650 +0100
1432 @@ -0,0 +1,333 @@
1433 +
1434 +Aufs3 -- advanced multi layered unification filesystem version 3.x
1435 +http://aufs.sf.net
1436 +Junjiro R. Okajima
1437 +
1438 +
1439 +0. Introduction
1440 +----------------------------------------
1441 +In the early days, aufs was entirely re-designed and re-implemented
1442 +Unionfs Version 1.x series. After many original ideas, approaches,
1443 +improvements and implementations, it becomes totally different from
1444 +Unionfs while keeping the basic features.
1445 +Recently, Unionfs Version 2.x series begin taking some of the same
1446 +approaches to aufs1's.
1447 +Unionfs is being developed by Professor Erez Zadok at Stony Brook
1448 +University and his team.
1449 +
1450 +Aufs3 supports linux-3.0 and later.
1451 +If you want older kernel version support, try aufs2-2.6.git or
1452 +aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
1453 +
1454 +Note: it becomes clear that "Aufs was rejected. Let's give it up."
1455 +According to Christoph Hellwig, linux rejects all union-type filesystems
1456 +but UnionMount.
1457 +<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
1458 +
1459 +
1460 +1. Features
1461 +----------------------------------------
1462 +- unite several directories into a single virtual filesystem. The member
1463 +  directory is called as a branch.
1464 +- you can specify the permission flags to the branch, which are 'readonly',
1465 +  'readwrite' and 'whiteout-able.'
1466 +- by upper writable branch, internal copyup and whiteout, files/dirs on
1467 +  readonly branch are modifiable logically.
1468 +- dynamic branch manipulation, add, del.
1469 +- etc...
1470 +
1471 +Also there are many enhancements in aufs1, such as:
1472 +- readdir(3) in userspace.
1473 +- keep inode number by external inode number table
1474 +- keep the timestamps of file/dir in internal copyup operation
1475 +- seekable directory, supporting NFS readdir.
1476 +- whiteout is hardlinked in order to reduce the consumption of inodes
1477 +  on branch
1478 +- do not copyup, nor create a whiteout when it is unnecessary
1479 +- revert a single systemcall when an error occurs in aufs
1480 +- remount interface instead of ioctl
1481 +- maintain /etc/mtab by an external command, /sbin/mount.aufs.
1482 +- loopback mounted filesystem as a branch
1483 +- kernel thread for removing the dir who has a plenty of whiteouts
1484 +- support copyup sparse file (a file which has a 'hole' in it)
1485 +- default permission flags for branches
1486 +- selectable permission flags for ro branch, whether whiteout can
1487 +  exist or not
1488 +- export via NFS.
1489 +- support <sysfs>/fs/aufs and <debugfs>/aufs.
1490 +- support multiple writable branches, some policies to select one
1491 +  among multiple writable branches.
1492 +- a new semantics for link(2) and rename(2) to support multiple
1493 +  writable branches.
1494 +- no glibc changes are required.
1495 +- pseudo hardlink (hardlink over branches)
1496 +- allow a direct access manually to a file on branch, e.g. bypassing aufs.
1497 +  including NFS or remote filesystem branch.
1498 +- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
1499 +- and more...
1500 +
1501 +Currently these features are dropped temporary from aufs3.
1502 +See design/08plan.txt in detail.
1503 +- test only the highest one for the directory permission (dirperm1)
1504 +- copyup on open (coo=)
1505 +- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
1506 +  (robr)
1507 +- statistics of aufs thread (/sys/fs/aufs/stat)
1508 +- delegation mode (dlgt)
1509 +  a delegation of the internal branch access to support task I/O
1510 +  accounting, which also supports Linux Security Modules (LSM) mainly
1511 +  for Suse AppArmor.
1512 +- intent.open/create (file open in a single lookup)
1513 +
1514 +Features or just an idea in the future (see also design/*.txt),
1515 +- reorder the branch index without del/re-add.
1516 +- permanent xino files for NFSD
1517 +- an option for refreshing the opened files after add/del branches
1518 +- 'move' policy for copy-up between two writable branches, after
1519 +  checking free space.
1520 +- light version, without branch manipulation. (unnecessary?)
1521 +- copyup in userspace
1522 +- inotify in userspace
1523 +- readv/writev
1524 +- xattr, acl
1525 +
1526 +
1527 +2. Download
1528 +----------------------------------------
1529 +There were three GIT trees for aufs3, aufs3-linux.git,
1530 +aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
1531 +"aufs-util.git."
1532 +While the aufs-util is always necessary, you need either of aufs3-linux
1533 +or aufs3-standalone.
1534 +
1535 +The aufs3-linux tree includes the whole linux mainline GIT tree,
1536 +git://git.kernel.org/.../torvalds/linux.git.
1537 +And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
1538 +build aufs3 as an external kernel module.
1539 +
1540 +On the other hand, the aufs3-standalone tree has only aufs source files
1541 +and necessary patches, and you can select CONFIG_AUFS_FS=m.
1542 +
1543 +You will find GIT branches whose name is in form of "aufs3.x" where "x"
1544 +represents the linux kernel version, "linux-3.x". For instance,
1545 +"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
1546 +"aufs3.x-rcN" branch.
1547 +
1548 +o aufs3-linux tree
1549 +$ git clone --reference /your/linux/git/tree \
1550 +       git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-linux.git \
1551 +       aufs3-linux.git
1552 +- if you don't have linux GIT tree, then remove "--reference ..."
1553 +$ cd aufs3-linux.git
1554 +$ git checkout origin/aufs3.0
1555 +
1556 +o aufs3-standalone tree
1557 +$ git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git \
1558 +       aufs3-standalone.git
1559 +$ cd aufs3-standalone.git
1560 +$ git checkout origin/aufs3.0
1561 +
1562 +o aufs-util tree
1563 +$ git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs-util.git \
1564 +       aufs-util.git
1565 +$ cd aufs-util.git
1566 +$ git checkout origin/aufs3.0
1567 +
1568 +Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
1569 +The minor version number, 'x' in '3.x', of aufs may not always
1570 +follow the minor version number of the kernel.
1571 +Because changes in the kernel that cause the use of a new
1572 +minor version number do not always require changes to aufs-util.
1573 +
1574 +Since aufs-util has its own minor version number, you may not be
1575 +able to find a GIT branch in aufs-util for your kernel's
1576 +exact minor version number.
1577 +In this case, you should git-checkout the branch for the
1578 +nearest lower number.
1579 +
1580 +For (an unreleased) example:
1581 +If you are using "linux-3.10" and the "aufs3.10" branch
1582 +does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
1583 +or something numerically smaller is the branch for your kernel.
1584 +
1585 +Also you can view all branches by
1586 +       $ git branch -a
1587 +
1588 +
1589 +3. Configuration and Compilation
1590 +----------------------------------------
1591 +Make sure you have git-checkout'ed the correct branch.
1592 +
1593 +For aufs3-linux tree,
1594 +- enable CONFIG_EXPERIMENTAL and CONFIG_AUFS_FS.
1595 +- set other aufs configurations if necessary.
1596 +
1597 +For aufs3-standalone tree,
1598 +There are several ways to build.
1599 +
1600 +1.
1601 +- apply ./aufs3-kbuild.patch to your kernel source files.
1602 +- apply ./aufs3-base.patch too.
1603 +- apply ./aufs3-proc_map.patch too, if you want to make /proc/PID/maps (and
1604 +  others including lsof(1)) show the file path on aufs instead of the
1605 +  path on the branch fs.
1606 +- apply ./aufs3-standalone.patch too, if you have a plan to set
1607 +  CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
1608 +- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
1609 +  kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
1610 +- enable CONFIG_EXPERIMENTAL and CONFIG_AUFS_FS, you can select either
1611 +  =m or =y.
1612 +- and build your kernel as usual.
1613 +- install the built kernel.
1614 +- install the header files too by "make headers_install" to the
1615 +  directory where you specify. By default, it is $PWD/usr.
1616 +  "make help" shows a brief note for headers_install.
1617 +- and reboot your system.
1618 +
1619 +2.
1620 +- module only (CONFIG_AUFS_FS=m).
1621 +- apply ./aufs3-base.patch to your kernel source files.
1622 +- apply ./aufs3-proc_map.patch too to your kernel source files,
1623 +  if you want to make /proc/PID/maps (and others including lsof(1)) show
1624 +  the file path on aufs instead of the path on the branch fs.
1625 +- apply ./aufs3-standalone.patch too.
1626 +- build your kernel, don't forget "make headers_install", and reboot.
1627 +- edit ./config.mk and set other aufs configurations if necessary.
1628 +  Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
1629 +  every aufs configurations.
1630 +- build the module by simple "make".
1631 +- you can specify ${KDIR} make variable which points to your kernel
1632 +  source tree.
1633 +- install the files
1634 +  + run "make install" to install the aufs module, or copy the built
1635 +    $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
1636 +  + run "make install_headers" (instead of headers_install) to install
1637 +    the modified aufs header file (you can specify DESTDIR which is
1638 +    available in aufs standalone version's Makefile only), or copy
1639 +    $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
1640 +    you like manually. By default, the target directory is $PWD/usr.
1641 +- no need to apply aufs3-kbuild.patch, nor copying source files to your
1642 +  kernel source tree.
1643 +
1644 +Note: The header file aufs_type.h is necessary to build aufs-util
1645 +      as well as "make headers_install" in the kernel source tree.
1646 +      headers_install is subject to be forgotten, but it is essentially
1647 +      necessary, not only for building aufs-util.
1648 +      You may not meet problems without headers_install in some older
1649 +      version though.
1650 +
1651 +And then,
1652 +- read README in aufs-util, build and install it
1653 +- note that your distribution may contain an obsoleted version of
1654 +  aufs_type.h in /usr/include/linux or something. When you build aufs
1655 +  utilities, make sure that your compiler refers the correct aufs header
1656 +  file which is built by "make headers_install."
1657 +- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
1658 +  then run "make install_ulib" too. And refer to the aufs manual in
1659 +  detail.
1660 +
1661 +
1662 +4. Usage
1663 +----------------------------------------
1664 +At first, make sure aufs-util are installed, and please read the aufs
1665 +manual, aufs.5 in aufs-util.git tree.
1666 +$ man -l aufs.5
1667 +
1668 +And then,
1669 +$ mkdir /tmp/rw /tmp/aufs
1670 +# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
1671 +
1672 +Here is another example. The result is equivalent.
1673 +# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
1674 +  Or
1675 +# mount -t aufs -o br:/tmp/rw none /tmp/aufs
1676 +# mount -o remount,append:${HOME} /tmp/aufs
1677 +
1678 +Then, you can see whole tree of your home dir through /tmp/aufs. If
1679 +you modify a file under /tmp/aufs, the one on your home directory is
1680 +not affected, instead the same named file will be newly created under
1681 +/tmp/rw. And all of your modification to a file will be applied to
1682 +the one under /tmp/rw. This is called the file based Copy on Write
1683 +(COW) method.
1684 +Aufs mount options are described in aufs.5.
1685 +If you run chroot or something and make your aufs as a root directory,
1686 +then you need to customize the shutdown script. See the aufs manual in
1687 +detail.
1688 +
1689 +Additionally, there are some sample usages of aufs which are a
1690 +diskless system with network booting, and LiveCD over NFS.
1691 +See sample dir in CVS tree on SourceForge.
1692 +
1693 +
1694 +5. Contact
1695 +----------------------------------------
1696 +When you have any problems or strange behaviour in aufs, please let me
1697 +know with:
1698 +- /proc/mounts (instead of the output of mount(8))
1699 +- /sys/module/aufs/*
1700 +- /sys/fs/aufs/* (if you have them)
1701 +- /debug/aufs/* (if you have them)
1702 +- linux kernel version
1703 +  if your kernel is not plain, for example modified by distributor,
1704 +  the url where i can download its source is necessary too.
1705 +- aufs version which was printed at loading the module or booting the
1706 +  system, instead of the date you downloaded.
1707 +- configuration (define/undefine CONFIG_AUFS_xxx)
1708 +- kernel configuration or /proc/config.gz (if you have it)
1709 +- behaviour which you think to be incorrect
1710 +- actual operation, reproducible one is better
1711 +- mailto: aufs-users at lists.sourceforge.net
1712 +
1713 +Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
1714 +and Feature Requests) on SourceForge. Please join and write to
1715 +aufs-users ML.
1716 +
1717 +
1718 +6. Acknowledgements
1719 +----------------------------------------
1720 +Thanks to everyone who have tried and are using aufs, whoever
1721 +have reported a bug or any feedback.
1722 +
1723 +Especially donators:
1724 +Tomas Matejicek(slax.org) made a donation (much more than once).
1725 +       Since Apr 2010, Tomas M (the author of Slax and Linux Live
1726 +       scripts) is making "doubling" donations.
1727 +       Unfortunately I cannot list all of the donators, but I really
1728 +       appreciate.
1729 +       It ends Aug 2010, but the ordinary donation URL is still available.
1730 +       <http://sourceforge.net/donate/index.php?group_id=167503>
1731 +Dai Itasaka made a donation (2007/8).
1732 +Chuck Smith made a donation (2008/4, 10 and 12).
1733 +Henk Schoneveld made a donation (2008/9).
1734 +Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
1735 +Francois Dupoux made a donation (2008/11).
1736 +Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
1737 +       aufs2 GIT tree (2009/2).
1738 +William Grant made a donation (2009/3).
1739 +Patrick Lane made a donation (2009/4).
1740 +The Mail Archive (mail-archive.com) made donations (2009/5).
1741 +Nippy Networks (Ed Wildgoose) made a donation (2009/7).
1742 +New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
1743 +Pavel Pronskiy made a donation (2011/2).
1744 +Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
1745 +       Networks (Ed Wildgoose) made a donation for hardware (2011/3).
1746 +Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
1747 +11).
1748 +Sam Liddicott made a donation (2011/9).
1749 +
1750 +Thank you very much.
1751 +Donations are always, including future donations, very important and
1752 +helpful for me to keep on developing aufs.
1753 +
1754 +
1755 +7.
1756 +----------------------------------------
1757 +If you are an experienced user, no explanation is needed. Aufs is
1758 +just a linux filesystem.
1759 +
1760 +
1761 +Enjoy!
1762 +
1763 +# Local variables: ;
1764 +# mode: text;
1765 +# End: ;
1766 diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
1767 --- /usr/share/empty/fs/aufs/aufs.h     1970-01-01 01:00:00.000000000 +0100
1768 +++ linux/fs/aufs/aufs.h        2013-01-11 19:46:12.635947932 +0100
1769 @@ -0,0 +1,60 @@
1770 +/*
1771 + * Copyright (C) 2005-2013 Junjiro R. Okajima
1772 + *
1773 + * This program, aufs is free software; you can redistribute it and/or modify
1774 + * it under the terms of the GNU General Public License as published by
1775 + * the Free Software Foundation; either version 2 of the License, or
1776 + * (at your option) any later version.
1777 + *
1778 + * This program is distributed in the hope that it will be useful,
1779 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1780 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1781 + * GNU General Public License for more details.
1782 + *
1783 + * You should have received a copy of the GNU General Public License
1784 + * along with this program; if not, write to the Free Software
1785 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1786 + */
1787 +
1788 +/*
1789 + * all header files
1790 + */
1791 +
1792 +#ifndef __AUFS_H__
1793 +#define __AUFS_H__
1794 +
1795 +#ifdef __KERNEL__
1796 +
1797 +#define AuStub(type, name, body, ...) \
1798 +       static inline type name(__VA_ARGS__) { body; }
1799 +
1800 +#define AuStubVoid(name, ...) \
1801 +       AuStub(void, name, , __VA_ARGS__)
1802 +#define AuStubInt0(name, ...) \
1803 +       AuStub(int, name, return 0, __VA_ARGS__)
1804 +
1805 +#include "debug.h"
1806 +
1807 +#include "branch.h"
1808 +#include "cpup.h"
1809 +#include "dcsub.h"
1810 +#include "dbgaufs.h"
1811 +#include "dentry.h"
1812 +#include "dir.h"
1813 +#include "dynop.h"
1814 +#include "file.h"
1815 +#include "fstype.h"
1816 +#include "inode.h"
1817 +#include "loop.h"
1818 +#include "module.h"
1819 +#include "opts.h"
1820 +#include "rwsem.h"
1821 +#include "spl.h"
1822 +#include "super.h"
1823 +#include "sysaufs.h"
1824 +#include "vfsub.h"
1825 +#include "whout.h"
1826 +#include "wkq.h"
1827 +
1828 +#endif /* __KERNEL__ */
1829 +#endif /* __AUFS_H__ */
1830 diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
1831 --- /usr/share/empty/fs/aufs/branch.c   1970-01-01 01:00:00.000000000 +0100
1832 +++ linux/fs/aufs/branch.c      2013-01-11 19:46:12.635947932 +0100
1833 @@ -0,0 +1,1172 @@
1834 +/*
1835 + * Copyright (C) 2005-2013 Junjiro R. Okajima
1836 + *
1837 + * This program, aufs is free software; you can redistribute it and/or modify
1838 + * it under the terms of the GNU General Public License as published by
1839 + * the Free Software Foundation; either version 2 of the License, or
1840 + * (at your option) any later version.
1841 + *
1842 + * This program is distributed in the hope that it will be useful,
1843 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1844 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1845 + * GNU General Public License for more details.
1846 + *
1847 + * You should have received a copy of the GNU General Public License
1848 + * along with this program; if not, write to the Free Software
1849 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1850 + */
1851 +
1852 +/*
1853 + * branch management
1854 + */
1855 +
1856 +#include <linux/compat.h>
1857 +#include <linux/statfs.h>
1858 +#include "aufs.h"
1859 +
1860 +/*
1861 + * free a single branch
1862 + */
1863 +static void au_br_do_free(struct au_branch *br)
1864 +{
1865 +       int i;
1866 +       struct au_wbr *wbr;
1867 +       struct au_dykey **key;
1868 +
1869 +       au_hnotify_fin_br(br);
1870 +
1871 +       if (br->br_xino.xi_file)
1872 +               fput(br->br_xino.xi_file);
1873 +       mutex_destroy(&br->br_xino.xi_nondir_mtx);
1874 +
1875 +       AuDebugOn(atomic_read(&br->br_count));
1876 +
1877 +       wbr = br->br_wbr;
1878 +       if (wbr) {
1879 +               for (i = 0; i < AuBrWh_Last; i++)
1880 +                       dput(wbr->wbr_wh[i]);
1881 +               AuDebugOn(atomic_read(&wbr->wbr_wh_running));
1882 +               AuRwDestroy(&wbr->wbr_wh_rwsem);
1883 +       }
1884 +
1885 +       key = br->br_dykey;
1886 +       for (i = 0; i < AuBrDynOp; i++, key++)
1887 +               if (*key)
1888 +                       au_dy_put(*key);
1889 +               else
1890 +                       break;
1891 +
1892 +       /* recursive lock, s_umount of branch's */
1893 +       lockdep_off();
1894 +       mntput(br->br_mnt);
1895 +       lockdep_on();
1896 +       kfree(wbr);
1897 +       kfree(br);
1898 +}
1899 +
1900 +/*
1901 + * frees all branches
1902 + */
1903 +void au_br_free(struct au_sbinfo *sbinfo)
1904 +{
1905 +       aufs_bindex_t bmax;
1906 +       struct au_branch **br;
1907 +
1908 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
1909 +
1910 +       bmax = sbinfo->si_bend + 1;
1911 +       br = sbinfo->si_branch;
1912 +       while (bmax--)
1913 +               au_br_do_free(*br++);
1914 +}
1915 +
1916 +/*
1917 + * find the index of a branch which is specified by @br_id.
1918 + */
1919 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
1920 +{
1921 +       aufs_bindex_t bindex, bend;
1922 +
1923 +       bend = au_sbend(sb);
1924 +       for (bindex = 0; bindex <= bend; bindex++)
1925 +               if (au_sbr_id(sb, bindex) == br_id)
1926 +                       return bindex;
1927 +       return -1;
1928 +}
1929 +
1930 +/* ---------------------------------------------------------------------- */
1931 +
1932 +/*
1933 + * add a branch
1934 + */
1935 +
1936 +static int test_overlap(struct super_block *sb, struct dentry *h_adding,
1937 +                       struct dentry *h_root)
1938 +{
1939 +       if (unlikely(h_adding == h_root
1940 +                    || au_test_loopback_overlap(sb, h_adding)))
1941 +               return 1;
1942 +       if (h_adding->d_sb != h_root->d_sb)
1943 +               return 0;
1944 +       return au_test_subdir(h_adding, h_root)
1945 +               || au_test_subdir(h_root, h_adding);
1946 +}
1947 +
1948 +/*
1949 + * returns a newly allocated branch. @new_nbranch is a number of branches
1950 + * after adding a branch.
1951 + */
1952 +static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
1953 +                                    int perm)
1954 +{
1955 +       struct au_branch *add_branch;
1956 +       struct dentry *root;
1957 +       int err;
1958 +
1959 +       err = -ENOMEM;
1960 +       root = sb->s_root;
1961 +       add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
1962 +       if (unlikely(!add_branch))
1963 +               goto out;
1964 +
1965 +       err = au_hnotify_init_br(add_branch, perm);
1966 +       if (unlikely(err))
1967 +               goto out_br;
1968 +
1969 +       add_branch->br_wbr = NULL;
1970 +       if (au_br_writable(perm)) {
1971 +               /* may be freed separately at changing the branch permission */
1972 +               add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
1973 +                                            GFP_NOFS);
1974 +               if (unlikely(!add_branch->br_wbr))
1975 +                       goto out_hnotify;
1976 +       }
1977 +
1978 +       err = au_sbr_realloc(au_sbi(sb), new_nbranch);
1979 +       if (!err)
1980 +               err = au_di_realloc(au_di(root), new_nbranch);
1981 +       if (!err)
1982 +               err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
1983 +       if (!err)
1984 +               return add_branch; /* success */
1985 +
1986 +       kfree(add_branch->br_wbr);
1987 +
1988 +out_hnotify:
1989 +       au_hnotify_fin_br(add_branch);
1990 +out_br:
1991 +       kfree(add_branch);
1992 +out:
1993 +       return ERR_PTR(err);
1994 +}
1995 +
1996 +/*
1997 + * test if the branch permission is legal or not.
1998 + */
1999 +static int test_br(struct inode *inode, int brperm, char *path)
2000 +{
2001 +       int err;
2002 +
2003 +       err = (au_br_writable(brperm) && IS_RDONLY(inode));
2004 +       if (!err)
2005 +               goto out;
2006 +
2007 +       err = -EINVAL;
2008 +       pr_err("write permission for readonly mount or inode, %s\n", path);
2009 +
2010 +out:
2011 +       return err;
2012 +}
2013 +
2014 +/*
2015 + * returns:
2016 + * 0: success, the caller will add it
2017 + * plus: success, it is already unified, the caller should ignore it
2018 + * minus: error
2019 + */
2020 +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2021 +{
2022 +       int err;
2023 +       aufs_bindex_t bend, bindex;
2024 +       struct dentry *root;
2025 +       struct inode *inode, *h_inode;
2026 +
2027 +       root = sb->s_root;
2028 +       bend = au_sbend(sb);
2029 +       if (unlikely(bend >= 0
2030 +                    && au_find_dbindex(root, add->path.dentry) >= 0)) {
2031 +               err = 1;
2032 +               if (!remount) {
2033 +                       err = -EINVAL;
2034 +                       pr_err("%s duplicated\n", add->pathname);
2035 +               }
2036 +               goto out;
2037 +       }
2038 +
2039 +       err = -ENOSPC; /* -E2BIG; */
2040 +       if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2041 +                    || AUFS_BRANCH_MAX - 1 <= bend)) {
2042 +               pr_err("number of branches exceeded %s\n", add->pathname);
2043 +               goto out;
2044 +       }
2045 +
2046 +       err = -EDOM;
2047 +       if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
2048 +               pr_err("bad index %d\n", add->bindex);
2049 +               goto out;
2050 +       }
2051 +
2052 +       inode = add->path.dentry->d_inode;
2053 +       err = -ENOENT;
2054 +       if (unlikely(!inode->i_nlink)) {
2055 +               pr_err("no existence %s\n", add->pathname);
2056 +               goto out;
2057 +       }
2058 +
2059 +       err = -EINVAL;
2060 +       if (unlikely(inode->i_sb == sb)) {
2061 +               pr_err("%s must be outside\n", add->pathname);
2062 +               goto out;
2063 +       }
2064 +
2065 +       if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
2066 +               pr_err("unsupported filesystem, %s (%s)\n",
2067 +                      add->pathname, au_sbtype(inode->i_sb));
2068 +               goto out;
2069 +       }
2070 +
2071 +       err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2072 +       if (unlikely(err))
2073 +               goto out;
2074 +
2075 +       if (bend < 0)
2076 +               return 0; /* success */
2077 +
2078 +       err = -EINVAL;
2079 +       for (bindex = 0; bindex <= bend; bindex++)
2080 +               if (unlikely(test_overlap(sb, add->path.dentry,
2081 +                                         au_h_dptr(root, bindex)))) {
2082 +                       pr_err("%s is overlapped\n", add->pathname);
2083 +                       goto out;
2084 +               }
2085 +
2086 +       err = 0;
2087 +       if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2088 +               h_inode = au_h_dptr(root, 0)->d_inode;
2089 +               if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
2090 +                   || !uid_eq(h_inode->i_uid, inode->i_uid)
2091 +                   || !gid_eq(h_inode->i_gid, inode->i_gid))
2092 +                       pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2093 +                               add->pathname,
2094 +                               i_uid_read(inode), i_gid_read(inode),
2095 +                               (inode->i_mode & S_IALLUGO),
2096 +                               i_uid_read(h_inode), i_gid_read(h_inode),
2097 +                               (h_inode->i_mode & S_IALLUGO));
2098 +       }
2099 +
2100 +out:
2101 +       return err;
2102 +}
2103 +
2104 +/*
2105 + * initialize or clean the whiteouts for an adding branch
2106 + */
2107 +static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
2108 +                        int new_perm, struct dentry *h_root)
2109 +{
2110 +       int err, old_perm;
2111 +       aufs_bindex_t bindex;
2112 +       struct mutex *h_mtx;
2113 +       struct au_wbr *wbr;
2114 +       struct au_hinode *hdir;
2115 +
2116 +       wbr = br->br_wbr;
2117 +       old_perm = br->br_perm;
2118 +       br->br_perm = new_perm;
2119 +       hdir = NULL;
2120 +       h_mtx = NULL;
2121 +       bindex = au_br_index(sb, br->br_id);
2122 +       if (0 <= bindex) {
2123 +               hdir = au_hi(sb->s_root->d_inode, bindex);
2124 +               au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
2125 +       } else {
2126 +               h_mtx = &h_root->d_inode->i_mutex;
2127 +               mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2128 +       }
2129 +       if (!wbr)
2130 +               err = au_wh_init(h_root, br, sb);
2131 +       else {
2132 +               wbr_wh_write_lock(wbr);
2133 +               err = au_wh_init(h_root, br, sb);
2134 +               wbr_wh_write_unlock(wbr);
2135 +       }
2136 +       if (hdir)
2137 +               au_hn_imtx_unlock(hdir);
2138 +       else
2139 +               mutex_unlock(h_mtx);
2140 +       br->br_perm = old_perm;
2141 +
2142 +       if (!err && wbr && !au_br_writable(new_perm)) {
2143 +               kfree(wbr);
2144 +               br->br_wbr = NULL;
2145 +       }
2146 +
2147 +       return err;
2148 +}
2149 +
2150 +static int au_wbr_init(struct au_branch *br, struct super_block *sb,
2151 +                      int perm, struct path *path)
2152 +{
2153 +       int err;
2154 +       struct kstatfs kst;
2155 +       struct au_wbr *wbr;
2156 +       struct dentry *h_dentry;
2157 +
2158 +       wbr = br->br_wbr;
2159 +       au_rw_init(&wbr->wbr_wh_rwsem);
2160 +       memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2161 +       atomic_set(&wbr->wbr_wh_running, 0);
2162 +       wbr->wbr_bytes = 0;
2163 +
2164 +       /*
2165 +        * a limit for rmdir/rename a dir
2166 +        * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h
2167 +        */
2168 +       err = vfs_statfs(path, &kst);
2169 +       if (unlikely(err))
2170 +               goto out;
2171 +       err = -EINVAL;
2172 +       h_dentry = path->dentry;
2173 +       if (kst.f_namelen >= NAME_MAX)
2174 +               err = au_br_init_wh(sb, br, perm, h_dentry);
2175 +       else
2176 +               pr_err("%.*s(%s), unsupported namelen %ld\n",
2177 +                      AuDLNPair(h_dentry), au_sbtype(h_dentry->d_sb),
2178 +                      kst.f_namelen);
2179 +
2180 +out:
2181 +       return err;
2182 +}
2183 +
2184 +/* intialize a new branch */
2185 +static int au_br_init(struct au_branch *br, struct super_block *sb,
2186 +                     struct au_opt_add *add)
2187 +{
2188 +       int err;
2189 +
2190 +       err = 0;
2191 +       memset(&br->br_xino, 0, sizeof(br->br_xino));
2192 +       mutex_init(&br->br_xino.xi_nondir_mtx);
2193 +       br->br_perm = add->perm;
2194 +       br->br_mnt = add->path.mnt; /* set first, mntget() later */
2195 +       spin_lock_init(&br->br_dykey_lock);
2196 +       memset(br->br_dykey, 0, sizeof(br->br_dykey));
2197 +       atomic_set(&br->br_count, 0);
2198 +       br->br_xino_upper = AUFS_XINO_TRUNC_INIT;
2199 +       atomic_set(&br->br_xino_running, 0);
2200 +       br->br_id = au_new_br_id(sb);
2201 +       AuDebugOn(br->br_id < 0);
2202 +
2203 +       if (au_br_writable(add->perm)) {
2204 +               err = au_wbr_init(br, sb, add->perm, &add->path);
2205 +               if (unlikely(err))
2206 +                       goto out_err;
2207 +       }
2208 +
2209 +       if (au_opt_test(au_mntflags(sb), XINO)) {
2210 +               err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
2211 +                                au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
2212 +               if (unlikely(err)) {
2213 +                       AuDebugOn(br->br_xino.xi_file);
2214 +                       goto out_err;
2215 +               }
2216 +       }
2217 +
2218 +       sysaufs_br_init(br);
2219 +       mntget(add->path.mnt);
2220 +       goto out; /* success */
2221 +
2222 +out_err:
2223 +       br->br_mnt = NULL;
2224 +out:
2225 +       return err;
2226 +}
2227 +
2228 +static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
2229 +                            struct au_branch *br, aufs_bindex_t bend,
2230 +                            aufs_bindex_t amount)
2231 +{
2232 +       struct au_branch **brp;
2233 +
2234 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
2235 +
2236 +       brp = sbinfo->si_branch + bindex;
2237 +       memmove(brp + 1, brp, sizeof(*brp) * amount);
2238 +       *brp = br;
2239 +       sbinfo->si_bend++;
2240 +       if (unlikely(bend < 0))
2241 +               sbinfo->si_bend = 0;
2242 +}
2243 +
2244 +static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
2245 +                            aufs_bindex_t bend, aufs_bindex_t amount)
2246 +{
2247 +       struct au_hdentry *hdp;
2248 +
2249 +       AuRwMustWriteLock(&dinfo->di_rwsem);
2250 +
2251 +       hdp = dinfo->di_hdentry + bindex;
2252 +       memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
2253 +       au_h_dentry_init(hdp);
2254 +       dinfo->di_bend++;
2255 +       if (unlikely(bend < 0))
2256 +               dinfo->di_bstart = 0;
2257 +}
2258 +
2259 +static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
2260 +                            aufs_bindex_t bend, aufs_bindex_t amount)
2261 +{
2262 +       struct au_hinode *hip;
2263 +
2264 +       AuRwMustWriteLock(&iinfo->ii_rwsem);
2265 +
2266 +       hip = iinfo->ii_hinode + bindex;
2267 +       memmove(hip + 1, hip, sizeof(*hip) * amount);
2268 +       hip->hi_inode = NULL;
2269 +       au_hn_init(hip);
2270 +       iinfo->ii_bend++;
2271 +       if (unlikely(bend < 0))
2272 +               iinfo->ii_bstart = 0;
2273 +}
2274 +
2275 +static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry,
2276 +                        struct au_branch *br, aufs_bindex_t bindex)
2277 +{
2278 +       struct dentry *root;
2279 +       struct inode *root_inode;
2280 +       aufs_bindex_t bend, amount;
2281 +
2282 +       root = sb->s_root;
2283 +       root_inode = root->d_inode;
2284 +       bend = au_sbend(sb);
2285 +       amount = bend + 1 - bindex;
2286 +       au_sbilist_lock();
2287 +       au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
2288 +       au_br_do_add_hdp(au_di(root), bindex, bend, amount);
2289 +       au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
2290 +       au_set_h_dptr(root, bindex, dget(h_dentry));
2291 +       au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
2292 +                     /*flags*/0);
2293 +       au_sbilist_unlock();
2294 +}
2295 +
2296 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
2297 +{
2298 +       int err;
2299 +       aufs_bindex_t bend, add_bindex;
2300 +       struct dentry *root, *h_dentry;
2301 +       struct inode *root_inode;
2302 +       struct au_branch *add_branch;
2303 +
2304 +       root = sb->s_root;
2305 +       root_inode = root->d_inode;
2306 +       IMustLock(root_inode);
2307 +       err = test_add(sb, add, remount);
2308 +       if (unlikely(err < 0))
2309 +               goto out;
2310 +       if (err) {
2311 +               err = 0;
2312 +               goto out; /* success */
2313 +       }
2314 +
2315 +       bend = au_sbend(sb);
2316 +       add_branch = au_br_alloc(sb, bend + 2, add->perm);
2317 +       err = PTR_ERR(add_branch);
2318 +       if (IS_ERR(add_branch))
2319 +               goto out;
2320 +
2321 +       err = au_br_init(add_branch, sb, add);
2322 +       if (unlikely(err)) {
2323 +               au_br_do_free(add_branch);
2324 +               goto out;
2325 +       }
2326 +
2327 +       add_bindex = add->bindex;
2328 +       h_dentry = add->path.dentry;
2329 +       if (!remount)
2330 +               au_br_do_add(sb, h_dentry, add_branch, add_bindex);
2331 +       else {
2332 +               sysaufs_brs_del(sb, add_bindex);
2333 +               au_br_do_add(sb, h_dentry, add_branch, add_bindex);
2334 +               sysaufs_brs_add(sb, add_bindex);
2335 +       }
2336 +
2337 +       if (!add_bindex) {
2338 +               au_cpup_attr_all(root_inode, /*force*/1);
2339 +               sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
2340 +       } else
2341 +               au_add_nlink(root_inode, h_dentry->d_inode);
2342 +
2343 +       /*
2344 +        * this test/set prevents aufs from handling unnecesary notify events
2345 +        * of xino files, in case of re-adding a writable branch which was
2346 +        * once detached from aufs.
2347 +        */
2348 +       if (au_xino_brid(sb) < 0
2349 +           && au_br_writable(add_branch->br_perm)
2350 +           && !au_test_fs_bad_xino(h_dentry->d_sb)
2351 +           && add_branch->br_xino.xi_file
2352 +           && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
2353 +               au_xino_brid_set(sb, add_branch->br_id);
2354 +
2355 +out:
2356 +       return err;
2357 +}
2358 +
2359 +/* ---------------------------------------------------------------------- */
2360 +
2361 +/*
2362 + * delete a branch
2363 + */
2364 +
2365 +/* to show the line number, do not make it inlined function */
2366 +#define AuVerbose(do_info, fmt, ...) do { \
2367 +       if (do_info) \
2368 +               pr_info(fmt, ##__VA_ARGS__); \
2369 +} while (0)
2370 +
2371 +static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
2372 +                        aufs_bindex_t bend)
2373 +{
2374 +       return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
2375 +}
2376 +
2377 +static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
2378 +                        aufs_bindex_t bend)
2379 +{
2380 +       return au_test_ibusy(dentry->d_inode, bstart, bend);
2381 +}
2382 +
2383 +/*
2384 + * test if the branch is deletable or not.
2385 + */
2386 +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
2387 +                           unsigned int sigen, const unsigned int verbose)
2388 +{
2389 +       int err, i, j, ndentry;
2390 +       aufs_bindex_t bstart, bend;
2391 +       struct au_dcsub_pages dpages;
2392 +       struct au_dpage *dpage;
2393 +       struct dentry *d;
2394 +
2395 +       err = au_dpages_init(&dpages, GFP_NOFS);
2396 +       if (unlikely(err))
2397 +               goto out;
2398 +       err = au_dcsub_pages(&dpages, root, NULL, NULL);
2399 +       if (unlikely(err))
2400 +               goto out_dpages;
2401 +
2402 +       for (i = 0; !err && i < dpages.ndpage; i++) {
2403 +               dpage = dpages.dpages + i;
2404 +               ndentry = dpage->ndentry;
2405 +               for (j = 0; !err && j < ndentry; j++) {
2406 +                       d = dpage->dentries[j];
2407 +                       AuDebugOn(!d->d_count);
2408 +                       if (!au_digen_test(d, sigen)) {
2409 +                               di_read_lock_child(d, AuLock_IR);
2410 +                               if (unlikely(au_dbrange_test(d))) {
2411 +                                       di_read_unlock(d, AuLock_IR);
2412 +                                       continue;
2413 +                               }
2414 +                       } else {
2415 +                               di_write_lock_child(d);
2416 +                               if (unlikely(au_dbrange_test(d))) {
2417 +                                       di_write_unlock(d);
2418 +                                       continue;
2419 +                               }
2420 +                               err = au_reval_dpath(d, sigen);
2421 +                               if (!err)
2422 +                                       di_downgrade_lock(d, AuLock_IR);
2423 +                               else {
2424 +                                       di_write_unlock(d);
2425 +                                       break;
2426 +                               }
2427 +                       }
2428 +
2429 +                       /* AuDbgDentry(d); */
2430 +                       bstart = au_dbstart(d);
2431 +                       bend = au_dbend(d);
2432 +                       if (bstart <= bindex
2433 +                           && bindex <= bend
2434 +                           && au_h_dptr(d, bindex)
2435 +                           && au_test_dbusy(d, bstart, bend)) {
2436 +                               err = -EBUSY;
2437 +                               AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
2438 +                               AuDbgDentry(d);
2439 +                       }
2440 +                       di_read_unlock(d, AuLock_IR);
2441 +               }
2442 +       }
2443 +
2444 +out_dpages:
2445 +       au_dpages_free(&dpages);
2446 +out:
2447 +       return err;
2448 +}
2449 +
2450 +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
2451 +                          unsigned int sigen, const unsigned int verbose)
2452 +{
2453 +       int err;
2454 +       unsigned long long max, ull;
2455 +       struct inode *i, **array;
2456 +       aufs_bindex_t bstart, bend;
2457 +
2458 +       array = au_iarray_alloc(sb, &max);
2459 +       err = PTR_ERR(array);
2460 +       if (IS_ERR(array))
2461 +               goto out;
2462 +
2463 +       err = 0;
2464 +       AuDbg("b%d\n", bindex);
2465 +       for (ull = 0; !err && ull < max; ull++) {
2466 +               i = array[ull];
2467 +               if (i->i_ino == AUFS_ROOT_INO)
2468 +                       continue;
2469 +
2470 +               /* AuDbgInode(i); */
2471 +               if (au_iigen(i, NULL) == sigen)
2472 +                       ii_read_lock_child(i);
2473 +               else {
2474 +                       ii_write_lock_child(i);
2475 +                       err = au_refresh_hinode_self(i);
2476 +                       au_iigen_dec(i);
2477 +                       if (!err)
2478 +                               ii_downgrade_lock(i);
2479 +                       else {
2480 +                               ii_write_unlock(i);
2481 +                               break;
2482 +                       }
2483 +               }
2484 +
2485 +               bstart = au_ibstart(i);
2486 +               bend = au_ibend(i);
2487 +               if (bstart <= bindex
2488 +                   && bindex <= bend
2489 +                   && au_h_iptr(i, bindex)
2490 +                   && au_test_ibusy(i, bstart, bend)) {
2491 +                       err = -EBUSY;
2492 +                       AuVerbose(verbose, "busy i%lu\n", i->i_ino);
2493 +                       AuDbgInode(i);
2494 +               }
2495 +               ii_read_unlock(i);
2496 +       }
2497 +       au_iarray_free(array, max);
2498 +
2499 +out:
2500 +       return err;
2501 +}
2502 +
2503 +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
2504 +                             const unsigned int verbose)
2505 +{
2506 +       int err;
2507 +       unsigned int sigen;
2508 +
2509 +       sigen = au_sigen(root->d_sb);
2510 +       DiMustNoWaiters(root);
2511 +       IiMustNoWaiters(root->d_inode);
2512 +       di_write_unlock(root);
2513 +       err = test_dentry_busy(root, bindex, sigen, verbose);
2514 +       if (!err)
2515 +               err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
2516 +       di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
2517 +
2518 +       return err;
2519 +}
2520 +
2521 +static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
2522 +                            const aufs_bindex_t bindex,
2523 +                            const aufs_bindex_t bend)
2524 +{
2525 +       struct au_branch **brp, **p;
2526 +
2527 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
2528 +
2529 +       brp = sbinfo->si_branch + bindex;
2530 +       if (bindex < bend)
2531 +               memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
2532 +       sbinfo->si_branch[0 + bend] = NULL;
2533 +       sbinfo->si_bend--;
2534 +
2535 +       p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
2536 +       if (p)
2537 +               sbinfo->si_branch = p;
2538 +       /* harmless error */
2539 +}
2540 +
2541 +static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
2542 +                            const aufs_bindex_t bend)
2543 +{
2544 +       struct au_hdentry *hdp, *p;
2545 +
2546 +       AuRwMustWriteLock(&dinfo->di_rwsem);
2547 +
2548 +       hdp = dinfo->di_hdentry;
2549 +       if (bindex < bend)
2550 +               memmove(hdp + bindex, hdp + bindex + 1,
2551 +                       sizeof(*hdp) * (bend - bindex));
2552 +       hdp[0 + bend].hd_dentry = NULL;
2553 +       dinfo->di_bend--;
2554 +
2555 +       p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
2556 +       if (p)
2557 +               dinfo->di_hdentry = p;
2558 +       /* harmless error */
2559 +}
2560 +
2561 +static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
2562 +                            const aufs_bindex_t bend)
2563 +{
2564 +       struct au_hinode *hip, *p;
2565 +
2566 +       AuRwMustWriteLock(&iinfo->ii_rwsem);
2567 +
2568 +       hip = iinfo->ii_hinode + bindex;
2569 +       if (bindex < bend)
2570 +               memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
2571 +       iinfo->ii_hinode[0 + bend].hi_inode = NULL;
2572 +       au_hn_init(iinfo->ii_hinode + bend);
2573 +       iinfo->ii_bend--;
2574 +
2575 +       p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
2576 +       if (p)
2577 +               iinfo->ii_hinode = p;
2578 +       /* harmless error */
2579 +}
2580 +
2581 +static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
2582 +                        struct au_branch *br)
2583 +{
2584 +       aufs_bindex_t bend;
2585 +       struct au_sbinfo *sbinfo;
2586 +       struct dentry *root, *h_root;
2587 +       struct inode *inode, *h_inode;
2588 +       struct au_hinode *hinode;
2589 +
2590 +       SiMustWriteLock(sb);
2591 +
2592 +       root = sb->s_root;
2593 +       inode = root->d_inode;
2594 +       sbinfo = au_sbi(sb);
2595 +       bend = sbinfo->si_bend;
2596 +
2597 +       h_root = au_h_dptr(root, bindex);
2598 +       hinode = au_hi(inode, bindex);
2599 +       h_inode = au_igrab(hinode->hi_inode);
2600 +       au_hiput(hinode);
2601 +
2602 +       au_sbilist_lock();
2603 +       au_br_do_del_brp(sbinfo, bindex, bend);
2604 +       au_br_do_del_hdp(au_di(root), bindex, bend);
2605 +       au_br_do_del_hip(au_ii(inode), bindex, bend);
2606 +       au_sbilist_unlock();
2607 +
2608 +       dput(h_root);
2609 +       iput(h_inode);
2610 +       au_br_do_free(br);
2611 +}
2612 +
2613 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
2614 +{
2615 +       int err, rerr, i;
2616 +       unsigned int mnt_flags;
2617 +       aufs_bindex_t bindex, bend, br_id;
2618 +       unsigned char do_wh, verbose;
2619 +       struct au_branch *br;
2620 +       struct au_wbr *wbr;
2621 +
2622 +       err = 0;
2623 +       bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
2624 +       if (bindex < 0) {
2625 +               if (remount)
2626 +                       goto out; /* success */
2627 +               err = -ENOENT;
2628 +               pr_err("%s no such branch\n", del->pathname);
2629 +               goto out;
2630 +       }
2631 +       AuDbg("bindex b%d\n", bindex);
2632 +
2633 +       err = -EBUSY;
2634 +       mnt_flags = au_mntflags(sb);
2635 +       verbose = !!au_opt_test(mnt_flags, VERBOSE);
2636 +       bend = au_sbend(sb);
2637 +       if (unlikely(!bend)) {
2638 +               AuVerbose(verbose, "no more branches left\n");
2639 +               goto out;
2640 +       }
2641 +       br = au_sbr(sb, bindex);
2642 +       i = atomic_read(&br->br_count);
2643 +       if (unlikely(i)) {
2644 +               AuVerbose(verbose, "%d file(s) opened\n", i);
2645 +               goto out;
2646 +       }
2647 +
2648 +       wbr = br->br_wbr;
2649 +       do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
2650 +       if (do_wh) {
2651 +               /* instead of WbrWhMustWriteLock(wbr) */
2652 +               SiMustWriteLock(sb);
2653 +               for (i = 0; i < AuBrWh_Last; i++) {
2654 +                       dput(wbr->wbr_wh[i]);
2655 +                       wbr->wbr_wh[i] = NULL;
2656 +               }
2657 +       }
2658 +
2659 +       err = test_children_busy(sb->s_root, bindex, verbose);
2660 +       if (unlikely(err)) {
2661 +               if (do_wh)
2662 +                       goto out_wh;
2663 +               goto out;
2664 +       }
2665 +
2666 +       err = 0;
2667 +       br_id = br->br_id;
2668 +       if (!remount)
2669 +               au_br_do_del(sb, bindex, br);
2670 +       else {
2671 +               sysaufs_brs_del(sb, bindex);
2672 +               au_br_do_del(sb, bindex, br);
2673 +               sysaufs_brs_add(sb, bindex);
2674 +       }
2675 +
2676 +       if (!bindex) {
2677 +               au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
2678 +               sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
2679 +       } else
2680 +               au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
2681 +       if (au_opt_test(mnt_flags, PLINK))
2682 +               au_plink_half_refresh(sb, br_id);
2683 +
2684 +       if (au_xino_brid(sb) == br_id)
2685 +               au_xino_brid_set(sb, -1);
2686 +       goto out; /* success */
2687 +
2688 +out_wh:
2689 +       /* revert */
2690 +       rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry);
2691 +       if (rerr)
2692 +               pr_warn("failed re-creating base whiteout, %s. (%d)\n",
2693 +                       del->pathname, rerr);
2694 +out:
2695 +       return err;
2696 +}
2697 +
2698 +/* ---------------------------------------------------------------------- */
2699 +
2700 +static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
2701 +{
2702 +       int err;
2703 +       aufs_bindex_t bstart, bend;
2704 +       struct aufs_ibusy ibusy;
2705 +       struct inode *inode, *h_inode;
2706 +
2707 +       err = -EPERM;
2708 +       if (unlikely(!capable(CAP_SYS_ADMIN)))
2709 +               goto out;
2710 +
2711 +       err = copy_from_user(&ibusy, arg, sizeof(ibusy));
2712 +       if (!err)
2713 +               err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
2714 +       if (unlikely(err)) {
2715 +               err = -EFAULT;
2716 +               AuTraceErr(err);
2717 +               goto out;
2718 +       }
2719 +
2720 +       err = -EINVAL;
2721 +       si_read_lock(sb, AuLock_FLUSH);
2722 +       if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
2723 +               goto out_unlock;
2724 +
2725 +       err = 0;
2726 +       ibusy.h_ino = 0; /* invalid */
2727 +       inode = ilookup(sb, ibusy.ino);
2728 +       if (!inode
2729 +           || inode->i_ino == AUFS_ROOT_INO
2730 +           || is_bad_inode(inode))
2731 +               goto out_unlock;
2732 +
2733 +       ii_read_lock_child(inode);
2734 +       bstart = au_ibstart(inode);
2735 +       bend = au_ibend(inode);
2736 +       if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
2737 +               h_inode = au_h_iptr(inode, ibusy.bindex);
2738 +               if (h_inode && au_test_ibusy(inode, bstart, bend))
2739 +                       ibusy.h_ino = h_inode->i_ino;
2740 +       }
2741 +       ii_read_unlock(inode);
2742 +       iput(inode);
2743 +
2744 +out_unlock:
2745 +       si_read_unlock(sb);
2746 +       if (!err) {
2747 +               err = __put_user(ibusy.h_ino, &arg->h_ino);
2748 +               if (unlikely(err)) {
2749 +                       err = -EFAULT;
2750 +                       AuTraceErr(err);
2751 +               }
2752 +       }
2753 +out:
2754 +       return err;
2755 +}
2756 +
2757 +long au_ibusy_ioctl(struct file *file, unsigned long arg)
2758 +{
2759 +       return au_ibusy(file->f_dentry->d_sb, (void __user *)arg);
2760 +}
2761 +
2762 +#ifdef CONFIG_COMPAT
2763 +long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
2764 +{
2765 +       return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg));
2766 +}
2767 +#endif
2768 +
2769 +/* ---------------------------------------------------------------------- */
2770 +
2771 +/*
2772 + * change a branch permission
2773 + */
2774 +
2775 +static void au_warn_ima(void)
2776 +{
2777 +#ifdef CONFIG_IMA
2778 +       /* since it doesn't support mark_files_ro() */
2779 +       AuWarn1("RW -> RO makes IMA to produce wrong message\n");
2780 +#endif
2781 +}
2782 +
2783 +static int do_need_sigen_inc(int a, int b)
2784 +{
2785 +       return au_br_whable(a) && !au_br_whable(b);
2786 +}
2787 +
2788 +static int need_sigen_inc(int old, int new)
2789 +{
2790 +       return do_need_sigen_inc(old, new)
2791 +               || do_need_sigen_inc(new, old);
2792 +}
2793 +
2794 +static unsigned long long au_farray_cb(void *a,
2795 +                                      unsigned long long max __maybe_unused,
2796 +                                      void *arg)
2797 +{
2798 +       unsigned long long n;
2799 +       struct file **p, *f;
2800 +       struct super_block *sb = arg;
2801 +
2802 +       n = 0;
2803 +       p = a;
2804 +       lg_global_lock(&files_lglock);
2805 +       do_file_list_for_each_entry(sb, f) {
2806 +               if (au_fi(f)
2807 +                   && file_count(f)
2808 +                   && !special_file(f->f_dentry->d_inode->i_mode)) {
2809 +                       get_file(f);
2810 +                       *p++ = f;
2811 +                       n++;
2812 +                       AuDebugOn(n > max);
2813 +               }
2814 +       } while_file_list_for_each_entry;
2815 +       lg_global_unlock(&files_lglock);
2816 +
2817 +       return n;
2818 +}
2819 +
2820 +static struct file **au_farray_alloc(struct super_block *sb,
2821 +                                    unsigned long long *max)
2822 +{
2823 +       *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
2824 +       return au_array_alloc(max, au_farray_cb, sb);
2825 +}
2826 +
2827 +static void au_farray_free(struct file **a, unsigned long long max)
2828 +{
2829 +       unsigned long long ull;
2830 +
2831 +       for (ull = 0; ull < max; ull++)
2832 +               if (a[ull])
2833 +                       fput(a[ull]);
2834 +       au_array_free(a);
2835 +}
2836 +
2837 +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
2838 +{
2839 +       int err, do_warn;
2840 +       unsigned int mnt_flags;
2841 +       unsigned long long ull, max;
2842 +       aufs_bindex_t br_id;
2843 +       unsigned char verbose;
2844 +       struct file *file, *hf, **array;
2845 +       struct inode *inode;
2846 +       struct au_hfile *hfile;
2847 +
2848 +       mnt_flags = au_mntflags(sb);
2849 +       verbose = !!au_opt_test(mnt_flags, VERBOSE);
2850 +
2851 +       array = au_farray_alloc(sb, &max);
2852 +       err = PTR_ERR(array);
2853 +       if (IS_ERR(array))
2854 +               goto out;
2855 +
2856 +       do_warn = 0;
2857 +       br_id = au_sbr_id(sb, bindex);
2858 +       for (ull = 0; ull < max; ull++) {
2859 +               file = array[ull];
2860 +
2861 +               /* AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); */
2862 +               fi_read_lock(file);
2863 +               if (unlikely(au_test_mmapped(file))) {
2864 +                       err = -EBUSY;
2865 +                       AuVerbose(verbose, "mmapped %.*s\n",
2866 +                                 AuDLNPair(file->f_dentry));
2867 +                       AuDbgFile(file);
2868 +                       FiMustNoWaiters(file);
2869 +                       fi_read_unlock(file);
2870 +                       goto out_array;
2871 +               }
2872 +
2873 +               inode = file->f_dentry->d_inode;
2874 +               hfile = &au_fi(file)->fi_htop;
2875 +               hf = hfile->hf_file;
2876 +               if (!S_ISREG(inode->i_mode)
2877 +                   || !(file->f_mode & FMODE_WRITE)
2878 +                   || hfile->hf_br->br_id != br_id
2879 +                   || !(hf->f_mode & FMODE_WRITE))
2880 +                       array[ull] = NULL;
2881 +               else {
2882 +                       do_warn = 1;
2883 +                       get_file(file);
2884 +               }
2885 +
2886 +               FiMustNoWaiters(file);
2887 +               fi_read_unlock(file);
2888 +               fput(file);
2889 +       }
2890 +
2891 +       err = 0;
2892 +       if (do_warn)
2893 +               au_warn_ima();
2894 +
2895 +       for (ull = 0; ull < max; ull++) {
2896 +               file = array[ull];
2897 +               if (!file)
2898 +                       continue;
2899 +
2900 +               /* todo: already flushed? */
2901 +               /* cf. fs/super.c:mark_files_ro() */
2902 +               /* fi_read_lock(file); */
2903 +               hfile = &au_fi(file)->fi_htop;
2904 +               hf = hfile->hf_file;
2905 +               /* fi_read_unlock(file); */
2906 +               spin_lock(&hf->f_lock);
2907 +               hf->f_mode &= ~FMODE_WRITE;
2908 +               spin_unlock(&hf->f_lock);
2909 +               if (!file_check_writeable(hf)) {
2910 +                       file_release_write(hf);
2911 +                       vfsub_mnt_drop_write(hf->f_vfsmnt);
2912 +               }
2913 +       }
2914 +
2915 +out_array:
2916 +       au_farray_free(array, max);
2917 +out:
2918 +       AuTraceErr(err);
2919 +       return err;
2920 +}
2921 +
2922 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
2923 +             int *do_refresh)
2924 +{
2925 +       int err, rerr;
2926 +       aufs_bindex_t bindex;
2927 +       struct path path;
2928 +       struct dentry *root;
2929 +       struct au_branch *br;
2930 +
2931 +       root = sb->s_root;
2932 +       bindex = au_find_dbindex(root, mod->h_root);
2933 +       if (bindex < 0) {
2934 +               if (remount)
2935 +                       return 0; /* success */
2936 +               err = -ENOENT;
2937 +               pr_err("%s no such branch\n", mod->path);
2938 +               goto out;
2939 +       }
2940 +       AuDbg("bindex b%d\n", bindex);
2941 +
2942 +       err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
2943 +       if (unlikely(err))
2944 +               goto out;
2945 +
2946 +       br = au_sbr(sb, bindex);
2947 +       if (br->br_perm == mod->perm)
2948 +               return 0; /* success */
2949 +
2950 +       if (au_br_writable(br->br_perm)) {
2951 +               /* remove whiteout base */
2952 +               err = au_br_init_wh(sb, br, mod->perm, mod->h_root);
2953 +               if (unlikely(err))
2954 +                       goto out;
2955 +
2956 +               if (!au_br_writable(mod->perm)) {
2957 +                       /* rw --> ro, file might be mmapped */
2958 +                       DiMustNoWaiters(root);
2959 +                       IiMustNoWaiters(root->d_inode);
2960 +                       di_write_unlock(root);
2961 +                       err = au_br_mod_files_ro(sb, bindex);
2962 +                       /* aufs_write_lock() calls ..._child() */
2963 +                       di_write_lock_child(root);
2964 +
2965 +                       if (unlikely(err)) {
2966 +                               rerr = -ENOMEM;
2967 +                               br->br_wbr = kmalloc(sizeof(*br->br_wbr),
2968 +                                                    GFP_NOFS);
2969 +                               if (br->br_wbr) {
2970 +                                       path.mnt = br->br_mnt;
2971 +                                       path.dentry = mod->h_root;
2972 +                                       rerr = au_wbr_init(br, sb, br->br_perm,
2973 +                                                          &path);
2974 +                               }
2975 +                               if (unlikely(rerr)) {
2976 +                                       AuIOErr("nested error %d (%d)\n",
2977 +                                               rerr, err);
2978 +                                       br->br_perm = mod->perm;
2979 +                               }
2980 +                       }
2981 +               }
2982 +       } else if (au_br_writable(mod->perm)) {
2983 +               /* ro --> rw */
2984 +               err = -ENOMEM;
2985 +               br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
2986 +               if (br->br_wbr) {
2987 +                       path.mnt = br->br_mnt;
2988 +                       path.dentry = mod->h_root;
2989 +                       err = au_wbr_init(br, sb, mod->perm, &path);
2990 +                       if (unlikely(err)) {
2991 +                               kfree(br->br_wbr);
2992 +                               br->br_wbr = NULL;
2993 +                       }
2994 +               }
2995 +       }
2996 +
2997 +       if (!err) {
2998 +               *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
2999 +               br->br_perm = mod->perm;
3000 +       }
3001 +
3002 +out:
3003 +       AuTraceErr(err);
3004 +       return err;
3005 +}
3006 diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
3007 --- /usr/share/empty/fs/aufs/branch.h   1970-01-01 01:00:00.000000000 +0100
3008 +++ linux/fs/aufs/branch.h      2013-01-11 19:46:12.635947932 +0100
3009 @@ -0,0 +1,230 @@
3010 +/*
3011 + * Copyright (C) 2005-2013 Junjiro R. Okajima
3012 + *
3013 + * This program, aufs is free software; you can redistribute it and/or modify
3014 + * it under the terms of the GNU General Public License as published by
3015 + * the Free Software Foundation; either version 2 of the License, or
3016 + * (at your option) any later version.
3017 + *
3018 + * This program is distributed in the hope that it will be useful,
3019 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3020 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3021 + * GNU General Public License for more details.
3022 + *
3023 + * You should have received a copy of the GNU General Public License
3024 + * along with this program; if not, write to the Free Software
3025 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
3026 + */
3027 +
3028 +/*
3029 + * branch filesystems and xino for them
3030 + */
3031 +
3032 +#ifndef __AUFS_BRANCH_H__
3033 +#define __AUFS_BRANCH_H__
3034 +
3035 +#ifdef __KERNEL__
3036 +
3037 +#include <linux/mount.h>
3038 +#include "dynop.h"
3039 +#include "rwsem.h"
3040 +#include "super.h"
3041 +
3042 +/* ---------------------------------------------------------------------- */
3043 +
3044 +/* a xino file */
3045 +struct au_xino_file {
3046 +       struct file             *xi_file;
3047 +       struct mutex            xi_nondir_mtx;
3048 +
3049 +       /* todo: make xino files an array to support huge inode number */
3050 +
3051 +#ifdef CONFIG_DEBUG_FS
3052 +       struct dentry            *xi_dbgaufs;
3053 +#endif
3054 +};
3055 +
3056 +/* members for writable branch only */
3057 +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
3058 +struct au_wbr {
3059 +       struct au_rwsem         wbr_wh_rwsem;
3060 +       struct dentry           *wbr_wh[AuBrWh_Last];
3061 +       atomic_t                wbr_wh_running;
3062 +#define wbr_whbase             wbr_wh[AuBrWh_BASE]     /* whiteout base */
3063 +#define wbr_plink              wbr_wh[AuBrWh_PLINK]    /* pseudo-link dir */
3064 +#define wbr_orph               wbr_wh[AuBrWh_ORPH]     /* dir for orphans */
3065 +
3066 +       /* mfs mode */
3067 +       unsigned long long      wbr_bytes;
3068 +};
3069 +
3070 +/* ext2 has 3 types of operations at least, ext3 has 4 */
3071 +#define AuBrDynOp (AuDyLast * 4)
3072 +
3073 +/* protected by superblock rwsem */
3074 +struct au_branch {
3075 +       struct au_xino_file     br_xino;
3076 +
3077 +       aufs_bindex_t           br_id;
3078 +
3079 +       int                     br_perm;
3080 +       struct vfsmount         *br_mnt;
3081 +       spinlock_t              br_dykey_lock;
3082 +       struct au_dykey         *br_dykey[AuBrDynOp];
3083 +       atomic_t                br_count;
3084 +
3085 +       struct au_wbr           *br_wbr;
3086 +
3087 +       /* xino truncation */
3088 +       blkcnt_t                br_xino_upper;  /* watermark in blocks */
3089 +       atomic_t                br_xino_running;
3090 +
3091 +#ifdef CONFIG_AUFS_HFSNOTIFY
3092 +       struct fsnotify_group   *br_hfsn_group;
3093 +       struct fsnotify_ops     br_hfsn_ops;
3094 +#endif
3095 +
3096 +#ifdef CONFIG_SYSFS
3097 +       /* an entry under sysfs per mount-point */
3098 +       char                    br_name[8];
3099 +       struct attribute        br_attr;
3100 +#endif
3101 +};
3102 +
3103 +/* ---------------------------------------------------------------------- */
3104 +
3105 +/* branch permissions and attributes */
3106 +#define AuBrPerm_RW            1               /* writable, hardlinkable wh */
3107 +#define AuBrPerm_RO            (1 << 1)        /* readonly */
3108 +#define AuBrPerm_RR            (1 << 2)        /* natively readonly */
3109 +#define AuBrPerm_Mask          (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
3110 +
3111 +#define AuBrRAttr_WH           (1 << 3)        /* whiteout-able */
3112 +
3113 +#define AuBrWAttr_NoLinkWH     (1 << 4)        /* un-hardlinkable whiteouts */
3114 +
3115 +static inline int au_br_writable(int brperm)
3116 +{
3117 +       return brperm & AuBrPerm_RW;
3118 +}
3119 +
3120 +static inline int au_br_whable(int brperm)
3121 +{
3122 +       return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
3123 +}
3124 +
3125 +static inline int au_br_wh_linkable(int brperm)
3126 +{
3127 +       return !(brperm & AuBrWAttr_NoLinkWH);
3128 +}
3129 +
3130 +static inline int au_br_rdonly(struct au_branch *br)
3131 +{
3132 +       return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY)
3133 +               || !au_br_writable(br->br_perm))
3134 +               ? -EROFS : 0;
3135 +}
3136 +
3137 +static inline int au_br_hnotifyable(int brperm __maybe_unused)
3138 +{
3139 +#ifdef CONFIG_AUFS_HNOTIFY
3140 +       return !(brperm & AuBrPerm_RR);
3141 +#else
3142 +       return 0;
3143 +#endif
3144 +}
3145 +
3146 +/* ---------------------------------------------------------------------- */
3147 +
3148 +/* branch.c */
3149 +struct au_sbinfo;
3150 +void au_br_free(struct au_sbinfo *sinfo);
3151 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
3152 +struct au_opt_add;
3153 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
3154 +struct au_opt_del;
3155 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
3156 +long au_ibusy_ioctl(struct file *file, unsigned long arg);
3157 +#ifdef CONFIG_COMPAT
3158 +long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
3159 +#endif
3160 +struct au_opt_mod;
3161 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
3162 +             int *do_refresh);
3163 +
3164 +/* xino.c */
3165 +static const loff_t au_loff_max = LLONG_MAX;
3166 +
3167 +int au_xib_trunc(struct super_block *sb);
3168 +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
3169 +                  loff_t *pos);
3170 +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
3171 +                   loff_t *pos);
3172 +struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
3173 +struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
3174 +ino_t au_xino_new_ino(struct super_block *sb);
3175 +void au_xino_delete_inode(struct inode *inode, const int unlinked);
3176 +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3177 +                 ino_t ino);
3178 +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3179 +                ino_t *ino);
3180 +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
3181 +              struct file *base_file, int do_test);
3182 +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
3183 +
3184 +struct au_opt_xino;
3185 +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
3186 +void au_xino_clr(struct super_block *sb);
3187 +struct file *au_xino_def(struct super_block *sb);
3188 +int au_xino_path(struct seq_file *seq, struct file *file);
3189 +
3190 +/* ---------------------------------------------------------------------- */
3191 +
3192 +/* Superblock to branch */
3193 +static inline
3194 +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
3195 +{
3196 +       return au_sbr(sb, bindex)->br_id;
3197 +}
3198 +
3199 +static inline
3200 +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
3201 +{
3202 +       return au_sbr(sb, bindex)->br_mnt;
3203 +}
3204 +
3205 +static inline
3206 +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
3207 +{
3208 +       return au_sbr_mnt(sb, bindex)->mnt_sb;
3209 +}
3210 +
3211 +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
3212 +{
3213 +       atomic_dec(&au_sbr(sb, bindex)->br_count);
3214 +}
3215 +
3216 +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
3217 +{
3218 +       return au_sbr(sb, bindex)->br_perm;
3219 +}
3220 +
3221 +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
3222 +{
3223 +       return au_br_whable(au_sbr_perm(sb, bindex));
3224 +}
3225 +
3226 +/* ---------------------------------------------------------------------- */
3227 +
3228 +/*
3229 + * wbr_wh_read_lock, wbr_wh_write_lock
3230 + * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
3231 + */
3232 +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
3233 +
3234 +#define WbrWhMustNoWaiters(wbr)        AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
3235 +#define WbrWhMustAnyLock(wbr)  AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
3236 +#define WbrWhMustWriteLock(wbr)        AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
3237 +
3238 +#endif /* __KERNEL__ */
3239 +#endif /* __AUFS_BRANCH_H__ */
3240 diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
3241 --- /usr/share/empty/fs/aufs/conf.mk    1970-01-01 01:00:00.000000000 +0100
3242 +++ linux/fs/aufs/conf.mk       2012-08-26 08:39:00.757174634 +0200
3243 @@ -0,0 +1,38 @@
3244 +
3245 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
3246 +
3247 +define AuConf
3248 +ifdef ${1}
3249 +AuConfStr += ${1}=${${1}}
3250 +endif
3251 +endef
3252 +
3253 +AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
3254 +       SBILIST \
3255 +       HNOTIFY HFSNOTIFY \
3256 +       EXPORT INO_T_64 \
3257 +       RDU \
3258 +       PROC_MAP \
3259 +       SP_IATTR \
3260 +       SHWH \
3261 +       BR_RAMFS \
3262 +       BR_FUSE POLL \
3263 +       BR_HFSPLUS \
3264 +       BDEV_LOOP \
3265 +       DEBUG MAGIC_SYSRQ
3266 +$(foreach i, ${AuConfAll}, \
3267 +       $(eval $(call AuConf,CONFIG_AUFS_${i})))
3268 +
3269 +AuConfName = ${obj}/conf.str
3270 +${AuConfName}.tmp: FORCE
3271 +       @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
3272 +${AuConfName}: ${AuConfName}.tmp
3273 +       @diff -q $< $@ > /dev/null 2>&1 || { \
3274 +       echo '  GEN    ' $@; \
3275 +       cp -p $< $@; \
3276 +       }
3277 +FORCE:
3278 +clean-files += ${AuConfName} ${AuConfName}.tmp
3279 +${obj}/sysfs.o: ${AuConfName}
3280 +
3281 +-include ${srctree}/${src}/conf_priv.mk
3282 diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
3283 --- /usr/share/empty/fs/aufs/cpup.c     1970-01-01 01:00:00.000000000 +0100
3284 +++ linux/fs/aufs/cpup.c        2013-01-11 19:46:28.699667650 +0100
3285 @@ -0,0 +1,1085 @@
3286 +/*
3287 + * Copyright (C) 2005-2013 Junjiro R. Okajima
3288 + *
3289 + * This program, aufs is free software; you can redistribute it and/or modify
3290 + * it under the terms of the GNU General Public License as published by
3291 + * the Free Software Foundation; either version 2 of the License, or
3292 + * (at your option) any later version.
3293 + *
3294 + * This program is distributed in the hope that it will be useful,
3295 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3296 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3297 + * GNU General Public License for more details.
3298 + *
3299 + * You should have received a copy of the GNU General Public License
3300 + * along with this program; if not, write to the Free Software
3301 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
3302 + */
3303 +
3304 +/*
3305 + * copy-up functions, see wbr_policy.c for copy-down
3306 + */
3307 +
3308 +#include <linux/fs_stack.h>
3309 +#include <linux/mm.h>
3310 +#include "aufs.h"
3311 +
3312 +void au_cpup_attr_flags(struct inode *dst, struct inode *src)
3313 +{
3314 +       const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
3315 +               | S_NOATIME | S_NOCMTIME;
3316 +
3317 +       dst->i_flags |= src->i_flags & ~mask;
3318 +       if (au_test_fs_notime(dst->i_sb))
3319 +               dst->i_flags |= S_NOATIME | S_NOCMTIME;
3320 +}
3321 +
3322 +void au_cpup_attr_timesizes(struct inode *inode)
3323 +{
3324 +       struct inode *h_inode;
3325 +
3326 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
3327 +       fsstack_copy_attr_times(inode, h_inode);
3328 +       fsstack_copy_inode_size(inode, h_inode);
3329 +}
3330 +
3331 +void au_cpup_attr_nlink(struct inode *inode, int force)
3332 +{
3333 +       struct inode *h_inode;
3334 +       struct super_block *sb;
3335 +       aufs_bindex_t bindex, bend;
3336 +
3337 +       sb = inode->i_sb;
3338 +       bindex = au_ibstart(inode);
3339 +       h_inode = au_h_iptr(inode, bindex);
3340 +       if (!force
3341 +           && !S_ISDIR(h_inode->i_mode)
3342 +           && au_opt_test(au_mntflags(sb), PLINK)
3343 +           && au_plink_test(inode))
3344 +               return;
3345 +
3346 +       /*
3347 +        * 0 can happen in revalidating.
3348 +        * h_inode->i_mutex is not held, but it is harmless since once i_nlink
3349 +        * reaches 0, it will never become positive.
3350 +        */
3351 +       set_nlink(inode, h_inode->i_nlink);
3352 +
3353 +       /*
3354 +        * fewer nlink makes find(1) noisy, but larger nlink doesn't.
3355 +        * it may includes whplink directory.
3356 +        */
3357 +       if (S_ISDIR(h_inode->i_mode)) {
3358 +               bend = au_ibend(inode);
3359 +               for (bindex++; bindex <= bend; bindex++) {
3360 +                       h_inode = au_h_iptr(inode, bindex);
3361 +                       if (h_inode)
3362 +                               au_add_nlink(inode, h_inode);
3363 +               }
3364 +       }
3365 +}
3366 +
3367 +void au_cpup_attr_changeable(struct inode *inode)
3368 +{
3369 +       struct inode *h_inode;
3370 +
3371 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
3372 +       inode->i_mode = h_inode->i_mode;
3373 +       inode->i_uid = h_inode->i_uid;
3374 +       inode->i_gid = h_inode->i_gid;
3375 +       au_cpup_attr_timesizes(inode);
3376 +       au_cpup_attr_flags(inode, h_inode);
3377 +}
3378 +
3379 +void au_cpup_igen(struct inode *inode, struct inode *h_inode)
3380 +{
3381 +       struct au_iinfo *iinfo = au_ii(inode);
3382 +
3383 +       IiMustWriteLock(inode);
3384 +
3385 +       iinfo->ii_higen = h_inode->i_generation;
3386 +       iinfo->ii_hsb1 = h_inode->i_sb;
3387 +}
3388 +
3389 +void au_cpup_attr_all(struct inode *inode, int force)
3390 +{
3391 +       struct inode *h_inode;
3392 +
3393 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
3394 +       au_cpup_attr_changeable(inode);
3395 +       if (inode->i_nlink > 0)
3396 +               au_cpup_attr_nlink(inode, force);
3397 +       inode->i_rdev = h_inode->i_rdev;
3398 +       inode->i_blkbits = h_inode->i_blkbits;
3399 +       au_cpup_igen(inode, h_inode);
3400 +}
3401 +
3402 +/* ---------------------------------------------------------------------- */
3403 +
3404 +/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
3405 +
3406 +/* keep the timestamps of the parent dir when cpup */
3407 +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
3408 +                   struct path *h_path)
3409 +{
3410 +       struct inode *h_inode;
3411 +
3412 +       dt->dt_dentry = dentry;
3413 +       dt->dt_h_path = *h_path;
3414 +       h_inode = h_path->dentry->d_inode;
3415 +       dt->dt_atime = h_inode->i_atime;
3416 +       dt->dt_mtime = h_inode->i_mtime;
3417 +       /* smp_mb(); */
3418 +}
3419 +
3420 +void au_dtime_revert(struct au_dtime *dt)
3421 +{
3422 +       struct iattr attr;
3423 +       int err;
3424 +
3425 +       attr.ia_atime = dt->dt_atime;
3426 +       attr.ia_mtime = dt->dt_mtime;
3427 +       attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
3428 +               | ATTR_ATIME | ATTR_ATIME_SET;
3429 +
3430 +       err = vfsub_notify_change(&dt->dt_h_path, &attr);
3431 +       if (unlikely(err))
3432 +               pr_warn("restoring timestamps failed(%d). ignored\n", err);
3433 +}
3434 +
3435 +/* ---------------------------------------------------------------------- */
3436 +
3437 +static noinline_for_stack
3438 +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src)
3439 +{
3440 +       int err, sbits;
3441 +       struct iattr ia;
3442 +       struct path h_path;
3443 +       struct inode *h_isrc, *h_idst;
3444 +
3445 +       h_path.dentry = au_h_dptr(dst, bindex);
3446 +       h_idst = h_path.dentry->d_inode;
3447 +       h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
3448 +       h_isrc = h_src->d_inode;
3449 +       ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
3450 +               | ATTR_ATIME | ATTR_MTIME
3451 +               | ATTR_ATIME_SET | ATTR_MTIME_SET;
3452 +       ia.ia_uid = h_isrc->i_uid;
3453 +       ia.ia_gid = h_isrc->i_gid;
3454 +       ia.ia_atime = h_isrc->i_atime;
3455 +       ia.ia_mtime = h_isrc->i_mtime;
3456 +       if (h_idst->i_mode != h_isrc->i_mode
3457 +           && !S_ISLNK(h_idst->i_mode)) {
3458 +               ia.ia_valid |= ATTR_MODE;
3459 +               ia.ia_mode = h_isrc->i_mode;
3460 +       }
3461 +       sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
3462 +       au_cpup_attr_flags(h_idst, h_isrc);
3463 +       err = vfsub_notify_change(&h_path, &ia);
3464 +
3465 +       /* is this nfs only? */
3466 +       if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
3467 +               ia.ia_valid = ATTR_FORCE | ATTR_MODE;
3468 +               ia.ia_mode = h_isrc->i_mode;
3469 +               err = vfsub_notify_change(&h_path, &ia);
3470 +       }
3471 +
3472 +       return err;
3473 +}
3474 +
3475 +/* ---------------------------------------------------------------------- */
3476 +
3477 +static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
3478 +                          char *buf, unsigned long blksize)
3479 +{
3480 +       int err;
3481 +       size_t sz, rbytes, wbytes;
3482 +       unsigned char all_zero;
3483 +       char *p, *zp;
3484 +       struct mutex *h_mtx;
3485 +       /* reduce stack usage */
3486 +       struct iattr *ia;
3487 +
3488 +       zp = page_address(ZERO_PAGE(0));
3489 +       if (unlikely(!zp))
3490 +               return -ENOMEM; /* possible? */
3491 +
3492 +       err = 0;
3493 +       all_zero = 0;
3494 +       while (len) {
3495 +               AuDbg("len %lld\n", len);
3496 +               sz = blksize;
3497 +               if (len < blksize)
3498 +                       sz = len;
3499 +
3500 +               rbytes = 0;
3501 +               /* todo: signal_pending? */
3502 +               while (!rbytes || err == -EAGAIN || err == -EINTR) {
3503 +                       rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
3504 +                       err = rbytes;
3505 +               }
3506 +               if (unlikely(err < 0))
3507 +                       break;
3508 +
3509 +               all_zero = 0;
3510 +               if (len >= rbytes && rbytes == blksize)
3511 +                       all_zero = !memcmp(buf, zp, rbytes);
3512 +               if (!all_zero) {
3513 +                       wbytes = rbytes;
3514 +                       p = buf;
3515 +                       while (wbytes) {
3516 +                               size_t b;
3517 +
3518 +                               b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
3519 +                               err = b;
3520 +                               /* todo: signal_pending? */
3521 +                               if (unlikely(err == -EAGAIN || err == -EINTR))
3522 +                                       continue;
3523 +                               if (unlikely(err < 0))
3524 +                                       break;
3525 +                               wbytes -= b;
3526 +                               p += b;
3527 +                       }
3528 +               } else {
3529 +                       loff_t res;
3530 +
3531 +                       AuLabel(hole);
3532 +                       res = vfsub_llseek(dst, rbytes, SEEK_CUR);
3533 +                       err = res;
3534 +                       if (unlikely(res < 0))
3535 +                               break;
3536 +               }
3537 +               len -= rbytes;
3538 +               err = 0;
3539 +       }
3540 +
3541 +       /* the last block may be a hole */
3542 +       if (!err && all_zero) {
3543 +               AuLabel(last hole);
3544 +
3545 +               err = 1;
3546 +               if (au_test_nfs(dst->f_dentry->d_sb)) {
3547 +                       /* nfs requires this step to make last hole */
3548 +                       /* is this only nfs? */
3549 +                       do {
3550 +                               /* todo: signal_pending? */
3551 +                               err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
3552 +                       } while (err == -EAGAIN || err == -EINTR);
3553 +                       if (err == 1)
3554 +                               dst->f_pos--;
3555 +               }
3556 +
3557 +               if (err == 1) {
3558 +                       ia = (void *)buf;
3559 +                       ia->ia_size = dst->f_pos;
3560 +                       ia->ia_valid = ATTR_SIZE | ATTR_FILE;
3561 +                       ia->ia_file = dst;
3562 +                       h_mtx = &dst->f_dentry->d_inode->i_mutex;
3563 +                       mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
3564 +                       err = vfsub_notify_change(&dst->f_path, ia);
3565 +                       mutex_unlock(h_mtx);
3566 +               }
3567 +       }
3568 +
3569 +       return err;
3570 +}
3571 +
3572 +int au_copy_file(struct file *dst, struct file *src, loff_t len)
3573 +{
3574 +       int err;
3575 +       unsigned long blksize;
3576 +       unsigned char do_kfree;
3577 +       char *buf;
3578 +
3579 +       err = -ENOMEM;
3580 +       blksize = dst->f_dentry->d_sb->s_blocksize;
3581 +       if (!blksize || PAGE_SIZE < blksize)
3582 +               blksize = PAGE_SIZE;
3583 +       AuDbg("blksize %lu\n", blksize);
3584 +       do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
3585 +       if (do_kfree)
3586 +               buf = kmalloc(blksize, GFP_NOFS);
3587 +       else
3588 +               buf = (void *)__get_free_page(GFP_NOFS);
3589 +       if (unlikely(!buf))
3590 +               goto out;
3591 +
3592 +       if (len > (1 << 22))
3593 +               AuDbg("copying a large file %lld\n", (long long)len);
3594 +
3595 +       src->f_pos = 0;
3596 +       dst->f_pos = 0;
3597 +       err = au_do_copy_file(dst, src, len, buf, blksize);
3598 +       if (do_kfree)
3599 +               kfree(buf);
3600 +       else
3601 +               free_page((unsigned long)buf);
3602 +
3603 +out:
3604 +       return err;
3605 +}
3606 +
3607 +/*
3608 + * to support a sparse file which is opened with O_APPEND,
3609 + * we need to close the file.
3610 + */
3611 +static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst,
3612 +                        aufs_bindex_t bsrc, loff_t len)
3613 +{
3614 +       int err, i;
3615 +       enum { SRC, DST };
3616 +       struct {
3617 +               aufs_bindex_t bindex;
3618 +               unsigned int flags;
3619 +               struct dentry *dentry;
3620 +               struct file *file;
3621 +               void *label, *label_file;
3622 +       } *f, file[] = {
3623 +               {
3624 +                       .bindex = bsrc,
3625 +                       .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
3626 +                       .file = NULL,
3627 +                       .label = &&out,
3628 +                       .label_file = &&out_src
3629 +               },
3630 +               {
3631 +                       .bindex = bdst,
3632 +                       .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
3633 +                       .file = NULL,
3634 +                       .label = &&out_src,
3635 +                       .label_file = &&out_dst
3636 +               }
3637 +       };
3638 +       struct super_block *sb;
3639 +
3640 +       /* bsrc branch can be ro/rw. */
3641 +       sb = dentry->d_sb;
3642 +       f = file;
3643 +       for (i = 0; i < 2; i++, f++) {
3644 +               f->dentry = au_h_dptr(dentry, f->bindex);
3645 +               f->file = au_h_open(dentry, f->bindex, f->flags, /*file*/NULL);
3646 +               err = PTR_ERR(f->file);
3647 +               if (IS_ERR(f->file))
3648 +                       goto *f->label;
3649 +               err = -EINVAL;
3650 +               if (unlikely(!f->file->f_op))
3651 +                       goto *f->label_file;
3652 +       }
3653 +
3654 +       /* try stopping to update while we copyup */
3655 +       IMustLock(file[SRC].dentry->d_inode);
3656 +       err = au_copy_file(file[DST].file, file[SRC].file, len);
3657 +
3658 +out_dst:
3659 +       fput(file[DST].file);
3660 +       au_sbr_put(sb, file[DST].bindex);
3661 +out_src:
3662 +       fput(file[SRC].file);
3663 +       au_sbr_put(sb, file[SRC].bindex);
3664 +out:
3665 +       return err;
3666 +}
3667 +
3668 +static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst,
3669 +                             aufs_bindex_t bsrc, loff_t len,
3670 +                             struct inode *h_dir, struct path *h_path)
3671 +{
3672 +       int err, rerr;
3673 +       loff_t l;
3674 +
3675 +       err = 0;
3676 +       l = i_size_read(au_h_iptr(dentry->d_inode, bsrc));
3677 +       if (len == -1 || l < len)
3678 +               len = l;
3679 +       if (len)
3680 +               err = au_cp_regular(dentry, bdst, bsrc, len);
3681 +       if (!err)
3682 +               goto out; /* success */
3683 +
3684 +       rerr = vfsub_unlink(h_dir, h_path, /*force*/0);
3685 +       if (rerr) {
3686 +               AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n",
3687 +                       AuDLNPair(h_path->dentry), err, rerr);
3688 +               err = -EIO;
3689 +       }
3690 +
3691 +out:
3692 +       return err;
3693 +}
3694 +
3695 +static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
3696 +                             struct inode *h_dir)
3697 +{
3698 +       int err, symlen;
3699 +       mm_segment_t old_fs;
3700 +       union {
3701 +               char *k;
3702 +               char __user *u;
3703 +       } sym;
3704 +
3705 +       err = -ENOSYS;
3706 +       if (unlikely(!h_src->d_inode->i_op->readlink))
3707 +               goto out;
3708 +
3709 +       err = -ENOMEM;
3710 +       sym.k = (void *)__get_free_page(GFP_NOFS);
3711 +       if (unlikely(!sym.k))
3712 +               goto out;
3713 +
3714 +       /* unnecessary to support mmap_sem since symlink is not mmap-able */
3715 +       old_fs = get_fs();
3716 +       set_fs(KERNEL_DS);
3717 +       symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
3718 +       err = symlen;
3719 +       set_fs(old_fs);
3720 +
3721 +       if (symlen > 0) {
3722 +               sym.k[symlen] = 0;
3723 +               err = vfsub_symlink(h_dir, h_path, sym.k);
3724 +       }
3725 +       free_page((unsigned long)sym.k);
3726 +
3727 +out:
3728 +       return err;
3729 +}
3730 +
3731 +/* return with the lower dst inode is locked */
3732 +static noinline_for_stack
3733 +int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst,
3734 +              aufs_bindex_t bsrc, loff_t len, unsigned int flags,
3735 +              struct dentry *dst_parent)
3736 +{
3737 +       int err;
3738 +       umode_t mode;
3739 +       unsigned int mnt_flags;
3740 +       unsigned char isdir;
3741 +       const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME);
3742 +       struct au_dtime dt;
3743 +       struct path h_path;
3744 +       struct dentry *h_src, *h_dst, *h_parent;
3745 +       struct inode *h_inode, *h_dir;
3746 +       struct super_block *sb;
3747 +
3748 +       /* bsrc branch can be ro/rw. */
3749 +       h_src = au_h_dptr(dentry, bsrc);
3750 +       h_inode = h_src->d_inode;
3751 +       AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc));
3752 +
3753 +       /* try stopping to be referenced while we are creating */
3754 +       h_dst = au_h_dptr(dentry, bdst);
3755 +       h_parent = h_dst->d_parent; /* dir inode is locked */
3756 +       h_dir = h_parent->d_inode;
3757 +       IMustLock(h_dir);
3758 +       AuDebugOn(h_parent != h_dst->d_parent);
3759 +
3760 +       sb = dentry->d_sb;
3761 +       h_path.mnt = au_sbr_mnt(sb, bdst);
3762 +       if (do_dt) {
3763 +               h_path.dentry = h_parent;
3764 +               au_dtime_store(&dt, dst_parent, &h_path);
3765 +       }
3766 +       h_path.dentry = h_dst;
3767 +
3768 +       isdir = 0;
3769 +       mode = h_inode->i_mode;
3770 +       switch (mode & S_IFMT) {
3771 +       case S_IFREG:
3772 +               /* try stopping to update while we are referencing */
3773 +               IMustLock(h_inode);
3774 +               err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
3775 +                                  /*want_excl*/true);
3776 +               if (!err)
3777 +                       err = au_do_cpup_regular
3778 +                               (dentry, bdst, bsrc, len,
3779 +                                au_h_iptr(dst_parent->d_inode, bdst), &h_path);
3780 +               break;
3781 +       case S_IFDIR:
3782 +               isdir = 1;
3783 +               err = vfsub_mkdir(h_dir, &h_path, mode);
3784 +               if (!err) {
3785 +                       /*
3786 +                        * strange behaviour from the users view,
3787 +                        * particularry setattr case
3788 +                        */
3789 +                       if (au_ibstart(dst_parent->d_inode) == bdst)
3790 +                               au_cpup_attr_nlink(dst_parent->d_inode,
3791 +                                                  /*force*/1);
3792 +                       au_cpup_attr_nlink(dentry->d_inode, /*force*/1);
3793 +               }
3794 +               break;
3795 +       case S_IFLNK:
3796 +               err = au_do_cpup_symlink(&h_path, h_src, h_dir);
3797 +               break;
3798 +       case S_IFCHR:
3799 +       case S_IFBLK:
3800 +               AuDebugOn(!capable(CAP_MKNOD));
3801 +               /*FALLTHROUGH*/
3802 +       case S_IFIFO:
3803 +       case S_IFSOCK:
3804 +               err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
3805 +               break;
3806 +       default:
3807 +               AuIOErr("Unknown inode type 0%o\n", mode);
3808 +               err = -EIO;
3809 +       }
3810 +
3811 +       mnt_flags = au_mntflags(sb);
3812 +       if (!au_opt_test(mnt_flags, UDBA_NONE)
3813 +           && !isdir
3814 +           && au_opt_test(mnt_flags, XINO)
3815 +           && h_inode->i_nlink == 1
3816 +           /* todo: unnecessary? */
3817 +           /* && dentry->d_inode->i_nlink == 1 */
3818 +           && bdst < bsrc
3819 +           && !au_ftest_cpup(flags, KEEPLINO))
3820 +               au_xino_write(sb, bsrc, h_inode->i_ino, /*ino*/0);
3821 +               /* ignore this error */
3822 +
3823 +       if (do_dt)
3824 +               au_dtime_revert(&dt);
3825 +       return err;
3826 +}
3827 +
3828 +/*
3829 + * copyup the @dentry from @bsrc to @bdst.
3830 + * the caller must set the both of lower dentries.
3831 + * @len is for truncating when it is -1 copyup the entire file.
3832 + * in link/rename cases, @dst_parent may be different from the real one.
3833 + */
3834 +static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
3835 +                         aufs_bindex_t bsrc, loff_t len, unsigned int flags,
3836 +                         struct dentry *dst_parent)
3837 +{
3838 +       int err, rerr;
3839 +       aufs_bindex_t old_ibstart;
3840 +       unsigned char isdir, plink;
3841 +       struct au_dtime dt;
3842 +       struct path h_path;
3843 +       struct dentry *h_src, *h_dst, *h_parent;
3844 +       struct inode *dst_inode, *h_dir, *inode;
3845 +       struct super_block *sb;
3846 +
3847 +       AuDebugOn(bsrc <= bdst);
3848 +
3849 +       sb = dentry->d_sb;
3850 +       h_path.mnt = au_sbr_mnt(sb, bdst);
3851 +       h_dst = au_h_dptr(dentry, bdst);
3852 +       h_parent = h_dst->d_parent; /* dir inode is locked */
3853 +       h_dir = h_parent->d_inode;
3854 +       IMustLock(h_dir);
3855 +
3856 +       h_src = au_h_dptr(dentry, bsrc);
3857 +       inode = dentry->d_inode;
3858 +
3859 +       if (!dst_parent)
3860 +               dst_parent = dget_parent(dentry);
3861 +       else
3862 +               dget(dst_parent);
3863 +
3864 +       plink = !!au_opt_test(au_mntflags(sb), PLINK);
3865 +       dst_inode = au_h_iptr(inode, bdst);
3866 +       if (dst_inode) {
3867 +               if (unlikely(!plink)) {
3868 +                       err = -EIO;
3869 +                       AuIOErr("hi%lu(i%lu) exists on b%d "
3870 +                               "but plink is disabled\n",
3871 +                               dst_inode->i_ino, inode->i_ino, bdst);
3872 +                       goto out;
3873 +               }
3874 +
3875 +               if (dst_inode->i_nlink) {
3876 +                       const int do_dt = au_ftest_cpup(flags, DTIME);
3877 +
3878 +                       h_src = au_plink_lkup(inode, bdst);
3879 +                       err = PTR_ERR(h_src);
3880 +                       if (IS_ERR(h_src))
3881 +                               goto out;
3882 +                       if (unlikely(!h_src->d_inode)) {
3883 +                               err = -EIO;
3884 +                               AuIOErr("i%lu exists on a upper branch "
3885 +                                       "but not pseudo-linked\n",
3886 +                                       inode->i_ino);
3887 +                               dput(h_src);
3888 +                               goto out;
3889 +                       }
3890 +
3891 +                       if (do_dt) {
3892 +                               h_path.dentry = h_parent;
3893 +                               au_dtime_store(&dt, dst_parent, &h_path);
3894 +                       }
3895 +                       h_path.dentry = h_dst;
3896 +                       err = vfsub_link(h_src, h_dir, &h_path);
3897 +                       if (do_dt)
3898 +                               au_dtime_revert(&dt);
3899 +                       dput(h_src);
3900 +                       goto out;
3901 +               } else
3902 +                       /* todo: cpup_wh_file? */
3903 +                       /* udba work */
3904 +                       au_update_ibrange(inode, /*do_put_zero*/1);
3905 +       }
3906 +
3907 +       old_ibstart = au_ibstart(inode);
3908 +       err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent);
3909 +       if (unlikely(err))
3910 +               goto out;
3911 +       dst_inode = h_dst->d_inode;
3912 +       mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
3913 +
3914 +       err = cpup_iattr(dentry, bdst, h_src);
3915 +       isdir = S_ISDIR(dst_inode->i_mode);
3916 +       if (!err) {
3917 +               if (bdst < old_ibstart) {
3918 +                       if (S_ISREG(inode->i_mode)) {
3919 +                               err = au_dy_iaop(inode, bdst, dst_inode);
3920 +                               if (unlikely(err))
3921 +                                       goto out_rev;
3922 +                       }
3923 +                       au_set_ibstart(inode, bdst);
3924 +               }
3925 +               au_set_h_iptr(inode, bdst, au_igrab(dst_inode),
3926 +                             au_hi_flags(inode, isdir));
3927 +               mutex_unlock(&dst_inode->i_mutex);
3928 +               if (!isdir
3929 +                   && h_src->d_inode->i_nlink > 1
3930 +                   && plink)
3931 +                       au_plink_append(inode, bdst, h_dst);
3932 +               goto out; /* success */
3933 +       }
3934 +
3935 +       /* revert */
3936 +out_rev:
3937 +       h_path.dentry = h_parent;
3938 +       mutex_unlock(&dst_inode->i_mutex);
3939 +       au_dtime_store(&dt, dst_parent, &h_path);
3940 +       h_path.dentry = h_dst;
3941 +       if (!isdir)
3942 +               rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
3943 +       else
3944 +               rerr = vfsub_rmdir(h_dir, &h_path);
3945 +       au_dtime_revert(&dt);
3946 +       if (rerr) {
3947 +               AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
3948 +               err = -EIO;
3949 +       }
3950 +
3951 +out:
3952 +       dput(dst_parent);
3953 +       return err;
3954 +}
3955 +
3956 +struct au_cpup_single_args {
3957 +       int *errp;
3958 +       struct dentry *dentry;
3959 +       aufs_bindex_t bdst, bsrc;
3960 +       loff_t len;
3961 +       unsigned int flags;
3962 +       struct dentry *dst_parent;
3963 +};
3964 +
3965 +static void au_call_cpup_single(void *args)
3966 +{
3967 +       struct au_cpup_single_args *a = args;
3968 +       *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len,
3969 +                                 a->flags, a->dst_parent);
3970 +}
3971 +
3972 +/*
3973 + * prevent SIGXFSZ in copy-up.
3974 + * testing CAP_MKNOD is for generic fs,
3975 + * but CAP_FSETID is for xfs only, currently.
3976 + */
3977 +static int au_cpup_sio_test(struct super_block *sb, umode_t mode)
3978 +{
3979 +       int do_sio;
3980 +
3981 +       do_sio = 0;
3982 +       if (!au_wkq_test()
3983 +           && (!au_sbi(sb)->si_plink_maint_pid
3984 +               || au_plink_maint(sb, AuLock_NOPLM))) {
3985 +               switch (mode & S_IFMT) {
3986 +               case S_IFREG:
3987 +                       /* no condition about RLIMIT_FSIZE and the file size */
3988 +                       do_sio = 1;
3989 +                       break;
3990 +               case S_IFCHR:
3991 +               case S_IFBLK:
3992 +                       do_sio = !capable(CAP_MKNOD);
3993 +                       break;
3994 +               }
3995 +               if (!do_sio)
3996 +                       do_sio = ((mode & (S_ISUID | S_ISGID))
3997 +                                 && !capable(CAP_FSETID));
3998 +       }
3999 +
4000 +       return do_sio;
4001 +}
4002 +
4003 +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
4004 +                      aufs_bindex_t bsrc, loff_t len, unsigned int flags,
4005 +                      struct dentry *dst_parent)
4006 +{
4007 +       int err, wkq_err;
4008 +       struct dentry *h_dentry;
4009 +
4010 +       h_dentry = au_h_dptr(dentry, bsrc);
4011 +       if (!au_cpup_sio_test(dentry->d_sb, h_dentry->d_inode->i_mode))
4012 +               err = au_cpup_single(dentry, bdst, bsrc, len, flags,
4013 +                                    dst_parent);
4014 +       else {
4015 +               struct au_cpup_single_args args = {
4016 +                       .errp           = &err,
4017 +                       .dentry         = dentry,
4018 +                       .bdst           = bdst,
4019 +                       .bsrc           = bsrc,
4020 +                       .len            = len,
4021 +                       .flags          = flags,
4022 +                       .dst_parent     = dst_parent
4023 +               };
4024 +               wkq_err = au_wkq_wait(au_call_cpup_single, &args);
4025 +               if (unlikely(wkq_err))
4026 +                       err = wkq_err;
4027 +       }
4028 +
4029 +       return err;
4030 +}
4031 +
4032 +/*
4033 + * copyup the @dentry from the first active lower branch to @bdst,
4034 + * using au_cpup_single().
4035 + */
4036 +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4037 +                         unsigned int flags)
4038 +{
4039 +       int err;
4040 +       aufs_bindex_t bsrc, bend;
4041 +
4042 +       bend = au_dbend(dentry);
4043 +       for (bsrc = bdst + 1; bsrc <= bend; bsrc++)
4044 +               if (au_h_dptr(dentry, bsrc))
4045 +                       break;
4046 +
4047 +       err = au_lkup_neg(dentry, bdst);
4048 +       if (!err) {
4049 +               err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL);
4050 +               if (!err)
4051 +                       return 0; /* success */
4052 +
4053 +               /* revert */
4054 +               au_set_h_dptr(dentry, bdst, NULL);
4055 +               au_set_dbstart(dentry, bsrc);
4056 +       }
4057 +
4058 +       return err;
4059 +}
4060 +
4061 +struct au_cpup_simple_args {
4062 +       int *errp;
4063 +       struct dentry *dentry;
4064 +       aufs_bindex_t bdst;
4065 +       loff_t len;
4066 +       unsigned int flags;
4067 +};
4068 +
4069 +static void au_call_cpup_simple(void *args)
4070 +{
4071 +       struct au_cpup_simple_args *a = args;
4072 +       *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags);
4073 +}
4074 +
4075 +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4076 +                      unsigned int flags)
4077 +{
4078 +       int err, wkq_err;
4079 +       struct dentry *parent;
4080 +       struct inode *h_dir;
4081 +
4082 +       parent = dget_parent(dentry);
4083 +       h_dir = au_h_iptr(parent->d_inode, bdst);
4084 +       if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
4085 +           && !au_cpup_sio_test(dentry->d_sb, dentry->d_inode->i_mode))
4086 +               err = au_cpup_simple(dentry, bdst, len, flags);
4087 +       else {
4088 +               struct au_cpup_simple_args args = {
4089 +                       .errp           = &err,
4090 +                       .dentry         = dentry,
4091 +                       .bdst           = bdst,
4092 +                       .len            = len,
4093 +                       .flags          = flags
4094 +               };
4095 +               wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
4096 +               if (unlikely(wkq_err))
4097 +                       err = wkq_err;
4098 +       }
4099 +
4100 +       dput(parent);
4101 +       return err;
4102 +}
4103 +
4104 +/* ---------------------------------------------------------------------- */
4105 +
4106 +/*
4107 + * copyup the deleted file for writing.
4108 + */
4109 +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
4110 +                        struct dentry *wh_dentry, struct file *file,
4111 +                        loff_t len)
4112 +{
4113 +       int err;
4114 +       aufs_bindex_t bstart;
4115 +       struct au_dinfo *dinfo;
4116 +       struct dentry *h_d_dst, *h_d_start;
4117 +       struct au_hdentry *hdp;
4118 +
4119 +       dinfo = au_di(dentry);
4120 +       AuRwMustWriteLock(&dinfo->di_rwsem);
4121 +
4122 +       bstart = dinfo->di_bstart;
4123 +       hdp = dinfo->di_hdentry;
4124 +       h_d_dst = hdp[0 + bdst].hd_dentry;
4125 +       dinfo->di_bstart = bdst;
4126 +       hdp[0 + bdst].hd_dentry = wh_dentry;
4127 +       if (file) {
4128 +               h_d_start = hdp[0 + bstart].hd_dentry;
4129 +               hdp[0 + bstart].hd_dentry = au_hf_top(file)->f_dentry;
4130 +       }
4131 +       err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME,
4132 +                            /*h_parent*/NULL);
4133 +       if (file) {
4134 +               if (!err)
4135 +                       err = au_reopen_nondir(file);
4136 +               hdp[0 + bstart].hd_dentry = h_d_start;
4137 +       }
4138 +       hdp[0 + bdst].hd_dentry = h_d_dst;
4139 +       dinfo->di_bstart = bstart;
4140 +
4141 +       return err;
4142 +}
4143 +
4144 +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4145 +                     struct file *file)
4146 +{
4147 +       int err;
4148 +       struct au_dtime dt;
4149 +       struct dentry *parent, *h_parent, *wh_dentry;
4150 +       struct au_branch *br;
4151 +       struct path h_path;
4152 +
4153 +       br = au_sbr(dentry->d_sb, bdst);
4154 +       parent = dget_parent(dentry);
4155 +       h_parent = au_h_dptr(parent, bdst);
4156 +       wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
4157 +       err = PTR_ERR(wh_dentry);
4158 +       if (IS_ERR(wh_dentry))
4159 +               goto out;
4160 +
4161 +       h_path.dentry = h_parent;
4162 +       h_path.mnt = br->br_mnt;
4163 +       au_dtime_store(&dt, parent, &h_path);
4164 +       err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len);
4165 +       if (unlikely(err))
4166 +               goto out_wh;
4167 +
4168 +       dget(wh_dentry);
4169 +       h_path.dentry = wh_dentry;
4170 +       if (!S_ISDIR(wh_dentry->d_inode->i_mode))
4171 +               err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0);
4172 +       else
4173 +               err = vfsub_rmdir(h_parent->d_inode, &h_path);
4174 +       if (unlikely(err)) {
4175 +               AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
4176 +                       AuDLNPair(wh_dentry), err);
4177 +               err = -EIO;
4178 +       }
4179 +       au_dtime_revert(&dt);
4180 +       au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
4181 +
4182 +out_wh:
4183 +       dput(wh_dentry);
4184 +out:
4185 +       dput(parent);
4186 +       return err;
4187 +}
4188 +
4189 +struct au_cpup_wh_args {
4190 +       int *errp;
4191 +       struct dentry *dentry;
4192 +       aufs_bindex_t bdst;
4193 +       loff_t len;
4194 +       struct file *file;
4195 +};
4196 +
4197 +static void au_call_cpup_wh(void *args)
4198 +{
4199 +       struct au_cpup_wh_args *a = args;
4200 +       *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file);
4201 +}
4202 +
4203 +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4204 +                  struct file *file)
4205 +{
4206 +       int err, wkq_err;
4207 +       struct dentry *parent, *h_orph, *h_parent, *h_dentry;
4208 +       struct inode *dir, *h_dir, *h_tmpdir, *h_inode;
4209 +       struct au_wbr *wbr;
4210 +
4211 +       parent = dget_parent(dentry);
4212 +       dir = parent->d_inode;
4213 +       h_orph = NULL;
4214 +       h_parent = NULL;
4215 +       h_dir = au_igrab(au_h_iptr(dir, bdst));
4216 +       h_tmpdir = h_dir;
4217 +       if (!h_dir->i_nlink) {
4218 +               wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
4219 +               h_orph = wbr->wbr_orph;
4220 +
4221 +               h_parent = dget(au_h_dptr(parent, bdst));
4222 +               au_set_h_dptr(parent, bdst, dget(h_orph));
4223 +               h_tmpdir = h_orph->d_inode;
4224 +               au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
4225 +
4226 +               /* this temporary unlock is safe */
4227 +               if (file)
4228 +                       h_dentry = au_hf_top(file)->f_dentry;
4229 +               else
4230 +                       h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
4231 +               h_inode = h_dentry->d_inode;
4232 +               IMustLock(h_inode);
4233 +               mutex_unlock(&h_inode->i_mutex);
4234 +               mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4235 +               mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
4236 +               /* todo: au_h_open_pre()? */
4237 +       }
4238 +
4239 +       if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
4240 +           && !au_cpup_sio_test(dentry->d_sb, dentry->d_inode->i_mode))
4241 +               err = au_cpup_wh(dentry, bdst, len, file);
4242 +       else {
4243 +               struct au_cpup_wh_args args = {
4244 +                       .errp   = &err,
4245 +                       .dentry = dentry,
4246 +                       .bdst   = bdst,
4247 +                       .len    = len,
4248 +                       .file   = file
4249 +               };
4250 +               wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
4251 +               if (unlikely(wkq_err))
4252 +                       err = wkq_err;
4253 +       }
4254 +
4255 +       if (h_orph) {
4256 +               mutex_unlock(&h_tmpdir->i_mutex);
4257 +               /* todo: au_h_open_post()? */
4258 +               au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
4259 +               au_set_h_dptr(parent, bdst, h_parent);
4260 +       }
4261 +       iput(h_dir);
4262 +       dput(parent);
4263 +
4264 +       return err;
4265 +}
4266 +
4267 +/* ---------------------------------------------------------------------- */
4268 +
4269 +/*
4270 + * generic routine for both of copy-up and copy-down.
4271 + */
4272 +/* cf. revalidate function in file.c */
4273 +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4274 +              int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
4275 +                        struct dentry *h_parent, void *arg),
4276 +              void *arg)
4277 +{
4278 +       int err;
4279 +       struct au_pin pin;
4280 +       struct dentry *d, *parent, *h_parent, *real_parent;
4281 +
4282 +       err = 0;
4283 +       parent = dget_parent(dentry);
4284 +       if (IS_ROOT(parent))
4285 +               goto out;
4286 +
4287 +       au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
4288 +                   au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
4289 +
4290 +       /* do not use au_dpage */
4291 +       real_parent = parent;
4292 +       while (1) {
4293 +               dput(parent);
4294 +               parent = dget_parent(dentry);
4295 +               h_parent = au_h_dptr(parent, bdst);
4296 +               if (h_parent)
4297 +                       goto out; /* success */
4298 +
4299 +               /* find top dir which is necessary to cpup */
4300 +               do {
4301 +                       d = parent;
4302 +                       dput(parent);
4303 +                       parent = dget_parent(d);
4304 +                       di_read_lock_parent3(parent, !AuLock_IR);
4305 +                       h_parent = au_h_dptr(parent, bdst);
4306 +                       di_read_unlock(parent, !AuLock_IR);
4307 +               } while (!h_parent);
4308 +
4309 +               if (d != real_parent)
4310 +                       di_write_lock_child3(d);
4311 +
4312 +               /* somebody else might create while we were sleeping */
4313 +               if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
4314 +                       if (au_h_dptr(d, bdst))
4315 +                               au_update_dbstart(d);
4316 +
4317 +                       au_pin_set_dentry(&pin, d);
4318 +                       err = au_do_pin(&pin);
4319 +                       if (!err) {
4320 +                               err = cp(d, bdst, h_parent, arg);
4321 +                               au_unpin(&pin);
4322 +                       }
4323 +               }
4324 +
4325 +               if (d != real_parent)
4326 +                       di_write_unlock(d);
4327 +               if (unlikely(err))
4328 +                       break;
4329 +       }
4330 +
4331 +out:
4332 +       dput(parent);
4333 +       return err;
4334 +}
4335 +
4336 +static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
4337 +                      struct dentry *h_parent __maybe_unused ,
4338 +                      void *arg __maybe_unused)
4339 +{
4340 +       return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME);
4341 +}
4342 +
4343 +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4344 +{
4345 +       return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
4346 +}
4347 +
4348 +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4349 +{
4350 +       int err;
4351 +       struct dentry *parent;
4352 +       struct inode *dir;
4353 +
4354 +       parent = dget_parent(dentry);
4355 +       dir = parent->d_inode;
4356 +       err = 0;
4357 +       if (au_h_iptr(dir, bdst))
4358 +               goto out;
4359 +
4360 +       di_read_unlock(parent, AuLock_IR);
4361 +       di_write_lock_parent(parent);
4362 +       /* someone else might change our inode while we were sleeping */
4363 +       if (!au_h_iptr(dir, bdst))
4364 +               err = au_cpup_dirs(dentry, bdst);
4365 +       di_downgrade_lock(parent, AuLock_IR);
4366 +
4367 +out:
4368 +       dput(parent);
4369 +       return err;
4370 +}
4371 diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
4372 --- /usr/share/empty/fs/aufs/cpup.h     1970-01-01 01:00:00.000000000 +0100
4373 +++ linux/fs/aufs/cpup.h        2013-01-11 19:46:12.635947932 +0100
4374 @@ -0,0 +1,81 @@
4375 +/*
4376 + * Copyright (C) 2005-2013 Junjiro R. Okajima
4377 + *
4378 + * This program, aufs is free software; you can redistribute it and/or modify
4379 + * it under the terms of the GNU General Public License as published by
4380 + * the Free Software Foundation; either version 2 of the License, or
4381 + * (at your option) any later version.
4382 + *
4383 + * This program is distributed in the hope that it will be useful,
4384 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4385 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4386 + * GNU General Public License for more details.
4387 + *
4388 + * You should have received a copy of the GNU General Public License
4389 + * along with this program; if not, write to the Free Software
4390 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
4391 + */
4392 +
4393 +/*
4394 + * copy-up/down functions
4395 + */
4396 +
4397 +#ifndef __AUFS_CPUP_H__
4398 +#define __AUFS_CPUP_H__
4399 +
4400 +#ifdef __KERNEL__
4401 +
4402 +#include <linux/path.h>
4403 +
4404 +struct inode;
4405 +struct file;
4406 +
4407 +void au_cpup_attr_flags(struct inode *dst, struct inode *src);
4408 +void au_cpup_attr_timesizes(struct inode *inode);
4409 +void au_cpup_attr_nlink(struct inode *inode, int force);
4410 +void au_cpup_attr_changeable(struct inode *inode);
4411 +void au_cpup_igen(struct inode *inode, struct inode *h_inode);
4412 +void au_cpup_attr_all(struct inode *inode, int force);
4413 +
4414 +/* ---------------------------------------------------------------------- */
4415 +
4416 +/* cpup flags */
4417 +#define AuCpup_DTIME   1               /* do dtime_store/revert */
4418 +#define AuCpup_KEEPLINO        (1 << 1)        /* do not clear the lower xino,
4419 +                                          for link(2) */
4420 +#define au_ftest_cpup(flags, name)     ((flags) & AuCpup_##name)
4421 +#define au_fset_cpup(flags, name) \
4422 +       do { (flags) |= AuCpup_##name; } while (0)
4423 +#define au_fclr_cpup(flags, name) \
4424 +       do { (flags) &= ~AuCpup_##name; } while (0)
4425 +
4426 +int au_copy_file(struct file *dst, struct file *src, loff_t len);
4427 +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
4428 +                      aufs_bindex_t bsrc, loff_t len, unsigned int flags,
4429 +                      struct dentry *dst_parent);
4430 +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4431 +                      unsigned int flags);
4432 +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4433 +                  struct file *file);
4434 +
4435 +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4436 +              int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
4437 +                        struct dentry *h_parent, void *arg),
4438 +              void *arg);
4439 +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4440 +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4441 +
4442 +/* ---------------------------------------------------------------------- */
4443 +
4444 +/* keep timestamps when copyup */
4445 +struct au_dtime {
4446 +       struct dentry *dt_dentry;
4447 +       struct path dt_h_path;
4448 +       struct timespec dt_atime, dt_mtime;
4449 +};
4450 +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4451 +                   struct path *h_path);
4452 +void au_dtime_revert(struct au_dtime *dt);
4453 +
4454 +#endif /* __KERNEL__ */
4455 +#endif /* __AUFS_CPUP_H__ */
4456 diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
4457 --- /usr/share/empty/fs/aufs/dbgaufs.c  1970-01-01 01:00:00.000000000 +0100
4458 +++ linux/fs/aufs/dbgaufs.c     2013-01-11 19:46:12.635947932 +0100
4459 @@ -0,0 +1,334 @@
4460 +/*
4461 + * Copyright (C) 2005-2013 Junjiro R. Okajima
4462 + *
4463 + * This program, aufs is free software; you can redistribute it and/or modify
4464 + * it under the terms of the GNU General Public License as published by
4465 + * the Free Software Foundation; either version 2 of the License, or
4466 + * (at your option) any later version.
4467 + *
4468 + * This program is distributed in the hope that it will be useful,
4469 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4470 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4471 + * GNU General Public License for more details.
4472 + *
4473 + * You should have received a copy of the GNU General Public License
4474 + * along with this program; if not, write to the Free Software
4475 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
4476 + */
4477 +
4478 +/*
4479 + * debugfs interface
4480 + */
4481 +
4482 +#include <linux/debugfs.h>
4483 +#include "aufs.h"
4484 +
4485 +#ifndef CONFIG_SYSFS
4486 +#error DEBUG_FS depends upon SYSFS
4487 +#endif
4488 +
4489 +static struct dentry *dbgaufs;
4490 +static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
4491 +
4492 +/* 20 is max digits length of ulong 64 */
4493 +struct dbgaufs_arg {
4494 +       int n;
4495 +       char a[20 * 4];
4496 +};
4497 +
4498 +/*
4499 + * common function for all XINO files
4500 + */
4501 +static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
4502 +                             struct file *file)
4503 +{
4504 +       kfree(file->private_data);
4505 +       return 0;
4506 +}
4507 +
4508 +static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
4509 +{
4510 +       int err;
4511 +       struct kstat st;
4512 +       struct dbgaufs_arg *p;
4513 +
4514 +       err = -ENOMEM;
4515 +       p = kmalloc(sizeof(*p), GFP_NOFS);
4516 +       if (unlikely(!p))
4517 +               goto out;
4518 +
4519 +       err = 0;
4520 +       p->n = 0;
4521 +       file->private_data = p;
4522 +       if (!xf)
4523 +               goto out;
4524 +
4525 +       err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st);
4526 +       if (!err) {
4527 +               if (do_fcnt)
4528 +                       p->n = snprintf
4529 +                               (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
4530 +                                (long)file_count(xf), st.blocks, st.blksize,
4531 +                                (long long)st.size);
4532 +               else
4533 +                       p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
4534 +                                       st.blocks, st.blksize,
4535 +                                       (long long)st.size);
4536 +               AuDebugOn(p->n >= sizeof(p->a));
4537 +       } else {
4538 +               p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
4539 +               err = 0;
4540 +       }
4541 +
4542 +out:
4543 +       return err;
4544 +
4545 +}
4546 +
4547 +static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
4548 +                              size_t count, loff_t *ppos)
4549 +{
4550 +       struct dbgaufs_arg *p;
4551 +
4552 +       p = file->private_data;
4553 +       return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
4554 +}
4555 +
4556 +/* ---------------------------------------------------------------------- */
4557 +
4558 +static int dbgaufs_xib_open(struct inode *inode, struct file *file)
4559 +{
4560 +       int err;
4561 +       struct au_sbinfo *sbinfo;
4562 +       struct super_block *sb;
4563 +
4564 +       sbinfo = inode->i_private;
4565 +       sb = sbinfo->si_sb;
4566 +       si_noflush_read_lock(sb);
4567 +       err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
4568 +       si_read_unlock(sb);
4569 +       return err;
4570 +}
4571 +
4572 +static const struct file_operations dbgaufs_xib_fop = {
4573 +       .owner          = THIS_MODULE,
4574 +       .open           = dbgaufs_xib_open,
4575 +       .release        = dbgaufs_xi_release,
4576 +       .read           = dbgaufs_xi_read
4577 +};
4578 +
4579 +/* ---------------------------------------------------------------------- */
4580 +
4581 +#define DbgaufsXi_PREFIX "xi"
4582 +
4583 +static int dbgaufs_xino_open(struct inode *inode, struct file *file)
4584 +{
4585 +       int err;
4586 +       long l;
4587 +       struct au_sbinfo *sbinfo;
4588 +       struct super_block *sb;
4589 +       struct file *xf;
4590 +       struct qstr *name;
4591 +
4592 +       err = -ENOENT;
4593 +       xf = NULL;
4594 +       name = &file->f_dentry->d_name;
4595 +       if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
4596 +                    || memcmp(name->name, DbgaufsXi_PREFIX,
4597 +                              sizeof(DbgaufsXi_PREFIX) - 1)))
4598 +               goto out;
4599 +       err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
4600 +       if (unlikely(err))
4601 +               goto out;
4602 +
4603 +       sbinfo = inode->i_private;
4604 +       sb = sbinfo->si_sb;
4605 +       si_noflush_read_lock(sb);
4606 +       if (l <= au_sbend(sb)) {
4607 +               xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
4608 +               err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
4609 +       } else
4610 +               err = -ENOENT;
4611 +       si_read_unlock(sb);
4612 +
4613 +out:
4614 +       return err;
4615 +}
4616 +
4617 +static const struct file_operations dbgaufs_xino_fop = {
4618 +       .owner          = THIS_MODULE,
4619 +       .open           = dbgaufs_xino_open,
4620 +       .release        = dbgaufs_xi_release,
4621 +       .read           = dbgaufs_xi_read
4622 +};
4623 +
4624 +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
4625 +{
4626 +       aufs_bindex_t bend;
4627 +       struct au_branch *br;
4628 +       struct au_xino_file *xi;
4629 +
4630 +       if (!au_sbi(sb)->si_dbgaufs)
4631 +               return;
4632 +
4633 +       bend = au_sbend(sb);
4634 +       for (; bindex <= bend; bindex++) {
4635 +               br = au_sbr(sb, bindex);
4636 +               xi = &br->br_xino;
4637 +               if (xi->xi_dbgaufs) {
4638 +                       debugfs_remove(xi->xi_dbgaufs);
4639 +                       xi->xi_dbgaufs = NULL;
4640 +               }
4641 +       }
4642 +}
4643 +
4644 +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
4645 +{
4646 +       struct au_sbinfo *sbinfo;
4647 +       struct dentry *parent;
4648 +       struct au_branch *br;
4649 +       struct au_xino_file *xi;
4650 +       aufs_bindex_t bend;
4651 +       char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
4652 +
4653 +       sbinfo = au_sbi(sb);
4654 +       parent = sbinfo->si_dbgaufs;
4655 +       if (!parent)
4656 +               return;
4657 +
4658 +       bend = au_sbend(sb);
4659 +       for (; bindex <= bend; bindex++) {
4660 +               snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
4661 +               br = au_sbr(sb, bindex);
4662 +               xi = &br->br_xino;
4663 +               AuDebugOn(xi->xi_dbgaufs);
4664 +               xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
4665 +                                                    sbinfo, &dbgaufs_xino_fop);
4666 +               /* ignore an error */
4667 +               if (unlikely(!xi->xi_dbgaufs))
4668 +                       AuWarn1("failed %s under debugfs\n", name);
4669 +       }
4670 +}
4671 +
4672 +/* ---------------------------------------------------------------------- */
4673 +
4674 +#ifdef CONFIG_AUFS_EXPORT
4675 +static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
4676 +{
4677 +       int err;
4678 +       struct au_sbinfo *sbinfo;
4679 +       struct super_block *sb;
4680 +
4681 +       sbinfo = inode->i_private;
4682 +       sb = sbinfo->si_sb;
4683 +       si_noflush_read_lock(sb);
4684 +       err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
4685 +       si_read_unlock(sb);
4686 +       return err;
4687 +}
4688 +
4689 +static const struct file_operations dbgaufs_xigen_fop = {
4690 +       .owner          = THIS_MODULE,
4691 +       .open           = dbgaufs_xigen_open,
4692 +       .release        = dbgaufs_xi_release,
4693 +       .read           = dbgaufs_xi_read
4694 +};
4695 +
4696 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
4697 +{
4698 +       int err;
4699 +
4700 +       /*
4701 +        * This function is a dynamic '__init' fucntion actually,
4702 +        * so the tiny check for si_rwsem is unnecessary.
4703 +        */
4704 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
4705 +
4706 +       err = -EIO;
4707 +       sbinfo->si_dbgaufs_xigen = debugfs_create_file
4708 +               ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
4709 +                &dbgaufs_xigen_fop);
4710 +       if (sbinfo->si_dbgaufs_xigen)
4711 +               err = 0;
4712 +
4713 +       return err;
4714 +}
4715 +#else
4716 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
4717 +{
4718 +       return 0;
4719 +}
4720 +#endif /* CONFIG_AUFS_EXPORT */
4721 +
4722 +/* ---------------------------------------------------------------------- */
4723 +
4724 +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
4725 +{
4726 +       /*
4727 +        * This function is a dynamic '__init' fucntion actually,
4728 +        * so the tiny check for si_rwsem is unnecessary.
4729 +        */
4730 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
4731 +
4732 +       debugfs_remove_recursive(sbinfo->si_dbgaufs);
4733 +       sbinfo->si_dbgaufs = NULL;
4734 +       kobject_put(&sbinfo->si_kobj);
4735 +}
4736 +
4737 +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
4738 +{
4739 +       int err;
4740 +       char name[SysaufsSiNameLen];
4741 +
4742 +       /*
4743 +        * This function is a dynamic '__init' fucntion actually,
4744 +        * so the tiny check for si_rwsem is unnecessary.
4745 +        */
4746 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
4747 +
4748 +       err = -ENOENT;
4749 +       if (!dbgaufs) {
4750 +               AuErr1("/debug/aufs is uninitialized\n");
4751 +               goto out;
4752 +       }
4753 +
4754 +       err = -EIO;
4755 +       sysaufs_name(sbinfo, name);
4756 +       sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
4757 +       if (unlikely(!sbinfo->si_dbgaufs))
4758 +               goto out;
4759 +       kobject_get(&sbinfo->si_kobj);
4760 +
4761 +       sbinfo->si_dbgaufs_xib = debugfs_create_file
4762 +               ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
4763 +                &dbgaufs_xib_fop);
4764 +       if (unlikely(!sbinfo->si_dbgaufs_xib))
4765 +               goto out_dir;
4766 +
4767 +       err = dbgaufs_xigen_init(sbinfo);
4768 +       if (!err)
4769 +               goto out; /* success */
4770 +
4771 +out_dir:
4772 +       dbgaufs_si_fin(sbinfo);
4773 +out:
4774 +       return err;
4775 +}
4776 +
4777 +/* ---------------------------------------------------------------------- */
4778 +
4779 +void dbgaufs_fin(void)
4780 +{
4781 +       debugfs_remove(dbgaufs);
4782 +}
4783 +
4784 +int __init dbgaufs_init(void)
4785 +{
4786 +       int err;
4787 +
4788 +       err = -EIO;
4789 +       dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
4790 +       if (dbgaufs)
4791 +               err = 0;
4792 +       return err;
4793 +}
4794 diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
4795 --- /usr/share/empty/fs/aufs/dbgaufs.h  1970-01-01 01:00:00.000000000 +0100
4796 +++ linux/fs/aufs/dbgaufs.h     2013-01-11 19:46:12.635947932 +0100
4797 @@ -0,0 +1,49 @@
4798 +/*
4799 + * Copyright (C) 2005-2013 Junjiro R. Okajima
4800 + *
4801 + * This program, aufs is free software; you can redistribute it and/or modify
4802 + * it under the terms of the GNU General Public License as published by
4803 + * the Free Software Foundation; either version 2 of the License, or
4804 + * (at your option) any later version.
4805 + *
4806 + * This program is distributed in the hope that it will be useful,
4807 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4808 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4809 + * GNU General Public License for more details.
4810 + *
4811 + * You should have received a copy of the GNU General Public License
4812 + * along with this program; if not, write to the Free Software
4813 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
4814 + */
4815 +
4816 +/*
4817 + * debugfs interface
4818 + */
4819 +
4820 +#ifndef __DBGAUFS_H__
4821 +#define __DBGAUFS_H__
4822 +
4823 +#ifdef __KERNEL__
4824 +
4825 +struct super_block;
4826 +struct au_sbinfo;
4827 +
4828 +#ifdef CONFIG_DEBUG_FS
4829 +/* dbgaufs.c */
4830 +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
4831 +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
4832 +void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
4833 +int dbgaufs_si_init(struct au_sbinfo *sbinfo);
4834 +void dbgaufs_fin(void);
4835 +int __init dbgaufs_init(void);
4836 +#else
4837 +AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
4838 +AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
4839 +AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
4840 +AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
4841 +AuStubVoid(dbgaufs_fin, void)
4842 +AuStubInt0(__init dbgaufs_init, void)
4843 +#endif /* CONFIG_DEBUG_FS */
4844 +
4845 +#endif /* __KERNEL__ */
4846 +#endif /* __DBGAUFS_H__ */
4847 diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
4848 --- /usr/share/empty/fs/aufs/dcsub.c    1970-01-01 01:00:00.000000000 +0100
4849 +++ linux/fs/aufs/dcsub.c       2013-01-11 19:46:12.635947932 +0100
4850 @@ -0,0 +1,243 @@
4851 +/*
4852 + * Copyright (C) 2005-2013 Junjiro R. Okajima
4853 + *
4854 + * This program, aufs is free software; you can redistribute it and/or modify
4855 + * it under the terms of the GNU General Public License as published by
4856 + * the Free Software Foundation; either version 2 of the License, or
4857 + * (at your option) any later version.
4858 + *
4859 + * This program is distributed in the hope that it will be useful,
4860 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4861 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4862 + * GNU General Public License for more details.
4863 + *
4864 + * You should have received a copy of the GNU General Public License
4865 + * along with this program; if not, write to the Free Software
4866 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
4867 + */
4868 +
4869 +/*
4870 + * sub-routines for dentry cache
4871 + */
4872 +
4873 +#include "aufs.h"
4874 +
4875 +static void au_dpage_free(struct au_dpage *dpage)
4876 +{
4877 +       int i;
4878 +       struct dentry **p;
4879 +
4880 +       p = dpage->dentries;
4881 +       for (i = 0; i < dpage->ndentry; i++)
4882 +               dput(*p++);
4883 +       free_page((unsigned long)dpage->dentries);
4884 +}
4885 +
4886 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
4887 +{
4888 +       int err;
4889 +       void *p;
4890 +
4891 +       err = -ENOMEM;
4892 +       dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
4893 +       if (unlikely(!dpages->dpages))
4894 +               goto out;
4895 +
4896 +       p = (void *)__get_free_page(gfp);
4897 +       if (unlikely(!p))
4898 +               goto out_dpages;
4899 +
4900 +       dpages->dpages[0].ndentry = 0;
4901 +       dpages->dpages[0].dentries = p;
4902 +       dpages->ndpage = 1;
4903 +       return 0; /* success */
4904 +
4905 +out_dpages:
4906 +       kfree(dpages->dpages);
4907 +out:
4908 +       return err;
4909 +}
4910 +
4911 +void au_dpages_free(struct au_dcsub_pages *dpages)
4912 +{
4913 +       int i;
4914 +       struct au_dpage *p;
4915 +
4916 +       p = dpages->dpages;
4917 +       for (i = 0; i < dpages->ndpage; i++)
4918 +               au_dpage_free(p++);
4919 +       kfree(dpages->dpages);
4920 +}
4921 +
4922 +static int au_dpages_append(struct au_dcsub_pages *dpages,
4923 +                           struct dentry *dentry, gfp_t gfp)
4924 +{
4925 +       int err, sz;
4926 +       struct au_dpage *dpage;
4927 +       void *p;
4928 +
4929 +       dpage = dpages->dpages + dpages->ndpage - 1;
4930 +       sz = PAGE_SIZE / sizeof(dentry);
4931 +       if (unlikely(dpage->ndentry >= sz)) {
4932 +               AuLabel(new dpage);
4933 +               err = -ENOMEM;
4934 +               sz = dpages->ndpage * sizeof(*dpages->dpages);
4935 +               p = au_kzrealloc(dpages->dpages, sz,
4936 +                                sz + sizeof(*dpages->dpages), gfp);
4937 +               if (unlikely(!p))
4938 +                       goto out;
4939 +
4940 +               dpages->dpages = p;
4941 +               dpage = dpages->dpages + dpages->ndpage;
4942 +               p = (void *)__get_free_page(gfp);
4943 +               if (unlikely(!p))
4944 +                       goto out;
4945 +
4946 +               dpage->ndentry = 0;
4947 +               dpage->dentries = p;
4948 +               dpages->ndpage++;
4949 +       }
4950 +
4951 +       AuDebugOn(!dentry->d_count);
4952 +       dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
4953 +       return 0; /* success */
4954 +
4955 +out:
4956 +       return err;
4957 +}
4958 +
4959 +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
4960 +                  au_dpages_test test, void *arg)
4961 +{
4962 +       int err;
4963 +       struct dentry *this_parent;
4964 +       struct list_head *next;
4965 +       struct super_block *sb = root->d_sb;
4966 +
4967 +       err = 0;
4968 +       write_seqlock(&rename_lock);
4969 +       this_parent = root;
4970 +       spin_lock(&this_parent->d_lock);
4971 +repeat:
4972 +       next = this_parent->d_subdirs.next;
4973 +resume:
4974 +       if (this_parent->d_sb == sb
4975 +           && !IS_ROOT(this_parent)
4976 +           && au_di(this_parent)
4977 +           && this_parent->d_count
4978 +           && (!test || test(this_parent, arg))) {
4979 +               err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
4980 +               if (unlikely(err))
4981 +                       goto out;
4982 +       }
4983 +
4984 +       while (next != &this_parent->d_subdirs) {
4985 +               struct list_head *tmp = next;
4986 +               struct dentry *dentry = list_entry(tmp, struct dentry,
4987 +                                                  d_u.d_child);
4988 +
4989 +               next = tmp->next;
4990 +               spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
4991 +               if (dentry->d_count) {
4992 +                       if (!list_empty(&dentry->d_subdirs)) {
4993 +                               spin_unlock(&this_parent->d_lock);
4994 +                               spin_release(&dentry->d_lock.dep_map, 1,
4995 +                                            _RET_IP_);
4996 +                               this_parent = dentry;
4997 +                               spin_acquire(&this_parent->d_lock.dep_map, 0, 1,
4998 +                                            _RET_IP_);
4999 +                               goto repeat;
5000 +                       }
5001 +                       if (dentry->d_sb == sb
5002 +                           && au_di(dentry)
5003 +                           && (!test || test(dentry, arg)))
5004 +                               err = au_dpages_append(dpages, dentry,
5005 +                                                      GFP_ATOMIC);
5006 +               }
5007 +               spin_unlock(&dentry->d_lock);
5008 +               if (unlikely(err))
5009 +                       goto out;
5010 +       }
5011 +
5012 +       if (this_parent != root) {
5013 +               struct dentry *tmp;
5014 +               struct dentry *child;
5015 +
5016 +               tmp = this_parent->d_parent;
5017 +               rcu_read_lock();
5018 +               spin_unlock(&this_parent->d_lock);
5019 +               child = this_parent;
5020 +               this_parent = tmp;
5021 +               spin_lock(&this_parent->d_lock);
5022 +               rcu_read_unlock();
5023 +               next = child->d_u.d_child.next;
5024 +               goto resume;
5025 +       }
5026 +
5027 +out:
5028 +       spin_unlock(&this_parent->d_lock);
5029 +       write_sequnlock(&rename_lock);
5030 +       return err;
5031 +}
5032 +
5033 +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5034 +                      int do_include, au_dpages_test test, void *arg)
5035 +{
5036 +       int err;
5037 +
5038 +       err = 0;
5039 +       write_seqlock(&rename_lock);
5040 +       spin_lock(&dentry->d_lock);
5041 +       if (do_include
5042 +           && dentry->d_count
5043 +           && (!test || test(dentry, arg)))
5044 +               err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
5045 +       spin_unlock(&dentry->d_lock);
5046 +       if (unlikely(err))
5047 +               goto out;
5048 +
5049 +       /*
5050 +        * vfsmount_lock is unnecessary since this is a traverse in a single
5051 +        * mount
5052 +        */
5053 +       while (!IS_ROOT(dentry)) {
5054 +               dentry = dentry->d_parent; /* rename_lock is locked */
5055 +               spin_lock(&dentry->d_lock);
5056 +               if (dentry->d_count
5057 +                   && (!test || test(dentry, arg)))
5058 +                       err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
5059 +               spin_unlock(&dentry->d_lock);
5060 +               if (unlikely(err))
5061 +                       break;
5062 +       }
5063 +
5064 +out:
5065 +       write_sequnlock(&rename_lock);
5066 +       return err;
5067 +}
5068 +
5069 +static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
5070 +{
5071 +       return au_di(dentry) && dentry->d_sb == arg;
5072 +}
5073 +
5074 +int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5075 +                           struct dentry *dentry, int do_include)
5076 +{
5077 +       return au_dcsub_pages_rev(dpages, dentry, do_include,
5078 +                                 au_dcsub_dpages_aufs, dentry->d_sb);
5079 +}
5080 +
5081 +int au_test_subdir(struct dentry *d1, struct dentry *d2)
5082 +{
5083 +       struct path path[2] = {
5084 +               {
5085 +                       .dentry = d1
5086 +               },
5087 +               {
5088 +                       .dentry = d2
5089 +               }
5090 +       };
5091 +
5092 +       return path_is_under(path + 0, path + 1);
5093 +}
5094 diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
5095 --- /usr/share/empty/fs/aufs/dcsub.h    1970-01-01 01:00:00.000000000 +0100
5096 +++ linux/fs/aufs/dcsub.h       2013-01-11 19:46:12.635947932 +0100
5097 @@ -0,0 +1,94 @@
5098 +/*
5099 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5100 + *
5101 + * This program, aufs is free software; you can redistribute it and/or modify
5102 + * it under the terms of the GNU General Public License as published by
5103 + * the Free Software Foundation; either version 2 of the License, or
5104 + * (at your option) any later version.
5105 + *
5106 + * This program is distributed in the hope that it will be useful,
5107 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5108 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5109 + * GNU General Public License for more details.
5110 + *
5111 + * You should have received a copy of the GNU General Public License
5112 + * along with this program; if not, write to the Free Software
5113 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
5114 + */
5115 +
5116 +/*
5117 + * sub-routines for dentry cache
5118 + */
5119 +
5120 +#ifndef __AUFS_DCSUB_H__
5121 +#define __AUFS_DCSUB_H__
5122 +
5123 +#ifdef __KERNEL__
5124 +
5125 +#include <linux/dcache.h>
5126 +#include <linux/fs.h>
5127 +
5128 +struct dentry;
5129 +
5130 +struct au_dpage {
5131 +       int ndentry;
5132 +       struct dentry **dentries;
5133 +};
5134 +
5135 +struct au_dcsub_pages {
5136 +       int ndpage;
5137 +       struct au_dpage *dpages;
5138 +};
5139 +
5140 +/* ---------------------------------------------------------------------- */
5141 +
5142 +/* dcsub.c */
5143 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
5144 +void au_dpages_free(struct au_dcsub_pages *dpages);
5145 +typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
5146 +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5147 +                  au_dpages_test test, void *arg);
5148 +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5149 +                      int do_include, au_dpages_test test, void *arg);
5150 +int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5151 +                           struct dentry *dentry, int do_include);
5152 +int au_test_subdir(struct dentry *d1, struct dentry *d2);
5153 +
5154 +/* ---------------------------------------------------------------------- */
5155 +
5156 +static inline int au_d_hashed_positive(struct dentry *d)
5157 +{
5158 +       int err;
5159 +       struct inode *inode = d->d_inode;
5160 +       err = 0;
5161 +       if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
5162 +               err = -ENOENT;
5163 +       return err;
5164 +}
5165 +
5166 +static inline int au_d_alive(struct dentry *d)
5167 +{
5168 +       int err;
5169 +       struct inode *inode;
5170 +       err = 0;
5171 +       if (!IS_ROOT(d))
5172 +               err = au_d_hashed_positive(d);
5173 +       else {
5174 +               inode = d->d_inode;
5175 +               if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
5176 +                       err = -ENOENT;
5177 +       }
5178 +       return err;
5179 +}
5180 +
5181 +static inline int au_alive_dir(struct dentry *d)
5182 +{
5183 +       int err;
5184 +       err = au_d_alive(d);
5185 +       if (unlikely(err || IS_DEADDIR(d->d_inode)))
5186 +               err = -ENOENT;
5187 +       return err;
5188 +}
5189 +
5190 +#endif /* __KERNEL__ */
5191 +#endif /* __AUFS_DCSUB_H__ */
5192 diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
5193 --- /usr/share/empty/fs/aufs/debug.c    1970-01-01 01:00:00.000000000 +0100
5194 +++ linux/fs/aufs/debug.c       2013-01-11 19:46:12.635947932 +0100
5195 @@ -0,0 +1,490 @@
5196 +/*
5197 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5198 + *
5199 + * This program, aufs is free software; you can redistribute it and/or modify
5200 + * it under the terms of the GNU General Public License as published by
5201 + * the Free Software Foundation; either version 2 of the License, or
5202 + * (at your option) any later version.
5203 + *
5204 + * This program is distributed in the hope that it will be useful,
5205 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5206 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5207 + * GNU General Public License for more details.
5208 + *
5209 + * You should have received a copy of the GNU General Public License
5210 + * along with this program; if not, write to the Free Software
5211 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
5212 + */
5213 +
5214 +/*
5215 + * debug print functions
5216 + */
5217 +
5218 +#include <linux/vt_kern.h>
5219 +#include "aufs.h"
5220 +
5221 +int aufs_debug;
5222 +MODULE_PARM_DESC(debug, "debug print");
5223 +module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
5224 +
5225 +char *au_plevel = KERN_DEBUG;
5226 +#define dpri(fmt, ...) do {                                    \
5227 +       if ((au_plevel                                          \
5228 +            && strcmp(au_plevel, KERN_DEBUG))                  \
5229 +           || au_debug_test())                                 \
5230 +               printk("%s" fmt, au_plevel, ##__VA_ARGS__);     \
5231 +} while (0)
5232 +
5233 +/* ---------------------------------------------------------------------- */
5234 +
5235 +void au_dpri_whlist(struct au_nhash *whlist)
5236 +{
5237 +       unsigned long ul, n;
5238 +       struct hlist_head *head;
5239 +       struct au_vdir_wh *tpos;
5240 +       struct hlist_node *pos;
5241 +
5242 +       n = whlist->nh_num;
5243 +       head = whlist->nh_head;
5244 +       for (ul = 0; ul < n; ul++) {
5245 +               hlist_for_each_entry(tpos, pos, head, wh_hash)
5246 +                       dpri("b%d, %.*s, %d\n",
5247 +                            tpos->wh_bindex,
5248 +                            tpos->wh_str.len, tpos->wh_str.name,
5249 +                            tpos->wh_str.len);
5250 +               head++;
5251 +       }
5252 +}
5253 +
5254 +void au_dpri_vdir(struct au_vdir *vdir)
5255 +{
5256 +       unsigned long ul;
5257 +       union au_vdir_deblk_p p;
5258 +       unsigned char *o;
5259 +
5260 +       if (!vdir || IS_ERR(vdir)) {
5261 +               dpri("err %ld\n", PTR_ERR(vdir));
5262 +               return;
5263 +       }
5264 +
5265 +       dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
5266 +            vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
5267 +            vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
5268 +       for (ul = 0; ul < vdir->vd_nblk; ul++) {
5269 +               p.deblk = vdir->vd_deblk[ul];
5270 +               o = p.deblk;
5271 +               dpri("[%lu]: %p\n", ul, o);
5272 +       }
5273 +}
5274 +
5275 +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
5276 +                       struct dentry *wh)
5277 +{
5278 +       char *n = NULL;
5279 +       int l = 0;
5280 +
5281 +       if (!inode || IS_ERR(inode)) {
5282 +               dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
5283 +               return -1;
5284 +       }
5285 +
5286 +       /* the type of i_blocks depends upon CONFIG_LSF */
5287 +       BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
5288 +                    && sizeof(inode->i_blocks) != sizeof(u64));
5289 +       if (wh) {
5290 +               n = (void *)wh->d_name.name;
5291 +               l = wh->d_name.len;
5292 +       }
5293 +
5294 +       dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
5295 +            " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
5296 +            bindex, inode,
5297 +            inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
5298 +            atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
5299 +            i_size_read(inode), (unsigned long long)inode->i_blocks,
5300 +            hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
5301 +            inode->i_mapping ? inode->i_mapping->nrpages : 0,
5302 +            inode->i_state, inode->i_flags, inode->i_version,
5303 +            inode->i_generation,
5304 +            l ? ", wh " : "", l, n);
5305 +       return 0;
5306 +}
5307 +
5308 +void au_dpri_inode(struct inode *inode)
5309 +{
5310 +       struct au_iinfo *iinfo;
5311 +       aufs_bindex_t bindex;
5312 +       int err, hn;
5313 +
5314 +       err = do_pri_inode(-1, inode, -1, NULL);
5315 +       if (err || !au_test_aufs(inode->i_sb))
5316 +               return;
5317 +
5318 +       iinfo = au_ii(inode);
5319 +       if (!iinfo)
5320 +               return;
5321 +       dpri("i-1: bstart %d, bend %d, gen %d\n",
5322 +            iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
5323 +       if (iinfo->ii_bstart < 0)
5324 +               return;
5325 +       hn = 0;
5326 +       for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
5327 +               hn = !!au_hn(iinfo->ii_hinode + bindex);
5328 +               do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
5329 +                            iinfo->ii_hinode[0 + bindex].hi_whdentry);
5330 +       }
5331 +}
5332 +
5333 +void au_dpri_dalias(struct inode *inode)
5334 +{
5335 +       struct dentry *d;
5336 +       struct hlist_node *p;
5337 +
5338 +       spin_lock(&inode->i_lock);
5339 +       hlist_for_each_entry(d, p, &inode->i_dentry, d_alias)
5340 +               au_dpri_dentry(d);
5341 +       spin_unlock(&inode->i_lock);
5342 +}
5343 +
5344 +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
5345 +{
5346 +       struct dentry *wh = NULL;
5347 +       int hn;
5348 +
5349 +       if (!dentry || IS_ERR(dentry)) {
5350 +               dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
5351 +               return -1;
5352 +       }
5353 +       /* do not call dget_parent() here */
5354 +       /* note: access d_xxx without d_lock */
5355 +       dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
5356 +            bindex,
5357 +            AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
5358 +            dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
5359 +            dentry->d_count, dentry->d_flags);
5360 +       hn = -1;
5361 +       if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
5362 +               struct au_iinfo *iinfo = au_ii(dentry->d_inode);
5363 +               if (iinfo) {
5364 +                       hn = !!au_hn(iinfo->ii_hinode + bindex);
5365 +                       wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
5366 +               }
5367 +       }
5368 +       do_pri_inode(bindex, dentry->d_inode, hn, wh);
5369 +       return 0;
5370 +}
5371 +
5372 +void au_dpri_dentry(struct dentry *dentry)
5373 +{
5374 +       struct au_dinfo *dinfo;
5375 +       aufs_bindex_t bindex;
5376 +       int err;
5377 +       struct au_hdentry *hdp;
5378 +
5379 +       err = do_pri_dentry(-1, dentry);
5380 +       if (err || !au_test_aufs(dentry->d_sb))
5381 +               return;
5382 +
5383 +       dinfo = au_di(dentry);
5384 +       if (!dinfo)
5385 +               return;
5386 +       dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
5387 +            dinfo->di_bstart, dinfo->di_bend,
5388 +            dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
5389 +       if (dinfo->di_bstart < 0)
5390 +               return;
5391 +       hdp = dinfo->di_hdentry;
5392 +       for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
5393 +               do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
5394 +}
5395 +
5396 +static int do_pri_file(aufs_bindex_t bindex, struct file *file)
5397 +{
5398 +       char a[32];
5399 +
5400 +       if (!file || IS_ERR(file)) {
5401 +               dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
5402 +               return -1;
5403 +       }
5404 +       a[0] = 0;
5405 +       if (bindex < 0
5406 +           && file->f_dentry
5407 +           && au_test_aufs(file->f_dentry->d_sb)
5408 +           && au_fi(file))
5409 +               snprintf(a, sizeof(a), ", gen %d, mmapped %d",
5410 +                        au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
5411 +       dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
5412 +            bindex, file->f_mode, file->f_flags, (long)file_count(file),
5413 +            file->f_version, file->f_pos, a);
5414 +       if (file->f_dentry)
5415 +               do_pri_dentry(bindex, file->f_dentry);
5416 +       return 0;
5417 +}
5418 +
5419 +void au_dpri_file(struct file *file)
5420 +{
5421 +       struct au_finfo *finfo;
5422 +       struct au_fidir *fidir;
5423 +       struct au_hfile *hfile;
5424 +       aufs_bindex_t bindex;
5425 +       int err;
5426 +
5427 +       err = do_pri_file(-1, file);
5428 +       if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
5429 +               return;
5430 +
5431 +       finfo = au_fi(file);
5432 +       if (!finfo)
5433 +               return;
5434 +       if (finfo->fi_btop < 0)
5435 +               return;
5436 +       fidir = finfo->fi_hdir;
5437 +       if (!fidir)
5438 +               do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
5439 +       else
5440 +               for (bindex = finfo->fi_btop;
5441 +                    bindex >= 0 && bindex <= fidir->fd_bbot;
5442 +                    bindex++) {
5443 +                       hfile = fidir->fd_hfile + bindex;
5444 +                       do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
5445 +               }
5446 +}
5447 +
5448 +static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
5449 +{
5450 +       struct vfsmount *mnt;
5451 +       struct super_block *sb;
5452 +
5453 +       if (!br || IS_ERR(br))
5454 +               goto out;
5455 +       mnt = br->br_mnt;
5456 +       if (!mnt || IS_ERR(mnt))
5457 +               goto out;
5458 +       sb = mnt->mnt_sb;
5459 +       if (!sb || IS_ERR(sb))
5460 +               goto out;
5461 +
5462 +       dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
5463 +            "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
5464 +            "xino %d\n",
5465 +            bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
5466 +            br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
5467 +            sb->s_flags, sb->s_count,
5468 +            atomic_read(&sb->s_active), !!br->br_xino.xi_file);
5469 +       return 0;
5470 +
5471 +out:
5472 +       dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
5473 +       return -1;
5474 +}
5475 +
5476 +void au_dpri_sb(struct super_block *sb)
5477 +{
5478 +       struct au_sbinfo *sbinfo;
5479 +       aufs_bindex_t bindex;
5480 +       int err;
5481 +       /* to reuduce stack size */
5482 +       struct {
5483 +               struct vfsmount mnt;
5484 +               struct au_branch fake;
5485 +       } *a;
5486 +
5487 +       /* this function can be called from magic sysrq */
5488 +       a = kzalloc(sizeof(*a), GFP_ATOMIC);
5489 +       if (unlikely(!a)) {
5490 +               dpri("no memory\n");
5491 +               return;
5492 +       }
5493 +
5494 +       a->mnt.mnt_sb = sb;
5495 +       a->fake.br_perm = 0;
5496 +       a->fake.br_mnt = &a->mnt;
5497 +       a->fake.br_xino.xi_file = NULL;
5498 +       atomic_set(&a->fake.br_count, 0);
5499 +       smp_mb(); /* atomic_set */
5500 +       err = do_pri_br(-1, &a->fake);
5501 +       kfree(a);
5502 +       dpri("dev 0x%x\n", sb->s_dev);
5503 +       if (err || !au_test_aufs(sb))
5504 +               return;
5505 +
5506 +       sbinfo = au_sbi(sb);
5507 +       if (!sbinfo)
5508 +               return;
5509 +       dpri("nw %d, gen %u, kobj %d\n",
5510 +            atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
5511 +            atomic_read(&sbinfo->si_kobj.kref.refcount));
5512 +       for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
5513 +               do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
5514 +}
5515 +
5516 +/* ---------------------------------------------------------------------- */
5517 +
5518 +void au_dbg_sleep_jiffy(int jiffy)
5519 +{
5520 +       while (jiffy)
5521 +               jiffy = schedule_timeout_uninterruptible(jiffy);
5522 +}
5523 +
5524 +void au_dbg_iattr(struct iattr *ia)
5525 +{
5526 +#define AuBit(name)    if (ia->ia_valid & ATTR_ ## name) \
5527 +                               dpri(#name "\n")
5528 +       AuBit(MODE);
5529 +       AuBit(UID);
5530 +       AuBit(GID);
5531 +       AuBit(SIZE);
5532 +       AuBit(ATIME);
5533 +       AuBit(MTIME);
5534 +       AuBit(CTIME);
5535 +       AuBit(ATIME_SET);
5536 +       AuBit(MTIME_SET);
5537 +       AuBit(FORCE);
5538 +       AuBit(ATTR_FLAG);
5539 +       AuBit(KILL_SUID);
5540 +       AuBit(KILL_SGID);
5541 +       AuBit(FILE);
5542 +       AuBit(KILL_PRIV);
5543 +       AuBit(OPEN);
5544 +       AuBit(TIMES_SET);
5545 +#undef AuBit
5546 +       dpri("ia_file %p\n", ia->ia_file);
5547 +}
5548 +
5549 +/* ---------------------------------------------------------------------- */
5550 +
5551 +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
5552 +{
5553 +       struct inode *h_inode, *inode = dentry->d_inode;
5554 +       struct dentry *h_dentry;
5555 +       aufs_bindex_t bindex, bend, bi;
5556 +
5557 +       if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
5558 +               return;
5559 +
5560 +       bend = au_dbend(dentry);
5561 +       bi = au_ibend(inode);
5562 +       if (bi < bend)
5563 +               bend = bi;
5564 +       bindex = au_dbstart(dentry);
5565 +       bi = au_ibstart(inode);
5566 +       if (bi > bindex)
5567 +               bindex = bi;
5568 +
5569 +       for (; bindex <= bend; bindex++) {
5570 +               h_dentry = au_h_dptr(dentry, bindex);
5571 +               if (!h_dentry)
5572 +                       continue;
5573 +               h_inode = au_h_iptr(inode, bindex);
5574 +               if (unlikely(h_inode != h_dentry->d_inode)) {
5575 +                       int old = au_debug_test();
5576 +                       if (!old)
5577 +                               au_debug(1);
5578 +                       AuDbg("b%d, %s:%d\n", bindex, func, line);
5579 +                       AuDbgDentry(dentry);
5580 +                       AuDbgInode(inode);
5581 +                       if (!old)
5582 +                               au_debug(0);
5583 +                       BUG();
5584 +               }
5585 +       }
5586 +}
5587 +
5588 +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
5589 +{
5590 +       struct dentry *parent;
5591 +
5592 +       parent = dget_parent(dentry);
5593 +       AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
5594 +       AuDebugOn(IS_ROOT(dentry));
5595 +       AuDebugOn(au_digen_test(parent, sigen));
5596 +       dput(parent);
5597 +}
5598 +
5599 +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
5600 +{
5601 +       struct dentry *parent;
5602 +       struct inode *inode;
5603 +
5604 +       parent = dget_parent(dentry);
5605 +       inode = dentry->d_inode;
5606 +       AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
5607 +       AuDebugOn(au_digen_test(parent, sigen));
5608 +       dput(parent);
5609 +}
5610 +
5611 +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
5612 +{
5613 +       int err, i, j;
5614 +       struct au_dcsub_pages dpages;
5615 +       struct au_dpage *dpage;
5616 +       struct dentry **dentries;
5617 +
5618 +       err = au_dpages_init(&dpages, GFP_NOFS);
5619 +       AuDebugOn(err);
5620 +       err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
5621 +       AuDebugOn(err);
5622 +       for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
5623 +               dpage = dpages.dpages + i;
5624 +               dentries = dpage->dentries;
5625 +               for (j = dpage->ndentry - 1; !err && j >= 0; j--)
5626 +                       AuDebugOn(au_digen_test(dentries[j], sigen));
5627 +       }
5628 +       au_dpages_free(&dpages);
5629 +}
5630 +
5631 +void au_dbg_verify_kthread(void)
5632 +{
5633 +       if (au_wkq_test()) {
5634 +               au_dbg_blocked();
5635 +               /*
5636 +                * It may be recursive, but udba=notify between two aufs mounts,
5637 +                * where a single ro branch is shared, is not a problem.
5638 +                */
5639 +               /* WARN_ON(1); */
5640 +       }
5641 +}
5642 +
5643 +/* ---------------------------------------------------------------------- */
5644 +
5645 +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
5646 +{
5647 +#ifdef AuForceNoPlink
5648 +       au_opt_clr(sbinfo->si_mntflags, PLINK);
5649 +#endif
5650 +#ifdef AuForceNoXino
5651 +       au_opt_clr(sbinfo->si_mntflags, XINO);
5652 +#endif
5653 +#ifdef AuForceNoRefrof
5654 +       au_opt_clr(sbinfo->si_mntflags, REFROF);
5655 +#endif
5656 +#ifdef AuForceHnotify
5657 +       au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
5658 +#endif
5659 +#ifdef AuForceRd0
5660 +       sbinfo->si_rdblk = 0;
5661 +       sbinfo->si_rdhash = 0;
5662 +#endif
5663 +}
5664 +
5665 +int __init au_debug_init(void)
5666 +{
5667 +       aufs_bindex_t bindex;
5668 +       struct au_vdir_destr destr;
5669 +
5670 +       bindex = -1;
5671 +       AuDebugOn(bindex >= 0);
5672 +
5673 +       destr.len = -1;
5674 +       AuDebugOn(destr.len < NAME_MAX);
5675 +
5676 +#ifdef CONFIG_4KSTACKS
5677 +       pr_warn("CONFIG_4KSTACKS is defined.\n");
5678 +#endif
5679 +
5680 +#ifdef AuForceNoBrs
5681 +       sysaufs_brs = 0;
5682 +#endif
5683 +
5684 +       return 0;
5685 +}
5686 diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
5687 --- /usr/share/empty/fs/aufs/debug.h    1970-01-01 01:00:00.000000000 +0100
5688 +++ linux/fs/aufs/debug.h       2013-01-11 19:46:12.635947932 +0100
5689 @@ -0,0 +1,242 @@
5690 +/*
5691 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5692 + *
5693 + * This program, aufs is free software; you can redistribute it and/or modify
5694 + * it under the terms of the GNU General Public License as published by
5695 + * the Free Software Foundation; either version 2 of the License, or
5696 + * (at your option) any later version.
5697 + *
5698 + * This program is distributed in the hope that it will be useful,
5699 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5700 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5701 + * GNU General Public License for more details.
5702 + *
5703 + * You should have received a copy of the GNU General Public License
5704 + * along with this program; if not, write to the Free Software
5705 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
5706 + */
5707 +
5708 +/*
5709 + * debug print functions
5710 + */
5711 +
5712 +#ifndef __AUFS_DEBUG_H__
5713 +#define __AUFS_DEBUG_H__
5714 +
5715 +#ifdef __KERNEL__
5716 +
5717 +#include <linux/module.h>
5718 +#include <linux/kallsyms.h>
5719 +#include <linux/sysrq.h>
5720 +
5721 +#ifdef CONFIG_AUFS_DEBUG
5722 +#define AuDebugOn(a)           BUG_ON(a)
5723 +
5724 +/* module parameter */
5725 +extern int aufs_debug;
5726 +static inline void au_debug(int n)
5727 +{
5728 +       aufs_debug = n;
5729 +       smp_mb();
5730 +}
5731 +
5732 +static inline int au_debug_test(void)
5733 +{
5734 +       return aufs_debug;
5735 +}
5736 +#else
5737 +#define AuDebugOn(a)           do {} while (0)
5738 +AuStubVoid(au_debug, int n)
5739 +AuStubInt0(au_debug_test, void)
5740 +#endif /* CONFIG_AUFS_DEBUG */
5741 +
5742 +/* ---------------------------------------------------------------------- */
5743 +
5744 +/* debug print */
5745 +
5746 +#define AuDbg(fmt, ...) do { \
5747 +       if (au_debug_test()) \
5748 +               pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
5749 +} while (0)
5750 +#define AuLabel(l)             AuDbg(#l "\n")
5751 +#define AuIOErr(fmt, ...)      pr_err("I/O Error, " fmt, ##__VA_ARGS__)
5752 +#define AuWarn1(fmt, ...) do { \
5753 +       static unsigned char _c; \
5754 +       if (!_c++) \
5755 +               pr_warn(fmt, ##__VA_ARGS__); \
5756 +} while (0)
5757 +
5758 +#define AuErr1(fmt, ...) do { \
5759 +       static unsigned char _c; \
5760 +       if (!_c++) \
5761 +               pr_err(fmt, ##__VA_ARGS__); \
5762 +} while (0)
5763 +
5764 +#define AuIOErr1(fmt, ...) do { \
5765 +       static unsigned char _c; \
5766 +       if (!_c++) \
5767 +               AuIOErr(fmt, ##__VA_ARGS__); \
5768 +} while (0)
5769 +
5770 +#define AuUnsupportMsg "This operation is not supported." \
5771 +                       " Please report this application to aufs-users ML."
5772 +#define AuUnsupport(fmt, ...) do { \
5773 +       pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
5774 +       dump_stack(); \
5775 +} while (0)
5776 +
5777 +#define AuTraceErr(e) do { \
5778 +       if (unlikely((e) < 0)) \
5779 +               AuDbg("err %d\n", (int)(e)); \
5780 +} while (0)
5781 +
5782 +#define AuTraceErrPtr(p) do { \
5783 +       if (IS_ERR(p)) \
5784 +               AuDbg("err %ld\n", PTR_ERR(p)); \
5785 +} while (0)
5786 +
5787 +/* dirty macros for debug print, use with "%.*s" and caution */
5788 +#define AuLNPair(qstr)         (qstr)->len, (qstr)->name
5789 +#define AuDLNPair(d)           AuLNPair(&(d)->d_name)
5790 +
5791 +/* ---------------------------------------------------------------------- */
5792 +
5793 +struct au_sbinfo;
5794 +struct au_finfo;
5795 +struct dentry;
5796 +#ifdef CONFIG_AUFS_DEBUG
5797 +extern char *au_plevel;
5798 +struct au_nhash;
5799 +void au_dpri_whlist(struct au_nhash *whlist);
5800 +struct au_vdir;
5801 +void au_dpri_vdir(struct au_vdir *vdir);
5802 +struct inode;
5803 +void au_dpri_inode(struct inode *inode);
5804 +void au_dpri_dalias(struct inode *inode);
5805 +void au_dpri_dentry(struct dentry *dentry);
5806 +struct file;
5807 +void au_dpri_file(struct file *filp);
5808 +struct super_block;
5809 +void au_dpri_sb(struct super_block *sb);
5810 +
5811 +void au_dbg_sleep_jiffy(int jiffy);
5812 +struct iattr;
5813 +void au_dbg_iattr(struct iattr *ia);
5814 +
5815 +#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
5816 +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
5817 +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
5818 +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
5819 +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
5820 +void au_dbg_verify_kthread(void);
5821 +
5822 +int __init au_debug_init(void);
5823 +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
5824 +#define AuDbgWhlist(w) do { \
5825 +       AuDbg(#w "\n"); \
5826 +       au_dpri_whlist(w); \
5827 +} while (0)
5828 +
5829 +#define AuDbgVdir(v) do { \
5830 +       AuDbg(#v "\n"); \
5831 +       au_dpri_vdir(v); \
5832 +} while (0)
5833 +
5834 +#define AuDbgInode(i) do { \
5835 +       AuDbg(#i "\n"); \
5836 +       au_dpri_inode(i); \
5837 +} while (0)
5838 +
5839 +#define AuDbgDAlias(i) do { \
5840 +       AuDbg(#i "\n"); \
5841 +       au_dpri_dalias(i); \
5842 +} while (0)
5843 +
5844 +#define AuDbgDentry(d) do { \
5845 +       AuDbg(#d "\n"); \
5846 +       au_dpri_dentry(d); \
5847 +} while (0)
5848 +
5849 +#define AuDbgFile(f) do { \
5850 +       AuDbg(#f "\n"); \
5851 +       au_dpri_file(f); \
5852 +} while (0)
5853 +
5854 +#define AuDbgSb(sb) do { \
5855 +       AuDbg(#sb "\n"); \
5856 +       au_dpri_sb(sb); \
5857 +} while (0)
5858 +
5859 +#define AuDbgSleep(sec) do { \
5860 +       AuDbg("sleep %d sec\n", sec); \
5861 +       ssleep(sec); \
5862 +} while (0)
5863 +
5864 +#define AuDbgSleepJiffy(jiffy) do { \
5865 +       AuDbg("sleep %d jiffies\n", jiffy); \
5866 +       au_dbg_sleep_jiffy(jiffy); \
5867 +} while (0)
5868 +
5869 +#define AuDbgIAttr(ia) do { \
5870 +       AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
5871 +       au_dbg_iattr(ia); \
5872 +} while (0)
5873 +
5874 +#define AuDbgSym(addr) do {                            \
5875 +       char sym[KSYM_SYMBOL_LEN];                      \
5876 +       sprint_symbol(sym, (unsigned long)addr);        \
5877 +       AuDbg("%s\n", sym);                             \
5878 +} while (0)
5879 +
5880 +#define AuInfoSym(addr) do {                           \
5881 +       char sym[KSYM_SYMBOL_LEN];                      \
5882 +       sprint_symbol(sym, (unsigned long)addr);        \
5883 +       AuInfo("%s\n", sym);                            \
5884 +} while (0)
5885 +#else
5886 +AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
5887 +AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
5888 +AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
5889 +          unsigned int sigen)
5890 +AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
5891 +AuStubVoid(au_dbg_verify_kthread, void)
5892 +AuStubInt0(__init au_debug_init, void)
5893 +AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
5894 +
5895 +#define AuDbgWhlist(w)         do {} while (0)
5896 +#define AuDbgVdir(v)           do {} while (0)
5897 +#define AuDbgInode(i)          do {} while (0)
5898 +#define AuDbgDAlias(i)         do {} while (0)
5899 +#define AuDbgDentry(d)         do {} while (0)
5900 +#define AuDbgFile(f)           do {} while (0)
5901 +#define AuDbgSb(sb)            do {} while (0)
5902 +#define AuDbgSleep(sec)                do {} while (0)
5903 +#define AuDbgSleepJiffy(jiffy) do {} while (0)
5904 +#define AuDbgIAttr(ia)         do {} while (0)
5905 +#define AuDbgSym(addr)         do {} while (0)
5906 +#define AuInfoSym(addr)                do {} while (0)
5907 +#endif /* CONFIG_AUFS_DEBUG */
5908 +
5909 +/* ---------------------------------------------------------------------- */
5910 +
5911 +#ifdef CONFIG_AUFS_MAGIC_SYSRQ
5912 +int __init au_sysrq_init(void);
5913 +void au_sysrq_fin(void);
5914 +
5915 +#ifdef CONFIG_HW_CONSOLE
5916 +#define au_dbg_blocked() do { \
5917 +       WARN_ON(1); \
5918 +       handle_sysrq('w'); \
5919 +} while (0)
5920 +#else
5921 +AuStubVoid(au_dbg_blocked, void)
5922 +#endif
5923 +
5924 +#else
5925 +AuStubInt0(__init au_sysrq_init, void)
5926 +AuStubVoid(au_sysrq_fin, void)
5927 +AuStubVoid(au_dbg_blocked, void)
5928 +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
5929 +
5930 +#endif /* __KERNEL__ */
5931 +#endif /* __AUFS_DEBUG_H__ */
5932 diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
5933 --- /usr/share/empty/fs/aufs/dentry.c   1970-01-01 01:00:00.000000000 +0100
5934 +++ linux/fs/aufs/dentry.c      2013-01-11 19:46:12.635947932 +0100
5935 @@ -0,0 +1,1060 @@
5936 +/*
5937 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5938 + *
5939 + * This program, aufs is free software; you can redistribute it and/or modify
5940 + * it under the terms of the GNU General Public License as published by
5941 + * the Free Software Foundation; either version 2 of the License, or
5942 + * (at your option) any later version.
5943 + *
5944 + * This program is distributed in the hope that it will be useful,
5945 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5946 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5947 + * GNU General Public License for more details.
5948 + *
5949 + * You should have received a copy of the GNU General Public License
5950 + * along with this program; if not, write to the Free Software
5951 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
5952 + */
5953 +
5954 +/*
5955 + * lookup and dentry operations
5956 + */
5957 +
5958 +#include <linux/namei.h>
5959 +#include "aufs.h"
5960 +
5961 +#define AuLkup_ALLOW_NEG       1
5962 +#define au_ftest_lkup(flags, name)     ((flags) & AuLkup_##name)
5963 +#define au_fset_lkup(flags, name) \
5964 +       do { (flags) |= AuLkup_##name; } while (0)
5965 +#define au_fclr_lkup(flags, name) \
5966 +       do { (flags) &= ~AuLkup_##name; } while (0)
5967 +
5968 +struct au_do_lookup_args {
5969 +       unsigned int            flags;
5970 +       mode_t                  type;
5971 +};
5972 +
5973 +/*
5974 + * returns positive/negative dentry, NULL or an error.
5975 + * NULL means whiteout-ed or not-found.
5976 + */
5977 +static struct dentry*
5978 +au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
5979 +            aufs_bindex_t bindex, struct qstr *wh_name,
5980 +            struct au_do_lookup_args *args)
5981 +{
5982 +       struct dentry *h_dentry;
5983 +       struct inode *h_inode, *inode;
5984 +       struct au_branch *br;
5985 +       int wh_found, opq;
5986 +       unsigned char wh_able;
5987 +       const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
5988 +
5989 +       wh_found = 0;
5990 +       br = au_sbr(dentry->d_sb, bindex);
5991 +       wh_able = !!au_br_whable(br->br_perm);
5992 +       if (wh_able)
5993 +               wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
5994 +       h_dentry = ERR_PTR(wh_found);
5995 +       if (!wh_found)
5996 +               goto real_lookup;
5997 +       if (unlikely(wh_found < 0))
5998 +               goto out;
5999 +
6000 +       /* We found a whiteout */
6001 +       /* au_set_dbend(dentry, bindex); */
6002 +       au_set_dbwh(dentry, bindex);
6003 +       if (!allow_neg)
6004 +               return NULL; /* success */
6005 +
6006 +real_lookup:
6007 +       h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
6008 +       if (IS_ERR(h_dentry))
6009 +               goto out;
6010 +
6011 +       h_inode = h_dentry->d_inode;
6012 +       if (!h_inode) {
6013 +               if (!allow_neg)
6014 +                       goto out_neg;
6015 +       } else if (wh_found
6016 +                  || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
6017 +               goto out_neg;
6018 +
6019 +       if (au_dbend(dentry) <= bindex)
6020 +               au_set_dbend(dentry, bindex);
6021 +       if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
6022 +               au_set_dbstart(dentry, bindex);
6023 +       au_set_h_dptr(dentry, bindex, h_dentry);
6024 +
6025 +       inode = dentry->d_inode;
6026 +       if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
6027 +           || (inode && !S_ISDIR(inode->i_mode)))
6028 +               goto out; /* success */
6029 +
6030 +       mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
6031 +       opq = au_diropq_test(h_dentry, br);
6032 +       mutex_unlock(&h_inode->i_mutex);
6033 +       if (opq > 0)
6034 +               au_set_dbdiropq(dentry, bindex);
6035 +       else if (unlikely(opq < 0)) {
6036 +               au_set_h_dptr(dentry, bindex, NULL);
6037 +               h_dentry = ERR_PTR(opq);
6038 +       }
6039 +       goto out;
6040 +
6041 +out_neg:
6042 +       dput(h_dentry);
6043 +       h_dentry = NULL;
6044 +out:
6045 +       return h_dentry;
6046 +}
6047 +
6048 +static int au_test_shwh(struct super_block *sb, const struct qstr *name)
6049 +{
6050 +       if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
6051 +                    && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
6052 +               return -EPERM;
6053 +       return 0;
6054 +}
6055 +
6056 +/*
6057 + * returns the number of lower positive dentries,
6058 + * otherwise an error.
6059 + * can be called at unlinking with @type is zero.
6060 + */
6061 +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
6062 +{
6063 +       int npositive, err;
6064 +       aufs_bindex_t bindex, btail, bdiropq;
6065 +       unsigned char isdir;
6066 +       struct qstr whname;
6067 +       struct au_do_lookup_args args = {
6068 +               .flags          = 0,
6069 +               .type           = type
6070 +       };
6071 +       const struct qstr *name = &dentry->d_name;
6072 +       struct dentry *parent;
6073 +       struct inode *inode;
6074 +
6075 +       err = au_test_shwh(dentry->d_sb, name);
6076 +       if (unlikely(err))
6077 +               goto out;
6078 +
6079 +       err = au_wh_name_alloc(&whname, name);
6080 +       if (unlikely(err))
6081 +               goto out;
6082 +
6083 +       inode = dentry->d_inode;
6084 +       isdir = !!(inode && S_ISDIR(inode->i_mode));
6085 +       if (!type)
6086 +               au_fset_lkup(args.flags, ALLOW_NEG);
6087 +
6088 +       npositive = 0;
6089 +       parent = dget_parent(dentry);
6090 +       btail = au_dbtaildir(parent);
6091 +       for (bindex = bstart; bindex <= btail; bindex++) {
6092 +               struct dentry *h_parent, *h_dentry;
6093 +               struct inode *h_inode, *h_dir;
6094 +
6095 +               h_dentry = au_h_dptr(dentry, bindex);
6096 +               if (h_dentry) {
6097 +                       if (h_dentry->d_inode)
6098 +                               npositive++;
6099 +                       if (type != S_IFDIR)
6100 +                               break;
6101 +                       continue;
6102 +               }
6103 +               h_parent = au_h_dptr(parent, bindex);
6104 +               if (!h_parent)
6105 +                       continue;
6106 +               h_dir = h_parent->d_inode;
6107 +               if (!h_dir || !S_ISDIR(h_dir->i_mode))
6108 +                       continue;
6109 +
6110 +               mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
6111 +               h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
6112 +                                       &args);
6113 +               mutex_unlock(&h_dir->i_mutex);
6114 +               err = PTR_ERR(h_dentry);
6115 +               if (IS_ERR(h_dentry))
6116 +                       goto out_parent;
6117 +               au_fclr_lkup(args.flags, ALLOW_NEG);
6118 +
6119 +               if (au_dbwh(dentry) >= 0)
6120 +                       break;
6121 +               if (!h_dentry)
6122 +                       continue;
6123 +               h_inode = h_dentry->d_inode;
6124 +               if (!h_inode)
6125 +                       continue;
6126 +               npositive++;
6127 +               if (!args.type)
6128 +                       args.type = h_inode->i_mode & S_IFMT;
6129 +               if (args.type != S_IFDIR)
6130 +                       break;
6131 +               else if (isdir) {
6132 +                       /* the type of lower may be different */
6133 +                       bdiropq = au_dbdiropq(dentry);
6134 +                       if (bdiropq >= 0 && bdiropq <= bindex)
6135 +                               break;
6136 +               }
6137 +       }
6138 +
6139 +       if (npositive) {
6140 +               AuLabel(positive);
6141 +               au_update_dbstart(dentry);
6142 +       }
6143 +       err = npositive;
6144 +       if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
6145 +                    && au_dbstart(dentry) < 0)) {
6146 +               err = -EIO;
6147 +               AuIOErr("both of real entry and whiteout found, %.*s, err %d\n",
6148 +                       AuDLNPair(dentry), err);
6149 +       }
6150 +
6151 +out_parent:
6152 +       dput(parent);
6153 +       kfree(whname.name);
6154 +out:
6155 +       return err;
6156 +}
6157 +
6158 +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
6159 +                              struct au_branch *br)
6160 +{
6161 +       struct dentry *dentry;
6162 +       int wkq_err;
6163 +
6164 +       if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
6165 +               dentry = vfsub_lkup_one(name, parent);
6166 +       else {
6167 +               struct vfsub_lkup_one_args args = {
6168 +                       .errp   = &dentry,
6169 +                       .name   = name,
6170 +                       .parent = parent
6171 +               };
6172 +
6173 +               wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
6174 +               if (unlikely(wkq_err))
6175 +                       dentry = ERR_PTR(wkq_err);
6176 +       }
6177 +
6178 +       return dentry;
6179 +}
6180 +
6181 +/*
6182 + * lookup @dentry on @bindex which should be negative.
6183 + */
6184 +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex)
6185 +{
6186 +       int err;
6187 +       struct dentry *parent, *h_parent, *h_dentry;
6188 +
6189 +       parent = dget_parent(dentry);
6190 +       h_parent = au_h_dptr(parent, bindex);
6191 +       h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent,
6192 +                                  au_sbr(dentry->d_sb, bindex));
6193 +       err = PTR_ERR(h_dentry);
6194 +       if (IS_ERR(h_dentry))
6195 +               goto out;
6196 +       if (unlikely(h_dentry->d_inode)) {
6197 +               err = -EIO;
6198 +               AuIOErr("%.*s should be negative on b%d.\n",
6199 +                       AuDLNPair(h_dentry), bindex);
6200 +               dput(h_dentry);
6201 +               goto out;
6202 +       }
6203 +
6204 +       err = 0;
6205 +       if (bindex < au_dbstart(dentry))
6206 +               au_set_dbstart(dentry, bindex);
6207 +       if (au_dbend(dentry) < bindex)
6208 +               au_set_dbend(dentry, bindex);
6209 +       au_set_h_dptr(dentry, bindex, h_dentry);
6210 +
6211 +out:
6212 +       dput(parent);
6213 +       return err;
6214 +}
6215 +
6216 +/* ---------------------------------------------------------------------- */
6217 +
6218 +/* subset of struct inode */
6219 +struct au_iattr {
6220 +       unsigned long           i_ino;
6221 +       /* unsigned int         i_nlink; */
6222 +       kuid_t                  i_uid;
6223 +       kgid_t                  i_gid;
6224 +       u64                     i_version;
6225 +/*
6226 +       loff_t                  i_size;
6227 +       blkcnt_t                i_blocks;
6228 +*/
6229 +       umode_t                 i_mode;
6230 +};
6231 +
6232 +static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
6233 +{
6234 +       ia->i_ino = h_inode->i_ino;
6235 +       /* ia->i_nlink = h_inode->i_nlink; */
6236 +       ia->i_uid = h_inode->i_uid;
6237 +       ia->i_gid = h_inode->i_gid;
6238 +       ia->i_version = h_inode->i_version;
6239 +/*
6240 +       ia->i_size = h_inode->i_size;
6241 +       ia->i_blocks = h_inode->i_blocks;
6242 +*/
6243 +       ia->i_mode = (h_inode->i_mode & S_IFMT);
6244 +}
6245 +
6246 +static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
6247 +{
6248 +       return ia->i_ino != h_inode->i_ino
6249 +               /* || ia->i_nlink != h_inode->i_nlink */
6250 +               || !uid_eq(ia->i_uid, h_inode->i_uid)
6251 +               || !gid_eq(ia->i_gid, h_inode->i_gid)
6252 +               || ia->i_version != h_inode->i_version
6253 +/*
6254 +               || ia->i_size != h_inode->i_size
6255 +               || ia->i_blocks != h_inode->i_blocks
6256 +*/
6257 +               || ia->i_mode != (h_inode->i_mode & S_IFMT);
6258 +}
6259 +
6260 +static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
6261 +                             struct au_branch *br)
6262 +{
6263 +       int err;
6264 +       struct au_iattr ia;
6265 +       struct inode *h_inode;
6266 +       struct dentry *h_d;
6267 +       struct super_block *h_sb;
6268 +
6269 +       err = 0;
6270 +       memset(&ia, -1, sizeof(ia));
6271 +       h_sb = h_dentry->d_sb;
6272 +       h_inode = h_dentry->d_inode;
6273 +       if (h_inode)
6274 +               au_iattr_save(&ia, h_inode);
6275 +       else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
6276 +               /* nfs d_revalidate may return 0 for negative dentry */
6277 +               /* fuse d_revalidate always return 0 for negative dentry */
6278 +               goto out;
6279 +
6280 +       /* main purpose is namei.c:cached_lookup() and d_revalidate */
6281 +       h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
6282 +       err = PTR_ERR(h_d);
6283 +       if (IS_ERR(h_d))
6284 +               goto out;
6285 +
6286 +       err = 0;
6287 +       if (unlikely(h_d != h_dentry
6288 +                    || h_d->d_inode != h_inode
6289 +                    || (h_inode && au_iattr_test(&ia, h_inode))))
6290 +               err = au_busy_or_stale();
6291 +       dput(h_d);
6292 +
6293 +out:
6294 +       AuTraceErr(err);
6295 +       return err;
6296 +}
6297 +
6298 +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
6299 +               struct dentry *h_parent, struct au_branch *br)
6300 +{
6301 +       int err;
6302 +
6303 +       err = 0;
6304 +       if (udba == AuOpt_UDBA_REVAL
6305 +           && !au_test_fs_remote(h_dentry->d_sb)) {
6306 +               IMustLock(h_dir);
6307 +               err = (h_dentry->d_parent->d_inode != h_dir);
6308 +       } else if (udba != AuOpt_UDBA_NONE)
6309 +               err = au_h_verify_dentry(h_dentry, h_parent, br);
6310 +
6311 +       return err;
6312 +}
6313 +
6314 +/* ---------------------------------------------------------------------- */
6315 +
6316 +static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
6317 +{
6318 +       int err;
6319 +       aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
6320 +       struct au_hdentry tmp, *p, *q;
6321 +       struct au_dinfo *dinfo;
6322 +       struct super_block *sb;
6323 +
6324 +       DiMustWriteLock(dentry);
6325 +
6326 +       sb = dentry->d_sb;
6327 +       dinfo = au_di(dentry);
6328 +       bend = dinfo->di_bend;
6329 +       bwh = dinfo->di_bwh;
6330 +       bdiropq = dinfo->di_bdiropq;
6331 +       p = dinfo->di_hdentry + dinfo->di_bstart;
6332 +       for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
6333 +               if (!p->hd_dentry)
6334 +                       continue;
6335 +
6336 +               new_bindex = au_br_index(sb, p->hd_id);
6337 +               if (new_bindex == bindex)
6338 +                       continue;
6339 +
6340 +               if (dinfo->di_bwh == bindex)
6341 +                       bwh = new_bindex;
6342 +               if (dinfo->di_bdiropq == bindex)
6343 +                       bdiropq = new_bindex;
6344 +               if (new_bindex < 0) {
6345 +                       au_hdput(p);
6346 +                       p->hd_dentry = NULL;
6347 +                       continue;
6348 +               }
6349 +
6350 +               /* swap two lower dentries, and loop again */
6351 +               q = dinfo->di_hdentry + new_bindex;
6352 +               tmp = *q;
6353 +               *q = *p;
6354 +               *p = tmp;
6355 +               if (tmp.hd_dentry) {
6356 +                       bindex--;
6357 +                       p--;
6358 +               }
6359 +       }
6360 +
6361 +       dinfo->di_bwh = -1;
6362 +       if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
6363 +               dinfo->di_bwh = bwh;
6364 +
6365 +       dinfo->di_bdiropq = -1;
6366 +       if (bdiropq >= 0
6367 +           && bdiropq <= au_sbend(sb)
6368 +           && au_sbr_whable(sb, bdiropq))
6369 +               dinfo->di_bdiropq = bdiropq;
6370 +
6371 +       err = -EIO;
6372 +       dinfo->di_bstart = -1;
6373 +       dinfo->di_bend = -1;
6374 +       bend = au_dbend(parent);
6375 +       p = dinfo->di_hdentry;
6376 +       for (bindex = 0; bindex <= bend; bindex++, p++)
6377 +               if (p->hd_dentry) {
6378 +                       dinfo->di_bstart = bindex;
6379 +                       break;
6380 +               }
6381 +
6382 +       if (dinfo->di_bstart >= 0) {
6383 +               p = dinfo->di_hdentry + bend;
6384 +               for (bindex = bend; bindex >= 0; bindex--, p--)
6385 +                       if (p->hd_dentry) {
6386 +                               dinfo->di_bend = bindex;
6387 +                               err = 0;
6388 +                               break;
6389 +                       }
6390 +       }
6391 +
6392 +       return err;
6393 +}
6394 +
6395 +static void au_do_hide(struct dentry *dentry)
6396 +{
6397 +       struct inode *inode;
6398 +
6399 +       inode = dentry->d_inode;
6400 +       if (inode) {
6401 +               if (!S_ISDIR(inode->i_mode)) {
6402 +                       if (inode->i_nlink && !d_unhashed(dentry))
6403 +                               drop_nlink(inode);
6404 +               } else {
6405 +                       clear_nlink(inode);
6406 +                       /* stop next lookup */
6407 +                       inode->i_flags |= S_DEAD;
6408 +               }
6409 +               smp_mb(); /* necessary? */
6410 +       }
6411 +       d_drop(dentry);
6412 +}
6413 +
6414 +static int au_hide_children(struct dentry *parent)
6415 +{
6416 +       int err, i, j, ndentry;
6417 +       struct au_dcsub_pages dpages;
6418 +       struct au_dpage *dpage;
6419 +       struct dentry *dentry;
6420 +
6421 +       err = au_dpages_init(&dpages, GFP_NOFS);
6422 +       if (unlikely(err))
6423 +               goto out;
6424 +       err = au_dcsub_pages(&dpages, parent, NULL, NULL);
6425 +       if (unlikely(err))
6426 +               goto out_dpages;
6427 +
6428 +       /* in reverse order */
6429 +       for (i = dpages.ndpage - 1; i >= 0; i--) {
6430 +               dpage = dpages.dpages + i;
6431 +               ndentry = dpage->ndentry;
6432 +               for (j = ndentry - 1; j >= 0; j--) {
6433 +                       dentry = dpage->dentries[j];
6434 +                       if (dentry != parent)
6435 +                               au_do_hide(dentry);
6436 +               }
6437 +       }
6438 +
6439 +out_dpages:
6440 +       au_dpages_free(&dpages);
6441 +out:
6442 +       return err;
6443 +}
6444 +
6445 +static void au_hide(struct dentry *dentry)
6446 +{
6447 +       int err;
6448 +       struct inode *inode;
6449 +
6450 +       AuDbgDentry(dentry);
6451 +       inode = dentry->d_inode;
6452 +       if (inode && S_ISDIR(inode->i_mode)) {
6453 +               /* shrink_dcache_parent(dentry); */
6454 +               err = au_hide_children(dentry);
6455 +               if (unlikely(err))
6456 +                       AuIOErr("%.*s, failed hiding children, ignored %d\n",
6457 +                               AuDLNPair(dentry), err);
6458 +       }
6459 +       au_do_hide(dentry);
6460 +}
6461 +
6462 +/*
6463 + * By adding a dirty branch, a cached dentry may be affected in various ways.
6464 + *
6465 + * a dirty branch is added
6466 + * - on the top of layers
6467 + * - in the middle of layers
6468 + * - to the bottom of layers
6469 + *
6470 + * on the added branch there exists
6471 + * - a whiteout
6472 + * - a diropq
6473 + * - a same named entry
6474 + *   + exist
6475 + *     * negative --> positive
6476 + *     * positive --> positive
6477 + *      - type is unchanged
6478 + *      - type is changed
6479 + *   + doesn't exist
6480 + *     * negative --> negative
6481 + *     * positive --> negative (rejected by au_br_del() for non-dir case)
6482 + * - none
6483 + */
6484 +static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
6485 +                              struct au_dinfo *tmp)
6486 +{
6487 +       int err;
6488 +       aufs_bindex_t bindex, bend;
6489 +       struct {
6490 +               struct dentry *dentry;
6491 +               struct inode *inode;
6492 +               mode_t mode;
6493 +       } orig_h, tmp_h;
6494 +       struct au_hdentry *hd;
6495 +       struct inode *inode, *h_inode;
6496 +       struct dentry *h_dentry;
6497 +
6498 +       err = 0;
6499 +       AuDebugOn(dinfo->di_bstart < 0);
6500 +       orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
6501 +       orig_h.inode = orig_h.dentry->d_inode;
6502 +       orig_h.mode = 0;
6503 +       if (orig_h.inode)
6504 +               orig_h.mode = orig_h.inode->i_mode & S_IFMT;
6505 +       memset(&tmp_h, 0, sizeof(tmp_h));
6506 +       if (tmp->di_bstart >= 0) {
6507 +               tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
6508 +               tmp_h.inode = tmp_h.dentry->d_inode;
6509 +               if (tmp_h.inode)
6510 +                       tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
6511 +       }
6512 +
6513 +       inode = dentry->d_inode;
6514 +       if (!orig_h.inode) {
6515 +               AuDbg("nagative originally\n");
6516 +               if (inode) {
6517 +                       au_hide(dentry);
6518 +                       goto out;
6519 +               }
6520 +               AuDebugOn(inode);
6521 +               AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
6522 +               AuDebugOn(dinfo->di_bdiropq != -1);
6523 +
6524 +               if (!tmp_h.inode) {
6525 +                       AuDbg("negative --> negative\n");
6526 +                       /* should have only one negative lower */
6527 +                       if (tmp->di_bstart >= 0
6528 +                           && tmp->di_bstart < dinfo->di_bstart) {
6529 +                               AuDebugOn(tmp->di_bstart != tmp->di_bend);
6530 +                               AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
6531 +                               au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
6532 +                               au_di_cp(dinfo, tmp);
6533 +                               hd = tmp->di_hdentry + tmp->di_bstart;
6534 +                               au_set_h_dptr(dentry, tmp->di_bstart,
6535 +                                             dget(hd->hd_dentry));
6536 +                       }
6537 +                       au_dbg_verify_dinode(dentry);
6538 +               } else {
6539 +                       AuDbg("negative --> positive\n");
6540 +                       /*
6541 +                        * similar to the behaviour of creating with bypassing
6542 +                        * aufs.
6543 +                        * unhash it in order to force an error in the
6544 +                        * succeeding create operation.
6545 +                        * we should not set S_DEAD here.
6546 +                        */
6547 +                       d_drop(dentry);
6548 +                       /* au_di_swap(tmp, dinfo); */
6549 +                       au_dbg_verify_dinode(dentry);
6550 +               }
6551 +       } else {
6552 +               AuDbg("positive originally\n");
6553 +               /* inode may be NULL */
6554 +               AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
6555 +               if (!tmp_h.inode) {
6556 +                       AuDbg("positive --> negative\n");
6557 +                       /* or bypassing aufs */
6558 +                       au_hide(dentry);
6559 +                       if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
6560 +                               dinfo->di_bwh = tmp->di_bwh;
6561 +                       if (inode)
6562 +                               err = au_refresh_hinode_self(inode);
6563 +                       au_dbg_verify_dinode(dentry);
6564 +               } else if (orig_h.mode == tmp_h.mode) {
6565 +                       AuDbg("positive --> positive, same type\n");
6566 +                       if (!S_ISDIR(orig_h.mode)
6567 +                           && dinfo->di_bstart > tmp->di_bstart) {
6568 +                               /*
6569 +                                * similar to the behaviour of removing and
6570 +                                * creating.
6571 +                                */
6572 +                               au_hide(dentry);
6573 +                               if (inode)
6574 +                                       err = au_refresh_hinode_self(inode);
6575 +                               au_dbg_verify_dinode(dentry);
6576 +                       } else {
6577 +                               /* fill empty slots */
6578 +                               if (dinfo->di_bstart > tmp->di_bstart)
6579 +                                       dinfo->di_bstart = tmp->di_bstart;
6580 +                               if (dinfo->di_bend < tmp->di_bend)
6581 +                                       dinfo->di_bend = tmp->di_bend;
6582 +                               dinfo->di_bwh = tmp->di_bwh;
6583 +                               dinfo->di_bdiropq = tmp->di_bdiropq;
6584 +                               hd = tmp->di_hdentry;
6585 +                               bend = dinfo->di_bend;
6586 +                               for (bindex = tmp->di_bstart; bindex <= bend;
6587 +                                    bindex++) {
6588 +                                       if (au_h_dptr(dentry, bindex))
6589 +                                               continue;
6590 +                                       h_dentry = hd[bindex].hd_dentry;
6591 +                                       if (!h_dentry)
6592 +                                               continue;
6593 +                                       h_inode = h_dentry->d_inode;
6594 +                                       AuDebugOn(!h_inode);
6595 +                                       AuDebugOn(orig_h.mode
6596 +                                                 != (h_inode->i_mode
6597 +                                                     & S_IFMT));
6598 +                                       au_set_h_dptr(dentry, bindex,
6599 +                                                     dget(h_dentry));
6600 +                               }
6601 +                               err = au_refresh_hinode(inode, dentry);
6602 +                               au_dbg_verify_dinode(dentry);
6603 +                       }
6604 +               } else {
6605 +                       AuDbg("positive --> positive, different type\n");
6606 +                       /* similar to the behaviour of removing and creating */
6607 +                       au_hide(dentry);
6608 +                       if (inode)
6609 +                               err = au_refresh_hinode_self(inode);
6610 +                       au_dbg_verify_dinode(dentry);
6611 +               }
6612 +       }
6613 +
6614 +out:
6615 +       return err;
6616 +}
6617 +
6618 +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
6619 +{
6620 +       int err, ebrange;
6621 +       unsigned int sigen;
6622 +       struct au_dinfo *dinfo, *tmp;
6623 +       struct super_block *sb;
6624 +       struct inode *inode;
6625 +
6626 +       DiMustWriteLock(dentry);
6627 +       AuDebugOn(IS_ROOT(dentry));
6628 +       AuDebugOn(!parent->d_inode);
6629 +
6630 +       sb = dentry->d_sb;
6631 +       inode = dentry->d_inode;
6632 +       sigen = au_sigen(sb);
6633 +       err = au_digen_test(parent, sigen);
6634 +       if (unlikely(err))
6635 +               goto out;
6636 +
6637 +       dinfo = au_di(dentry);
6638 +       err = au_di_realloc(dinfo, au_sbend(sb) + 1);
6639 +       if (unlikely(err))
6640 +               goto out;
6641 +       ebrange = au_dbrange_test(dentry);
6642 +       if (!ebrange)
6643 +               ebrange = au_do_refresh_hdentry(dentry, parent);
6644 +
6645 +       if (d_unhashed(dentry) || ebrange) {
6646 +               AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
6647 +               if (inode)
6648 +                       err = au_refresh_hinode_self(inode);
6649 +               au_dbg_verify_dinode(dentry);
6650 +               if (!err)
6651 +                       goto out_dgen; /* success */
6652 +               goto out;
6653 +       }
6654 +
6655 +       /* temporary dinfo */
6656 +       AuDbgDentry(dentry);
6657 +       err = -ENOMEM;
6658 +       tmp = au_di_alloc(sb, AuLsc_DI_TMP);
6659 +       if (unlikely(!tmp))
6660 +               goto out;
6661 +       au_di_swap(tmp, dinfo);
6662 +       /* returns the number of positive dentries */
6663 +       /*
6664 +        * if current working dir is removed, it returns an error.
6665 +        * but the dentry is legal.
6666 +        */
6667 +       err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
6668 +       AuDbgDentry(dentry);
6669 +       au_di_swap(tmp, dinfo);
6670 +       if (err == -ENOENT)
6671 +               err = 0;
6672 +       if (err >= 0) {
6673 +               /* compare/refresh by dinfo */
6674 +               AuDbgDentry(dentry);
6675 +               err = au_refresh_by_dinfo(dentry, dinfo, tmp);
6676 +               au_dbg_verify_dinode(dentry);
6677 +               AuTraceErr(err);
6678 +       }
6679 +       au_rw_write_unlock(&tmp->di_rwsem);
6680 +       au_di_free(tmp);
6681 +       if (unlikely(err))
6682 +               goto out;
6683 +
6684 +out_dgen:
6685 +       au_update_digen(dentry);
6686 +out:
6687 +       if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
6688 +               AuIOErr("failed refreshing %.*s, %d\n",
6689 +                       AuDLNPair(dentry), err);
6690 +               AuDbgDentry(dentry);
6691 +       }
6692 +       AuTraceErr(err);
6693 +       return err;
6694 +}
6695 +
6696 +static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
6697 +                          struct dentry *dentry, aufs_bindex_t bindex)
6698 +{
6699 +       int err, valid;
6700 +
6701 +       err = 0;
6702 +       if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
6703 +               goto out;
6704 +
6705 +       AuDbg("b%d\n", bindex);
6706 +       /*
6707 +        * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
6708 +        * due to whiteout and branch permission.
6709 +        */
6710 +       flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
6711 +                  | LOOKUP_FOLLOW | LOOKUP_EXCL);
6712 +       /* it may return tri-state */
6713 +       valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
6714 +
6715 +       if (unlikely(valid < 0))
6716 +               err = valid;
6717 +       else if (!valid)
6718 +               err = -EINVAL;
6719 +
6720 +out:
6721 +       AuTraceErr(err);
6722 +       return err;
6723 +}
6724 +
6725 +/* todo: remove this */
6726 +static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
6727 +                         unsigned int flags, int do_udba)
6728 +{
6729 +       int err;
6730 +       umode_t mode, h_mode;
6731 +       aufs_bindex_t bindex, btail, bstart, ibs, ibe;
6732 +       unsigned char plus, unhashed, is_root, h_plus;
6733 +       struct inode *h_inode, *h_cached_inode;
6734 +       struct dentry *h_dentry;
6735 +       struct qstr *name, *h_name;
6736 +
6737 +       err = 0;
6738 +       plus = 0;
6739 +       mode = 0;
6740 +       ibs = -1;
6741 +       ibe = -1;
6742 +       unhashed = !!d_unhashed(dentry);
6743 +       is_root = !!IS_ROOT(dentry);
6744 +       name = &dentry->d_name;
6745 +
6746 +       /*
6747 +        * Theoretically, REVAL test should be unnecessary in case of
6748 +        * {FS,I}NOTIFY.
6749 +        * But {fs,i}notify doesn't fire some necessary events,
6750 +        *      IN_ATTRIB for atime/nlink/pageio
6751 +        *      IN_DELETE for NFS dentry
6752 +        * Let's do REVAL test too.
6753 +        */
6754 +       if (do_udba && inode) {
6755 +               mode = (inode->i_mode & S_IFMT);
6756 +               plus = (inode->i_nlink > 0);
6757 +               ibs = au_ibstart(inode);
6758 +               ibe = au_ibend(inode);
6759 +       }
6760 +
6761 +       bstart = au_dbstart(dentry);
6762 +       btail = bstart;
6763 +       if (inode && S_ISDIR(inode->i_mode))
6764 +               btail = au_dbtaildir(dentry);
6765 +       for (bindex = bstart; bindex <= btail; bindex++) {
6766 +               h_dentry = au_h_dptr(dentry, bindex);
6767 +               if (!h_dentry)
6768 +                       continue;
6769 +
6770 +               AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
6771 +               spin_lock(&h_dentry->d_lock);
6772 +               h_name = &h_dentry->d_name;
6773 +               if (unlikely(do_udba
6774 +                            && !is_root
6775 +                            && (unhashed != !!d_unhashed(h_dentry)
6776 +                                || name->len != h_name->len
6777 +                                || memcmp(name->name, h_name->name, name->len))
6778 +                           )) {
6779 +                       AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n",
6780 +                                 unhashed, d_unhashed(h_dentry),
6781 +                                 AuDLNPair(dentry), AuDLNPair(h_dentry));
6782 +                       spin_unlock(&h_dentry->d_lock);
6783 +                       goto err;
6784 +               }
6785 +               spin_unlock(&h_dentry->d_lock);
6786 +
6787 +               err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
6788 +               if (unlikely(err))
6789 +                       /* do not goto err, to keep the errno */
6790 +                       break;
6791 +
6792 +               /* todo: plink too? */
6793 +               if (!do_udba)
6794 +                       continue;
6795 +
6796 +               /* UDBA tests */
6797 +               h_inode = h_dentry->d_inode;
6798 +               if (unlikely(!!inode != !!h_inode))
6799 +                       goto err;
6800 +
6801 +               h_plus = plus;
6802 +               h_mode = mode;
6803 +               h_cached_inode = h_inode;
6804 +               if (h_inode) {
6805 +                       h_mode = (h_inode->i_mode & S_IFMT);
6806 +                       h_plus = (h_inode->i_nlink > 0);
6807 +               }
6808 +               if (inode && ibs <= bindex && bindex <= ibe)
6809 +                       h_cached_inode = au_h_iptr(inode, bindex);
6810 +
6811 +               if (unlikely(plus != h_plus
6812 +                            || mode != h_mode
6813 +                            || h_cached_inode != h_inode))
6814 +                       goto err;
6815 +               continue;
6816 +
6817 +       err:
6818 +               err = -EINVAL;
6819 +               break;
6820 +       }
6821 +
6822 +       return err;
6823 +}
6824 +
6825 +/* todo: consolidate with do_refresh() and au_reval_for_attr() */
6826 +static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
6827 +{
6828 +       int err;
6829 +       struct dentry *parent;
6830 +
6831 +       if (!au_digen_test(dentry, sigen))
6832 +               return 0;
6833 +
6834 +       parent = dget_parent(dentry);
6835 +       di_read_lock_parent(parent, AuLock_IR);
6836 +       AuDebugOn(au_digen_test(parent, sigen));
6837 +       au_dbg_verify_gen(parent, sigen);
6838 +       err = au_refresh_dentry(dentry, parent);
6839 +       di_read_unlock(parent, AuLock_IR);
6840 +       dput(parent);
6841 +       AuTraceErr(err);
6842 +       return err;
6843 +}
6844 +
6845 +int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
6846 +{
6847 +       int err;
6848 +       struct dentry *d, *parent;
6849 +       struct inode *inode;
6850 +
6851 +       if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
6852 +               return simple_reval_dpath(dentry, sigen);
6853 +
6854 +       /* slow loop, keep it simple and stupid */
6855 +       /* cf: au_cpup_dirs() */
6856 +       err = 0;
6857 +       parent = NULL;
6858 +       while (au_digen_test(dentry, sigen)) {
6859 +               d = dentry;
6860 +               while (1) {
6861 +                       dput(parent);
6862 +                       parent = dget_parent(d);
6863 +                       if (!au_digen_test(parent, sigen))
6864 +                               break;
6865 +                       d = parent;
6866 +               }
6867 +
6868 +               inode = d->d_inode;
6869 +               if (d != dentry)
6870 +                       di_write_lock_child2(d);
6871 +
6872 +               /* someone might update our dentry while we were sleeping */
6873 +               if (au_digen_test(d, sigen)) {
6874 +                       /*
6875 +                        * todo: consolidate with simple_reval_dpath(),
6876 +                        * do_refresh() and au_reval_for_attr().
6877 +                        */
6878 +                       di_read_lock_parent(parent, AuLock_IR);
6879 +                       err = au_refresh_dentry(d, parent);
6880 +                       di_read_unlock(parent, AuLock_IR);
6881 +               }
6882 +
6883 +               if (d != dentry)
6884 +                       di_write_unlock(d);
6885 +               dput(parent);
6886 +               if (unlikely(err))
6887 +                       break;
6888 +       }
6889 +
6890 +       return err;
6891 +}
6892 +
6893 +/*
6894 + * if valid returns 1, otherwise 0.
6895 + */
6896 +static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
6897 +{
6898 +       int valid, err;
6899 +       unsigned int sigen;
6900 +       unsigned char do_udba;
6901 +       struct super_block *sb;
6902 +       struct inode *inode;
6903 +
6904 +       /* todo: support rcu-walk? */
6905 +       if (flags & LOOKUP_RCU)
6906 +               return -ECHILD;
6907 +
6908 +       valid = 0;
6909 +       if (unlikely(!au_di(dentry)))
6910 +               goto out;
6911 +
6912 +       inode = dentry->d_inode;
6913 +       if (inode && is_bad_inode(inode))
6914 +               goto out;
6915 +
6916 +       valid = 1;
6917 +       sb = dentry->d_sb;
6918 +       /*
6919 +        * todo: very ugly
6920 +        * i_mutex of parent dir may be held,
6921 +        * but we should not return 'invalid' due to busy.
6922 +        */
6923 +       err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
6924 +       if (unlikely(err)) {
6925 +               valid = err;
6926 +               AuTraceErr(err);
6927 +               goto out;
6928 +       }
6929 +       if (unlikely(au_dbrange_test(dentry))) {
6930 +               err = -EINVAL;
6931 +               AuTraceErr(err);
6932 +               goto out_dgrade;
6933 +       }
6934 +
6935 +       sigen = au_sigen(sb);
6936 +       if (au_digen_test(dentry, sigen)) {
6937 +               AuDebugOn(IS_ROOT(dentry));
6938 +               err = au_reval_dpath(dentry, sigen);
6939 +               if (unlikely(err)) {
6940 +                       AuTraceErr(err);
6941 +                       goto out_dgrade;
6942 +               }
6943 +       }
6944 +       di_downgrade_lock(dentry, AuLock_IR);
6945 +
6946 +       err = -EINVAL;
6947 +       if (inode && (IS_DEADDIR(inode) || !inode->i_nlink))
6948 +               goto out_inval;
6949 +
6950 +       do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
6951 +       if (do_udba && inode) {
6952 +               aufs_bindex_t bstart = au_ibstart(inode);
6953 +               struct inode *h_inode;
6954 +
6955 +               if (bstart >= 0) {
6956 +                       h_inode = au_h_iptr(inode, bstart);
6957 +                       if (h_inode && au_test_higen(inode, h_inode))
6958 +                               goto out_inval;
6959 +               }
6960 +       }
6961 +
6962 +       err = h_d_revalidate(dentry, inode, flags, do_udba);
6963 +       if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
6964 +               err = -EIO;
6965 +               AuDbg("both of real entry and whiteout found, %.*s, err %d\n",
6966 +                     AuDLNPair(dentry), err);
6967 +       }
6968 +       goto out_inval;
6969 +
6970 +out_dgrade:
6971 +       di_downgrade_lock(dentry, AuLock_IR);
6972 +out_inval:
6973 +       aufs_read_unlock(dentry, AuLock_IR);
6974 +       AuTraceErr(err);
6975 +       valid = !err;
6976 +out:
6977 +       if (!valid) {
6978 +               AuDbg("%.*s invalid, %d\n", AuDLNPair(dentry), valid);
6979 +               d_drop(dentry);
6980 +       }
6981 +       return valid;
6982 +}
6983 +
6984 +static void aufs_d_release(struct dentry *dentry)
6985 +{
6986 +       if (au_di(dentry)) {
6987 +               au_di_fin(dentry);
6988 +               au_hn_di_reinit(dentry);
6989 +       }
6990 +}
6991 +
6992 +const struct dentry_operations aufs_dop = {
6993 +       .d_revalidate   = aufs_d_revalidate,
6994 +       .d_release      = aufs_d_release
6995 +};
6996 diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
6997 --- /usr/share/empty/fs/aufs/dentry.h   1970-01-01 01:00:00.000000000 +0100
6998 +++ linux/fs/aufs/dentry.h      2013-01-11 19:46:12.635947932 +0100
6999 @@ -0,0 +1,234 @@
7000 +/*
7001 + * Copyright (C) 2005-2013 Junjiro R. Okajima
7002 + *
7003 + * This program, aufs is free software; you can redistribute it and/or modify
7004 + * it under the terms of the GNU General Public License as published by
7005 + * the Free Software Foundation; either version 2 of the License, or
7006 + * (at your option) any later version.
7007 + *
7008 + * This program is distributed in the hope that it will be useful,
7009 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7010 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7011 + * GNU General Public License for more details.
7012 + *
7013 + * You should have received a copy of the GNU General Public License
7014 + * along with this program; if not, write to the Free Software
7015 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
7016 + */
7017 +
7018 +/*
7019 + * lookup and dentry operations
7020 + */
7021 +
7022 +#ifndef __AUFS_DENTRY_H__
7023 +#define __AUFS_DENTRY_H__
7024 +
7025 +#ifdef __KERNEL__
7026 +
7027 +#include <linux/dcache.h>
7028 +#include "rwsem.h"
7029 +
7030 +struct au_hdentry {
7031 +       struct dentry           *hd_dentry;
7032 +       aufs_bindex_t           hd_id;
7033 +};
7034 +
7035 +struct au_dinfo {
7036 +       atomic_t                di_generation;
7037 +
7038 +       struct au_rwsem         di_rwsem;
7039 +       aufs_bindex_t           di_bstart, di_bend, di_bwh, di_bdiropq;
7040 +       struct au_hdentry       *di_hdentry;
7041 +} ____cacheline_aligned_in_smp;
7042 +
7043 +/* ---------------------------------------------------------------------- */
7044 +
7045 +/* dentry.c */
7046 +extern const struct dentry_operations aufs_dop;
7047 +struct au_branch;
7048 +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
7049 +                              struct au_branch *br);
7050 +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7051 +               struct dentry *h_parent, struct au_branch *br);
7052 +
7053 +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
7054 +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex);
7055 +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
7056 +int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
7057 +
7058 +/* dinfo.c */
7059 +void au_di_init_once(void *_di);
7060 +struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
7061 +void au_di_free(struct au_dinfo *dinfo);
7062 +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
7063 +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
7064 +int au_di_init(struct dentry *dentry);
7065 +void au_di_fin(struct dentry *dentry);
7066 +int au_di_realloc(struct au_dinfo *dinfo, int nbr);
7067 +
7068 +void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
7069 +void di_read_unlock(struct dentry *d, int flags);
7070 +void di_downgrade_lock(struct dentry *d, int flags);
7071 +void di_write_lock(struct dentry *d, unsigned int lsc);
7072 +void di_write_unlock(struct dentry *d);
7073 +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
7074 +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
7075 +void di_write_unlock2(struct dentry *d1, struct dentry *d2);
7076 +
7077 +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
7078 +struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
7079 +aufs_bindex_t au_dbtail(struct dentry *dentry);
7080 +aufs_bindex_t au_dbtaildir(struct dentry *dentry);
7081 +
7082 +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
7083 +                  struct dentry *h_dentry);
7084 +int au_digen_test(struct dentry *dentry, unsigned int sigen);
7085 +int au_dbrange_test(struct dentry *dentry);
7086 +void au_update_digen(struct dentry *dentry);
7087 +void au_update_dbrange(struct dentry *dentry, int do_put_zero);
7088 +void au_update_dbstart(struct dentry *dentry);
7089 +void au_update_dbend(struct dentry *dentry);
7090 +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
7091 +
7092 +/* ---------------------------------------------------------------------- */
7093 +
7094 +static inline struct au_dinfo *au_di(struct dentry *dentry)
7095 +{
7096 +       return dentry->d_fsdata;
7097 +}
7098 +
7099 +/* ---------------------------------------------------------------------- */
7100 +
7101 +/* lock subclass for dinfo */
7102 +enum {
7103 +       AuLsc_DI_CHILD,         /* child first */
7104 +       AuLsc_DI_CHILD2,        /* rename(2), link(2), and cpup at hnotify */
7105 +       AuLsc_DI_CHILD3,        /* copyup dirs */
7106 +       AuLsc_DI_PARENT,
7107 +       AuLsc_DI_PARENT2,
7108 +       AuLsc_DI_PARENT3,
7109 +       AuLsc_DI_TMP            /* temp for replacing dinfo */
7110 +};
7111 +
7112 +/*
7113 + * di_read_lock_child, di_write_lock_child,
7114 + * di_read_lock_child2, di_write_lock_child2,
7115 + * di_read_lock_child3, di_write_lock_child3,
7116 + * di_read_lock_parent, di_write_lock_parent,
7117 + * di_read_lock_parent2, di_write_lock_parent2,
7118 + * di_read_lock_parent3, di_write_lock_parent3,
7119 + */
7120 +#define AuReadLockFunc(name, lsc) \
7121 +static inline void di_read_lock_##name(struct dentry *d, int flags) \
7122 +{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
7123 +
7124 +#define AuWriteLockFunc(name, lsc) \
7125 +static inline void di_write_lock_##name(struct dentry *d) \
7126 +{ di_write_lock(d, AuLsc_DI_##lsc); }
7127 +
7128 +#define AuRWLockFuncs(name, lsc) \
7129 +       AuReadLockFunc(name, lsc) \
7130 +       AuWriteLockFunc(name, lsc)
7131 +
7132 +AuRWLockFuncs(child, CHILD);
7133 +AuRWLockFuncs(child2, CHILD2);
7134 +AuRWLockFuncs(child3, CHILD3);
7135 +AuRWLockFuncs(parent, PARENT);
7136 +AuRWLockFuncs(parent2, PARENT2);
7137 +AuRWLockFuncs(parent3, PARENT3);
7138 +
7139 +#undef AuReadLockFunc
7140 +#undef AuWriteLockFunc
7141 +#undef AuRWLockFuncs
7142 +
7143 +#define DiMustNoWaiters(d)     AuRwMustNoWaiters(&au_di(d)->di_rwsem)
7144 +#define DiMustAnyLock(d)       AuRwMustAnyLock(&au_di(d)->di_rwsem)
7145 +#define DiMustWriteLock(d)     AuRwMustWriteLock(&au_di(d)->di_rwsem)
7146 +
7147 +/* ---------------------------------------------------------------------- */
7148 +
7149 +/* todo: memory barrier? */
7150 +static inline unsigned int au_digen(struct dentry *d)
7151 +{
7152 +       return atomic_read(&au_di(d)->di_generation);
7153 +}
7154 +
7155 +static inline void au_h_dentry_init(struct au_hdentry *hdentry)
7156 +{
7157 +       hdentry->hd_dentry = NULL;
7158 +}
7159 +
7160 +static inline void au_hdput(struct au_hdentry *hd)
7161 +{
7162 +       if (hd)
7163 +               dput(hd->hd_dentry);
7164 +}
7165 +
7166 +static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
7167 +{
7168 +       DiMustAnyLock(dentry);
7169 +       return au_di(dentry)->di_bstart;
7170 +}
7171 +
7172 +static inline aufs_bindex_t au_dbend(struct dentry *dentry)
7173 +{
7174 +       DiMustAnyLock(dentry);
7175 +       return au_di(dentry)->di_bend;
7176 +}
7177 +
7178 +static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
7179 +{
7180 +       DiMustAnyLock(dentry);
7181 +       return au_di(dentry)->di_bwh;
7182 +}
7183 +
7184 +static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
7185 +{
7186 +       DiMustAnyLock(dentry);
7187 +       return au_di(dentry)->di_bdiropq;
7188 +}
7189 +
7190 +/* todo: hard/soft set? */
7191 +static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
7192 +{
7193 +       DiMustWriteLock(dentry);
7194 +       au_di(dentry)->di_bstart = bindex;
7195 +}
7196 +
7197 +static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
7198 +{
7199 +       DiMustWriteLock(dentry);
7200 +       au_di(dentry)->di_bend = bindex;
7201 +}
7202 +
7203 +static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
7204 +{
7205 +       DiMustWriteLock(dentry);
7206 +       /* dbwh can be outside of bstart - bend range */
7207 +       au_di(dentry)->di_bwh = bindex;
7208 +}
7209 +
7210 +static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
7211 +{
7212 +       DiMustWriteLock(dentry);
7213 +       au_di(dentry)->di_bdiropq = bindex;
7214 +}
7215 +
7216 +/* ---------------------------------------------------------------------- */
7217 +
7218 +#ifdef CONFIG_AUFS_HNOTIFY
7219 +static inline void au_digen_dec(struct dentry *d)
7220 +{
7221 +       atomic_dec(&au_di(d)->di_generation);
7222 +}
7223 +
7224 +static inline void au_hn_di_reinit(struct dentry *dentry)
7225 +{
7226 +       dentry->d_fsdata = NULL;
7227 +}
7228 +#else
7229 +AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
7230 +#endif /* CONFIG_AUFS_HNOTIFY */
7231 +
7232 +#endif /* __KERNEL__ */
7233 +#endif /* __AUFS_DENTRY_H__ */
7234 diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
7235 --- /usr/share/empty/fs/aufs/dinfo.c    1970-01-01 01:00:00.000000000 +0100
7236 +++ linux/fs/aufs/dinfo.c       2013-01-11 19:46:12.635947932 +0100
7237 @@ -0,0 +1,543 @@
7238 +/*
7239 + * Copyright (C) 2005-2013 Junjiro R. Okajima
7240 + *
7241 + * This program, aufs is free software; you can redistribute it and/or modify
7242 + * it under the terms of the GNU General Public License as published by
7243 + * the Free Software Foundation; either version 2 of the License, or
7244 + * (at your option) any later version.
7245 + *
7246 + * This program is distributed in the hope that it will be useful,
7247 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7248 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7249 + * GNU General Public License for more details.
7250 + *
7251 + * You should have received a copy of the GNU General Public License
7252 + * along with this program; if not, write to the Free Software
7253 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
7254 + */
7255 +
7256 +/*
7257 + * dentry private data
7258 + */
7259 +
7260 +#include "aufs.h"
7261 +
7262 +void au_di_init_once(void *_dinfo)
7263 +{
7264 +       struct au_dinfo *dinfo = _dinfo;
7265 +       static struct lock_class_key aufs_di;
7266 +
7267 +       au_rw_init(&dinfo->di_rwsem);
7268 +       au_rw_class(&dinfo->di_rwsem, &aufs_di);
7269 +}
7270 +
7271 +struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
7272 +{
7273 +       struct au_dinfo *dinfo;
7274 +       int nbr, i;
7275 +
7276 +       dinfo = au_cache_alloc_dinfo();
7277 +       if (unlikely(!dinfo))
7278 +               goto out;
7279 +
7280 +       nbr = au_sbend(sb) + 1;
7281 +       if (nbr <= 0)
7282 +               nbr = 1;
7283 +       dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
7284 +       if (dinfo->di_hdentry) {
7285 +               au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
7286 +               dinfo->di_bstart = -1;
7287 +               dinfo->di_bend = -1;
7288 +               dinfo->di_bwh = -1;
7289 +               dinfo->di_bdiropq = -1;
7290 +               for (i = 0; i < nbr; i++)
7291 +                       dinfo->di_hdentry[i].hd_id = -1;
7292 +               goto out;
7293 +       }
7294 +
7295 +       au_cache_free_dinfo(dinfo);
7296 +       dinfo = NULL;
7297 +
7298 +out:
7299 +       return dinfo;
7300 +}
7301 +
7302 +void au_di_free(struct au_dinfo *dinfo)
7303 +{
7304 +       struct au_hdentry *p;
7305 +       aufs_bindex_t bend, bindex;
7306 +
7307 +       /* dentry may not be revalidated */
7308 +       bindex = dinfo->di_bstart;
7309 +       if (bindex >= 0) {
7310 +               bend = dinfo->di_bend;
7311 +               p = dinfo->di_hdentry + bindex;
7312 +               while (bindex++ <= bend)
7313 +                       au_hdput(p++);
7314 +       }
7315 +       kfree(dinfo->di_hdentry);
7316 +       au_cache_free_dinfo(dinfo);
7317 +}
7318 +
7319 +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
7320 +{
7321 +       struct au_hdentry *p;
7322 +       aufs_bindex_t bi;
7323 +
7324 +       AuRwMustWriteLock(&a->di_rwsem);
7325 +       AuRwMustWriteLock(&b->di_rwsem);
7326 +
7327 +#define DiSwap(v, name)                                \
7328 +       do {                                    \
7329 +               v = a->di_##name;               \
7330 +               a->di_##name = b->di_##name;    \
7331 +               b->di_##name = v;               \
7332 +       } while (0)
7333 +
7334 +       DiSwap(p, hdentry);
7335 +       DiSwap(bi, bstart);
7336 +       DiSwap(bi, bend);
7337 +       DiSwap(bi, bwh);
7338 +       DiSwap(bi, bdiropq);
7339 +       /* smp_mb(); */
7340 +
7341 +#undef DiSwap
7342 +}
7343 +
7344 +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
7345 +{
7346 +       AuRwMustWriteLock(&dst->di_rwsem);
7347 +       AuRwMustWriteLock(&src->di_rwsem);
7348 +
7349 +       dst->di_bstart = src->di_bstart;
7350 +       dst->di_bend = src->di_bend;
7351 +       dst->di_bwh = src->di_bwh;
7352 +       dst->di_bdiropq = src->di_bdiropq;
7353 +       /* smp_mb(); */
7354 +}
7355 +
7356 +int au_di_init(struct dentry *dentry)
7357 +{
7358 +       int err;
7359 +       struct super_block *sb;
7360 +       struct au_dinfo *dinfo;
7361 +
7362 +       err = 0;
7363 +       sb = dentry->d_sb;
7364 +       dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
7365 +       if (dinfo) {
7366 +               atomic_set(&dinfo->di_generation, au_sigen(sb));
7367 +               /* smp_mb(); */ /* atomic_set */
7368 +               dentry->d_fsdata = dinfo;
7369 +       } else
7370 +               err = -ENOMEM;
7371 +
7372 +       return err;
7373 +}
7374 +
7375 +void au_di_fin(struct dentry *dentry)
7376 +{
7377 +       struct au_dinfo *dinfo;
7378 +
7379 +       dinfo = au_di(dentry);
7380 +       AuRwDestroy(&dinfo->di_rwsem);
7381 +       au_di_free(dinfo);
7382 +}
7383 +
7384 +int au_di_realloc(struct au_dinfo *dinfo, int nbr)
7385 +{
7386 +       int err, sz;
7387 +       struct au_hdentry *hdp;
7388 +
7389 +       AuRwMustWriteLock(&dinfo->di_rwsem);
7390 +
7391 +       err = -ENOMEM;
7392 +       sz = sizeof(*hdp) * (dinfo->di_bend + 1);
7393 +       if (!sz)
7394 +               sz = sizeof(*hdp);
7395 +       hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
7396 +       if (hdp) {
7397 +               dinfo->di_hdentry = hdp;
7398 +               err = 0;
7399 +       }
7400 +
7401 +       return err;
7402 +}
7403 +
7404 +/* ---------------------------------------------------------------------- */
7405 +
7406 +static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
7407 +{
7408 +       switch (lsc) {
7409 +       case AuLsc_DI_CHILD:
7410 +               ii_write_lock_child(inode);
7411 +               break;
7412 +       case AuLsc_DI_CHILD2:
7413 +               ii_write_lock_child2(inode);
7414 +               break;
7415 +       case AuLsc_DI_CHILD3:
7416 +               ii_write_lock_child3(inode);
7417 +               break;
7418 +       case AuLsc_DI_PARENT:
7419 +               ii_write_lock_parent(inode);
7420 +               break;
7421 +       case AuLsc_DI_PARENT2:
7422 +               ii_write_lock_parent2(inode);
7423 +               break;
7424 +       case AuLsc_DI_PARENT3:
7425 +               ii_write_lock_parent3(inode);
7426 +               break;
7427 +       default:
7428 +               BUG();
7429 +       }
7430 +}
7431 +
7432 +static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
7433 +{
7434 +       switch (lsc) {
7435 +       case AuLsc_DI_CHILD:
7436 +               ii_read_lock_child(inode);
7437 +               break;
7438 +       case AuLsc_DI_CHILD2:
7439 +               ii_read_lock_child2(inode);
7440 +               break;
7441 +       case AuLsc_DI_CHILD3:
7442 +               ii_read_lock_child3(inode);
7443 +               break;
7444 +       case AuLsc_DI_PARENT:
7445 +               ii_read_lock_parent(inode);
7446 +               break;
7447 +       case AuLsc_DI_PARENT2:
7448 +               ii_read_lock_parent2(inode);
7449 +               break;
7450 +       case AuLsc_DI_PARENT3:
7451 +               ii_read_lock_parent3(inode);
7452 +               break;
7453 +       default:
7454 +               BUG();
7455 +       }
7456 +}
7457 +
7458 +void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
7459 +{
7460 +       au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
7461 +       if (d->d_inode) {
7462 +               if (au_ftest_lock(flags, IW))
7463 +                       do_ii_write_lock(d->d_inode, lsc);
7464 +               else if (au_ftest_lock(flags, IR))
7465 +                       do_ii_read_lock(d->d_inode, lsc);
7466 +       }
7467 +}
7468 +
7469 +void di_read_unlock(struct dentry *d, int flags)
7470 +{
7471 +       if (d->d_inode) {
7472 +               if (au_ftest_lock(flags, IW)) {
7473 +                       au_dbg_verify_dinode(d);
7474 +                       ii_write_unlock(d->d_inode);
7475 +               } else if (au_ftest_lock(flags, IR)) {
7476 +                       au_dbg_verify_dinode(d);
7477 +                       ii_read_unlock(d->d_inode);
7478 +               }
7479 +       }
7480 +       au_rw_read_unlock(&au_di(d)->di_rwsem);
7481 +}
7482 +
7483 +void di_downgrade_lock(struct dentry *d, int flags)
7484 +{
7485 +       if (d->d_inode && au_ftest_lock(flags, IR))
7486 +               ii_downgrade_lock(d->d_inode);
7487 +       au_rw_dgrade_lock(&au_di(d)->di_rwsem);
7488 +}
7489 +
7490 +void di_write_lock(struct dentry *d, unsigned int lsc)
7491 +{
7492 +       au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
7493 +       if (d->d_inode)
7494 +               do_ii_write_lock(d->d_inode, lsc);
7495 +}
7496 +
7497 +void di_write_unlock(struct dentry *d)
7498 +{
7499 +       au_dbg_verify_dinode(d);
7500 +       if (d->d_inode)
7501 +               ii_write_unlock(d->d_inode);
7502 +       au_rw_write_unlock(&au_di(d)->di_rwsem);
7503 +}
7504 +
7505 +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
7506 +{
7507 +       AuDebugOn(d1 == d2
7508 +                 || d1->d_inode == d2->d_inode
7509 +                 || d1->d_sb != d2->d_sb);
7510 +
7511 +       if (isdir && au_test_subdir(d1, d2)) {
7512 +               di_write_lock_child(d1);
7513 +               di_write_lock_child2(d2);
7514 +       } else {
7515 +               /* there should be no races */
7516 +               di_write_lock_child(d2);
7517 +               di_write_lock_child2(d1);
7518 +       }
7519 +}
7520 +
7521 +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
7522 +{
7523 +       AuDebugOn(d1 == d2
7524 +                 || d1->d_inode == d2->d_inode
7525 +                 || d1->d_sb != d2->d_sb);
7526 +
7527 +       if (isdir && au_test_subdir(d1, d2)) {
7528 +               di_write_lock_parent(d1);
7529 +               di_write_lock_parent2(d2);
7530 +       } else {
7531 +               /* there should be no races */
7532 +               di_write_lock_parent(d2);
7533 +               di_write_lock_parent2(d1);
7534 +       }
7535 +}
7536 +
7537 +void di_write_unlock2(struct dentry *d1, struct dentry *d2)
7538 +{
7539 +       di_write_unlock(d1);
7540 +       if (d1->d_inode == d2->d_inode)
7541 +               au_rw_write_unlock(&au_di(d2)->di_rwsem);
7542 +       else
7543 +               di_write_unlock(d2);
7544 +}
7545 +
7546 +/* ---------------------------------------------------------------------- */
7547 +
7548 +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
7549 +{
7550 +       struct dentry *d;
7551 +
7552 +       DiMustAnyLock(dentry);
7553 +
7554 +       if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
7555 +               return NULL;
7556 +       AuDebugOn(bindex < 0);
7557 +       d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
7558 +       AuDebugOn(d && d->d_count <= 0);
7559 +       return d;
7560 +}
7561 +
7562 +/*
7563 + * extended version of au_h_dptr().
7564 + * returns a hashed and positive h_dentry in bindex, NULL, or error.
7565 + */
7566 +struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
7567 +{
7568 +       struct dentry *h_dentry;
7569 +       struct inode *inode, *h_inode;
7570 +
7571 +       inode = dentry->d_inode;
7572 +       AuDebugOn(!inode);
7573 +
7574 +       h_dentry = NULL;
7575 +       if (au_dbstart(dentry) <= bindex
7576 +           && bindex <= au_dbend(dentry))
7577 +               h_dentry = au_h_dptr(dentry, bindex);
7578 +       if (h_dentry && !au_d_hashed_positive(h_dentry)) {
7579 +               dget(h_dentry);
7580 +               goto out; /* success */
7581 +       }
7582 +
7583 +       AuDebugOn(bindex < au_ibstart(inode));
7584 +       AuDebugOn(au_ibend(inode) < bindex);
7585 +       h_inode = au_h_iptr(inode, bindex);
7586 +       h_dentry = d_find_alias(h_inode);
7587 +       if (h_dentry) {
7588 +               if (!IS_ERR(h_dentry)) {
7589 +                       if (!au_d_hashed_positive(h_dentry))
7590 +                               goto out; /* success */
7591 +                       dput(h_dentry);
7592 +               } else
7593 +                       goto out;
7594 +       }
7595 +
7596 +       if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
7597 +               h_dentry = au_plink_lkup(inode, bindex);
7598 +               AuDebugOn(!h_dentry);
7599 +               if (!IS_ERR(h_dentry)) {
7600 +                       if (!au_d_hashed_positive(h_dentry))
7601 +                               goto out; /* success */
7602 +                       dput(h_dentry);
7603 +                       h_dentry = NULL;
7604 +               }
7605 +       }
7606 +
7607 +out:
7608 +       AuDbgDentry(h_dentry);
7609 +       return h_dentry;
7610 +}
7611 +
7612 +aufs_bindex_t au_dbtail(struct dentry *dentry)
7613 +{
7614 +       aufs_bindex_t bend, bwh;
7615 +
7616 +       bend = au_dbend(dentry);
7617 +       if (0 <= bend) {
7618 +               bwh = au_dbwh(dentry);
7619 +               if (!bwh)
7620 +                       return bwh;
7621 +               if (0 < bwh && bwh < bend)
7622 +                       return bwh - 1;
7623 +       }
7624 +       return bend;
7625 +}
7626 +
7627 +aufs_bindex_t au_dbtaildir(struct dentry *dentry)
7628 +{
7629 +       aufs_bindex_t bend, bopq;
7630 +
7631 +       bend = au_dbtail(dentry);
7632 +       if (0 <= bend) {
7633 +               bopq = au_dbdiropq(dentry);
7634 +               if (0 <= bopq && bopq < bend)
7635 +                       bend = bopq;
7636 +       }
7637 +       return bend;
7638 +}
7639 +
7640 +/* ---------------------------------------------------------------------- */
7641 +
7642 +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
7643 +                  struct dentry *h_dentry)
7644 +{
7645 +       struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
7646 +       struct au_branch *br;
7647 +
7648 +       DiMustWriteLock(dentry);
7649 +
7650 +       au_hdput(hd);
7651 +       hd->hd_dentry = h_dentry;
7652 +       if (h_dentry) {
7653 +               br = au_sbr(dentry->d_sb, bindex);
7654 +               hd->hd_id = br->br_id;
7655 +       }
7656 +}
7657 +
7658 +int au_dbrange_test(struct dentry *dentry)
7659 +{
7660 +       int err;
7661 +       aufs_bindex_t bstart, bend;
7662 +
7663 +       err = 0;
7664 +       bstart = au_dbstart(dentry);
7665 +       bend = au_dbend(dentry);
7666 +       if (bstart >= 0)
7667 +               AuDebugOn(bend < 0 && bstart > bend);
7668 +       else {
7669 +               err = -EIO;
7670 +               AuDebugOn(bend >= 0);
7671 +       }
7672 +
7673 +       return err;
7674 +}
7675 +
7676 +int au_digen_test(struct dentry *dentry, unsigned int sigen)
7677 +{
7678 +       int err;
7679 +
7680 +       err = 0;
7681 +       if (unlikely(au_digen(dentry) != sigen
7682 +                    || au_iigen_test(dentry->d_inode, sigen)))
7683 +               err = -EIO;
7684 +
7685 +       return err;
7686 +}
7687 +
7688 +void au_update_digen(struct dentry *dentry)
7689 +{
7690 +       atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
7691 +       /* smp_mb(); */ /* atomic_set */
7692 +}
7693 +
7694 +void au_update_dbrange(struct dentry *dentry, int do_put_zero)
7695 +{
7696 +       struct au_dinfo *dinfo;
7697 +       struct dentry *h_d;
7698 +       struct au_hdentry *hdp;
7699 +
7700 +       DiMustWriteLock(dentry);
7701 +
7702 +       dinfo = au_di(dentry);
7703 +       if (!dinfo || dinfo->di_bstart < 0)
7704 +               return;
7705 +
7706 +       hdp = dinfo->di_hdentry;
7707 +       if (do_put_zero) {
7708 +               aufs_bindex_t bindex, bend;
7709 +
7710 +               bend = dinfo->di_bend;
7711 +               for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
7712 +                       h_d = hdp[0 + bindex].hd_dentry;
7713 +                       if (h_d && !h_d->d_inode)
7714 +                               au_set_h_dptr(dentry, bindex, NULL);
7715 +               }
7716 +       }
7717 +
7718 +       dinfo->di_bstart = -1;
7719 +       while (++dinfo->di_bstart <= dinfo->di_bend)
7720 +               if (hdp[0 + dinfo->di_bstart].hd_dentry)
7721 +                       break;
7722 +       if (dinfo->di_bstart > dinfo->di_bend) {
7723 +               dinfo->di_bstart = -1;
7724 +               dinfo->di_bend = -1;
7725 +               return;
7726 +       }
7727 +
7728 +       dinfo->di_bend++;
7729 +       while (0 <= --dinfo->di_bend)
7730 +               if (hdp[0 + dinfo->di_bend].hd_dentry)
7731 +                       break;
7732 +       AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
7733 +}
7734 +
7735 +void au_update_dbstart(struct dentry *dentry)
7736 +{
7737 +       aufs_bindex_t bindex, bend;
7738 +       struct dentry *h_dentry;
7739 +
7740 +       bend = au_dbend(dentry);
7741 +       for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
7742 +               h_dentry = au_h_dptr(dentry, bindex);
7743 +               if (!h_dentry)
7744 +                       continue;
7745 +               if (h_dentry->d_inode) {
7746 +                       au_set_dbstart(dentry, bindex);
7747 +                       return;
7748 +               }
7749 +               au_set_h_dptr(dentry, bindex, NULL);
7750 +       }
7751 +}
7752 +
7753 +void au_update_dbend(struct dentry *dentry)
7754 +{
7755 +       aufs_bindex_t bindex, bstart;
7756 +       struct dentry *h_dentry;
7757 +
7758 +       bstart = au_dbstart(dentry);
7759 +       for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
7760 +               h_dentry = au_h_dptr(dentry, bindex);
7761 +               if (!h_dentry)
7762 +                       continue;
7763 +               if (h_dentry->d_inode) {
7764 +                       au_set_dbend(dentry, bindex);
7765 +                       return;
7766 +               }
7767 +               au_set_h_dptr(dentry, bindex, NULL);
7768 +       }
7769 +}
7770 +
7771 +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
7772 +{
7773 +       aufs_bindex_t bindex, bend;
7774 +
7775 +       bend = au_dbend(dentry);
7776 +       for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
7777 +               if (au_h_dptr(dentry, bindex) == h_dentry)
7778 +                       return bindex;
7779 +       return -1;
7780 +}
7781 diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
7782 --- /usr/share/empty/fs/aufs/dir.c      1970-01-01 01:00:00.000000000 +0100
7783 +++ linux/fs/aufs/dir.c 2013-01-11 19:46:12.635947932 +0100
7784 @@ -0,0 +1,633 @@
7785 +/*
7786 + * Copyright (C) 2005-2013 Junjiro R. Okajima
7787 + *
7788 + * This program, aufs is free software; you can redistribute it and/or modify
7789 + * it under the terms of the GNU General Public License as published by
7790 + * the Free Software Foundation; either version 2 of the License, or
7791 + * (at your option) any later version.
7792 + *
7793 + * This program is distributed in the hope that it will be useful,
7794 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7795 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7796 + * GNU General Public License for more details.
7797 + *
7798 + * You should have received a copy of the GNU General Public License
7799 + * along with this program; if not, write to the Free Software
7800 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
7801 + */
7802 +
7803 +/*
7804 + * directory operations
7805 + */
7806 +
7807 +#include <linux/fs_stack.h>
7808 +#include "aufs.h"
7809 +
7810 +void au_add_nlink(struct inode *dir, struct inode *h_dir)
7811 +{
7812 +       unsigned int nlink;
7813 +
7814 +       AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
7815 +
7816 +       nlink = dir->i_nlink;
7817 +       nlink += h_dir->i_nlink - 2;
7818 +       if (h_dir->i_nlink < 2)
7819 +               nlink += 2;
7820 +       /* 0 can happen in revaliding */
7821 +       set_nlink(dir, nlink);
7822 +}
7823 +
7824 +void au_sub_nlink(struct inode *dir, struct inode *h_dir)
7825 +{
7826 +       unsigned int nlink;
7827 +
7828 +       AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
7829 +
7830 +       nlink = dir->i_nlink;
7831 +       nlink -= h_dir->i_nlink - 2;
7832 +       if (h_dir->i_nlink < 2)
7833 +               nlink -= 2;
7834 +       /* nlink == 0 means the branch-fs is broken */
7835 +       set_nlink(dir, nlink);
7836 +}
7837 +
7838 +loff_t au_dir_size(struct file *file, struct dentry *dentry)
7839 +{
7840 +       loff_t sz;
7841 +       aufs_bindex_t bindex, bend;
7842 +       struct file *h_file;
7843 +       struct dentry *h_dentry;
7844 +
7845 +       sz = 0;
7846 +       if (file) {
7847 +               AuDebugOn(!file->f_dentry);
7848 +               AuDebugOn(!file->f_dentry->d_inode);
7849 +               AuDebugOn(!S_ISDIR(file->f_dentry->d_inode->i_mode));
7850 +
7851 +               bend = au_fbend_dir(file);
7852 +               for (bindex = au_fbstart(file);
7853 +                    bindex <= bend && sz < KMALLOC_MAX_SIZE;
7854 +                    bindex++) {
7855 +                       h_file = au_hf_dir(file, bindex);
7856 +                       if (h_file
7857 +                           && h_file->f_dentry
7858 +                           && h_file->f_dentry->d_inode)
7859 +                               sz += i_size_read(h_file->f_dentry->d_inode);
7860 +               }
7861 +       } else {
7862 +               AuDebugOn(!dentry);
7863 +               AuDebugOn(!dentry->d_inode);
7864 +               AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
7865 +
7866 +               bend = au_dbtaildir(dentry);
7867 +               for (bindex = au_dbstart(dentry);
7868 +                    bindex <= bend && sz < KMALLOC_MAX_SIZE;
7869 +                    bindex++) {
7870 +                       h_dentry = au_h_dptr(dentry, bindex);
7871 +                       if (h_dentry && h_dentry->d_inode)
7872 +                               sz += i_size_read(h_dentry->d_inode);
7873 +               }
7874 +       }
7875 +       if (sz < KMALLOC_MAX_SIZE)
7876 +               sz = roundup_pow_of_two(sz);
7877 +       if (sz > KMALLOC_MAX_SIZE)
7878 +               sz = KMALLOC_MAX_SIZE;
7879 +       else if (sz < NAME_MAX) {
7880 +               BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
7881 +               sz = AUFS_RDBLK_DEF;
7882 +       }
7883 +       return sz;
7884 +}
7885 +
7886 +/* ---------------------------------------------------------------------- */
7887 +
7888 +static int reopen_dir(struct file *file)
7889 +{
7890 +       int err;
7891 +       unsigned int flags;
7892 +       aufs_bindex_t bindex, btail, bstart;
7893 +       struct dentry *dentry, *h_dentry;
7894 +       struct file *h_file;
7895 +
7896 +       /* open all lower dirs */
7897 +       dentry = file->f_dentry;
7898 +       bstart = au_dbstart(dentry);
7899 +       for (bindex = au_fbstart(file); bindex < bstart; bindex++)
7900 +               au_set_h_fptr(file, bindex, NULL);
7901 +       au_set_fbstart(file, bstart);
7902 +
7903 +       btail = au_dbtaildir(dentry);
7904 +       for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
7905 +               au_set_h_fptr(file, bindex, NULL);
7906 +       au_set_fbend_dir(file, btail);
7907 +
7908 +       flags = vfsub_file_flags(file);
7909 +       for (bindex = bstart; bindex <= btail; bindex++) {
7910 +               h_dentry = au_h_dptr(dentry, bindex);
7911 +               if (!h_dentry)
7912 +                       continue;
7913 +               h_file = au_hf_dir(file, bindex);
7914 +               if (h_file)
7915 +                       continue;
7916 +
7917 +               h_file = au_h_open(dentry, bindex, flags, file);
7918 +               err = PTR_ERR(h_file);
7919 +               if (IS_ERR(h_file))
7920 +                       goto out; /* close all? */
7921 +               au_set_h_fptr(file, bindex, h_file);
7922 +       }
7923 +       au_update_figen(file);
7924 +       /* todo: necessary? */
7925 +       /* file->f_ra = h_file->f_ra; */
7926 +       err = 0;
7927 +
7928 +out:
7929 +       return err;
7930 +}
7931 +
7932 +static int do_open_dir(struct file *file, int flags)
7933 +{
7934 +       int err;
7935 +       aufs_bindex_t bindex, btail;
7936 +       struct dentry *dentry, *h_dentry;
7937 +       struct file *h_file;
7938 +
7939 +       FiMustWriteLock(file);
7940 +
7941 +       dentry = file->f_dentry;
7942 +       err = au_alive_dir(dentry);
7943 +       if (unlikely(err))
7944 +               goto out;
7945 +
7946 +       file->f_version = dentry->d_inode->i_version;
7947 +       bindex = au_dbstart(dentry);
7948 +       au_set_fbstart(file, bindex);
7949 +       btail = au_dbtaildir(dentry);
7950 +       au_set_fbend_dir(file, btail);
7951 +       for (; !err && bindex <= btail; bindex++) {
7952 +               h_dentry = au_h_dptr(dentry, bindex);
7953 +               if (!h_dentry)
7954 +                       continue;
7955 +
7956 +               h_file = au_h_open(dentry, bindex, flags, file);
7957 +               if (IS_ERR(h_file)) {
7958 +                       err = PTR_ERR(h_file);
7959 +                       break;
7960 +               }
7961 +               au_set_h_fptr(file, bindex, h_file);
7962 +       }
7963 +       au_update_figen(file);
7964 +       /* todo: necessary? */
7965 +       /* file->f_ra = h_file->f_ra; */
7966 +       if (!err)
7967 +               return 0; /* success */
7968 +
7969 +       /* close all */
7970 +       for (bindex = au_fbstart(file); bindex <= btail; bindex++)
7971 +               au_set_h_fptr(file, bindex, NULL);
7972 +       au_set_fbstart(file, -1);
7973 +       au_set_fbend_dir(file, -1);
7974 +
7975 +out:
7976 +       return err;
7977 +}
7978 +
7979 +static int aufs_open_dir(struct inode *inode __maybe_unused,
7980 +                        struct file *file)
7981 +{
7982 +       int err;
7983 +       struct super_block *sb;
7984 +       struct au_fidir *fidir;
7985 +
7986 +       err = -ENOMEM;
7987 +       sb = file->f_dentry->d_sb;
7988 +       si_read_lock(sb, AuLock_FLUSH);
7989 +       fidir = au_fidir_alloc(sb);
7990 +       if (fidir) {
7991 +               err = au_do_open(file, do_open_dir, fidir);
7992 +               if (unlikely(err))
7993 +                       kfree(fidir);
7994 +       }
7995 +       si_read_unlock(sb);
7996 +       return err;
7997 +}
7998 +
7999 +static int aufs_release_dir(struct inode *inode __maybe_unused,
8000 +                           struct file *file)
8001 +{
8002 +       struct au_vdir *vdir_cache;
8003 +       struct au_finfo *finfo;
8004 +       struct au_fidir *fidir;
8005 +       aufs_bindex_t bindex, bend;
8006 +
8007 +       finfo = au_fi(file);
8008 +       fidir = finfo->fi_hdir;
8009 +       if (fidir) {
8010 +               vdir_cache = fidir->fd_vdir_cache; /* lock-free */
8011 +               if (vdir_cache)
8012 +                       au_vdir_free(vdir_cache);
8013 +
8014 +               bindex = finfo->fi_btop;
8015 +               if (bindex >= 0) {
8016 +                       /*
8017 +                        * calls fput() instead of filp_close(),
8018 +                        * since no dnotify or lock for the lower file.
8019 +                        */
8020 +                       bend = fidir->fd_bbot;
8021 +                       for (; bindex <= bend; bindex++)
8022 +                               au_set_h_fptr(file, bindex, NULL);
8023 +               }
8024 +               kfree(fidir);
8025 +               finfo->fi_hdir = NULL;
8026 +       }
8027 +       au_finfo_fin(file);
8028 +       return 0;
8029 +}
8030 +
8031 +/* ---------------------------------------------------------------------- */
8032 +
8033 +static int au_do_flush_dir(struct file *file, fl_owner_t id)
8034 +{
8035 +       int err;
8036 +       aufs_bindex_t bindex, bend;
8037 +       struct file *h_file;
8038 +
8039 +       err = 0;
8040 +       bend = au_fbend_dir(file);
8041 +       for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8042 +               h_file = au_hf_dir(file, bindex);
8043 +               if (h_file)
8044 +                       err = vfsub_flush(h_file, id);
8045 +       }
8046 +       return err;
8047 +}
8048 +
8049 +static int aufs_flush_dir(struct file *file, fl_owner_t id)
8050 +{
8051 +       return au_do_flush(file, id, au_do_flush_dir);
8052 +}
8053 +
8054 +/* ---------------------------------------------------------------------- */
8055 +
8056 +static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
8057 +{
8058 +       int err;
8059 +       aufs_bindex_t bend, bindex;
8060 +       struct inode *inode;
8061 +       struct super_block *sb;
8062 +
8063 +       err = 0;
8064 +       sb = dentry->d_sb;
8065 +       inode = dentry->d_inode;
8066 +       IMustLock(inode);
8067 +       bend = au_dbend(dentry);
8068 +       for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
8069 +               struct path h_path;
8070 +
8071 +               if (au_test_ro(sb, bindex, inode))
8072 +                       continue;
8073 +               h_path.dentry = au_h_dptr(dentry, bindex);
8074 +               if (!h_path.dentry)
8075 +                       continue;
8076 +
8077 +               h_path.mnt = au_sbr_mnt(sb, bindex);
8078 +               err = vfsub_fsync(NULL, &h_path, datasync);
8079 +       }
8080 +
8081 +       return err;
8082 +}
8083 +
8084 +static int au_do_fsync_dir(struct file *file, int datasync)
8085 +{
8086 +       int err;
8087 +       aufs_bindex_t bend, bindex;
8088 +       struct file *h_file;
8089 +       struct super_block *sb;
8090 +       struct inode *inode;
8091 +
8092 +       err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8093 +       if (unlikely(err))
8094 +               goto out;
8095 +
8096 +       sb = file->f_dentry->d_sb;
8097 +       inode = file->f_dentry->d_inode;
8098 +       bend = au_fbend_dir(file);
8099 +       for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8100 +               h_file = au_hf_dir(file, bindex);
8101 +               if (!h_file || au_test_ro(sb, bindex, inode))
8102 +                       continue;
8103 +
8104 +               err = vfsub_fsync(h_file, &h_file->f_path, datasync);
8105 +       }
8106 +
8107 +out:
8108 +       return err;
8109 +}
8110 +
8111 +/*
8112 + * @file may be NULL
8113 + */
8114 +static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
8115 +                         int datasync)
8116 +{
8117 +       int err;
8118 +       struct dentry *dentry;
8119 +       struct super_block *sb;
8120 +       struct mutex *mtx;
8121 +
8122 +       err = 0;
8123 +       dentry = file->f_dentry;
8124 +       mtx = &dentry->d_inode->i_mutex;
8125 +       mutex_lock(mtx);
8126 +       sb = dentry->d_sb;
8127 +       si_noflush_read_lock(sb);
8128 +       if (file)
8129 +               err = au_do_fsync_dir(file, datasync);
8130 +       else {
8131 +               di_write_lock_child(dentry);
8132 +               err = au_do_fsync_dir_no_file(dentry, datasync);
8133 +       }
8134 +       au_cpup_attr_timesizes(dentry->d_inode);
8135 +       di_write_unlock(dentry);
8136 +       if (file)
8137 +               fi_write_unlock(file);
8138 +
8139 +       si_read_unlock(sb);
8140 +       mutex_unlock(mtx);
8141 +       return err;
8142 +}
8143 +
8144 +/* ---------------------------------------------------------------------- */
8145 +
8146 +static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir)
8147 +{
8148 +       int err;
8149 +       struct dentry *dentry;
8150 +       struct inode *inode, *h_inode;
8151 +       struct super_block *sb;
8152 +
8153 +       dentry = file->f_dentry;
8154 +       inode = dentry->d_inode;
8155 +       IMustLock(inode);
8156 +
8157 +       sb = dentry->d_sb;
8158 +       si_read_lock(sb, AuLock_FLUSH);
8159 +       err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8160 +       if (unlikely(err))
8161 +               goto out;
8162 +       err = au_alive_dir(dentry);
8163 +       if (!err)
8164 +               err = au_vdir_init(file);
8165 +       di_downgrade_lock(dentry, AuLock_IR);
8166 +       if (unlikely(err))
8167 +               goto out_unlock;
8168 +
8169 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
8170 +       if (!au_test_nfsd()) {
8171 +               err = au_vdir_fill_de(file, dirent, filldir);
8172 +               fsstack_copy_attr_atime(inode, h_inode);
8173 +       } else {
8174 +               /*
8175 +                * nfsd filldir may call lookup_one_len(), vfs_getattr(),
8176 +                * encode_fh() and others.
8177 +                */
8178 +               atomic_inc(&h_inode->i_count);
8179 +               di_read_unlock(dentry, AuLock_IR);
8180 +               si_read_unlock(sb);
8181 +               err = au_vdir_fill_de(file, dirent, filldir);
8182 +               fsstack_copy_attr_atime(inode, h_inode);
8183 +               fi_write_unlock(file);
8184 +               iput(h_inode);
8185 +
8186 +               AuTraceErr(err);
8187 +               return err;
8188 +       }
8189 +
8190 +out_unlock:
8191 +       di_read_unlock(dentry, AuLock_IR);
8192 +       fi_write_unlock(file);
8193 +out:
8194 +       si_read_unlock(sb);
8195 +       return err;
8196 +}
8197 +
8198 +/* ---------------------------------------------------------------------- */
8199 +
8200 +#define AuTestEmpty_WHONLY     1
8201 +#define AuTestEmpty_CALLED     (1 << 1)
8202 +#define AuTestEmpty_SHWH       (1 << 2)
8203 +#define au_ftest_testempty(flags, name)        ((flags) & AuTestEmpty_##name)
8204 +#define au_fset_testempty(flags, name) \
8205 +       do { (flags) |= AuTestEmpty_##name; } while (0)
8206 +#define au_fclr_testempty(flags, name) \
8207 +       do { (flags) &= ~AuTestEmpty_##name; } while (0)
8208 +
8209 +#ifndef CONFIG_AUFS_SHWH
8210 +#undef AuTestEmpty_SHWH
8211 +#define AuTestEmpty_SHWH       0
8212 +#endif
8213 +
8214 +struct test_empty_arg {
8215 +       struct au_nhash *whlist;
8216 +       unsigned int flags;
8217 +       int err;
8218 +       aufs_bindex_t bindex;
8219 +};
8220 +
8221 +static int test_empty_cb(void *__arg, const char *__name, int namelen,
8222 +                        loff_t offset __maybe_unused, u64 ino,
8223 +                        unsigned int d_type)
8224 +{
8225 +       struct test_empty_arg *arg = __arg;
8226 +       char *name = (void *)__name;
8227 +
8228 +       arg->err = 0;
8229 +       au_fset_testempty(arg->flags, CALLED);
8230 +       /* smp_mb(); */
8231 +       if (name[0] == '.'
8232 +           && (namelen == 1 || (name[1] == '.' && namelen == 2)))
8233 +               goto out; /* success */
8234 +
8235 +       if (namelen <= AUFS_WH_PFX_LEN
8236 +           || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
8237 +               if (au_ftest_testempty(arg->flags, WHONLY)
8238 +                   && !au_nhash_test_known_wh(arg->whlist, name, namelen))
8239 +                       arg->err = -ENOTEMPTY;
8240 +               goto out;
8241 +       }
8242 +
8243 +       name += AUFS_WH_PFX_LEN;
8244 +       namelen -= AUFS_WH_PFX_LEN;
8245 +       if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
8246 +               arg->err = au_nhash_append_wh
8247 +                       (arg->whlist, name, namelen, ino, d_type, arg->bindex,
8248 +                        au_ftest_testempty(arg->flags, SHWH));
8249 +
8250 +out:
8251 +       /* smp_mb(); */
8252 +       AuTraceErr(arg->err);
8253 +       return arg->err;
8254 +}
8255 +
8256 +static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8257 +{
8258 +       int err;
8259 +       struct file *h_file;
8260 +
8261 +       h_file = au_h_open(dentry, arg->bindex,
8262 +                          O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
8263 +                          /*file*/NULL);
8264 +       err = PTR_ERR(h_file);
8265 +       if (IS_ERR(h_file))
8266 +               goto out;
8267 +
8268 +       err = 0;
8269 +       if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
8270 +           && !h_file->f_dentry->d_inode->i_nlink)
8271 +               goto out_put;
8272 +
8273 +       do {
8274 +               arg->err = 0;
8275 +               au_fclr_testempty(arg->flags, CALLED);
8276 +               /* smp_mb(); */
8277 +               err = vfsub_readdir(h_file, test_empty_cb, arg);
8278 +               if (err >= 0)
8279 +                       err = arg->err;
8280 +       } while (!err && au_ftest_testempty(arg->flags, CALLED));
8281 +
8282 +out_put:
8283 +       fput(h_file);
8284 +       au_sbr_put(dentry->d_sb, arg->bindex);
8285 +out:
8286 +       return err;
8287 +}
8288 +
8289 +struct do_test_empty_args {
8290 +       int *errp;
8291 +       struct dentry *dentry;
8292 +       struct test_empty_arg *arg;
8293 +};
8294 +
8295 +static void call_do_test_empty(void *args)
8296 +{
8297 +       struct do_test_empty_args *a = args;
8298 +       *a->errp = do_test_empty(a->dentry, a->arg);
8299 +}
8300 +
8301 +static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8302 +{
8303 +       int err, wkq_err;
8304 +       struct dentry *h_dentry;
8305 +       struct inode *h_inode;
8306 +
8307 +       h_dentry = au_h_dptr(dentry, arg->bindex);
8308 +       h_inode = h_dentry->d_inode;
8309 +       /* todo: i_mode changes anytime? */
8310 +       mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
8311 +       err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
8312 +       mutex_unlock(&h_inode->i_mutex);
8313 +       if (!err)
8314 +               err = do_test_empty(dentry, arg);
8315 +       else {
8316 +               struct do_test_empty_args args = {
8317 +                       .errp   = &err,
8318 +                       .dentry = dentry,
8319 +                       .arg    = arg
8320 +               };
8321 +               unsigned int flags = arg->flags;
8322 +
8323 +               wkq_err = au_wkq_wait(call_do_test_empty, &args);
8324 +               if (unlikely(wkq_err))
8325 +                       err = wkq_err;
8326 +               arg->flags = flags;
8327 +       }
8328 +
8329 +       return err;
8330 +}
8331 +
8332 +int au_test_empty_lower(struct dentry *dentry)
8333 +{
8334 +       int err;
8335 +       unsigned int rdhash;
8336 +       aufs_bindex_t bindex, bstart, btail;
8337 +       struct au_nhash whlist;
8338 +       struct test_empty_arg arg;
8339 +
8340 +       SiMustAnyLock(dentry->d_sb);
8341 +
8342 +       rdhash = au_sbi(dentry->d_sb)->si_rdhash;
8343 +       if (!rdhash)
8344 +               rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
8345 +       err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
8346 +       if (unlikely(err))
8347 +               goto out;
8348 +
8349 +       arg.flags = 0;
8350 +       arg.whlist = &whlist;
8351 +       bstart = au_dbstart(dentry);
8352 +       if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8353 +               au_fset_testempty(arg.flags, SHWH);
8354 +       arg.bindex = bstart;
8355 +       err = do_test_empty(dentry, &arg);
8356 +       if (unlikely(err))
8357 +               goto out_whlist;
8358 +
8359 +       au_fset_testempty(arg.flags, WHONLY);
8360 +       btail = au_dbtaildir(dentry);
8361 +       for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
8362 +               struct dentry *h_dentry;
8363 +
8364 +               h_dentry = au_h_dptr(dentry, bindex);
8365 +               if (h_dentry && h_dentry->d_inode) {
8366 +                       arg.bindex = bindex;
8367 +                       err = do_test_empty(dentry, &arg);
8368 +               }
8369 +       }
8370 +
8371 +out_whlist:
8372 +       au_nhash_wh_free(&whlist);
8373 +out:
8374 +       return err;
8375 +}
8376 +
8377 +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
8378 +{
8379 +       int err;
8380 +       struct test_empty_arg arg;
8381 +       aufs_bindex_t bindex, btail;
8382 +
8383 +       err = 0;
8384 +       arg.whlist = whlist;
8385 +       arg.flags = AuTestEmpty_WHONLY;
8386 +       if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8387 +               au_fset_testempty(arg.flags, SHWH);
8388 +       btail = au_dbtaildir(dentry);
8389 +       for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
8390 +               struct dentry *h_dentry;
8391 +
8392 +               h_dentry = au_h_dptr(dentry, bindex);
8393 +               if (h_dentry && h_dentry->d_inode) {
8394 +                       arg.bindex = bindex;
8395 +                       err = sio_test_empty(dentry, &arg);
8396 +               }
8397 +       }
8398 +
8399 +       return err;
8400 +}
8401 +
8402 +/* ---------------------------------------------------------------------- */
8403 +
8404 +const struct file_operations aufs_dir_fop = {
8405 +       .owner          = THIS_MODULE,
8406 +       .llseek         = default_llseek,
8407 +       .read           = generic_read_dir,
8408 +       .readdir        = aufs_readdir,
8409 +       .unlocked_ioctl = aufs_ioctl_dir,
8410 +#ifdef CONFIG_COMPAT
8411 +       .compat_ioctl   = aufs_compat_ioctl_dir,
8412 +#endif
8413 +       .open           = aufs_open_dir,
8414 +       .release        = aufs_release_dir,
8415 +       .flush          = aufs_flush_dir,
8416 +       .fsync          = aufs_fsync_dir
8417 +};
8418 diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
8419 --- /usr/share/empty/fs/aufs/dir.h      1970-01-01 01:00:00.000000000 +0100
8420 +++ linux/fs/aufs/dir.h 2013-01-11 19:46:12.635947932 +0100
8421 @@ -0,0 +1,137 @@
8422 +/*
8423 + * Copyright (C) 2005-2013 Junjiro R. Okajima
8424 + *
8425 + * This program, aufs is free software; you can redistribute it and/or modify
8426 + * it under the terms of the GNU General Public License as published by
8427 + * the Free Software Foundation; either version 2 of the License, or
8428 + * (at your option) any later version.
8429 + *
8430 + * This program is distributed in the hope that it will be useful,
8431 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8432 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8433 + * GNU General Public License for more details.
8434 + *
8435 + * You should have received a copy of the GNU General Public License
8436 + * along with this program; if not, write to the Free Software
8437 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
8438 + */
8439 +
8440 +/*
8441 + * directory operations
8442 + */
8443 +
8444 +#ifndef __AUFS_DIR_H__
8445 +#define __AUFS_DIR_H__
8446 +
8447 +#ifdef __KERNEL__
8448 +
8449 +#include <linux/fs.h>
8450 +
8451 +/* ---------------------------------------------------------------------- */
8452 +
8453 +/* need to be faster and smaller */
8454 +
8455 +struct au_nhash {
8456 +       unsigned int            nh_num;
8457 +       struct hlist_head       *nh_head;
8458 +};
8459 +
8460 +struct au_vdir_destr {
8461 +       unsigned char   len;
8462 +       unsigned char   name[0];
8463 +} __packed;
8464 +
8465 +struct au_vdir_dehstr {
8466 +       struct hlist_node       hash;
8467 +       struct au_vdir_destr    *str;
8468 +} ____cacheline_aligned_in_smp;
8469 +
8470 +struct au_vdir_de {
8471 +       ino_t                   de_ino;
8472 +       unsigned char           de_type;
8473 +       /* caution: packed */
8474 +       struct au_vdir_destr    de_str;
8475 +} __packed;
8476 +
8477 +struct au_vdir_wh {
8478 +       struct hlist_node       wh_hash;
8479 +#ifdef CONFIG_AUFS_SHWH
8480 +       ino_t                   wh_ino;
8481 +       aufs_bindex_t           wh_bindex;
8482 +       unsigned char           wh_type;
8483 +#else
8484 +       aufs_bindex_t           wh_bindex;
8485 +#endif
8486 +       /* caution: packed */
8487 +       struct au_vdir_destr    wh_str;
8488 +} __packed;
8489 +
8490 +union au_vdir_deblk_p {
8491 +       unsigned char           *deblk;
8492 +       struct au_vdir_de       *de;
8493 +};
8494 +
8495 +struct au_vdir {
8496 +       unsigned char   **vd_deblk;
8497 +       unsigned long   vd_nblk;
8498 +       struct {
8499 +               unsigned long           ul;
8500 +               union au_vdir_deblk_p   p;
8501 +       } vd_last;
8502 +
8503 +       unsigned long   vd_version;
8504 +       unsigned int    vd_deblk_sz;
8505 +       unsigned long   vd_jiffy;
8506 +} ____cacheline_aligned_in_smp;
8507 +
8508 +/* ---------------------------------------------------------------------- */
8509 +
8510 +/* dir.c */
8511 +extern const struct file_operations aufs_dir_fop;
8512 +void au_add_nlink(struct inode *dir, struct inode *h_dir);
8513 +void au_sub_nlink(struct inode *dir, struct inode *h_dir);
8514 +loff_t au_dir_size(struct file *file, struct dentry *dentry);
8515 +int au_test_empty_lower(struct dentry *dentry);
8516 +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
8517 +
8518 +/* vdir.c */
8519 +unsigned int au_rdhash_est(loff_t sz);
8520 +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
8521 +void au_nhash_wh_free(struct au_nhash *whlist);
8522 +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
8523 +                           int limit);
8524 +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
8525 +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
8526 +                      unsigned int d_type, aufs_bindex_t bindex,
8527 +                      unsigned char shwh);
8528 +void au_vdir_free(struct au_vdir *vdir);
8529 +int au_vdir_init(struct file *file);
8530 +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir);
8531 +
8532 +/* ioctl.c */
8533 +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
8534 +
8535 +#ifdef CONFIG_AUFS_RDU
8536 +/* rdu.c */
8537 +long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
8538 +#ifdef CONFIG_COMPAT
8539 +long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
8540 +                        unsigned long arg);
8541 +#endif
8542 +#else
8543 +static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
8544 +                               unsigned long arg)
8545 +{
8546 +       return -EINVAL;
8547 +}
8548 +#ifdef CONFIG_COMPAT
8549 +static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
8550 +                                      unsigned long arg)
8551 +{
8552 +       return -EINVAL;
8553 +}
8554 +#endif
8555 +#endif
8556 +
8557 +#endif /* __KERNEL__ */
8558 +#endif /* __AUFS_DIR_H__ */
8559 diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
8560 --- /usr/share/empty/fs/aufs/dynop.c    1970-01-01 01:00:00.000000000 +0100
8561 +++ linux/fs/aufs/dynop.c       2013-01-11 19:46:12.635947932 +0100
8562 @@ -0,0 +1,379 @@
8563 +/*
8564 + * Copyright (C) 2010-2013 Junjiro R. Okajima
8565 + *
8566 + * This program, aufs is free software; you can redistribute it and/or modify
8567 + * it under the terms of the GNU General Public License as published by
8568 + * the Free Software Foundation; either version 2 of the License, or
8569 + * (at your option) any later version.
8570 + *
8571 + * This program is distributed in the hope that it will be useful,
8572 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8573 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8574 + * GNU General Public License for more details.
8575 + *
8576 + * You should have received a copy of the GNU General Public License
8577 + * along with this program; if not, write to the Free Software
8578 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
8579 + */
8580 +
8581 +/*
8582 + * dynamically customizable operations for regular files
8583 + */
8584 +
8585 +#include "aufs.h"
8586 +
8587 +#define DyPrSym(key)   AuDbgSym(key->dk_op.dy_hop)
8588 +
8589 +/*
8590 + * How large will these lists be?
8591 + * Usually just a few elements, 20-30 at most for each, I guess.
8592 + */
8593 +static struct au_splhead dynop[AuDyLast];
8594 +
8595 +static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
8596 +{
8597 +       struct au_dykey *key, *tmp;
8598 +       struct list_head *head;
8599 +
8600 +       key = NULL;
8601 +       head = &spl->head;
8602 +       rcu_read_lock();
8603 +       list_for_each_entry_rcu(tmp, head, dk_list)
8604 +               if (tmp->dk_op.dy_hop == h_op) {
8605 +                       key = tmp;
8606 +                       kref_get(&key->dk_kref);
8607 +                       break;
8608 +               }
8609 +       rcu_read_unlock();
8610 +
8611 +       return key;
8612 +}
8613 +
8614 +static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
8615 +{
8616 +       struct au_dykey **k, *found;
8617 +       const void *h_op = key->dk_op.dy_hop;
8618 +       int i;
8619 +
8620 +       found = NULL;
8621 +       k = br->br_dykey;
8622 +       for (i = 0; i < AuBrDynOp; i++)
8623 +               if (k[i]) {
8624 +                       if (k[i]->dk_op.dy_hop == h_op) {
8625 +                               found = k[i];
8626 +                               break;
8627 +                       }
8628 +               } else
8629 +                       break;
8630 +       if (!found) {
8631 +               spin_lock(&br->br_dykey_lock);
8632 +               for (; i < AuBrDynOp; i++)
8633 +                       if (k[i]) {
8634 +                               if (k[i]->dk_op.dy_hop == h_op) {
8635 +                                       found = k[i];
8636 +                                       break;
8637 +                               }
8638 +                       } else {
8639 +                               k[i] = key;
8640 +                               break;
8641 +                       }
8642 +               spin_unlock(&br->br_dykey_lock);
8643 +               BUG_ON(i == AuBrDynOp); /* expand the array */
8644 +       }
8645 +
8646 +       return found;
8647 +}
8648 +
8649 +/* kref_get() if @key is already added */
8650 +static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
8651 +{
8652 +       struct au_dykey *tmp, *found;
8653 +       struct list_head *head;
8654 +       const void *h_op = key->dk_op.dy_hop;
8655 +
8656 +       found = NULL;
8657 +       head = &spl->head;
8658 +       spin_lock(&spl->spin);
8659 +       list_for_each_entry(tmp, head, dk_list)
8660 +               if (tmp->dk_op.dy_hop == h_op) {
8661 +                       kref_get(&tmp->dk_kref);
8662 +                       found = tmp;
8663 +                       break;
8664 +               }
8665 +       if (!found)
8666 +               list_add_rcu(&key->dk_list, head);
8667 +       spin_unlock(&spl->spin);
8668 +
8669 +       if (!found)
8670 +               DyPrSym(key);
8671 +       return found;
8672 +}
8673 +
8674 +static void dy_free_rcu(struct rcu_head *rcu)
8675 +{
8676 +       struct au_dykey *key;
8677 +
8678 +       key = container_of(rcu, struct au_dykey, dk_rcu);
8679 +       DyPrSym(key);
8680 +       kfree(key);
8681 +}
8682 +
8683 +static void dy_free(struct kref *kref)
8684 +{
8685 +       struct au_dykey *key;
8686 +       struct au_splhead *spl;
8687 +
8688 +       key = container_of(kref, struct au_dykey, dk_kref);
8689 +       spl = dynop + key->dk_op.dy_type;
8690 +       au_spl_del_rcu(&key->dk_list, spl);
8691 +       call_rcu(&key->dk_rcu, dy_free_rcu);
8692 +}
8693 +
8694 +void au_dy_put(struct au_dykey *key)
8695 +{
8696 +       kref_put(&key->dk_kref, dy_free);
8697 +}
8698 +
8699 +/* ---------------------------------------------------------------------- */
8700 +
8701 +#define DyDbgSize(cnt, op)     AuDebugOn(cnt != sizeof(op)/sizeof(void *))
8702 +
8703 +#ifdef CONFIG_AUFS_DEBUG
8704 +#define DyDbgDeclare(cnt)      unsigned int cnt = 0
8705 +#define DyDbgInc(cnt)          do { cnt++; } while (0)
8706 +#else
8707 +#define DyDbgDeclare(cnt)      do {} while (0)
8708 +#define DyDbgInc(cnt)          do {} while (0)
8709 +#endif
8710 +
8711 +#define DySet(func, dst, src, h_op, h_sb) do {                         \
8712 +       DyDbgInc(cnt);                                                  \
8713 +       if (h_op->func) {                                               \
8714 +               if (src.func)                                           \
8715 +                       dst.func = src.func;                            \
8716 +               else                                                    \
8717 +                       AuDbg("%s %s\n", au_sbtype(h_sb), #func);       \
8718 +       }                                                               \
8719 +} while (0)
8720 +
8721 +#define DySetForce(func, dst, src) do {                \
8722 +       AuDebugOn(!src.func);                   \
8723 +       DyDbgInc(cnt);                          \
8724 +       dst.func = src.func;                    \
8725 +} while (0)
8726 +
8727 +#define DySetAop(func) \
8728 +       DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
8729 +#define DySetAopForce(func) \
8730 +       DySetForce(func, dyaop->da_op, aufs_aop)
8731 +
8732 +static void dy_aop(struct au_dykey *key, const void *h_op,
8733 +                  struct super_block *h_sb __maybe_unused)
8734 +{
8735 +       struct au_dyaop *dyaop = (void *)key;
8736 +       const struct address_space_operations *h_aop = h_op;
8737 +       DyDbgDeclare(cnt);
8738 +
8739 +       AuDbg("%s\n", au_sbtype(h_sb));
8740 +
8741 +       DySetAop(writepage);
8742 +       DySetAopForce(readpage);        /* force */
8743 +       DySetAop(writepages);
8744 +       DySetAop(set_page_dirty);
8745 +       DySetAop(readpages);
8746 +       DySetAop(write_begin);
8747 +       DySetAop(write_end);
8748 +       DySetAop(bmap);
8749 +       DySetAop(invalidatepage);
8750 +       DySetAop(releasepage);
8751 +       DySetAop(freepage);
8752 +       /* these two will be changed according to an aufs mount option */
8753 +       DySetAop(direct_IO);
8754 +       DySetAop(get_xip_mem);
8755 +       DySetAop(migratepage);
8756 +       DySetAop(launder_page);
8757 +       DySetAop(is_partially_uptodate);
8758 +       DySetAop(error_remove_page);
8759 +       DySetAop(swap_activate);
8760 +       DySetAop(swap_deactivate);
8761 +
8762 +       DyDbgSize(cnt, *h_aop);
8763 +       dyaop->da_get_xip_mem = h_aop->get_xip_mem;
8764 +}
8765 +
8766 +/* ---------------------------------------------------------------------- */
8767 +
8768 +static void dy_bug(struct kref *kref)
8769 +{
8770 +       BUG();
8771 +}
8772 +
8773 +static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
8774 +{
8775 +       struct au_dykey *key, *old;
8776 +       struct au_splhead *spl;
8777 +       struct op {
8778 +               unsigned int sz;
8779 +               void (*set)(struct au_dykey *key, const void *h_op,
8780 +                           struct super_block *h_sb __maybe_unused);
8781 +       };
8782 +       static const struct op a[] = {
8783 +               [AuDy_AOP] = {
8784 +                       .sz     = sizeof(struct au_dyaop),
8785 +                       .set    = dy_aop
8786 +               }
8787 +       };
8788 +       const struct op *p;
8789 +
8790 +       spl = dynop + op->dy_type;
8791 +       key = dy_gfind_get(spl, op->dy_hop);
8792 +       if (key)
8793 +               goto out_add; /* success */
8794 +
8795 +       p = a + op->dy_type;
8796 +       key = kzalloc(p->sz, GFP_NOFS);
8797 +       if (unlikely(!key)) {
8798 +               key = ERR_PTR(-ENOMEM);
8799 +               goto out;
8800 +       }
8801 +
8802 +       key->dk_op.dy_hop = op->dy_hop;
8803 +       kref_init(&key->dk_kref);
8804 +       p->set(key, op->dy_hop, br->br_mnt->mnt_sb);
8805 +       old = dy_gadd(spl, key);
8806 +       if (old) {
8807 +               kfree(key);
8808 +               key = old;
8809 +       }
8810 +
8811 +out_add:
8812 +       old = dy_bradd(br, key);
8813 +       if (old)
8814 +               /* its ref-count should never be zero here */
8815 +               kref_put(&key->dk_kref, dy_bug);
8816 +out:
8817 +       return key;
8818 +}
8819 +
8820 +/* ---------------------------------------------------------------------- */
8821 +/*
8822 + * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
8823 + * This behaviour is neccessary to return an error from open(O_DIRECT) instead
8824 + * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
8825 + * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
8826 + * See the aufs manual in detail.
8827 + *
8828 + * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
8829 + * performance of fadvise() and madvise() may be affected.
8830 + */
8831 +static void dy_adx(struct au_dyaop *dyaop, int do_dx)
8832 +{
8833 +       if (!do_dx) {
8834 +               dyaop->da_op.direct_IO = NULL;
8835 +               dyaop->da_op.get_xip_mem = NULL;
8836 +       } else {
8837 +               dyaop->da_op.direct_IO = aufs_aop.direct_IO;
8838 +               dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
8839 +               if (!dyaop->da_get_xip_mem)
8840 +                       dyaop->da_op.get_xip_mem = NULL;
8841 +       }
8842 +}
8843 +
8844 +static struct au_dyaop *dy_aget(struct au_branch *br,
8845 +                               const struct address_space_operations *h_aop,
8846 +                               int do_dx)
8847 +{
8848 +       struct au_dyaop *dyaop;
8849 +       struct au_dynop op;
8850 +
8851 +       op.dy_type = AuDy_AOP;
8852 +       op.dy_haop = h_aop;
8853 +       dyaop = (void *)dy_get(&op, br);
8854 +       if (IS_ERR(dyaop))
8855 +               goto out;
8856 +       dy_adx(dyaop, do_dx);
8857 +
8858 +out:
8859 +       return dyaop;
8860 +}
8861 +
8862 +int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
8863 +               struct inode *h_inode)
8864 +{
8865 +       int err, do_dx;
8866 +       struct super_block *sb;
8867 +       struct au_branch *br;
8868 +       struct au_dyaop *dyaop;
8869 +
8870 +       AuDebugOn(!S_ISREG(h_inode->i_mode));
8871 +       IiMustWriteLock(inode);
8872 +
8873 +       sb = inode->i_sb;
8874 +       br = au_sbr(sb, bindex);
8875 +       do_dx = !!au_opt_test(au_mntflags(sb), DIO);
8876 +       dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
8877 +       err = PTR_ERR(dyaop);
8878 +       if (IS_ERR(dyaop))
8879 +               /* unnecessary to call dy_fput() */
8880 +               goto out;
8881 +
8882 +       err = 0;
8883 +       inode->i_mapping->a_ops = &dyaop->da_op;
8884 +
8885 +out:
8886 +       return err;
8887 +}
8888 +
8889 +/*
8890 + * Is it safe to replace a_ops during the inode/file is in operation?
8891 + * Yes, I hope so.
8892 + */
8893 +int au_dy_irefresh(struct inode *inode)
8894 +{
8895 +       int err;
8896 +       aufs_bindex_t bstart;
8897 +       struct inode *h_inode;
8898 +
8899 +       err = 0;
8900 +       if (S_ISREG(inode->i_mode)) {
8901 +               bstart = au_ibstart(inode);
8902 +               h_inode = au_h_iptr(inode, bstart);
8903 +               err = au_dy_iaop(inode, bstart, h_inode);
8904 +       }
8905 +       return err;
8906 +}
8907 +
8908 +void au_dy_arefresh(int do_dx)
8909 +{
8910 +       struct au_splhead *spl;
8911 +       struct list_head *head;
8912 +       struct au_dykey *key;
8913 +
8914 +       spl = dynop + AuDy_AOP;
8915 +       head = &spl->head;
8916 +       spin_lock(&spl->spin);
8917 +       list_for_each_entry(key, head, dk_list)
8918 +               dy_adx((void *)key, do_dx);
8919 +       spin_unlock(&spl->spin);
8920 +}
8921 +
8922 +/* ---------------------------------------------------------------------- */
8923 +
8924 +void __init au_dy_init(void)
8925 +{
8926 +       int i;
8927 +
8928 +       /* make sure that 'struct au_dykey *' can be any type */
8929 +       BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
8930 +
8931 +       for (i = 0; i < AuDyLast; i++)
8932 +               au_spl_init(dynop + i);
8933 +}
8934 +
8935 +void au_dy_fin(void)
8936 +{
8937 +       int i;
8938 +
8939 +       for (i = 0; i < AuDyLast; i++)
8940 +               WARN_ON(!list_empty(&dynop[i].head));
8941 +}
8942 diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
8943 --- /usr/share/empty/fs/aufs/dynop.h    1970-01-01 01:00:00.000000000 +0100
8944 +++ linux/fs/aufs/dynop.h       2013-01-11 19:46:12.635947932 +0100
8945 @@ -0,0 +1,76 @@
8946 +/*
8947 + * Copyright (C) 2010-2013 Junjiro R. Okajima
8948 + *
8949 + * This program, aufs is free software; you can redistribute it and/or modify
8950 + * it under the terms of the GNU General Public License as published by
8951 + * the Free Software Foundation; either version 2 of the License, or
8952 + * (at your option) any later version.
8953 + *
8954 + * This program is distributed in the hope that it will be useful,
8955 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8956 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8957 + * GNU General Public License for more details.
8958 + *
8959 + * You should have received a copy of the GNU General Public License
8960 + * along with this program; if not, write to the Free Software
8961 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
8962 + */
8963 +
8964 +/*
8965 + * dynamically customizable operations (for regular files only)
8966 + */
8967 +
8968 +#ifndef __AUFS_DYNOP_H__
8969 +#define __AUFS_DYNOP_H__
8970 +
8971 +#ifdef __KERNEL__
8972 +
8973 +#include "inode.h"
8974 +
8975 +enum {AuDy_AOP, AuDyLast};
8976 +
8977 +struct au_dynop {
8978 +       int                                             dy_type;
8979 +       union {
8980 +               const void                              *dy_hop;
8981 +               const struct address_space_operations   *dy_haop;
8982 +       };
8983 +};
8984 +
8985 +struct au_dykey {
8986 +       union {
8987 +               struct list_head        dk_list;
8988 +               struct rcu_head         dk_rcu;
8989 +       };
8990 +       struct au_dynop         dk_op;
8991 +
8992 +       /*
8993 +        * during I am in the branch local array, kref is gotten. when the
8994 +        * branch is removed, kref is put.
8995 +        */
8996 +       struct kref             dk_kref;
8997 +};
8998 +
8999 +/* stop unioning since their sizes are very different from each other */
9000 +struct au_dyaop {
9001 +       struct au_dykey                 da_key;
9002 +       struct address_space_operations da_op; /* not const */
9003 +       int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
9004 +                             void **, unsigned long *);
9005 +};
9006 +
9007 +/* ---------------------------------------------------------------------- */
9008 +
9009 +/* dynop.c */
9010 +struct au_branch;
9011 +void au_dy_put(struct au_dykey *key);
9012 +int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9013 +               struct inode *h_inode);
9014 +int au_dy_irefresh(struct inode *inode);
9015 +void au_dy_arefresh(int do_dio);
9016 +
9017 +void __init au_dy_init(void);
9018 +void au_dy_fin(void);
9019 +
9020 +#endif /* __KERNEL__ */
9021 +#endif /* __AUFS_DYNOP_H__ */
9022 diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
9023 --- /usr/share/empty/fs/aufs/export.c   1970-01-01 01:00:00.000000000 +0100
9024 +++ linux/fs/aufs/export.c      2013-01-11 19:46:28.699667650 +0100
9025 @@ -0,0 +1,811 @@
9026 +/*
9027 + * Copyright (C) 2005-2013 Junjiro R. Okajima
9028 + *
9029 + * This program, aufs is free software; you can redistribute it and/or modify
9030 + * it under the terms of the GNU General Public License as published by
9031 + * the Free Software Foundation; either version 2 of the License, or
9032 + * (at your option) any later version.
9033 + *
9034 + * This program is distributed in the hope that it will be useful,
9035 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9036 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9037 + * GNU General Public License for more details.
9038 + *
9039 + * You should have received a copy of the GNU General Public License
9040 + * along with this program; if not, write to the Free Software
9041 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
9042 + */
9043 +
9044 +/*
9045 + * export via nfs
9046 + */
9047 +
9048 +#include <linux/exportfs.h>
9049 +#include <linux/fs_struct.h>
9050 +#include <linux/namei.h>
9051 +#include <linux/nsproxy.h>
9052 +#include <linux/random.h>
9053 +#include <linux/writeback.h>
9054 +#include "../fs/mount.h"
9055 +#include "aufs.h"
9056 +
9057 +union conv {
9058 +#ifdef CONFIG_AUFS_INO_T_64
9059 +       __u32 a[2];
9060 +#else
9061 +       __u32 a[1];
9062 +#endif
9063 +       ino_t ino;
9064 +};
9065 +
9066 +static ino_t decode_ino(__u32 *a)
9067 +{
9068 +       union conv u;
9069 +
9070 +       BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
9071 +       u.a[0] = a[0];
9072 +#ifdef CONFIG_AUFS_INO_T_64
9073 +       u.a[1] = a[1];
9074 +#endif
9075 +       return u.ino;
9076 +}
9077 +
9078 +static void encode_ino(__u32 *a, ino_t ino)
9079 +{
9080 +       union conv u;
9081 +
9082 +       u.ino = ino;
9083 +       a[0] = u.a[0];
9084 +#ifdef CONFIG_AUFS_INO_T_64
9085 +       a[1] = u.a[1];
9086 +#endif
9087 +}
9088 +
9089 +/* NFS file handle */
9090 +enum {
9091 +       Fh_br_id,
9092 +       Fh_sigen,
9093 +#ifdef CONFIG_AUFS_INO_T_64
9094 +       /* support 64bit inode number */
9095 +       Fh_ino1,
9096 +       Fh_ino2,
9097 +       Fh_dir_ino1,
9098 +       Fh_dir_ino2,
9099 +#else
9100 +       Fh_ino1,
9101 +       Fh_dir_ino1,
9102 +#endif
9103 +       Fh_igen,
9104 +       Fh_h_type,
9105 +       Fh_tail,
9106 +
9107 +       Fh_ino = Fh_ino1,
9108 +       Fh_dir_ino = Fh_dir_ino1
9109 +};
9110 +
9111 +static int au_test_anon(struct dentry *dentry)
9112 +{
9113 +       /* note: read d_flags without d_lock */
9114 +       return !!(dentry->d_flags & DCACHE_DISCONNECTED);
9115 +}
9116 +
9117 +/* ---------------------------------------------------------------------- */
9118 +/* inode generation external table */
9119 +
9120 +void au_xigen_inc(struct inode *inode)
9121 +{
9122 +       loff_t pos;
9123 +       ssize_t sz;
9124 +       __u32 igen;
9125 +       struct super_block *sb;
9126 +       struct au_sbinfo *sbinfo;
9127 +
9128 +       sb = inode->i_sb;
9129 +       AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
9130 +
9131 +       sbinfo = au_sbi(sb);
9132 +       pos = inode->i_ino;
9133 +       pos *= sizeof(igen);
9134 +       igen = inode->i_generation + 1;
9135 +       sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
9136 +                        sizeof(igen), &pos);
9137 +       if (sz == sizeof(igen))
9138 +               return; /* success */
9139 +
9140 +       if (unlikely(sz >= 0))
9141 +               AuIOErr("xigen error (%zd)\n", sz);
9142 +}
9143 +
9144 +int au_xigen_new(struct inode *inode)
9145 +{
9146 +       int err;
9147 +       loff_t pos;
9148 +       ssize_t sz;
9149 +       struct super_block *sb;
9150 +       struct au_sbinfo *sbinfo;
9151 +       struct file *file;
9152 +
9153 +       err = 0;
9154 +       /* todo: dirty, at mount time */
9155 +       if (inode->i_ino == AUFS_ROOT_INO)
9156 +               goto out;
9157 +       sb = inode->i_sb;
9158 +       SiMustAnyLock(sb);
9159 +       if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
9160 +               goto out;
9161 +
9162 +       err = -EFBIG;
9163 +       pos = inode->i_ino;
9164 +       if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
9165 +               AuIOErr1("too large i%lld\n", pos);
9166 +               goto out;
9167 +       }
9168 +       pos *= sizeof(inode->i_generation);
9169 +
9170 +       err = 0;
9171 +       sbinfo = au_sbi(sb);
9172 +       file = sbinfo->si_xigen;
9173 +       BUG_ON(!file);
9174 +
9175 +       if (i_size_read(file->f_dentry->d_inode)
9176 +           < pos + sizeof(inode->i_generation)) {
9177 +               inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
9178 +               sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
9179 +                                sizeof(inode->i_generation), &pos);
9180 +       } else
9181 +               sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
9182 +                               sizeof(inode->i_generation), &pos);
9183 +       if (sz == sizeof(inode->i_generation))
9184 +               goto out; /* success */
9185 +
9186 +       err = sz;
9187 +       if (unlikely(sz >= 0)) {
9188 +               err = -EIO;
9189 +               AuIOErr("xigen error (%zd)\n", sz);
9190 +       }
9191 +
9192 +out:
9193 +       return err;
9194 +}
9195 +
9196 +int au_xigen_set(struct super_block *sb, struct file *base)
9197 +{
9198 +       int err;
9199 +       struct au_sbinfo *sbinfo;
9200 +       struct file *file;
9201 +
9202 +       SiMustWriteLock(sb);
9203 +
9204 +       sbinfo = au_sbi(sb);
9205 +       file = au_xino_create2(base, sbinfo->si_xigen);
9206 +       err = PTR_ERR(file);
9207 +       if (IS_ERR(file))
9208 +               goto out;
9209 +       err = 0;
9210 +       if (sbinfo->si_xigen)
9211 +               fput(sbinfo->si_xigen);
9212 +       sbinfo->si_xigen = file;
9213 +
9214 +out:
9215 +       return err;
9216 +}
9217 +
9218 +void au_xigen_clr(struct super_block *sb)
9219 +{
9220 +       struct au_sbinfo *sbinfo;
9221 +
9222 +       SiMustWriteLock(sb);
9223 +
9224 +       sbinfo = au_sbi(sb);
9225 +       if (sbinfo->si_xigen) {
9226 +               fput(sbinfo->si_xigen);
9227 +               sbinfo->si_xigen = NULL;
9228 +       }
9229 +}
9230 +
9231 +/* ---------------------------------------------------------------------- */
9232 +
9233 +static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
9234 +                                   ino_t dir_ino)
9235 +{
9236 +       struct dentry *dentry, *d;
9237 +       struct inode *inode;
9238 +       unsigned int sigen;
9239 +       struct hlist_node *p;
9240 +
9241 +       dentry = NULL;
9242 +       inode = ilookup(sb, ino);
9243 +       if (!inode)
9244 +               goto out;
9245 +
9246 +       dentry = ERR_PTR(-ESTALE);
9247 +       sigen = au_sigen(sb);
9248 +       if (unlikely(is_bad_inode(inode)
9249 +                    || IS_DEADDIR(inode)
9250 +                    || sigen != au_iigen(inode, NULL)))
9251 +               goto out_iput;
9252 +
9253 +       dentry = NULL;
9254 +       if (!dir_ino || S_ISDIR(inode->i_mode))
9255 +               dentry = d_find_alias(inode);
9256 +       else {
9257 +               spin_lock(&inode->i_lock);
9258 +               hlist_for_each_entry(d, p, &inode->i_dentry, d_alias) {
9259 +                       spin_lock(&d->d_lock);
9260 +                       if (!au_test_anon(d)
9261 +                           && d->d_parent->d_inode->i_ino == dir_ino) {
9262 +                               dentry = dget_dlock(d);
9263 +                               spin_unlock(&d->d_lock);
9264 +                               break;
9265 +                       }
9266 +                       spin_unlock(&d->d_lock);
9267 +               }
9268 +               spin_unlock(&inode->i_lock);
9269 +       }
9270 +       if (unlikely(dentry && au_digen_test(dentry, sigen))) {
9271 +               /* need to refresh */
9272 +               dput(dentry);
9273 +               dentry = NULL;
9274 +       }
9275 +
9276 +out_iput:
9277 +       iput(inode);
9278 +out:
9279 +       AuTraceErrPtr(dentry);
9280 +       return dentry;
9281 +}
9282 +
9283 +/* ---------------------------------------------------------------------- */
9284 +
9285 +/* todo: dirty? */
9286 +/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
9287 +
9288 +struct au_compare_mnt_args {
9289 +       /* input */
9290 +       struct super_block *sb;
9291 +
9292 +       /* output */
9293 +       struct vfsmount *mnt;
9294 +};
9295 +
9296 +static int au_compare_mnt(struct vfsmount *mnt, void *arg)
9297 +{
9298 +       struct au_compare_mnt_args *a = arg;
9299 +
9300 +       if (mnt->mnt_sb != a->sb)
9301 +               return 0;
9302 +       a->mnt = mntget(mnt);
9303 +       return 1;
9304 +}
9305 +
9306 +static struct vfsmount *au_mnt_get(struct super_block *sb)
9307 +{
9308 +       int err;
9309 +       struct path root;
9310 +       struct au_compare_mnt_args args = {
9311 +               .sb = sb
9312 +       };
9313 +
9314 +       get_fs_root(current->fs, &root);
9315 +       br_read_lock(&vfsmount_lock);
9316 +       err = iterate_mounts(au_compare_mnt, &args, root.mnt);
9317 +       br_read_unlock(&vfsmount_lock);
9318 +       path_put(&root);
9319 +       AuDebugOn(!err);
9320 +       AuDebugOn(!args.mnt);
9321 +       return args.mnt;
9322 +}
9323 +
9324 +struct au_nfsd_si_lock {
9325 +       unsigned int sigen;
9326 +       aufs_bindex_t bindex, br_id;
9327 +       unsigned char force_lock;
9328 +};
9329 +
9330 +static int si_nfsd_read_lock(struct super_block *sb,
9331 +                            struct au_nfsd_si_lock *nsi_lock)
9332 +{
9333 +       int err;
9334 +       aufs_bindex_t bindex;
9335 +
9336 +       si_read_lock(sb, AuLock_FLUSH);
9337 +
9338 +       /* branch id may be wrapped around */
9339 +       err = 0;
9340 +       bindex = au_br_index(sb, nsi_lock->br_id);
9341 +       if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
9342 +               goto out; /* success */
9343 +
9344 +       err = -ESTALE;
9345 +       bindex = -1;
9346 +       if (!nsi_lock->force_lock)
9347 +               si_read_unlock(sb);
9348 +
9349 +out:
9350 +       nsi_lock->bindex = bindex;
9351 +       return err;
9352 +}
9353 +
9354 +struct find_name_by_ino {
9355 +       int called, found;
9356 +       ino_t ino;
9357 +       char *name;
9358 +       int namelen;
9359 +};
9360 +
9361 +static int
9362 +find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
9363 +                u64 ino, unsigned int d_type)
9364 +{
9365 +       struct find_name_by_ino *a = arg;
9366 +
9367 +       a->called++;
9368 +       if (a->ino != ino)
9369 +               return 0;
9370 +
9371 +       memcpy(a->name, name, namelen);
9372 +       a->namelen = namelen;
9373 +       a->found = 1;
9374 +       return 1;
9375 +}
9376 +
9377 +static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
9378 +                                    struct au_nfsd_si_lock *nsi_lock)
9379 +{
9380 +       struct dentry *dentry, *parent;
9381 +       struct file *file;
9382 +       struct inode *dir;
9383 +       struct find_name_by_ino arg;
9384 +       int err;
9385 +
9386 +       parent = path->dentry;
9387 +       if (nsi_lock)
9388 +               si_read_unlock(parent->d_sb);
9389 +       file = vfsub_dentry_open(path, au_dir_roflags);
9390 +       dentry = (void *)file;
9391 +       if (IS_ERR(file))
9392 +               goto out;
9393 +
9394 +       dentry = ERR_PTR(-ENOMEM);
9395 +       arg.name = (void *)__get_free_page(GFP_NOFS);
9396 +       if (unlikely(!arg.name))
9397 +               goto out_file;
9398 +       arg.ino = ino;
9399 +       arg.found = 0;
9400 +       do {
9401 +               arg.called = 0;
9402 +               /* smp_mb(); */
9403 +               err = vfsub_readdir(file, find_name_by_ino, &arg);
9404 +       } while (!err && !arg.found && arg.called);
9405 +       dentry = ERR_PTR(err);
9406 +       if (unlikely(err))
9407 +               goto out_name;
9408 +       dentry = ERR_PTR(-ENOENT);
9409 +       if (!arg.found)
9410 +               goto out_name;
9411 +
9412 +       /* do not call vfsub_lkup_one() */
9413 +       dir = parent->d_inode;
9414 +       mutex_lock(&dir->i_mutex);
9415 +       dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
9416 +       mutex_unlock(&dir->i_mutex);
9417 +       AuTraceErrPtr(dentry);
9418 +       if (IS_ERR(dentry))
9419 +               goto out_name;
9420 +       AuDebugOn(au_test_anon(dentry));
9421 +       if (unlikely(!dentry->d_inode)) {
9422 +               dput(dentry);
9423 +               dentry = ERR_PTR(-ENOENT);
9424 +       }
9425 +
9426 +out_name:
9427 +       free_page((unsigned long)arg.name);
9428 +out_file:
9429 +       fput(file);
9430 +out:
9431 +       if (unlikely(nsi_lock
9432 +                    && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
9433 +               if (!IS_ERR(dentry)) {
9434 +                       dput(dentry);
9435 +                       dentry = ERR_PTR(-ESTALE);
9436 +               }
9437 +       AuTraceErrPtr(dentry);
9438 +       return dentry;
9439 +}
9440 +
9441 +static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
9442 +                                       ino_t dir_ino,
9443 +                                       struct au_nfsd_si_lock *nsi_lock)
9444 +{
9445 +       struct dentry *dentry;
9446 +       struct path path;
9447 +
9448 +       if (dir_ino != AUFS_ROOT_INO) {
9449 +               path.dentry = decode_by_ino(sb, dir_ino, 0);
9450 +               dentry = path.dentry;
9451 +               if (!path.dentry || IS_ERR(path.dentry))
9452 +                       goto out;
9453 +               AuDebugOn(au_test_anon(path.dentry));
9454 +       } else
9455 +               path.dentry = dget(sb->s_root);
9456 +
9457 +       path.mnt = au_mnt_get(sb);
9458 +       dentry = au_lkup_by_ino(&path, ino, nsi_lock);
9459 +       path_put(&path);
9460 +
9461 +out:
9462 +       AuTraceErrPtr(dentry);
9463 +       return dentry;
9464 +}
9465 +
9466 +/* ---------------------------------------------------------------------- */
9467 +
9468 +static int h_acceptable(void *expv, struct dentry *dentry)
9469 +{
9470 +       return 1;
9471 +}
9472 +
9473 +static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
9474 +                          char *buf, int len, struct super_block *sb)
9475 +{
9476 +       char *p;
9477 +       int n;
9478 +       struct path path;
9479 +
9480 +       p = d_path(h_rootpath, buf, len);
9481 +       if (IS_ERR(p))
9482 +               goto out;
9483 +       n = strlen(p);
9484 +
9485 +       path.mnt = h_rootpath->mnt;
9486 +       path.dentry = h_parent;
9487 +       p = d_path(&path, buf, len);
9488 +       if (IS_ERR(p))
9489 +               goto out;
9490 +       if (n != 1)
9491 +               p += n;
9492 +
9493 +       path.mnt = au_mnt_get(sb);
9494 +       path.dentry = sb->s_root;
9495 +       p = d_path(&path, buf, len - strlen(p));
9496 +       mntput(path.mnt);
9497 +       if (IS_ERR(p))
9498 +               goto out;
9499 +       if (n != 1)
9500 +               p[strlen(p)] = '/';
9501 +
9502 +out:
9503 +       AuTraceErrPtr(p);
9504 +       return p;
9505 +}
9506 +
9507 +static
9508 +struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
9509 +                             int fh_len, struct au_nfsd_si_lock *nsi_lock)
9510 +{
9511 +       struct dentry *dentry, *h_parent, *root;
9512 +       struct super_block *h_sb;
9513 +       char *pathname, *p;
9514 +       struct vfsmount *h_mnt;
9515 +       struct au_branch *br;
9516 +       int err;
9517 +       struct path path;
9518 +
9519 +       br = au_sbr(sb, nsi_lock->bindex);
9520 +       h_mnt = br->br_mnt;
9521 +       h_sb = h_mnt->mnt_sb;
9522 +       /* todo: call lower fh_to_dentry()? fh_to_parent()? */
9523 +       h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
9524 +                                     fh_len - Fh_tail, fh[Fh_h_type],
9525 +                                     h_acceptable, /*context*/NULL);
9526 +       dentry = h_parent;
9527 +       if (unlikely(!h_parent || IS_ERR(h_parent))) {
9528 +               AuWarn1("%s decode_fh failed, %ld\n",
9529 +                       au_sbtype(h_sb), PTR_ERR(h_parent));
9530 +               goto out;
9531 +       }
9532 +       dentry = NULL;
9533 +       if (unlikely(au_test_anon(h_parent))) {
9534 +               AuWarn1("%s decode_fh returned a disconnected dentry\n",
9535 +                       au_sbtype(h_sb));
9536 +               goto out_h_parent;
9537 +       }
9538 +
9539 +       dentry = ERR_PTR(-ENOMEM);
9540 +       pathname = (void *)__get_free_page(GFP_NOFS);
9541 +       if (unlikely(!pathname))
9542 +               goto out_h_parent;
9543 +
9544 +       root = sb->s_root;
9545 +       path.mnt = h_mnt;
9546 +       di_read_lock_parent(root, !AuLock_IR);
9547 +       path.dentry = au_h_dptr(root, nsi_lock->bindex);
9548 +       di_read_unlock(root, !AuLock_IR);
9549 +       p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
9550 +       dentry = (void *)p;
9551 +       if (IS_ERR(p))
9552 +               goto out_pathname;
9553 +
9554 +       si_read_unlock(sb);
9555 +       err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
9556 +       dentry = ERR_PTR(err);
9557 +       if (unlikely(err))
9558 +               goto out_relock;
9559 +
9560 +       dentry = ERR_PTR(-ENOENT);
9561 +       AuDebugOn(au_test_anon(path.dentry));
9562 +       if (unlikely(!path.dentry->d_inode))
9563 +               goto out_path;
9564 +
9565 +       if (ino != path.dentry->d_inode->i_ino)
9566 +               dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
9567 +       else
9568 +               dentry = dget(path.dentry);
9569 +
9570 +out_path:
9571 +       path_put(&path);
9572 +out_relock:
9573 +       if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
9574 +               if (!IS_ERR(dentry)) {
9575 +                       dput(dentry);
9576 +                       dentry = ERR_PTR(-ESTALE);
9577 +               }
9578 +out_pathname:
9579 +       free_page((unsigned long)pathname);
9580 +out_h_parent:
9581 +       dput(h_parent);
9582 +out:
9583 +       AuTraceErrPtr(dentry);
9584 +       return dentry;
9585 +}
9586 +
9587 +/* ---------------------------------------------------------------------- */
9588 +
9589 +static struct dentry *
9590 +aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
9591 +                 int fh_type)
9592 +{
9593 +       struct dentry *dentry;
9594 +       __u32 *fh = fid->raw;
9595 +       struct au_branch *br;
9596 +       ino_t ino, dir_ino;
9597 +       struct au_nfsd_si_lock nsi_lock = {
9598 +               .force_lock     = 0
9599 +       };
9600 +
9601 +       dentry = ERR_PTR(-ESTALE);
9602 +       /* it should never happen, but the file handle is unreliable */
9603 +       if (unlikely(fh_len < Fh_tail))
9604 +               goto out;
9605 +       nsi_lock.sigen = fh[Fh_sigen];
9606 +       nsi_lock.br_id = fh[Fh_br_id];
9607 +
9608 +       /* branch id may be wrapped around */
9609 +       br = NULL;
9610 +       if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
9611 +               goto out;
9612 +       nsi_lock.force_lock = 1;
9613 +
9614 +       /* is this inode still cached? */
9615 +       ino = decode_ino(fh + Fh_ino);
9616 +       /* it should never happen */
9617 +       if (unlikely(ino == AUFS_ROOT_INO))
9618 +               goto out;
9619 +
9620 +       dir_ino = decode_ino(fh + Fh_dir_ino);
9621 +       dentry = decode_by_ino(sb, ino, dir_ino);
9622 +       if (IS_ERR(dentry))
9623 +               goto out_unlock;
9624 +       if (dentry)
9625 +               goto accept;
9626 +
9627 +       /* is the parent dir cached? */
9628 +       br = au_sbr(sb, nsi_lock.bindex);
9629 +       atomic_inc(&br->br_count);
9630 +       dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
9631 +       if (IS_ERR(dentry))
9632 +               goto out_unlock;
9633 +       if (dentry)
9634 +               goto accept;
9635 +
9636 +       /* lookup path */
9637 +       dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
9638 +       if (IS_ERR(dentry))
9639 +               goto out_unlock;
9640 +       if (unlikely(!dentry))
9641 +               /* todo?: make it ESTALE */
9642 +               goto out_unlock;
9643 +
9644 +accept:
9645 +       if (!au_digen_test(dentry, au_sigen(sb))
9646 +           && dentry->d_inode->i_generation == fh[Fh_igen])
9647 +               goto out_unlock; /* success */
9648 +
9649 +       dput(dentry);
9650 +       dentry = ERR_PTR(-ESTALE);
9651 +out_unlock:
9652 +       if (br)
9653 +               atomic_dec(&br->br_count);
9654 +       si_read_unlock(sb);
9655 +out:
9656 +       AuTraceErrPtr(dentry);
9657 +       return dentry;
9658 +}
9659 +
9660 +#if 0 /* reserved for future use */
9661 +/* support subtreecheck option */
9662 +static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
9663 +                                       int fh_len, int fh_type)
9664 +{
9665 +       struct dentry *parent;
9666 +       __u32 *fh = fid->raw;
9667 +       ino_t dir_ino;
9668 +
9669 +       dir_ino = decode_ino(fh + Fh_dir_ino);
9670 +       parent = decode_by_ino(sb, dir_ino, 0);
9671 +       if (IS_ERR(parent))
9672 +               goto out;
9673 +       if (!parent)
9674 +               parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
9675 +                                       dir_ino, fh, fh_len);
9676 +
9677 +out:
9678 +       AuTraceErrPtr(parent);
9679 +       return parent;
9680 +}
9681 +#endif
9682 +
9683 +/* ---------------------------------------------------------------------- */
9684 +
9685 +static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
9686 +                         struct inode *dir)
9687 +{
9688 +       int err;
9689 +       aufs_bindex_t bindex;
9690 +       struct super_block *sb, *h_sb;
9691 +       struct dentry *dentry, *parent, *h_parent;
9692 +       struct inode *h_dir;
9693 +       struct au_branch *br;
9694 +
9695 +       err = -ENOSPC;
9696 +       if (unlikely(*max_len <= Fh_tail)) {
9697 +               AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
9698 +               goto out;
9699 +       }
9700 +
9701 +       err = FILEID_ROOT;
9702 +       if (inode->i_ino == AUFS_ROOT_INO) {
9703 +               AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
9704 +               goto out;
9705 +       }
9706 +
9707 +       h_parent = NULL;
9708 +       sb = inode->i_sb;
9709 +       err = si_read_lock(sb, AuLock_FLUSH);
9710 +       if (unlikely(err))
9711 +               goto out;
9712 +
9713 +#ifdef CONFIG_AUFS_DEBUG
9714 +       if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
9715 +               AuWarn1("NFS-exporting requires xino\n");
9716 +#endif
9717 +       err = -EIO;
9718 +       parent = NULL;
9719 +       ii_read_lock_child(inode);
9720 +       bindex = au_ibstart(inode);
9721 +       if (!dir) {
9722 +               dentry = d_find_alias(inode);
9723 +               if (unlikely(!dentry))
9724 +                       goto out_unlock;
9725 +               AuDebugOn(au_test_anon(dentry));
9726 +               parent = dget_parent(dentry);
9727 +               dput(dentry);
9728 +               if (unlikely(!parent))
9729 +                       goto out_unlock;
9730 +               dir = parent->d_inode;
9731 +       }
9732 +
9733 +       ii_read_lock_parent(dir);
9734 +       h_dir = au_h_iptr(dir, bindex);
9735 +       ii_read_unlock(dir);
9736 +       if (unlikely(!h_dir))
9737 +               goto out_parent;
9738 +       h_parent = d_find_alias(h_dir);
9739 +       if (unlikely(!h_parent))
9740 +               goto out_hparent;
9741 +
9742 +       err = -EPERM;
9743 +       br = au_sbr(sb, bindex);
9744 +       h_sb = br->br_mnt->mnt_sb;
9745 +       if (unlikely(!h_sb->s_export_op)) {
9746 +               AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
9747 +               goto out_hparent;
9748 +       }
9749 +
9750 +       fh[Fh_br_id] = br->br_id;
9751 +       fh[Fh_sigen] = au_sigen(sb);
9752 +       encode_ino(fh + Fh_ino, inode->i_ino);
9753 +       encode_ino(fh + Fh_dir_ino, dir->i_ino);
9754 +       fh[Fh_igen] = inode->i_generation;
9755 +
9756 +       *max_len -= Fh_tail;
9757 +       fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
9758 +                                          max_len,
9759 +                                          /*connectable or subtreecheck*/0);
9760 +       err = fh[Fh_h_type];
9761 +       *max_len += Fh_tail;
9762 +       /* todo: macros? */
9763 +       if (err != 255)
9764 +               err = 99;
9765 +       else
9766 +               AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
9767 +
9768 +out_hparent:
9769 +       dput(h_parent);
9770 +out_parent:
9771 +       dput(parent);
9772 +out_unlock:
9773 +       ii_read_unlock(inode);
9774 +       si_read_unlock(sb);
9775 +out:
9776 +       if (unlikely(err < 0))
9777 +               err = 255;
9778 +       return err;
9779 +}
9780 +
9781 +/* ---------------------------------------------------------------------- */
9782 +
9783 +static int aufs_commit_metadata(struct inode *inode)
9784 +{
9785 +       int err;
9786 +       aufs_bindex_t bindex;
9787 +       struct super_block *sb;
9788 +       struct inode *h_inode;
9789 +       int (*f)(struct inode *inode);
9790 +
9791 +       sb = inode->i_sb;
9792 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
9793 +       ii_write_lock_child(inode);
9794 +       bindex = au_ibstart(inode);
9795 +       AuDebugOn(bindex < 0);
9796 +       h_inode = au_h_iptr(inode, bindex);
9797 +
9798 +       f = h_inode->i_sb->s_export_op->commit_metadata;
9799 +       if (f)
9800 +               err = f(h_inode);
9801 +       else {
9802 +               struct writeback_control wbc = {
9803 +                       .sync_mode      = WB_SYNC_ALL,
9804 +                       .nr_to_write    = 0 /* metadata only */
9805 +               };
9806 +
9807 +               err = sync_inode(h_inode, &wbc);
9808 +       }
9809 +
9810 +       au_cpup_attr_timesizes(inode);
9811 +       ii_write_unlock(inode);
9812 +       si_read_unlock(sb);
9813 +       return err;
9814 +}
9815 +
9816 +/* ---------------------------------------------------------------------- */
9817 +
9818 +static struct export_operations aufs_export_op = {
9819 +       .fh_to_dentry           = aufs_fh_to_dentry,
9820 +       /* .fh_to_parent        = aufs_fh_to_parent, */
9821 +       .encode_fh              = aufs_encode_fh,
9822 +       .commit_metadata        = aufs_commit_metadata
9823 +};
9824 +
9825 +void au_export_init(struct super_block *sb)
9826 +{
9827 +       struct au_sbinfo *sbinfo;
9828 +       __u32 u;
9829 +
9830 +       sb->s_export_op = &aufs_export_op;
9831 +       sbinfo = au_sbi(sb);
9832 +       sbinfo->si_xigen = NULL;
9833 +       get_random_bytes(&u, sizeof(u));
9834 +       BUILD_BUG_ON(sizeof(u) != sizeof(int));
9835 +       atomic_set(&sbinfo->si_xigen_next, u);
9836 +}
9837 diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
9838 --- /usr/share/empty/fs/aufs/file.c     1970-01-01 01:00:00.000000000 +0100
9839 +++ linux/fs/aufs/file.c        2013-01-11 19:46:12.635947932 +0100
9840 @@ -0,0 +1,683 @@
9841 +/*
9842 + * Copyright (C) 2005-2013 Junjiro R. Okajima
9843 + *
9844 + * This program, aufs is free software; you can redistribute it and/or modify
9845 + * it under the terms of the GNU General Public License as published by
9846 + * the Free Software Foundation; either version 2 of the License, or
9847 + * (at your option) any later version.
9848 + *
9849 + * This program is distributed in the hope that it will be useful,
9850 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9851 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9852 + * GNU General Public License for more details.
9853 + *
9854 + * You should have received a copy of the GNU General Public License
9855 + * along with this program; if not, write to the Free Software
9856 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
9857 + */
9858 +
9859 +/*
9860 + * handling file/dir, and address_space operation
9861 + */
9862 +
9863 +#ifdef CONFIG_AUFS_DEBUG
9864 +#include <linux/migrate.h>
9865 +#endif
9866 +#include <linux/pagemap.h>
9867 +#include "aufs.h"
9868 +
9869 +/* drop flags for writing */
9870 +unsigned int au_file_roflags(unsigned int flags)
9871 +{
9872 +       flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
9873 +       flags |= O_RDONLY | O_NOATIME;
9874 +       return flags;
9875 +}
9876 +
9877 +/* common functions to regular file and dir */
9878 +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
9879 +                      struct file *file)
9880 +{
9881 +       struct file *h_file;
9882 +       struct dentry *h_dentry;
9883 +       struct inode *h_inode;
9884 +       struct super_block *sb;
9885 +       struct au_branch *br;
9886 +       struct path h_path;
9887 +       int err, exec_flag;
9888 +
9889 +       /* a race condition can happen between open and unlink/rmdir */
9890 +       h_file = ERR_PTR(-ENOENT);
9891 +       h_dentry = au_h_dptr(dentry, bindex);
9892 +       if (au_test_nfsd() && !h_dentry)
9893 +               goto out;
9894 +       h_inode = h_dentry->d_inode;
9895 +       if (au_test_nfsd() && !h_inode)
9896 +               goto out;
9897 +       spin_lock(&h_dentry->d_lock);
9898 +       err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
9899 +               || !h_inode
9900 +               /* || !dentry->d_inode->i_nlink */
9901 +               ;
9902 +       spin_unlock(&h_dentry->d_lock);
9903 +       if (unlikely(err))
9904 +               goto out;
9905 +
9906 +       sb = dentry->d_sb;
9907 +       br = au_sbr(sb, bindex);
9908 +       h_file = ERR_PTR(-EACCES);
9909 +       exec_flag = flags & __FMODE_EXEC;
9910 +       if (exec_flag && (br->br_mnt->mnt_flags & MNT_NOEXEC))
9911 +               goto out;
9912 +
9913 +       /* drop flags for writing */
9914 +       if (au_test_ro(sb, bindex, dentry->d_inode))
9915 +               flags = au_file_roflags(flags);
9916 +       flags &= ~O_CREAT;
9917 +       atomic_inc(&br->br_count);
9918 +       h_path.dentry = h_dentry;
9919 +       h_path.mnt = br->br_mnt;
9920 +       if (!au_special_file(h_inode->i_mode))
9921 +               h_file = vfsub_dentry_open(&h_path, flags);
9922 +       else {
9923 +               /* this block depends upon the configuration */
9924 +               di_read_unlock(dentry, AuLock_IR);
9925 +               fi_write_unlock(file);
9926 +               si_read_unlock(sb);
9927 +               h_file = vfsub_dentry_open(&h_path, flags);
9928 +               si_noflush_read_lock(sb);
9929 +               fi_write_lock(file);
9930 +               di_read_lock_child(dentry, AuLock_IR);
9931 +       }
9932 +       if (IS_ERR(h_file))
9933 +               goto out_br;
9934 +
9935 +       if (exec_flag) {
9936 +               err = deny_write_access(h_file);
9937 +               if (unlikely(err)) {
9938 +                       fput(h_file);
9939 +                       h_file = ERR_PTR(err);
9940 +                       goto out_br;
9941 +               }
9942 +       }
9943 +       fsnotify_open(h_file);
9944 +       goto out; /* success */
9945 +
9946 +out_br:
9947 +       atomic_dec(&br->br_count);
9948 +out:
9949 +       return h_file;
9950 +}
9951 +
9952 +int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
9953 +              struct au_fidir *fidir)
9954 +{
9955 +       int err;
9956 +       struct dentry *dentry;
9957 +
9958 +       err = au_finfo_init(file, fidir);
9959 +       if (unlikely(err))
9960 +               goto out;
9961 +
9962 +       dentry = file->f_dentry;
9963 +       di_read_lock_child(dentry, AuLock_IR);
9964 +       err = open(file, vfsub_file_flags(file));
9965 +       di_read_unlock(dentry, AuLock_IR);
9966 +
9967 +       fi_write_unlock(file);
9968 +       if (unlikely(err)) {
9969 +               au_fi(file)->fi_hdir = NULL;
9970 +               au_finfo_fin(file);
9971 +       }
9972 +
9973 +out:
9974 +       return err;
9975 +}
9976 +
9977 +int au_reopen_nondir(struct file *file)
9978 +{
9979 +       int err;
9980 +       aufs_bindex_t bstart;
9981 +       struct dentry *dentry;
9982 +       struct file *h_file, *h_file_tmp;
9983 +
9984 +       dentry = file->f_dentry;
9985 +       AuDebugOn(au_special_file(dentry->d_inode->i_mode));
9986 +       bstart = au_dbstart(dentry);
9987 +       h_file_tmp = NULL;
9988 +       if (au_fbstart(file) == bstart) {
9989 +               h_file = au_hf_top(file);
9990 +               if (file->f_mode == h_file->f_mode)
9991 +                       return 0; /* success */
9992 +               h_file_tmp = h_file;
9993 +               get_file(h_file_tmp);
9994 +               au_set_h_fptr(file, bstart, NULL);
9995 +       }
9996 +       AuDebugOn(au_fi(file)->fi_hdir);
9997 +       AuDebugOn(au_fbstart(file) < bstart);
9998 +
9999 +       h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
10000 +                          file);
10001 +       err = PTR_ERR(h_file);
10002 +       if (IS_ERR(h_file))
10003 +               goto out; /* todo: close all? */
10004 +
10005 +       err = 0;
10006 +       au_set_fbstart(file, bstart);
10007 +       au_set_h_fptr(file, bstart, h_file);
10008 +       au_update_figen(file);
10009 +       /* todo: necessary? */
10010 +       /* file->f_ra = h_file->f_ra; */
10011 +
10012 +out:
10013 +       if (h_file_tmp)
10014 +               fput(h_file_tmp);
10015 +       return err;
10016 +}
10017 +
10018 +/* ---------------------------------------------------------------------- */
10019 +
10020 +static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
10021 +                       struct dentry *hi_wh)
10022 +{
10023 +       int err;
10024 +       aufs_bindex_t bstart;
10025 +       struct au_dinfo *dinfo;
10026 +       struct dentry *h_dentry;
10027 +       struct au_hdentry *hdp;
10028 +
10029 +       dinfo = au_di(file->f_dentry);
10030 +       AuRwMustWriteLock(&dinfo->di_rwsem);
10031 +
10032 +       bstart = dinfo->di_bstart;
10033 +       dinfo->di_bstart = btgt;
10034 +       hdp = dinfo->di_hdentry;
10035 +       h_dentry = hdp[0 + btgt].hd_dentry;
10036 +       hdp[0 + btgt].hd_dentry = hi_wh;
10037 +       err = au_reopen_nondir(file);
10038 +       hdp[0 + btgt].hd_dentry = h_dentry;
10039 +       dinfo->di_bstart = bstart;
10040 +
10041 +       return err;
10042 +}
10043 +
10044 +static int au_ready_to_write_wh(struct file *file, loff_t len,
10045 +                               aufs_bindex_t bcpup)
10046 +{
10047 +       int err;
10048 +       struct inode *inode, *h_inode;
10049 +       struct dentry *dentry, *h_dentry, *hi_wh;
10050 +
10051 +       dentry = file->f_dentry;
10052 +       au_update_dbstart(dentry);
10053 +       inode = dentry->d_inode;
10054 +       h_inode = NULL;
10055 +       if (au_dbstart(dentry) <= bcpup && au_dbend(dentry) >= bcpup) {
10056 +               h_dentry = au_h_dptr(dentry, bcpup);
10057 +               if (h_dentry)
10058 +                       h_inode = h_dentry->d_inode;
10059 +       }
10060 +       hi_wh = au_hi_wh(inode, bcpup);
10061 +       if (!hi_wh && !h_inode)
10062 +               err = au_sio_cpup_wh(dentry, bcpup, len, file);
10063 +       else
10064 +               /* already copied-up after unlink */
10065 +               err = au_reopen_wh(file, bcpup, hi_wh);
10066 +
10067 +       if (!err
10068 +           && inode->i_nlink > 1
10069 +           && au_opt_test(au_mntflags(dentry->d_sb), PLINK))
10070 +               au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup));
10071 +
10072 +       return err;
10073 +}
10074 +
10075 +/*
10076 + * prepare the @file for writing.
10077 + */
10078 +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
10079 +{
10080 +       int err;
10081 +       aufs_bindex_t bstart, bcpup, dbstart;
10082 +       struct dentry *dentry, *parent, *h_dentry;
10083 +       struct inode *h_inode, *inode;
10084 +       struct super_block *sb;
10085 +       struct file *h_file;
10086 +
10087 +       dentry = file->f_dentry;
10088 +       sb = dentry->d_sb;
10089 +       inode = dentry->d_inode;
10090 +       AuDebugOn(au_special_file(inode->i_mode));
10091 +       bstart = au_fbstart(file);
10092 +       err = au_test_ro(sb, bstart, inode);
10093 +       if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
10094 +               err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0);
10095 +               goto out;
10096 +       }
10097 +
10098 +       /* need to cpup or reopen */
10099 +       parent = dget_parent(dentry);
10100 +       di_write_lock_parent(parent);
10101 +       err = AuWbrCopyup(au_sbi(sb), dentry);
10102 +       bcpup = err;
10103 +       if (unlikely(err < 0))
10104 +               goto out_dgrade;
10105 +       err = 0;
10106 +
10107 +       if (!d_unhashed(dentry) && !au_h_dptr(parent, bcpup)) {
10108 +               err = au_cpup_dirs(dentry, bcpup);
10109 +               if (unlikely(err))
10110 +                       goto out_dgrade;
10111 +       }
10112 +
10113 +       err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE,
10114 +                    AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10115 +       if (unlikely(err))
10116 +               goto out_dgrade;
10117 +
10118 +       h_dentry = au_hf_top(file)->f_dentry;
10119 +       h_inode = h_dentry->d_inode;
10120 +       dbstart = au_dbstart(dentry);
10121 +       if (dbstart <= bcpup) {
10122 +               h_dentry = au_h_dptr(dentry, bcpup);
10123 +               AuDebugOn(!h_dentry);
10124 +               h_inode = h_dentry->d_inode;
10125 +               AuDebugOn(!h_inode);
10126 +               bstart = bcpup;
10127 +       }
10128 +
10129 +       if (dbstart <= bcpup            /* just reopen */
10130 +           || !d_unhashed(dentry)      /* copyup and reopen */
10131 +               ) {
10132 +               mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
10133 +               h_file = au_h_open_pre(dentry, bstart);
10134 +               if (IS_ERR(h_file)) {
10135 +                       err = PTR_ERR(h_file);
10136 +                       h_file = NULL;
10137 +               } else {
10138 +                       di_downgrade_lock(parent, AuLock_IR);
10139 +                       if (dbstart > bcpup)
10140 +                               err = au_sio_cpup_simple(dentry, bcpup, len,
10141 +                                                        AuCpup_DTIME);
10142 +                       if (!err)
10143 +                               err = au_reopen_nondir(file);
10144 +               }
10145 +               mutex_unlock(&h_inode->i_mutex);
10146 +               au_h_open_post(dentry, bstart, h_file);
10147 +       } else {                        /* copyup as wh and reopen */
10148 +               /*
10149 +                * since writable hfsplus branch is not supported,
10150 +                * h_open_pre/post() are unnecessary.
10151 +                */
10152 +               mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
10153 +               err = au_ready_to_write_wh(file, len, bcpup);
10154 +               di_downgrade_lock(parent, AuLock_IR);
10155 +               mutex_unlock(&h_inode->i_mutex);
10156 +       }
10157 +
10158 +       if (!err) {
10159 +               au_pin_set_parent_lflag(pin, /*lflag*/0);
10160 +               goto out_dput; /* success */
10161 +       }
10162 +       au_unpin(pin);
10163 +       goto out_unlock;
10164 +
10165 +out_dgrade:
10166 +       di_downgrade_lock(parent, AuLock_IR);
10167 +out_unlock:
10168 +       di_read_unlock(parent, AuLock_IR);
10169 +out_dput:
10170 +       dput(parent);
10171 +out:
10172 +       return err;
10173 +}
10174 +
10175 +/* ---------------------------------------------------------------------- */
10176 +
10177 +int au_do_flush(struct file *file, fl_owner_t id,
10178 +               int (*flush)(struct file *file, fl_owner_t id))
10179 +{
10180 +       int err;
10181 +       struct dentry *dentry;
10182 +       struct super_block *sb;
10183 +       struct inode *inode;
10184 +
10185 +       dentry = file->f_dentry;
10186 +       sb = dentry->d_sb;
10187 +       inode = dentry->d_inode;
10188 +       si_noflush_read_lock(sb);
10189 +       fi_read_lock(file);
10190 +       ii_read_lock_child(inode);
10191 +
10192 +       err = flush(file, id);
10193 +       au_cpup_attr_timesizes(inode);
10194 +
10195 +       ii_read_unlock(inode);
10196 +       fi_read_unlock(file);
10197 +       si_read_unlock(sb);
10198 +       return err;
10199 +}
10200 +
10201 +/* ---------------------------------------------------------------------- */
10202 +
10203 +static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
10204 +{
10205 +       int err;
10206 +       aufs_bindex_t bstart;
10207 +       struct au_pin pin;
10208 +       struct au_finfo *finfo;
10209 +       struct dentry *dentry, *parent, *hi_wh;
10210 +       struct inode *inode;
10211 +       struct super_block *sb;
10212 +
10213 +       FiMustWriteLock(file);
10214 +
10215 +       err = 0;
10216 +       finfo = au_fi(file);
10217 +       dentry = file->f_dentry;
10218 +       sb = dentry->d_sb;
10219 +       inode = dentry->d_inode;
10220 +       bstart = au_ibstart(inode);
10221 +       if (bstart == finfo->fi_btop || IS_ROOT(dentry))
10222 +               goto out;
10223 +
10224 +       parent = dget_parent(dentry);
10225 +       if (au_test_ro(sb, bstart, inode)) {
10226 +               di_read_lock_parent(parent, !AuLock_IR);
10227 +               err = AuWbrCopyup(au_sbi(sb), dentry);
10228 +               bstart = err;
10229 +               di_read_unlock(parent, !AuLock_IR);
10230 +               if (unlikely(err < 0))
10231 +                       goto out_parent;
10232 +               err = 0;
10233 +       }
10234 +
10235 +       di_read_lock_parent(parent, AuLock_IR);
10236 +       hi_wh = au_hi_wh(inode, bstart);
10237 +       if (!S_ISDIR(inode->i_mode)
10238 +           && au_opt_test(au_mntflags(sb), PLINK)
10239 +           && au_plink_test(inode)
10240 +           && !d_unhashed(dentry)) {
10241 +               err = au_test_and_cpup_dirs(dentry, bstart);
10242 +               if (unlikely(err))
10243 +                       goto out_unlock;
10244 +
10245 +               /* always superio. */
10246 +               err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE,
10247 +                            AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10248 +               if (!err)
10249 +                       err = au_sio_cpup_simple(dentry, bstart, -1,
10250 +                                                AuCpup_DTIME);
10251 +               au_unpin(&pin);
10252 +       } else if (hi_wh) {
10253 +               /* already copied-up after unlink */
10254 +               err = au_reopen_wh(file, bstart, hi_wh);
10255 +               *need_reopen = 0;
10256 +       }
10257 +
10258 +out_unlock:
10259 +       di_read_unlock(parent, AuLock_IR);
10260 +out_parent:
10261 +       dput(parent);
10262 +out:
10263 +       return err;
10264 +}
10265 +
10266 +static void au_do_refresh_dir(struct file *file)
10267 +{
10268 +       aufs_bindex_t bindex, bend, new_bindex, brid;
10269 +       struct au_hfile *p, tmp, *q;
10270 +       struct au_finfo *finfo;
10271 +       struct super_block *sb;
10272 +       struct au_fidir *fidir;
10273 +
10274 +       FiMustWriteLock(file);
10275 +
10276 +       sb = file->f_dentry->d_sb;
10277 +       finfo = au_fi(file);
10278 +       fidir = finfo->fi_hdir;
10279 +       AuDebugOn(!fidir);
10280 +       p = fidir->fd_hfile + finfo->fi_btop;
10281 +       brid = p->hf_br->br_id;
10282 +       bend = fidir->fd_bbot;
10283 +       for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
10284 +               if (!p->hf_file)
10285 +                       continue;
10286 +
10287 +               new_bindex = au_br_index(sb, p->hf_br->br_id);
10288 +               if (new_bindex == bindex)
10289 +                       continue;
10290 +               if (new_bindex < 0) {
10291 +                       au_set_h_fptr(file, bindex, NULL);
10292 +                       continue;
10293 +               }
10294 +
10295 +               /* swap two lower inode, and loop again */
10296 +               q = fidir->fd_hfile + new_bindex;
10297 +               tmp = *q;
10298 +               *q = *p;
10299 +               *p = tmp;
10300 +               if (tmp.hf_file) {
10301 +                       bindex--;
10302 +                       p--;
10303 +               }
10304 +       }
10305 +
10306 +       p = fidir->fd_hfile;
10307 +       if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
10308 +               bend = au_sbend(sb);
10309 +               for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
10310 +                    finfo->fi_btop++, p++)
10311 +                       if (p->hf_file) {
10312 +                               if (p->hf_file->f_dentry
10313 +                                   && p->hf_file->f_dentry->d_inode)
10314 +                                       break;
10315 +                               else
10316 +                                       au_hfput(p, file);
10317 +                       }
10318 +       } else {
10319 +               bend = au_br_index(sb, brid);
10320 +               for (finfo->fi_btop = 0; finfo->fi_btop < bend;
10321 +                    finfo->fi_btop++, p++)
10322 +                       if (p->hf_file)
10323 +                               au_hfput(p, file);
10324 +               bend = au_sbend(sb);
10325 +       }
10326 +
10327 +       p = fidir->fd_hfile + bend;
10328 +       for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
10329 +            fidir->fd_bbot--, p--)
10330 +               if (p->hf_file) {
10331 +                       if (p->hf_file->f_dentry
10332 +                           && p->hf_file->f_dentry->d_inode)
10333 +                               break;
10334 +                       else
10335 +                               au_hfput(p, file);
10336 +               }
10337 +       AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
10338 +}
10339 +
10340 +/*
10341 + * after branch manipulating, refresh the file.
10342 + */
10343 +static int refresh_file(struct file *file, int (*reopen)(struct file *file))
10344 +{
10345 +       int err, need_reopen;
10346 +       aufs_bindex_t bend, bindex;
10347 +       struct dentry *dentry;
10348 +       struct au_finfo *finfo;
10349 +       struct au_hfile *hfile;
10350 +
10351 +       dentry = file->f_dentry;
10352 +       finfo = au_fi(file);
10353 +       if (!finfo->fi_hdir) {
10354 +               hfile = &finfo->fi_htop;
10355 +               AuDebugOn(!hfile->hf_file);
10356 +               bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
10357 +               AuDebugOn(bindex < 0);
10358 +               if (bindex != finfo->fi_btop)
10359 +                       au_set_fbstart(file, bindex);
10360 +       } else {
10361 +               err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
10362 +               if (unlikely(err))
10363 +                       goto out;
10364 +               au_do_refresh_dir(file);
10365 +       }
10366 +
10367 +       err = 0;
10368 +       need_reopen = 1;
10369 +       if (!au_test_mmapped(file))
10370 +               err = au_file_refresh_by_inode(file, &need_reopen);
10371 +       if (!err && need_reopen && !d_unlinked(dentry))
10372 +               err = reopen(file);
10373 +       if (!err) {
10374 +               au_update_figen(file);
10375 +               goto out; /* success */
10376 +       }
10377 +
10378 +       /* error, close all lower files */
10379 +       if (finfo->fi_hdir) {
10380 +               bend = au_fbend_dir(file);
10381 +               for (bindex = au_fbstart(file); bindex <= bend; bindex++)
10382 +                       au_set_h_fptr(file, bindex, NULL);
10383 +       }
10384 +
10385 +out:
10386 +       return err;
10387 +}
10388 +
10389 +/* common function to regular file and dir */
10390 +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
10391 +                         int wlock)
10392 +{
10393 +       int err;
10394 +       unsigned int sigen, figen;
10395 +       aufs_bindex_t bstart;
10396 +       unsigned char pseudo_link;
10397 +       struct dentry *dentry;
10398 +       struct inode *inode;
10399 +
10400 +       err = 0;
10401 +       dentry = file->f_dentry;
10402 +       inode = dentry->d_inode;
10403 +       AuDebugOn(au_special_file(inode->i_mode));
10404 +       sigen = au_sigen(dentry->d_sb);
10405 +       fi_write_lock(file);
10406 +       figen = au_figen(file);
10407 +       di_write_lock_child(dentry);
10408 +       bstart = au_dbstart(dentry);
10409 +       pseudo_link = (bstart != au_ibstart(inode));
10410 +       if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
10411 +               if (!wlock) {
10412 +                       di_downgrade_lock(dentry, AuLock_IR);
10413 +                       fi_downgrade_lock(file);
10414 +               }
10415 +               goto out; /* success */
10416 +       }
10417 +
10418 +       AuDbg("sigen %d, figen %d\n", sigen, figen);
10419 +       if (au_digen_test(dentry, sigen)) {
10420 +               err = au_reval_dpath(dentry, sigen);
10421 +               AuDebugOn(!err && au_digen_test(dentry, sigen));
10422 +       }
10423 +
10424 +       if (!err)
10425 +               err = refresh_file(file, reopen);
10426 +       if (!err) {
10427 +               if (!wlock) {
10428 +                       di_downgrade_lock(dentry, AuLock_IR);
10429 +                       fi_downgrade_lock(file);
10430 +               }
10431 +       } else {
10432 +               di_write_unlock(dentry);
10433 +               fi_write_unlock(file);
10434 +       }
10435 +
10436 +out:
10437 +       return err;
10438 +}
10439 +
10440 +/* ---------------------------------------------------------------------- */
10441 +
10442 +/* cf. aufs_nopage() */
10443 +/* for madvise(2) */
10444 +static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
10445 +{
10446 +       unlock_page(page);
10447 +       return 0;
10448 +}
10449 +
10450 +/* it will never be called, but necessary to support O_DIRECT */
10451 +static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
10452 +                             const struct iovec *iov, loff_t offset,
10453 +                             unsigned long nr_segs)
10454 +{ BUG(); return 0; }
10455 +
10456 +/*
10457 + * it will never be called, but madvise and fadvise behaves differently
10458 + * when get_xip_mem is defined
10459 + */
10460 +static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
10461 +                           int create, void **kmem, unsigned long *pfn)
10462 +{ BUG(); return 0; }
10463 +
10464 +/* they will never be called. */
10465 +#ifdef CONFIG_AUFS_DEBUG
10466 +static int aufs_write_begin(struct file *file, struct address_space *mapping,
10467 +                           loff_t pos, unsigned len, unsigned flags,
10468 +                           struct page **pagep, void **fsdata)
10469 +{ AuUnsupport(); return 0; }
10470 +static int aufs_write_end(struct file *file, struct address_space *mapping,
10471 +                         loff_t pos, unsigned len, unsigned copied,
10472 +                         struct page *page, void *fsdata)
10473 +{ AuUnsupport(); return 0; }
10474 +static int aufs_writepage(struct page *page, struct writeback_control *wbc)
10475 +{ AuUnsupport(); return 0; }
10476 +
10477 +static int aufs_set_page_dirty(struct page *page)
10478 +{ AuUnsupport(); return 0; }
10479 +static void aufs_invalidatepage(struct page *page, unsigned long offset)
10480 +{ AuUnsupport(); }
10481 +static int aufs_releasepage(struct page *page, gfp_t gfp)
10482 +{ AuUnsupport(); return 0; }
10483 +static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
10484 +                           struct page *page, enum migrate_mode mode)
10485 +{ AuUnsupport(); return 0; }
10486 +static int aufs_launder_page(struct page *page)
10487 +{ AuUnsupport(); return 0; }
10488 +static int aufs_is_partially_uptodate(struct page *page,
10489 +                                     read_descriptor_t *desc,
10490 +                                     unsigned long from)
10491 +{ AuUnsupport(); return 0; }
10492 +static int aufs_error_remove_page(struct address_space *mapping,
10493 +                                 struct page *page)
10494 +{ AuUnsupport(); return 0; }
10495 +static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
10496 +                             sector_t *span)
10497 +{ AuUnsupport(); return 0; }
10498 +static void aufs_swap_deactivate(struct file *file)
10499 +{ AuUnsupport(); }
10500 +#endif /* CONFIG_AUFS_DEBUG */
10501 +
10502 +const struct address_space_operations aufs_aop = {
10503 +       .readpage               = aufs_readpage,
10504 +       .direct_IO              = aufs_direct_IO,
10505 +       .get_xip_mem            = aufs_get_xip_mem,
10506 +#ifdef CONFIG_AUFS_DEBUG
10507 +       .writepage              = aufs_writepage,
10508 +       /* no writepages, because of writepage */
10509 +       .set_page_dirty         = aufs_set_page_dirty,
10510 +       /* no readpages, because of readpage */
10511 +       .write_begin            = aufs_write_begin,
10512 +       .write_end              = aufs_write_end,
10513 +       /* no bmap, no block device */
10514 +       .invalidatepage         = aufs_invalidatepage,
10515 +       .releasepage            = aufs_releasepage,
10516 +       .migratepage            = aufs_migratepage,
10517 +       .launder_page           = aufs_launder_page,
10518 +       .is_partially_uptodate  = aufs_is_partially_uptodate,
10519 +       .error_remove_page      = aufs_error_remove_page,
10520 +       .swap_activate          = aufs_swap_activate,
10521 +       .swap_deactivate        = aufs_swap_deactivate
10522 +#endif /* CONFIG_AUFS_DEBUG */
10523 +};
10524 diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
10525 --- /usr/share/empty/fs/aufs/file.h     1970-01-01 01:00:00.000000000 +0100
10526 +++ linux/fs/aufs/file.h        2013-01-11 19:46:12.635947932 +0100
10527 @@ -0,0 +1,298 @@
10528 +/*
10529 + * Copyright (C) 2005-2013 Junjiro R. Okajima
10530 + *
10531 + * This program, aufs is free software; you can redistribute it and/or modify
10532 + * it under the terms of the GNU General Public License as published by
10533 + * the Free Software Foundation; either version 2 of the License, or
10534 + * (at your option) any later version.
10535 + *
10536 + * This program is distributed in the hope that it will be useful,
10537 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10538 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10539 + * GNU General Public License for more details.
10540 + *
10541 + * You should have received a copy of the GNU General Public License
10542 + * along with this program; if not, write to the Free Software
10543 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
10544 + */
10545 +
10546 +/*
10547 + * file operations
10548 + */
10549 +
10550 +#ifndef __AUFS_FILE_H__
10551 +#define __AUFS_FILE_H__
10552 +
10553 +#ifdef __KERNEL__
10554 +
10555 +#include <linux/file.h>
10556 +#include <linux/fs.h>
10557 +#include <linux/poll.h>
10558 +#include "rwsem.h"
10559 +
10560 +struct au_branch;
10561 +struct au_hfile {
10562 +       struct file             *hf_file;
10563 +       struct au_branch        *hf_br;
10564 +};
10565 +
10566 +struct au_vdir;
10567 +struct au_fidir {
10568 +       aufs_bindex_t           fd_bbot;
10569 +       aufs_bindex_t           fd_nent;
10570 +       struct au_vdir          *fd_vdir_cache;
10571 +       struct au_hfile         fd_hfile[];
10572 +};
10573 +
10574 +static inline int au_fidir_sz(int nent)
10575 +{
10576 +       AuDebugOn(nent < 0);
10577 +       return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
10578 +}
10579 +
10580 +struct au_finfo {
10581 +       atomic_t                fi_generation;
10582 +
10583 +       struct au_rwsem         fi_rwsem;
10584 +       aufs_bindex_t           fi_btop;
10585 +
10586 +       /* do not union them */
10587 +       struct {                                /* for non-dir */
10588 +               struct au_hfile                 fi_htop;
10589 +               atomic_t                        fi_mmapped;
10590 +       };
10591 +       struct au_fidir         *fi_hdir;       /* for dir only */
10592 +} ____cacheline_aligned_in_smp;
10593 +
10594 +/* ---------------------------------------------------------------------- */
10595 +
10596 +/* file.c */
10597 +extern const struct address_space_operations aufs_aop;
10598 +unsigned int au_file_roflags(unsigned int flags);
10599 +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
10600 +                      struct file *file);
10601 +int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
10602 +              struct au_fidir *fidir);
10603 +int au_reopen_nondir(struct file *file);
10604 +struct au_pin;
10605 +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
10606 +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
10607 +                         int wlock);
10608 +int au_do_flush(struct file *file, fl_owner_t id,
10609 +               int (*flush)(struct file *file, fl_owner_t id));
10610 +
10611 +/* poll.c */
10612 +#ifdef CONFIG_AUFS_POLL
10613 +unsigned int aufs_poll(struct file *file, poll_table *wait);
10614 +#endif
10615 +
10616 +#ifdef CONFIG_AUFS_BR_HFSPLUS
10617 +/* hfsplus.c */
10618 +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex);
10619 +void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
10620 +                   struct file *h_file);
10621 +#else
10622 +static inline
10623 +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
10624 +{
10625 +       return NULL;
10626 +}
10627 +
10628 +AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
10629 +          struct file *h_file);
10630 +#endif
10631 +
10632 +/* f_op.c */
10633 +extern const struct file_operations aufs_file_fop;
10634 +int au_do_open_nondir(struct file *file, int flags);
10635 +int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
10636 +
10637 +#ifdef CONFIG_AUFS_SP_IATTR
10638 +/* f_op_sp.c */
10639 +int au_special_file(umode_t mode);
10640 +void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
10641 +#else
10642 +AuStubInt0(au_special_file, umode_t mode)
10643 +static inline void au_init_special_fop(struct inode *inode, umode_t mode,
10644 +                                      dev_t rdev)
10645 +{
10646 +       init_special_inode(inode, mode, rdev);
10647 +}
10648 +#endif
10649 +
10650 +/* finfo.c */
10651 +void au_hfput(struct au_hfile *hf, struct file *file);
10652 +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
10653 +                  struct file *h_file);
10654 +
10655 +void au_update_figen(struct file *file);
10656 +struct au_fidir *au_fidir_alloc(struct super_block *sb);
10657 +int au_fidir_realloc(struct au_finfo *finfo, int nbr);
10658 +
10659 +void au_fi_init_once(void *_fi);
10660 +void au_finfo_fin(struct file *file);
10661 +int au_finfo_init(struct file *file, struct au_fidir *fidir);
10662 +
10663 +/* ioctl.c */
10664 +long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
10665 +#ifdef CONFIG_COMPAT
10666 +long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
10667 +                          unsigned long arg);
10668 +#endif
10669 +
10670 +/* ---------------------------------------------------------------------- */
10671 +
10672 +static inline struct au_finfo *au_fi(struct file *file)
10673 +{
10674 +       return file->private_data;
10675 +}
10676 +
10677 +/* ---------------------------------------------------------------------- */
10678 +
10679 +/*
10680 + * fi_read_lock, fi_write_lock,
10681 + * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
10682 + */
10683 +AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
10684 +
10685 +#define FiMustNoWaiters(f)     AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
10686 +#define FiMustAnyLock(f)       AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
10687 +#define FiMustWriteLock(f)     AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
10688 +
10689 +/* ---------------------------------------------------------------------- */
10690 +
10691 +/* todo: hard/soft set? */
10692 +static inline aufs_bindex_t au_fbstart(struct file *file)
10693 +{
10694 +       FiMustAnyLock(file);
10695 +       return au_fi(file)->fi_btop;
10696 +}
10697 +
10698 +static inline aufs_bindex_t au_fbend_dir(struct file *file)
10699 +{
10700 +       FiMustAnyLock(file);
10701 +       AuDebugOn(!au_fi(file)->fi_hdir);
10702 +       return au_fi(file)->fi_hdir->fd_bbot;
10703 +}
10704 +
10705 +static inline struct au_vdir *au_fvdir_cache(struct file *file)
10706 +{
10707 +       FiMustAnyLock(file);
10708 +       AuDebugOn(!au_fi(file)->fi_hdir);
10709 +       return au_fi(file)->fi_hdir->fd_vdir_cache;
10710 +}
10711 +
10712 +static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
10713 +{
10714 +       FiMustWriteLock(file);
10715 +       au_fi(file)->fi_btop = bindex;
10716 +}
10717 +
10718 +static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
10719 +{
10720 +       FiMustWriteLock(file);
10721 +       AuDebugOn(!au_fi(file)->fi_hdir);
10722 +       au_fi(file)->fi_hdir->fd_bbot = bindex;
10723 +}
10724 +
10725 +static inline void au_set_fvdir_cache(struct file *file,
10726 +                                     struct au_vdir *vdir_cache)
10727 +{
10728 +       FiMustWriteLock(file);
10729 +       AuDebugOn(!au_fi(file)->fi_hdir);
10730 +       au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
10731 +}
10732 +
10733 +static inline struct file *au_hf_top(struct file *file)
10734 +{
10735 +       FiMustAnyLock(file);
10736 +       AuDebugOn(au_fi(file)->fi_hdir);
10737 +       return au_fi(file)->fi_htop.hf_file;
10738 +}
10739 +
10740 +static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
10741 +{
10742 +       FiMustAnyLock(file);
10743 +       AuDebugOn(!au_fi(file)->fi_hdir);
10744 +       return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
10745 +}
10746 +
10747 +/* todo: memory barrier? */
10748 +static inline unsigned int au_figen(struct file *f)
10749 +{
10750 +       return atomic_read(&au_fi(f)->fi_generation);
10751 +}
10752 +
10753 +static inline void au_set_mmapped(struct file *f)
10754 +{
10755 +       if (atomic_inc_return(&au_fi(f)->fi_mmapped))
10756 +               return;
10757 +       pr_warn("fi_mmapped wrapped around\n");
10758 +       while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
10759 +               ;
10760 +}
10761 +
10762 +static inline void au_unset_mmapped(struct file *f)
10763 +{
10764 +       atomic_dec(&au_fi(f)->fi_mmapped);
10765 +}
10766 +
10767 +static inline int au_test_mmapped(struct file *f)
10768 +{
10769 +       return atomic_read(&au_fi(f)->fi_mmapped);
10770 +}
10771 +
10772 +/* customize vma->vm_file */
10773 +
10774 +static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
10775 +                                      struct file *file)
10776 +{
10777 +       struct file *f;
10778 +
10779 +       f = vma->vm_file;
10780 +       get_file(file);
10781 +       vma->vm_file = file;
10782 +       fput(f);
10783 +}
10784 +
10785 +#ifdef CONFIG_MMU
10786 +#define AuDbgVmRegion(file, vma) do {} while (0)
10787 +
10788 +static inline void au_vm_file_reset(struct vm_area_struct *vma,
10789 +                                   struct file *file)
10790 +{
10791 +       au_do_vm_file_reset(vma, file);
10792 +}
10793 +#else
10794 +#define AuDbgVmRegion(file, vma) \
10795 +       AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
10796 +
10797 +static inline void au_vm_file_reset(struct vm_area_struct *vma,
10798 +                                   struct file *file)
10799 +{
10800 +       struct file *f;
10801 +
10802 +       au_do_vm_file_reset(vma, file);
10803 +       f = vma->vm_region->vm_file;
10804 +       get_file(file);
10805 +       vma->vm_region->vm_file = file;
10806 +       fput(f);
10807 +}
10808 +#endif /* CONFIG_MMU */
10809 +
10810 +/* handle vma->vm_prfile */
10811 +static inline void au_vm_prfile_set(struct vm_area_struct *vma,
10812 +                                   struct file *file)
10813 +{
10814 +#ifdef CONFIG_AUFS_PROC_MAP
10815 +       get_file(file);
10816 +       vma->vm_prfile = file;
10817 +#ifndef CONFIG_MMU
10818 +       get_file(file);
10819 +       vma->vm_region->vm_prfile = file;
10820 +#endif
10821 +#endif
10822 +}
10823 +
10824 +#endif /* __KERNEL__ */
10825 +#endif /* __AUFS_FILE_H__ */
10826 diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
10827 --- /usr/share/empty/fs/aufs/finfo.c    1970-01-01 01:00:00.000000000 +0100
10828 +++ linux/fs/aufs/finfo.c       2013-01-11 19:46:12.635947932 +0100
10829 @@ -0,0 +1,156 @@
10830 +/*
10831 + * Copyright (C) 2005-2013 Junjiro R. Okajima
10832 + *
10833 + * This program, aufs is free software; you can redistribute it and/or modify
10834 + * it under the terms of the GNU General Public License as published by
10835 + * the Free Software Foundation; either version 2 of the License, or
10836 + * (at your option) any later version.
10837 + *
10838 + * This program is distributed in the hope that it will be useful,
10839 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10840 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10841 + * GNU General Public License for more details.
10842 + *
10843 + * You should have received a copy of the GNU General Public License
10844 + * along with this program; if not, write to the Free Software
10845 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
10846 + */
10847 +
10848 +/*
10849 + * file private data
10850 + */
10851 +
10852 +#include "aufs.h"
10853 +
10854 +void au_hfput(struct au_hfile *hf, struct file *file)
10855 +{
10856 +       /* todo: direct access f_flags */
10857 +       if (vfsub_file_flags(file) & __FMODE_EXEC)
10858 +               allow_write_access(hf->hf_file);
10859 +       fput(hf->hf_file);
10860 +       hf->hf_file = NULL;
10861 +       atomic_dec(&hf->hf_br->br_count);
10862 +       hf->hf_br = NULL;
10863 +}
10864 +
10865 +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
10866 +{
10867 +       struct au_finfo *finfo = au_fi(file);
10868 +       struct au_hfile *hf;
10869 +       struct au_fidir *fidir;
10870 +
10871 +       fidir = finfo->fi_hdir;
10872 +       if (!fidir) {
10873 +               AuDebugOn(finfo->fi_btop != bindex);
10874 +               hf = &finfo->fi_htop;
10875 +       } else
10876 +               hf = fidir->fd_hfile + bindex;
10877 +
10878 +       if (hf && hf->hf_file)
10879 +               au_hfput(hf, file);
10880 +       if (val) {
10881 +               FiMustWriteLock(file);
10882 +               hf->hf_file = val;
10883 +               hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
10884 +       }
10885 +}
10886 +
10887 +void au_update_figen(struct file *file)
10888 +{
10889 +       atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
10890 +       /* smp_mb(); */ /* atomic_set */
10891 +}
10892 +
10893 +/* ---------------------------------------------------------------------- */
10894 +
10895 +struct au_fidir *au_fidir_alloc(struct super_block *sb)
10896 +{
10897 +       struct au_fidir *fidir;
10898 +       int nbr;
10899 +
10900 +       nbr = au_sbend(sb) + 1;
10901 +       if (nbr < 2)
10902 +               nbr = 2; /* initial allocate for 2 branches */
10903 +       fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
10904 +       if (fidir) {
10905 +               fidir->fd_bbot = -1;
10906 +               fidir->fd_nent = nbr;
10907 +               fidir->fd_vdir_cache = NULL;
10908 +       }
10909 +
10910 +       return fidir;
10911 +}
10912 +
10913 +int au_fidir_realloc(struct au_finfo *finfo, int nbr)
10914 +{
10915 +       int err;
10916 +       struct au_fidir *fidir, *p;
10917 +
10918 +       AuRwMustWriteLock(&finfo->fi_rwsem);
10919 +       fidir = finfo->fi_hdir;
10920 +       AuDebugOn(!fidir);
10921 +
10922 +       err = -ENOMEM;
10923 +       p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
10924 +                        GFP_NOFS);
10925 +       if (p) {
10926 +               p->fd_nent = nbr;
10927 +               finfo->fi_hdir = p;
10928 +               err = 0;
10929 +       }
10930 +
10931 +       return err;
10932 +}
10933 +
10934 +/* ---------------------------------------------------------------------- */
10935 +
10936 +void au_finfo_fin(struct file *file)
10937 +{
10938 +       struct au_finfo *finfo;
10939 +
10940 +       au_nfiles_dec(file->f_dentry->d_sb);
10941 +
10942 +       finfo = au_fi(file);
10943 +       AuDebugOn(finfo->fi_hdir);
10944 +       AuRwDestroy(&finfo->fi_rwsem);
10945 +       au_cache_free_finfo(finfo);
10946 +}
10947 +
10948 +void au_fi_init_once(void *_finfo)
10949 +{
10950 +       struct au_finfo *finfo = _finfo;
10951 +       static struct lock_class_key aufs_fi;
10952 +
10953 +       au_rw_init(&finfo->fi_rwsem);
10954 +       au_rw_class(&finfo->fi_rwsem, &aufs_fi);
10955 +}
10956 +
10957 +int au_finfo_init(struct file *file, struct au_fidir *fidir)
10958 +{
10959 +       int err, lc_idx;
10960 +       struct au_finfo *finfo;
10961 +       struct dentry *dentry;
10962 +
10963 +       err = -ENOMEM;
10964 +       dentry = file->f_dentry;
10965 +       finfo = au_cache_alloc_finfo();
10966 +       if (unlikely(!finfo))
10967 +               goto out;
10968 +
10969 +       err = 0;
10970 +       au_nfiles_inc(dentry->d_sb);
10971 +       lc_idx = AuLcNonDir_FIINFO;
10972 +       if (fidir)
10973 +               lc_idx = AuLcDir_FIINFO;
10974 +       au_rw_class(&finfo->fi_rwsem, au_lc_key + lc_idx);
10975 +       au_rw_write_lock(&finfo->fi_rwsem);
10976 +       finfo->fi_btop = -1;
10977 +       finfo->fi_hdir = fidir;
10978 +       atomic_set(&finfo->fi_generation, au_digen(dentry));
10979 +       /* smp_mb(); */ /* atomic_set */
10980 +
10981 +       file->private_data = finfo;
10982 +
10983 +out:
10984 +       return err;
10985 +}
10986 diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
10987 --- /usr/share/empty/fs/aufs/f_op.c     1970-01-01 01:00:00.000000000 +0100
10988 +++ linux/fs/aufs/f_op.c        2013-01-11 19:46:28.699667650 +0100
10989 @@ -0,0 +1,723 @@
10990 +/*
10991 + * Copyright (C) 2005-2013 Junjiro R. Okajima
10992 + *
10993 + * This program, aufs is free software; you can redistribute it and/or modify
10994 + * it under the terms of the GNU General Public License as published by
10995 + * the Free Software Foundation; either version 2 of the License, or
10996 + * (at your option) any later version.
10997 + *
10998 + * This program is distributed in the hope that it will be useful,
10999 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11000 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11001 + * GNU General Public License for more details.
11002 + *
11003 + * You should have received a copy of the GNU General Public License
11004 + * along with this program; if not, write to the Free Software
11005 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
11006 + */
11007 +
11008 +/*
11009 + * file and vm operations
11010 + */
11011 +
11012 +#include <linux/fs_stack.h>
11013 +#include <linux/mman.h>
11014 +#include <linux/security.h>
11015 +#include "aufs.h"
11016 +
11017 +int au_do_open_nondir(struct file *file, int flags)
11018 +{
11019 +       int err;
11020 +       aufs_bindex_t bindex;
11021 +       struct file *h_file;
11022 +       struct dentry *dentry;
11023 +       struct au_finfo *finfo;
11024 +
11025 +       FiMustWriteLock(file);
11026 +
11027 +       dentry = file->f_dentry;
11028 +       err = au_d_alive(dentry);
11029 +       if (unlikely(err))
11030 +               goto out;
11031 +
11032 +       finfo = au_fi(file);
11033 +       memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
11034 +       atomic_set(&finfo->fi_mmapped, 0);
11035 +       bindex = au_dbstart(dentry);
11036 +       h_file = au_h_open(dentry, bindex, flags, file);
11037 +       if (IS_ERR(h_file))
11038 +               err = PTR_ERR(h_file);
11039 +       else {
11040 +               au_set_fbstart(file, bindex);
11041 +               au_set_h_fptr(file, bindex, h_file);
11042 +               au_update_figen(file);
11043 +               /* todo: necessary? */
11044 +               /* file->f_ra = h_file->f_ra; */
11045 +       }
11046 +
11047 +out:
11048 +       return err;
11049 +}
11050 +
11051 +static int aufs_open_nondir(struct inode *inode __maybe_unused,
11052 +                           struct file *file)
11053 +{
11054 +       int err;
11055 +       struct super_block *sb;
11056 +
11057 +       AuDbg("%.*s, f_flags 0x%x, f_mode 0x%x\n",
11058 +             AuDLNPair(file->f_dentry), vfsub_file_flags(file),
11059 +             file->f_mode);
11060 +
11061 +       sb = file->f_dentry->d_sb;
11062 +       si_read_lock(sb, AuLock_FLUSH);
11063 +       err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
11064 +       si_read_unlock(sb);
11065 +       return err;
11066 +}
11067 +
11068 +int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
11069 +{
11070 +       struct au_finfo *finfo;
11071 +       aufs_bindex_t bindex;
11072 +
11073 +       finfo = au_fi(file);
11074 +       bindex = finfo->fi_btop;
11075 +       if (bindex >= 0)
11076 +               au_set_h_fptr(file, bindex, NULL);
11077 +
11078 +       au_finfo_fin(file);
11079 +       return 0;
11080 +}
11081 +
11082 +/* ---------------------------------------------------------------------- */
11083 +
11084 +static int au_do_flush_nondir(struct file *file, fl_owner_t id)
11085 +{
11086 +       int err;
11087 +       struct file *h_file;
11088 +
11089 +       err = 0;
11090 +       h_file = au_hf_top(file);
11091 +       if (h_file)
11092 +               err = vfsub_flush(h_file, id);
11093 +       return err;
11094 +}
11095 +
11096 +static int aufs_flush_nondir(struct file *file, fl_owner_t id)
11097 +{
11098 +       return au_do_flush(file, id, au_do_flush_nondir);
11099 +}
11100 +
11101 +/* ---------------------------------------------------------------------- */
11102 +/*
11103 + * read and write functions acquire [fdi]_rwsem once, but release before
11104 + * mmap_sem. This is because to stop a race condition between mmap(2).
11105 + * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
11106 + * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
11107 + * read functions after [fdi]_rwsem are released, but it should be harmless.
11108 + */
11109 +
11110 +static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
11111 +                        loff_t *ppos)
11112 +{
11113 +       ssize_t err;
11114 +       struct dentry *dentry;
11115 +       struct file *h_file;
11116 +       struct super_block *sb;
11117 +
11118 +       dentry = file->f_dentry;
11119 +       sb = dentry->d_sb;
11120 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11121 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11122 +       if (unlikely(err))
11123 +               goto out;
11124 +
11125 +       h_file = au_hf_top(file);
11126 +       get_file(h_file);
11127 +       di_read_unlock(dentry, AuLock_IR);
11128 +       fi_read_unlock(file);
11129 +
11130 +       /* filedata may be obsoleted by concurrent copyup, but no problem */
11131 +       err = vfsub_read_u(h_file, buf, count, ppos);
11132 +       /* todo: necessary? */
11133 +       /* file->f_ra = h_file->f_ra; */
11134 +       /* update without lock, I don't think it a problem */
11135 +       fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
11136 +       fput(h_file);
11137 +
11138 +out:
11139 +       si_read_unlock(sb);
11140 +       return err;
11141 +}
11142 +
11143 +/*
11144 + * todo: very ugly
11145 + * it locks both of i_mutex and si_rwsem for read in safe.
11146 + * if the plink maintenance mode continues forever (that is the problem),
11147 + * may loop forever.
11148 + */
11149 +static void au_mtx_and_read_lock(struct inode *inode)
11150 +{
11151 +       int err;
11152 +       struct super_block *sb = inode->i_sb;
11153 +
11154 +       while (1) {
11155 +               mutex_lock(&inode->i_mutex);
11156 +               err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11157 +               if (!err)
11158 +                       break;
11159 +               mutex_unlock(&inode->i_mutex);
11160 +               si_read_lock(sb, AuLock_NOPLMW);
11161 +               si_read_unlock(sb);
11162 +       }
11163 +}
11164 +
11165 +static ssize_t aufs_write(struct file *file, const char __user *ubuf,
11166 +                         size_t count, loff_t *ppos)
11167 +{
11168 +       ssize_t err;
11169 +       struct au_pin pin;
11170 +       struct dentry *dentry;
11171 +       struct super_block *sb;
11172 +       struct inode *inode;
11173 +       struct file *h_file;
11174 +       char __user *buf = (char __user *)ubuf;
11175 +
11176 +       dentry = file->f_dentry;
11177 +       sb = dentry->d_sb;
11178 +       inode = dentry->d_inode;
11179 +       au_mtx_and_read_lock(inode);
11180 +
11181 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11182 +       if (unlikely(err))
11183 +               goto out;
11184 +
11185 +       err = au_ready_to_write(file, -1, &pin);
11186 +       di_downgrade_lock(dentry, AuLock_IR);
11187 +       if (unlikely(err)) {
11188 +               di_read_unlock(dentry, AuLock_IR);
11189 +               fi_write_unlock(file);
11190 +               goto out;
11191 +       }
11192 +
11193 +       h_file = au_hf_top(file);
11194 +       get_file(h_file);
11195 +       au_unpin(&pin);
11196 +       di_read_unlock(dentry, AuLock_IR);
11197 +       fi_write_unlock(file);
11198 +
11199 +       err = vfsub_write_u(h_file, buf, count, ppos);
11200 +       ii_write_lock_child(inode);
11201 +       au_cpup_attr_timesizes(inode);
11202 +       inode->i_mode = h_file->f_dentry->d_inode->i_mode;
11203 +       ii_write_unlock(inode);
11204 +       fput(h_file);
11205 +
11206 +out:
11207 +       si_read_unlock(sb);
11208 +       mutex_unlock(&inode->i_mutex);
11209 +       return err;
11210 +}
11211 +
11212 +static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
11213 +                        const struct iovec *iov, unsigned long nv, loff_t pos)
11214 +{
11215 +       ssize_t err;
11216 +       struct file *file;
11217 +       ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
11218 +                       loff_t);
11219 +
11220 +       err = security_file_permission(h_file, rw);
11221 +       if (unlikely(err))
11222 +               goto out;
11223 +
11224 +       err = -ENOSYS;
11225 +       func = NULL;
11226 +       if (rw == MAY_READ)
11227 +               func = h_file->f_op->aio_read;
11228 +       else if (rw == MAY_WRITE)
11229 +               func = h_file->f_op->aio_write;
11230 +       if (func) {
11231 +               file = kio->ki_filp;
11232 +               kio->ki_filp = h_file;
11233 +               lockdep_off();
11234 +               err = func(kio, iov, nv, pos);
11235 +               lockdep_on();
11236 +               kio->ki_filp = file;
11237 +       } else
11238 +               /* currently there is no such fs */
11239 +               WARN_ON_ONCE(1);
11240 +
11241 +out:
11242 +       return err;
11243 +}
11244 +
11245 +static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
11246 +                            unsigned long nv, loff_t pos)
11247 +{
11248 +       ssize_t err;
11249 +       struct file *file, *h_file;
11250 +       struct dentry *dentry;
11251 +       struct super_block *sb;
11252 +
11253 +       file = kio->ki_filp;
11254 +       dentry = file->f_dentry;
11255 +       sb = dentry->d_sb;
11256 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11257 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11258 +       if (unlikely(err))
11259 +               goto out;
11260 +
11261 +       h_file = au_hf_top(file);
11262 +       get_file(h_file);
11263 +       di_read_unlock(dentry, AuLock_IR);
11264 +       fi_read_unlock(file);
11265 +
11266 +       err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
11267 +       /* todo: necessary? */
11268 +       /* file->f_ra = h_file->f_ra; */
11269 +       /* update without lock, I don't think it a problem */
11270 +       fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
11271 +       fput(h_file);
11272 +
11273 +out:
11274 +       si_read_unlock(sb);
11275 +       return err;
11276 +}
11277 +
11278 +static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
11279 +                             unsigned long nv, loff_t pos)
11280 +{
11281 +       ssize_t err;
11282 +       struct au_pin pin;
11283 +       struct dentry *dentry;
11284 +       struct inode *inode;
11285 +       struct file *file, *h_file;
11286 +       struct super_block *sb;
11287 +
11288 +       file = kio->ki_filp;
11289 +       dentry = file->f_dentry;
11290 +       sb = dentry->d_sb;
11291 +       inode = dentry->d_inode;
11292 +       au_mtx_and_read_lock(inode);
11293 +
11294 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11295 +       if (unlikely(err))
11296 +               goto out;
11297 +
11298 +       err = au_ready_to_write(file, -1, &pin);
11299 +       di_downgrade_lock(dentry, AuLock_IR);
11300 +       if (unlikely(err)) {
11301 +               di_read_unlock(dentry, AuLock_IR);
11302 +               fi_write_unlock(file);
11303 +               goto out;
11304 +       }
11305 +
11306 +       h_file = au_hf_top(file);
11307 +       get_file(h_file);
11308 +       au_unpin(&pin);
11309 +       di_read_unlock(dentry, AuLock_IR);
11310 +       fi_write_unlock(file);
11311 +
11312 +       err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
11313 +       ii_write_lock_child(inode);
11314 +       au_cpup_attr_timesizes(inode);
11315 +       inode->i_mode = h_file->f_dentry->d_inode->i_mode;
11316 +       ii_write_unlock(inode);
11317 +       fput(h_file);
11318 +
11319 +out:
11320 +       si_read_unlock(sb);
11321 +       mutex_unlock(&inode->i_mutex);
11322 +       return err;
11323 +}
11324 +
11325 +static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
11326 +                               struct pipe_inode_info *pipe, size_t len,
11327 +                               unsigned int flags)
11328 +{
11329 +       ssize_t err;
11330 +       struct file *h_file;
11331 +       struct dentry *dentry;
11332 +       struct super_block *sb;
11333 +
11334 +       dentry = file->f_dentry;
11335 +       sb = dentry->d_sb;
11336 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11337 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11338 +       if (unlikely(err))
11339 +               goto out;
11340 +
11341 +       err = -EINVAL;
11342 +       h_file = au_hf_top(file);
11343 +       get_file(h_file);
11344 +       if (au_test_loopback_kthread()) {
11345 +               au_warn_loopback(h_file->f_dentry->d_sb);
11346 +               if (file->f_mapping != h_file->f_mapping) {
11347 +                       file->f_mapping = h_file->f_mapping;
11348 +                       smp_mb(); /* unnecessary? */
11349 +               }
11350 +       }
11351 +       di_read_unlock(dentry, AuLock_IR);
11352 +       fi_read_unlock(file);
11353 +
11354 +       err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
11355 +       /* todo: necessasry? */
11356 +       /* file->f_ra = h_file->f_ra; */
11357 +       /* update without lock, I don't think it a problem */
11358 +       fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode);
11359 +       fput(h_file);
11360 +
11361 +out:
11362 +       si_read_unlock(sb);
11363 +       return err;
11364 +}
11365 +
11366 +static ssize_t
11367 +aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
11368 +                 size_t len, unsigned int flags)
11369 +{
11370 +       ssize_t err;
11371 +       struct au_pin pin;
11372 +       struct dentry *dentry;
11373 +       struct inode *inode;
11374 +       struct file *h_file;
11375 +       struct super_block *sb;
11376 +
11377 +       dentry = file->f_dentry;
11378 +       sb = dentry->d_sb;
11379 +       inode = dentry->d_inode;
11380 +       au_mtx_and_read_lock(inode);
11381 +
11382 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11383 +       if (unlikely(err))
11384 +               goto out;
11385 +
11386 +       err = au_ready_to_write(file, -1, &pin);
11387 +       di_downgrade_lock(dentry, AuLock_IR);
11388 +       if (unlikely(err)) {
11389 +               di_read_unlock(dentry, AuLock_IR);
11390 +               fi_write_unlock(file);
11391 +               goto out;
11392 +       }
11393 +
11394 +       h_file = au_hf_top(file);
11395 +       get_file(h_file);
11396 +       au_unpin(&pin);
11397 +       di_read_unlock(dentry, AuLock_IR);
11398 +       fi_write_unlock(file);
11399 +
11400 +       err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
11401 +       ii_write_lock_child(inode);
11402 +       au_cpup_attr_timesizes(inode);
11403 +       inode->i_mode = h_file->f_dentry->d_inode->i_mode;
11404 +       ii_write_unlock(inode);
11405 +       fput(h_file);
11406 +
11407 +out:
11408 +       si_read_unlock(sb);
11409 +       mutex_unlock(&inode->i_mutex);
11410 +       return err;
11411 +}
11412 +
11413 +/* ---------------------------------------------------------------------- */
11414 +
11415 +/*
11416 + * The locking order around current->mmap_sem.
11417 + * - in most and regular cases
11418 + *   file I/O syscall -- aufs_read() or something
11419 + *     -- si_rwsem for read -- mmap_sem
11420 + *     (Note that [fdi]i_rwsem are released before mmap_sem).
11421 + * - in mmap case
11422 + *   mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
11423 + * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
11424 + * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
11425 + * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
11426 + * It means that when aufs acquires si_rwsem for write, the process should never
11427 + * acquire mmap_sem.
11428 + *
11429 + * Actually aufs_readdir() holds [fdi]i_rwsem before mmap_sem, but this is not a
11430 + * problem either since any directory is not able to be mmap-ed.
11431 + * The similar scenario is applied to aufs_readlink() too.
11432 + */
11433 +
11434 +/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
11435 +#define AuConv_VM_PROT(f, b)   _calc_vm_trans(f, VM_##b, PROT_##b)
11436 +
11437 +static unsigned long au_arch_prot_conv(unsigned long flags)
11438 +{
11439 +       /* currently ppc64 only */
11440 +#ifdef CONFIG_PPC64
11441 +       /* cf. linux/arch/powerpc/include/asm/mman.h */
11442 +       AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
11443 +       return AuConv_VM_PROT(flags, SAO);
11444 +#else
11445 +       AuDebugOn(arch_calc_vm_prot_bits(-1));
11446 +       return 0;
11447 +#endif
11448 +}
11449 +
11450 +static unsigned long au_prot_conv(unsigned long flags)
11451 +{
11452 +       return AuConv_VM_PROT(flags, READ)
11453 +               | AuConv_VM_PROT(flags, WRITE)
11454 +               | AuConv_VM_PROT(flags, EXEC)
11455 +               | au_arch_prot_conv(flags);
11456 +}
11457 +
11458 +/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
11459 +#define AuConv_VM_MAP(f, b)    _calc_vm_trans(f, VM_##b, MAP_##b)
11460 +
11461 +static unsigned long au_flag_conv(unsigned long flags)
11462 +{
11463 +       return AuConv_VM_MAP(flags, GROWSDOWN)
11464 +               | AuConv_VM_MAP(flags, DENYWRITE)
11465 +               | AuConv_VM_MAP(flags, LOCKED);
11466 +}
11467 +
11468 +static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
11469 +{
11470 +       int err;
11471 +       aufs_bindex_t bstart;
11472 +       const unsigned char wlock
11473 +               = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
11474 +       struct dentry *dentry;
11475 +       struct super_block *sb;
11476 +       struct file *h_file;
11477 +       struct au_branch *br;
11478 +       struct au_pin pin;
11479 +
11480 +       AuDbgVmRegion(file, vma);
11481 +
11482 +       dentry = file->f_dentry;
11483 +       sb = dentry->d_sb;
11484 +       lockdep_off();
11485 +       si_read_lock(sb, AuLock_NOPLMW);
11486 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11487 +       if (unlikely(err))
11488 +               goto out;
11489 +
11490 +       if (wlock) {
11491 +               err = au_ready_to_write(file, -1, &pin);
11492 +               di_write_unlock(dentry);
11493 +               if (unlikely(err)) {
11494 +                       fi_write_unlock(file);
11495 +                       goto out;
11496 +               }
11497 +               au_unpin(&pin);
11498 +       } else
11499 +               di_write_unlock(dentry);
11500 +
11501 +       bstart = au_fbstart(file);
11502 +       br = au_sbr(sb, bstart);
11503 +       h_file = au_hf_top(file);
11504 +       get_file(h_file);
11505 +       au_set_mmapped(file);
11506 +       fi_write_unlock(file);
11507 +       lockdep_on();
11508 +
11509 +       au_vm_file_reset(vma, h_file);
11510 +       err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
11511 +                                au_flag_conv(vma->vm_flags));
11512 +       if (!err)
11513 +               err = h_file->f_op->mmap(h_file, vma);
11514 +       if (unlikely(err))
11515 +               goto out_reset;
11516 +
11517 +       au_vm_prfile_set(vma, file);
11518 +       /* update without lock, I don't think it a problem */
11519 +       fsstack_copy_attr_atime(file->f_dentry->d_inode,
11520 +                               h_file->f_dentry->d_inode);
11521 +       goto out_fput; /* success */
11522 +
11523 +out_reset:
11524 +       au_unset_mmapped(file);
11525 +       au_vm_file_reset(vma, file);
11526 +out_fput:
11527 +       fput(h_file);
11528 +       lockdep_off();
11529 +out:
11530 +       si_read_unlock(sb);
11531 +       lockdep_on();
11532 +       AuTraceErr(err);
11533 +       return err;
11534 +}
11535 +
11536 +/* ---------------------------------------------------------------------- */
11537 +
11538 +static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
11539 +                            int datasync)
11540 +{
11541 +       int err;
11542 +       struct au_pin pin;
11543 +       struct dentry *dentry;
11544 +       struct inode *inode;
11545 +       struct file *h_file;
11546 +       struct super_block *sb;
11547 +
11548 +       dentry = file->f_dentry;
11549 +       inode = dentry->d_inode;
11550 +       sb = dentry->d_sb;
11551 +       mutex_lock(&inode->i_mutex);
11552 +       err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11553 +       if (unlikely(err))
11554 +               goto out;
11555 +
11556 +       err = 0; /* -EBADF; */ /* posix? */
11557 +       if (unlikely(!(file->f_mode & FMODE_WRITE)))
11558 +               goto out_si;
11559 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11560 +       if (unlikely(err))
11561 +               goto out_si;
11562 +
11563 +       err = au_ready_to_write(file, -1, &pin);
11564 +       di_downgrade_lock(dentry, AuLock_IR);
11565 +       if (unlikely(err))
11566 +               goto out_unlock;
11567 +       au_unpin(&pin);
11568 +
11569 +       err = -EINVAL;
11570 +       h_file = au_hf_top(file);
11571 +       err = vfsub_fsync(h_file, &h_file->f_path, datasync);
11572 +       au_cpup_attr_timesizes(inode);
11573 +
11574 +out_unlock:
11575 +       di_read_unlock(dentry, AuLock_IR);
11576 +       fi_write_unlock(file);
11577 +out_si:
11578 +       si_read_unlock(sb);
11579 +out:
11580 +       mutex_unlock(&inode->i_mutex);
11581 +       return err;
11582 +}
11583 +
11584 +/* no one supports this operation, currently */
11585 +#if 0
11586 +static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
11587 +{
11588 +       int err;
11589 +       struct au_pin pin;
11590 +       struct dentry *dentry;
11591 +       struct inode *inode;
11592 +       struct file *file, *h_file;
11593 +
11594 +       file = kio->ki_filp;
11595 +       dentry = file->f_dentry;
11596 +       inode = dentry->d_inode;
11597 +       au_mtx_and_read_lock(inode);
11598 +
11599 +       err = 0; /* -EBADF; */ /* posix? */
11600 +       if (unlikely(!(file->f_mode & FMODE_WRITE)))
11601 +               goto out;
11602 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11603 +       if (unlikely(err))
11604 +               goto out;
11605 +
11606 +       err = au_ready_to_write(file, -1, &pin);
11607 +       di_downgrade_lock(dentry, AuLock_IR);
11608 +       if (unlikely(err))
11609 +               goto out_unlock;
11610 +       au_unpin(&pin);
11611 +
11612 +       err = -ENOSYS;
11613 +       h_file = au_hf_top(file);
11614 +       if (h_file->f_op && h_file->f_op->aio_fsync) {
11615 +               struct dentry *h_d;
11616 +               struct mutex *h_mtx;
11617 +
11618 +               h_d = h_file->f_dentry;
11619 +               h_mtx = &h_d->d_inode->i_mutex;
11620 +               if (!is_sync_kiocb(kio)) {
11621 +                       get_file(h_file);
11622 +                       fput(file);
11623 +               }
11624 +               kio->ki_filp = h_file;
11625 +               err = h_file->f_op->aio_fsync(kio, datasync);
11626 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
11627 +               if (!err)
11628 +                       vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
11629 +               /*ignore*/
11630 +               au_cpup_attr_timesizes(inode);
11631 +               mutex_unlock(h_mtx);
11632 +       }
11633 +
11634 +out_unlock:
11635 +       di_read_unlock(dentry, AuLock_IR);
11636 +       fi_write_unlock(file);
11637 +out:
11638 +       si_read_unlock(inode->sb);
11639 +       mutex_unlock(&inode->i_mutex);
11640 +       return err;
11641 +}
11642 +#endif
11643 +
11644 +static int aufs_fasync(int fd, struct file *file, int flag)
11645 +{
11646 +       int err;
11647 +       struct file *h_file;
11648 +       struct dentry *dentry;
11649 +       struct super_block *sb;
11650 +
11651 +       dentry = file->f_dentry;
11652 +       sb = dentry->d_sb;
11653 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11654 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11655 +       if (unlikely(err))
11656 +               goto out;
11657 +
11658 +       h_file = au_hf_top(file);
11659 +       if (h_file->f_op && h_file->f_op->fasync)
11660 +               err = h_file->f_op->fasync(fd, h_file, flag);
11661 +
11662 +       di_read_unlock(dentry, AuLock_IR);
11663 +       fi_read_unlock(file);
11664 +
11665 +out:
11666 +       si_read_unlock(sb);
11667 +       return err;
11668 +}
11669 +
11670 +/* ---------------------------------------------------------------------- */
11671 +
11672 +/* no one supports this operation, currently */
11673 +#if 0
11674 +static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
11675 +                            size_t len, loff_t *pos , int more)
11676 +{
11677 +}
11678 +#endif
11679 +
11680 +/* ---------------------------------------------------------------------- */
11681 +
11682 +const struct file_operations aufs_file_fop = {
11683 +       .owner          = THIS_MODULE,
11684 +
11685 +       .llseek         = default_llseek,
11686 +
11687 +       .read           = aufs_read,
11688 +       .write          = aufs_write,
11689 +       .aio_read       = aufs_aio_read,
11690 +       .aio_write      = aufs_aio_write,
11691 +#ifdef CONFIG_AUFS_POLL
11692 +       .poll           = aufs_poll,
11693 +#endif
11694 +       .unlocked_ioctl = aufs_ioctl_nondir,
11695 +#ifdef CONFIG_COMPAT
11696 +       .compat_ioctl   = aufs_ioctl_nondir, /* same */
11697 +#endif
11698 +       .mmap           = aufs_mmap,
11699 +       .open           = aufs_open_nondir,
11700 +       .flush          = aufs_flush_nondir,
11701 +       .release        = aufs_release_nondir,
11702 +       .fsync          = aufs_fsync_nondir,
11703 +       /* .aio_fsync   = aufs_aio_fsync_nondir, */
11704 +       .fasync         = aufs_fasync,
11705 +       /* .sendpage    = aufs_sendpage, */
11706 +       .splice_write   = aufs_splice_write,
11707 +       .splice_read    = aufs_splice_read,
11708 +#if 0
11709 +       .aio_splice_write = aufs_aio_splice_write,
11710 +       .aio_splice_read  = aufs_aio_splice_read
11711 +#endif
11712 +};
11713 diff -urN /usr/share/empty/fs/aufs/f_op_sp.c linux/fs/aufs/f_op_sp.c
11714 --- /usr/share/empty/fs/aufs/f_op_sp.c  1970-01-01 01:00:00.000000000 +0100
11715 +++ linux/fs/aufs/f_op_sp.c     2013-01-11 19:46:12.635947932 +0100
11716 @@ -0,0 +1,295 @@
11717 +/*
11718 + * Copyright (C) 2005-2013 Junjiro R. Okajima
11719 + *
11720 + * This program, aufs is free software; you can redistribute it and/or modify
11721 + * it under the terms of the GNU General Public License as published by
11722 + * the Free Software Foundation; either version 2 of the License, or
11723 + * (at your option) any later version.
11724 + *
11725 + * This program is distributed in the hope that it will be useful,
11726 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11727 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11728 + * GNU General Public License for more details.
11729 + *
11730 + * You should have received a copy of the GNU General Public License
11731 + * along with this program; if not, write to the Free Software
11732 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
11733 + */
11734 +
11735 +/*
11736 + * file operations for special files.
11737 + * while they exist in aufs virtually,
11738 + * their file I/O is handled out of aufs.
11739 + */
11740 +
11741 +#include "aufs.h"
11742 +
11743 +static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
11744 +                               unsigned long nv, loff_t pos)
11745 +{
11746 +       ssize_t err;
11747 +       aufs_bindex_t bstart;
11748 +       unsigned char wbr;
11749 +       struct file *file, *h_file;
11750 +       struct super_block *sb;
11751 +
11752 +       file = kio->ki_filp;
11753 +       sb = file->f_dentry->d_sb;
11754 +       si_read_lock(sb, AuLock_FLUSH);
11755 +       fi_read_lock(file);
11756 +       bstart = au_fbstart(file);
11757 +       h_file = au_hf_top(file);
11758 +       fi_read_unlock(file);
11759 +       wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
11760 +       si_read_unlock(sb);
11761 +
11762 +       /* do not change the file in kio */
11763 +       AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
11764 +       err = h_file->f_op->aio_read(kio, iov, nv, pos);
11765 +       if (err > 0 && wbr)
11766 +               file_accessed(h_file);
11767 +
11768 +       return err;
11769 +}
11770 +
11771 +static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
11772 +                                unsigned long nv, loff_t pos)
11773 +{
11774 +       ssize_t err;
11775 +       aufs_bindex_t bstart;
11776 +       unsigned char wbr;
11777 +       struct super_block *sb;
11778 +       struct file *file, *h_file;
11779 +
11780 +       file = kio->ki_filp;
11781 +       sb = file->f_dentry->d_sb;
11782 +       si_read_lock(sb, AuLock_FLUSH);
11783 +       fi_read_lock(file);
11784 +       bstart = au_fbstart(file);
11785 +       h_file = au_hf_top(file);
11786 +       fi_read_unlock(file);
11787 +       wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
11788 +       si_read_unlock(sb);
11789 +
11790 +       /* do not change the file in kio */
11791 +       AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
11792 +       err = h_file->f_op->aio_write(kio, iov, nv, pos);
11793 +       return err;
11794 +}
11795 +
11796 +/* ---------------------------------------------------------------------- */
11797 +
11798 +static int aufs_release_sp(struct inode *inode, struct file *file)
11799 +{
11800 +       int err;
11801 +       struct file *h_file;
11802 +
11803 +       fi_read_lock(file);
11804 +       h_file = au_hf_top(file);
11805 +       fi_read_unlock(file);
11806 +       /* close this fifo in aufs */
11807 +       err = h_file->f_op->release(inode, file); /* ignore */
11808 +       aufs_release_nondir(inode, file); /* ignore */
11809 +       return err;
11810 +}
11811 +
11812 +/* ---------------------------------------------------------------------- */
11813 +
11814 +/* currently, support only FIFO */
11815 +enum {
11816 +       AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
11817 +       /* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
11818 +       AuSp_Last
11819 +};
11820 +static int aufs_open_sp(struct inode *inode, struct file *file);
11821 +static struct au_sp_fop {
11822 +       int                     done;
11823 +       struct file_operations  fop;    /* not 'const' */
11824 +       spinlock_t              spin;
11825 +} au_sp_fop[AuSp_Last] = {
11826 +       [AuSp_FIFO] = {
11827 +               .fop    = {
11828 +                       .owner  = THIS_MODULE,
11829 +                       .open   = aufs_open_sp
11830 +               }
11831 +       }
11832 +};
11833 +
11834 +static void au_init_fop_sp(struct file *file)
11835 +{
11836 +       struct au_sp_fop *p;
11837 +       int i;
11838 +       struct file *h_file;
11839 +
11840 +       p = au_sp_fop;
11841 +       if (unlikely(!p->done)) {
11842 +               /* initialize first time only */
11843 +               static DEFINE_SPINLOCK(spin);
11844 +
11845 +               spin_lock(&spin);
11846 +               if (!p->done) {
11847 +                       BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
11848 +                                    != AuSp_Last);
11849 +                       for (i = 0; i < AuSp_Last; i++)
11850 +                               spin_lock_init(&p[i].spin);
11851 +                       p->done = 1;
11852 +               }
11853 +               spin_unlock(&spin);
11854 +       }
11855 +
11856 +       switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
11857 +       case FMODE_READ:
11858 +               i = AuSp_FIFO_R;
11859 +               break;
11860 +       case FMODE_WRITE:
11861 +               i = AuSp_FIFO_W;
11862 +               break;
11863 +       case FMODE_READ | FMODE_WRITE:
11864 +               i = AuSp_FIFO_RW;
11865 +               break;
11866 +       default:
11867 +               BUG();
11868 +       }
11869 +
11870 +       p += i;
11871 +       if (unlikely(!p->done)) {
11872 +               /* initialize first time only */
11873 +               h_file = au_hf_top(file);
11874 +               spin_lock(&p->spin);
11875 +               if (!p->done) {
11876 +                       p->fop = *h_file->f_op;
11877 +                       p->fop.owner = THIS_MODULE;
11878 +                       if (p->fop.aio_read)
11879 +                               p->fop.aio_read = aufs_aio_read_sp;
11880 +                       if (p->fop.aio_write)
11881 +                               p->fop.aio_write = aufs_aio_write_sp;
11882 +                       p->fop.release = aufs_release_sp;
11883 +                       p->done = 1;
11884 +               }
11885 +               spin_unlock(&p->spin);
11886 +       }
11887 +       file->f_op = &p->fop;
11888 +}
11889 +
11890 +static int au_cpup_sp(struct dentry *dentry)
11891 +{
11892 +       int err;
11893 +       aufs_bindex_t bcpup;
11894 +       struct au_pin pin;
11895 +       struct au_wr_dir_args wr_dir_args = {
11896 +               .force_btgt     = -1,
11897 +               .flags          = 0
11898 +       };
11899 +
11900 +       AuDbg("%.*s\n", AuDLNPair(dentry));
11901 +
11902 +       di_read_unlock(dentry, AuLock_IR);
11903 +       di_write_lock_child(dentry);
11904 +       err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
11905 +       if (unlikely(err < 0))
11906 +               goto out;
11907 +       bcpup = err;
11908 +       err = 0;
11909 +       if (bcpup == au_dbstart(dentry))
11910 +               goto out; /* success */
11911 +
11912 +       err = au_pin(&pin, dentry, bcpup, au_opt_udba(dentry->d_sb),
11913 +                    AuPin_MNT_WRITE);
11914 +       if (!err) {
11915 +               err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME);
11916 +               au_unpin(&pin);
11917 +       }
11918 +
11919 +out:
11920 +       di_downgrade_lock(dentry, AuLock_IR);
11921 +       return err;
11922 +}
11923 +
11924 +static int au_do_open_sp(struct file *file, int flags)
11925 +{
11926 +       int err;
11927 +       struct dentry *dentry;
11928 +       struct super_block *sb;
11929 +       struct file *h_file;
11930 +       struct inode *h_inode;
11931 +
11932 +       dentry = file->f_dentry;
11933 +       AuDbg("%.*s\n", AuDLNPair(dentry));
11934 +
11935 +       /*
11936 +        * try copying-up.
11937 +        * operate on the ro branch is not an error.
11938 +        */
11939 +       au_cpup_sp(dentry); /* ignore */
11940 +
11941 +       /* prepare h_file */
11942 +       err = au_do_open_nondir(file, vfsub_file_flags(file));
11943 +       if (unlikely(err))
11944 +               goto out;
11945 +
11946 +       sb = dentry->d_sb;
11947 +       h_file = au_hf_top(file);
11948 +       h_inode = h_file->f_dentry->d_inode;
11949 +       di_read_unlock(dentry, AuLock_IR);
11950 +       fi_write_unlock(file);
11951 +       si_read_unlock(sb);
11952 +       /* open this fifo in aufs */
11953 +       err = h_inode->i_fop->open(file->f_dentry->d_inode, file);
11954 +       si_noflush_read_lock(sb);
11955 +       fi_write_lock(file);
11956 +       di_read_lock_child(dentry, AuLock_IR);
11957 +       if (!err)
11958 +               au_init_fop_sp(file);
11959 +
11960 +out:
11961 +       return err;
11962 +}
11963 +
11964 +static int aufs_open_sp(struct inode *inode, struct file *file)
11965 +{
11966 +       int err;
11967 +       struct super_block *sb;
11968 +
11969 +       sb = file->f_dentry->d_sb;
11970 +       si_read_lock(sb, AuLock_FLUSH);
11971 +       err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
11972 +       si_read_unlock(sb);
11973 +       return err;
11974 +}
11975 +
11976 +/* ---------------------------------------------------------------------- */
11977 +
11978 +void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
11979 +{
11980 +       init_special_inode(inode, mode, rdev);
11981 +
11982 +       switch (mode & S_IFMT) {
11983 +       case S_IFIFO:
11984 +               inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
11985 +               /*FALLTHROUGH*/
11986 +       case S_IFCHR:
11987 +       case S_IFBLK:
11988 +       case S_IFSOCK:
11989 +               break;
11990 +       default:
11991 +               AuDebugOn(1);
11992 +       }
11993 +}
11994 +
11995 +int au_special_file(umode_t mode)
11996 +{
11997 +       int ret;
11998 +
11999 +       ret = 0;
12000 +       switch (mode & S_IFMT) {
12001 +       case S_IFIFO:
12002 +#if 0
12003 +       case S_IFCHR:
12004 +       case S_IFBLK:
12005 +       case S_IFSOCK:
12006 +#endif
12007 +               ret = 1;
12008 +       }
12009 +
12010 +       return ret;
12011 +}
12012 diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
12013 --- /usr/share/empty/fs/aufs/fstype.h   1970-01-01 01:00:00.000000000 +0100
12014 +++ linux/fs/aufs/fstype.h      2013-01-11 19:46:12.635947932 +0100
12015 @@ -0,0 +1,481 @@
12016 +/*
12017 + * Copyright (C) 2005-2013 Junjiro R. Okajima
12018 + *
12019 + * This program, aufs is free software; you can redistribute it and/or modify
12020 + * it under the terms of the GNU General Public License as published by
12021 + * the Free Software Foundation; either version 2 of the License, or
12022 + * (at your option) any later version.
12023 + *
12024 + * This program is distributed in the hope that it will be useful,
12025 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12026 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12027 + * GNU General Public License for more details.
12028 + *
12029 + * You should have received a copy of the GNU General Public License
12030 + * along with this program; if not, write to the Free Software
12031 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
12032 + */
12033 +
12034 +/*
12035 + * judging filesystem type
12036 + */
12037 +
12038 +#ifndef __AUFS_FSTYPE_H__
12039 +#define __AUFS_FSTYPE_H__
12040 +
12041 +#ifdef __KERNEL__
12042 +
12043 +#include <linux/fs.h>
12044 +#include <linux/magic.h>
12045 +#include <linux/romfs_fs.h>
12046 +
12047 +static inline int au_test_aufs(struct super_block *sb)
12048 +{
12049 +       return sb->s_magic == AUFS_SUPER_MAGIC;
12050 +}
12051 +
12052 +static inline const char *au_sbtype(struct super_block *sb)
12053 +{
12054 +       return sb->s_type->name;
12055 +}
12056 +
12057 +static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
12058 +{
12059 +#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
12060 +       return sb->s_magic == ROMFS_MAGIC;
12061 +#else
12062 +       return 0;
12063 +#endif
12064 +}
12065 +
12066 +static inline int au_test_romfs(struct super_block *sb __maybe_unused)
12067 +{
12068 +#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
12069 +       return sb->s_magic == ISOFS_SUPER_MAGIC;
12070 +#else
12071 +       return 0;
12072 +#endif
12073 +}
12074 +
12075 +static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
12076 +{
12077 +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
12078 +       return sb->s_magic == CRAMFS_MAGIC;
12079 +#endif
12080 +       return 0;
12081 +}
12082 +
12083 +static inline int au_test_nfs(struct super_block *sb __maybe_unused)
12084 +{
12085 +#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
12086 +       return sb->s_magic == NFS_SUPER_MAGIC;
12087 +#else
12088 +       return 0;
12089 +#endif
12090 +}
12091 +
12092 +static inline int au_test_fuse(struct super_block *sb __maybe_unused)
12093 +{
12094 +#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
12095 +       return sb->s_magic == FUSE_SUPER_MAGIC;
12096 +#else
12097 +       return 0;
12098 +#endif
12099 +}
12100 +
12101 +static inline int au_test_xfs(struct super_block *sb __maybe_unused)
12102 +{
12103 +#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
12104 +       return sb->s_magic == XFS_SB_MAGIC;
12105 +#else
12106 +       return 0;
12107 +#endif
12108 +}
12109 +
12110 +static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
12111 +{
12112 +#ifdef CONFIG_TMPFS
12113 +       return sb->s_magic == TMPFS_MAGIC;
12114 +#else
12115 +       return 0;
12116 +#endif
12117 +}
12118 +
12119 +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
12120 +{
12121 +#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
12122 +       return !strcmp(au_sbtype(sb), "ecryptfs");
12123 +#else
12124 +       return 0;
12125 +#endif
12126 +}
12127 +
12128 +static inline int au_test_smbfs(struct super_block *sb __maybe_unused)
12129 +{
12130 +#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE)
12131 +       return sb->s_magic == SMB_SUPER_MAGIC;
12132 +#else
12133 +       return 0;
12134 +#endif
12135 +}
12136 +
12137 +static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
12138 +{
12139 +#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
12140 +       return sb->s_magic == OCFS2_SUPER_MAGIC;
12141 +#else
12142 +       return 0;
12143 +#endif
12144 +}
12145 +
12146 +static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
12147 +{
12148 +#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
12149 +       return sb->s_magic == DLMFS_MAGIC;
12150 +#else
12151 +       return 0;
12152 +#endif
12153 +}
12154 +
12155 +static inline int au_test_coda(struct super_block *sb __maybe_unused)
12156 +{
12157 +#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
12158 +       return sb->s_magic == CODA_SUPER_MAGIC;
12159 +#else
12160 +       return 0;
12161 +#endif
12162 +}
12163 +
12164 +static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
12165 +{
12166 +#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
12167 +       return sb->s_magic == V9FS_MAGIC;
12168 +#else
12169 +       return 0;
12170 +#endif
12171 +}
12172 +
12173 +static inline int au_test_ext4(struct super_block *sb __maybe_unused)
12174 +{
12175 +#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE)
12176 +       return sb->s_magic == EXT4_SUPER_MAGIC;
12177 +#else
12178 +       return 0;
12179 +#endif
12180 +}
12181 +
12182 +static inline int au_test_sysv(struct super_block *sb __maybe_unused)
12183 +{
12184 +#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
12185 +       return !strcmp(au_sbtype(sb), "sysv");
12186 +#else
12187 +       return 0;
12188 +#endif
12189 +}
12190 +
12191 +static inline int au_test_ramfs(struct super_block *sb)
12192 +{
12193 +       return sb->s_magic == RAMFS_MAGIC;
12194 +}
12195 +
12196 +static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
12197 +{
12198 +#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
12199 +       return sb->s_magic == UBIFS_SUPER_MAGIC;
12200 +#else
12201 +       return 0;
12202 +#endif
12203 +}
12204 +
12205 +static inline int au_test_procfs(struct super_block *sb __maybe_unused)
12206 +{
12207 +#ifdef CONFIG_PROC_FS
12208 +       return sb->s_magic == PROC_SUPER_MAGIC;
12209 +#else
12210 +       return 0;
12211 +#endif
12212 +}
12213 +
12214 +static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
12215 +{
12216 +#ifdef CONFIG_SYSFS
12217 +       return sb->s_magic == SYSFS_MAGIC;
12218 +#else
12219 +       return 0;
12220 +#endif
12221 +}
12222 +
12223 +static inline int au_test_configfs(struct super_block *sb __maybe_unused)
12224 +{
12225 +#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
12226 +       return sb->s_magic == CONFIGFS_MAGIC;
12227 +#else
12228 +       return 0;
12229 +#endif
12230 +}
12231 +
12232 +static inline int au_test_minix(struct super_block *sb __maybe_unused)
12233 +{
12234 +#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
12235 +       return sb->s_magic == MINIX3_SUPER_MAGIC
12236 +               || sb->s_magic == MINIX2_SUPER_MAGIC
12237 +               || sb->s_magic == MINIX2_SUPER_MAGIC2
12238 +               || sb->s_magic == MINIX_SUPER_MAGIC
12239 +               || sb->s_magic == MINIX_SUPER_MAGIC2;
12240 +#else
12241 +       return 0;
12242 +#endif
12243 +}
12244 +
12245 +static inline int au_test_cifs(struct super_block *sb __maybe_unused)
12246 +{
12247 +#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
12248 +       return sb->s_magic == CIFS_MAGIC_NUMBER;
12249 +#else
12250 +       return 0;
12251 +#endif
12252 +}
12253 +
12254 +static inline int au_test_fat(struct super_block *sb __maybe_unused)
12255 +{
12256 +#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
12257 +       return sb->s_magic == MSDOS_SUPER_MAGIC;
12258 +#else
12259 +       return 0;
12260 +#endif
12261 +}
12262 +
12263 +static inline int au_test_msdos(struct super_block *sb)
12264 +{
12265 +       return au_test_fat(sb);
12266 +}
12267 +
12268 +static inline int au_test_vfat(struct super_block *sb)
12269 +{
12270 +       return au_test_fat(sb);
12271 +}
12272 +
12273 +static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
12274 +{
12275 +#ifdef CONFIG_SECURITYFS
12276 +       return sb->s_magic == SECURITYFS_MAGIC;
12277 +#else
12278 +       return 0;
12279 +#endif
12280 +}
12281 +
12282 +static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
12283 +{
12284 +#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
12285 +       return sb->s_magic == SQUASHFS_MAGIC;
12286 +#else
12287 +       return 0;
12288 +#endif
12289 +}
12290 +
12291 +static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
12292 +{
12293 +#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
12294 +       return sb->s_magic == BTRFS_SUPER_MAGIC;
12295 +#else
12296 +       return 0;
12297 +#endif
12298 +}
12299 +
12300 +static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
12301 +{
12302 +#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
12303 +       return sb->s_magic == XENFS_SUPER_MAGIC;
12304 +#else
12305 +       return 0;
12306 +#endif
12307 +}
12308 +
12309 +static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
12310 +{
12311 +#ifdef CONFIG_DEBUG_FS
12312 +       return sb->s_magic == DEBUGFS_MAGIC;
12313 +#else
12314 +       return 0;
12315 +#endif
12316 +}
12317 +
12318 +static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
12319 +{
12320 +#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
12321 +       return sb->s_magic == NILFS_SUPER_MAGIC;
12322 +#else
12323 +       return 0;
12324 +#endif
12325 +}
12326 +
12327 +static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
12328 +{
12329 +#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
12330 +       return sb->s_magic == HFSPLUS_SUPER_MAGIC;
12331 +#else
12332 +       return 0;
12333 +#endif
12334 +}
12335 +
12336 +/* ---------------------------------------------------------------------- */
12337 +/*
12338 + * they can't be an aufs branch.
12339 + */
12340 +static inline int au_test_fs_unsuppoted(struct super_block *sb)
12341 +{
12342 +       return
12343 +#ifndef CONFIG_AUFS_BR_RAMFS
12344 +               au_test_ramfs(sb) ||
12345 +#endif
12346 +               au_test_procfs(sb)
12347 +               || au_test_sysfs(sb)
12348 +               || au_test_configfs(sb)
12349 +               || au_test_debugfs(sb)
12350 +               || au_test_securityfs(sb)
12351 +               || au_test_xenfs(sb)
12352 +               || au_test_ecryptfs(sb)
12353 +               /* || !strcmp(au_sbtype(sb), "unionfs") */
12354 +               || au_test_aufs(sb); /* will be supported in next version */
12355 +}
12356 +
12357 +static inline int au_test_fs_remote(struct super_block *sb)
12358 +{
12359 +       return !au_test_tmpfs(sb)
12360 +#ifdef CONFIG_AUFS_BR_RAMFS
12361 +               && !au_test_ramfs(sb)
12362 +#endif
12363 +               && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
12364 +}
12365 +
12366 +/* ---------------------------------------------------------------------- */
12367 +
12368 +/*
12369 + * Note: these functions (below) are created after reading ->getattr() in all
12370 + * filesystems under linux/fs. it means we have to do so in every update...
12371 + */
12372 +
12373 +/*
12374 + * some filesystems require getattr to refresh the inode attributes before
12375 + * referencing.
12376 + * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
12377 + * and leave the work for d_revalidate()
12378 + */
12379 +static inline int au_test_fs_refresh_iattr(struct super_block *sb)
12380 +{
12381 +       return au_test_nfs(sb)
12382 +               || au_test_fuse(sb)
12383 +               /* || au_test_smbfs(sb) */      /* untested */
12384 +               /* || au_test_ocfs2(sb) */      /* untested */
12385 +               /* || au_test_btrfs(sb) */      /* untested */
12386 +               /* || au_test_coda(sb) */       /* untested */
12387 +               /* || au_test_v9fs(sb) */       /* untested */
12388 +               ;
12389 +}
12390 +
12391 +/*
12392 + * filesystems which don't maintain i_size or i_blocks.
12393 + */
12394 +static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
12395 +{
12396 +       return au_test_xfs(sb)
12397 +               || au_test_btrfs(sb)
12398 +               || au_test_ubifs(sb)
12399 +               || au_test_hfsplus(sb)  /* maintained, but incorrect */
12400 +               /* || au_test_ext4(sb) */       /* untested */
12401 +               /* || au_test_ocfs2(sb) */      /* untested */
12402 +               /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
12403 +               /* || au_test_sysv(sb) */       /* untested */
12404 +               /* || au_test_minix(sb) */      /* untested */
12405 +               ;
12406 +}
12407 +
12408 +/*
12409 + * filesystems which don't store the correct value in some of their inode
12410 + * attributes.
12411 + */
12412 +static inline int au_test_fs_bad_iattr(struct super_block *sb)
12413 +{
12414 +       return au_test_fs_bad_iattr_size(sb)
12415 +               /* || au_test_cifs(sb) */       /* untested */
12416 +               || au_test_fat(sb)
12417 +               || au_test_msdos(sb)
12418 +               || au_test_vfat(sb);
12419 +}
12420 +
12421 +/* they don't check i_nlink in link(2) */
12422 +static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
12423 +{
12424 +       return au_test_tmpfs(sb)
12425 +#ifdef CONFIG_AUFS_BR_RAMFS
12426 +               || au_test_ramfs(sb)
12427 +#endif
12428 +               || au_test_ubifs(sb)
12429 +               || au_test_btrfs(sb)
12430 +               || au_test_hfsplus(sb);
12431 +}
12432 +
12433 +/*
12434 + * filesystems which sets S_NOATIME and S_NOCMTIME.
12435 + */
12436 +static inline int au_test_fs_notime(struct super_block *sb)
12437 +{
12438 +       return au_test_nfs(sb)
12439 +               || au_test_fuse(sb)
12440 +               || au_test_ubifs(sb)
12441 +               /* || au_test_cifs(sb) */       /* untested */
12442 +               ;
12443 +}
12444 +
12445 +/*
12446 + * filesystems which requires replacing i_mapping.
12447 + */
12448 +static inline int au_test_fs_bad_mapping(struct super_block *sb)
12449 +{
12450 +       return au_test_fuse(sb)
12451 +               || au_test_ubifs(sb);
12452 +}
12453 +
12454 +/* temporary support for i#1 in cramfs */
12455 +static inline int au_test_fs_unique_ino(struct inode *inode)
12456 +{
12457 +       if (au_test_cramfs(inode->i_sb))
12458 +               return inode->i_ino != 1;
12459 +       return 1;
12460 +}
12461 +
12462 +/* ---------------------------------------------------------------------- */
12463 +
12464 +/*
12465 + * the filesystem where the xino files placed must support i/o after unlink and
12466 + * maintain i_size and i_blocks.
12467 + */
12468 +static inline int au_test_fs_bad_xino(struct super_block *sb)
12469 +{
12470 +       return au_test_fs_remote(sb)
12471 +               || au_test_fs_bad_iattr_size(sb)
12472 +               /* don't want unnecessary work for xino */
12473 +               || au_test_aufs(sb)
12474 +               || au_test_ecryptfs(sb)
12475 +               || au_test_nilfs(sb);
12476 +}
12477 +
12478 +static inline int au_test_fs_trunc_xino(struct super_block *sb)
12479 +{
12480 +       return au_test_tmpfs(sb)
12481 +               || au_test_ramfs(sb);
12482 +}
12483 +
12484 +/*
12485 + * test if the @sb is real-readonly.
12486 + */
12487 +static inline int au_test_fs_rr(struct super_block *sb)
12488 +{
12489 +       return au_test_squashfs(sb)
12490 +               || au_test_iso9660(sb)
12491 +               || au_test_cramfs(sb)
12492 +               || au_test_romfs(sb);
12493 +}
12494 +
12495 +#endif /* __KERNEL__ */
12496 +#endif /* __AUFS_FSTYPE_H__ */
12497 diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
12498 --- /usr/share/empty/fs/aufs/hfsnotify.c        1970-01-01 01:00:00.000000000 +0100
12499 +++ linux/fs/aufs/hfsnotify.c   2013-01-11 19:46:12.635947932 +0100
12500 @@ -0,0 +1,257 @@
12501 +/*
12502 + * Copyright (C) 2005-2013 Junjiro R. Okajima
12503 + *
12504 + * This program, aufs is free software; you can redistribute it and/or modify
12505 + * it under the terms of the GNU General Public License as published by
12506 + * the Free Software Foundation; either version 2 of the License, or
12507 + * (at your option) any later version.
12508 + *
12509 + * This program is distributed in the hope that it will be useful,
12510 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12511 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12512 + * GNU General Public License for more details.
12513 + *
12514 + * You should have received a copy of the GNU General Public License
12515 + * along with this program; if not, write to the Free Software
12516 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
12517 + */
12518 +
12519 +/*
12520 + * fsnotify for the lower directories
12521 + */
12522 +
12523 +#include "aufs.h"
12524 +
12525 +/* FS_IN_IGNORED is unnecessary */
12526 +static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
12527 +                                | FS_CREATE | FS_EVENT_ON_CHILD);
12528 +static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
12529 +static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
12530 +
12531 +static void au_hfsn_free_mark(struct fsnotify_mark *mark)
12532 +{
12533 +       struct au_hnotify *hn = container_of(mark, struct au_hnotify,
12534 +                                            hn_mark);
12535 +       AuDbg("here\n");
12536 +       au_cache_free_hnotify(hn);
12537 +       smp_mb__before_atomic_dec();
12538 +       atomic64_dec(&au_hfsn_ifree);
12539 +       wake_up(&au_hfsn_wq);
12540 +}
12541 +
12542 +static int au_hfsn_alloc(struct au_hinode *hinode)
12543 +{
12544 +       struct au_hnotify *hn;
12545 +       struct super_block *sb;
12546 +       struct au_branch *br;
12547 +       struct fsnotify_mark *mark;
12548 +       aufs_bindex_t bindex;
12549 +
12550 +       hn = hinode->hi_notify;
12551 +       sb = hn->hn_aufs_inode->i_sb;
12552 +       bindex = au_br_index(sb, hinode->hi_id);
12553 +       br = au_sbr(sb, bindex);
12554 +       mark = &hn->hn_mark;
12555 +       fsnotify_init_mark(mark, au_hfsn_free_mark);
12556 +       mark->mask = AuHfsnMask;
12557 +       /*
12558 +        * by udba rename or rmdir, aufs assign a new inode to the known
12559 +        * h_inode, so specify 1 to allow dups.
12560 +        */
12561 +       return fsnotify_add_mark(mark, br->br_hfsn_group, hinode->hi_inode,
12562 +                                /*mnt*/NULL, /*allow_dups*/1);
12563 +}
12564 +
12565 +static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
12566 +{
12567 +       struct fsnotify_mark *mark;
12568 +       unsigned long long ull;
12569 +
12570 +       ull = atomic64_inc_return(&au_hfsn_ifree);
12571 +       BUG_ON(!ull);
12572 +
12573 +       mark = &hn->hn_mark;
12574 +       fsnotify_destroy_mark(mark);
12575 +       fsnotify_put_mark(mark);
12576 +
12577 +       /* free hn by myself */
12578 +       return 0;
12579 +}
12580 +
12581 +/* ---------------------------------------------------------------------- */
12582 +
12583 +static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
12584 +{
12585 +       struct fsnotify_mark *mark;
12586 +
12587 +       mark = &hinode->hi_notify->hn_mark;
12588 +       spin_lock(&mark->lock);
12589 +       if (do_set) {
12590 +               AuDebugOn(mark->mask & AuHfsnMask);
12591 +               mark->mask |= AuHfsnMask;
12592 +       } else {
12593 +               AuDebugOn(!(mark->mask & AuHfsnMask));
12594 +               mark->mask &= ~AuHfsnMask;
12595 +       }
12596 +       spin_unlock(&mark->lock);
12597 +       /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
12598 +}
12599 +
12600 +/* ---------------------------------------------------------------------- */
12601 +
12602 +/* #define AuDbgHnotify */
12603 +#ifdef AuDbgHnotify
12604 +static char *au_hfsn_name(u32 mask)
12605 +{
12606 +#ifdef CONFIG_AUFS_DEBUG
12607 +#define test_ret(flag) if (mask & flag) \
12608 +                               return #flag;
12609 +       test_ret(FS_ACCESS);
12610 +       test_ret(FS_MODIFY);
12611 +       test_ret(FS_ATTRIB);
12612 +       test_ret(FS_CLOSE_WRITE);
12613 +       test_ret(FS_CLOSE_NOWRITE);
12614 +       test_ret(FS_OPEN);
12615 +       test_ret(FS_MOVED_FROM);
12616 +       test_ret(FS_MOVED_TO);
12617 +       test_ret(FS_CREATE);
12618 +       test_ret(FS_DELETE);
12619 +       test_ret(FS_DELETE_SELF);
12620 +       test_ret(FS_MOVE_SELF);
12621 +       test_ret(FS_UNMOUNT);
12622 +       test_ret(FS_Q_OVERFLOW);
12623 +       test_ret(FS_IN_IGNORED);
12624 +       test_ret(FS_IN_ISDIR);
12625 +       test_ret(FS_IN_ONESHOT);
12626 +       test_ret(FS_EVENT_ON_CHILD);
12627 +       return "";
12628 +#undef test_ret
12629 +#else
12630 +       return "??";
12631 +#endif
12632 +}
12633 +#endif
12634 +
12635 +/* ---------------------------------------------------------------------- */
12636 +
12637 +static int au_hfsn_handle_event(struct fsnotify_group *group,
12638 +                               struct fsnotify_mark *inode_mark,
12639 +                               struct fsnotify_mark *vfsmount_mark,
12640 +                               struct fsnotify_event *event)
12641 +{
12642 +       int err;
12643 +       struct au_hnotify *hnotify;
12644 +       struct inode *h_dir, *h_inode;
12645 +       __u32 mask;
12646 +       struct qstr h_child_qstr = QSTR_INIT(event->file_name, event->name_len);
12647 +
12648 +       AuDebugOn(event->data_type != FSNOTIFY_EVENT_INODE);
12649 +
12650 +       err = 0;
12651 +       /* if FS_UNMOUNT happens, there must be another bug */
12652 +       mask = event->mask;
12653 +       AuDebugOn(mask & FS_UNMOUNT);
12654 +       if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
12655 +               goto out;
12656 +
12657 +       h_dir = event->to_tell;
12658 +       h_inode = event->inode;
12659 +#ifdef AuDbgHnotify
12660 +       au_debug(1);
12661 +       if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
12662 +           || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
12663 +               AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
12664 +                     h_dir->i_ino, mask, au_hfsn_name(mask),
12665 +                     AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
12666 +               /* WARN_ON(1); */
12667 +       }
12668 +       au_debug(0);
12669 +#endif
12670 +
12671 +       AuDebugOn(!inode_mark);
12672 +       hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
12673 +       err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
12674 +
12675 +out:
12676 +       return err;
12677 +}
12678 +
12679 +/* isn't it waste to ask every registered 'group'? */
12680 +/* copied from linux/fs/notify/inotify/inotify_fsnotiry.c */
12681 +/* it should be exported to modules */
12682 +static bool au_hfsn_should_send_event(struct fsnotify_group *group,
12683 +                                     struct inode *h_inode,
12684 +                                     struct fsnotify_mark *inode_mark,
12685 +                                     struct fsnotify_mark *vfsmount_mark,
12686 +                                     __u32 mask, void *data, int data_type)
12687 +{
12688 +       mask = (mask & ~FS_EVENT_ON_CHILD);
12689 +       return inode_mark->mask & mask;
12690 +}
12691 +
12692 +static struct fsnotify_ops au_hfsn_ops = {
12693 +       .should_send_event      = au_hfsn_should_send_event,
12694 +       .handle_event           = au_hfsn_handle_event
12695 +};
12696 +
12697 +/* ---------------------------------------------------------------------- */
12698 +
12699 +static void au_hfsn_fin_br(struct au_branch *br)
12700 +{
12701 +       if (br->br_hfsn_group)
12702 +               fsnotify_put_group(br->br_hfsn_group);
12703 +}
12704 +
12705 +static int au_hfsn_init_br(struct au_branch *br, int perm)
12706 +{
12707 +       br->br_hfsn_group = NULL;
12708 +       br->br_hfsn_ops = au_hfsn_ops;
12709 +       return 0;
12710 +}
12711 +
12712 +static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
12713 +{
12714 +       int err;
12715 +
12716 +       err = 0;
12717 +       if (udba != AuOpt_UDBA_HNOTIFY
12718 +           || !au_br_hnotifyable(perm)) {
12719 +               au_hfsn_fin_br(br);
12720 +               br->br_hfsn_group = NULL;
12721 +               goto out;
12722 +       }
12723 +
12724 +       if (br->br_hfsn_group)
12725 +               goto out;
12726 +
12727 +       br->br_hfsn_group = fsnotify_alloc_group(&br->br_hfsn_ops);
12728 +       if (IS_ERR(br->br_hfsn_group)) {
12729 +               err = PTR_ERR(br->br_hfsn_group);
12730 +               pr_err("fsnotify_alloc_group() failed, %d\n", err);
12731 +               br->br_hfsn_group = NULL;
12732 +       }
12733 +
12734 +out:
12735 +       AuTraceErr(err);
12736 +       return err;
12737 +}
12738 +
12739 +/* ---------------------------------------------------------------------- */
12740 +
12741 +static void au_hfsn_fin(void)
12742 +{
12743 +       AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
12744 +       wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
12745 +}
12746 +
12747 +const struct au_hnotify_op au_hnotify_op = {
12748 +       .ctl            = au_hfsn_ctl,
12749 +       .alloc          = au_hfsn_alloc,
12750 +       .free           = au_hfsn_free,
12751 +
12752 +       .fin            = au_hfsn_fin,
12753 +
12754 +       .reset_br       = au_hfsn_reset_br,
12755 +       .fin_br         = au_hfsn_fin_br,
12756 +       .init_br        = au_hfsn_init_br
12757 +};
12758 diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
12759 --- /usr/share/empty/fs/aufs/hfsplus.c  1970-01-01 01:00:00.000000000 +0100
12760 +++ linux/fs/aufs/hfsplus.c     2013-01-11 19:46:12.639281345 +0100
12761 @@ -0,0 +1,57 @@
12762 +/*
12763 + * Copyright (C) 2010-2013 Junjiro R. Okajima
12764 + *
12765 + * This program, aufs is free software; you can redistribute it and/or modify
12766 + * it under the terms of the GNU General Public License as published by
12767 + * the Free Software Foundation; either version 2 of the License, or
12768 + * (at your option) any later version.
12769 + *
12770 + * This program is distributed in the hope that it will be useful,
12771 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12772 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12773 + * GNU General Public License for more details.
12774 + *
12775 + * You should have received a copy of the GNU General Public License
12776 + * along with this program; if not, write to the Free Software
12777 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
12778 + */
12779 +
12780 +/*
12781 + * special support for filesystems which aqucires an inode mutex
12782 + * at final closing a file, eg, hfsplus.
12783 + *
12784 + * This trick is very simple and stupid, just to open the file before really
12785 + * neceeary open to tell hfsplus that this is not the final closing.
12786 + * The caller should call au_h_open_pre() after acquiring the inode mutex,
12787 + * and au_h_open_post() after releasing it.
12788 + */
12789 +
12790 +#include "aufs.h"
12791 +
12792 +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
12793 +{
12794 +       struct file *h_file;
12795 +       struct dentry *h_dentry;
12796 +
12797 +       h_dentry = au_h_dptr(dentry, bindex);
12798 +       AuDebugOn(!h_dentry);
12799 +       AuDebugOn(!h_dentry->d_inode);
12800 +       IMustLock(h_dentry->d_inode);
12801 +
12802 +       h_file = NULL;
12803 +       if (au_test_hfsplus(h_dentry->d_sb)
12804 +           && S_ISREG(h_dentry->d_inode->i_mode))
12805 +               h_file = au_h_open(dentry, bindex,
12806 +                                  O_RDONLY | O_NOATIME | O_LARGEFILE,
12807 +                                  /*file*/NULL);
12808 +       return h_file;
12809 +}
12810 +
12811 +void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
12812 +                   struct file *h_file)
12813 +{
12814 +       if (h_file) {
12815 +               fput(h_file);
12816 +               au_sbr_put(dentry->d_sb, bindex);
12817 +       }
12818 +}
12819 diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
12820 --- /usr/share/empty/fs/aufs/hnotify.c  1970-01-01 01:00:00.000000000 +0100
12821 +++ linux/fs/aufs/hnotify.c     2013-01-11 19:46:12.639281345 +0100
12822 @@ -0,0 +1,713 @@
12823 +/*
12824 + * Copyright (C) 2005-2013 Junjiro R. Okajima
12825 + *
12826 + * This program, aufs is free software; you can redistribute it and/or modify
12827 + * it under the terms of the GNU General Public License as published by
12828 + * the Free Software Foundation; either version 2 of the License, or
12829 + * (at your option) any later version.
12830 + *
12831 + * This program is distributed in the hope that it will be useful,
12832 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12833 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12834 + * GNU General Public License for more details.
12835 + *
12836 + * You should have received a copy of the GNU General Public License
12837 + * along with this program; if not, write to the Free Software
12838 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
12839 + */
12840 +
12841 +/*
12842 + * abstraction to notify the direct changes on lower directories
12843 + */
12844 +
12845 +#include "aufs.h"
12846 +
12847 +int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
12848 +{
12849 +       int err;
12850 +       struct au_hnotify *hn;
12851 +
12852 +       err = -ENOMEM;
12853 +       hn = au_cache_alloc_hnotify();
12854 +       if (hn) {
12855 +               hn->hn_aufs_inode = inode;
12856 +               hinode->hi_notify = hn;
12857 +               err = au_hnotify_op.alloc(hinode);
12858 +               AuTraceErr(err);
12859 +               if (unlikely(err)) {
12860 +                       hinode->hi_notify = NULL;
12861 +                       au_cache_free_hnotify(hn);
12862 +                       /*
12863 +                        * The upper dir was removed by udba, but the same named
12864 +                        * dir left. In this case, aufs assignes a new inode
12865 +                        * number and set the monitor again.
12866 +                        * For the lower dir, the old monitnor is still left.
12867 +                        */
12868 +                       if (err == -EEXIST)
12869 +                               err = 0;
12870 +               }
12871 +       }
12872 +
12873 +       AuTraceErr(err);
12874 +       return err;
12875 +}
12876 +
12877 +void au_hn_free(struct au_hinode *hinode)
12878 +{
12879 +       struct au_hnotify *hn;
12880 +
12881 +       hn = hinode->hi_notify;
12882 +       if (hn) {
12883 +               hinode->hi_notify = NULL;
12884 +               if (au_hnotify_op.free(hinode, hn))
12885 +                       au_cache_free_hnotify(hn);
12886 +       }
12887 +}
12888 +
12889 +/* ---------------------------------------------------------------------- */
12890 +
12891 +void au_hn_ctl(struct au_hinode *hinode, int do_set)
12892 +{
12893 +       if (hinode->hi_notify)
12894 +               au_hnotify_op.ctl(hinode, do_set);
12895 +}
12896 +
12897 +void au_hn_reset(struct inode *inode, unsigned int flags)
12898 +{
12899 +       aufs_bindex_t bindex, bend;
12900 +       struct inode *hi;
12901 +       struct dentry *iwhdentry;
12902 +
12903 +       bend = au_ibend(inode);
12904 +       for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
12905 +               hi = au_h_iptr(inode, bindex);
12906 +               if (!hi)
12907 +                       continue;
12908 +
12909 +               /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
12910 +               iwhdentry = au_hi_wh(inode, bindex);
12911 +               if (iwhdentry)
12912 +                       dget(iwhdentry);
12913 +               au_igrab(hi);
12914 +               au_set_h_iptr(inode, bindex, NULL, 0);
12915 +               au_set_h_iptr(inode, bindex, au_igrab(hi),
12916 +                             flags & ~AuHi_XINO);
12917 +               iput(hi);
12918 +               dput(iwhdentry);
12919 +               /* mutex_unlock(&hi->i_mutex); */
12920 +       }
12921 +}
12922 +
12923 +/* ---------------------------------------------------------------------- */
12924 +
12925 +static int hn_xino(struct inode *inode, struct inode *h_inode)
12926 +{
12927 +       int err;
12928 +       aufs_bindex_t bindex, bend, bfound, bstart;
12929 +       struct inode *h_i;
12930 +
12931 +       err = 0;
12932 +       if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
12933 +               pr_warn("branch root dir was changed\n");
12934 +               goto out;
12935 +       }
12936 +
12937 +       bfound = -1;
12938 +       bend = au_ibend(inode);
12939 +       bstart = au_ibstart(inode);
12940 +#if 0 /* reserved for future use */
12941 +       if (bindex == bend) {
12942 +               /* keep this ino in rename case */
12943 +               goto out;
12944 +       }
12945 +#endif
12946 +       for (bindex = bstart; bindex <= bend; bindex++)
12947 +               if (au_h_iptr(inode, bindex) == h_inode) {
12948 +                       bfound = bindex;
12949 +                       break;
12950 +               }
12951 +       if (bfound < 0)
12952 +               goto out;
12953 +
12954 +       for (bindex = bstart; bindex <= bend; bindex++) {
12955 +               h_i = au_h_iptr(inode, bindex);
12956 +               if (!h_i)
12957 +                       continue;
12958 +
12959 +               err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
12960 +               /* ignore this error */
12961 +               /* bad action? */
12962 +       }
12963 +
12964 +       /* children inode number will be broken */
12965 +
12966 +out:
12967 +       AuTraceErr(err);
12968 +       return err;
12969 +}
12970 +
12971 +static int hn_gen_tree(struct dentry *dentry)
12972 +{
12973 +       int err, i, j, ndentry;
12974 +       struct au_dcsub_pages dpages;
12975 +       struct au_dpage *dpage;
12976 +       struct dentry **dentries;
12977 +
12978 +       err = au_dpages_init(&dpages, GFP_NOFS);
12979 +       if (unlikely(err))
12980 +               goto out;
12981 +       err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
12982 +       if (unlikely(err))
12983 +               goto out_dpages;
12984 +
12985 +       for (i = 0; i < dpages.ndpage; i++) {
12986 +               dpage = dpages.dpages + i;
12987 +               dentries = dpage->dentries;
12988 +               ndentry = dpage->ndentry;
12989 +               for (j = 0; j < ndentry; j++) {
12990 +                       struct dentry *d;
12991 +
12992 +                       d = dentries[j];
12993 +                       if (IS_ROOT(d))
12994 +                               continue;
12995 +
12996 +                       au_digen_dec(d);
12997 +                       if (d->d_inode)
12998 +                               /* todo: reset children xino?
12999 +                                  cached children only? */
13000 +                               au_iigen_dec(d->d_inode);
13001 +               }
13002 +       }
13003 +
13004 +out_dpages:
13005 +       au_dpages_free(&dpages);
13006 +
13007 +#if 0
13008 +       /* discard children */
13009 +       dentry_unhash(dentry);
13010 +       dput(dentry);
13011 +#endif
13012 +out:
13013 +       return err;
13014 +}
13015 +
13016 +/*
13017 + * return 0 if processed.
13018 + */
13019 +static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
13020 +                          const unsigned int isdir)
13021 +{
13022 +       int err;
13023 +       struct dentry *d;
13024 +       struct qstr *dname;
13025 +       struct hlist_node *p;
13026 +
13027 +       err = 1;
13028 +       if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
13029 +               pr_warn("branch root dir was changed\n");
13030 +               err = 0;
13031 +               goto out;
13032 +       }
13033 +
13034 +       if (!isdir) {
13035 +               AuDebugOn(!name);
13036 +               au_iigen_dec(inode);
13037 +               spin_lock(&inode->i_lock);
13038 +               hlist_for_each_entry(d, p, &inode->i_dentry, d_alias) {
13039 +                       spin_lock(&d->d_lock);
13040 +                       dname = &d->d_name;
13041 +                       if (dname->len != nlen
13042 +                           && memcmp(dname->name, name, nlen)) {
13043 +                               spin_unlock(&d->d_lock);
13044 +                               continue;
13045 +                       }
13046 +                       err = 0;
13047 +                       au_digen_dec(d);
13048 +                       spin_unlock(&d->d_lock);
13049 +                       break;
13050 +               }
13051 +               spin_unlock(&inode->i_lock);
13052 +       } else {
13053 +               au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
13054 +               d = d_find_alias(inode);
13055 +               if (!d) {
13056 +                       au_iigen_dec(inode);
13057 +                       goto out;
13058 +               }
13059 +
13060 +               spin_lock(&d->d_lock);
13061 +               dname = &d->d_name;
13062 +               if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
13063 +                       spin_unlock(&d->d_lock);
13064 +                       err = hn_gen_tree(d);
13065 +                       spin_lock(&d->d_lock);
13066 +               }
13067 +               spin_unlock(&d->d_lock);
13068 +               dput(d);
13069 +       }
13070 +
13071 +out:
13072 +       AuTraceErr(err);
13073 +       return err;
13074 +}
13075 +
13076 +static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
13077 +{
13078 +       int err;
13079 +       struct inode *inode;
13080 +
13081 +       inode = dentry->d_inode;
13082 +       if (IS_ROOT(dentry)
13083 +           /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
13084 +               ) {
13085 +               pr_warn("branch root dir was changed\n");
13086 +               return 0;
13087 +       }
13088 +
13089 +       err = 0;
13090 +       if (!isdir) {
13091 +               au_digen_dec(dentry);
13092 +               if (inode)
13093 +                       au_iigen_dec(inode);
13094 +       } else {
13095 +               au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
13096 +               if (inode)
13097 +                       err = hn_gen_tree(dentry);
13098 +       }
13099 +
13100 +       AuTraceErr(err);
13101 +       return err;
13102 +}
13103 +
13104 +/* ---------------------------------------------------------------------- */
13105 +
13106 +/* hnotify job flags */
13107 +#define AuHnJob_XINO0          1
13108 +#define AuHnJob_GEN            (1 << 1)
13109 +#define AuHnJob_DIRENT         (1 << 2)
13110 +#define AuHnJob_ISDIR          (1 << 3)
13111 +#define AuHnJob_TRYXINO0       (1 << 4)
13112 +#define AuHnJob_MNTPNT         (1 << 5)
13113 +#define au_ftest_hnjob(flags, name)    ((flags) & AuHnJob_##name)
13114 +#define au_fset_hnjob(flags, name) \
13115 +       do { (flags) |= AuHnJob_##name; } while (0)
13116 +#define au_fclr_hnjob(flags, name) \
13117 +       do { (flags) &= ~AuHnJob_##name; } while (0)
13118 +
13119 +enum {
13120 +       AuHn_CHILD,
13121 +       AuHn_PARENT,
13122 +       AuHnLast
13123 +};
13124 +
13125 +struct au_hnotify_args {
13126 +       struct inode *h_dir, *dir, *h_child_inode;
13127 +       u32 mask;
13128 +       unsigned int flags[AuHnLast];
13129 +       unsigned int h_child_nlen;
13130 +       char h_child_name[];
13131 +};
13132 +
13133 +struct hn_job_args {
13134 +       unsigned int flags;
13135 +       struct inode *inode, *h_inode, *dir, *h_dir;
13136 +       struct dentry *dentry;
13137 +       char *h_name;
13138 +       int h_nlen;
13139 +};
13140 +
13141 +static int hn_job(struct hn_job_args *a)
13142 +{
13143 +       const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
13144 +
13145 +       /* reset xino */
13146 +       if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
13147 +               hn_xino(a->inode, a->h_inode); /* ignore this error */
13148 +
13149 +       if (au_ftest_hnjob(a->flags, TRYXINO0)
13150 +           && a->inode
13151 +           && a->h_inode) {
13152 +               mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
13153 +               if (!a->h_inode->i_nlink)
13154 +                       hn_xino(a->inode, a->h_inode); /* ignore this error */
13155 +               mutex_unlock(&a->h_inode->i_mutex);
13156 +       }
13157 +
13158 +       /* make the generation obsolete */
13159 +       if (au_ftest_hnjob(a->flags, GEN)) {
13160 +               int err = -1;
13161 +               if (a->inode)
13162 +                       err = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
13163 +                                             isdir);
13164 +               if (err && a->dentry)
13165 +                       hn_gen_by_name(a->dentry, isdir);
13166 +               /* ignore this error */
13167 +       }
13168 +
13169 +       /* make dir entries obsolete */
13170 +       if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
13171 +               struct au_vdir *vdir;
13172 +
13173 +               vdir = au_ivdir(a->inode);
13174 +               if (vdir)
13175 +                       vdir->vd_jiffy = 0;
13176 +               /* IMustLock(a->inode); */
13177 +               /* a->inode->i_version++; */
13178 +       }
13179 +
13180 +       /* can do nothing but warn */
13181 +       if (au_ftest_hnjob(a->flags, MNTPNT)
13182 +           && a->dentry
13183 +           && d_mountpoint(a->dentry))
13184 +               pr_warn("mount-point %.*s is removed or renamed\n",
13185 +                       AuDLNPair(a->dentry));
13186 +
13187 +       return 0;
13188 +}
13189 +
13190 +/* ---------------------------------------------------------------------- */
13191 +
13192 +static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
13193 +                                          struct inode *dir)
13194 +{
13195 +       struct dentry *dentry, *d, *parent;
13196 +       struct qstr *dname;
13197 +
13198 +       parent = d_find_alias(dir);
13199 +       if (!parent)
13200 +               return NULL;
13201 +
13202 +       dentry = NULL;
13203 +       spin_lock(&parent->d_lock);
13204 +       list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
13205 +               /* AuDbg("%.*s\n", AuDLNPair(d)); */
13206 +               spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
13207 +               dname = &d->d_name;
13208 +               if (dname->len != nlen || memcmp(dname->name, name, nlen))
13209 +                       goto cont_unlock;
13210 +               if (au_di(d))
13211 +                       au_digen_dec(d);
13212 +               else
13213 +                       goto cont_unlock;
13214 +               if (d->d_count) {
13215 +                       dentry = dget_dlock(d);
13216 +                       spin_unlock(&d->d_lock);
13217 +                       break;
13218 +               }
13219 +
13220 +       cont_unlock:
13221 +               spin_unlock(&d->d_lock);
13222 +       }
13223 +       spin_unlock(&parent->d_lock);
13224 +       dput(parent);
13225 +
13226 +       if (dentry)
13227 +               di_write_lock_child(dentry);
13228 +
13229 +       return dentry;
13230 +}
13231 +
13232 +static struct inode *lookup_wlock_by_ino(struct super_block *sb,
13233 +                                        aufs_bindex_t bindex, ino_t h_ino)
13234 +{
13235 +       struct inode *inode;
13236 +       ino_t ino;
13237 +       int err;
13238 +
13239 +       inode = NULL;
13240 +       err = au_xino_read(sb, bindex, h_ino, &ino);
13241 +       if (!err && ino)
13242 +               inode = ilookup(sb, ino);
13243 +       if (!inode)
13244 +               goto out;
13245 +
13246 +       if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
13247 +               pr_warn("wrong root branch\n");
13248 +               iput(inode);
13249 +               inode = NULL;
13250 +               goto out;
13251 +       }
13252 +
13253 +       ii_write_lock_child(inode);
13254 +
13255 +out:
13256 +       return inode;
13257 +}
13258 +
13259 +static void au_hn_bh(void *_args)
13260 +{
13261 +       struct au_hnotify_args *a = _args;
13262 +       struct super_block *sb;
13263 +       aufs_bindex_t bindex, bend, bfound;
13264 +       unsigned char xino, try_iput;
13265 +       int err;
13266 +       struct inode *inode;
13267 +       ino_t h_ino;
13268 +       struct hn_job_args args;
13269 +       struct dentry *dentry;
13270 +       struct au_sbinfo *sbinfo;
13271 +
13272 +       AuDebugOn(!_args);
13273 +       AuDebugOn(!a->h_dir);
13274 +       AuDebugOn(!a->dir);
13275 +       AuDebugOn(!a->mask);
13276 +       AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
13277 +             a->mask, a->dir->i_ino, a->h_dir->i_ino,
13278 +             a->h_child_inode ? a->h_child_inode->i_ino : 0);
13279 +
13280 +       inode = NULL;
13281 +       dentry = NULL;
13282 +       /*
13283 +        * do not lock a->dir->i_mutex here
13284 +        * because of d_revalidate() may cause a deadlock.
13285 +        */
13286 +       sb = a->dir->i_sb;
13287 +       AuDebugOn(!sb);
13288 +       sbinfo = au_sbi(sb);
13289 +       AuDebugOn(!sbinfo);
13290 +       si_write_lock(sb, AuLock_NOPLMW);
13291 +
13292 +       ii_read_lock_parent(a->dir);
13293 +       bfound = -1;
13294 +       bend = au_ibend(a->dir);
13295 +       for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
13296 +               if (au_h_iptr(a->dir, bindex) == a->h_dir) {
13297 +                       bfound = bindex;
13298 +                       break;
13299 +               }
13300 +       ii_read_unlock(a->dir);
13301 +       if (unlikely(bfound < 0))
13302 +               goto out;
13303 +
13304 +       xino = !!au_opt_test(au_mntflags(sb), XINO);
13305 +       h_ino = 0;
13306 +       if (a->h_child_inode)
13307 +               h_ino = a->h_child_inode->i_ino;
13308 +
13309 +       if (a->h_child_nlen
13310 +           && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
13311 +               || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
13312 +               dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
13313 +                                             a->dir);
13314 +       try_iput = 0;
13315 +       if (dentry)
13316 +               inode = dentry->d_inode;
13317 +       if (xino && !inode && h_ino
13318 +           && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
13319 +               || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
13320 +               || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
13321 +               inode = lookup_wlock_by_ino(sb, bfound, h_ino);
13322 +               try_iput = 1;
13323 +           }
13324 +
13325 +       args.flags = a->flags[AuHn_CHILD];
13326 +       args.dentry = dentry;
13327 +       args.inode = inode;
13328 +       args.h_inode = a->h_child_inode;
13329 +       args.dir = a->dir;
13330 +       args.h_dir = a->h_dir;
13331 +       args.h_name = a->h_child_name;
13332 +       args.h_nlen = a->h_child_nlen;
13333 +       err = hn_job(&args);
13334 +       if (dentry) {
13335 +               if (au_di(dentry))
13336 +                       di_write_unlock(dentry);
13337 +               dput(dentry);
13338 +       }
13339 +       if (inode && try_iput) {
13340 +               ii_write_unlock(inode);
13341 +               iput(inode);
13342 +       }
13343 +
13344 +       ii_write_lock_parent(a->dir);
13345 +       args.flags = a->flags[AuHn_PARENT];
13346 +       args.dentry = NULL;
13347 +       args.inode = a->dir;
13348 +       args.h_inode = a->h_dir;
13349 +       args.dir = NULL;
13350 +       args.h_dir = NULL;
13351 +       args.h_name = NULL;
13352 +       args.h_nlen = 0;
13353 +       err = hn_job(&args);
13354 +       ii_write_unlock(a->dir);
13355 +
13356 +out:
13357 +       iput(a->h_child_inode);
13358 +       iput(a->h_dir);
13359 +       iput(a->dir);
13360 +       si_write_unlock(sb);
13361 +       au_nwt_done(&sbinfo->si_nowait);
13362 +       kfree(a);
13363 +}
13364 +
13365 +/* ---------------------------------------------------------------------- */
13366 +
13367 +int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
13368 +              struct qstr *h_child_qstr, struct inode *h_child_inode)
13369 +{
13370 +       int err, len;
13371 +       unsigned int flags[AuHnLast], f;
13372 +       unsigned char isdir, isroot, wh;
13373 +       struct inode *dir;
13374 +       struct au_hnotify_args *args;
13375 +       char *p, *h_child_name;
13376 +
13377 +       err = 0;
13378 +       AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
13379 +       dir = igrab(hnotify->hn_aufs_inode);
13380 +       if (!dir)
13381 +               goto out;
13382 +
13383 +       isroot = (dir->i_ino == AUFS_ROOT_INO);
13384 +       wh = 0;
13385 +       h_child_name = (void *)h_child_qstr->name;
13386 +       len = h_child_qstr->len;
13387 +       if (h_child_name) {
13388 +               if (len > AUFS_WH_PFX_LEN
13389 +                   && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
13390 +                       h_child_name += AUFS_WH_PFX_LEN;
13391 +                       len -= AUFS_WH_PFX_LEN;
13392 +                       wh = 1;
13393 +               }
13394 +       }
13395 +
13396 +       isdir = 0;
13397 +       if (h_child_inode)
13398 +               isdir = !!S_ISDIR(h_child_inode->i_mode);
13399 +       flags[AuHn_PARENT] = AuHnJob_ISDIR;
13400 +       flags[AuHn_CHILD] = 0;
13401 +       if (isdir)
13402 +               flags[AuHn_CHILD] = AuHnJob_ISDIR;
13403 +       au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
13404 +       au_fset_hnjob(flags[AuHn_CHILD], GEN);
13405 +       switch (mask & FS_EVENTS_POSS_ON_CHILD) {
13406 +       case FS_MOVED_FROM:
13407 +       case FS_MOVED_TO:
13408 +               au_fset_hnjob(flags[AuHn_CHILD], XINO0);
13409 +               au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
13410 +               /*FALLTHROUGH*/
13411 +       case FS_CREATE:
13412 +               AuDebugOn(!h_child_name || !h_child_inode);
13413 +               break;
13414 +
13415 +       case FS_DELETE:
13416 +               /*
13417 +                * aufs never be able to get this child inode.
13418 +                * revalidation should be in d_revalidate()
13419 +                * by checking i_nlink, i_generation or d_unhashed().
13420 +                */
13421 +               AuDebugOn(!h_child_name);
13422 +               au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
13423 +               au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
13424 +               break;
13425 +
13426 +       default:
13427 +               AuDebugOn(1);
13428 +       }
13429 +
13430 +       if (wh)
13431 +               h_child_inode = NULL;
13432 +
13433 +       err = -ENOMEM;
13434 +       /* iput() and kfree() will be called in au_hnotify() */
13435 +       args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
13436 +       if (unlikely(!args)) {
13437 +               AuErr1("no memory\n");
13438 +               iput(dir);
13439 +               goto out;
13440 +       }
13441 +       args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
13442 +       args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
13443 +       args->mask = mask;
13444 +       args->dir = dir;
13445 +       args->h_dir = igrab(h_dir);
13446 +       if (h_child_inode)
13447 +               h_child_inode = igrab(h_child_inode); /* can be NULL */
13448 +       args->h_child_inode = h_child_inode;
13449 +       args->h_child_nlen = len;
13450 +       if (len) {
13451 +               p = (void *)args;
13452 +               p += sizeof(*args);
13453 +               memcpy(p, h_child_name, len);
13454 +               p[len] = 0;
13455 +       }
13456 +
13457 +       f = 0;
13458 +       if (!dir->i_nlink)
13459 +               f = AuWkq_NEST;
13460 +       err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
13461 +       if (unlikely(err)) {
13462 +               pr_err("wkq %d\n", err);
13463 +               iput(args->h_child_inode);
13464 +               iput(args->h_dir);
13465 +               iput(args->dir);
13466 +               kfree(args);
13467 +       }
13468 +
13469 +out:
13470 +       return err;
13471 +}
13472 +
13473 +/* ---------------------------------------------------------------------- */
13474 +
13475 +int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
13476 +{
13477 +       int err;
13478 +
13479 +       AuDebugOn(!(udba & AuOptMask_UDBA));
13480 +
13481 +       err = 0;
13482 +       if (au_hnotify_op.reset_br)
13483 +               err = au_hnotify_op.reset_br(udba, br, perm);
13484 +
13485 +       return err;
13486 +}
13487 +
13488 +int au_hnotify_init_br(struct au_branch *br, int perm)
13489 +{
13490 +       int err;
13491 +
13492 +       err = 0;
13493 +       if (au_hnotify_op.init_br)
13494 +               err = au_hnotify_op.init_br(br, perm);
13495 +
13496 +       return err;
13497 +}
13498 +
13499 +void au_hnotify_fin_br(struct au_branch *br)
13500 +{
13501 +       if (au_hnotify_op.fin_br)
13502 +               au_hnotify_op.fin_br(br);
13503 +}
13504 +
13505 +static void au_hn_destroy_cache(void)
13506 +{
13507 +       kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
13508 +       au_cachep[AuCache_HNOTIFY] = NULL;
13509 +}
13510 +
13511 +int __init au_hnotify_init(void)
13512 +{
13513 +       int err;
13514 +
13515 +       err = -ENOMEM;
13516 +       au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
13517 +       if (au_cachep[AuCache_HNOTIFY]) {
13518 +               err = 0;
13519 +               if (au_hnotify_op.init)
13520 +                       err = au_hnotify_op.init();
13521 +               if (unlikely(err))
13522 +                       au_hn_destroy_cache();
13523 +       }
13524 +       AuTraceErr(err);
13525 +       return err;
13526 +}
13527 +
13528 +void au_hnotify_fin(void)
13529 +{
13530 +       if (au_hnotify_op.fin)
13531 +               au_hnotify_op.fin();
13532 +       /* cf. au_cache_fin() */
13533 +       if (au_cachep[AuCache_HNOTIFY])
13534 +               au_hn_destroy_cache();
13535 +}
13536 diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
13537 --- /usr/share/empty/fs/aufs/iinfo.c    1970-01-01 01:00:00.000000000 +0100
13538 +++ linux/fs/aufs/iinfo.c       2013-01-11 19:46:12.639281345 +0100
13539 @@ -0,0 +1,276 @@
13540 +/*
13541 + * Copyright (C) 2005-2013 Junjiro R. Okajima
13542 + *
13543 + * This program, aufs is free software; you can redistribute it and/or modify
13544 + * it under the terms of the GNU General Public License as published by
13545 + * the Free Software Foundation; either version 2 of the License, or
13546 + * (at your option) any later version.
13547 + *
13548 + * This program is distributed in the hope that it will be useful,
13549 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13550 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13551 + * GNU General Public License for more details.
13552 + *
13553 + * You should have received a copy of the GNU General Public License
13554 + * along with this program; if not, write to the Free Software
13555 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
13556 + */
13557 +
13558 +/*
13559 + * inode private data
13560 + */
13561 +
13562 +#include "aufs.h"
13563 +
13564 +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
13565 +{
13566 +       struct inode *h_inode;
13567 +
13568 +       IiMustAnyLock(inode);
13569 +
13570 +       h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
13571 +       AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
13572 +       return h_inode;
13573 +}
13574 +
13575 +/* todo: hard/soft set? */
13576 +void au_hiput(struct au_hinode *hinode)
13577 +{
13578 +       au_hn_free(hinode);
13579 +       dput(hinode->hi_whdentry);
13580 +       iput(hinode->hi_inode);
13581 +}
13582 +
13583 +unsigned int au_hi_flags(struct inode *inode, int isdir)
13584 +{
13585 +       unsigned int flags;
13586 +       const unsigned int mnt_flags = au_mntflags(inode->i_sb);
13587 +
13588 +       flags = 0;
13589 +       if (au_opt_test(mnt_flags, XINO))
13590 +               au_fset_hi(flags, XINO);
13591 +       if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
13592 +               au_fset_hi(flags, HNOTIFY);
13593 +       return flags;
13594 +}
13595 +
13596 +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
13597 +                  struct inode *h_inode, unsigned int flags)
13598 +{
13599 +       struct au_hinode *hinode;
13600 +       struct inode *hi;
13601 +       struct au_iinfo *iinfo = au_ii(inode);
13602 +
13603 +       IiMustWriteLock(inode);
13604 +
13605 +       hinode = iinfo->ii_hinode + bindex;
13606 +       hi = hinode->hi_inode;
13607 +       AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
13608 +
13609 +       if (hi)
13610 +               au_hiput(hinode);
13611 +       hinode->hi_inode = h_inode;
13612 +       if (h_inode) {
13613 +               int err;
13614 +               struct super_block *sb = inode->i_sb;
13615 +               struct au_branch *br;
13616 +
13617 +               AuDebugOn(inode->i_mode
13618 +                         && (h_inode->i_mode & S_IFMT)
13619 +                         != (inode->i_mode & S_IFMT));
13620 +               if (bindex == iinfo->ii_bstart)
13621 +                       au_cpup_igen(inode, h_inode);
13622 +               br = au_sbr(sb, bindex);
13623 +               hinode->hi_id = br->br_id;
13624 +               if (au_ftest_hi(flags, XINO)) {
13625 +                       err = au_xino_write(sb, bindex, h_inode->i_ino,
13626 +                                           inode->i_ino);
13627 +                       if (unlikely(err))
13628 +                               AuIOErr1("failed au_xino_write() %d\n", err);
13629 +               }
13630 +
13631 +               if (au_ftest_hi(flags, HNOTIFY)
13632 +                   && au_br_hnotifyable(br->br_perm)) {
13633 +                       err = au_hn_alloc(hinode, inode);
13634 +                       if (unlikely(err))
13635 +                               AuIOErr1("au_hn_alloc() %d\n", err);
13636 +               }
13637 +       }
13638 +}
13639 +
13640 +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
13641 +                 struct dentry *h_wh)
13642 +{
13643 +       struct au_hinode *hinode;
13644 +
13645 +       IiMustWriteLock(inode);
13646 +
13647 +       hinode = au_ii(inode)->ii_hinode + bindex;
13648 +       AuDebugOn(hinode->hi_whdentry);
13649 +       hinode->hi_whdentry = h_wh;
13650 +}
13651 +
13652 +void au_update_iigen(struct inode *inode, int half)
13653 +{
13654 +       struct au_iinfo *iinfo;
13655 +       struct au_iigen *iigen;
13656 +       unsigned int sigen;
13657 +
13658 +       sigen = au_sigen(inode->i_sb);
13659 +       iinfo = au_ii(inode);
13660 +       iigen = &iinfo->ii_generation;
13661 +       spin_lock(&iinfo->ii_genspin);
13662 +       iigen->ig_generation = sigen;
13663 +       if (half)
13664 +               au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
13665 +       else
13666 +               au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
13667 +       spin_unlock(&iinfo->ii_genspin);
13668 +}
13669 +
13670 +/* it may be called at remount time, too */
13671 +void au_update_ibrange(struct inode *inode, int do_put_zero)
13672 +{
13673 +       struct au_iinfo *iinfo;
13674 +       aufs_bindex_t bindex, bend;
13675 +
13676 +       iinfo = au_ii(inode);
13677 +       if (!iinfo)
13678 +               return;
13679 +
13680 +       IiMustWriteLock(inode);
13681 +
13682 +       if (do_put_zero && iinfo->ii_bstart >= 0) {
13683 +               for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
13684 +                    bindex++) {
13685 +                       struct inode *h_i;
13686 +
13687 +                       h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
13688 +                       if (h_i && !h_i->i_nlink)
13689 +                               au_set_h_iptr(inode, bindex, NULL, 0);
13690 +               }
13691 +       }
13692 +
13693 +       iinfo->ii_bstart = -1;
13694 +       iinfo->ii_bend = -1;
13695 +       bend = au_sbend(inode->i_sb);
13696 +       for (bindex = 0; bindex <= bend; bindex++)
13697 +               if (iinfo->ii_hinode[0 + bindex].hi_inode) {
13698 +                       iinfo->ii_bstart = bindex;
13699 +                       break;
13700 +               }
13701 +       if (iinfo->ii_bstart >= 0)
13702 +               for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
13703 +                       if (iinfo->ii_hinode[0 + bindex].hi_inode) {
13704 +                               iinfo->ii_bend = bindex;
13705 +                               break;
13706 +                       }
13707 +       AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
13708 +}
13709 +
13710 +/* ---------------------------------------------------------------------- */
13711 +
13712 +void au_icntnr_init_once(void *_c)
13713 +{
13714 +       struct au_icntnr *c = _c;
13715 +       struct au_iinfo *iinfo = &c->iinfo;
13716 +       static struct lock_class_key aufs_ii;
13717 +
13718 +       spin_lock_init(&iinfo->ii_genspin);
13719 +       au_rw_init(&iinfo->ii_rwsem);
13720 +       au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
13721 +       inode_init_once(&c->vfs_inode);
13722 +}
13723 +
13724 +int au_iinfo_init(struct inode *inode)
13725 +{
13726 +       struct au_iinfo *iinfo;
13727 +       struct super_block *sb;
13728 +       int nbr, i;
13729 +
13730 +       sb = inode->i_sb;
13731 +       iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
13732 +       nbr = au_sbend(sb) + 1;
13733 +       if (unlikely(nbr <= 0))
13734 +               nbr = 1;
13735 +       iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
13736 +       if (iinfo->ii_hinode) {
13737 +               au_ninodes_inc(sb);
13738 +               for (i = 0; i < nbr; i++)
13739 +                       iinfo->ii_hinode[i].hi_id = -1;
13740 +
13741 +               iinfo->ii_generation.ig_generation = au_sigen(sb);
13742 +               iinfo->ii_bstart = -1;
13743 +               iinfo->ii_bend = -1;
13744 +               iinfo->ii_vdir = NULL;
13745 +               return 0;
13746 +       }
13747 +       return -ENOMEM;
13748 +}
13749 +
13750 +int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
13751 +{
13752 +       int err, sz;
13753 +       struct au_hinode *hip;
13754 +
13755 +       AuRwMustWriteLock(&iinfo->ii_rwsem);
13756 +
13757 +       err = -ENOMEM;
13758 +       sz = sizeof(*hip) * (iinfo->ii_bend + 1);
13759 +       if (!sz)
13760 +               sz = sizeof(*hip);
13761 +       hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
13762 +       if (hip) {
13763 +               iinfo->ii_hinode = hip;
13764 +               err = 0;
13765 +       }
13766 +
13767 +       return err;
13768 +}
13769 +
13770 +void au_iinfo_fin(struct inode *inode)
13771 +{
13772 +       struct au_iinfo *iinfo;
13773 +       struct au_hinode *hi;
13774 +       struct super_block *sb;
13775 +       aufs_bindex_t bindex, bend;
13776 +       const unsigned char unlinked = !inode->i_nlink;
13777 +
13778 +       iinfo = au_ii(inode);
13779 +       /* bad_inode case */
13780 +       if (!iinfo)
13781 +               return;
13782 +
13783 +       sb = inode->i_sb;
13784 +       au_ninodes_dec(sb);
13785 +       if (si_pid_test(sb))
13786 +               au_xino_delete_inode(inode, unlinked);
13787 +       else {
13788 +               /*
13789 +                * it is safe to hide the dependency between sbinfo and
13790 +                * sb->s_umount.
13791 +                */
13792 +               lockdep_off();
13793 +               si_noflush_read_lock(sb);
13794 +               au_xino_delete_inode(inode, unlinked);
13795 +               si_read_unlock(sb);
13796 +               lockdep_on();
13797 +       }
13798 +
13799 +       if (iinfo->ii_vdir)
13800 +               au_vdir_free(iinfo->ii_vdir);
13801 +
13802 +       bindex = iinfo->ii_bstart;
13803 +       if (bindex >= 0) {
13804 +               hi = iinfo->ii_hinode + bindex;
13805 +               bend = iinfo->ii_bend;
13806 +               while (bindex++ <= bend) {
13807 +                       if (hi->hi_inode)
13808 +                               au_hiput(hi);
13809 +                       hi++;
13810 +               }
13811 +       }
13812 +       kfree(iinfo->ii_hinode);
13813 +       iinfo->ii_hinode = NULL;
13814 +       AuRwDestroy(&iinfo->ii_rwsem);
13815 +}
13816 diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
13817 --- /usr/share/empty/fs/aufs/inode.c    1970-01-01 01:00:00.000000000 +0100
13818 +++ linux/fs/aufs/inode.c       2013-01-11 19:46:12.639281345 +0100
13819 @@ -0,0 +1,488 @@
13820 +/*
13821 + * Copyright (C) 2005-2013 Junjiro R. Okajima
13822 + *
13823 + * This program, aufs is free software; you can redistribute it and/or modify
13824 + * it under the terms of the GNU General Public License as published by
13825 + * the Free Software Foundation; either version 2 of the License, or
13826 + * (at your option) any later version.
13827 + *
13828 + * This program is distributed in the hope that it will be useful,
13829 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13830 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13831 + * GNU General Public License for more details.
13832 + *
13833 + * You should have received a copy of the GNU General Public License
13834 + * along with this program; if not, write to the Free Software
13835 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
13836 + */
13837 +
13838 +/*
13839 + * inode functions
13840 + */
13841 +
13842 +#include "aufs.h"
13843 +
13844 +struct inode *au_igrab(struct inode *inode)
13845 +{
13846 +       if (inode) {
13847 +               AuDebugOn(!atomic_read(&inode->i_count));
13848 +               ihold(inode);
13849 +       }
13850 +       return inode;
13851 +}
13852 +
13853 +static void au_refresh_hinode_attr(struct inode *inode, int do_version)
13854 +{
13855 +       au_cpup_attr_all(inode, /*force*/0);
13856 +       au_update_iigen(inode, /*half*/1);
13857 +       if (do_version)
13858 +               inode->i_version++;
13859 +}
13860 +
13861 +static int au_ii_refresh(struct inode *inode, int *update)
13862 +{
13863 +       int err, e;
13864 +       umode_t type;
13865 +       aufs_bindex_t bindex, new_bindex;
13866 +       struct super_block *sb;
13867 +       struct au_iinfo *iinfo;
13868 +       struct au_hinode *p, *q, tmp;
13869 +
13870 +       IiMustWriteLock(inode);
13871 +
13872 +       *update = 0;
13873 +       sb = inode->i_sb;
13874 +       type = inode->i_mode & S_IFMT;
13875 +       iinfo = au_ii(inode);
13876 +       err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
13877 +       if (unlikely(err))
13878 +               goto out;
13879 +
13880 +       AuDebugOn(iinfo->ii_bstart < 0);
13881 +       p = iinfo->ii_hinode + iinfo->ii_bstart;
13882 +       for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
13883 +            bindex++, p++) {
13884 +               if (!p->hi_inode)
13885 +                       continue;
13886 +
13887 +               AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
13888 +               new_bindex = au_br_index(sb, p->hi_id);
13889 +               if (new_bindex == bindex)
13890 +                       continue;
13891 +
13892 +               if (new_bindex < 0) {
13893 +                       *update = 1;
13894 +                       au_hiput(p);
13895 +                       p->hi_inode = NULL;
13896 +                       continue;
13897 +               }
13898 +
13899 +               if (new_bindex < iinfo->ii_bstart)
13900 +                       iinfo->ii_bstart = new_bindex;
13901 +               if (iinfo->ii_bend < new_bindex)
13902 +                       iinfo->ii_bend = new_bindex;
13903 +               /* swap two lower inode, and loop again */
13904 +               q = iinfo->ii_hinode + new_bindex;
13905 +               tmp = *q;
13906 +               *q = *p;
13907 +               *p = tmp;
13908 +               if (tmp.hi_inode) {
13909 +                       bindex--;
13910 +                       p--;
13911 +               }
13912 +       }
13913 +       au_update_ibrange(inode, /*do_put_zero*/0);
13914 +       e = au_dy_irefresh(inode);
13915 +       if (unlikely(e && !err))
13916 +               err = e;
13917 +
13918 +out:
13919 +       AuTraceErr(err);
13920 +       return err;
13921 +}
13922 +
13923 +int au_refresh_hinode_self(struct inode *inode)
13924 +{
13925 +       int err, update;
13926 +
13927 +       err = au_ii_refresh(inode, &update);
13928 +       if (!err)
13929 +               au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
13930 +
13931 +       AuTraceErr(err);
13932 +       return err;
13933 +}
13934 +
13935 +int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
13936 +{
13937 +       int err, e, update;
13938 +       unsigned int flags;
13939 +       umode_t mode;
13940 +       aufs_bindex_t bindex, bend;
13941 +       unsigned char isdir;
13942 +       struct au_hinode *p;
13943 +       struct au_iinfo *iinfo;
13944 +
13945 +       err = au_ii_refresh(inode, &update);
13946 +       if (unlikely(err))
13947 +               goto out;
13948 +
13949 +       update = 0;
13950 +       iinfo = au_ii(inode);
13951 +       p = iinfo->ii_hinode + iinfo->ii_bstart;
13952 +       mode = (inode->i_mode & S_IFMT);
13953 +       isdir = S_ISDIR(mode);
13954 +       flags = au_hi_flags(inode, isdir);
13955 +       bend = au_dbend(dentry);
13956 +       for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
13957 +               struct inode *h_i;
13958 +               struct dentry *h_d;
13959 +
13960 +               h_d = au_h_dptr(dentry, bindex);
13961 +               if (!h_d || !h_d->d_inode)
13962 +                       continue;
13963 +
13964 +               AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
13965 +               if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
13966 +                       h_i = au_h_iptr(inode, bindex);
13967 +                       if (h_i) {
13968 +                               if (h_i == h_d->d_inode)
13969 +                                       continue;
13970 +                               err = -EIO;
13971 +                               break;
13972 +                       }
13973 +               }
13974 +               if (bindex < iinfo->ii_bstart)
13975 +                       iinfo->ii_bstart = bindex;
13976 +               if (iinfo->ii_bend < bindex)
13977 +                       iinfo->ii_bend = bindex;
13978 +               au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
13979 +               update = 1;
13980 +       }
13981 +       au_update_ibrange(inode, /*do_put_zero*/0);
13982 +       e = au_dy_irefresh(inode);
13983 +       if (unlikely(e && !err))
13984 +               err = e;
13985 +       if (!err)
13986 +               au_refresh_hinode_attr(inode, update && isdir);
13987 +
13988 +out:
13989 +       AuTraceErr(err);
13990 +       return err;
13991 +}
13992 +
13993 +static int set_inode(struct inode *inode, struct dentry *dentry)
13994 +{
13995 +       int err;
13996 +       unsigned int flags;
13997 +       umode_t mode;
13998 +       aufs_bindex_t bindex, bstart, btail;
13999 +       unsigned char isdir;
14000 +       struct dentry *h_dentry;
14001 +       struct inode *h_inode;
14002 +       struct au_iinfo *iinfo;
14003 +
14004 +       IiMustWriteLock(inode);
14005 +
14006 +       err = 0;
14007 +       isdir = 0;
14008 +       bstart = au_dbstart(dentry);
14009 +       h_inode = au_h_dptr(dentry, bstart)->d_inode;
14010 +       mode = h_inode->i_mode;
14011 +       switch (mode & S_IFMT) {
14012 +       case S_IFREG:
14013 +               btail = au_dbtail(dentry);
14014 +               inode->i_op = &aufs_iop;
14015 +               inode->i_fop = &aufs_file_fop;
14016 +               err = au_dy_iaop(inode, bstart, h_inode);
14017 +               if (unlikely(err))
14018 +                       goto out;
14019 +               break;
14020 +       case S_IFDIR:
14021 +               isdir = 1;
14022 +               btail = au_dbtaildir(dentry);
14023 +               inode->i_op = &aufs_dir_iop;
14024 +               inode->i_fop = &aufs_dir_fop;
14025 +               break;
14026 +       case S_IFLNK:
14027 +               btail = au_dbtail(dentry);
14028 +               inode->i_op = &aufs_symlink_iop;
14029 +               break;
14030 +       case S_IFBLK:
14031 +       case S_IFCHR:
14032 +       case S_IFIFO:
14033 +       case S_IFSOCK:
14034 +               btail = au_dbtail(dentry);
14035 +               inode->i_op = &aufs_iop;
14036 +               au_init_special_fop(inode, mode, h_inode->i_rdev);
14037 +               break;
14038 +       default:
14039 +               AuIOErr("Unknown file type 0%o\n", mode);
14040 +               err = -EIO;
14041 +               goto out;
14042 +       }
14043 +
14044 +       /* do not set hnotify for whiteouted dirs (SHWH mode) */
14045 +       flags = au_hi_flags(inode, isdir);
14046 +       if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
14047 +           && au_ftest_hi(flags, HNOTIFY)
14048 +           && dentry->d_name.len > AUFS_WH_PFX_LEN
14049 +           && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
14050 +               au_fclr_hi(flags, HNOTIFY);
14051 +       iinfo = au_ii(inode);
14052 +       iinfo->ii_bstart = bstart;
14053 +       iinfo->ii_bend = btail;
14054 +       for (bindex = bstart; bindex <= btail; bindex++) {
14055 +               h_dentry = au_h_dptr(dentry, bindex);
14056 +               if (h_dentry)
14057 +                       au_set_h_iptr(inode, bindex,
14058 +                                     au_igrab(h_dentry->d_inode), flags);
14059 +       }
14060 +       au_cpup_attr_all(inode, /*force*/1);
14061 +
14062 +out:
14063 +       return err;
14064 +}
14065 +
14066 +/*
14067 + * successful returns with iinfo write_locked
14068 + * minus: errno
14069 + * zero: success, matched
14070 + * plus: no error, but unmatched
14071 + */
14072 +static int reval_inode(struct inode *inode, struct dentry *dentry)
14073 +{
14074 +       int err;
14075 +       unsigned int gen;
14076 +       struct au_iigen iigen;
14077 +       aufs_bindex_t bindex, bend;
14078 +       struct inode *h_inode, *h_dinode;
14079 +
14080 +       /*
14081 +        * before this function, if aufs got any iinfo lock, it must be only
14082 +        * one, the parent dir.
14083 +        * it can happen by UDBA and the obsoleted inode number.
14084 +        */
14085 +       err = -EIO;
14086 +       if (unlikely(inode->i_ino == parent_ino(dentry)))
14087 +               goto out;
14088 +
14089 +       err = 1;
14090 +       ii_write_lock_new_child(inode);
14091 +       h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
14092 +       bend = au_ibend(inode);
14093 +       for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14094 +               h_inode = au_h_iptr(inode, bindex);
14095 +               if (!h_inode || h_inode != h_dinode)
14096 +                       continue;
14097 +
14098 +               err = 0;
14099 +               gen = au_iigen(inode, &iigen);
14100 +               if (gen == au_digen(dentry)
14101 +                   && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
14102 +                       break;
14103 +
14104 +               /* fully refresh inode using dentry */
14105 +               err = au_refresh_hinode(inode, dentry);
14106 +               if (!err)
14107 +                       au_update_iigen(inode, /*half*/0);
14108 +               break;
14109 +       }
14110 +
14111 +       if (unlikely(err))
14112 +               ii_write_unlock(inode);
14113 +out:
14114 +       return err;
14115 +}
14116 +
14117 +int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14118 +          unsigned int d_type, ino_t *ino)
14119 +{
14120 +       int err;
14121 +       struct mutex *mtx;
14122 +
14123 +       /* prevent hardlinked inode number from race condition */
14124 +       mtx = NULL;
14125 +       if (d_type != DT_DIR) {
14126 +               mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
14127 +               mutex_lock(mtx);
14128 +       }
14129 +       err = au_xino_read(sb, bindex, h_ino, ino);
14130 +       if (unlikely(err))
14131 +               goto out;
14132 +
14133 +       if (!*ino) {
14134 +               err = -EIO;
14135 +               *ino = au_xino_new_ino(sb);
14136 +               if (unlikely(!*ino))
14137 +                       goto out;
14138 +               err = au_xino_write(sb, bindex, h_ino, *ino);
14139 +               if (unlikely(err))
14140 +                       goto out;
14141 +       }
14142 +
14143 +out:
14144 +       if (mtx)
14145 +               mutex_unlock(mtx);
14146 +       return err;
14147 +}
14148 +
14149 +/* successful returns with iinfo write_locked */
14150 +/* todo: return with unlocked? */
14151 +struct inode *au_new_inode(struct dentry *dentry, int must_new)
14152 +{
14153 +       struct inode *inode, *h_inode;
14154 +       struct dentry *h_dentry;
14155 +       struct super_block *sb;
14156 +       struct mutex *mtx;
14157 +       ino_t h_ino, ino;
14158 +       int err, lc_idx;
14159 +       aufs_bindex_t bstart;
14160 +
14161 +       sb = dentry->d_sb;
14162 +       bstart = au_dbstart(dentry);
14163 +       h_dentry = au_h_dptr(dentry, bstart);
14164 +       h_inode = h_dentry->d_inode;
14165 +       h_ino = h_inode->i_ino;
14166 +
14167 +       /*
14168 +        * stop 'race'-ing between hardlinks under different
14169 +        * parents.
14170 +        */
14171 +       mtx = NULL;
14172 +       if (!S_ISDIR(h_inode->i_mode))
14173 +               mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
14174 +
14175 +new_ino:
14176 +       if (mtx)
14177 +               mutex_lock(mtx);
14178 +       err = au_xino_read(sb, bstart, h_ino, &ino);
14179 +       inode = ERR_PTR(err);
14180 +       if (unlikely(err))
14181 +               goto out;
14182 +
14183 +       if (!ino) {
14184 +               ino = au_xino_new_ino(sb);
14185 +               if (unlikely(!ino)) {
14186 +                       inode = ERR_PTR(-EIO);
14187 +                       goto out;
14188 +               }
14189 +       }
14190 +
14191 +       AuDbg("i%lu\n", (unsigned long)ino);
14192 +       inode = au_iget_locked(sb, ino);
14193 +       err = PTR_ERR(inode);
14194 +       if (IS_ERR(inode))
14195 +               goto out;
14196 +
14197 +       AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
14198 +       if (inode->i_state & I_NEW) {
14199 +               lc_idx = AuLcNonDir_IIINFO;
14200 +               if (S_ISLNK(h_inode->i_mode))
14201 +                       lc_idx = AuLcSymlink_IIINFO;
14202 +               else if (S_ISDIR(h_inode->i_mode))
14203 +                       lc_idx = AuLcDir_IIINFO;
14204 +               au_rw_class(&au_ii(inode)->ii_rwsem, au_lc_key + lc_idx);
14205 +
14206 +               ii_write_lock_new_child(inode);
14207 +               err = set_inode(inode, dentry);
14208 +               if (!err) {
14209 +                       unlock_new_inode(inode);
14210 +                       goto out; /* success */
14211 +               }
14212 +
14213 +               /*
14214 +                * iget_failed() calls iput(), but we need to call
14215 +                * ii_write_unlock() after iget_failed(). so dirty hack for
14216 +                * i_count.
14217 +                */
14218 +               atomic_inc(&inode->i_count);
14219 +               iget_failed(inode);
14220 +               ii_write_unlock(inode);
14221 +               au_xino_write(sb, bstart, h_ino, /*ino*/0);
14222 +               /* ignore this error */
14223 +               goto out_iput;
14224 +       } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
14225 +               /*
14226 +                * horrible race condition between lookup, readdir and copyup
14227 +                * (or something).
14228 +                */
14229 +               if (mtx)
14230 +                       mutex_unlock(mtx);
14231 +               err = reval_inode(inode, dentry);
14232 +               if (unlikely(err < 0)) {
14233 +                       mtx = NULL;
14234 +                       goto out_iput;
14235 +               }
14236 +
14237 +               if (!err) {
14238 +                       mtx = NULL;
14239 +                       goto out; /* success */
14240 +               } else if (mtx)
14241 +                       mutex_lock(mtx);
14242 +       }
14243 +
14244 +       if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
14245 +               AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
14246 +                       " b%d, %s, %.*s, hi%lu, i%lu.\n",
14247 +                       bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
14248 +                       (unsigned long)h_ino, (unsigned long)ino);
14249 +       ino = 0;
14250 +       err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
14251 +       if (!err) {
14252 +               iput(inode);
14253 +               if (mtx)
14254 +                       mutex_unlock(mtx);
14255 +               goto new_ino;
14256 +       }
14257 +
14258 +out_iput:
14259 +       iput(inode);
14260 +       inode = ERR_PTR(err);
14261 +out:
14262 +       if (mtx)
14263 +               mutex_unlock(mtx);
14264 +       return inode;
14265 +}
14266 +
14267 +/* ---------------------------------------------------------------------- */
14268 +
14269 +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14270 +              struct inode *inode)
14271 +{
14272 +       int err;
14273 +
14274 +       err = au_br_rdonly(au_sbr(sb, bindex));
14275 +
14276 +       /* pseudo-link after flushed may happen out of bounds */
14277 +       if (!err
14278 +           && inode
14279 +           && au_ibstart(inode) <= bindex
14280 +           && bindex <= au_ibend(inode)) {
14281 +               /*
14282 +                * permission check is unnecessary since vfsub routine
14283 +                * will be called later
14284 +                */
14285 +               struct inode *hi = au_h_iptr(inode, bindex);
14286 +               if (hi)
14287 +                       err = IS_IMMUTABLE(hi) ? -EROFS : 0;
14288 +       }
14289 +
14290 +       return err;
14291 +}
14292 +
14293 +int au_test_h_perm(struct inode *h_inode, int mask)
14294 +{
14295 +       if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
14296 +               return 0;
14297 +       return inode_permission(h_inode, mask);
14298 +}
14299 +
14300 +int au_test_h_perm_sio(struct inode *h_inode, int mask)
14301 +{
14302 +       if (au_test_nfs(h_inode->i_sb)
14303 +           && (mask & MAY_WRITE)
14304 +           && S_ISDIR(h_inode->i_mode))
14305 +               mask |= MAY_READ; /* force permission check */
14306 +       return au_test_h_perm(h_inode, mask);
14307 +}
14308 diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
14309 --- /usr/share/empty/fs/aufs/inode.h    1970-01-01 01:00:00.000000000 +0100
14310 +++ linux/fs/aufs/inode.h       2013-01-11 19:46:12.639281345 +0100
14311 @@ -0,0 +1,588 @@
14312 +/*
14313 + * Copyright (C) 2005-2013 Junjiro R. Okajima
14314 + *
14315 + * This program, aufs is free software; you can redistribute it and/or modify
14316 + * it under the terms of the GNU General Public License as published by
14317 + * the Free Software Foundation; either version 2 of the License, or
14318 + * (at your option) any later version.
14319 + *
14320 + * This program is distributed in the hope that it will be useful,
14321 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14322 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14323 + * GNU General Public License for more details.
14324 + *
14325 + * You should have received a copy of the GNU General Public License
14326 + * along with this program; if not, write to the Free Software
14327 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
14328 + */
14329 +
14330 +/*
14331 + * inode operations
14332 + */
14333 +
14334 +#ifndef __AUFS_INODE_H__
14335 +#define __AUFS_INODE_H__
14336 +
14337 +#ifdef __KERNEL__
14338 +
14339 +#include <linux/fsnotify.h>
14340 +#include "rwsem.h"
14341 +
14342 +struct vfsmount;
14343 +
14344 +struct au_hnotify {
14345 +#ifdef CONFIG_AUFS_HNOTIFY
14346 +#ifdef CONFIG_AUFS_HFSNOTIFY
14347 +       /* never use fsnotify_add_vfsmount_mark() */
14348 +       struct fsnotify_mark            hn_mark;
14349 +#endif
14350 +       struct inode                    *hn_aufs_inode; /* no get/put */
14351 +#endif
14352 +} ____cacheline_aligned_in_smp;
14353 +
14354 +struct au_hinode {
14355 +       struct inode            *hi_inode;
14356 +       aufs_bindex_t           hi_id;
14357 +#ifdef CONFIG_AUFS_HNOTIFY
14358 +       struct au_hnotify       *hi_notify;
14359 +#endif
14360 +
14361 +       /* reference to the copied-up whiteout with get/put */
14362 +       struct dentry           *hi_whdentry;
14363 +};
14364 +
14365 +/* ig_flags */
14366 +#define AuIG_HALF_REFRESHED            1
14367 +#define au_ig_ftest(flags, name)       ((flags) & AuIG_##name)
14368 +#define au_ig_fset(flags, name) \
14369 +       do { (flags) |= AuIG_##name; } while (0)
14370 +#define au_ig_fclr(flags, name) \
14371 +       do { (flags) &= ~AuIG_##name; } while (0)
14372 +
14373 +struct au_iigen {
14374 +       __u32           ig_generation, ig_flags;
14375 +};
14376 +
14377 +struct au_vdir;
14378 +struct au_iinfo {
14379 +       spinlock_t              ii_genspin;
14380 +       struct au_iigen         ii_generation;
14381 +       struct super_block      *ii_hsb1;       /* no get/put */
14382 +
14383 +       struct au_rwsem         ii_rwsem;
14384 +       aufs_bindex_t           ii_bstart, ii_bend;
14385 +       __u32                   ii_higen;
14386 +       struct au_hinode        *ii_hinode;
14387 +       struct au_vdir          *ii_vdir;
14388 +};
14389 +
14390 +struct au_icntnr {
14391 +       struct au_iinfo iinfo;
14392 +       struct inode vfs_inode;
14393 +} ____cacheline_aligned_in_smp;
14394 +
14395 +/* au_pin flags */
14396 +#define AuPin_DI_LOCKED                1
14397 +#define AuPin_MNT_WRITE                (1 << 1)
14398 +#define au_ftest_pin(flags, name)      ((flags) & AuPin_##name)
14399 +#define au_fset_pin(flags, name) \
14400 +       do { (flags) |= AuPin_##name; } while (0)
14401 +#define au_fclr_pin(flags, name) \
14402 +       do { (flags) &= ~AuPin_##name; } while (0)
14403 +
14404 +struct au_pin {
14405 +       /* input */
14406 +       struct dentry *dentry;
14407 +       unsigned int udba;
14408 +       unsigned char lsc_di, lsc_hi, flags;
14409 +       aufs_bindex_t bindex;
14410 +
14411 +       /* output */
14412 +       struct dentry *parent;
14413 +       struct au_hinode *hdir;
14414 +       struct vfsmount *h_mnt;
14415 +};
14416 +
14417 +/* ---------------------------------------------------------------------- */
14418 +
14419 +static inline struct au_iinfo *au_ii(struct inode *inode)
14420 +{
14421 +       struct au_iinfo *iinfo;
14422 +
14423 +       iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
14424 +       if (iinfo->ii_hinode)
14425 +               return iinfo;
14426 +       return NULL; /* debugging bad_inode case */
14427 +}
14428 +
14429 +/* ---------------------------------------------------------------------- */
14430 +
14431 +/* inode.c */
14432 +struct inode *au_igrab(struct inode *inode);
14433 +int au_refresh_hinode_self(struct inode *inode);
14434 +int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
14435 +int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14436 +          unsigned int d_type, ino_t *ino);
14437 +struct inode *au_new_inode(struct dentry *dentry, int must_new);
14438 +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14439 +              struct inode *inode);
14440 +int au_test_h_perm(struct inode *h_inode, int mask);
14441 +int au_test_h_perm_sio(struct inode *h_inode, int mask);
14442 +
14443 +static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
14444 +                           ino_t h_ino, unsigned int d_type, ino_t *ino)
14445 +{
14446 +#ifdef CONFIG_AUFS_SHWH
14447 +       return au_ino(sb, bindex, h_ino, d_type, ino);
14448 +#else
14449 +       return 0;
14450 +#endif
14451 +}
14452 +
14453 +/* i_op.c */
14454 +extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
14455 +
14456 +/* au_wr_dir flags */
14457 +#define AuWrDir_ADD_ENTRY      1
14458 +#define AuWrDir_ISDIR          (1 << 1)
14459 +#define au_ftest_wrdir(flags, name)    ((flags) & AuWrDir_##name)
14460 +#define au_fset_wrdir(flags, name) \
14461 +       do { (flags) |= AuWrDir_##name; } while (0)
14462 +#define au_fclr_wrdir(flags, name) \
14463 +       do { (flags) &= ~AuWrDir_##name; } while (0)
14464 +
14465 +struct au_wr_dir_args {
14466 +       aufs_bindex_t force_btgt;
14467 +       unsigned char flags;
14468 +};
14469 +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
14470 +             struct au_wr_dir_args *args);
14471 +
14472 +struct dentry *au_pinned_h_parent(struct au_pin *pin);
14473 +void au_pin_init(struct au_pin *pin, struct dentry *dentry,
14474 +                aufs_bindex_t bindex, int lsc_di, int lsc_hi,
14475 +                unsigned int udba, unsigned char flags);
14476 +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
14477 +          unsigned int udba, unsigned char flags) __must_check;
14478 +int au_do_pin(struct au_pin *pin) __must_check;
14479 +void au_unpin(struct au_pin *pin);
14480 +
14481 +/* i_op_add.c */
14482 +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
14483 +              struct dentry *h_parent, int isdir);
14484 +int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
14485 +              dev_t dev);
14486 +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
14487 +int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
14488 +               bool want_excl);
14489 +int aufs_link(struct dentry *src_dentry, struct inode *dir,
14490 +             struct dentry *dentry);
14491 +int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
14492 +
14493 +/* i_op_del.c */
14494 +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
14495 +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
14496 +              struct dentry *h_parent, int isdir);
14497 +int aufs_unlink(struct inode *dir, struct dentry *dentry);
14498 +int aufs_rmdir(struct inode *dir, struct dentry *dentry);
14499 +
14500 +/* i_op_ren.c */
14501 +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
14502 +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
14503 +               struct inode *dir, struct dentry *dentry);
14504 +
14505 +/* iinfo.c */
14506 +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
14507 +void au_hiput(struct au_hinode *hinode);
14508 +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
14509 +                 struct dentry *h_wh);
14510 +unsigned int au_hi_flags(struct inode *inode, int isdir);
14511 +
14512 +/* hinode flags */
14513 +#define AuHi_XINO      1
14514 +#define AuHi_HNOTIFY   (1 << 1)
14515 +#define au_ftest_hi(flags, name)       ((flags) & AuHi_##name)
14516 +#define au_fset_hi(flags, name) \
14517 +       do { (flags) |= AuHi_##name; } while (0)
14518 +#define au_fclr_hi(flags, name) \
14519 +       do { (flags) &= ~AuHi_##name; } while (0)
14520 +
14521 +#ifndef CONFIG_AUFS_HNOTIFY
14522 +#undef AuHi_HNOTIFY
14523 +#define AuHi_HNOTIFY   0
14524 +#endif
14525 +
14526 +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
14527 +                  struct inode *h_inode, unsigned int flags);
14528 +
14529 +void au_update_iigen(struct inode *inode, int half);
14530 +void au_update_ibrange(struct inode *inode, int do_put_zero);
14531 +
14532 +void au_icntnr_init_once(void *_c);
14533 +int au_iinfo_init(struct inode *inode);
14534 +void au_iinfo_fin(struct inode *inode);
14535 +int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
14536 +
14537 +#ifdef CONFIG_PROC_FS
14538 +/* plink.c */
14539 +int au_plink_maint(struct super_block *sb, int flags);
14540 +void au_plink_maint_leave(struct au_sbinfo *sbinfo);
14541 +int au_plink_maint_enter(struct super_block *sb);
14542 +#ifdef CONFIG_AUFS_DEBUG
14543 +void au_plink_list(struct super_block *sb);
14544 +#else
14545 +AuStubVoid(au_plink_list, struct super_block *sb)
14546 +#endif
14547 +int au_plink_test(struct inode *inode);
14548 +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
14549 +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
14550 +                    struct dentry *h_dentry);
14551 +void au_plink_put(struct super_block *sb, int verbose);
14552 +void au_plink_clean(struct super_block *sb, int verbose);
14553 +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
14554 +#else
14555 +AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
14556 +AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
14557 +AuStubInt0(au_plink_maint_enter, struct super_block *sb);
14558 +AuStubVoid(au_plink_list, struct super_block *sb);
14559 +AuStubInt0(au_plink_test, struct inode *inode);
14560 +AuStub(struct dentry *, au_plink_lkup, return NULL,
14561 +       struct inode *inode, aufs_bindex_t bindex);
14562 +AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
14563 +          struct dentry *h_dentry);
14564 +AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
14565 +AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
14566 +AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
14567 +#endif /* CONFIG_PROC_FS */
14568 +
14569 +/* ---------------------------------------------------------------------- */
14570 +
14571 +/* lock subclass for iinfo */
14572 +enum {
14573 +       AuLsc_II_CHILD,         /* child first */
14574 +       AuLsc_II_CHILD2,        /* rename(2), link(2), and cpup at hnotify */
14575 +       AuLsc_II_CHILD3,        /* copyup dirs */
14576 +       AuLsc_II_PARENT,        /* see AuLsc_I_PARENT in vfsub.h */
14577 +       AuLsc_II_PARENT2,
14578 +       AuLsc_II_PARENT3,       /* copyup dirs */
14579 +       AuLsc_II_NEW_CHILD
14580 +};
14581 +
14582 +/*
14583 + * ii_read_lock_child, ii_write_lock_child,
14584 + * ii_read_lock_child2, ii_write_lock_child2,
14585 + * ii_read_lock_child3, ii_write_lock_child3,
14586 + * ii_read_lock_parent, ii_write_lock_parent,
14587 + * ii_read_lock_parent2, ii_write_lock_parent2,
14588 + * ii_read_lock_parent3, ii_write_lock_parent3,
14589 + * ii_read_lock_new_child, ii_write_lock_new_child,
14590 + */
14591 +#define AuReadLockFunc(name, lsc) \
14592 +static inline void ii_read_lock_##name(struct inode *i) \
14593 +{ \
14594 +       au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
14595 +}
14596 +
14597 +#define AuWriteLockFunc(name, lsc) \
14598 +static inline void ii_write_lock_##name(struct inode *i) \
14599 +{ \
14600 +       au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
14601 +}
14602 +
14603 +#define AuRWLockFuncs(name, lsc) \
14604 +       AuReadLockFunc(name, lsc) \
14605 +       AuWriteLockFunc(name, lsc)
14606 +
14607 +AuRWLockFuncs(child, CHILD);
14608 +AuRWLockFuncs(child2, CHILD2);
14609 +AuRWLockFuncs(child3, CHILD3);
14610 +AuRWLockFuncs(parent, PARENT);
14611 +AuRWLockFuncs(parent2, PARENT2);
14612 +AuRWLockFuncs(parent3, PARENT3);
14613 +AuRWLockFuncs(new_child, NEW_CHILD);
14614 +
14615 +#undef AuReadLockFunc
14616 +#undef AuWriteLockFunc
14617 +#undef AuRWLockFuncs
14618 +
14619 +/*
14620 + * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
14621 + */
14622 +AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
14623 +
14624 +#define IiMustNoWaiters(i)     AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
14625 +#define IiMustAnyLock(i)       AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
14626 +#define IiMustWriteLock(i)     AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
14627 +
14628 +/* ---------------------------------------------------------------------- */
14629 +
14630 +static inline void au_icntnr_init(struct au_icntnr *c)
14631 +{
14632 +#ifdef CONFIG_AUFS_DEBUG
14633 +       c->vfs_inode.i_mode = 0;
14634 +#endif
14635 +}
14636 +
14637 +static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
14638 +{
14639 +       unsigned int gen;
14640 +       struct au_iinfo *iinfo;
14641 +
14642 +       iinfo = au_ii(inode);
14643 +       spin_lock(&iinfo->ii_genspin);
14644 +       if (iigen)
14645 +               *iigen = iinfo->ii_generation;
14646 +       gen = iinfo->ii_generation.ig_generation;
14647 +       spin_unlock(&iinfo->ii_genspin);
14648 +
14649 +       return gen;
14650 +}
14651 +
14652 +/* tiny test for inode number */
14653 +/* tmpfs generation is too rough */
14654 +static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
14655 +{
14656 +       struct au_iinfo *iinfo;
14657 +
14658 +       iinfo = au_ii(inode);
14659 +       AuRwMustAnyLock(&iinfo->ii_rwsem);
14660 +       return !(iinfo->ii_hsb1 == h_inode->i_sb
14661 +                && iinfo->ii_higen == h_inode->i_generation);
14662 +}
14663 +
14664 +static inline void au_iigen_dec(struct inode *inode)
14665 +{
14666 +       struct au_iinfo *iinfo;
14667 +
14668 +       iinfo = au_ii(inode);
14669 +       spin_lock(&iinfo->ii_genspin);
14670 +       iinfo->ii_generation.ig_generation--;
14671 +       spin_unlock(&iinfo->ii_genspin);
14672 +}
14673 +
14674 +static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
14675 +{
14676 +       int err;
14677 +
14678 +       err = 0;
14679 +       if (unlikely(inode && au_iigen(inode, NULL) != sigen))
14680 +               err = -EIO;
14681 +
14682 +       return err;
14683 +}
14684 +
14685 +/* ---------------------------------------------------------------------- */
14686 +
14687 +static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
14688 +                                       aufs_bindex_t bindex)
14689 +{
14690 +       IiMustAnyLock(inode);
14691 +       return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
14692 +}
14693 +
14694 +static inline aufs_bindex_t au_ibstart(struct inode *inode)
14695 +{
14696 +       IiMustAnyLock(inode);
14697 +       return au_ii(inode)->ii_bstart;
14698 +}
14699 +
14700 +static inline aufs_bindex_t au_ibend(struct inode *inode)
14701 +{
14702 +       IiMustAnyLock(inode);
14703 +       return au_ii(inode)->ii_bend;
14704 +}
14705 +
14706 +static inline struct au_vdir *au_ivdir(struct inode *inode)
14707 +{
14708 +       IiMustAnyLock(inode);
14709 +       return au_ii(inode)->ii_vdir;
14710 +}
14711 +
14712 +static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
14713 +{
14714 +       IiMustAnyLock(inode);
14715 +       return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
14716 +}
14717 +
14718 +static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
14719 +{
14720 +       IiMustWriteLock(inode);
14721 +       au_ii(inode)->ii_bstart = bindex;
14722 +}
14723 +
14724 +static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
14725 +{
14726 +       IiMustWriteLock(inode);
14727 +       au_ii(inode)->ii_bend = bindex;
14728 +}
14729 +
14730 +static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
14731 +{
14732 +       IiMustWriteLock(inode);
14733 +       au_ii(inode)->ii_vdir = vdir;
14734 +}
14735 +
14736 +static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
14737 +{
14738 +       IiMustAnyLock(inode);
14739 +       return au_ii(inode)->ii_hinode + bindex;
14740 +}
14741 +
14742 +/* ---------------------------------------------------------------------- */
14743 +
14744 +static inline struct dentry *au_pinned_parent(struct au_pin *pin)
14745 +{
14746 +       if (pin)
14747 +               return pin->parent;
14748 +       return NULL;
14749 +}
14750 +
14751 +static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
14752 +{
14753 +       if (pin && pin->hdir)
14754 +               return pin->hdir->hi_inode;
14755 +       return NULL;
14756 +}
14757 +
14758 +static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
14759 +{
14760 +       if (pin)
14761 +               return pin->hdir;
14762 +       return NULL;
14763 +}
14764 +
14765 +static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
14766 +{
14767 +       if (pin)
14768 +               pin->dentry = dentry;
14769 +}
14770 +
14771 +static inline void au_pin_set_parent_lflag(struct au_pin *pin,
14772 +                                          unsigned char lflag)
14773 +{
14774 +       if (pin) {
14775 +               if (lflag)
14776 +                       au_fset_pin(pin->flags, DI_LOCKED);
14777 +               else
14778 +                       au_fclr_pin(pin->flags, DI_LOCKED);
14779 +       }
14780 +}
14781 +
14782 +static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
14783 +{
14784 +       if (pin) {
14785 +               dput(pin->parent);
14786 +               pin->parent = dget(parent);
14787 +       }
14788 +}
14789 +
14790 +/* ---------------------------------------------------------------------- */
14791 +
14792 +struct au_branch;
14793 +#ifdef CONFIG_AUFS_HNOTIFY
14794 +struct au_hnotify_op {
14795 +       void (*ctl)(struct au_hinode *hinode, int do_set);
14796 +       int (*alloc)(struct au_hinode *hinode);
14797 +
14798 +       /*
14799 +        * if it returns true, the the caller should free hinode->hi_notify,
14800 +        * otherwise ->free() frees it.
14801 +        */
14802 +       int (*free)(struct au_hinode *hinode,
14803 +                   struct au_hnotify *hn) __must_check;
14804 +
14805 +       void (*fin)(void);
14806 +       int (*init)(void);
14807 +
14808 +       int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
14809 +       void (*fin_br)(struct au_branch *br);
14810 +       int (*init_br)(struct au_branch *br, int perm);
14811 +};
14812 +
14813 +/* hnotify.c */
14814 +int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
14815 +void au_hn_free(struct au_hinode *hinode);
14816 +void au_hn_ctl(struct au_hinode *hinode, int do_set);
14817 +void au_hn_reset(struct inode *inode, unsigned int flags);
14818 +int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
14819 +              struct qstr *h_child_qstr, struct inode *h_child_inode);
14820 +int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
14821 +int au_hnotify_init_br(struct au_branch *br, int perm);
14822 +void au_hnotify_fin_br(struct au_branch *br);
14823 +int __init au_hnotify_init(void);
14824 +void au_hnotify_fin(void);
14825 +
14826 +/* hfsnotify.c */
14827 +extern const struct au_hnotify_op au_hnotify_op;
14828 +
14829 +static inline
14830 +void au_hn_init(struct au_hinode *hinode)
14831 +{
14832 +       hinode->hi_notify = NULL;
14833 +}
14834 +
14835 +static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
14836 +{
14837 +       return hinode->hi_notify;
14838 +}
14839 +
14840 +#else
14841 +static inline
14842 +int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
14843 +               struct inode *inode __maybe_unused)
14844 +{
14845 +       return -EOPNOTSUPP;
14846 +}
14847 +
14848 +static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
14849 +{
14850 +       return NULL;
14851 +}
14852 +
14853 +AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
14854 +AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
14855 +          int do_set __maybe_unused)
14856 +AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
14857 +          unsigned int flags __maybe_unused)
14858 +AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
14859 +          struct au_branch *br __maybe_unused,
14860 +          int perm __maybe_unused)
14861 +AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
14862 +          int perm __maybe_unused)
14863 +AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
14864 +AuStubInt0(__init au_hnotify_init, void)
14865 +AuStubVoid(au_hnotify_fin, void)
14866 +AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
14867 +#endif /* CONFIG_AUFS_HNOTIFY */
14868 +
14869 +static inline void au_hn_suspend(struct au_hinode *hdir)
14870 +{
14871 +       au_hn_ctl(hdir, /*do_set*/0);
14872 +}
14873 +
14874 +static inline void au_hn_resume(struct au_hinode *hdir)
14875 +{
14876 +       au_hn_ctl(hdir, /*do_set*/1);
14877 +}
14878 +
14879 +static inline void au_hn_imtx_lock(struct au_hinode *hdir)
14880 +{
14881 +       mutex_lock(&hdir->hi_inode->i_mutex);
14882 +       au_hn_suspend(hdir);
14883 +}
14884 +
14885 +static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
14886 +                                         unsigned int sc __maybe_unused)
14887 +{
14888 +       mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
14889 +       au_hn_suspend(hdir);
14890 +}
14891 +
14892 +static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
14893 +{
14894 +       au_hn_resume(hdir);
14895 +       mutex_unlock(&hdir->hi_inode->i_mutex);
14896 +}
14897 +
14898 +#endif /* __KERNEL__ */
14899 +#endif /* __AUFS_INODE_H__ */
14900 diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
14901 --- /usr/share/empty/fs/aufs/ioctl.c    1970-01-01 01:00:00.000000000 +0100
14902 +++ linux/fs/aufs/ioctl.c       2013-01-11 19:46:12.639281345 +0100
14903 @@ -0,0 +1,196 @@
14904 +/*
14905 + * Copyright (C) 2005-2013 Junjiro R. Okajima
14906 + *
14907 + * This program, aufs is free software; you can redistribute it and/or modify
14908 + * it under the terms of the GNU General Public License as published by
14909 + * the Free Software Foundation; either version 2 of the License, or
14910 + * (at your option) any later version.
14911 + *
14912 + * This program is distributed in the hope that it will be useful,
14913 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14914 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14915 + * GNU General Public License for more details.
14916 + *
14917 + * You should have received a copy of the GNU General Public License
14918 + * along with this program; if not, write to the Free Software
14919 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
14920 + */
14921 +
14922 +/*
14923 + * ioctl
14924 + * plink-management and readdir in userspace.
14925 + * assist the pathconf(3) wrapper library.
14926 + */
14927 +
14928 +#include "aufs.h"
14929 +
14930 +static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
14931 +{
14932 +       int err, fd;
14933 +       aufs_bindex_t wbi, bindex, bend;
14934 +       struct file *h_file;
14935 +       struct super_block *sb;
14936 +       struct dentry *root;
14937 +       struct au_branch *br;
14938 +       struct aufs_wbr_fd wbrfd = {
14939 +               .oflags = au_dir_roflags,
14940 +               .brid   = -1
14941 +       };
14942 +       const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
14943 +               | O_NOATIME | O_CLOEXEC;
14944 +
14945 +       AuDebugOn(wbrfd.oflags & ~valid);
14946 +
14947 +       if (arg) {
14948 +               err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
14949 +               if (unlikely(err)) {
14950 +                       err = -EFAULT;
14951 +                       goto out;
14952 +               }
14953 +
14954 +               err = -EINVAL;
14955 +               AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
14956 +               wbrfd.oflags |= au_dir_roflags;
14957 +               AuDbg("0%o\n", wbrfd.oflags);
14958 +               if (unlikely(wbrfd.oflags & ~valid))
14959 +                       goto out;
14960 +       }
14961 +
14962 +       fd = get_unused_fd();
14963 +       err = fd;
14964 +       if (unlikely(fd < 0))
14965 +               goto out;
14966 +
14967 +       h_file = ERR_PTR(-EINVAL);
14968 +       wbi = 0;
14969 +       br = NULL;
14970 +       sb = path->dentry->d_sb;
14971 +       root = sb->s_root;
14972 +       aufs_read_lock(root, AuLock_IR);
14973 +       bend = au_sbend(sb);
14974 +       if (wbrfd.brid >= 0) {
14975 +               wbi = au_br_index(sb, wbrfd.brid);
14976 +               if (unlikely(wbi < 0 || wbi > bend))
14977 +                       goto out_unlock;
14978 +       }
14979 +
14980 +       h_file = ERR_PTR(-ENOENT);
14981 +       br = au_sbr(sb, wbi);
14982 +       if (!au_br_writable(br->br_perm)) {
14983 +               if (arg)
14984 +                       goto out_unlock;
14985 +
14986 +               bindex = wbi + 1;
14987 +               wbi = -1;
14988 +               for (; bindex <= bend; bindex++) {
14989 +                       br = au_sbr(sb, bindex);
14990 +                       if (au_br_writable(br->br_perm)) {
14991 +                               wbi = bindex;
14992 +                               br = au_sbr(sb, wbi);
14993 +                               break;
14994 +                       }
14995 +               }
14996 +       }
14997 +       AuDbg("wbi %d\n", wbi);
14998 +       if (wbi >= 0)
14999 +               h_file = au_h_open(root, wbi, wbrfd.oflags, NULL);
15000 +
15001 +out_unlock:
15002 +       aufs_read_unlock(root, AuLock_IR);
15003 +       err = PTR_ERR(h_file);
15004 +       if (IS_ERR(h_file))
15005 +               goto out_fd;
15006 +
15007 +       atomic_dec(&br->br_count); /* cf. au_h_open() */
15008 +       fd_install(fd, h_file);
15009 +       err = fd;
15010 +       goto out; /* success */
15011 +
15012 +out_fd:
15013 +       put_unused_fd(fd);
15014 +out:
15015 +       AuTraceErr(err);
15016 +       return err;
15017 +}
15018 +
15019 +/* ---------------------------------------------------------------------- */
15020 +
15021 +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
15022 +{
15023 +       long err;
15024 +
15025 +       switch (cmd) {
15026 +       case AUFS_CTL_RDU:
15027 +       case AUFS_CTL_RDU_INO:
15028 +               err = au_rdu_ioctl(file, cmd, arg);
15029 +               break;
15030 +
15031 +       case AUFS_CTL_WBR_FD:
15032 +               err = au_wbr_fd(&file->f_path, (void __user *)arg);
15033 +               break;
15034 +
15035 +       case AUFS_CTL_IBUSY:
15036 +               err = au_ibusy_ioctl(file, arg);
15037 +               break;
15038 +
15039 +       default:
15040 +               /* do not call the lower */
15041 +               AuDbg("0x%x\n", cmd);
15042 +               err = -ENOTTY;
15043 +       }
15044 +
15045 +       AuTraceErr(err);
15046 +       return err;
15047 +}
15048 +
15049 +long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
15050 +{
15051 +       long err;
15052 +
15053 +       switch (cmd) {
15054 +       case AUFS_CTL_WBR_FD:
15055 +               err = au_wbr_fd(&file->f_path, (void __user *)arg);
15056 +               break;
15057 +
15058 +       default:
15059 +               /* do not call the lower */
15060 +               AuDbg("0x%x\n", cmd);
15061 +               err = -ENOTTY;
15062 +       }
15063 +
15064 +       AuTraceErr(err);
15065 +       return err;
15066 +}
15067 +
15068 +#ifdef CONFIG_COMPAT
15069 +long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15070 +                          unsigned long arg)
15071 +{
15072 +       long err;
15073 +
15074 +       switch (cmd) {
15075 +       case AUFS_CTL_RDU:
15076 +       case AUFS_CTL_RDU_INO:
15077 +               err = au_rdu_compat_ioctl(file, cmd, arg);
15078 +               break;
15079 +
15080 +       case AUFS_CTL_IBUSY:
15081 +               err = au_ibusy_compat_ioctl(file, arg);
15082 +               break;
15083 +
15084 +       default:
15085 +               err = aufs_ioctl_dir(file, cmd, arg);
15086 +       }
15087 +
15088 +       AuTraceErr(err);
15089 +       return err;
15090 +}
15091 +
15092 +#if 0 /* unused yet */
15093 +long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15094 +                             unsigned long arg)
15095 +{
15096 +       return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
15097 +}
15098 +#endif
15099 +#endif
15100 diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
15101 --- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
15102 +++ linux/fs/aufs/i_op_add.c    2013-01-11 19:46:12.639281345 +0100
15103 @@ -0,0 +1,713 @@
15104 +/*
15105 + * Copyright (C) 2005-2013 Junjiro R. Okajima
15106 + *
15107 + * This program, aufs is free software; you can redistribute it and/or modify
15108 + * it under the terms of the GNU General Public License as published by
15109 + * the Free Software Foundation; either version 2 of the License, or
15110 + * (at your option) any later version.
15111 + *
15112 + * This program is distributed in the hope that it will be useful,
15113 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15114 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15115 + * GNU General Public License for more details.
15116 + *
15117 + * You should have received a copy of the GNU General Public License
15118 + * along with this program; if not, write to the Free Software
15119 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15120 + */
15121 +
15122 +/*
15123 + * inode operations (add entry)
15124 + */
15125 +
15126 +#include "aufs.h"
15127 +
15128 +/*
15129 + * final procedure of adding a new entry, except link(2).
15130 + * remove whiteout, instantiate, copyup the parent dir's times and size
15131 + * and update version.
15132 + * if it failed, re-create the removed whiteout.
15133 + */
15134 +static int epilog(struct inode *dir, aufs_bindex_t bindex,
15135 +                 struct dentry *wh_dentry, struct dentry *dentry)
15136 +{
15137 +       int err, rerr;
15138 +       aufs_bindex_t bwh;
15139 +       struct path h_path;
15140 +       struct inode *inode, *h_dir;
15141 +       struct dentry *wh;
15142 +
15143 +       bwh = -1;
15144 +       if (wh_dentry) {
15145 +               h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
15146 +               IMustLock(h_dir);
15147 +               AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
15148 +               bwh = au_dbwh(dentry);
15149 +               h_path.dentry = wh_dentry;
15150 +               h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
15151 +               err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
15152 +                                         dentry);
15153 +               if (unlikely(err))
15154 +                       goto out;
15155 +       }
15156 +
15157 +       inode = au_new_inode(dentry, /*must_new*/1);
15158 +       if (!IS_ERR(inode)) {
15159 +               d_instantiate(dentry, inode);
15160 +               dir = dentry->d_parent->d_inode; /* dir inode is locked */
15161 +               IMustLock(dir);
15162 +               if (au_ibstart(dir) == au_dbstart(dentry))
15163 +                       au_cpup_attr_timesizes(dir);
15164 +               dir->i_version++;
15165 +               return 0; /* success */
15166 +       }
15167 +
15168 +       err = PTR_ERR(inode);
15169 +       if (!wh_dentry)
15170 +               goto out;
15171 +
15172 +       /* revert */
15173 +       /* dir inode is locked */
15174 +       wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
15175 +       rerr = PTR_ERR(wh);
15176 +       if (IS_ERR(wh)) {
15177 +               AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
15178 +                       AuDLNPair(dentry), err, rerr);
15179 +               err = -EIO;
15180 +       } else
15181 +               dput(wh);
15182 +
15183 +out:
15184 +       return err;
15185 +}
15186 +
15187 +static int au_d_may_add(struct dentry *dentry)
15188 +{
15189 +       int err;
15190 +
15191 +       err = 0;
15192 +       if (unlikely(d_unhashed(dentry)))
15193 +               err = -ENOENT;
15194 +       if (unlikely(dentry->d_inode))
15195 +               err = -EEXIST;
15196 +       return err;
15197 +}
15198 +
15199 +/*
15200 + * simple tests for the adding inode operations.
15201 + * following the checks in vfs, plus the parent-child relationship.
15202 + */
15203 +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15204 +              struct dentry *h_parent, int isdir)
15205 +{
15206 +       int err;
15207 +       umode_t h_mode;
15208 +       struct dentry *h_dentry;
15209 +       struct inode *h_inode;
15210 +
15211 +       err = -ENAMETOOLONG;
15212 +       if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15213 +               goto out;
15214 +
15215 +       h_dentry = au_h_dptr(dentry, bindex);
15216 +       h_inode = h_dentry->d_inode;
15217 +       if (!dentry->d_inode) {
15218 +               err = -EEXIST;
15219 +               if (unlikely(h_inode))
15220 +                       goto out;
15221 +       } else {
15222 +               /* rename(2) case */
15223 +               err = -EIO;
15224 +               if (unlikely(!h_inode || !h_inode->i_nlink))
15225 +                       goto out;
15226 +
15227 +               h_mode = h_inode->i_mode;
15228 +               if (!isdir) {
15229 +                       err = -EISDIR;
15230 +                       if (unlikely(S_ISDIR(h_mode)))
15231 +                               goto out;
15232 +               } else if (unlikely(!S_ISDIR(h_mode))) {
15233 +                       err = -ENOTDIR;
15234 +                       goto out;
15235 +               }
15236 +       }
15237 +
15238 +       err = 0;
15239 +       /* expected parent dir is locked */
15240 +       if (unlikely(h_parent != h_dentry->d_parent))
15241 +               err = -EIO;
15242 +
15243 +out:
15244 +       AuTraceErr(err);
15245 +       return err;
15246 +}
15247 +
15248 +/*
15249 + * initial procedure of adding a new entry.
15250 + * prepare writable branch and the parent dir, lock it,
15251 + * and lookup whiteout for the new entry.
15252 + */
15253 +static struct dentry*
15254 +lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
15255 +                 struct dentry *src_dentry, struct au_pin *pin,
15256 +                 struct au_wr_dir_args *wr_dir_args)
15257 +{
15258 +       struct dentry *wh_dentry, *h_parent;
15259 +       struct super_block *sb;
15260 +       struct au_branch *br;
15261 +       int err;
15262 +       unsigned int udba;
15263 +       aufs_bindex_t bcpup;
15264 +
15265 +       AuDbg("%.*s\n", AuDLNPair(dentry));
15266 +
15267 +       err = au_wr_dir(dentry, src_dentry, wr_dir_args);
15268 +       bcpup = err;
15269 +       wh_dentry = ERR_PTR(err);
15270 +       if (unlikely(err < 0))
15271 +               goto out;
15272 +
15273 +       sb = dentry->d_sb;
15274 +       udba = au_opt_udba(sb);
15275 +       err = au_pin(pin, dentry, bcpup, udba,
15276 +                    AuPin_DI_LOCKED | AuPin_MNT_WRITE);
15277 +       wh_dentry = ERR_PTR(err);
15278 +       if (unlikely(err))
15279 +               goto out;
15280 +
15281 +       h_parent = au_pinned_h_parent(pin);
15282 +       if (udba != AuOpt_UDBA_NONE
15283 +           && au_dbstart(dentry) == bcpup)
15284 +               err = au_may_add(dentry, bcpup, h_parent,
15285 +                                au_ftest_wrdir(wr_dir_args->flags, ISDIR));
15286 +       else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15287 +               err = -ENAMETOOLONG;
15288 +       wh_dentry = ERR_PTR(err);
15289 +       if (unlikely(err))
15290 +               goto out_unpin;
15291 +
15292 +       br = au_sbr(sb, bcpup);
15293 +       if (dt) {
15294 +               struct path tmp = {
15295 +                       .dentry = h_parent,
15296 +                       .mnt    = br->br_mnt
15297 +               };
15298 +               au_dtime_store(dt, au_pinned_parent(pin), &tmp);
15299 +       }
15300 +
15301 +       wh_dentry = NULL;
15302 +       if (bcpup != au_dbwh(dentry))
15303 +               goto out; /* success */
15304 +
15305 +       wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
15306 +
15307 +out_unpin:
15308 +       if (IS_ERR(wh_dentry))
15309 +               au_unpin(pin);
15310 +out:
15311 +       return wh_dentry;
15312 +}
15313 +
15314 +/* ---------------------------------------------------------------------- */
15315 +
15316 +enum { Mknod, Symlink, Creat };
15317 +struct simple_arg {
15318 +       int type;
15319 +       union {
15320 +               struct {
15321 +                       umode_t mode;
15322 +                       bool want_excl;
15323 +               } c;
15324 +               struct {
15325 +                       const char *symname;
15326 +               } s;
15327 +               struct {
15328 +                       umode_t mode;
15329 +                       dev_t dev;
15330 +               } m;
15331 +       } u;
15332 +};
15333 +
15334 +static int add_simple(struct inode *dir, struct dentry *dentry,
15335 +                     struct simple_arg *arg)
15336 +{
15337 +       int err;
15338 +       aufs_bindex_t bstart;
15339 +       unsigned char created;
15340 +       struct au_dtime dt;
15341 +       struct au_pin pin;
15342 +       struct path h_path;
15343 +       struct dentry *wh_dentry, *parent;
15344 +       struct inode *h_dir;
15345 +       struct au_wr_dir_args wr_dir_args = {
15346 +               .force_btgt     = -1,
15347 +               .flags          = AuWrDir_ADD_ENTRY
15348 +       };
15349 +
15350 +       AuDbg("%.*s\n", AuDLNPair(dentry));
15351 +       IMustLock(dir);
15352 +
15353 +       parent = dentry->d_parent; /* dir inode is locked */
15354 +       err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
15355 +       if (unlikely(err))
15356 +               goto out;
15357 +       err = au_d_may_add(dentry);
15358 +       if (unlikely(err))
15359 +               goto out_unlock;
15360 +       di_write_lock_parent(parent);
15361 +       wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin,
15362 +                                     &wr_dir_args);
15363 +       err = PTR_ERR(wh_dentry);
15364 +       if (IS_ERR(wh_dentry))
15365 +               goto out_parent;
15366 +
15367 +       bstart = au_dbstart(dentry);
15368 +       h_path.dentry = au_h_dptr(dentry, bstart);
15369 +       h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
15370 +       h_dir = au_pinned_h_dir(&pin);
15371 +       switch (arg->type) {
15372 +       case Creat:
15373 +               err = vfsub_create(h_dir, &h_path, arg->u.c.mode,
15374 +                                  arg->u.c.want_excl);
15375 +               break;
15376 +       case Symlink:
15377 +               err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname);
15378 +               break;
15379 +       case Mknod:
15380 +               err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev);
15381 +               break;
15382 +       default:
15383 +               BUG();
15384 +       }
15385 +       created = !err;
15386 +       if (!err)
15387 +               err = epilog(dir, bstart, wh_dentry, dentry);
15388 +
15389 +       /* revert */
15390 +       if (unlikely(created && err && h_path.dentry->d_inode)) {
15391 +               int rerr;
15392 +               rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
15393 +               if (rerr) {
15394 +                       AuIOErr("%.*s revert failure(%d, %d)\n",
15395 +                               AuDLNPair(dentry), err, rerr);
15396 +                       err = -EIO;
15397 +               }
15398 +               au_dtime_revert(&dt);
15399 +       }
15400 +
15401 +       au_unpin(&pin);
15402 +       dput(wh_dentry);
15403 +
15404 +out_parent:
15405 +       di_write_unlock(parent);
15406 +out_unlock:
15407 +       if (unlikely(err)) {
15408 +               au_update_dbstart(dentry);
15409 +               d_drop(dentry);
15410 +       }
15411 +       aufs_read_unlock(dentry, AuLock_DW);
15412 +out:
15413 +       return err;
15414 +}
15415 +
15416 +int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15417 +              dev_t dev)
15418 +{
15419 +       struct simple_arg arg = {
15420 +               .type = Mknod,
15421 +               .u.m = {
15422 +                       .mode   = mode,
15423 +                       .dev    = dev
15424 +               }
15425 +       };
15426 +       return add_simple(dir, dentry, &arg);
15427 +}
15428 +
15429 +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
15430 +{
15431 +       struct simple_arg arg = {
15432 +               .type = Symlink,
15433 +               .u.s.symname = symname
15434 +       };
15435 +       return add_simple(dir, dentry, &arg);
15436 +}
15437 +
15438 +int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
15439 +               bool want_excl)
15440 +{
15441 +       struct simple_arg arg = {
15442 +               .type = Creat,
15443 +               .u.c = {
15444 +                       .mode           = mode,
15445 +                       .want_excl      = want_excl
15446 +               }
15447 +       };
15448 +       return add_simple(dir, dentry, &arg);
15449 +}
15450 +
15451 +/* ---------------------------------------------------------------------- */
15452 +
15453 +struct au_link_args {
15454 +       aufs_bindex_t bdst, bsrc;
15455 +       struct au_pin pin;
15456 +       struct path h_path;
15457 +       struct dentry *src_parent, *parent;
15458 +};
15459 +
15460 +static int au_cpup_before_link(struct dentry *src_dentry,
15461 +                              struct au_link_args *a)
15462 +{
15463 +       int err;
15464 +       struct dentry *h_src_dentry;
15465 +       struct mutex *h_mtx;
15466 +       struct file *h_file;
15467 +
15468 +       di_read_lock_parent(a->src_parent, AuLock_IR);
15469 +       err = au_test_and_cpup_dirs(src_dentry, a->bdst);
15470 +       if (unlikely(err))
15471 +               goto out;
15472 +
15473 +       h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
15474 +       h_mtx = &h_src_dentry->d_inode->i_mutex;
15475 +       err = au_pin(&a->pin, src_dentry, a->bdst,
15476 +                    au_opt_udba(src_dentry->d_sb),
15477 +                    AuPin_DI_LOCKED | AuPin_MNT_WRITE);
15478 +       if (unlikely(err))
15479 +               goto out;
15480 +       mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
15481 +       h_file = au_h_open_pre(src_dentry, a->bsrc);
15482 +       if (IS_ERR(h_file)) {
15483 +               err = PTR_ERR(h_file);
15484 +               h_file = NULL;
15485 +       } else
15486 +               err = au_sio_cpup_simple(src_dentry, a->bdst, -1,
15487 +                                        AuCpup_DTIME /* | AuCpup_KEEPLINO */);
15488 +       mutex_unlock(h_mtx);
15489 +       au_h_open_post(src_dentry, a->bsrc, h_file);
15490 +       au_unpin(&a->pin);
15491 +
15492 +out:
15493 +       di_read_unlock(a->src_parent, AuLock_IR);
15494 +       return err;
15495 +}
15496 +
15497 +static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a)
15498 +{
15499 +       int err;
15500 +       unsigned char plink;
15501 +       struct inode *h_inode, *inode;
15502 +       struct dentry *h_src_dentry;
15503 +       struct super_block *sb;
15504 +       struct file *h_file;
15505 +
15506 +       plink = 0;
15507 +       h_inode = NULL;
15508 +       sb = src_dentry->d_sb;
15509 +       inode = src_dentry->d_inode;
15510 +       if (au_ibstart(inode) <= a->bdst)
15511 +               h_inode = au_h_iptr(inode, a->bdst);
15512 +       if (!h_inode || !h_inode->i_nlink) {
15513 +               /* copyup src_dentry as the name of dentry. */
15514 +               au_set_dbstart(src_dentry, a->bdst);
15515 +               au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry));
15516 +               h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode;
15517 +               mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
15518 +               h_file = au_h_open_pre(src_dentry, a->bsrc);
15519 +               if (IS_ERR(h_file)) {
15520 +                       err = PTR_ERR(h_file);
15521 +                       h_file = NULL;
15522 +               } else
15523 +                       err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc,
15524 +                                                -1, AuCpup_KEEPLINO,
15525 +                                                a->parent);
15526 +               mutex_unlock(&h_inode->i_mutex);
15527 +               au_h_open_post(src_dentry, a->bsrc, h_file);
15528 +               au_set_h_dptr(src_dentry, a->bdst, NULL);
15529 +               au_set_dbstart(src_dentry, a->bsrc);
15530 +       } else {
15531 +               /* the inode of src_dentry already exists on a.bdst branch */
15532 +               h_src_dentry = d_find_alias(h_inode);
15533 +               if (!h_src_dentry && au_plink_test(inode)) {
15534 +                       plink = 1;
15535 +                       h_src_dentry = au_plink_lkup(inode, a->bdst);
15536 +                       err = PTR_ERR(h_src_dentry);
15537 +                       if (IS_ERR(h_src_dentry))
15538 +                               goto out;
15539 +
15540 +                       if (unlikely(!h_src_dentry->d_inode)) {
15541 +                               dput(h_src_dentry);
15542 +                               h_src_dentry = NULL;
15543 +                       }
15544 +
15545 +               }
15546 +               if (h_src_dentry) {
15547 +                       err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
15548 +                                        &a->h_path);
15549 +                       dput(h_src_dentry);
15550 +               } else {
15551 +                       AuIOErr("no dentry found for hi%lu on b%d\n",
15552 +                               h_inode->i_ino, a->bdst);
15553 +                       err = -EIO;
15554 +               }
15555 +       }
15556 +
15557 +       if (!err && !plink)
15558 +               au_plink_append(inode, a->bdst, a->h_path.dentry);
15559 +
15560 +out:
15561 +       AuTraceErr(err);
15562 +       return err;
15563 +}
15564 +
15565 +int aufs_link(struct dentry *src_dentry, struct inode *dir,
15566 +             struct dentry *dentry)
15567 +{
15568 +       int err, rerr;
15569 +       struct au_dtime dt;
15570 +       struct au_link_args *a;
15571 +       struct dentry *wh_dentry, *h_src_dentry;
15572 +       struct inode *inode;
15573 +       struct super_block *sb;
15574 +       struct au_wr_dir_args wr_dir_args = {
15575 +               /* .force_btgt  = -1, */
15576 +               .flags          = AuWrDir_ADD_ENTRY
15577 +       };
15578 +
15579 +       IMustLock(dir);
15580 +       inode = src_dentry->d_inode;
15581 +       IMustLock(inode);
15582 +
15583 +       err = -ENOMEM;
15584 +       a = kzalloc(sizeof(*a), GFP_NOFS);
15585 +       if (unlikely(!a))
15586 +               goto out;
15587 +
15588 +       a->parent = dentry->d_parent; /* dir inode is locked */
15589 +       err = aufs_read_and_write_lock2(dentry, src_dentry,
15590 +                                       AuLock_NOPLM | AuLock_GEN);
15591 +       if (unlikely(err))
15592 +               goto out_kfree;
15593 +       err = au_d_hashed_positive(src_dentry);
15594 +       if (unlikely(err))
15595 +               goto out_unlock;
15596 +       err = au_d_may_add(dentry);
15597 +       if (unlikely(err))
15598 +               goto out_unlock;
15599 +
15600 +       a->src_parent = dget_parent(src_dentry);
15601 +       wr_dir_args.force_btgt = au_ibstart(inode);
15602 +
15603 +       di_write_lock_parent(a->parent);
15604 +       wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
15605 +       wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
15606 +                                     &wr_dir_args);
15607 +       err = PTR_ERR(wh_dentry);
15608 +       if (IS_ERR(wh_dentry))
15609 +               goto out_parent;
15610 +
15611 +       err = 0;
15612 +       sb = dentry->d_sb;
15613 +       a->bdst = au_dbstart(dentry);
15614 +       a->h_path.dentry = au_h_dptr(dentry, a->bdst);
15615 +       a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
15616 +       a->bsrc = au_ibstart(inode);
15617 +       h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
15618 +       if (!h_src_dentry) {
15619 +               a->bsrc = au_dbstart(src_dentry);
15620 +               h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
15621 +               AuDebugOn(!h_src_dentry);
15622 +       } else if (IS_ERR(h_src_dentry))
15623 +               goto out_parent;
15624 +
15625 +       if (au_opt_test(au_mntflags(sb), PLINK)) {
15626 +               if (a->bdst < a->bsrc
15627 +                   /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
15628 +                       err = au_cpup_or_link(src_dentry, a);
15629 +               else
15630 +                       err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
15631 +                                        &a->h_path);
15632 +               dput(h_src_dentry);
15633 +       } else {
15634 +               /*
15635 +                * copyup src_dentry to the branch we process,
15636 +                * and then link(2) to it.
15637 +                */
15638 +               dput(h_src_dentry);
15639 +               if (a->bdst < a->bsrc
15640 +                   /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
15641 +                       au_unpin(&a->pin);
15642 +                       di_write_unlock(a->parent);
15643 +                       err = au_cpup_before_link(src_dentry, a);
15644 +                       di_write_lock_parent(a->parent);
15645 +                       if (!err)
15646 +                               err = au_pin(&a->pin, dentry, a->bdst,
15647 +                                            au_opt_udba(sb),
15648 +                                            AuPin_DI_LOCKED | AuPin_MNT_WRITE);
15649 +                       if (unlikely(err))
15650 +                               goto out_wh;
15651 +               }
15652 +               if (!err) {
15653 +                       h_src_dentry = au_h_dptr(src_dentry, a->bdst);
15654 +                       err = -ENOENT;
15655 +                       if (h_src_dentry && h_src_dentry->d_inode)
15656 +                               err = vfsub_link(h_src_dentry,
15657 +                                                au_pinned_h_dir(&a->pin),
15658 +                                                &a->h_path);
15659 +               }
15660 +       }
15661 +       if (unlikely(err))
15662 +               goto out_unpin;
15663 +
15664 +       if (wh_dentry) {
15665 +               a->h_path.dentry = wh_dentry;
15666 +               err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
15667 +                                         dentry);
15668 +               if (unlikely(err))
15669 +                       goto out_revert;
15670 +       }
15671 +
15672 +       dir->i_version++;
15673 +       if (au_ibstart(dir) == au_dbstart(dentry))
15674 +               au_cpup_attr_timesizes(dir);
15675 +       inc_nlink(inode);
15676 +       inode->i_ctime = dir->i_ctime;
15677 +       d_instantiate(dentry, au_igrab(inode));
15678 +       if (d_unhashed(a->h_path.dentry))
15679 +               /* some filesystem calls d_drop() */
15680 +               d_drop(dentry);
15681 +       goto out_unpin; /* success */
15682 +
15683 +out_revert:
15684 +       rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
15685 +       if (unlikely(rerr)) {
15686 +               AuIOErr("%.*s reverting failed(%d, %d)\n",
15687 +                       AuDLNPair(dentry), err, rerr);
15688 +               err = -EIO;
15689 +       }
15690 +       au_dtime_revert(&dt);
15691 +out_unpin:
15692 +       au_unpin(&a->pin);
15693 +out_wh:
15694 +       dput(wh_dentry);
15695 +out_parent:
15696 +       di_write_unlock(a->parent);
15697 +       dput(a->src_parent);
15698 +out_unlock:
15699 +       if (unlikely(err)) {
15700 +               au_update_dbstart(dentry);
15701 +               d_drop(dentry);
15702 +       }
15703 +       aufs_read_and_write_unlock2(dentry, src_dentry);
15704 +out_kfree:
15705 +       kfree(a);
15706 +out:
15707 +       return err;
15708 +}
15709 +
15710 +int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
15711 +{
15712 +       int err, rerr;
15713 +       aufs_bindex_t bindex;
15714 +       unsigned char diropq;
15715 +       struct path h_path;
15716 +       struct dentry *wh_dentry, *parent, *opq_dentry;
15717 +       struct mutex *h_mtx;
15718 +       struct super_block *sb;
15719 +       struct {
15720 +               struct au_pin pin;
15721 +               struct au_dtime dt;
15722 +       } *a; /* reduce the stack usage */
15723 +       struct au_wr_dir_args wr_dir_args = {
15724 +               .force_btgt     = -1,
15725 +               .flags          = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
15726 +       };
15727 +
15728 +       IMustLock(dir);
15729 +
15730 +       err = -ENOMEM;
15731 +       a = kmalloc(sizeof(*a), GFP_NOFS);
15732 +       if (unlikely(!a))
15733 +               goto out;
15734 +
15735 +       err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
15736 +       if (unlikely(err))
15737 +               goto out_free;
15738 +       err = au_d_may_add(dentry);
15739 +       if (unlikely(err))
15740 +               goto out_unlock;
15741 +
15742 +       parent = dentry->d_parent; /* dir inode is locked */
15743 +       di_write_lock_parent(parent);
15744 +       wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
15745 +                                     &a->pin, &wr_dir_args);
15746 +       err = PTR_ERR(wh_dentry);
15747 +       if (IS_ERR(wh_dentry))
15748 +               goto out_parent;
15749 +
15750 +       sb = dentry->d_sb;
15751 +       bindex = au_dbstart(dentry);
15752 +       h_path.dentry = au_h_dptr(dentry, bindex);
15753 +       h_path.mnt = au_sbr_mnt(sb, bindex);
15754 +       err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
15755 +       if (unlikely(err))
15756 +               goto out_unpin;
15757 +
15758 +       /* make the dir opaque */
15759 +       diropq = 0;
15760 +       h_mtx = &h_path.dentry->d_inode->i_mutex;
15761 +       if (wh_dentry
15762 +           || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
15763 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
15764 +               opq_dentry = au_diropq_create(dentry, bindex);
15765 +               mutex_unlock(h_mtx);
15766 +               err = PTR_ERR(opq_dentry);
15767 +               if (IS_ERR(opq_dentry))
15768 +                       goto out_dir;
15769 +               dput(opq_dentry);
15770 +               diropq = 1;
15771 +       }
15772 +
15773 +       err = epilog(dir, bindex, wh_dentry, dentry);
15774 +       if (!err) {
15775 +               inc_nlink(dir);
15776 +               goto out_unpin; /* success */
15777 +       }
15778 +
15779 +       /* revert */
15780 +       if (diropq) {
15781 +               AuLabel(revert opq);
15782 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
15783 +               rerr = au_diropq_remove(dentry, bindex);
15784 +               mutex_unlock(h_mtx);
15785 +               if (rerr) {
15786 +                       AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
15787 +                               AuDLNPair(dentry), err, rerr);
15788 +                       err = -EIO;
15789 +               }
15790 +       }
15791 +
15792 +out_dir:
15793 +       AuLabel(revert dir);
15794 +       rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
15795 +       if (rerr) {
15796 +               AuIOErr("%.*s reverting dir failed(%d, %d)\n",
15797 +                       AuDLNPair(dentry), err, rerr);
15798 +               err = -EIO;
15799 +       }
15800 +       au_dtime_revert(&a->dt);
15801 +out_unpin:
15802 +       au_unpin(&a->pin);
15803 +       dput(wh_dentry);
15804 +out_parent:
15805 +       di_write_unlock(parent);
15806 +out_unlock:
15807 +       if (unlikely(err)) {
15808 +               au_update_dbstart(dentry);
15809 +               d_drop(dentry);
15810 +       }
15811 +       aufs_read_unlock(dentry, AuLock_DW);
15812 +out_free:
15813 +       kfree(a);
15814 +out:
15815 +       return err;
15816 +}
15817 diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
15818 --- /usr/share/empty/fs/aufs/i_op.c     1970-01-01 01:00:00.000000000 +0100
15819 +++ linux/fs/aufs/i_op.c        2013-01-11 19:46:28.699667650 +0100
15820 @@ -0,0 +1,1026 @@
15821 +/*
15822 + * Copyright (C) 2005-2013 Junjiro R. Okajima
15823 + *
15824 + * This program, aufs is free software; you can redistribute it and/or modify
15825 + * it under the terms of the GNU General Public License as published by
15826 + * the Free Software Foundation; either version 2 of the License, or
15827 + * (at your option) any later version.
15828 + *
15829 + * This program is distributed in the hope that it will be useful,
15830 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15831 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15832 + * GNU General Public License for more details.
15833 + *
15834 + * You should have received a copy of the GNU General Public License
15835 + * along with this program; if not, write to the Free Software
15836 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15837 + */
15838 +
15839 +/*
15840 + * inode operations (except add/del/rename)
15841 + */
15842 +
15843 +#include <linux/device_cgroup.h>
15844 +#include <linux/fs_stack.h>
15845 +#include <linux/mm.h>
15846 +#include <linux/namei.h>
15847 +#include <linux/security.h>
15848 +#include "aufs.h"
15849 +
15850 +static int h_permission(struct inode *h_inode, int mask,
15851 +                       struct vfsmount *h_mnt, int brperm)
15852 +{
15853 +       int err;
15854 +       const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
15855 +
15856 +       err = -EACCES;
15857 +       if ((write_mask && IS_IMMUTABLE(h_inode))
15858 +           || ((mask & MAY_EXEC)
15859 +               && S_ISREG(h_inode->i_mode)
15860 +               && ((h_mnt->mnt_flags & MNT_NOEXEC)
15861 +                   || !(h_inode->i_mode & S_IXUGO))))
15862 +               goto out;
15863 +
15864 +       /*
15865 +        * - skip the lower fs test in the case of write to ro branch.
15866 +        * - nfs dir permission write check is optimized, but a policy for
15867 +        *   link/rename requires a real check.
15868 +        */
15869 +       if ((write_mask && !au_br_writable(brperm))
15870 +           || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
15871 +               && write_mask && !(mask & MAY_READ))
15872 +           || !h_inode->i_op->permission) {
15873 +               /* AuLabel(generic_permission); */
15874 +               err = generic_permission(h_inode, mask);
15875 +       } else {
15876 +               /* AuLabel(h_inode->permission); */
15877 +               err = h_inode->i_op->permission(h_inode, mask);
15878 +               AuTraceErr(err);
15879 +       }
15880 +
15881 +       if (!err)
15882 +               err = devcgroup_inode_permission(h_inode, mask);
15883 +       if (!err)
15884 +               err = security_inode_permission(h_inode, mask);
15885 +
15886 +#if 0
15887 +       if (!err) {
15888 +               /* todo: do we need to call ima_path_check()? */
15889 +               struct path h_path = {
15890 +                       .dentry =
15891 +                       .mnt    = h_mnt
15892 +               };
15893 +               err = ima_path_check(&h_path,
15894 +                                    mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
15895 +                                    IMA_COUNT_LEAVE);
15896 +       }
15897 +#endif
15898 +
15899 +out:
15900 +       return err;
15901 +}
15902 +
15903 +static int aufs_permission(struct inode *inode, int mask)
15904 +{
15905 +       int err;
15906 +       aufs_bindex_t bindex, bend;
15907 +       const unsigned char isdir = !!S_ISDIR(inode->i_mode),
15908 +               write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
15909 +       struct inode *h_inode;
15910 +       struct super_block *sb;
15911 +       struct au_branch *br;
15912 +
15913 +       /* todo: support rcu-walk? */
15914 +       if (mask & MAY_NOT_BLOCK)
15915 +               return -ECHILD;
15916 +
15917 +       sb = inode->i_sb;
15918 +       si_read_lock(sb, AuLock_FLUSH);
15919 +       ii_read_lock_child(inode);
15920 +#if 0
15921 +       err = au_iigen_test(inode, au_sigen(sb));
15922 +       if (unlikely(err))
15923 +               goto out;
15924 +#endif
15925 +
15926 +       if (!isdir || write_mask) {
15927 +               err = au_busy_or_stale();
15928 +               h_inode = au_h_iptr(inode, au_ibstart(inode));
15929 +               if (unlikely(!h_inode
15930 +                            || (h_inode->i_mode & S_IFMT)
15931 +                            != (inode->i_mode & S_IFMT)))
15932 +                       goto out;
15933 +
15934 +               err = 0;
15935 +               bindex = au_ibstart(inode);
15936 +               br = au_sbr(sb, bindex);
15937 +               err = h_permission(h_inode, mask, br->br_mnt, br->br_perm);
15938 +               if (write_mask
15939 +                   && !err
15940 +                   && !special_file(h_inode->i_mode)) {
15941 +                       /* test whether the upper writable branch exists */
15942 +                       err = -EROFS;
15943 +                       for (; bindex >= 0; bindex--)
15944 +                               if (!au_br_rdonly(au_sbr(sb, bindex))) {
15945 +                                       err = 0;
15946 +                                       break;
15947 +                               }
15948 +               }
15949 +               goto out;
15950 +       }
15951 +
15952 +       /* non-write to dir */
15953 +       err = 0;
15954 +       bend = au_ibend(inode);
15955 +       for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
15956 +               h_inode = au_h_iptr(inode, bindex);
15957 +               if (h_inode) {
15958 +                       err = au_busy_or_stale();
15959 +                       if (unlikely(!S_ISDIR(h_inode->i_mode)))
15960 +                               break;
15961 +
15962 +                       br = au_sbr(sb, bindex);
15963 +                       err = h_permission(h_inode, mask, br->br_mnt,
15964 +                                          br->br_perm);
15965 +               }
15966 +       }
15967 +
15968 +out:
15969 +       ii_read_unlock(inode);
15970 +       si_read_unlock(sb);
15971 +       return err;
15972 +}
15973 +
15974 +/* ---------------------------------------------------------------------- */
15975 +
15976 +static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
15977 +                                 unsigned int flags)
15978 +{
15979 +       struct dentry *ret, *parent;
15980 +       struct inode *inode;
15981 +       struct super_block *sb;
15982 +       int err, npositive, lc_idx;
15983 +
15984 +       IMustLock(dir);
15985 +
15986 +       /* todo: support rcu-walk? */
15987 +       ret = ERR_PTR(-ECHILD);
15988 +       if (flags & LOOKUP_RCU)
15989 +               goto out;
15990 +
15991 +       ret = ERR_PTR(-ENAMETOOLONG);
15992 +       if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15993 +               goto out;
15994 +
15995 +       sb = dir->i_sb;
15996 +       err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
15997 +       ret = ERR_PTR(err);
15998 +       if (unlikely(err))
15999 +               goto out;
16000 +
16001 +       err = au_di_init(dentry);
16002 +       ret = ERR_PTR(err);
16003 +       if (unlikely(err))
16004 +               goto out_si;
16005 +
16006 +       inode = NULL;
16007 +       npositive = 0; /* suppress a warning */
16008 +       parent = dentry->d_parent; /* dir inode is locked */
16009 +       di_read_lock_parent(parent, AuLock_IR);
16010 +       err = au_alive_dir(parent);
16011 +       if (!err)
16012 +               err = au_digen_test(parent, au_sigen(sb));
16013 +       if (!err) {
16014 +               npositive = au_lkup_dentry(dentry, au_dbstart(parent),
16015 +                                          /*type*/0);
16016 +               err = npositive;
16017 +       }
16018 +       di_read_unlock(parent, AuLock_IR);
16019 +       ret = ERR_PTR(err);
16020 +       if (unlikely(err < 0))
16021 +               goto out_unlock;
16022 +
16023 +       if (npositive) {
16024 +               inode = au_new_inode(dentry, /*must_new*/0);
16025 +               ret = (void *)inode;
16026 +       }
16027 +       if (IS_ERR(inode)) {
16028 +               inode = NULL;
16029 +               goto out_unlock;
16030 +       }
16031 +
16032 +       ret = d_splice_alias(inode, dentry);
16033 +#if 0
16034 +       if (unlikely(d_need_lookup(dentry))) {
16035 +               spin_lock(&dentry->d_lock);
16036 +               dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
16037 +               spin_unlock(&dentry->d_lock);
16038 +       } else
16039 +#endif
16040 +       if (unlikely(IS_ERR(ret) && inode)) {
16041 +               ii_write_unlock(inode);
16042 +               iput(inode);
16043 +               inode = NULL;
16044 +       }
16045 +
16046 +out_unlock:
16047 +       di_write_unlock(dentry);
16048 +       if (inode) {
16049 +               lc_idx = AuLcNonDir_DIINFO;
16050 +               if (S_ISLNK(inode->i_mode))
16051 +                       lc_idx = AuLcSymlink_DIINFO;
16052 +               else if (S_ISDIR(inode->i_mode))
16053 +                       lc_idx = AuLcDir_DIINFO;
16054 +               au_rw_class(&au_di(dentry)->di_rwsem, au_lc_key + lc_idx);
16055 +       }
16056 +out_si:
16057 +       si_read_unlock(sb);
16058 +out:
16059 +       return ret;
16060 +}
16061 +
16062 +/* ---------------------------------------------------------------------- */
16063 +
16064 +static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
16065 +                         const unsigned char add_entry, aufs_bindex_t bcpup,
16066 +                         aufs_bindex_t bstart)
16067 +{
16068 +       int err;
16069 +       struct dentry *h_parent;
16070 +       struct inode *h_dir;
16071 +
16072 +       if (add_entry)
16073 +               IMustLock(parent->d_inode);
16074 +       else
16075 +               di_write_lock_parent(parent);
16076 +
16077 +       err = 0;
16078 +       if (!au_h_dptr(parent, bcpup)) {
16079 +               if (bstart < bcpup)
16080 +                       err = au_cpdown_dirs(dentry, bcpup);
16081 +               else
16082 +                       err = au_cpup_dirs(dentry, bcpup);
16083 +       }
16084 +       if (!err && add_entry) {
16085 +               h_parent = au_h_dptr(parent, bcpup);
16086 +               h_dir = h_parent->d_inode;
16087 +               mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
16088 +               err = au_lkup_neg(dentry, bcpup);
16089 +               /* todo: no unlock here */
16090 +               mutex_unlock(&h_dir->i_mutex);
16091 +
16092 +               AuDbg("bcpup %d\n", bcpup);
16093 +               if (!err) {
16094 +                       if (!dentry->d_inode)
16095 +                               au_set_h_dptr(dentry, bstart, NULL);
16096 +                       au_update_dbrange(dentry, /*do_put_zero*/0);
16097 +               }
16098 +       }
16099 +
16100 +       if (!add_entry)
16101 +               di_write_unlock(parent);
16102 +       if (!err)
16103 +               err = bcpup; /* success */
16104 +
16105 +       AuTraceErr(err);
16106 +       return err;
16107 +}
16108 +
16109 +/*
16110 + * decide the branch and the parent dir where we will create a new entry.
16111 + * returns new bindex or an error.
16112 + * copyup the parent dir if needed.
16113 + */
16114 +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16115 +             struct au_wr_dir_args *args)
16116 +{
16117 +       int err;
16118 +       aufs_bindex_t bcpup, bstart, src_bstart;
16119 +       const unsigned char add_entry = !!au_ftest_wrdir(args->flags,
16120 +                                                        ADD_ENTRY);
16121 +       struct super_block *sb;
16122 +       struct dentry *parent;
16123 +       struct au_sbinfo *sbinfo;
16124 +
16125 +       sb = dentry->d_sb;
16126 +       sbinfo = au_sbi(sb);
16127 +       parent = dget_parent(dentry);
16128 +       bstart = au_dbstart(dentry);
16129 +       bcpup = bstart;
16130 +       if (args->force_btgt < 0) {
16131 +               if (src_dentry) {
16132 +                       src_bstart = au_dbstart(src_dentry);
16133 +                       if (src_bstart < bstart)
16134 +                               bcpup = src_bstart;
16135 +               } else if (add_entry) {
16136 +                       err = AuWbrCreate(sbinfo, dentry,
16137 +                                         au_ftest_wrdir(args->flags, ISDIR));
16138 +                       bcpup = err;
16139 +               }
16140 +
16141 +               if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
16142 +                       if (add_entry)
16143 +                               err = AuWbrCopyup(sbinfo, dentry);
16144 +                       else {
16145 +                               if (!IS_ROOT(dentry)) {
16146 +                                       di_read_lock_parent(parent, !AuLock_IR);
16147 +                                       err = AuWbrCopyup(sbinfo, dentry);
16148 +                                       di_read_unlock(parent, !AuLock_IR);
16149 +                               } else
16150 +                                       err = AuWbrCopyup(sbinfo, dentry);
16151 +                       }
16152 +                       bcpup = err;
16153 +                       if (unlikely(err < 0))
16154 +                               goto out;
16155 +               }
16156 +       } else {
16157 +               bcpup = args->force_btgt;
16158 +               AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
16159 +       }
16160 +
16161 +       AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
16162 +       err = bcpup;
16163 +       if (bcpup == bstart)
16164 +               goto out; /* success */
16165 +
16166 +       /* copyup the new parent into the branch we process */
16167 +       err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
16168 +       if (err >= 0) {
16169 +               if (!dentry->d_inode) {
16170 +                       au_set_h_dptr(dentry, bstart, NULL);
16171 +                       au_set_dbstart(dentry, bcpup);
16172 +                       au_set_dbend(dentry, bcpup);
16173 +               }
16174 +               AuDebugOn(add_entry && !au_h_dptr(dentry, bcpup));
16175 +       }
16176 +
16177 +out:
16178 +       dput(parent);
16179 +       return err;
16180 +}
16181 +
16182 +/* ---------------------------------------------------------------------- */
16183 +
16184 +struct dentry *au_pinned_h_parent(struct au_pin *pin)
16185 +{
16186 +       if (pin && pin->parent)
16187 +               return au_h_dptr(pin->parent, pin->bindex);
16188 +       return NULL;
16189 +}
16190 +
16191 +void au_unpin(struct au_pin *p)
16192 +{
16193 +       if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
16194 +               vfsub_mnt_drop_write(p->h_mnt);
16195 +       if (!p->hdir)
16196 +               return;
16197 +
16198 +       au_hn_imtx_unlock(p->hdir);
16199 +       if (!au_ftest_pin(p->flags, DI_LOCKED))
16200 +               di_read_unlock(p->parent, AuLock_IR);
16201 +       iput(p->hdir->hi_inode);
16202 +       dput(p->parent);
16203 +       p->parent = NULL;
16204 +       p->hdir = NULL;
16205 +       p->h_mnt = NULL;
16206 +}
16207 +
16208 +int au_do_pin(struct au_pin *p)
16209 +{
16210 +       int err;
16211 +       struct super_block *sb;
16212 +       struct dentry *h_dentry, *h_parent;
16213 +       struct au_branch *br;
16214 +       struct inode *h_dir;
16215 +
16216 +       err = 0;
16217 +       sb = p->dentry->d_sb;
16218 +       br = au_sbr(sb, p->bindex);
16219 +       if (IS_ROOT(p->dentry)) {
16220 +               if (au_ftest_pin(p->flags, MNT_WRITE)) {
16221 +                       p->h_mnt = br->br_mnt;
16222 +                       err = vfsub_mnt_want_write(p->h_mnt);
16223 +                       if (unlikely(err)) {
16224 +                               au_fclr_pin(p->flags, MNT_WRITE);
16225 +                               goto out_err;
16226 +                       }
16227 +               }
16228 +               goto out;
16229 +       }
16230 +
16231 +       h_dentry = NULL;
16232 +       if (p->bindex <= au_dbend(p->dentry))
16233 +               h_dentry = au_h_dptr(p->dentry, p->bindex);
16234 +
16235 +       p->parent = dget_parent(p->dentry);
16236 +       if (!au_ftest_pin(p->flags, DI_LOCKED))
16237 +               di_read_lock(p->parent, AuLock_IR, p->lsc_di);
16238 +
16239 +       h_dir = NULL;
16240 +       h_parent = au_h_dptr(p->parent, p->bindex);
16241 +       p->hdir = au_hi(p->parent->d_inode, p->bindex);
16242 +       if (p->hdir)
16243 +               h_dir = p->hdir->hi_inode;
16244 +
16245 +       /*
16246 +        * udba case, or
16247 +        * if DI_LOCKED is not set, then p->parent may be different
16248 +        * and h_parent can be NULL.
16249 +        */
16250 +       if (unlikely(!p->hdir || !h_dir || !h_parent)) {
16251 +               err = -EBUSY;
16252 +               if (!au_ftest_pin(p->flags, DI_LOCKED))
16253 +                       di_read_unlock(p->parent, AuLock_IR);
16254 +               dput(p->parent);
16255 +               p->parent = NULL;
16256 +               goto out_err;
16257 +       }
16258 +
16259 +       au_igrab(h_dir);
16260 +       au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
16261 +
16262 +       if (unlikely(p->hdir->hi_inode != h_parent->d_inode)) {
16263 +               err = -EBUSY;
16264 +               goto out_unpin;
16265 +       }
16266 +       if (h_dentry) {
16267 +               err = au_h_verify(h_dentry, p->udba, h_dir, h_parent, br);
16268 +               if (unlikely(err)) {
16269 +                       au_fclr_pin(p->flags, MNT_WRITE);
16270 +                       goto out_unpin;
16271 +               }
16272 +       }
16273 +
16274 +       if (au_ftest_pin(p->flags, MNT_WRITE)) {
16275 +               p->h_mnt = br->br_mnt;
16276 +               err = vfsub_mnt_want_write(p->h_mnt);
16277 +               if (unlikely(err)) {
16278 +                       au_fclr_pin(p->flags, MNT_WRITE);
16279 +                       goto out_unpin;
16280 +               }
16281 +       }
16282 +       goto out; /* success */
16283 +
16284 +out_unpin:
16285 +       au_unpin(p);
16286 +out_err:
16287 +       pr_err("err %d\n", err);
16288 +       err = au_busy_or_stale();
16289 +out:
16290 +       return err;
16291 +}
16292 +
16293 +void au_pin_init(struct au_pin *p, struct dentry *dentry,
16294 +                aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16295 +                unsigned int udba, unsigned char flags)
16296 +{
16297 +       p->dentry = dentry;
16298 +       p->udba = udba;
16299 +       p->lsc_di = lsc_di;
16300 +       p->lsc_hi = lsc_hi;
16301 +       p->flags = flags;
16302 +       p->bindex = bindex;
16303 +
16304 +       p->parent = NULL;
16305 +       p->hdir = NULL;
16306 +       p->h_mnt = NULL;
16307 +}
16308 +
16309 +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16310 +          unsigned int udba, unsigned char flags)
16311 +{
16312 +       au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
16313 +                   udba, flags);
16314 +       return au_do_pin(pin);
16315 +}
16316 +
16317 +/* ---------------------------------------------------------------------- */
16318 +
16319 +/*
16320 + * ->setattr() and ->getattr() are called in various cases.
16321 + * chmod, stat: dentry is revalidated.
16322 + * fchmod, fstat: file and dentry are not revalidated, additionally they may be
16323 + *               unhashed.
16324 + * for ->setattr(), ia->ia_file is passed from ftruncate only.
16325 + */
16326 +/* todo: consolidate with do_refresh() and simple_reval_dpath() */
16327 +static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
16328 +{
16329 +       int err;
16330 +       struct inode *inode;
16331 +       struct dentry *parent;
16332 +
16333 +       err = 0;
16334 +       inode = dentry->d_inode;
16335 +       if (au_digen_test(dentry, sigen)) {
16336 +               parent = dget_parent(dentry);
16337 +               di_read_lock_parent(parent, AuLock_IR);
16338 +               err = au_refresh_dentry(dentry, parent);
16339 +               di_read_unlock(parent, AuLock_IR);
16340 +               dput(parent);
16341 +       }
16342 +
16343 +       AuTraceErr(err);
16344 +       return err;
16345 +}
16346 +
16347 +#define AuIcpup_DID_CPUP       1
16348 +#define au_ftest_icpup(flags, name)    ((flags) & AuIcpup_##name)
16349 +#define au_fset_icpup(flags, name) \
16350 +       do { (flags) |= AuIcpup_##name; } while (0)
16351 +#define au_fclr_icpup(flags, name) \
16352 +       do { (flags) &= ~AuIcpup_##name; } while (0)
16353 +
16354 +struct au_icpup_args {
16355 +       unsigned char flags;
16356 +       unsigned char pin_flags;
16357 +       aufs_bindex_t btgt;
16358 +       unsigned int udba;
16359 +       struct au_pin pin;
16360 +       struct path h_path;
16361 +       struct inode *h_inode;
16362 +};
16363 +
16364 +static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
16365 +                           struct au_icpup_args *a)
16366 +{
16367 +       int err;
16368 +       loff_t sz;
16369 +       aufs_bindex_t bstart, ibstart;
16370 +       struct dentry *hi_wh, *parent;
16371 +       struct inode *inode;
16372 +       struct file *h_file;
16373 +       struct au_wr_dir_args wr_dir_args = {
16374 +               .force_btgt     = -1,
16375 +               .flags          = 0
16376 +       };
16377 +
16378 +       bstart = au_dbstart(dentry);
16379 +       inode = dentry->d_inode;
16380 +       if (S_ISDIR(inode->i_mode))
16381 +               au_fset_wrdir(wr_dir_args.flags, ISDIR);
16382 +       /* plink or hi_wh() case */
16383 +       ibstart = au_ibstart(inode);
16384 +       if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
16385 +               wr_dir_args.force_btgt = ibstart;
16386 +       err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
16387 +       if (unlikely(err < 0))
16388 +               goto out;
16389 +       a->btgt = err;
16390 +       if (err != bstart)
16391 +               au_fset_icpup(a->flags, DID_CPUP);
16392 +
16393 +       err = 0;
16394 +       a->pin_flags = AuPin_MNT_WRITE;
16395 +       parent = NULL;
16396 +       if (!IS_ROOT(dentry)) {
16397 +               au_fset_pin(a->pin_flags, DI_LOCKED);
16398 +               parent = dget_parent(dentry);
16399 +               di_write_lock_parent(parent);
16400 +       }
16401 +
16402 +       err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
16403 +       if (unlikely(err))
16404 +               goto out_parent;
16405 +
16406 +       a->h_path.dentry = au_h_dptr(dentry, bstart);
16407 +       a->h_inode = a->h_path.dentry->d_inode;
16408 +       mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
16409 +       sz = -1;
16410 +       if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
16411 +               sz = ia->ia_size;
16412 +
16413 +       h_file = NULL;
16414 +       hi_wh = NULL;
16415 +       if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
16416 +               hi_wh = au_hi_wh(inode, a->btgt);
16417 +               if (!hi_wh) {
16418 +                       err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL);
16419 +                       if (unlikely(err))
16420 +                               goto out_unlock;
16421 +                       hi_wh = au_hi_wh(inode, a->btgt);
16422 +                       /* todo: revalidate hi_wh? */
16423 +               }
16424 +       }
16425 +
16426 +       if (parent) {
16427 +               au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
16428 +               di_downgrade_lock(parent, AuLock_IR);
16429 +               dput(parent);
16430 +               parent = NULL;
16431 +       }
16432 +       if (!au_ftest_icpup(a->flags, DID_CPUP))
16433 +               goto out; /* success */
16434 +
16435 +       if (!d_unhashed(dentry)) {
16436 +               h_file = au_h_open_pre(dentry, bstart);
16437 +               if (IS_ERR(h_file)) {
16438 +                       err = PTR_ERR(h_file);
16439 +                       h_file = NULL;
16440 +               } else
16441 +                       err = au_sio_cpup_simple(dentry, a->btgt, sz,
16442 +                                                AuCpup_DTIME);
16443 +               if (!err)
16444 +                       a->h_path.dentry = au_h_dptr(dentry, a->btgt);
16445 +       } else if (!hi_wh)
16446 +               a->h_path.dentry = au_h_dptr(dentry, a->btgt);
16447 +       else
16448 +               a->h_path.dentry = hi_wh; /* do not dget here */
16449 +
16450 +out_unlock:
16451 +       mutex_unlock(&a->h_inode->i_mutex);
16452 +       au_h_open_post(dentry, bstart, h_file);
16453 +       a->h_inode = a->h_path.dentry->d_inode;
16454 +       if (!err) {
16455 +               mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
16456 +               goto out; /* success */
16457 +       }
16458 +
16459 +       au_unpin(&a->pin);
16460 +out_parent:
16461 +       if (parent) {
16462 +               di_write_unlock(parent);
16463 +               dput(parent);
16464 +       }
16465 +out:
16466 +       return err;
16467 +}
16468 +
16469 +static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
16470 +{
16471 +       int err;
16472 +       struct inode *inode;
16473 +       struct super_block *sb;
16474 +       struct file *file;
16475 +       struct au_icpup_args *a;
16476 +
16477 +       inode = dentry->d_inode;
16478 +       IMustLock(inode);
16479 +
16480 +       err = -ENOMEM;
16481 +       a = kzalloc(sizeof(*a), GFP_NOFS);
16482 +       if (unlikely(!a))
16483 +               goto out;
16484 +
16485 +       if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
16486 +               ia->ia_valid &= ~ATTR_MODE;
16487 +
16488 +       file = NULL;
16489 +       sb = dentry->d_sb;
16490 +       err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16491 +       if (unlikely(err))
16492 +               goto out_kfree;
16493 +
16494 +       if (ia->ia_valid & ATTR_FILE) {
16495 +               /* currently ftruncate(2) only */
16496 +               AuDebugOn(!S_ISREG(inode->i_mode));
16497 +               file = ia->ia_file;
16498 +               err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
16499 +               if (unlikely(err))
16500 +                       goto out_si;
16501 +               ia->ia_file = au_hf_top(file);
16502 +               a->udba = AuOpt_UDBA_NONE;
16503 +       } else {
16504 +               /* fchmod() doesn't pass ia_file */
16505 +               a->udba = au_opt_udba(sb);
16506 +               di_write_lock_child(dentry);
16507 +               /* no d_unlinked(), to set UDBA_NONE for root */
16508 +               if (d_unhashed(dentry))
16509 +                       a->udba = AuOpt_UDBA_NONE;
16510 +               if (a->udba != AuOpt_UDBA_NONE) {
16511 +                       AuDebugOn(IS_ROOT(dentry));
16512 +                       err = au_reval_for_attr(dentry, au_sigen(sb));
16513 +                       if (unlikely(err))
16514 +                               goto out_dentry;
16515 +               }
16516 +       }
16517 +
16518 +       err = au_pin_and_icpup(dentry, ia, a);
16519 +       if (unlikely(err < 0))
16520 +               goto out_dentry;
16521 +       if (au_ftest_icpup(a->flags, DID_CPUP)) {
16522 +               ia->ia_file = NULL;
16523 +               ia->ia_valid &= ~ATTR_FILE;
16524 +       }
16525 +
16526 +       a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
16527 +       if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
16528 +           == (ATTR_MODE | ATTR_CTIME)) {
16529 +               err = security_path_chmod(&a->h_path, ia->ia_mode);
16530 +               if (unlikely(err))
16531 +                       goto out_unlock;
16532 +       } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
16533 +                  && (ia->ia_valid & ATTR_CTIME)) {
16534 +               err = security_path_chown(&a->h_path, vfsub_ia_uid(ia),
16535 +                                         vfsub_ia_gid(ia));
16536 +               if (unlikely(err))
16537 +                       goto out_unlock;
16538 +       }
16539 +
16540 +       if (ia->ia_valid & ATTR_SIZE) {
16541 +               struct file *f;
16542 +
16543 +               if (ia->ia_size < i_size_read(inode))
16544 +                       /* unmap only */
16545 +                       truncate_setsize(inode, ia->ia_size);
16546 +
16547 +               f = NULL;
16548 +               if (ia->ia_valid & ATTR_FILE)
16549 +                       f = ia->ia_file;
16550 +               mutex_unlock(&a->h_inode->i_mutex);
16551 +               err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
16552 +               mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
16553 +       } else
16554 +               err = vfsub_notify_change(&a->h_path, ia);
16555 +       if (!err)
16556 +               au_cpup_attr_changeable(inode);
16557 +
16558 +out_unlock:
16559 +       mutex_unlock(&a->h_inode->i_mutex);
16560 +       au_unpin(&a->pin);
16561 +       if (unlikely(err))
16562 +               au_update_dbstart(dentry);
16563 +out_dentry:
16564 +       di_write_unlock(dentry);
16565 +       if (file) {
16566 +               fi_write_unlock(file);
16567 +               ia->ia_file = file;
16568 +               ia->ia_valid |= ATTR_FILE;
16569 +       }
16570 +out_si:
16571 +       si_read_unlock(sb);
16572 +out_kfree:
16573 +       kfree(a);
16574 +out:
16575 +       AuTraceErr(err);
16576 +       return err;
16577 +}
16578 +
16579 +static void au_refresh_iattr(struct inode *inode, struct kstat *st,
16580 +                            unsigned int nlink)
16581 +{
16582 +       unsigned int n;
16583 +
16584 +       inode->i_mode = st->mode;
16585 +       i_uid_write(inode, st->uid);
16586 +       i_gid_write(inode, st->gid);
16587 +       inode->i_atime = st->atime;
16588 +       inode->i_mtime = st->mtime;
16589 +       inode->i_ctime = st->ctime;
16590 +
16591 +       au_cpup_attr_nlink(inode, /*force*/0);
16592 +       if (S_ISDIR(inode->i_mode)) {
16593 +               n = inode->i_nlink;
16594 +               n -= nlink;
16595 +               n += st->nlink;
16596 +               /* 0 can happen */
16597 +               set_nlink(inode, n);
16598 +       }
16599 +
16600 +       spin_lock(&inode->i_lock);
16601 +       inode->i_blocks = st->blocks;
16602 +       i_size_write(inode, st->size);
16603 +       spin_unlock(&inode->i_lock);
16604 +}
16605 +
16606 +static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
16607 +                       struct dentry *dentry, struct kstat *st)
16608 +{
16609 +       int err;
16610 +       unsigned int mnt_flags;
16611 +       aufs_bindex_t bindex;
16612 +       unsigned char udba_none, positive;
16613 +       struct super_block *sb, *h_sb;
16614 +       struct inode *inode;
16615 +       struct vfsmount *h_mnt;
16616 +       struct dentry *h_dentry;
16617 +
16618 +       sb = dentry->d_sb;
16619 +       inode = dentry->d_inode;
16620 +       err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16621 +       if (unlikely(err))
16622 +               goto out;
16623 +       mnt_flags = au_mntflags(sb);
16624 +       udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
16625 +
16626 +       /* support fstat(2) */
16627 +       if (!d_unlinked(dentry) && !udba_none) {
16628 +               unsigned int sigen = au_sigen(sb);
16629 +               err = au_digen_test(dentry, sigen);
16630 +               if (!err) {
16631 +                       di_read_lock_child(dentry, AuLock_IR);
16632 +                       err = au_dbrange_test(dentry);
16633 +                       if (unlikely(err))
16634 +                               goto out_unlock;
16635 +               } else {
16636 +                       AuDebugOn(IS_ROOT(dentry));
16637 +                       di_write_lock_child(dentry);
16638 +                       err = au_dbrange_test(dentry);
16639 +                       if (!err)
16640 +                               err = au_reval_for_attr(dentry, sigen);
16641 +                       di_downgrade_lock(dentry, AuLock_IR);
16642 +                       if (unlikely(err))
16643 +                               goto out_unlock;
16644 +               }
16645 +       } else
16646 +               di_read_lock_child(dentry, AuLock_IR);
16647 +
16648 +       bindex = au_ibstart(inode);
16649 +       h_mnt = au_sbr_mnt(sb, bindex);
16650 +       h_sb = h_mnt->mnt_sb;
16651 +       if (!au_test_fs_bad_iattr(h_sb) && udba_none)
16652 +               goto out_fill; /* success */
16653 +
16654 +       h_dentry = NULL;
16655 +       if (au_dbstart(dentry) == bindex)
16656 +               h_dentry = dget(au_h_dptr(dentry, bindex));
16657 +       else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
16658 +               h_dentry = au_plink_lkup(inode, bindex);
16659 +               if (IS_ERR(h_dentry))
16660 +                       goto out_fill; /* pretending success */
16661 +       }
16662 +       /* illegally overlapped or something */
16663 +       if (unlikely(!h_dentry))
16664 +               goto out_fill; /* pretending success */
16665 +
16666 +       positive = !!h_dentry->d_inode;
16667 +       if (positive)
16668 +               err = vfs_getattr(h_mnt, h_dentry, st);
16669 +       dput(h_dentry);
16670 +       if (!err) {
16671 +               if (positive)
16672 +                       au_refresh_iattr(inode, st, h_dentry->d_inode->i_nlink);
16673 +               goto out_fill; /* success */
16674 +       }
16675 +       AuTraceErr(err);
16676 +       goto out_unlock;
16677 +
16678 +out_fill:
16679 +       generic_fillattr(inode, st);
16680 +out_unlock:
16681 +       di_read_unlock(dentry, AuLock_IR);
16682 +       si_read_unlock(sb);
16683 +out:
16684 +       AuTraceErr(err);
16685 +       return err;
16686 +}
16687 +
16688 +/* ---------------------------------------------------------------------- */
16689 +
16690 +static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
16691 +                     int bufsiz)
16692 +{
16693 +       int err;
16694 +       struct super_block *sb;
16695 +       struct dentry *h_dentry;
16696 +
16697 +       err = -EINVAL;
16698 +       h_dentry = au_h_dptr(dentry, bindex);
16699 +       if (unlikely(!h_dentry->d_inode->i_op->readlink))
16700 +               goto out;
16701 +
16702 +       err = security_inode_readlink(h_dentry);
16703 +       if (unlikely(err))
16704 +               goto out;
16705 +
16706 +       sb = dentry->d_sb;
16707 +       if (!au_test_ro(sb, bindex, dentry->d_inode)) {
16708 +               vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
16709 +               fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
16710 +       }
16711 +       err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
16712 +
16713 +out:
16714 +       return err;
16715 +}
16716 +
16717 +static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
16718 +{
16719 +       int err;
16720 +
16721 +       err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
16722 +       if (unlikely(err))
16723 +               goto out;
16724 +       err = au_d_hashed_positive(dentry);
16725 +       if (!err)
16726 +               err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
16727 +       aufs_read_unlock(dentry, AuLock_IR);
16728 +
16729 +out:
16730 +       return err;
16731 +}
16732 +
16733 +static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
16734 +{
16735 +       int err;
16736 +       mm_segment_t old_fs;
16737 +       union {
16738 +               char *k;
16739 +               char __user *u;
16740 +       } buf;
16741 +
16742 +       err = -ENOMEM;
16743 +       buf.k = (void *)__get_free_page(GFP_NOFS);
16744 +       if (unlikely(!buf.k))
16745 +               goto out;
16746 +
16747 +       err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
16748 +       if (unlikely(err))
16749 +               goto out_name;
16750 +
16751 +       err = au_d_hashed_positive(dentry);
16752 +       if (!err) {
16753 +               old_fs = get_fs();
16754 +               set_fs(KERNEL_DS);
16755 +               err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
16756 +               set_fs(old_fs);
16757 +       }
16758 +       aufs_read_unlock(dentry, AuLock_IR);
16759 +
16760 +       if (err >= 0) {
16761 +               buf.k[err] = 0;
16762 +               /* will be freed by put_link */
16763 +               nd_set_link(nd, buf.k);
16764 +               return NULL; /* success */
16765 +       }
16766 +
16767 +out_name:
16768 +       free_page((unsigned long)buf.k);
16769 +out:
16770 +       AuTraceErr(err);
16771 +       return ERR_PTR(err);
16772 +}
16773 +
16774 +static void aufs_put_link(struct dentry *dentry __maybe_unused,
16775 +                         struct nameidata *nd, void *cookie __maybe_unused)
16776 +{
16777 +       char *p;
16778 +
16779 +       p = nd_get_link(nd);
16780 +       if (!IS_ERR_OR_NULL(p))
16781 +               free_page((unsigned long)p);
16782 +}
16783 +
16784 +/* ---------------------------------------------------------------------- */
16785 +
16786 +static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
16787 +{
16788 +       int err;
16789 +       struct super_block *sb;
16790 +       struct inode *h_inode;
16791 +
16792 +       sb = inode->i_sb;
16793 +       /* mmap_sem might be acquired already, cf. aufs_mmap() */
16794 +       lockdep_off();
16795 +       si_read_lock(sb, AuLock_FLUSH);
16796 +       ii_write_lock_child(inode);
16797 +       lockdep_on();
16798 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
16799 +       err = vfsub_update_time(h_inode, ts, flags);
16800 +       lockdep_off();
16801 +       ii_write_unlock(inode);
16802 +       si_read_unlock(sb);
16803 +       lockdep_on();
16804 +       return err;
16805 +}
16806 +
16807 +/* ---------------------------------------------------------------------- */
16808 +
16809 +struct inode_operations aufs_symlink_iop = {
16810 +       .permission     = aufs_permission,
16811 +       .setattr        = aufs_setattr,
16812 +       .getattr        = aufs_getattr,
16813 +
16814 +       .readlink       = aufs_readlink,
16815 +       .follow_link    = aufs_follow_link,
16816 +       .put_link       = aufs_put_link,
16817 +
16818 +       /* .update_time = aufs_update_time */
16819 +};
16820 +
16821 +struct inode_operations aufs_dir_iop = {
16822 +       .create         = aufs_create,
16823 +       .lookup         = aufs_lookup,
16824 +       .link           = aufs_link,
16825 +       .unlink         = aufs_unlink,
16826 +       .symlink        = aufs_symlink,
16827 +       .mkdir          = aufs_mkdir,
16828 +       .rmdir          = aufs_rmdir,
16829 +       .mknod          = aufs_mknod,
16830 +       .rename         = aufs_rename,
16831 +
16832 +       .permission     = aufs_permission,
16833 +       .setattr        = aufs_setattr,
16834 +       .getattr        = aufs_getattr,
16835 +
16836 +       .update_time    = aufs_update_time
16837 +       /* no support for atomic_open() */
16838 +};
16839 +
16840 +struct inode_operations aufs_iop = {
16841 +       .permission     = aufs_permission,
16842 +       .setattr        = aufs_setattr,
16843 +       .getattr        = aufs_getattr,
16844 +
16845 +       .update_time    = aufs_update_time
16846 +};
16847 diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
16848 --- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
16849 +++ linux/fs/aufs/i_op_del.c    2013-01-11 19:46:12.639281345 +0100
16850 @@ -0,0 +1,477 @@
16851 +/*
16852 + * Copyright (C) 2005-2013 Junjiro R. Okajima
16853 + *
16854 + * This program, aufs is free software; you can redistribute it and/or modify
16855 + * it under the terms of the GNU General Public License as published by
16856 + * the Free Software Foundation; either version 2 of the License, or
16857 + * (at your option) any later version.
16858 + *
16859 + * This program is distributed in the hope that it will be useful,
16860 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16861 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16862 + * GNU General Public License for more details.
16863 + *
16864 + * You should have received a copy of the GNU General Public License
16865 + * along with this program; if not, write to the Free Software
16866 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16867 + */
16868 +
16869 +/*
16870 + * inode operations (del entry)
16871 + */
16872 +
16873 +#include "aufs.h"
16874 +
16875 +/*
16876 + * decide if a new whiteout for @dentry is necessary or not.
16877 + * when it is necessary, prepare the parent dir for the upper branch whose
16878 + * branch index is @bcpup for creation. the actual creation of the whiteout will
16879 + * be done by caller.
16880 + * return value:
16881 + * 0: wh is unnecessary
16882 + * plus: wh is necessary
16883 + * minus: error
16884 + */
16885 +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
16886 +{
16887 +       int need_wh, err;
16888 +       aufs_bindex_t bstart;
16889 +       struct super_block *sb;
16890 +
16891 +       sb = dentry->d_sb;
16892 +       bstart = au_dbstart(dentry);
16893 +       if (*bcpup < 0) {
16894 +               *bcpup = bstart;
16895 +               if (au_test_ro(sb, bstart, dentry->d_inode)) {
16896 +                       err = AuWbrCopyup(au_sbi(sb), dentry);
16897 +                       *bcpup = err;
16898 +                       if (unlikely(err < 0))
16899 +                               goto out;
16900 +               }
16901 +       } else
16902 +               AuDebugOn(bstart < *bcpup
16903 +                         || au_test_ro(sb, *bcpup, dentry->d_inode));
16904 +       AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
16905 +
16906 +       if (*bcpup != bstart) {
16907 +               err = au_cpup_dirs(dentry, *bcpup);
16908 +               if (unlikely(err))
16909 +                       goto out;
16910 +               need_wh = 1;
16911 +       } else {
16912 +               struct au_dinfo *dinfo, *tmp;
16913 +
16914 +               need_wh = -ENOMEM;
16915 +               dinfo = au_di(dentry);
16916 +               tmp = au_di_alloc(sb, AuLsc_DI_TMP);
16917 +               if (tmp) {
16918 +                       au_di_cp(tmp, dinfo);
16919 +                       au_di_swap(tmp, dinfo);
16920 +                       /* returns the number of positive dentries */
16921 +                       need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
16922 +                       au_di_swap(tmp, dinfo);
16923 +                       au_rw_write_unlock(&tmp->di_rwsem);
16924 +                       au_di_free(tmp);
16925 +               }
16926 +       }
16927 +       AuDbg("need_wh %d\n", need_wh);
16928 +       err = need_wh;
16929 +
16930 +out:
16931 +       return err;
16932 +}
16933 +
16934 +/*
16935 + * simple tests for the del-entry operations.
16936 + * following the checks in vfs, plus the parent-child relationship.
16937 + */
16938 +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
16939 +              struct dentry *h_parent, int isdir)
16940 +{
16941 +       int err;
16942 +       umode_t h_mode;
16943 +       struct dentry *h_dentry, *h_latest;
16944 +       struct inode *h_inode;
16945 +
16946 +       h_dentry = au_h_dptr(dentry, bindex);
16947 +       h_inode = h_dentry->d_inode;
16948 +       if (dentry->d_inode) {
16949 +               err = -ENOENT;
16950 +               if (unlikely(!h_inode || !h_inode->i_nlink))
16951 +                       goto out;
16952 +
16953 +               h_mode = h_inode->i_mode;
16954 +               if (!isdir) {
16955 +                       err = -EISDIR;
16956 +                       if (unlikely(S_ISDIR(h_mode)))
16957 +                               goto out;
16958 +               } else if (unlikely(!S_ISDIR(h_mode))) {
16959 +                       err = -ENOTDIR;
16960 +                       goto out;
16961 +               }
16962 +       } else {
16963 +               /* rename(2) case */
16964 +               err = -EIO;
16965 +               if (unlikely(h_inode))
16966 +                       goto out;
16967 +       }
16968 +
16969 +       err = -ENOENT;
16970 +       /* expected parent dir is locked */
16971 +       if (unlikely(h_parent != h_dentry->d_parent))
16972 +               goto out;
16973 +       err = 0;
16974 +
16975 +       /*
16976 +        * rmdir a dir may break the consistency on some filesystem.
16977 +        * let's try heavy test.
16978 +        */
16979 +       err = -EACCES;
16980 +       if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
16981 +               goto out;
16982 +
16983 +       h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
16984 +                                  au_sbr(dentry->d_sb, bindex));
16985 +       err = -EIO;
16986 +       if (IS_ERR(h_latest))
16987 +               goto out;
16988 +       if (h_latest == h_dentry)
16989 +               err = 0;
16990 +       dput(h_latest);
16991 +
16992 +out:
16993 +       return err;
16994 +}
16995 +
16996 +/*
16997 + * decide the branch where we operate for @dentry. the branch index will be set
16998 + * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
16999 + * dir for reverting.
17000 + * when a new whiteout is necessary, create it.
17001 + */
17002 +static struct dentry*
17003 +lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
17004 +                   struct au_dtime *dt, struct au_pin *pin)
17005 +{
17006 +       struct dentry *wh_dentry;
17007 +       struct super_block *sb;
17008 +       struct path h_path;
17009 +       int err, need_wh;
17010 +       unsigned int udba;
17011 +       aufs_bindex_t bcpup;
17012 +
17013 +       need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
17014 +       wh_dentry = ERR_PTR(need_wh);
17015 +       if (unlikely(need_wh < 0))
17016 +               goto out;
17017 +
17018 +       sb = dentry->d_sb;
17019 +       udba = au_opt_udba(sb);
17020 +       bcpup = *rbcpup;
17021 +       err = au_pin(pin, dentry, bcpup, udba,
17022 +                    AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17023 +       wh_dentry = ERR_PTR(err);
17024 +       if (unlikely(err))
17025 +               goto out;
17026 +
17027 +       h_path.dentry = au_pinned_h_parent(pin);
17028 +       if (udba != AuOpt_UDBA_NONE
17029 +           && au_dbstart(dentry) == bcpup) {
17030 +               err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
17031 +               wh_dentry = ERR_PTR(err);
17032 +               if (unlikely(err))
17033 +                       goto out_unpin;
17034 +       }
17035 +
17036 +       h_path.mnt = au_sbr_mnt(sb, bcpup);
17037 +       au_dtime_store(dt, au_pinned_parent(pin), &h_path);
17038 +       wh_dentry = NULL;
17039 +       if (!need_wh)
17040 +               goto out; /* success, no need to create whiteout */
17041 +
17042 +       wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
17043 +       if (IS_ERR(wh_dentry))
17044 +               goto out_unpin;
17045 +
17046 +       /* returns with the parent is locked and wh_dentry is dget-ed */
17047 +       goto out; /* success */
17048 +
17049 +out_unpin:
17050 +       au_unpin(pin);
17051 +out:
17052 +       return wh_dentry;
17053 +}
17054 +
17055 +/*
17056 + * when removing a dir, rename it to a unique temporary whiteout-ed name first
17057 + * in order to be revertible and save time for removing many child whiteouts
17058 + * under the dir.
17059 + * returns 1 when there are too many child whiteout and caller should remove
17060 + * them asynchronously. returns 0 when the number of children is enough small to
17061 + * remove now or the branch fs is a remote fs.
17062 + * otherwise return an error.
17063 + */
17064 +static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
17065 +                          struct au_nhash *whlist, struct inode *dir)
17066 +{
17067 +       int rmdir_later, err, dirwh;
17068 +       struct dentry *h_dentry;
17069 +       struct super_block *sb;
17070 +
17071 +       sb = dentry->d_sb;
17072 +       SiMustAnyLock(sb);
17073 +       h_dentry = au_h_dptr(dentry, bindex);
17074 +       err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
17075 +       if (unlikely(err))
17076 +               goto out;
17077 +
17078 +       /* stop monitoring */
17079 +       au_hn_free(au_hi(dentry->d_inode, bindex));
17080 +
17081 +       if (!au_test_fs_remote(h_dentry->d_sb)) {
17082 +               dirwh = au_sbi(sb)->si_dirwh;
17083 +               rmdir_later = (dirwh <= 1);
17084 +               if (!rmdir_later)
17085 +                       rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
17086 +                                                             dirwh);
17087 +               if (rmdir_later)
17088 +                       return rmdir_later;
17089 +       }
17090 +
17091 +       err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
17092 +       if (unlikely(err)) {
17093 +               AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
17094 +                       AuDLNPair(h_dentry), bindex, err);
17095 +               err = 0;
17096 +       }
17097 +
17098 +out:
17099 +       AuTraceErr(err);
17100 +       return err;
17101 +}
17102 +
17103 +/*
17104 + * final procedure for deleting a entry.
17105 + * maintain dentry and iattr.
17106 + */
17107 +static void epilog(struct inode *dir, struct dentry *dentry,
17108 +                  aufs_bindex_t bindex)
17109 +{
17110 +       struct inode *inode;
17111 +
17112 +       inode = dentry->d_inode;
17113 +       d_drop(dentry);
17114 +       inode->i_ctime = dir->i_ctime;
17115 +
17116 +       if (au_ibstart(dir) == bindex)
17117 +               au_cpup_attr_timesizes(dir);
17118 +       dir->i_version++;
17119 +}
17120 +
17121 +/*
17122 + * when an error happened, remove the created whiteout and revert everything.
17123 + */
17124 +static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
17125 +                    aufs_bindex_t bwh, struct dentry *wh_dentry,
17126 +                    struct dentry *dentry, struct au_dtime *dt)
17127 +{
17128 +       int rerr;
17129 +       struct path h_path = {
17130 +               .dentry = wh_dentry,
17131 +               .mnt    = au_sbr_mnt(dir->i_sb, bindex)
17132 +       };
17133 +
17134 +       rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
17135 +       if (!rerr) {
17136 +               au_set_dbwh(dentry, bwh);
17137 +               au_dtime_revert(dt);
17138 +               return 0;
17139 +       }
17140 +
17141 +       AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
17142 +               AuDLNPair(dentry), err, rerr);
17143 +       return -EIO;
17144 +}
17145 +
17146 +/* ---------------------------------------------------------------------- */
17147 +
17148 +int aufs_unlink(struct inode *dir, struct dentry *dentry)
17149 +{
17150 +       int err;
17151 +       aufs_bindex_t bwh, bindex, bstart;
17152 +       struct au_dtime dt;
17153 +       struct au_pin pin;
17154 +       struct path h_path;
17155 +       struct inode *inode, *h_dir;
17156 +       struct dentry *parent, *wh_dentry;
17157 +
17158 +       IMustLock(dir);
17159 +
17160 +       err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17161 +       if (unlikely(err))
17162 +               goto out;
17163 +       err = au_d_hashed_positive(dentry);
17164 +       if (unlikely(err))
17165 +               goto out_unlock;
17166 +       inode = dentry->d_inode;
17167 +       IMustLock(inode);
17168 +       err = -EISDIR;
17169 +       if (unlikely(S_ISDIR(inode->i_mode)))
17170 +               goto out_unlock; /* possible? */
17171 +
17172 +       bstart = au_dbstart(dentry);
17173 +       bwh = au_dbwh(dentry);
17174 +       bindex = -1;
17175 +       parent = dentry->d_parent; /* dir inode is locked */
17176 +       di_write_lock_parent(parent);
17177 +       wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
17178 +       err = PTR_ERR(wh_dentry);
17179 +       if (IS_ERR(wh_dentry))
17180 +               goto out_parent;
17181 +
17182 +       h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
17183 +       h_path.dentry = au_h_dptr(dentry, bstart);
17184 +       dget(h_path.dentry);
17185 +       if (bindex == bstart) {
17186 +               h_dir = au_pinned_h_dir(&pin);
17187 +               err = vfsub_unlink(h_dir, &h_path, /*force*/0);
17188 +       } else {
17189 +               /* dir inode is locked */
17190 +               h_dir = wh_dentry->d_parent->d_inode;
17191 +               IMustLock(h_dir);
17192 +               err = 0;
17193 +       }
17194 +
17195 +       if (!err) {
17196 +               vfsub_drop_nlink(inode);
17197 +               epilog(dir, dentry, bindex);
17198 +
17199 +               /* update target timestamps */
17200 +               if (bindex == bstart) {
17201 +                       vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
17202 +                       inode->i_ctime = h_path.dentry->d_inode->i_ctime;
17203 +               } else
17204 +                       /* todo: this timestamp may be reverted later */
17205 +                       inode->i_ctime = h_dir->i_ctime;
17206 +               goto out_unpin; /* success */
17207 +       }
17208 +
17209 +       /* revert */
17210 +       if (wh_dentry) {
17211 +               int rerr;
17212 +
17213 +               rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
17214 +               if (rerr)
17215 +                       err = rerr;
17216 +       }
17217 +
17218 +out_unpin:
17219 +       au_unpin(&pin);
17220 +       dput(wh_dentry);
17221 +       dput(h_path.dentry);
17222 +out_parent:
17223 +       di_write_unlock(parent);
17224 +out_unlock:
17225 +       aufs_read_unlock(dentry, AuLock_DW);
17226 +out:
17227 +       return err;
17228 +}
17229 +
17230 +int aufs_rmdir(struct inode *dir, struct dentry *dentry)
17231 +{
17232 +       int err, rmdir_later;
17233 +       aufs_bindex_t bwh, bindex, bstart;
17234 +       struct au_dtime dt;
17235 +       struct au_pin pin;
17236 +       struct inode *inode;
17237 +       struct dentry *parent, *wh_dentry, *h_dentry;
17238 +       struct au_whtmp_rmdir *args;
17239 +
17240 +       IMustLock(dir);
17241 +
17242 +       err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
17243 +       if (unlikely(err))
17244 +               goto out;
17245 +       err = au_alive_dir(dentry);
17246 +       if (unlikely(err))
17247 +               goto out_unlock;
17248 +       inode = dentry->d_inode;
17249 +       IMustLock(inode);
17250 +       err = -ENOTDIR;
17251 +       if (unlikely(!S_ISDIR(inode->i_mode)))
17252 +               goto out_unlock; /* possible? */
17253 +
17254 +       err = -ENOMEM;
17255 +       args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
17256 +       if (unlikely(!args))
17257 +               goto out_unlock;
17258 +
17259 +       parent = dentry->d_parent; /* dir inode is locked */
17260 +       di_write_lock_parent(parent);
17261 +       err = au_test_empty(dentry, &args->whlist);
17262 +       if (unlikely(err))
17263 +               goto out_parent;
17264 +
17265 +       bstart = au_dbstart(dentry);
17266 +       bwh = au_dbwh(dentry);
17267 +       bindex = -1;
17268 +       wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
17269 +       err = PTR_ERR(wh_dentry);
17270 +       if (IS_ERR(wh_dentry))
17271 +               goto out_parent;
17272 +
17273 +       h_dentry = au_h_dptr(dentry, bstart);
17274 +       dget(h_dentry);
17275 +       rmdir_later = 0;
17276 +       if (bindex == bstart) {
17277 +               err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
17278 +               if (err > 0) {
17279 +                       rmdir_later = err;
17280 +                       err = 0;
17281 +               }
17282 +       } else {
17283 +               /* stop monitoring */
17284 +               au_hn_free(au_hi(inode, bstart));
17285 +
17286 +               /* dir inode is locked */
17287 +               IMustLock(wh_dentry->d_parent->d_inode);
17288 +               err = 0;
17289 +       }
17290 +
17291 +       if (!err) {
17292 +               vfsub_dead_dir(inode);
17293 +               au_set_dbdiropq(dentry, -1);
17294 +               epilog(dir, dentry, bindex);
17295 +
17296 +               if (rmdir_later) {
17297 +                       au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
17298 +                       args = NULL;
17299 +               }
17300 +
17301 +               goto out_unpin; /* success */
17302 +       }
17303 +
17304 +       /* revert */
17305 +       AuLabel(revert);
17306 +       if (wh_dentry) {
17307 +               int rerr;
17308 +
17309 +               rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
17310 +               if (rerr)
17311 +                       err = rerr;
17312 +       }
17313 +
17314 +out_unpin:
17315 +       au_unpin(&pin);
17316 +       dput(wh_dentry);
17317 +       dput(h_dentry);
17318 +out_parent:
17319 +       di_write_unlock(parent);
17320 +       if (args)
17321 +               au_whtmp_rmdir_free(args);
17322 +out_unlock:
17323 +       aufs_read_unlock(dentry, AuLock_DW);
17324 +out:
17325 +       AuTraceErr(err);
17326 +       return err;
17327 +}
17328 diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
17329 --- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
17330 +++ linux/fs/aufs/i_op_ren.c    2013-01-11 19:46:12.639281345 +0100
17331 @@ -0,0 +1,1026 @@
17332 +/*
17333 + * Copyright (C) 2005-2013 Junjiro R. Okajima
17334 + *
17335 + * This program, aufs is free software; you can redistribute it and/or modify
17336 + * it under the terms of the GNU General Public License as published by
17337 + * the Free Software Foundation; either version 2 of the License, or
17338 + * (at your option) any later version.
17339 + *
17340 + * This program is distributed in the hope that it will be useful,
17341 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17342 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17343 + * GNU General Public License for more details.
17344 + *
17345 + * You should have received a copy of the GNU General Public License
17346 + * along with this program; if not, write to the Free Software
17347 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17348 + */
17349 +
17350 +/*
17351 + * inode operation (rename entry)
17352 + * todo: this is crazy monster
17353 + */
17354 +
17355 +#include "aufs.h"
17356 +
17357 +enum { AuSRC, AuDST, AuSrcDst };
17358 +enum { AuPARENT, AuCHILD, AuParentChild };
17359 +
17360 +#define AuRen_ISDIR    1
17361 +#define AuRen_ISSAMEDIR        (1 << 1)
17362 +#define AuRen_WHSRC    (1 << 2)
17363 +#define AuRen_WHDST    (1 << 3)
17364 +#define AuRen_MNT_WRITE        (1 << 4)
17365 +#define AuRen_DT_DSTDIR        (1 << 5)
17366 +#define AuRen_DIROPQ   (1 << 6)
17367 +#define AuRen_CPUP     (1 << 7)
17368 +#define au_ftest_ren(flags, name)      ((flags) & AuRen_##name)
17369 +#define au_fset_ren(flags, name) \
17370 +       do { (flags) |= AuRen_##name; } while (0)
17371 +#define au_fclr_ren(flags, name) \
17372 +       do { (flags) &= ~AuRen_##name; } while (0)
17373 +
17374 +struct au_ren_args {
17375 +       struct {
17376 +               struct dentry *dentry, *h_dentry, *parent, *h_parent,
17377 +                       *wh_dentry;
17378 +               struct inode *dir, *inode;
17379 +               struct au_hinode *hdir;
17380 +               struct au_dtime dt[AuParentChild];
17381 +               aufs_bindex_t bstart;
17382 +       } sd[AuSrcDst];
17383 +
17384 +#define src_dentry     sd[AuSRC].dentry
17385 +#define src_dir                sd[AuSRC].dir
17386 +#define src_inode      sd[AuSRC].inode
17387 +#define src_h_dentry   sd[AuSRC].h_dentry
17388 +#define src_parent     sd[AuSRC].parent
17389 +#define src_h_parent   sd[AuSRC].h_parent
17390 +#define src_wh_dentry  sd[AuSRC].wh_dentry
17391 +#define src_hdir       sd[AuSRC].hdir
17392 +#define src_h_dir      sd[AuSRC].hdir->hi_inode
17393 +#define src_dt         sd[AuSRC].dt
17394 +#define src_bstart     sd[AuSRC].bstart
17395 +
17396 +#define dst_dentry     sd[AuDST].dentry
17397 +#define dst_dir                sd[AuDST].dir
17398 +#define dst_inode      sd[AuDST].inode
17399 +#define dst_h_dentry   sd[AuDST].h_dentry
17400 +#define dst_parent     sd[AuDST].parent
17401 +#define dst_h_parent   sd[AuDST].h_parent
17402 +#define dst_wh_dentry  sd[AuDST].wh_dentry
17403 +#define dst_hdir       sd[AuDST].hdir
17404 +#define dst_h_dir      sd[AuDST].hdir->hi_inode
17405 +#define dst_dt         sd[AuDST].dt
17406 +#define dst_bstart     sd[AuDST].bstart
17407 +
17408 +       struct dentry *h_trap;
17409 +       struct au_branch *br;
17410 +       struct au_hinode *src_hinode;
17411 +       struct path h_path;
17412 +       struct au_nhash whlist;
17413 +       aufs_bindex_t btgt, src_bwh, src_bdiropq;
17414 +
17415 +       unsigned int flags;
17416 +
17417 +       struct au_whtmp_rmdir *thargs;
17418 +       struct dentry *h_dst;
17419 +};
17420 +
17421 +/* ---------------------------------------------------------------------- */
17422 +
17423 +/*
17424 + * functions for reverting.
17425 + * when an error happened in a single rename systemcall, we should revert
17426 + * everything as if nothing happend.
17427 + * we don't need to revert the copied-up/down the parent dir since they are
17428 + * harmless.
17429 + */
17430 +
17431 +#define RevertFailure(fmt, ...) do { \
17432 +       AuIOErr("revert failure: " fmt " (%d, %d)\n", \
17433 +               ##__VA_ARGS__, err, rerr); \
17434 +       err = -EIO; \
17435 +} while (0)
17436 +
17437 +static void au_ren_rev_diropq(int err, struct au_ren_args *a)
17438 +{
17439 +       int rerr;
17440 +
17441 +       au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
17442 +       rerr = au_diropq_remove(a->src_dentry, a->btgt);
17443 +       au_hn_imtx_unlock(a->src_hinode);
17444 +       au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
17445 +       if (rerr)
17446 +               RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
17447 +}
17448 +
17449 +static void au_ren_rev_rename(int err, struct au_ren_args *a)
17450 +{
17451 +       int rerr;
17452 +
17453 +       a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
17454 +                                         a->src_h_parent);
17455 +       rerr = PTR_ERR(a->h_path.dentry);
17456 +       if (IS_ERR(a->h_path.dentry)) {
17457 +               RevertFailure("lkup one %.*s", AuDLNPair(a->src_dentry));
17458 +               return;
17459 +       }
17460 +
17461 +       rerr = vfsub_rename(a->dst_h_dir,
17462 +                           au_h_dptr(a->src_dentry, a->btgt),
17463 +                           a->src_h_dir, &a->h_path);
17464 +       d_drop(a->h_path.dentry);
17465 +       dput(a->h_path.dentry);
17466 +       /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
17467 +       if (rerr)
17468 +               RevertFailure("rename %.*s", AuDLNPair(a->src_dentry));
17469 +}
17470 +
17471 +static void au_ren_rev_cpup(int err, struct au_ren_args *a)
17472 +{
17473 +       int rerr;
17474 +
17475 +       a->h_path.dentry = a->dst_h_dentry;
17476 +       rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0);
17477 +       au_set_h_dptr(a->src_dentry, a->btgt, NULL);
17478 +       au_set_dbstart(a->src_dentry, a->src_bstart);
17479 +       if (rerr)
17480 +               RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry));
17481 +}
17482 +
17483 +static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
17484 +{
17485 +       int rerr;
17486 +
17487 +       a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
17488 +                                         a->dst_h_parent);
17489 +       rerr = PTR_ERR(a->h_path.dentry);
17490 +       if (IS_ERR(a->h_path.dentry)) {
17491 +               RevertFailure("lkup one %.*s", AuDLNPair(a->dst_dentry));
17492 +               return;
17493 +       }
17494 +       if (a->h_path.dentry->d_inode) {
17495 +               d_drop(a->h_path.dentry);
17496 +               dput(a->h_path.dentry);
17497 +               return;
17498 +       }
17499 +
17500 +       rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path);
17501 +       d_drop(a->h_path.dentry);
17502 +       dput(a->h_path.dentry);
17503 +       if (!rerr)
17504 +               au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
17505 +       else
17506 +               RevertFailure("rename %.*s", AuDLNPair(a->h_dst));
17507 +}
17508 +
17509 +static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
17510 +{
17511 +       int rerr;
17512 +
17513 +       a->h_path.dentry = a->src_wh_dentry;
17514 +       rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
17515 +       au_set_dbwh(a->src_dentry, a->src_bwh);
17516 +       if (rerr)
17517 +               RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
17518 +}
17519 +#undef RevertFailure
17520 +
17521 +/* ---------------------------------------------------------------------- */
17522 +
17523 +/*
17524 + * when we have to copyup the renaming entry, do it with the rename-target name
17525 + * in order to minimize the cost (the later actual rename is unnecessary).
17526 + * otherwise rename it on the target branch.
17527 + */
17528 +static int au_ren_or_cpup(struct au_ren_args *a)
17529 +{
17530 +       int err;
17531 +       struct dentry *d;
17532 +
17533 +       d = a->src_dentry;
17534 +       if (au_dbstart(d) == a->btgt) {
17535 +               a->h_path.dentry = a->dst_h_dentry;
17536 +               if (au_ftest_ren(a->flags, DIROPQ)
17537 +                   && au_dbdiropq(d) == a->btgt)
17538 +                       au_fclr_ren(a->flags, DIROPQ);
17539 +               AuDebugOn(au_dbstart(d) != a->btgt);
17540 +               err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
17541 +                                  a->dst_h_dir, &a->h_path);
17542 +       } else {
17543 +               struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
17544 +               struct file *h_file;
17545 +
17546 +               au_fset_ren(a->flags, CPUP);
17547 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17548 +               au_set_dbstart(d, a->btgt);
17549 +               au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry));
17550 +               h_file = au_h_open_pre(d, a->src_bstart);
17551 +               if (IS_ERR(h_file)) {
17552 +                       err = PTR_ERR(h_file);
17553 +                       h_file = NULL;
17554 +               } else
17555 +                       err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1,
17556 +                                                !AuCpup_DTIME, a->dst_parent);
17557 +               mutex_unlock(h_mtx);
17558 +               au_h_open_post(d, a->src_bstart, h_file);
17559 +               if (!err) {
17560 +                       d = a->dst_dentry;
17561 +                       au_set_h_dptr(d, a->btgt, NULL);
17562 +                       au_update_dbstart(d);
17563 +               } else {
17564 +                       au_set_h_dptr(d, a->btgt, NULL);
17565 +                       au_set_dbstart(d, a->src_bstart);
17566 +               }
17567 +       }
17568 +       if (!err && a->h_dst)
17569 +               /* it will be set to dinfo later */
17570 +               dget(a->h_dst);
17571 +
17572 +       return err;
17573 +}
17574 +
17575 +/* cf. aufs_rmdir() */
17576 +static int au_ren_del_whtmp(struct au_ren_args *a)
17577 +{
17578 +       int err;
17579 +       struct inode *dir;
17580 +
17581 +       dir = a->dst_dir;
17582 +       SiMustAnyLock(dir->i_sb);
17583 +       if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
17584 +                                    au_sbi(dir->i_sb)->si_dirwh)
17585 +           || au_test_fs_remote(a->h_dst->d_sb)) {
17586 +               err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
17587 +               if (unlikely(err))
17588 +                       pr_warn("failed removing whtmp dir %.*s (%d), "
17589 +                               "ignored.\n", AuDLNPair(a->h_dst), err);
17590 +       } else {
17591 +               au_nhash_wh_free(&a->thargs->whlist);
17592 +               a->thargs->whlist = a->whlist;
17593 +               a->whlist.nh_num = 0;
17594 +               au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
17595 +               dput(a->h_dst);
17596 +               a->thargs = NULL;
17597 +       }
17598 +
17599 +       return 0;
17600 +}
17601 +
17602 +/* make it 'opaque' dir. */
17603 +static int au_ren_diropq(struct au_ren_args *a)
17604 +{
17605 +       int err;
17606 +       struct dentry *diropq;
17607 +
17608 +       err = 0;
17609 +       a->src_bdiropq = au_dbdiropq(a->src_dentry);
17610 +       a->src_hinode = au_hi(a->src_inode, a->btgt);
17611 +       au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
17612 +       diropq = au_diropq_create(a->src_dentry, a->btgt);
17613 +       au_hn_imtx_unlock(a->src_hinode);
17614 +       if (IS_ERR(diropq))
17615 +               err = PTR_ERR(diropq);
17616 +       dput(diropq);
17617 +
17618 +       return err;
17619 +}
17620 +
17621 +static int do_rename(struct au_ren_args *a)
17622 +{
17623 +       int err;
17624 +       struct dentry *d, *h_d;
17625 +
17626 +       /* prepare workqueue args for asynchronous rmdir */
17627 +       h_d = a->dst_h_dentry;
17628 +       if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
17629 +               err = -ENOMEM;
17630 +               a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
17631 +               if (unlikely(!a->thargs))
17632 +                       goto out;
17633 +               a->h_dst = dget(h_d);
17634 +       }
17635 +
17636 +       /* create whiteout for src_dentry */
17637 +       if (au_ftest_ren(a->flags, WHSRC)) {
17638 +               a->src_bwh = au_dbwh(a->src_dentry);
17639 +               AuDebugOn(a->src_bwh >= 0);
17640 +               a->src_wh_dentry
17641 +                       = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
17642 +               err = PTR_ERR(a->src_wh_dentry);
17643 +               if (IS_ERR(a->src_wh_dentry))
17644 +                       goto out_thargs;
17645 +       }
17646 +
17647 +       /* lookup whiteout for dentry */
17648 +       if (au_ftest_ren(a->flags, WHDST)) {
17649 +               h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
17650 +                                a->br);
17651 +               err = PTR_ERR(h_d);
17652 +               if (IS_ERR(h_d))
17653 +                       goto out_whsrc;
17654 +               if (!h_d->d_inode)
17655 +                       dput(h_d);
17656 +               else
17657 +                       a->dst_wh_dentry = h_d;
17658 +       }
17659 +
17660 +       /* rename dentry to tmpwh */
17661 +       if (a->thargs) {
17662 +               err = au_whtmp_ren(a->dst_h_dentry, a->br);
17663 +               if (unlikely(err))
17664 +                       goto out_whdst;
17665 +
17666 +               d = a->dst_dentry;
17667 +               au_set_h_dptr(d, a->btgt, NULL);
17668 +               err = au_lkup_neg(d, a->btgt);
17669 +               if (unlikely(err))
17670 +                       goto out_whtmp;
17671 +               a->dst_h_dentry = au_h_dptr(d, a->btgt);
17672 +       }
17673 +
17674 +       /* cpup src */
17675 +       if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) {
17676 +               struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex;
17677 +               struct file *h_file;
17678 +
17679 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17680 +               AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
17681 +               h_file = au_h_open_pre(a->src_dentry, a->src_bstart);
17682 +               if (IS_ERR(h_file)) {
17683 +                       err = PTR_ERR(h_file);
17684 +                       h_file = NULL;
17685 +               } else
17686 +                       err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1,
17687 +                                                !AuCpup_DTIME);
17688 +               mutex_unlock(h_mtx);
17689 +               au_h_open_post(a->src_dentry, a->src_bstart, h_file);
17690 +               if (unlikely(err))
17691 +                       goto out_whtmp;
17692 +       }
17693 +
17694 +       /* rename by vfs_rename or cpup */
17695 +       d = a->dst_dentry;
17696 +       if (au_ftest_ren(a->flags, ISDIR)
17697 +           && (a->dst_wh_dentry
17698 +               || au_dbdiropq(d) == a->btgt
17699 +               /* hide the lower to keep xino */
17700 +               || a->btgt < au_dbend(d)
17701 +               || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
17702 +               au_fset_ren(a->flags, DIROPQ);
17703 +       err = au_ren_or_cpup(a);
17704 +       if (unlikely(err))
17705 +               /* leave the copied-up one */
17706 +               goto out_whtmp;
17707 +
17708 +       /* make dir opaque */
17709 +       if (au_ftest_ren(a->flags, DIROPQ)) {
17710 +               err = au_ren_diropq(a);
17711 +               if (unlikely(err))
17712 +                       goto out_rename;
17713 +       }
17714 +
17715 +       /* update target timestamps */
17716 +       AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
17717 +       a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
17718 +       vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
17719 +       a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
17720 +
17721 +       /* remove whiteout for dentry */
17722 +       if (a->dst_wh_dentry) {
17723 +               a->h_path.dentry = a->dst_wh_dentry;
17724 +               err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
17725 +                                         a->dst_dentry);
17726 +               if (unlikely(err))
17727 +                       goto out_diropq;
17728 +       }
17729 +
17730 +       /* remove whtmp */
17731 +       if (a->thargs)
17732 +               au_ren_del_whtmp(a); /* ignore this error */
17733 +
17734 +       err = 0;
17735 +       goto out_success;
17736 +
17737 +out_diropq:
17738 +       if (au_ftest_ren(a->flags, DIROPQ))
17739 +               au_ren_rev_diropq(err, a);
17740 +out_rename:
17741 +       if (!au_ftest_ren(a->flags, CPUP))
17742 +               au_ren_rev_rename(err, a);
17743 +       else
17744 +               au_ren_rev_cpup(err, a);
17745 +       dput(a->h_dst);
17746 +out_whtmp:
17747 +       if (a->thargs)
17748 +               au_ren_rev_whtmp(err, a);
17749 +out_whdst:
17750 +       dput(a->dst_wh_dentry);
17751 +       a->dst_wh_dentry = NULL;
17752 +out_whsrc:
17753 +       if (a->src_wh_dentry)
17754 +               au_ren_rev_whsrc(err, a);
17755 +out_success:
17756 +       dput(a->src_wh_dentry);
17757 +       dput(a->dst_wh_dentry);
17758 +out_thargs:
17759 +       if (a->thargs) {
17760 +               dput(a->h_dst);
17761 +               au_whtmp_rmdir_free(a->thargs);
17762 +               a->thargs = NULL;
17763 +       }
17764 +out:
17765 +       return err;
17766 +}
17767 +
17768 +/* ---------------------------------------------------------------------- */
17769 +
17770 +/*
17771 + * test if @dentry dir can be rename destination or not.
17772 + * success means, it is a logically empty dir.
17773 + */
17774 +static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
17775 +{
17776 +       return au_test_empty(dentry, whlist);
17777 +}
17778 +
17779 +/*
17780 + * test if @dentry dir can be rename source or not.
17781 + * if it can, return 0 and @children is filled.
17782 + * success means,
17783 + * - it is a logically empty dir.
17784 + * - or, it exists on writable branch and has no children including whiteouts
17785 + *       on the lower branch.
17786 + */
17787 +static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
17788 +{
17789 +       int err;
17790 +       unsigned int rdhash;
17791 +       aufs_bindex_t bstart;
17792 +
17793 +       bstart = au_dbstart(dentry);
17794 +       if (bstart != btgt) {
17795 +               struct au_nhash whlist;
17796 +
17797 +               SiMustAnyLock(dentry->d_sb);
17798 +               rdhash = au_sbi(dentry->d_sb)->si_rdhash;
17799 +               if (!rdhash)
17800 +                       rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
17801 +                                                          dentry));
17802 +               err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
17803 +               if (unlikely(err))
17804 +                       goto out;
17805 +               err = au_test_empty(dentry, &whlist);
17806 +               au_nhash_wh_free(&whlist);
17807 +               goto out;
17808 +       }
17809 +
17810 +       if (bstart == au_dbtaildir(dentry))
17811 +               return 0; /* success */
17812 +
17813 +       err = au_test_empty_lower(dentry);
17814 +
17815 +out:
17816 +       if (err == -ENOTEMPTY) {
17817 +               AuWarn1("renaming dir who has child(ren) on multiple branches,"
17818 +                       " is not supported\n");
17819 +               err = -EXDEV;
17820 +       }
17821 +       return err;
17822 +}
17823 +
17824 +/* side effect: sets whlist and h_dentry */
17825 +static int au_ren_may_dir(struct au_ren_args *a)
17826 +{
17827 +       int err;
17828 +       unsigned int rdhash;
17829 +       struct dentry *d;
17830 +
17831 +       d = a->dst_dentry;
17832 +       SiMustAnyLock(d->d_sb);
17833 +
17834 +       err = 0;
17835 +       if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
17836 +               rdhash = au_sbi(d->d_sb)->si_rdhash;
17837 +               if (!rdhash)
17838 +                       rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
17839 +               err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
17840 +               if (unlikely(err))
17841 +                       goto out;
17842 +
17843 +               au_set_dbstart(d, a->dst_bstart);
17844 +               err = may_rename_dstdir(d, &a->whlist);
17845 +               au_set_dbstart(d, a->btgt);
17846 +       }
17847 +       a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
17848 +       if (unlikely(err))
17849 +               goto out;
17850 +
17851 +       d = a->src_dentry;
17852 +       a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
17853 +       if (au_ftest_ren(a->flags, ISDIR)) {
17854 +               err = may_rename_srcdir(d, a->btgt);
17855 +               if (unlikely(err)) {
17856 +                       au_nhash_wh_free(&a->whlist);
17857 +                       a->whlist.nh_num = 0;
17858 +               }
17859 +       }
17860 +out:
17861 +       return err;
17862 +}
17863 +
17864 +/* ---------------------------------------------------------------------- */
17865 +
17866 +/*
17867 + * simple tests for rename.
17868 + * following the checks in vfs, plus the parent-child relationship.
17869 + */
17870 +static int au_may_ren(struct au_ren_args *a)
17871 +{
17872 +       int err, isdir;
17873 +       struct inode *h_inode;
17874 +
17875 +       if (a->src_bstart == a->btgt) {
17876 +               err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
17877 +                                au_ftest_ren(a->flags, ISDIR));
17878 +               if (unlikely(err))
17879 +                       goto out;
17880 +               err = -EINVAL;
17881 +               if (unlikely(a->src_h_dentry == a->h_trap))
17882 +                       goto out;
17883 +       }
17884 +
17885 +       err = 0;
17886 +       if (a->dst_bstart != a->btgt)
17887 +               goto out;
17888 +
17889 +       err = -ENOTEMPTY;
17890 +       if (unlikely(a->dst_h_dentry == a->h_trap))
17891 +               goto out;
17892 +
17893 +       err = -EIO;
17894 +       h_inode = a->dst_h_dentry->d_inode;
17895 +       isdir = !!au_ftest_ren(a->flags, ISDIR);
17896 +       if (!a->dst_dentry->d_inode) {
17897 +               if (unlikely(h_inode))
17898 +                       goto out;
17899 +               err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
17900 +                                isdir);
17901 +       } else {
17902 +               if (unlikely(!h_inode || !h_inode->i_nlink))
17903 +                       goto out;
17904 +               err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
17905 +                                isdir);
17906 +               if (unlikely(err))
17907 +                       goto out;
17908 +       }
17909 +
17910 +out:
17911 +       if (unlikely(err == -ENOENT || err == -EEXIST))
17912 +               err = -EIO;
17913 +       AuTraceErr(err);
17914 +       return err;
17915 +}
17916 +
17917 +/* ---------------------------------------------------------------------- */
17918 +
17919 +/*
17920 + * locking order
17921 + * (VFS)
17922 + * - src_dir and dir by lock_rename()
17923 + * - inode if exitsts
17924 + * (aufs)
17925 + * - lock all
17926 + *   + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
17927 + *     + si_read_lock
17928 + *     + di_write_lock2_child()
17929 + *       + di_write_lock_child()
17930 + *        + ii_write_lock_child()
17931 + *       + di_write_lock_child2()
17932 + *        + ii_write_lock_child2()
17933 + *     + src_parent and parent
17934 + *       + di_write_lock_parent()
17935 + *        + ii_write_lock_parent()
17936 + *       + di_write_lock_parent2()
17937 + *        + ii_write_lock_parent2()
17938 + *   + lower src_dir and dir by vfsub_lock_rename()
17939 + *   + verify the every relationships between child and parent. if any
17940 + *     of them failed, unlock all and return -EBUSY.
17941 + */
17942 +static void au_ren_unlock(struct au_ren_args *a)
17943 +{
17944 +       struct super_block *sb;
17945 +
17946 +       sb = a->dst_dentry->d_sb;
17947 +       if (au_ftest_ren(a->flags, MNT_WRITE))
17948 +               vfsub_mnt_drop_write(a->br->br_mnt);
17949 +       vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
17950 +                           a->dst_h_parent, a->dst_hdir);
17951 +}
17952 +
17953 +static int au_ren_lock(struct au_ren_args *a)
17954 +{
17955 +       int err;
17956 +       unsigned int udba;
17957 +
17958 +       err = 0;
17959 +       a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
17960 +       a->src_hdir = au_hi(a->src_dir, a->btgt);
17961 +       a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
17962 +       a->dst_hdir = au_hi(a->dst_dir, a->btgt);
17963 +       a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
17964 +                                     a->dst_h_parent, a->dst_hdir);
17965 +       udba = au_opt_udba(a->src_dentry->d_sb);
17966 +       if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
17967 +                    || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
17968 +               err = au_busy_or_stale();
17969 +       if (!err && au_dbstart(a->src_dentry) == a->btgt)
17970 +               err = au_h_verify(a->src_h_dentry, udba,
17971 +                                 a->src_h_parent->d_inode, a->src_h_parent,
17972 +                                 a->br);
17973 +       if (!err && au_dbstart(a->dst_dentry) == a->btgt)
17974 +               err = au_h_verify(a->dst_h_dentry, udba,
17975 +                                 a->dst_h_parent->d_inode, a->dst_h_parent,
17976 +                                 a->br);
17977 +       if (!err) {
17978 +               err = vfsub_mnt_want_write(a->br->br_mnt);
17979 +               if (unlikely(err))
17980 +                       goto out_unlock;
17981 +               au_fset_ren(a->flags, MNT_WRITE);
17982 +               goto out; /* success */
17983 +       }
17984 +
17985 +       err = au_busy_or_stale();
17986 +
17987 +out_unlock:
17988 +       au_ren_unlock(a);
17989 +out:
17990 +       return err;
17991 +}
17992 +
17993 +/* ---------------------------------------------------------------------- */
17994 +
17995 +static void au_ren_refresh_dir(struct au_ren_args *a)
17996 +{
17997 +       struct inode *dir;
17998 +
17999 +       dir = a->dst_dir;
18000 +       dir->i_version++;
18001 +       if (au_ftest_ren(a->flags, ISDIR)) {
18002 +               /* is this updating defined in POSIX? */
18003 +               au_cpup_attr_timesizes(a->src_inode);
18004 +               au_cpup_attr_nlink(dir, /*force*/1);
18005 +       }
18006 +
18007 +       if (au_ibstart(dir) == a->btgt)
18008 +               au_cpup_attr_timesizes(dir);
18009 +
18010 +       if (au_ftest_ren(a->flags, ISSAMEDIR))
18011 +               return;
18012 +
18013 +       dir = a->src_dir;
18014 +       dir->i_version++;
18015 +       if (au_ftest_ren(a->flags, ISDIR))
18016 +               au_cpup_attr_nlink(dir, /*force*/1);
18017 +       if (au_ibstart(dir) == a->btgt)
18018 +               au_cpup_attr_timesizes(dir);
18019 +}
18020 +
18021 +static void au_ren_refresh(struct au_ren_args *a)
18022 +{
18023 +       aufs_bindex_t bend, bindex;
18024 +       struct dentry *d, *h_d;
18025 +       struct inode *i, *h_i;
18026 +       struct super_block *sb;
18027 +
18028 +       d = a->dst_dentry;
18029 +       d_drop(d);
18030 +       if (a->h_dst)
18031 +               /* already dget-ed by au_ren_or_cpup() */
18032 +               au_set_h_dptr(d, a->btgt, a->h_dst);
18033 +
18034 +       i = a->dst_inode;
18035 +       if (i) {
18036 +               if (!au_ftest_ren(a->flags, ISDIR))
18037 +                       vfsub_drop_nlink(i);
18038 +               else {
18039 +                       vfsub_dead_dir(i);
18040 +                       au_cpup_attr_timesizes(i);
18041 +               }
18042 +               au_update_dbrange(d, /*do_put_zero*/1);
18043 +       } else {
18044 +               bend = a->btgt;
18045 +               for (bindex = au_dbstart(d); bindex < bend; bindex++)
18046 +                       au_set_h_dptr(d, bindex, NULL);
18047 +               bend = au_dbend(d);
18048 +               for (bindex = a->btgt + 1; bindex <= bend; bindex++)
18049 +                       au_set_h_dptr(d, bindex, NULL);
18050 +               au_update_dbrange(d, /*do_put_zero*/0);
18051 +       }
18052 +
18053 +       d = a->src_dentry;
18054 +       au_set_dbwh(d, -1);
18055 +       bend = au_dbend(d);
18056 +       for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18057 +               h_d = au_h_dptr(d, bindex);
18058 +               if (h_d)
18059 +                       au_set_h_dptr(d, bindex, NULL);
18060 +       }
18061 +       au_set_dbend(d, a->btgt);
18062 +
18063 +       sb = d->d_sb;
18064 +       i = a->src_inode;
18065 +       if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
18066 +               return; /* success */
18067 +
18068 +       bend = au_ibend(i);
18069 +       for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18070 +               h_i = au_h_iptr(i, bindex);
18071 +               if (h_i) {
18072 +                       au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
18073 +                       /* ignore this error */
18074 +                       au_set_h_iptr(i, bindex, NULL, 0);
18075 +               }
18076 +       }
18077 +       au_set_ibend(i, a->btgt);
18078 +}
18079 +
18080 +/* ---------------------------------------------------------------------- */
18081 +
18082 +/* mainly for link(2) and rename(2) */
18083 +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
18084 +{
18085 +       aufs_bindex_t bdiropq, bwh;
18086 +       struct dentry *parent;
18087 +       struct au_branch *br;
18088 +
18089 +       parent = dentry->d_parent;
18090 +       IMustLock(parent->d_inode); /* dir is locked */
18091 +
18092 +       bdiropq = au_dbdiropq(parent);
18093 +       bwh = au_dbwh(dentry);
18094 +       br = au_sbr(dentry->d_sb, btgt);
18095 +       if (au_br_rdonly(br)
18096 +           || (0 <= bdiropq && bdiropq < btgt)
18097 +           || (0 <= bwh && bwh < btgt))
18098 +               btgt = -1;
18099 +
18100 +       AuDbg("btgt %d\n", btgt);
18101 +       return btgt;
18102 +}
18103 +
18104 +/* sets src_bstart, dst_bstart and btgt */
18105 +static int au_ren_wbr(struct au_ren_args *a)
18106 +{
18107 +       int err;
18108 +       struct au_wr_dir_args wr_dir_args = {
18109 +               /* .force_btgt  = -1, */
18110 +               .flags          = AuWrDir_ADD_ENTRY
18111 +       };
18112 +
18113 +       a->src_bstart = au_dbstart(a->src_dentry);
18114 +       a->dst_bstart = au_dbstart(a->dst_dentry);
18115 +       if (au_ftest_ren(a->flags, ISDIR))
18116 +               au_fset_wrdir(wr_dir_args.flags, ISDIR);
18117 +       wr_dir_args.force_btgt = a->src_bstart;
18118 +       if (a->dst_inode && a->dst_bstart < a->src_bstart)
18119 +               wr_dir_args.force_btgt = a->dst_bstart;
18120 +       wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
18121 +       err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
18122 +       a->btgt = err;
18123 +
18124 +       return err;
18125 +}
18126 +
18127 +static void au_ren_dt(struct au_ren_args *a)
18128 +{
18129 +       a->h_path.dentry = a->src_h_parent;
18130 +       au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
18131 +       if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
18132 +               a->h_path.dentry = a->dst_h_parent;
18133 +               au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
18134 +       }
18135 +
18136 +       au_fclr_ren(a->flags, DT_DSTDIR);
18137 +       if (!au_ftest_ren(a->flags, ISDIR))
18138 +               return;
18139 +
18140 +       a->h_path.dentry = a->src_h_dentry;
18141 +       au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
18142 +       if (a->dst_h_dentry->d_inode) {
18143 +               au_fset_ren(a->flags, DT_DSTDIR);
18144 +               a->h_path.dentry = a->dst_h_dentry;
18145 +               au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
18146 +       }
18147 +}
18148 +
18149 +static void au_ren_rev_dt(int err, struct au_ren_args *a)
18150 +{
18151 +       struct dentry *h_d;
18152 +       struct mutex *h_mtx;
18153 +
18154 +       au_dtime_revert(a->src_dt + AuPARENT);
18155 +       if (!au_ftest_ren(a->flags, ISSAMEDIR))
18156 +               au_dtime_revert(a->dst_dt + AuPARENT);
18157 +
18158 +       if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
18159 +               h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
18160 +               h_mtx = &h_d->d_inode->i_mutex;
18161 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18162 +               au_dtime_revert(a->src_dt + AuCHILD);
18163 +               mutex_unlock(h_mtx);
18164 +
18165 +               if (au_ftest_ren(a->flags, DT_DSTDIR)) {
18166 +                       h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
18167 +                       h_mtx = &h_d->d_inode->i_mutex;
18168 +                       mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18169 +                       au_dtime_revert(a->dst_dt + AuCHILD);
18170 +                       mutex_unlock(h_mtx);
18171 +               }
18172 +       }
18173 +}
18174 +
18175 +/* ---------------------------------------------------------------------- */
18176 +
18177 +int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
18178 +               struct inode *_dst_dir, struct dentry *_dst_dentry)
18179 +{
18180 +       int err, flags;
18181 +       /* reduce stack space */
18182 +       struct au_ren_args *a;
18183 +
18184 +       AuDbg("%.*s, %.*s\n", AuDLNPair(_src_dentry), AuDLNPair(_dst_dentry));
18185 +       IMustLock(_src_dir);
18186 +       IMustLock(_dst_dir);
18187 +
18188 +       err = -ENOMEM;
18189 +       BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
18190 +       a = kzalloc(sizeof(*a), GFP_NOFS);
18191 +       if (unlikely(!a))
18192 +               goto out;
18193 +
18194 +       a->src_dir = _src_dir;
18195 +       a->src_dentry = _src_dentry;
18196 +       a->src_inode = a->src_dentry->d_inode;
18197 +       a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
18198 +       a->dst_dir = _dst_dir;
18199 +       a->dst_dentry = _dst_dentry;
18200 +       a->dst_inode = a->dst_dentry->d_inode;
18201 +       a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
18202 +       if (a->dst_inode) {
18203 +               IMustLock(a->dst_inode);
18204 +               au_igrab(a->dst_inode);
18205 +       }
18206 +
18207 +       err = -ENOTDIR;
18208 +       flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
18209 +       if (S_ISDIR(a->src_inode->i_mode)) {
18210 +               au_fset_ren(a->flags, ISDIR);
18211 +               if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
18212 +                       goto out_free;
18213 +               err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18214 +                                               AuLock_DIR | flags);
18215 +       } else
18216 +               err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18217 +                                               flags);
18218 +       if (unlikely(err))
18219 +               goto out_free;
18220 +
18221 +       err = au_d_hashed_positive(a->src_dentry);
18222 +       if (unlikely(err))
18223 +               goto out_unlock;
18224 +       err = -ENOENT;
18225 +       if (a->dst_inode) {
18226 +               /*
18227 +                * If it is a dir, VFS unhash dst_dentry before this
18228 +                * function. It means we cannot rely upon d_unhashed().
18229 +                */
18230 +               if (unlikely(!a->dst_inode->i_nlink))
18231 +                       goto out_unlock;
18232 +               if (!S_ISDIR(a->dst_inode->i_mode)) {
18233 +                       err = au_d_hashed_positive(a->dst_dentry);
18234 +                       if (unlikely(err))
18235 +                               goto out_unlock;
18236 +               } else if (unlikely(IS_DEADDIR(a->dst_inode)))
18237 +                       goto out_unlock;
18238 +       } else if (unlikely(d_unhashed(a->dst_dentry)))
18239 +               goto out_unlock;
18240 +
18241 +       /*
18242 +        * is it possible?
18243 +        * yes, it happend (in linux-3.3-rcN) but I don't know why.
18244 +        * there may exist a problem somewhere else.
18245 +        */
18246 +       err = -EINVAL;
18247 +       if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
18248 +               goto out_unlock;
18249 +
18250 +       au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
18251 +       di_write_lock_parent(a->dst_parent);
18252 +
18253 +       /* which branch we process */
18254 +       err = au_ren_wbr(a);
18255 +       if (unlikely(err < 0))
18256 +               goto out_parent;
18257 +       a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
18258 +       a->h_path.mnt = a->br->br_mnt;
18259 +
18260 +       /* are they available to be renamed */
18261 +       err = au_ren_may_dir(a);
18262 +       if (unlikely(err))
18263 +               goto out_children;
18264 +
18265 +       /* prepare the writable parent dir on the same branch */
18266 +       if (a->dst_bstart == a->btgt) {
18267 +               au_fset_ren(a->flags, WHDST);
18268 +       } else {
18269 +               err = au_cpup_dirs(a->dst_dentry, a->btgt);
18270 +               if (unlikely(err))
18271 +                       goto out_children;
18272 +       }
18273 +
18274 +       if (a->src_dir != a->dst_dir) {
18275 +               /*
18276 +                * this temporary unlock is safe,
18277 +                * because both dir->i_mutex are locked.
18278 +                */
18279 +               di_write_unlock(a->dst_parent);
18280 +               di_write_lock_parent(a->src_parent);
18281 +               err = au_wr_dir_need_wh(a->src_dentry,
18282 +                                       au_ftest_ren(a->flags, ISDIR),
18283 +                                       &a->btgt);
18284 +               di_write_unlock(a->src_parent);
18285 +               di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
18286 +               au_fclr_ren(a->flags, ISSAMEDIR);
18287 +       } else
18288 +               err = au_wr_dir_need_wh(a->src_dentry,
18289 +                                       au_ftest_ren(a->flags, ISDIR),
18290 +                                       &a->btgt);
18291 +       if (unlikely(err < 0))
18292 +               goto out_children;
18293 +       if (err)
18294 +               au_fset_ren(a->flags, WHSRC);
18295 +
18296 +       /* lock them all */
18297 +       err = au_ren_lock(a);
18298 +       if (unlikely(err))
18299 +               goto out_children;
18300 +
18301 +       if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
18302 +               err = au_may_ren(a);
18303 +       else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
18304 +               err = -ENAMETOOLONG;
18305 +       if (unlikely(err))
18306 +               goto out_hdir;
18307 +
18308 +       /* store timestamps to be revertible */
18309 +       au_ren_dt(a);
18310 +
18311 +       /* here we go */
18312 +       err = do_rename(a);
18313 +       if (unlikely(err))
18314 +               goto out_dt;
18315 +
18316 +       /* update dir attributes */
18317 +       au_ren_refresh_dir(a);
18318 +
18319 +       /* dput/iput all lower dentries */
18320 +       au_ren_refresh(a);
18321 +
18322 +       goto out_hdir; /* success */
18323 +
18324 +out_dt:
18325 +       au_ren_rev_dt(err, a);
18326 +out_hdir:
18327 +       au_ren_unlock(a);
18328 +out_children:
18329 +       au_nhash_wh_free(&a->whlist);
18330 +       if (err && a->dst_inode && a->dst_bstart != a->btgt) {
18331 +               AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
18332 +               au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
18333 +               au_set_dbstart(a->dst_dentry, a->dst_bstart);
18334 +       }
18335 +out_parent:
18336 +       if (!err)
18337 +               d_move(a->src_dentry, a->dst_dentry);
18338 +       else {
18339 +               au_update_dbstart(a->dst_dentry);
18340 +               if (!a->dst_inode)
18341 +                       d_drop(a->dst_dentry);
18342 +       }
18343 +       if (au_ftest_ren(a->flags, ISSAMEDIR))
18344 +               di_write_unlock(a->dst_parent);
18345 +       else
18346 +               di_write_unlock2(a->src_parent, a->dst_parent);
18347 +out_unlock:
18348 +       aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
18349 +out_free:
18350 +       iput(a->dst_inode);
18351 +       if (a->thargs)
18352 +               au_whtmp_rmdir_free(a->thargs);
18353 +       kfree(a);
18354 +out:
18355 +       AuTraceErr(err);
18356 +       return err;
18357 +}
18358 diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
18359 --- /usr/share/empty/fs/aufs/Kconfig    1970-01-01 01:00:00.000000000 +0100
18360 +++ linux/fs/aufs/Kconfig       2012-08-26 08:39:00.757174634 +0200
18361 @@ -0,0 +1,203 @@
18362 +config AUFS_FS
18363 +       tristate "Aufs (Advanced multi layered unification filesystem) support"
18364 +       depends on EXPERIMENTAL
18365 +       help
18366 +       Aufs is a stackable unification filesystem such as Unionfs,
18367 +       which unifies several directories and provides a merged single
18368 +       directory.
18369 +       In the early days, aufs was entirely re-designed and
18370 +       re-implemented Unionfs Version 1.x series. Introducing many
18371 +       original ideas, approaches and improvements, it becomes totally
18372 +       different from Unionfs while keeping the basic features.
18373 +
18374 +if AUFS_FS
18375 +choice
18376 +       prompt "Maximum number of branches"
18377 +       default AUFS_BRANCH_MAX_127
18378 +       help
18379 +       Specifies the maximum number of branches (or member directories)
18380 +       in a single aufs. The larger value consumes more system
18381 +       resources and has a minor impact to performance.
18382 +config AUFS_BRANCH_MAX_127
18383 +       bool "127"
18384 +       help
18385 +       Specifies the maximum number of branches (or member directories)
18386 +       in a single aufs. The larger value consumes more system
18387 +       resources and has a minor impact to performance.
18388 +config AUFS_BRANCH_MAX_511
18389 +       bool "511"
18390 +       help
18391 +       Specifies the maximum number of branches (or member directories)
18392 +       in a single aufs. The larger value consumes more system
18393 +       resources and has a minor impact to performance.
18394 +config AUFS_BRANCH_MAX_1023
18395 +       bool "1023"
18396 +       help
18397 +       Specifies the maximum number of branches (or member directories)
18398 +       in a single aufs. The larger value consumes more system
18399 +       resources and has a minor impact to performance.
18400 +config AUFS_BRANCH_MAX_32767
18401 +       bool "32767"
18402 +       help
18403 +       Specifies the maximum number of branches (or member directories)
18404 +       in a single aufs. The larger value consumes more system
18405 +       resources and has a minor impact to performance.
18406 +endchoice
18407 +
18408 +config AUFS_SBILIST
18409 +       bool
18410 +       depends on AUFS_MAGIC_SYSRQ || PROC_FS
18411 +       default y
18412 +       help
18413 +       Automatic configuration for internal use.
18414 +       When aufs supports Magic SysRq or /proc, enabled automatically.
18415 +
18416 +config AUFS_HNOTIFY
18417 +       bool "Detect direct branch access (bypassing aufs)"
18418 +       help
18419 +       If you want to modify files on branches directly, eg. bypassing aufs,
18420 +       and want aufs to detect the changes of them fully, then enable this
18421 +       option and use 'udba=notify' mount option.
18422 +       Currently there is only one available configuration, "fsnotify".
18423 +       It will have a negative impact to the performance.
18424 +       See detail in aufs.5.
18425 +
18426 +choice
18427 +       prompt "method" if AUFS_HNOTIFY
18428 +       default AUFS_HFSNOTIFY
18429 +config AUFS_HFSNOTIFY
18430 +       bool "fsnotify"
18431 +       select FSNOTIFY
18432 +endchoice
18433 +
18434 +config AUFS_EXPORT
18435 +       bool "NFS-exportable aufs"
18436 +       depends on EXPORTFS
18437 +       help
18438 +       If you want to export your mounted aufs via NFS, then enable this
18439 +       option. There are several requirements for this configuration.
18440 +       See detail in aufs.5.
18441 +
18442 +config AUFS_INO_T_64
18443 +       bool
18444 +       depends on AUFS_EXPORT
18445 +       depends on 64BIT && !(ALPHA || S390)
18446 +       default y
18447 +       help
18448 +       Automatic configuration for internal use.
18449 +       /* typedef unsigned long/int __kernel_ino_t */
18450 +       /* alpha and s390x are int */
18451 +
18452 +config AUFS_RDU
18453 +       bool "Readdir in userspace"
18454 +       help
18455 +       Aufs has two methods to provide a merged view for a directory,
18456 +       by a user-space library and by kernel-space natively. The latter
18457 +       is always enabled but sometimes large and slow.
18458 +       If you enable this option, install the library in aufs2-util
18459 +       package, and set some environment variables for your readdir(3),
18460 +       then the work will be handled in user-space which generally
18461 +       shows better performance in most cases.
18462 +       See detail in aufs.5.
18463 +
18464 +config AUFS_PROC_MAP
18465 +       bool "support for /proc/maps and lsof(1)"
18466 +       depends on PROC_FS
18467 +       help
18468 +       When you issue mmap(2) in aufs, it is actually a direct mmap(2)
18469 +       call to the file on the branch fs since the file in aufs is
18470 +       purely virtual. And the file path printed in /proc/maps (and
18471 +       others) will be the path on the branch fs. In most cases, it
18472 +       does no harm. But some utilities like lsof(1) may confuse since
18473 +       the utility or user may expect the file path in aufs to be
18474 +       printed.
18475 +       To address this issue, aufs provides a patch which introduces a
18476 +       new member called vm_prfile into struct vm_are_struct. The patch
18477 +       is meaningless without enabling this configuration since nobody
18478 +       sets the new vm_prfile member.
18479 +       If you don't apply the patch, then enabling this configuration
18480 +       will cause a compile error.
18481 +       This approach is fragile since if someone else make some changes
18482 +       around vm_file, then vm_prfile may not work anymore. As a
18483 +       workaround such case, aufs provides this configuration. If you
18484 +       disable it, then lsof(1) may produce incorrect result but the
18485 +       problem will be gone even if the aufs patch is applied (I hope).
18486 +
18487 +config AUFS_SP_IATTR
18488 +       bool "Respect the attributes (mtime/ctime mainly) of special files"
18489 +       help
18490 +       When you write something to a special file, some attributes of it
18491 +       (mtime/ctime mainly) may be updated. Generally such updates are
18492 +       less important (actually some device drivers and NFS ignore
18493 +       it). But some applications (such like test program) requires
18494 +       such updates. If you need these updates, then enable this
18495 +       configuration which introduces some overhead.
18496 +       Currently this configuration handles FIFO only.
18497 +
18498 +config AUFS_SHWH
18499 +       bool "Show whiteouts"
18500 +       help
18501 +       If you want to make the whiteouts in aufs visible, then enable
18502 +       this option and specify 'shwh' mount option. Although it may
18503 +       sounds like philosophy or something, but in technically it
18504 +       simply shows the name of whiteout with keeping its behaviour.
18505 +
18506 +config AUFS_BR_RAMFS
18507 +       bool "Ramfs (initramfs/rootfs) as an aufs branch"
18508 +       help
18509 +       If you want to use ramfs as an aufs branch fs, then enable this
18510 +       option. Generally tmpfs is recommended.
18511 +       Aufs prohibited them to be a branch fs by default, because
18512 +       initramfs becomes unusable after switch_root or something
18513 +       generally. If you sets initramfs as an aufs branch and boot your
18514 +       system by switch_root, you will meet a problem easily since the
18515 +       files in initramfs may be inaccessible.
18516 +       Unless you are going to use ramfs as an aufs branch fs without
18517 +       switch_root or something, leave it N.
18518 +
18519 +config AUFS_BR_FUSE
18520 +       bool "Fuse fs as an aufs branch"
18521 +       depends on FUSE_FS
18522 +       select AUFS_POLL
18523 +       help
18524 +       If you want to use fuse-based userspace filesystem as an aufs
18525 +       branch fs, then enable this option.
18526 +       It implements the internal poll(2) operation which is
18527 +       implemented by fuse only (curretnly).
18528 +
18529 +config AUFS_POLL
18530 +       bool
18531 +       help
18532 +       Automatic configuration for internal use.
18533 +
18534 +config AUFS_BR_HFSPLUS
18535 +       bool "Hfsplus as an aufs branch"
18536 +       depends on HFSPLUS_FS
18537 +       default y
18538 +       help
18539 +       If you want to use hfsplus fs as an aufs branch fs, then enable
18540 +       this option. This option introduces a small overhead at
18541 +       copying-up a file on hfsplus.
18542 +
18543 +config AUFS_BDEV_LOOP
18544 +       bool
18545 +       depends on BLK_DEV_LOOP
18546 +       default y
18547 +       help
18548 +       Automatic configuration for internal use.
18549 +       Convert =[ym] into =y.
18550 +
18551 +config AUFS_DEBUG
18552 +       bool "Debug aufs"
18553 +       help
18554 +       Enable this to compile aufs internal debug code.
18555 +       It will have a negative impact to the performance.
18556 +
18557 +config AUFS_MAGIC_SYSRQ
18558 +       bool
18559 +       depends on AUFS_DEBUG && MAGIC_SYSRQ
18560 +       default y
18561 +       help
18562 +       Automatic configuration for internal use.
18563 +       When aufs supports Magic SysRq, enabled automatically.
18564 +endif
18565 diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
18566 --- /usr/share/empty/fs/aufs/loop.c     1970-01-01 01:00:00.000000000 +0100
18567 +++ linux/fs/aufs/loop.c        2013-01-11 19:46:12.639281345 +0100
18568 @@ -0,0 +1,133 @@
18569 +/*
18570 + * Copyright (C) 2005-2013 Junjiro R. Okajima
18571 + *
18572 + * This program, aufs is free software; you can redistribute it and/or modify
18573 + * it under the terms of the GNU General Public License as published by
18574 + * the Free Software Foundation; either version 2 of the License, or
18575 + * (at your option) any later version.
18576 + *
18577 + * This program is distributed in the hope that it will be useful,
18578 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
18579 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18580 + * GNU General Public License for more details.
18581 + *
18582 + * You should have received a copy of the GNU General Public License
18583 + * along with this program; if not, write to the Free Software
18584 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18585 + */
18586 +
18587 +/*
18588 + * support for loopback block device as a branch
18589 + */
18590 +
18591 +#include <linux/loop.h>
18592 +#include "aufs.h"
18593 +
18594 +/*
18595 + * test if two lower dentries have overlapping branches.
18596 + */
18597 +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
18598 +{
18599 +       struct super_block *h_sb;
18600 +       struct loop_device *l;
18601 +
18602 +       h_sb = h_adding->d_sb;
18603 +       if (MAJOR(h_sb->s_dev) != LOOP_MAJOR)
18604 +               return 0;
18605 +
18606 +       l = h_sb->s_bdev->bd_disk->private_data;
18607 +       h_adding = l->lo_backing_file->f_dentry;
18608 +       /*
18609 +        * h_adding can be local NFS.
18610 +        * in this case aufs cannot detect the loop.
18611 +        */
18612 +       if (unlikely(h_adding->d_sb == sb))
18613 +               return 1;
18614 +       return !!au_test_subdir(h_adding, sb->s_root);
18615 +}
18616 +
18617 +/* true if a kernel thread named 'loop[0-9].*' accesses a file */
18618 +int au_test_loopback_kthread(void)
18619 +{
18620 +       int ret;
18621 +       struct task_struct *tsk = current;
18622 +
18623 +       ret = 0;
18624 +       if (tsk->flags & PF_KTHREAD) {
18625 +               const char c = tsk->comm[4];
18626 +               ret = ('0' <= c && c <= '9'
18627 +                      && !strncmp(tsk->comm, "loop", 4));
18628 +       }
18629 +
18630 +       return ret;
18631 +}
18632 +
18633 +/* ---------------------------------------------------------------------- */
18634 +
18635 +#define au_warn_loopback_step  16
18636 +static int au_warn_loopback_nelem = au_warn_loopback_step;
18637 +static unsigned long *au_warn_loopback_array;
18638 +
18639 +void au_warn_loopback(struct super_block *h_sb)
18640 +{
18641 +       int i, new_nelem;
18642 +       unsigned long *a, magic;
18643 +       static DEFINE_SPINLOCK(spin);
18644 +
18645 +       magic = h_sb->s_magic;
18646 +       spin_lock(&spin);
18647 +       a = au_warn_loopback_array;
18648 +       for (i = 0; i < au_warn_loopback_nelem && *a; i++)
18649 +               if (a[i] == magic) {
18650 +                       spin_unlock(&spin);
18651 +                       return;
18652 +               }
18653 +
18654 +       /* h_sb is new to us, print it */
18655 +       if (i < au_warn_loopback_nelem) {
18656 +               a[i] = magic;
18657 +               goto pr;
18658 +       }
18659 +
18660 +       /* expand the array */
18661 +       new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
18662 +       a = au_kzrealloc(au_warn_loopback_array,
18663 +                        au_warn_loopback_nelem * sizeof(unsigned long),
18664 +                        new_nelem * sizeof(unsigned long), GFP_ATOMIC);
18665 +       if (a) {
18666 +               au_warn_loopback_nelem = new_nelem;
18667 +               au_warn_loopback_array = a;
18668 +               a[i] = magic;
18669 +               goto pr;
18670 +       }
18671 +
18672 +       spin_unlock(&spin);
18673 +       AuWarn1("realloc failed, ignored\n");
18674 +       return;
18675 +
18676 +pr:
18677 +       spin_unlock(&spin);
18678 +       pr_warn("you may want to try another patch for loopback file "
18679 +               "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
18680 +}
18681 +
18682 +int au_loopback_init(void)
18683 +{
18684 +       int err;
18685 +       struct super_block *sb __maybe_unused;
18686 +
18687 +       AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
18688 +
18689 +       err = 0;
18690 +       au_warn_loopback_array = kcalloc(au_warn_loopback_step,
18691 +                                        sizeof(unsigned long), GFP_NOFS);
18692 +       if (unlikely(!au_warn_loopback_array))
18693 +               err = -ENOMEM;
18694 +
18695 +       return err;
18696 +}
18697 +
18698 +void au_loopback_fin(void)
18699 +{
18700 +       kfree(au_warn_loopback_array);
18701 +}
18702 diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
18703 --- /usr/share/empty/fs/aufs/loop.h     1970-01-01 01:00:00.000000000 +0100
18704 +++ linux/fs/aufs/loop.h        2013-01-11 19:46:12.639281345 +0100
18705 @@ -0,0 +1,50 @@
18706 +/*
18707 + * Copyright (C) 2005-2013 Junjiro R. Okajima
18708 + *
18709 + * This program, aufs is free software; you can redistribute it and/or modify
18710 + * it under the terms of the GNU General Public License as published by
18711 + * the Free Software Foundation; either version 2 of the License, or
18712 + * (at your option) any later version.
18713 + *
18714 + * This program is distributed in the hope that it will be useful,
18715 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
18716 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18717 + * GNU General Public License for more details.
18718 + *
18719 + * You should have received a copy of the GNU General Public License
18720 + * along with this program; if not, write to the Free Software
18721 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18722 + */
18723 +
18724 +/*
18725 + * support for loopback mount as a branch
18726 + */
18727 +
18728 +#ifndef __AUFS_LOOP_H__
18729 +#define __AUFS_LOOP_H__
18730 +
18731 +#ifdef __KERNEL__
18732 +
18733 +struct dentry;
18734 +struct super_block;
18735 +
18736 +#ifdef CONFIG_AUFS_BDEV_LOOP
18737 +/* loop.c */
18738 +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
18739 +int au_test_loopback_kthread(void);
18740 +void au_warn_loopback(struct super_block *h_sb);
18741 +
18742 +int au_loopback_init(void);
18743 +void au_loopback_fin(void);
18744 +#else
18745 +AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
18746 +          struct dentry *h_adding)
18747 +AuStubInt0(au_test_loopback_kthread, void)
18748 +AuStubVoid(au_warn_loopback, struct super_block *h_sb)
18749 +
18750 +AuStubInt0(au_loopback_init, void)
18751 +AuStubVoid(au_loopback_fin, void)
18752 +#endif /* BLK_DEV_LOOP */
18753 +
18754 +#endif /* __KERNEL__ */
18755 +#endif /* __AUFS_LOOP_H__ */
18756 diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
18757 --- /usr/share/empty/fs/aufs/magic.mk   1970-01-01 01:00:00.000000000 +0100
18758 +++ linux/fs/aufs/magic.mk      2012-08-26 08:39:00.760508065 +0200
18759 @@ -0,0 +1,54 @@
18760 +
18761 +# defined in ${srctree}/fs/fuse/inode.c
18762 +# tristate
18763 +ifdef CONFIG_FUSE_FS
18764 +ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
18765 +endif
18766 +
18767 +# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
18768 +# tristate
18769 +ifdef CONFIG_OCFS2_FS
18770 +ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
18771 +endif
18772 +
18773 +# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
18774 +# tristate
18775 +ifdef CONFIG_OCFS2_FS_O2CB
18776 +ccflags-y += -DDLMFS_MAGIC=0x76a9f425
18777 +endif
18778 +
18779 +# defined in ${srctree}/fs/cifs/cifsfs.c
18780 +# tristate
18781 +ifdef CONFIG_CIFS_FS
18782 +ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
18783 +endif
18784 +
18785 +# defined in ${srctree}/fs/xfs/xfs_sb.h
18786 +# tristate
18787 +ifdef CONFIG_XFS_FS
18788 +ccflags-y += -DXFS_SB_MAGIC=0x58465342
18789 +endif
18790 +
18791 +# defined in ${srctree}/fs/configfs/mount.c
18792 +# tristate
18793 +ifdef CONFIG_CONFIGFS_FS
18794 +ccflags-y += -DCONFIGFS_MAGIC=0x62656570
18795 +endif
18796 +
18797 +# defined in ${srctree}/fs/9p/v9fs.h
18798 +# tristate
18799 +ifdef CONFIG_9P_FS
18800 +ccflags-y += -DV9FS_MAGIC=0x01021997
18801 +endif
18802 +
18803 +# defined in ${srctree}/fs/ubifs/ubifs.h
18804 +# tristate
18805 +ifdef CONFIG_UBIFS_FS
18806 +ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
18807 +endif
18808 +
18809 +# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
18810 +# tristate
18811 +ifdef CONFIG_HFSPLUS_FS
18812 +ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
18813 +endif
18814 diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
18815 --- /usr/share/empty/fs/aufs/Makefile   1970-01-01 01:00:00.000000000 +0100
18816 +++ linux/fs/aufs/Makefile      2012-08-26 08:39:00.757174634 +0200
18817 @@ -0,0 +1,42 @@
18818 +
18819 +include ${src}/magic.mk
18820 +ifeq (${CONFIG_AUFS_FS},m)
18821 +include ${src}/conf.mk
18822 +endif
18823 +-include ${src}/priv_def.mk
18824 +
18825 +# cf. include/linux/kernel.h
18826 +# enable pr_debug
18827 +ccflags-y += -DDEBUG
18828 +# sparse requires the full pathname
18829 +ifdef M
18830 +ccflags-y += -include ${M}/../../include/linux/aufs_type.h
18831 +else
18832 +ccflags-y += -include ${srctree}/include/linux/aufs_type.h
18833 +endif
18834 +
18835 +obj-$(CONFIG_AUFS_FS) += aufs.o
18836 +aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
18837 +       wkq.o vfsub.o dcsub.o \
18838 +       cpup.o whout.o wbr_policy.o \
18839 +       dinfo.o dentry.o \
18840 +       dynop.o \
18841 +       finfo.o file.o f_op.o \
18842 +       dir.o vdir.o \
18843 +       iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
18844 +       ioctl.o
18845 +
18846 +# all are boolean
18847 +aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
18848 +aufs-$(CONFIG_SYSFS) += sysfs.o
18849 +aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
18850 +aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
18851 +aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
18852 +aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
18853 +aufs-$(CONFIG_AUFS_EXPORT) += export.o
18854 +aufs-$(CONFIG_AUFS_POLL) += poll.o
18855 +aufs-$(CONFIG_AUFS_RDU) += rdu.o
18856 +aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
18857 +aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
18858 +aufs-$(CONFIG_AUFS_DEBUG) += debug.o
18859 +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
18860 diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
18861 --- /usr/share/empty/fs/aufs/module.c   1970-01-01 01:00:00.000000000 +0100
18862 +++ linux/fs/aufs/module.c      2013-01-11 19:46:28.699667650 +0100
18863 @@ -0,0 +1,202 @@
18864 +/*
18865 + * Copyright (C) 2005-2013 Junjiro R. Okajima
18866 + *
18867 + * This program, aufs is free software; you can redistribute it and/or modify
18868 + * it under the terms of the GNU General Public License as published by
18869 + * the Free Software Foundation; either version 2 of the License, or
18870 + * (at your option) any later version.
18871 + *
18872 + * This program is distributed in the hope that it will be useful,
18873 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
18874 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18875 + * GNU General Public License for more details.
18876 + *
18877 + * You should have received a copy of the GNU General Public License
18878 + * along with this program; if not, write to the Free Software
18879 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18880 + */
18881 +
18882 +/*
18883 + * module global variables and operations
18884 + */
18885 +
18886 +#include <linux/module.h>
18887 +#include <linux/seq_file.h>
18888 +#include "aufs.h"
18889 +
18890 +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
18891 +{
18892 +       if (new_sz <= nused)
18893 +               return p;
18894 +
18895 +       p = krealloc(p, new_sz, gfp);
18896 +       if (p)
18897 +               memset(p + nused, 0, new_sz - nused);
18898 +       return p;
18899 +}
18900 +
18901 +/* ---------------------------------------------------------------------- */
18902 +
18903 +/*
18904 + * aufs caches
18905 + */
18906 +struct kmem_cache *au_cachep[AuCache_Last];
18907 +static int __init au_cache_init(void)
18908 +{
18909 +       au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
18910 +       if (au_cachep[AuCache_DINFO])
18911 +               /* SLAB_DESTROY_BY_RCU */
18912 +               au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
18913 +                                                       au_icntnr_init_once);
18914 +       if (au_cachep[AuCache_ICNTNR])
18915 +               au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
18916 +                                                      au_fi_init_once);
18917 +       if (au_cachep[AuCache_FINFO])
18918 +               au_cachep[AuCache_VDIR] = AuCache(au_vdir);
18919 +       if (au_cachep[AuCache_VDIR])
18920 +               au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
18921 +       if (au_cachep[AuCache_DEHSTR])
18922 +               return 0;
18923 +
18924 +       return -ENOMEM;
18925 +}
18926 +
18927 +static void au_cache_fin(void)
18928 +{
18929 +       int i;
18930 +
18931 +       /*
18932 +        * Make sure all delayed rcu free inodes are flushed before we
18933 +        * destroy cache.
18934 +        */
18935 +       rcu_barrier();
18936 +
18937 +       /* excluding AuCache_HNOTIFY */
18938 +       BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
18939 +       for (i = 0; i < AuCache_HNOTIFY; i++)
18940 +               if (au_cachep[i]) {
18941 +                       kmem_cache_destroy(au_cachep[i]);
18942 +                       au_cachep[i] = NULL;
18943 +               }
18944 +}
18945 +
18946 +/* ---------------------------------------------------------------------- */
18947 +
18948 +int au_dir_roflags;
18949 +
18950 +#ifdef CONFIG_AUFS_SBILIST
18951 +/*
18952 + * iterate_supers_type() doesn't protect us from
18953 + * remounting (branch management)
18954 + */
18955 +struct au_splhead au_sbilist;
18956 +#endif
18957 +
18958 +struct lock_class_key au_lc_key[AuLcKey_Last];
18959 +
18960 +/*
18961 + * functions for module interface.
18962 + */
18963 +MODULE_LICENSE("GPL");
18964 +/* MODULE_LICENSE("GPL v2"); */
18965 +MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
18966 +MODULE_DESCRIPTION(AUFS_NAME
18967 +       " -- Advanced multi layered unification filesystem");
18968 +MODULE_VERSION(AUFS_VERSION);
18969 +
18970 +/* this module parameter has no meaning when SYSFS is disabled */
18971 +int sysaufs_brs = 1;
18972 +MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
18973 +module_param_named(brs, sysaufs_brs, int, S_IRUGO);
18974 +
18975 +/* ---------------------------------------------------------------------- */
18976 +
18977 +static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
18978 +
18979 +int au_seq_path(struct seq_file *seq, struct path *path)
18980 +{
18981 +       return seq_path(seq, path, au_esc_chars);
18982 +}
18983 +
18984 +/* ---------------------------------------------------------------------- */
18985 +
18986 +static int __init aufs_init(void)
18987 +{
18988 +       int err, i;
18989 +       char *p;
18990 +
18991 +       p = au_esc_chars;
18992 +       for (i = 1; i <= ' '; i++)
18993 +               *p++ = i;
18994 +       *p++ = '\\';
18995 +       *p++ = '\x7f';
18996 +       *p = 0;
18997 +
18998 +       au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
18999 +
19000 +       au_sbilist_init();
19001 +       sysaufs_brs_init();
19002 +       au_debug_init();
19003 +       au_dy_init();
19004 +       err = sysaufs_init();
19005 +       if (unlikely(err))
19006 +               goto out;
19007 +       err = au_procfs_init();
19008 +       if (unlikely(err))
19009 +               goto out_sysaufs;
19010 +       err = au_wkq_init();
19011 +       if (unlikely(err))
19012 +               goto out_procfs;
19013 +       err = au_loopback_init();
19014 +       if (unlikely(err))
19015 +               goto out_wkq;
19016 +       err = au_hnotify_init();
19017 +       if (unlikely(err))
19018 +               goto out_loopback;
19019 +       err = au_sysrq_init();
19020 +       if (unlikely(err))
19021 +               goto out_hin;
19022 +       err = au_cache_init();
19023 +       if (unlikely(err))
19024 +               goto out_sysrq;
19025 +       err = register_filesystem(&aufs_fs_type);
19026 +       if (unlikely(err))
19027 +               goto out_cache;
19028 +       /* since we define pr_fmt, call printk directly */
19029 +       printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
19030 +       goto out; /* success */
19031 +
19032 +out_cache:
19033 +       au_cache_fin();
19034 +out_sysrq:
19035 +       au_sysrq_fin();
19036 +out_hin:
19037 +       au_hnotify_fin();
19038 +out_loopback:
19039 +       au_loopback_fin();
19040 +out_wkq:
19041 +       au_wkq_fin();
19042 +out_procfs:
19043 +       au_procfs_fin();
19044 +out_sysaufs:
19045 +       sysaufs_fin();
19046 +       au_dy_fin();
19047 +out:
19048 +       return err;
19049 +}
19050 +
19051 +static void __exit aufs_exit(void)
19052 +{
19053 +       unregister_filesystem(&aufs_fs_type);
19054 +       au_cache_fin();
19055 +       au_sysrq_fin();
19056 +       au_hnotify_fin();
19057 +       au_loopback_fin();
19058 +       au_wkq_fin();
19059 +       au_procfs_fin();
19060 +       sysaufs_fin();
19061 +       au_dy_fin();
19062 +}
19063 +
19064 +module_init(aufs_init);
19065 +module_exit(aufs_exit);
19066 diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
19067 --- /usr/share/empty/fs/aufs/module.h   1970-01-01 01:00:00.000000000 +0100
19068 +++ linux/fs/aufs/module.h      2013-01-11 19:46:12.639281345 +0100
19069 @@ -0,0 +1,105 @@
19070 +/*
19071 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19072 + *
19073 + * This program, aufs is free software; you can redistribute it and/or modify
19074 + * it under the terms of the GNU General Public License as published by
19075 + * the Free Software Foundation; either version 2 of the License, or
19076 + * (at your option) any later version.
19077 + *
19078 + * This program is distributed in the hope that it will be useful,
19079 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19080 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19081 + * GNU General Public License for more details.
19082 + *
19083 + * You should have received a copy of the GNU General Public License
19084 + * along with this program; if not, write to the Free Software
19085 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19086 + */
19087 +
19088 +/*
19089 + * module initialization and module-global
19090 + */
19091 +
19092 +#ifndef __AUFS_MODULE_H__
19093 +#define __AUFS_MODULE_H__
19094 +
19095 +#ifdef __KERNEL__
19096 +
19097 +#include <linux/slab.h>
19098 +
19099 +struct path;
19100 +struct seq_file;
19101 +
19102 +/* module parameters */
19103 +extern int sysaufs_brs;
19104 +
19105 +/* ---------------------------------------------------------------------- */
19106 +
19107 +extern int au_dir_roflags;
19108 +
19109 +enum {
19110 +       AuLcNonDir_FIINFO,
19111 +       AuLcNonDir_DIINFO,
19112 +       AuLcNonDir_IIINFO,
19113 +
19114 +       AuLcDir_FIINFO,
19115 +       AuLcDir_DIINFO,
19116 +       AuLcDir_IIINFO,
19117 +
19118 +       AuLcSymlink_DIINFO,
19119 +       AuLcSymlink_IIINFO,
19120 +
19121 +       AuLcKey_Last
19122 +};
19123 +extern struct lock_class_key au_lc_key[AuLcKey_Last];
19124 +
19125 +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
19126 +int au_seq_path(struct seq_file *seq, struct path *path);
19127 +
19128 +#ifdef CONFIG_PROC_FS
19129 +/* procfs.c */
19130 +int __init au_procfs_init(void);
19131 +void au_procfs_fin(void);
19132 +#else
19133 +AuStubInt0(au_procfs_init, void);
19134 +AuStubVoid(au_procfs_fin, void);
19135 +#endif
19136 +
19137 +/* ---------------------------------------------------------------------- */
19138 +
19139 +/* kmem cache */
19140 +enum {
19141 +       AuCache_DINFO,
19142 +       AuCache_ICNTNR,
19143 +       AuCache_FINFO,
19144 +       AuCache_VDIR,
19145 +       AuCache_DEHSTR,
19146 +       AuCache_HNOTIFY, /* must be last */
19147 +       AuCache_Last
19148 +};
19149 +
19150 +#define AuCacheFlags           (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
19151 +#define AuCache(type)          KMEM_CACHE(type, AuCacheFlags)
19152 +#define AuCacheCtor(type, ctor)        \
19153 +       kmem_cache_create(#type, sizeof(struct type), \
19154 +                         __alignof__(struct type), AuCacheFlags, ctor)
19155 +
19156 +extern struct kmem_cache *au_cachep[];
19157 +
19158 +#define AuCacheFuncs(name, index) \
19159 +static inline struct au_##name *au_cache_alloc_##name(void) \
19160 +{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
19161 +static inline void au_cache_free_##name(struct au_##name *p) \
19162 +{ kmem_cache_free(au_cachep[AuCache_##index], p); }
19163 +
19164 +AuCacheFuncs(dinfo, DINFO);
19165 +AuCacheFuncs(icntnr, ICNTNR);
19166 +AuCacheFuncs(finfo, FINFO);
19167 +AuCacheFuncs(vdir, VDIR);
19168 +AuCacheFuncs(vdir_dehstr, DEHSTR);
19169 +#ifdef CONFIG_AUFS_HNOTIFY
19170 +AuCacheFuncs(hnotify, HNOTIFY);
19171 +#endif
19172 +
19173 +#endif /* __KERNEL__ */
19174 +#endif /* __AUFS_MODULE_H__ */
19175 diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
19176 --- /usr/share/empty/fs/aufs/opts.c     1970-01-01 01:00:00.000000000 +0100
19177 +++ linux/fs/aufs/opts.c        2013-01-11 19:46:12.639281345 +0100
19178 @@ -0,0 +1,1677 @@
19179 +/*
19180 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19181 + *
19182 + * This program, aufs is free software; you can redistribute it and/or modify
19183 + * it under the terms of the GNU General Public License as published by
19184 + * the Free Software Foundation; either version 2 of the License, or
19185 + * (at your option) any later version.
19186 + *
19187 + * This program is distributed in the hope that it will be useful,
19188 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19189 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19190 + * GNU General Public License for more details.
19191 + *
19192 + * You should have received a copy of the GNU General Public License
19193 + * along with this program; if not, write to the Free Software
19194 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19195 + */
19196 +
19197 +/*
19198 + * mount options/flags
19199 + */
19200 +
19201 +#include <linux/namei.h>
19202 +#include <linux/types.h> /* a distribution requires */
19203 +#include <linux/parser.h>
19204 +#include "aufs.h"
19205 +
19206 +/* ---------------------------------------------------------------------- */
19207 +
19208 +enum {
19209 +       Opt_br,
19210 +       Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
19211 +       Opt_idel, Opt_imod, Opt_ireorder,
19212 +       Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
19213 +       Opt_rdblk_def, Opt_rdhash_def,
19214 +       Opt_xino, Opt_zxino, Opt_noxino,
19215 +       Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
19216 +       Opt_trunc_xino_path, Opt_itrunc_xino,
19217 +       Opt_trunc_xib, Opt_notrunc_xib,
19218 +       Opt_shwh, Opt_noshwh,
19219 +       Opt_plink, Opt_noplink, Opt_list_plink,
19220 +       Opt_udba,
19221 +       Opt_dio, Opt_nodio,
19222 +       /* Opt_lock, Opt_unlock, */
19223 +       Opt_cmd, Opt_cmd_args,
19224 +       Opt_diropq_a, Opt_diropq_w,
19225 +       Opt_warn_perm, Opt_nowarn_perm,
19226 +       Opt_wbr_copyup, Opt_wbr_create,
19227 +       Opt_refrof, Opt_norefrof,
19228 +       Opt_verbose, Opt_noverbose,
19229 +       Opt_sum, Opt_nosum, Opt_wsum,
19230 +       Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
19231 +};
19232 +
19233 +static match_table_t options = {
19234 +       {Opt_br, "br=%s"},
19235 +       {Opt_br, "br:%s"},
19236 +
19237 +       {Opt_add, "add=%d:%s"},
19238 +       {Opt_add, "add:%d:%s"},
19239 +       {Opt_add, "ins=%d:%s"},
19240 +       {Opt_add, "ins:%d:%s"},
19241 +       {Opt_append, "append=%s"},
19242 +       {Opt_append, "append:%s"},
19243 +       {Opt_prepend, "prepend=%s"},
19244 +       {Opt_prepend, "prepend:%s"},
19245 +
19246 +       {Opt_del, "del=%s"},
19247 +       {Opt_del, "del:%s"},
19248 +       /* {Opt_idel, "idel:%d"}, */
19249 +       {Opt_mod, "mod=%s"},
19250 +       {Opt_mod, "mod:%s"},
19251 +       /* {Opt_imod, "imod:%d:%s"}, */
19252 +
19253 +       {Opt_dirwh, "dirwh=%d"},
19254 +
19255 +       {Opt_xino, "xino=%s"},
19256 +       {Opt_noxino, "noxino"},
19257 +       {Opt_trunc_xino, "trunc_xino"},
19258 +       {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
19259 +       {Opt_notrunc_xino, "notrunc_xino"},
19260 +       {Opt_trunc_xino_path, "trunc_xino=%s"},
19261 +       {Opt_itrunc_xino, "itrunc_xino=%d"},
19262 +       /* {Opt_zxino, "zxino=%s"}, */
19263 +       {Opt_trunc_xib, "trunc_xib"},
19264 +       {Opt_notrunc_xib, "notrunc_xib"},
19265 +
19266 +#ifdef CONFIG_PROC_FS
19267 +       {Opt_plink, "plink"},
19268 +#else
19269 +       {Opt_ignore_silent, "plink"},
19270 +#endif
19271 +
19272 +       {Opt_noplink, "noplink"},
19273 +
19274 +#ifdef CONFIG_AUFS_DEBUG
19275 +       {Opt_list_plink, "list_plink"},
19276 +#endif
19277 +
19278 +       {Opt_udba, "udba=%s"},
19279 +
19280 +       {Opt_dio, "dio"},
19281 +       {Opt_nodio, "nodio"},
19282 +
19283 +       {Opt_diropq_a, "diropq=always"},
19284 +       {Opt_diropq_a, "diropq=a"},
19285 +       {Opt_diropq_w, "diropq=whiteouted"},
19286 +       {Opt_diropq_w, "diropq=w"},
19287 +
19288 +       {Opt_warn_perm, "warn_perm"},
19289 +       {Opt_nowarn_perm, "nowarn_perm"},
19290 +
19291 +       /* keep them temporary */
19292 +       {Opt_ignore_silent, "coo=%s"},
19293 +       {Opt_ignore_silent, "nodlgt"},
19294 +       {Opt_ignore_silent, "nodirperm1"},
19295 +       {Opt_ignore_silent, "clean_plink"},
19296 +
19297 +#ifdef CONFIG_AUFS_SHWH
19298 +       {Opt_shwh, "shwh"},
19299 +#endif
19300 +       {Opt_noshwh, "noshwh"},
19301 +
19302 +       {Opt_rendir, "rendir=%d"},
19303 +
19304 +       {Opt_refrof, "refrof"},
19305 +       {Opt_norefrof, "norefrof"},
19306 +
19307 +       {Opt_verbose, "verbose"},
19308 +       {Opt_verbose, "v"},
19309 +       {Opt_noverbose, "noverbose"},
19310 +       {Opt_noverbose, "quiet"},
19311 +       {Opt_noverbose, "q"},
19312 +       {Opt_noverbose, "silent"},
19313 +
19314 +       {Opt_sum, "sum"},
19315 +       {Opt_nosum, "nosum"},
19316 +       {Opt_wsum, "wsum"},
19317 +
19318 +       {Opt_rdcache, "rdcache=%d"},
19319 +       {Opt_rdblk, "rdblk=%d"},
19320 +       {Opt_rdblk_def, "rdblk=def"},
19321 +       {Opt_rdhash, "rdhash=%d"},
19322 +       {Opt_rdhash_def, "rdhash=def"},
19323 +
19324 +       {Opt_wbr_create, "create=%s"},
19325 +       {Opt_wbr_create, "create_policy=%s"},
19326 +       {Opt_wbr_copyup, "cpup=%s"},
19327 +       {Opt_wbr_copyup, "copyup=%s"},
19328 +       {Opt_wbr_copyup, "copyup_policy=%s"},
19329 +
19330 +       /* internal use for the scripts */
19331 +       {Opt_ignore_silent, "si=%s"},
19332 +
19333 +       {Opt_br, "dirs=%s"},
19334 +       {Opt_ignore, "debug=%d"},
19335 +       {Opt_ignore, "delete=whiteout"},
19336 +       {Opt_ignore, "delete=all"},
19337 +       {Opt_ignore, "imap=%s"},
19338 +
19339 +       /* temporary workaround, due to old mount(8)? */
19340 +       {Opt_ignore_silent, "relatime"},
19341 +
19342 +       {Opt_err, NULL}
19343 +};
19344 +
19345 +/* ---------------------------------------------------------------------- */
19346 +
19347 +static const char *au_parser_pattern(int val, struct match_token *token)
19348 +{
19349 +       while (token->pattern) {
19350 +               if (token->token == val)
19351 +                       return token->pattern;
19352 +               token++;
19353 +       }
19354 +       BUG();
19355 +       return "??";
19356 +}
19357 +
19358 +/* ---------------------------------------------------------------------- */
19359 +
19360 +static match_table_t brperm = {
19361 +       {AuBrPerm_RO, AUFS_BRPERM_RO},
19362 +       {AuBrPerm_RR, AUFS_BRPERM_RR},
19363 +       {AuBrPerm_RW, AUFS_BRPERM_RW},
19364 +       {0, NULL}
19365 +};
19366 +
19367 +static match_table_t brrattr = {
19368 +       {AuBrRAttr_WH, AUFS_BRRATTR_WH},
19369 +       {0, NULL}
19370 +};
19371 +
19372 +static match_table_t brwattr = {
19373 +       {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
19374 +       {0, NULL}
19375 +};
19376 +
19377 +#define AuBrStr_LONGEST        AUFS_BRPERM_RW "+" AUFS_BRWATTR_NLWH
19378 +
19379 +static int br_attr_val(char *str, match_table_t table, substring_t args[])
19380 +{
19381 +       int attr, v;
19382 +       char *p;
19383 +
19384 +       attr = 0;
19385 +       do {
19386 +               p = strchr(str, '+');
19387 +               if (p)
19388 +                       *p = 0;
19389 +               v = match_token(str, table, args);
19390 +               if (v)
19391 +                       attr |= v;
19392 +               else {
19393 +                       if (p)
19394 +                               *p = '+';
19395 +                       pr_warn("ignored branch attribute %s\n", str);
19396 +                       break;
19397 +               }
19398 +               if (p)
19399 +                       str = p + 1;
19400 +       } while (p);
19401 +
19402 +       return attr;
19403 +}
19404 +
19405 +static int noinline_for_stack br_perm_val(char *perm)
19406 +{
19407 +       int val;
19408 +       char *p;
19409 +       substring_t args[MAX_OPT_ARGS];
19410 +
19411 +       p = strchr(perm, '+');
19412 +       if (p)
19413 +               *p = 0;
19414 +       val = match_token(perm, brperm, args);
19415 +       if (!val) {
19416 +               if (p)
19417 +                       *p = '+';
19418 +               pr_warn("ignored branch permission %s\n", perm);
19419 +               val = AuBrPerm_RO;
19420 +               goto out;
19421 +       }
19422 +       if (!p)
19423 +               goto out;
19424 +
19425 +       switch (val) {
19426 +       case AuBrPerm_RO:
19427 +       case AuBrPerm_RR:
19428 +               val |= br_attr_val(p + 1, brrattr, args);
19429 +               break;
19430 +       case AuBrPerm_RW:
19431 +               val |= br_attr_val(p + 1, brwattr, args);
19432 +               break;
19433 +       }
19434 +
19435 +out:
19436 +       return val;
19437 +}
19438 +
19439 +/* Caller should free the return value */
19440 +char *au_optstr_br_perm(int brperm)
19441 +{
19442 +       char *p, a[sizeof(AuBrStr_LONGEST)];
19443 +       int sz;
19444 +
19445 +#define SetPerm(str) do {                      \
19446 +               sz = sizeof(str);               \
19447 +               memcpy(a, str, sz);             \
19448 +               p = a + sz - 1;                 \
19449 +       } while (0)
19450 +
19451 +#define AppendAttr(flag, str) do {                     \
19452 +               if (brperm & flag) {            \
19453 +                       sz = sizeof(str);       \
19454 +                       *p++ = '+';             \
19455 +                       memcpy(p, str, sz);     \
19456 +                       p += sz - 1;            \
19457 +               }                               \
19458 +       } while (0)
19459 +
19460 +       switch (brperm & AuBrPerm_Mask) {
19461 +       case AuBrPerm_RO:
19462 +               SetPerm(AUFS_BRPERM_RO);
19463 +               break;
19464 +       case AuBrPerm_RR:
19465 +               SetPerm(AUFS_BRPERM_RR);
19466 +               break;
19467 +       case AuBrPerm_RW:
19468 +               SetPerm(AUFS_BRPERM_RW);
19469 +               break;
19470 +       default:
19471 +               AuDebugOn(1);
19472 +       }
19473 +
19474 +       AppendAttr(AuBrRAttr_WH, AUFS_BRRATTR_WH);
19475 +       AppendAttr(AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH);
19476 +
19477 +       AuDebugOn(strlen(a) >= sizeof(a));
19478 +       return kstrdup(a, GFP_NOFS);
19479 +#undef SetPerm
19480 +#undef AppendAttr
19481 +}
19482 +
19483 +/* ---------------------------------------------------------------------- */
19484 +
19485 +static match_table_t udbalevel = {
19486 +       {AuOpt_UDBA_REVAL, "reval"},
19487 +       {AuOpt_UDBA_NONE, "none"},
19488 +#ifdef CONFIG_AUFS_HNOTIFY
19489 +       {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
19490 +#ifdef CONFIG_AUFS_HFSNOTIFY
19491 +       {AuOpt_UDBA_HNOTIFY, "fsnotify"},
19492 +#endif
19493 +#endif
19494 +       {-1, NULL}
19495 +};
19496 +
19497 +static int noinline_for_stack udba_val(char *str)
19498 +{
19499 +       substring_t args[MAX_OPT_ARGS];
19500 +
19501 +       return match_token(str, udbalevel, args);
19502 +}
19503 +
19504 +const char *au_optstr_udba(int udba)
19505 +{
19506 +       return au_parser_pattern(udba, (void *)udbalevel);
19507 +}
19508 +
19509 +/* ---------------------------------------------------------------------- */
19510 +
19511 +static match_table_t au_wbr_create_policy = {
19512 +       {AuWbrCreate_TDP, "tdp"},
19513 +       {AuWbrCreate_TDP, "top-down-parent"},
19514 +       {AuWbrCreate_RR, "rr"},
19515 +       {AuWbrCreate_RR, "round-robin"},
19516 +       {AuWbrCreate_MFS, "mfs"},
19517 +       {AuWbrCreate_MFS, "most-free-space"},
19518 +       {AuWbrCreate_MFSV, "mfs:%d"},
19519 +       {AuWbrCreate_MFSV, "most-free-space:%d"},
19520 +
19521 +       {AuWbrCreate_MFSRR, "mfsrr:%d"},
19522 +       {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
19523 +       {AuWbrCreate_PMFS, "pmfs"},
19524 +       {AuWbrCreate_PMFSV, "pmfs:%d"},
19525 +
19526 +       {-1, NULL}
19527 +};
19528 +
19529 +/*
19530 + * cf. linux/lib/parser.c and cmdline.c
19531 + * gave up calling memparse() since it uses simple_strtoull() instead of
19532 + * kstrto...().
19533 + */
19534 +static int noinline_for_stack
19535 +au_match_ull(substring_t *s, unsigned long long *result)
19536 +{
19537 +       int err;
19538 +       unsigned int len;
19539 +       char a[32];
19540 +
19541 +       err = -ERANGE;
19542 +       len = s->to - s->from;
19543 +       if (len + 1 <= sizeof(a)) {
19544 +               memcpy(a, s->from, len);
19545 +               a[len] = '\0';
19546 +               err = kstrtoull(a, 0, result);
19547 +       }
19548 +       return err;
19549 +}
19550 +
19551 +static int au_wbr_mfs_wmark(substring_t *arg, char *str,
19552 +                           struct au_opt_wbr_create *create)
19553 +{
19554 +       int err;
19555 +       unsigned long long ull;
19556 +
19557 +       err = 0;
19558 +       if (!au_match_ull(arg, &ull))
19559 +               create->mfsrr_watermark = ull;
19560 +       else {
19561 +               pr_err("bad integer in %s\n", str);
19562 +               err = -EINVAL;
19563 +       }
19564 +
19565 +       return err;
19566 +}
19567 +
19568 +static int au_wbr_mfs_sec(substring_t *arg, char *str,
19569 +                         struct au_opt_wbr_create *create)
19570 +{
19571 +       int n, err;
19572 +
19573 +       err = 0;
19574 +       if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
19575 +               create->mfs_second = n;
19576 +       else {
19577 +               pr_err("bad integer in %s\n", str);
19578 +               err = -EINVAL;
19579 +       }
19580 +
19581 +       return err;
19582 +}
19583 +
19584 +static int noinline_for_stack
19585 +au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
19586 +{
19587 +       int err, e;
19588 +       substring_t args[MAX_OPT_ARGS];
19589 +
19590 +       err = match_token(str, au_wbr_create_policy, args);
19591 +       create->wbr_create = err;
19592 +       switch (err) {
19593 +       case AuWbrCreate_MFSRRV:
19594 +               e = au_wbr_mfs_wmark(&args[0], str, create);
19595 +               if (!e)
19596 +                       e = au_wbr_mfs_sec(&args[1], str, create);
19597 +               if (unlikely(e))
19598 +                       err = e;
19599 +               break;
19600 +       case AuWbrCreate_MFSRR:
19601 +               e = au_wbr_mfs_wmark(&args[0], str, create);
19602 +               if (unlikely(e)) {
19603 +                       err = e;
19604 +                       break;
19605 +               }
19606 +               /*FALLTHROUGH*/
19607 +       case AuWbrCreate_MFS:
19608 +       case AuWbrCreate_PMFS:
19609 +               create->mfs_second = AUFS_MFS_DEF_SEC;
19610 +               break;
19611 +       case AuWbrCreate_MFSV:
19612 +       case AuWbrCreate_PMFSV:
19613 +               e = au_wbr_mfs_sec(&args[0], str, create);
19614 +               if (unlikely(e))
19615 +                       err = e;
19616 +               break;
19617 +       }
19618 +
19619 +       return err;
19620 +}
19621 +
19622 +const char *au_optstr_wbr_create(int wbr_create)
19623 +{
19624 +       return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
19625 +}
19626 +
19627 +static match_table_t au_wbr_copyup_policy = {
19628 +       {AuWbrCopyup_TDP, "tdp"},
19629 +       {AuWbrCopyup_TDP, "top-down-parent"},
19630 +       {AuWbrCopyup_BUP, "bup"},
19631 +       {AuWbrCopyup_BUP, "bottom-up-parent"},
19632 +       {AuWbrCopyup_BU, "bu"},
19633 +       {AuWbrCopyup_BU, "bottom-up"},
19634 +       {-1, NULL}
19635 +};
19636 +
19637 +static int noinline_for_stack au_wbr_copyup_val(char *str)
19638 +{
19639 +       substring_t args[MAX_OPT_ARGS];
19640 +
19641 +       return match_token(str, au_wbr_copyup_policy, args);
19642 +}
19643 +
19644 +const char *au_optstr_wbr_copyup(int wbr_copyup)
19645 +{
19646 +       return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
19647 +}
19648 +
19649 +/* ---------------------------------------------------------------------- */
19650 +
19651 +static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
19652 +
19653 +static void dump_opts(struct au_opts *opts)
19654 +{
19655 +#ifdef CONFIG_AUFS_DEBUG
19656 +       /* reduce stack space */
19657 +       union {
19658 +               struct au_opt_add *add;
19659 +               struct au_opt_del *del;
19660 +               struct au_opt_mod *mod;
19661 +               struct au_opt_xino *xino;
19662 +               struct au_opt_xino_itrunc *xino_itrunc;
19663 +               struct au_opt_wbr_create *create;
19664 +       } u;
19665 +       struct au_opt *opt;
19666 +
19667 +       opt = opts->opt;
19668 +       while (opt->type != Opt_tail) {
19669 +               switch (opt->type) {
19670 +               case Opt_add:
19671 +                       u.add = &opt->add;
19672 +                       AuDbg("add {b%d, %s, 0x%x, %p}\n",
19673 +                                 u.add->bindex, u.add->pathname, u.add->perm,
19674 +                                 u.add->path.dentry);
19675 +                       break;
19676 +               case Opt_del:
19677 +               case Opt_idel:
19678 +                       u.del = &opt->del;
19679 +                       AuDbg("del {%s, %p}\n",
19680 +                             u.del->pathname, u.del->h_path.dentry);
19681 +                       break;
19682 +               case Opt_mod:
19683 +               case Opt_imod:
19684 +                       u.mod = &opt->mod;
19685 +                       AuDbg("mod {%s, 0x%x, %p}\n",
19686 +                                 u.mod->path, u.mod->perm, u.mod->h_root);
19687 +                       break;
19688 +               case Opt_append:
19689 +                       u.add = &opt->add;
19690 +                       AuDbg("append {b%d, %s, 0x%x, %p}\n",
19691 +                                 u.add->bindex, u.add->pathname, u.add->perm,
19692 +                                 u.add->path.dentry);
19693 +                       break;
19694 +               case Opt_prepend:
19695 +                       u.add = &opt->add;
19696 +                       AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
19697 +                                 u.add->bindex, u.add->pathname, u.add->perm,
19698 +                                 u.add->path.dentry);
19699 +                       break;
19700 +               case Opt_dirwh:
19701 +                       AuDbg("dirwh %d\n", opt->dirwh);
19702 +                       break;
19703 +               case Opt_rdcache:
19704 +                       AuDbg("rdcache %d\n", opt->rdcache);
19705 +                       break;
19706 +               case Opt_rdblk:
19707 +                       AuDbg("rdblk %u\n", opt->rdblk);
19708 +                       break;
19709 +               case Opt_rdblk_def:
19710 +                       AuDbg("rdblk_def\n");
19711 +                       break;
19712 +               case Opt_rdhash:
19713 +                       AuDbg("rdhash %u\n", opt->rdhash);
19714 +                       break;
19715 +               case Opt_rdhash_def:
19716 +                       AuDbg("rdhash_def\n");
19717 +                       break;
19718 +               case Opt_xino:
19719 +                       u.xino = &opt->xino;
19720 +                       AuDbg("xino {%s %.*s}\n",
19721 +                                 u.xino->path,
19722 +                                 AuDLNPair(u.xino->file->f_dentry));
19723 +                       break;
19724 +               case Opt_trunc_xino:
19725 +                       AuLabel(trunc_xino);
19726 +                       break;
19727 +               case Opt_notrunc_xino:
19728 +                       AuLabel(notrunc_xino);
19729 +                       break;
19730 +               case Opt_trunc_xino_path:
19731 +               case Opt_itrunc_xino:
19732 +                       u.xino_itrunc = &opt->xino_itrunc;
19733 +                       AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
19734 +                       break;
19735 +
19736 +               case Opt_noxino:
19737 +                       AuLabel(noxino);
19738 +                       break;
19739 +               case Opt_trunc_xib:
19740 +                       AuLabel(trunc_xib);
19741 +                       break;
19742 +               case Opt_notrunc_xib:
19743 +                       AuLabel(notrunc_xib);
19744 +                       break;
19745 +               case Opt_shwh:
19746 +                       AuLabel(shwh);
19747 +                       break;
19748 +               case Opt_noshwh:
19749 +                       AuLabel(noshwh);
19750 +                       break;
19751 +               case Opt_plink:
19752 +                       AuLabel(plink);
19753 +                       break;
19754 +               case Opt_noplink:
19755 +                       AuLabel(noplink);
19756 +                       break;
19757 +               case Opt_list_plink:
19758 +                       AuLabel(list_plink);
19759 +                       break;
19760 +               case Opt_udba:
19761 +                       AuDbg("udba %d, %s\n",
19762 +                                 opt->udba, au_optstr_udba(opt->udba));
19763 +                       break;
19764 +               case Opt_dio:
19765 +                       AuLabel(dio);
19766 +                       break;
19767 +               case Opt_nodio:
19768 +                       AuLabel(nodio);
19769 +                       break;
19770 +               case Opt_diropq_a:
19771 +                       AuLabel(diropq_a);
19772 +                       break;
19773 +               case Opt_diropq_w:
19774 +                       AuLabel(diropq_w);
19775 +                       break;
19776 +               case Opt_warn_perm:
19777 +                       AuLabel(warn_perm);
19778 +                       break;
19779 +               case Opt_nowarn_perm:
19780 +                       AuLabel(nowarn_perm);
19781 +                       break;
19782 +               case Opt_refrof:
19783 +                       AuLabel(refrof);
19784 +                       break;
19785 +               case Opt_norefrof:
19786 +                       AuLabel(norefrof);
19787 +                       break;
19788 +               case Opt_verbose:
19789 +                       AuLabel(verbose);
19790 +                       break;
19791 +               case Opt_noverbose:
19792 +                       AuLabel(noverbose);
19793 +                       break;
19794 +               case Opt_sum:
19795 +                       AuLabel(sum);
19796 +                       break;
19797 +               case Opt_nosum:
19798 +                       AuLabel(nosum);
19799 +                       break;
19800 +               case Opt_wsum:
19801 +                       AuLabel(wsum);
19802 +                       break;
19803 +               case Opt_wbr_create:
19804 +                       u.create = &opt->wbr_create;
19805 +                       AuDbg("create %d, %s\n", u.create->wbr_create,
19806 +                                 au_optstr_wbr_create(u.create->wbr_create));
19807 +                       switch (u.create->wbr_create) {
19808 +                       case AuWbrCreate_MFSV:
19809 +                       case AuWbrCreate_PMFSV:
19810 +                               AuDbg("%d sec\n", u.create->mfs_second);
19811 +                               break;
19812 +                       case AuWbrCreate_MFSRR:
19813 +                               AuDbg("%llu watermark\n",
19814 +                                         u.create->mfsrr_watermark);
19815 +                               break;
19816 +                       case AuWbrCreate_MFSRRV:
19817 +                               AuDbg("%llu watermark, %d sec\n",
19818 +                                         u.create->mfsrr_watermark,
19819 +                                         u.create->mfs_second);
19820 +                               break;
19821 +                       }
19822 +                       break;
19823 +               case Opt_wbr_copyup:
19824 +                       AuDbg("copyup %d, %s\n", opt->wbr_copyup,
19825 +                                 au_optstr_wbr_copyup(opt->wbr_copyup));
19826 +                       break;
19827 +               default:
19828 +                       BUG();
19829 +               }
19830 +               opt++;
19831 +       }
19832 +#endif
19833 +}
19834 +
19835 +void au_opts_free(struct au_opts *opts)
19836 +{
19837 +       struct au_opt *opt;
19838 +
19839 +       opt = opts->opt;
19840 +       while (opt->type != Opt_tail) {
19841 +               switch (opt->type) {
19842 +               case Opt_add:
19843 +               case Opt_append:
19844 +               case Opt_prepend:
19845 +                       path_put(&opt->add.path);
19846 +                       break;
19847 +               case Opt_del:
19848 +               case Opt_idel:
19849 +                       path_put(&opt->del.h_path);
19850 +                       break;
19851 +               case Opt_mod:
19852 +               case Opt_imod:
19853 +                       dput(opt->mod.h_root);
19854 +                       break;
19855 +               case Opt_xino:
19856 +                       fput(opt->xino.file);
19857 +                       break;
19858 +               }
19859 +               opt++;
19860 +       }
19861 +}
19862 +
19863 +static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
19864 +                  aufs_bindex_t bindex)
19865 +{
19866 +       int err;
19867 +       struct au_opt_add *add = &opt->add;
19868 +       char *p;
19869 +
19870 +       add->bindex = bindex;
19871 +       add->perm = AuBrPerm_RO;
19872 +       add->pathname = opt_str;
19873 +       p = strchr(opt_str, '=');
19874 +       if (p) {
19875 +               *p++ = 0;
19876 +               if (*p)
19877 +                       add->perm = br_perm_val(p);
19878 +       }
19879 +
19880 +       err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
19881 +       if (!err) {
19882 +               if (!p) {
19883 +                       add->perm = AuBrPerm_RO;
19884 +                       if (au_test_fs_rr(add->path.dentry->d_sb))
19885 +                               add->perm = AuBrPerm_RR;
19886 +                       else if (!bindex && !(sb_flags & MS_RDONLY))
19887 +                               add->perm = AuBrPerm_RW;
19888 +               }
19889 +               opt->type = Opt_add;
19890 +               goto out;
19891 +       }
19892 +       pr_err("lookup failed %s (%d)\n", add->pathname, err);
19893 +       err = -EINVAL;
19894 +
19895 +out:
19896 +       return err;
19897 +}
19898 +
19899 +static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
19900 +{
19901 +       int err;
19902 +
19903 +       del->pathname = args[0].from;
19904 +       AuDbg("del path %s\n", del->pathname);
19905 +
19906 +       err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
19907 +       if (unlikely(err))
19908 +               pr_err("lookup failed %s (%d)\n", del->pathname, err);
19909 +
19910 +       return err;
19911 +}
19912 +
19913 +#if 0 /* reserved for future use */
19914 +static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
19915 +                             struct au_opt_del *del, substring_t args[])
19916 +{
19917 +       int err;
19918 +       struct dentry *root;
19919 +
19920 +       err = -EINVAL;
19921 +       root = sb->s_root;
19922 +       aufs_read_lock(root, AuLock_FLUSH);
19923 +       if (bindex < 0 || au_sbend(sb) < bindex) {
19924 +               pr_err("out of bounds, %d\n", bindex);
19925 +               goto out;
19926 +       }
19927 +
19928 +       err = 0;
19929 +       del->h_path.dentry = dget(au_h_dptr(root, bindex));
19930 +       del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
19931 +
19932 +out:
19933 +       aufs_read_unlock(root, !AuLock_IR);
19934 +       return err;
19935 +}
19936 +#endif
19937 +
19938 +static int noinline_for_stack
19939 +au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
19940 +{
19941 +       int err;
19942 +       struct path path;
19943 +       char *p;
19944 +
19945 +       err = -EINVAL;
19946 +       mod->path = args[0].from;
19947 +       p = strchr(mod->path, '=');
19948 +       if (unlikely(!p)) {
19949 +               pr_err("no permssion %s\n", args[0].from);
19950 +               goto out;
19951 +       }
19952 +
19953 +       *p++ = 0;
19954 +       err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
19955 +       if (unlikely(err)) {
19956 +               pr_err("lookup failed %s (%d)\n", mod->path, err);
19957 +               goto out;
19958 +       }
19959 +
19960 +       mod->perm = br_perm_val(p);
19961 +       AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
19962 +       mod->h_root = dget(path.dentry);
19963 +       path_put(&path);
19964 +
19965 +out:
19966 +       return err;
19967 +}
19968 +
19969 +#if 0 /* reserved for future use */
19970 +static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
19971 +                             struct au_opt_mod *mod, substring_t args[])
19972 +{
19973 +       int err;
19974 +       struct dentry *root;
19975 +
19976 +       err = -EINVAL;
19977 +       root = sb->s_root;
19978 +       aufs_read_lock(root, AuLock_FLUSH);
19979 +       if (bindex < 0 || au_sbend(sb) < bindex) {
19980 +               pr_err("out of bounds, %d\n", bindex);
19981 +               goto out;
19982 +       }
19983 +
19984 +       err = 0;
19985 +       mod->perm = br_perm_val(args[1].from);
19986 +       AuDbg("mod path %s, perm 0x%x, %s\n",
19987 +             mod->path, mod->perm, args[1].from);
19988 +       mod->h_root = dget(au_h_dptr(root, bindex));
19989 +
19990 +out:
19991 +       aufs_read_unlock(root, !AuLock_IR);
19992 +       return err;
19993 +}
19994 +#endif
19995 +
19996 +static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
19997 +                             substring_t args[])
19998 +{
19999 +       int err;
20000 +       struct file *file;
20001 +
20002 +       file = au_xino_create(sb, args[0].from, /*silent*/0);
20003 +       err = PTR_ERR(file);
20004 +       if (IS_ERR(file))
20005 +               goto out;
20006 +
20007 +       err = -EINVAL;
20008 +       if (unlikely(file->f_dentry->d_sb == sb)) {
20009 +               fput(file);
20010 +               pr_err("%s must be outside\n", args[0].from);
20011 +               goto out;
20012 +       }
20013 +
20014 +       err = 0;
20015 +       xino->file = file;
20016 +       xino->path = args[0].from;
20017 +
20018 +out:
20019 +       return err;
20020 +}
20021 +
20022 +static int noinline_for_stack
20023 +au_opts_parse_xino_itrunc_path(struct super_block *sb,
20024 +                              struct au_opt_xino_itrunc *xino_itrunc,
20025 +                              substring_t args[])
20026 +{
20027 +       int err;
20028 +       aufs_bindex_t bend, bindex;
20029 +       struct path path;
20030 +       struct dentry *root;
20031 +
20032 +       err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
20033 +       if (unlikely(err)) {
20034 +               pr_err("lookup failed %s (%d)\n", args[0].from, err);
20035 +               goto out;
20036 +       }
20037 +
20038 +       xino_itrunc->bindex = -1;
20039 +       root = sb->s_root;
20040 +       aufs_read_lock(root, AuLock_FLUSH);
20041 +       bend = au_sbend(sb);
20042 +       for (bindex = 0; bindex <= bend; bindex++) {
20043 +               if (au_h_dptr(root, bindex) == path.dentry) {
20044 +                       xino_itrunc->bindex = bindex;
20045 +                       break;
20046 +               }
20047 +       }
20048 +       aufs_read_unlock(root, !AuLock_IR);
20049 +       path_put(&path);
20050 +
20051 +       if (unlikely(xino_itrunc->bindex < 0)) {
20052 +               pr_err("no such branch %s\n", args[0].from);
20053 +               err = -EINVAL;
20054 +       }
20055 +
20056 +out:
20057 +       return err;
20058 +}
20059 +
20060 +/* called without aufs lock */
20061 +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
20062 +{
20063 +       int err, n, token;
20064 +       aufs_bindex_t bindex;
20065 +       unsigned char skipped;
20066 +       struct dentry *root;
20067 +       struct au_opt *opt, *opt_tail;
20068 +       char *opt_str;
20069 +       /* reduce the stack space */
20070 +       union {
20071 +               struct au_opt_xino_itrunc *xino_itrunc;
20072 +               struct au_opt_wbr_create *create;
20073 +       } u;
20074 +       struct {
20075 +               substring_t args[MAX_OPT_ARGS];
20076 +       } *a;
20077 +
20078 +       err = -ENOMEM;
20079 +       a = kmalloc(sizeof(*a), GFP_NOFS);
20080 +       if (unlikely(!a))
20081 +               goto out;
20082 +
20083 +       root = sb->s_root;
20084 +       err = 0;
20085 +       bindex = 0;
20086 +       opt = opts->opt;
20087 +       opt_tail = opt + opts->max_opt - 1;
20088 +       opt->type = Opt_tail;
20089 +       while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
20090 +               err = -EINVAL;
20091 +               skipped = 0;
20092 +               token = match_token(opt_str, options, a->args);
20093 +               switch (token) {
20094 +               case Opt_br:
20095 +                       err = 0;
20096 +                       while (!err && (opt_str = strsep(&a->args[0].from, ":"))
20097 +                              && *opt_str) {
20098 +                               err = opt_add(opt, opt_str, opts->sb_flags,
20099 +                                             bindex++);
20100 +                               if (unlikely(!err && ++opt > opt_tail)) {
20101 +                                       err = -E2BIG;
20102 +                                       break;
20103 +                               }
20104 +                               opt->type = Opt_tail;
20105 +                               skipped = 1;
20106 +                       }
20107 +                       break;
20108 +               case Opt_add:
20109 +                       if (unlikely(match_int(&a->args[0], &n))) {
20110 +                               pr_err("bad integer in %s\n", opt_str);
20111 +                               break;
20112 +                       }
20113 +                       bindex = n;
20114 +                       err = opt_add(opt, a->args[1].from, opts->sb_flags,
20115 +                                     bindex);
20116 +                       if (!err)
20117 +                               opt->type = token;
20118 +                       break;
20119 +               case Opt_append:
20120 +                       err = opt_add(opt, a->args[0].from, opts->sb_flags,
20121 +                                     /*dummy bindex*/1);
20122 +                       if (!err)
20123 +                               opt->type = token;
20124 +                       break;
20125 +               case Opt_prepend:
20126 +                       err = opt_add(opt, a->args[0].from, opts->sb_flags,
20127 +                                     /*bindex*/0);
20128 +                       if (!err)
20129 +                               opt->type = token;
20130 +                       break;
20131 +               case Opt_del:
20132 +                       err = au_opts_parse_del(&opt->del, a->args);
20133 +                       if (!err)
20134 +                               opt->type = token;
20135 +                       break;
20136 +#if 0 /* reserved for future use */
20137 +               case Opt_idel:
20138 +                       del->pathname = "(indexed)";
20139 +                       if (unlikely(match_int(&args[0], &n))) {
20140 +                               pr_err("bad integer in %s\n", opt_str);
20141 +                               break;
20142 +                       }
20143 +                       err = au_opts_parse_idel(sb, n, &opt->del, a->args);
20144 +                       if (!err)
20145 +                               opt->type = token;
20146 +                       break;
20147 +#endif
20148 +               case Opt_mod:
20149 +                       err = au_opts_parse_mod(&opt->mod, a->args);
20150 +                       if (!err)
20151 +                               opt->type = token;
20152 +                       break;
20153 +#ifdef IMOD /* reserved for future use */
20154 +               case Opt_imod:
20155 +                       u.mod->path = "(indexed)";
20156 +                       if (unlikely(match_int(&a->args[0], &n))) {
20157 +                               pr_err("bad integer in %s\n", opt_str);
20158 +                               break;
20159 +                       }
20160 +                       err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
20161 +                       if (!err)
20162 +                               opt->type = token;
20163 +                       break;
20164 +#endif
20165 +               case Opt_xino:
20166 +                       err = au_opts_parse_xino(sb, &opt->xino, a->args);
20167 +                       if (!err)
20168 +                               opt->type = token;
20169 +                       break;
20170 +
20171 +               case Opt_trunc_xino_path:
20172 +                       err = au_opts_parse_xino_itrunc_path
20173 +                               (sb, &opt->xino_itrunc, a->args);
20174 +                       if (!err)
20175 +                               opt->type = token;
20176 +                       break;
20177 +
20178 +               case Opt_itrunc_xino:
20179 +                       u.xino_itrunc = &opt->xino_itrunc;
20180 +                       if (unlikely(match_int(&a->args[0], &n))) {
20181 +                               pr_err("bad integer in %s\n", opt_str);
20182 +                               break;
20183 +                       }
20184 +                       u.xino_itrunc->bindex = n;
20185 +                       aufs_read_lock(root, AuLock_FLUSH);
20186 +                       if (n < 0 || au_sbend(sb) < n) {
20187 +                               pr_err("out of bounds, %d\n", n);
20188 +                               aufs_read_unlock(root, !AuLock_IR);
20189 +                               break;
20190 +                       }
20191 +                       aufs_read_unlock(root, !AuLock_IR);
20192 +                       err = 0;
20193 +                       opt->type = token;
20194 +                       break;
20195 +
20196 +               case Opt_dirwh:
20197 +                       if (unlikely(match_int(&a->args[0], &opt->dirwh)))
20198 +                               break;
20199 +                       err = 0;
20200 +                       opt->type = token;
20201 +                       break;
20202 +
20203 +               case Opt_rdcache:
20204 +                       if (unlikely(match_int(&a->args[0], &n))) {
20205 +                               pr_err("bad integer in %s\n", opt_str);
20206 +                               break;
20207 +                       }
20208 +                       if (unlikely(n > AUFS_RDCACHE_MAX)) {
20209 +                               pr_err("rdcache must be smaller than %d\n",
20210 +                                      AUFS_RDCACHE_MAX);
20211 +                               break;
20212 +                       }
20213 +                       opt->rdcache = n;
20214 +                       err = 0;
20215 +                       opt->type = token;
20216 +                       break;
20217 +               case Opt_rdblk:
20218 +                       if (unlikely(match_int(&a->args[0], &n)
20219 +                                    || n < 0
20220 +                                    || n > KMALLOC_MAX_SIZE)) {
20221 +                               pr_err("bad integer in %s\n", opt_str);
20222 +                               break;
20223 +                       }
20224 +                       if (unlikely(n && n < NAME_MAX)) {
20225 +                               pr_err("rdblk must be larger than %d\n",
20226 +                                      NAME_MAX);
20227 +                               break;
20228 +                       }
20229 +                       opt->rdblk = n;
20230 +                       err = 0;
20231 +                       opt->type = token;
20232 +                       break;
20233 +               case Opt_rdhash:
20234 +                       if (unlikely(match_int(&a->args[0], &n)
20235 +                                    || n < 0
20236 +                                    || n * sizeof(struct hlist_head)
20237 +                                    > KMALLOC_MAX_SIZE)) {
20238 +                               pr_err("bad integer in %s\n", opt_str);
20239 +                               break;
20240 +                       }
20241 +                       opt->rdhash = n;
20242 +                       err = 0;
20243 +                       opt->type = token;
20244 +                       break;
20245 +
20246 +               case Opt_trunc_xino:
20247 +               case Opt_notrunc_xino:
20248 +               case Opt_noxino:
20249 +               case Opt_trunc_xib:
20250 +               case Opt_notrunc_xib:
20251 +               case Opt_shwh:
20252 +               case Opt_noshwh:
20253 +               case Opt_plink:
20254 +               case Opt_noplink:
20255 +               case Opt_list_plink:
20256 +               case Opt_dio:
20257 +               case Opt_nodio:
20258 +               case Opt_diropq_a:
20259 +               case Opt_diropq_w:
20260 +               case Opt_warn_perm:
20261 +               case Opt_nowarn_perm:
20262 +               case Opt_refrof:
20263 +               case Opt_norefrof:
20264 +               case Opt_verbose:
20265 +               case Opt_noverbose:
20266 +               case Opt_sum:
20267 +               case Opt_nosum:
20268 +               case Opt_wsum:
20269 +               case Opt_rdblk_def:
20270 +               case Opt_rdhash_def:
20271 +                       err = 0;
20272 +                       opt->type = token;
20273 +                       break;
20274 +
20275 +               case Opt_udba:
20276 +                       opt->udba = udba_val(a->args[0].from);
20277 +                       if (opt->udba >= 0) {
20278 +                               err = 0;
20279 +                               opt->type = token;
20280 +                       } else
20281 +                               pr_err("wrong value, %s\n", opt_str);
20282 +                       break;
20283 +
20284 +               case Opt_wbr_create:
20285 +                       u.create = &opt->wbr_create;
20286 +                       u.create->wbr_create
20287 +                               = au_wbr_create_val(a->args[0].from, u.create);
20288 +                       if (u.create->wbr_create >= 0) {
20289 +                               err = 0;
20290 +                               opt->type = token;
20291 +                       } else
20292 +                               pr_err("wrong value, %s\n", opt_str);
20293 +                       break;
20294 +               case Opt_wbr_copyup:
20295 +                       opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
20296 +                       if (opt->wbr_copyup >= 0) {
20297 +                               err = 0;
20298 +                               opt->type = token;
20299 +                       } else
20300 +                               pr_err("wrong value, %s\n", opt_str);
20301 +                       break;
20302 +
20303 +               case Opt_ignore:
20304 +                       pr_warn("ignored %s\n", opt_str);
20305 +                       /*FALLTHROUGH*/
20306 +               case Opt_ignore_silent:
20307 +                       skipped = 1;
20308 +                       err = 0;
20309 +                       break;
20310 +               case Opt_err:
20311 +                       pr_err("unknown option %s\n", opt_str);
20312 +                       break;
20313 +               }
20314 +
20315 +               if (!err && !skipped) {
20316 +                       if (unlikely(++opt > opt_tail)) {
20317 +                               err = -E2BIG;
20318 +                               opt--;
20319 +                               opt->type = Opt_tail;
20320 +                               break;
20321 +                       }
20322 +                       opt->type = Opt_tail;
20323 +               }
20324 +       }
20325 +
20326 +       kfree(a);
20327 +       dump_opts(opts);
20328 +       if (unlikely(err))
20329 +               au_opts_free(opts);
20330 +
20331 +out:
20332 +       return err;
20333 +}
20334 +
20335 +static int au_opt_wbr_create(struct super_block *sb,
20336 +                            struct au_opt_wbr_create *create)
20337 +{
20338 +       int err;
20339 +       struct au_sbinfo *sbinfo;
20340 +
20341 +       SiMustWriteLock(sb);
20342 +
20343 +       err = 1; /* handled */
20344 +       sbinfo = au_sbi(sb);
20345 +       if (sbinfo->si_wbr_create_ops->fin) {
20346 +               err = sbinfo->si_wbr_create_ops->fin(sb);
20347 +               if (!err)
20348 +                       err = 1;
20349 +       }
20350 +
20351 +       sbinfo->si_wbr_create = create->wbr_create;
20352 +       sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
20353 +       switch (create->wbr_create) {
20354 +       case AuWbrCreate_MFSRRV:
20355 +       case AuWbrCreate_MFSRR:
20356 +               sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
20357 +               /*FALLTHROUGH*/
20358 +       case AuWbrCreate_MFS:
20359 +       case AuWbrCreate_MFSV:
20360 +       case AuWbrCreate_PMFS:
20361 +       case AuWbrCreate_PMFSV:
20362 +               sbinfo->si_wbr_mfs.mfs_expire
20363 +                       = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
20364 +               break;
20365 +       }
20366 +
20367 +       if (sbinfo->si_wbr_create_ops->init)
20368 +               sbinfo->si_wbr_create_ops->init(sb); /* ignore */
20369 +
20370 +       return err;
20371 +}
20372 +
20373 +/*
20374 + * returns,
20375 + * plus: processed without an error
20376 + * zero: unprocessed
20377 + */
20378 +static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
20379 +                        struct au_opts *opts)
20380 +{
20381 +       int err;
20382 +       struct au_sbinfo *sbinfo;
20383 +
20384 +       SiMustWriteLock(sb);
20385 +
20386 +       err = 1; /* handled */
20387 +       sbinfo = au_sbi(sb);
20388 +       switch (opt->type) {
20389 +       case Opt_udba:
20390 +               sbinfo->si_mntflags &= ~AuOptMask_UDBA;
20391 +               sbinfo->si_mntflags |= opt->udba;
20392 +               opts->given_udba |= opt->udba;
20393 +               break;
20394 +
20395 +       case Opt_plink:
20396 +               au_opt_set(sbinfo->si_mntflags, PLINK);
20397 +               break;
20398 +       case Opt_noplink:
20399 +               if (au_opt_test(sbinfo->si_mntflags, PLINK))
20400 +                       au_plink_put(sb, /*verbose*/1);
20401 +               au_opt_clr(sbinfo->si_mntflags, PLINK);
20402 +               break;
20403 +       case Opt_list_plink:
20404 +               if (au_opt_test(sbinfo->si_mntflags, PLINK))
20405 +                       au_plink_list(sb);
20406 +               break;
20407 +
20408 +       case Opt_dio:
20409 +               au_opt_set(sbinfo->si_mntflags, DIO);
20410 +               au_fset_opts(opts->flags, REFRESH_DYAOP);
20411 +               break;
20412 +       case Opt_nodio:
20413 +               au_opt_clr(sbinfo->si_mntflags, DIO);
20414 +               au_fset_opts(opts->flags, REFRESH_DYAOP);
20415 +               break;
20416 +
20417 +       case Opt_diropq_a:
20418 +               au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
20419 +               break;
20420 +       case Opt_diropq_w:
20421 +               au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
20422 +               break;
20423 +
20424 +       case Opt_warn_perm:
20425 +               au_opt_set(sbinfo->si_mntflags, WARN_PERM);
20426 +               break;
20427 +       case Opt_nowarn_perm:
20428 +               au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
20429 +               break;
20430 +
20431 +       case Opt_refrof:
20432 +               au_opt_set(sbinfo->si_mntflags, REFROF);
20433 +               break;
20434 +       case Opt_norefrof:
20435 +               au_opt_clr(sbinfo->si_mntflags, REFROF);
20436 +               break;
20437 +
20438 +       case Opt_verbose:
20439 +               au_opt_set(sbinfo->si_mntflags, VERBOSE);
20440 +               break;
20441 +       case Opt_noverbose:
20442 +               au_opt_clr(sbinfo->si_mntflags, VERBOSE);
20443 +               break;
20444 +
20445 +       case Opt_sum:
20446 +               au_opt_set(sbinfo->si_mntflags, SUM);
20447 +               break;
20448 +       case Opt_wsum:
20449 +               au_opt_clr(sbinfo->si_mntflags, SUM);
20450 +               au_opt_set(sbinfo->si_mntflags, SUM_W);
20451 +       case Opt_nosum:
20452 +               au_opt_clr(sbinfo->si_mntflags, SUM);
20453 +               au_opt_clr(sbinfo->si_mntflags, SUM_W);
20454 +               break;
20455 +
20456 +       case Opt_wbr_create:
20457 +               err = au_opt_wbr_create(sb, &opt->wbr_create);
20458 +               break;
20459 +       case Opt_wbr_copyup:
20460 +               sbinfo->si_wbr_copyup = opt->wbr_copyup;
20461 +               sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
20462 +               break;
20463 +
20464 +       case Opt_dirwh:
20465 +               sbinfo->si_dirwh = opt->dirwh;
20466 +               break;
20467 +
20468 +       case Opt_rdcache:
20469 +               sbinfo->si_rdcache
20470 +                       = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
20471 +               break;
20472 +       case Opt_rdblk:
20473 +               sbinfo->si_rdblk = opt->rdblk;
20474 +               break;
20475 +       case Opt_rdblk_def:
20476 +               sbinfo->si_rdblk = AUFS_RDBLK_DEF;
20477 +               break;
20478 +       case Opt_rdhash:
20479 +               sbinfo->si_rdhash = opt->rdhash;
20480 +               break;
20481 +       case Opt_rdhash_def:
20482 +               sbinfo->si_rdhash = AUFS_RDHASH_DEF;
20483 +               break;
20484 +
20485 +       case Opt_shwh:
20486 +               au_opt_set(sbinfo->si_mntflags, SHWH);
20487 +               break;
20488 +       case Opt_noshwh:
20489 +               au_opt_clr(sbinfo->si_mntflags, SHWH);
20490 +               break;
20491 +
20492 +       case Opt_trunc_xino:
20493 +               au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
20494 +               break;
20495 +       case Opt_notrunc_xino:
20496 +               au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
20497 +               break;
20498 +
20499 +       case Opt_trunc_xino_path:
20500 +       case Opt_itrunc_xino:
20501 +               err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
20502 +               if (!err)
20503 +                       err = 1;
20504 +               break;
20505 +
20506 +       case Opt_trunc_xib:
20507 +               au_fset_opts(opts->flags, TRUNC_XIB);
20508 +               break;
20509 +       case Opt_notrunc_xib:
20510 +               au_fclr_opts(opts->flags, TRUNC_XIB);
20511 +               break;
20512 +
20513 +       default:
20514 +               err = 0;
20515 +               break;
20516 +       }
20517 +
20518 +       return err;
20519 +}
20520 +
20521 +/*
20522 + * returns tri-state.
20523 + * plus: processed without an error
20524 + * zero: unprocessed
20525 + * minus: error
20526 + */
20527 +static int au_opt_br(struct super_block *sb, struct au_opt *opt,
20528 +                    struct au_opts *opts)
20529 +{
20530 +       int err, do_refresh;
20531 +
20532 +       err = 0;
20533 +       switch (opt->type) {
20534 +       case Opt_append:
20535 +               opt->add.bindex = au_sbend(sb) + 1;
20536 +               if (opt->add.bindex < 0)
20537 +                       opt->add.bindex = 0;
20538 +               goto add;
20539 +       case Opt_prepend:
20540 +               opt->add.bindex = 0;
20541 +       add:
20542 +       case Opt_add:
20543 +               err = au_br_add(sb, &opt->add,
20544 +                               au_ftest_opts(opts->flags, REMOUNT));
20545 +               if (!err) {
20546 +                       err = 1;
20547 +                       au_fset_opts(opts->flags, REFRESH);
20548 +               }
20549 +               break;
20550 +
20551 +       case Opt_del:
20552 +       case Opt_idel:
20553 +               err = au_br_del(sb, &opt->del,
20554 +                               au_ftest_opts(opts->flags, REMOUNT));
20555 +               if (!err) {
20556 +                       err = 1;
20557 +                       au_fset_opts(opts->flags, TRUNC_XIB);
20558 +                       au_fset_opts(opts->flags, REFRESH);
20559 +               }
20560 +               break;
20561 +
20562 +       case Opt_mod:
20563 +       case Opt_imod:
20564 +               err = au_br_mod(sb, &opt->mod,
20565 +                               au_ftest_opts(opts->flags, REMOUNT),
20566 +                               &do_refresh);
20567 +               if (!err) {
20568 +                       err = 1;
20569 +                       if (do_refresh)
20570 +                               au_fset_opts(opts->flags, REFRESH);
20571 +               }
20572 +               break;
20573 +       }
20574 +
20575 +       return err;
20576 +}
20577 +
20578 +static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
20579 +                      struct au_opt_xino **opt_xino,
20580 +                      struct au_opts *opts)
20581 +{
20582 +       int err;
20583 +       aufs_bindex_t bend, bindex;
20584 +       struct dentry *root, *parent, *h_root;
20585 +
20586 +       err = 0;
20587 +       switch (opt->type) {
20588 +       case Opt_xino:
20589 +               err = au_xino_set(sb, &opt->xino,
20590 +                                 !!au_ftest_opts(opts->flags, REMOUNT));
20591 +               if (unlikely(err))
20592 +                       break;
20593 +
20594 +               *opt_xino = &opt->xino;
20595 +               au_xino_brid_set(sb, -1);
20596 +
20597 +               /* safe d_parent access */
20598 +               parent = opt->xino.file->f_dentry->d_parent;
20599 +               root = sb->s_root;
20600 +               bend = au_sbend(sb);
20601 +               for (bindex = 0; bindex <= bend; bindex++) {
20602 +                       h_root = au_h_dptr(root, bindex);
20603 +                       if (h_root == parent) {
20604 +                               au_xino_brid_set(sb, au_sbr_id(sb, bindex));
20605 +                               break;
20606 +                       }
20607 +               }
20608 +               break;
20609 +
20610 +       case Opt_noxino:
20611 +               au_xino_clr(sb);
20612 +               au_xino_brid_set(sb, -1);
20613 +               *opt_xino = (void *)-1;
20614 +               break;
20615 +       }
20616 +
20617 +       return err;
20618 +}
20619 +
20620 +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
20621 +                  unsigned int pending)
20622 +{
20623 +       int err;
20624 +       aufs_bindex_t bindex, bend;
20625 +       unsigned char do_plink, skip, do_free;
20626 +       struct au_branch *br;
20627 +       struct au_wbr *wbr;
20628 +       struct dentry *root;
20629 +       struct inode *dir, *h_dir;
20630 +       struct au_sbinfo *sbinfo;
20631 +       struct au_hinode *hdir;
20632 +
20633 +       SiMustAnyLock(sb);
20634 +
20635 +       sbinfo = au_sbi(sb);
20636 +       AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
20637 +
20638 +       if (!(sb_flags & MS_RDONLY)) {
20639 +               if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
20640 +                       pr_warn("first branch should be rw\n");
20641 +               if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
20642 +                       pr_warn("shwh should be used with ro\n");
20643 +       }
20644 +
20645 +       if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
20646 +           && !au_opt_test(sbinfo->si_mntflags, XINO))
20647 +               pr_warn("udba=*notify requires xino\n");
20648 +
20649 +       err = 0;
20650 +       root = sb->s_root;
20651 +       dir = root->d_inode;
20652 +       do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
20653 +       bend = au_sbend(sb);
20654 +       for (bindex = 0; !err && bindex <= bend; bindex++) {
20655 +               skip = 0;
20656 +               h_dir = au_h_iptr(dir, bindex);
20657 +               br = au_sbr(sb, bindex);
20658 +               do_free = 0;
20659 +
20660 +               wbr = br->br_wbr;
20661 +               if (wbr)
20662 +                       wbr_wh_read_lock(wbr);
20663 +
20664 +               if (!au_br_writable(br->br_perm)) {
20665 +                       do_free = !!wbr;
20666 +                       skip = (!wbr
20667 +                               || (!wbr->wbr_whbase
20668 +                                   && !wbr->wbr_plink
20669 +                                   && !wbr->wbr_orph));
20670 +               } else if (!au_br_wh_linkable(br->br_perm)) {
20671 +                       /* skip = (!br->br_whbase && !br->br_orph); */
20672 +                       skip = (!wbr || !wbr->wbr_whbase);
20673 +                       if (skip && wbr) {
20674 +                               if (do_plink)
20675 +                                       skip = !!wbr->wbr_plink;
20676 +                               else
20677 +                                       skip = !wbr->wbr_plink;
20678 +                       }
20679 +               } else {
20680 +                       /* skip = (br->br_whbase && br->br_ohph); */
20681 +                       skip = (wbr && wbr->wbr_whbase);
20682 +                       if (skip) {
20683 +                               if (do_plink)
20684 +                                       skip = !!wbr->wbr_plink;
20685 +                               else
20686 +                                       skip = !wbr->wbr_plink;
20687 +                       }
20688 +               }
20689 +               if (wbr)
20690 +                       wbr_wh_read_unlock(wbr);
20691 +
20692 +               if (skip)
20693 +                       continue;
20694 +
20695 +               hdir = au_hi(dir, bindex);
20696 +               au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
20697 +               if (wbr)
20698 +                       wbr_wh_write_lock(wbr);
20699 +               err = au_wh_init(au_h_dptr(root, bindex), br, sb);
20700 +               if (wbr)
20701 +                       wbr_wh_write_unlock(wbr);
20702 +               au_hn_imtx_unlock(hdir);
20703 +
20704 +               if (!err && do_free) {
20705 +                       kfree(wbr);
20706 +                       br->br_wbr = NULL;
20707 +               }
20708 +       }
20709 +
20710 +       return err;
20711 +}
20712 +
20713 +int au_opts_mount(struct super_block *sb, struct au_opts *opts)
20714 +{
20715 +       int err;
20716 +       unsigned int tmp;
20717 +       aufs_bindex_t bindex, bend;
20718 +       struct au_opt *opt;
20719 +       struct au_opt_xino *opt_xino, xino;
20720 +       struct au_sbinfo *sbinfo;
20721 +       struct au_branch *br;
20722 +
20723 +       SiMustWriteLock(sb);
20724 +
20725 +       err = 0;
20726 +       opt_xino = NULL;
20727 +       opt = opts->opt;
20728 +       while (err >= 0 && opt->type != Opt_tail)
20729 +               err = au_opt_simple(sb, opt++, opts);
20730 +       if (err > 0)
20731 +               err = 0;
20732 +       else if (unlikely(err < 0))
20733 +               goto out;
20734 +
20735 +       /* disable xino and udba temporary */
20736 +       sbinfo = au_sbi(sb);
20737 +       tmp = sbinfo->si_mntflags;
20738 +       au_opt_clr(sbinfo->si_mntflags, XINO);
20739 +       au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
20740 +
20741 +       opt = opts->opt;
20742 +       while (err >= 0 && opt->type != Opt_tail)
20743 +               err = au_opt_br(sb, opt++, opts);
20744 +       if (err > 0)
20745 +               err = 0;
20746 +       else if (unlikely(err < 0))
20747 +               goto out;
20748 +
20749 +       bend = au_sbend(sb);
20750 +       if (unlikely(bend < 0)) {
20751 +               err = -EINVAL;
20752 +               pr_err("no branches\n");
20753 +               goto out;
20754 +       }
20755 +
20756 +       if (au_opt_test(tmp, XINO))
20757 +               au_opt_set(sbinfo->si_mntflags, XINO);
20758 +       opt = opts->opt;
20759 +       while (!err && opt->type != Opt_tail)
20760 +               err = au_opt_xino(sb, opt++, &opt_xino, opts);
20761 +       if (unlikely(err))
20762 +               goto out;
20763 +
20764 +       err = au_opts_verify(sb, sb->s_flags, tmp);
20765 +       if (unlikely(err))
20766 +               goto out;
20767 +
20768 +       /* restore xino */
20769 +       if (au_opt_test(tmp, XINO) && !opt_xino) {
20770 +               xino.file = au_xino_def(sb);
20771 +               err = PTR_ERR(xino.file);
20772 +               if (IS_ERR(xino.file))
20773 +                       goto out;
20774 +
20775 +               err = au_xino_set(sb, &xino, /*remount*/0);
20776 +               fput(xino.file);
20777 +               if (unlikely(err))
20778 +                       goto out;
20779 +       }
20780 +
20781 +       /* restore udba */
20782 +       tmp &= AuOptMask_UDBA;
20783 +       sbinfo->si_mntflags &= ~AuOptMask_UDBA;
20784 +       sbinfo->si_mntflags |= tmp;
20785 +       bend = au_sbend(sb);
20786 +       for (bindex = 0; bindex <= bend; bindex++) {
20787 +               br = au_sbr(sb, bindex);
20788 +               err = au_hnotify_reset_br(tmp, br, br->br_perm);
20789 +               if (unlikely(err))
20790 +                       AuIOErr("hnotify failed on br %d, %d, ignored\n",
20791 +                               bindex, err);
20792 +               /* go on even if err */
20793 +       }
20794 +       if (au_opt_test(tmp, UDBA_HNOTIFY)) {
20795 +               struct inode *dir = sb->s_root->d_inode;
20796 +               au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
20797 +       }
20798 +
20799 +out:
20800 +       return err;
20801 +}
20802 +
20803 +int au_opts_remount(struct super_block *sb, struct au_opts *opts)
20804 +{
20805 +       int err, rerr;
20806 +       struct inode *dir;
20807 +       struct au_opt_xino *opt_xino;
20808 +       struct au_opt *opt;
20809 +       struct au_sbinfo *sbinfo;
20810 +
20811 +       SiMustWriteLock(sb);
20812 +
20813 +       dir = sb->s_root->d_inode;
20814 +       sbinfo = au_sbi(sb);
20815 +       err = 0;
20816 +       opt_xino = NULL;
20817 +       opt = opts->opt;
20818 +       while (err >= 0 && opt->type != Opt_tail) {
20819 +               err = au_opt_simple(sb, opt, opts);
20820 +               if (!err)
20821 +                       err = au_opt_br(sb, opt, opts);
20822 +               if (!err)
20823 +                       err = au_opt_xino(sb, opt, &opt_xino, opts);
20824 +               opt++;
20825 +       }
20826 +       if (err > 0)
20827 +               err = 0;
20828 +       AuTraceErr(err);
20829 +       /* go on even err */
20830 +
20831 +       rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
20832 +       if (unlikely(rerr && !err))
20833 +               err = rerr;
20834 +
20835 +       if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
20836 +               rerr = au_xib_trunc(sb);
20837 +               if (unlikely(rerr && !err))
20838 +                       err = rerr;
20839 +       }
20840 +
20841 +       /* will be handled by the caller */
20842 +       if (!au_ftest_opts(opts->flags, REFRESH)
20843 +           && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
20844 +               au_fset_opts(opts->flags, REFRESH);
20845 +
20846 +       AuDbg("status 0x%x\n", opts->flags);
20847 +       return err;
20848 +}
20849 +
20850 +/* ---------------------------------------------------------------------- */
20851 +
20852 +unsigned int au_opt_udba(struct super_block *sb)
20853 +{
20854 +       return au_mntflags(sb) & AuOptMask_UDBA;
20855 +}
20856 diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
20857 --- /usr/share/empty/fs/aufs/opts.h     1970-01-01 01:00:00.000000000 +0100
20858 +++ linux/fs/aufs/opts.h        2013-01-11 19:46:12.639281345 +0100
20859 @@ -0,0 +1,209 @@
20860 +/*
20861 + * Copyright (C) 2005-2013 Junjiro R. Okajima
20862 + *
20863 + * This program, aufs is free software; you can redistribute it and/or modify
20864 + * it under the terms of the GNU General Public License as published by
20865 + * the Free Software Foundation; either version 2 of the License, or
20866 + * (at your option) any later version.
20867 + *
20868 + * This program is distributed in the hope that it will be useful,
20869 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
20870 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20871 + * GNU General Public License for more details.
20872 + *
20873 + * You should have received a copy of the GNU General Public License
20874 + * along with this program; if not, write to the Free Software
20875 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20876 + */
20877 +
20878 +/*
20879 + * mount options/flags
20880 + */
20881 +
20882 +#ifndef __AUFS_OPTS_H__
20883 +#define __AUFS_OPTS_H__
20884 +
20885 +#ifdef __KERNEL__
20886 +
20887 +#include <linux/path.h>
20888 +
20889 +struct file;
20890 +struct super_block;
20891 +
20892 +/* ---------------------------------------------------------------------- */
20893 +
20894 +/* mount flags */
20895 +#define AuOpt_XINO             1               /* external inode number bitmap
20896 +                                                  and translation table */
20897 +#define AuOpt_TRUNC_XINO       (1 << 1)        /* truncate xino files */
20898 +#define AuOpt_UDBA_NONE                (1 << 2)        /* users direct branch access */
20899 +#define AuOpt_UDBA_REVAL       (1 << 3)
20900 +#define AuOpt_UDBA_HNOTIFY     (1 << 4)
20901 +#define AuOpt_SHWH             (1 << 5)        /* show whiteout */
20902 +#define AuOpt_PLINK            (1 << 6)        /* pseudo-link */
20903 +#define AuOpt_DIRPERM1         (1 << 7)        /* unimplemented */
20904 +#define AuOpt_REFROF           (1 << 8)        /* unimplemented */
20905 +#define AuOpt_ALWAYS_DIROPQ    (1 << 9)        /* policy to creating diropq */
20906 +#define AuOpt_SUM              (1 << 10)       /* summation for statfs(2) */
20907 +#define AuOpt_SUM_W            (1 << 11)       /* unimplemented */
20908 +#define AuOpt_WARN_PERM                (1 << 12)       /* warn when add-branch */
20909 +#define AuOpt_VERBOSE          (1 << 13)       /* busy inode when del-branch */
20910 +#define AuOpt_DIO              (1 << 14)       /* direct io */
20911 +
20912 +#ifndef CONFIG_AUFS_HNOTIFY
20913 +#undef AuOpt_UDBA_HNOTIFY
20914 +#define AuOpt_UDBA_HNOTIFY     0
20915 +#endif
20916 +#ifndef CONFIG_AUFS_SHWH
20917 +#undef AuOpt_SHWH
20918 +#define AuOpt_SHWH             0
20919 +#endif
20920 +
20921 +#define AuOpt_Def      (AuOpt_XINO \
20922 +                        | AuOpt_UDBA_REVAL \
20923 +                        | AuOpt_PLINK \
20924 +                        /* | AuOpt_DIRPERM1 */ \
20925 +                        | AuOpt_WARN_PERM)
20926 +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
20927 +                        | AuOpt_UDBA_REVAL \
20928 +                        | AuOpt_UDBA_HNOTIFY)
20929 +
20930 +#define au_opt_test(flags, name)       (flags & AuOpt_##name)
20931 +#define au_opt_set(flags, name) do { \
20932 +       BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
20933 +       ((flags) |= AuOpt_##name); \
20934 +} while (0)
20935 +#define au_opt_set_udba(flags, name) do { \
20936 +       (flags) &= ~AuOptMask_UDBA; \
20937 +       ((flags) |= AuOpt_##name); \
20938 +} while (0)
20939 +#define au_opt_clr(flags, name) do { \
20940 +       ((flags) &= ~AuOpt_##name); \
20941 +} while (0)
20942 +
20943 +static inline unsigned int au_opts_plink(unsigned int mntflags)
20944 +{
20945 +#ifdef CONFIG_PROC_FS
20946 +       return mntflags;
20947 +#else
20948 +       return mntflags & ~AuOpt_PLINK;
20949 +#endif
20950 +}
20951 +
20952 +/* ---------------------------------------------------------------------- */
20953 +
20954 +/* policies to select one among multiple writable branches */
20955 +enum {
20956 +       AuWbrCreate_TDP,        /* top down parent */
20957 +       AuWbrCreate_RR,         /* round robin */
20958 +       AuWbrCreate_MFS,        /* most free space */
20959 +       AuWbrCreate_MFSV,       /* mfs with seconds */
20960 +       AuWbrCreate_MFSRR,      /* mfs then rr */
20961 +       AuWbrCreate_MFSRRV,     /* mfs then rr with seconds */
20962 +       AuWbrCreate_PMFS,       /* parent and mfs */
20963 +       AuWbrCreate_PMFSV,      /* parent and mfs with seconds */
20964 +
20965 +       AuWbrCreate_Def = AuWbrCreate_TDP
20966 +};
20967 +
20968 +enum {
20969 +       AuWbrCopyup_TDP,        /* top down parent */
20970 +       AuWbrCopyup_BUP,        /* bottom up parent */
20971 +       AuWbrCopyup_BU,         /* bottom up */
20972 +
20973 +       AuWbrCopyup_Def = AuWbrCopyup_TDP
20974 +};
20975 +
20976 +/* ---------------------------------------------------------------------- */
20977 +
20978 +struct au_opt_add {
20979 +       aufs_bindex_t   bindex;
20980 +       char            *pathname;
20981 +       int             perm;
20982 +       struct path     path;
20983 +};
20984 +
20985 +struct au_opt_del {
20986 +       char            *pathname;
20987 +       struct path     h_path;
20988 +};
20989 +
20990 +struct au_opt_mod {
20991 +       char            *path;
20992 +       int             perm;
20993 +       struct dentry   *h_root;
20994 +};
20995 +
20996 +struct au_opt_xino {
20997 +       char            *path;
20998 +       struct file     *file;
20999 +};
21000 +
21001 +struct au_opt_xino_itrunc {
21002 +       aufs_bindex_t   bindex;
21003 +};
21004 +
21005 +struct au_opt_wbr_create {
21006 +       int                     wbr_create;
21007 +       int                     mfs_second;
21008 +       unsigned long long      mfsrr_watermark;
21009 +};
21010 +
21011 +struct au_opt {
21012 +       int type;
21013 +       union {
21014 +               struct au_opt_xino      xino;
21015 +               struct au_opt_xino_itrunc xino_itrunc;
21016 +               struct au_opt_add       add;
21017 +               struct au_opt_del       del;
21018 +               struct au_opt_mod       mod;
21019 +               int                     dirwh;
21020 +               int                     rdcache;
21021 +               unsigned int            rdblk;
21022 +               unsigned int            rdhash;
21023 +               int                     udba;
21024 +               struct au_opt_wbr_create wbr_create;
21025 +               int                     wbr_copyup;
21026 +       };
21027 +};
21028 +
21029 +/* opts flags */
21030 +#define AuOpts_REMOUNT         1
21031 +#define AuOpts_REFRESH         (1 << 1)
21032 +#define AuOpts_TRUNC_XIB       (1 << 2)
21033 +#define AuOpts_REFRESH_DYAOP   (1 << 3)
21034 +#define au_ftest_opts(flags, name)     ((flags) & AuOpts_##name)
21035 +#define au_fset_opts(flags, name) \
21036 +       do { (flags) |= AuOpts_##name; } while (0)
21037 +#define au_fclr_opts(flags, name) \
21038 +       do { (flags) &= ~AuOpts_##name; } while (0)
21039 +
21040 +struct au_opts {
21041 +       struct au_opt   *opt;
21042 +       int             max_opt;
21043 +
21044 +       unsigned int    given_udba;
21045 +       unsigned int    flags;
21046 +       unsigned long   sb_flags;
21047 +};
21048 +
21049 +/* ---------------------------------------------------------------------- */
21050 +
21051 +char *au_optstr_br_perm(int brperm);
21052 +const char *au_optstr_udba(int udba);
21053 +const char *au_optstr_wbr_copyup(int wbr_copyup);
21054 +const char *au_optstr_wbr_create(int wbr_create);
21055 +
21056 +void au_opts_free(struct au_opts *opts);
21057 +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
21058 +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
21059 +                  unsigned int pending);
21060 +int au_opts_mount(struct super_block *sb, struct au_opts *opts);
21061 +int au_opts_remount(struct super_block *sb, struct au_opts *opts);
21062 +
21063 +unsigned int au_opt_udba(struct super_block *sb);
21064 +
21065 +/* ---------------------------------------------------------------------- */
21066 +
21067 +#endif /* __KERNEL__ */
21068 +#endif /* __AUFS_OPTS_H__ */
21069 diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
21070 --- /usr/share/empty/fs/aufs/plink.c    1970-01-01 01:00:00.000000000 +0100
21071 +++ linux/fs/aufs/plink.c       2013-01-11 19:46:12.639281345 +0100
21072 @@ -0,0 +1,511 @@
21073 +/*
21074 + * Copyright (C) 2005-2013 Junjiro R. Okajima
21075 + *
21076 + * This program, aufs is free software; you can redistribute it and/or modify
21077 + * it under the terms of the GNU General Public License as published by
21078 + * the Free Software Foundation; either version 2 of the License, or
21079 + * (at your option) any later version.
21080 + *
21081 + * This program is distributed in the hope that it will be useful,
21082 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21083 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21084 + * GNU General Public License for more details.
21085 + *
21086 + * You should have received a copy of the GNU General Public License
21087 + * along with this program; if not, write to the Free Software
21088 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21089 + */
21090 +
21091 +/*
21092 + * pseudo-link
21093 + */
21094 +
21095 +#include "aufs.h"
21096 +
21097 +/*
21098 + * the pseudo-link maintenance mode.
21099 + * during a user process maintains the pseudo-links,
21100 + * prohibit adding a new plink and branch manipulation.
21101 + *
21102 + * Flags
21103 + * NOPLM:
21104 + *     For entry functions which will handle plink, and i_mutex is already held
21105 + *     in VFS.
21106 + *     They cannot wait and should return an error at once.
21107 + *     Callers has to check the error.
21108 + * NOPLMW:
21109 + *     For entry functions which will handle plink, but i_mutex is not held
21110 + *     in VFS.
21111 + *     They can wait the plink maintenance mode to finish.
21112 + *
21113 + * They behave like F_SETLK and F_SETLKW.
21114 + * If the caller never handle plink, then both flags are unnecessary.
21115 + */
21116 +
21117 +int au_plink_maint(struct super_block *sb, int flags)
21118 +{
21119 +       int err;
21120 +       pid_t pid, ppid;
21121 +       struct au_sbinfo *sbi;
21122 +
21123 +       SiMustAnyLock(sb);
21124 +
21125 +       err = 0;
21126 +       if (!au_opt_test(au_mntflags(sb), PLINK))
21127 +               goto out;
21128 +
21129 +       sbi = au_sbi(sb);
21130 +       pid = sbi->si_plink_maint_pid;
21131 +       if (!pid || pid == current->pid)
21132 +               goto out;
21133 +
21134 +       /* todo: it highly depends upon /sbin/mount.aufs */
21135 +       rcu_read_lock();
21136 +       ppid = task_pid_vnr(rcu_dereference(current->real_parent));
21137 +       rcu_read_unlock();
21138 +       if (pid == ppid)
21139 +               goto out;
21140 +
21141 +       if (au_ftest_lock(flags, NOPLMW)) {
21142 +               /* if there is no i_mutex lock in VFS, we don't need to wait */
21143 +               /* AuDebugOn(!lockdep_depth(current)); */
21144 +               while (sbi->si_plink_maint_pid) {
21145 +                       si_read_unlock(sb);
21146 +                       /* gave up wake_up_bit() */
21147 +                       wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
21148 +
21149 +                       if (au_ftest_lock(flags, FLUSH))
21150 +                               au_nwt_flush(&sbi->si_nowait);
21151 +                       si_noflush_read_lock(sb);
21152 +               }
21153 +       } else if (au_ftest_lock(flags, NOPLM)) {
21154 +               AuDbg("ppid %d, pid %d\n", ppid, pid);
21155 +               err = -EAGAIN;
21156 +       }
21157 +
21158 +out:
21159 +       return err;
21160 +}
21161 +
21162 +void au_plink_maint_leave(struct au_sbinfo *sbinfo)
21163 +{
21164 +       spin_lock(&sbinfo->si_plink_maint_lock);
21165 +       sbinfo->si_plink_maint_pid = 0;
21166 +       spin_unlock(&sbinfo->si_plink_maint_lock);
21167 +       wake_up_all(&sbinfo->si_plink_wq);
21168 +}
21169 +
21170 +int au_plink_maint_enter(struct super_block *sb)
21171 +{
21172 +       int err;
21173 +       struct au_sbinfo *sbinfo;
21174 +
21175 +       err = 0;
21176 +       sbinfo = au_sbi(sb);
21177 +       /* make sure i am the only one in this fs */
21178 +       si_write_lock(sb, AuLock_FLUSH);
21179 +       if (au_opt_test(au_mntflags(sb), PLINK)) {
21180 +               spin_lock(&sbinfo->si_plink_maint_lock);
21181 +               if (!sbinfo->si_plink_maint_pid)
21182 +                       sbinfo->si_plink_maint_pid = current->pid;
21183 +               else
21184 +                       err = -EBUSY;
21185 +               spin_unlock(&sbinfo->si_plink_maint_lock);
21186 +       }
21187 +       si_write_unlock(sb);
21188 +
21189 +       return err;
21190 +}
21191 +
21192 +/* ---------------------------------------------------------------------- */
21193 +
21194 +struct pseudo_link {
21195 +       union {
21196 +               struct list_head list;
21197 +               struct rcu_head rcu;
21198 +       };
21199 +       struct inode *inode;
21200 +};
21201 +
21202 +#ifdef CONFIG_AUFS_DEBUG
21203 +void au_plink_list(struct super_block *sb)
21204 +{
21205 +       struct au_sbinfo *sbinfo;
21206 +       struct list_head *plink_list;
21207 +       struct pseudo_link *plink;
21208 +
21209 +       SiMustAnyLock(sb);
21210 +
21211 +       sbinfo = au_sbi(sb);
21212 +       AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
21213 +       AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
21214 +
21215 +       plink_list = &sbinfo->si_plink.head;
21216 +       rcu_read_lock();
21217 +       list_for_each_entry_rcu(plink, plink_list, list)
21218 +               AuDbg("%lu\n", plink->inode->i_ino);
21219 +       rcu_read_unlock();
21220 +}
21221 +#endif
21222 +
21223 +/* is the inode pseudo-linked? */
21224 +int au_plink_test(struct inode *inode)
21225 +{
21226 +       int found;
21227 +       struct au_sbinfo *sbinfo;
21228 +       struct list_head *plink_list;
21229 +       struct pseudo_link *plink;
21230 +
21231 +       sbinfo = au_sbi(inode->i_sb);
21232 +       AuRwMustAnyLock(&sbinfo->si_rwsem);
21233 +       AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
21234 +       AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
21235 +
21236 +       found = 0;
21237 +       plink_list = &sbinfo->si_plink.head;
21238 +       rcu_read_lock();
21239 +       list_for_each_entry_rcu(plink, plink_list, list)
21240 +               if (plink->inode == inode) {
21241 +                       found = 1;
21242 +                       break;
21243 +               }
21244 +       rcu_read_unlock();
21245 +       return found;
21246 +}
21247 +
21248 +/* ---------------------------------------------------------------------- */
21249 +
21250 +/*
21251 + * generate a name for plink.
21252 + * the file will be stored under AUFS_WH_PLINKDIR.
21253 + */
21254 +/* 20 is max digits length of ulong 64 */
21255 +#define PLINK_NAME_LEN ((20 + 1) * 2)
21256 +
21257 +static int plink_name(char *name, int len, struct inode *inode,
21258 +                     aufs_bindex_t bindex)
21259 +{
21260 +       int rlen;
21261 +       struct inode *h_inode;
21262 +
21263 +       h_inode = au_h_iptr(inode, bindex);
21264 +       rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
21265 +       return rlen;
21266 +}
21267 +
21268 +struct au_do_plink_lkup_args {
21269 +       struct dentry **errp;
21270 +       struct qstr *tgtname;
21271 +       struct dentry *h_parent;
21272 +       struct au_branch *br;
21273 +};
21274 +
21275 +static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
21276 +                                      struct dentry *h_parent,
21277 +                                      struct au_branch *br)
21278 +{
21279 +       struct dentry *h_dentry;
21280 +       struct mutex *h_mtx;
21281 +
21282 +       h_mtx = &h_parent->d_inode->i_mutex;
21283 +       mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
21284 +       h_dentry = vfsub_lkup_one(tgtname, h_parent);
21285 +       mutex_unlock(h_mtx);
21286 +       return h_dentry;
21287 +}
21288 +
21289 +static void au_call_do_plink_lkup(void *args)
21290 +{
21291 +       struct au_do_plink_lkup_args *a = args;
21292 +       *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
21293 +}
21294 +
21295 +/* lookup the plink-ed @inode under the branch at @bindex */
21296 +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
21297 +{
21298 +       struct dentry *h_dentry, *h_parent;
21299 +       struct au_branch *br;
21300 +       struct inode *h_dir;
21301 +       int wkq_err;
21302 +       char a[PLINK_NAME_LEN];
21303 +       struct qstr tgtname = QSTR_INIT(a, 0);
21304 +
21305 +       AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
21306 +
21307 +       br = au_sbr(inode->i_sb, bindex);
21308 +       h_parent = br->br_wbr->wbr_plink;
21309 +       h_dir = h_parent->d_inode;
21310 +       tgtname.len = plink_name(a, sizeof(a), inode, bindex);
21311 +
21312 +       if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
21313 +               struct au_do_plink_lkup_args args = {
21314 +                       .errp           = &h_dentry,
21315 +                       .tgtname        = &tgtname,
21316 +                       .h_parent       = h_parent,
21317 +                       .br             = br
21318 +               };
21319 +
21320 +               wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
21321 +               if (unlikely(wkq_err))
21322 +                       h_dentry = ERR_PTR(wkq_err);
21323 +       } else
21324 +               h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
21325 +
21326 +       return h_dentry;
21327 +}
21328 +
21329 +/* create a pseudo-link */
21330 +static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
21331 +                     struct dentry *h_dentry, struct au_branch *br)
21332 +{
21333 +       int err;
21334 +       struct path h_path = {
21335 +               .mnt = br->br_mnt
21336 +       };
21337 +       struct inode *h_dir;
21338 +
21339 +       h_dir = h_parent->d_inode;
21340 +       mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
21341 +again:
21342 +       h_path.dentry = vfsub_lkup_one(tgt, h_parent);
21343 +       err = PTR_ERR(h_path.dentry);
21344 +       if (IS_ERR(h_path.dentry))
21345 +               goto out;
21346 +
21347 +       err = 0;
21348 +       /* wh.plink dir is not monitored */
21349 +       /* todo: is it really safe? */
21350 +       if (h_path.dentry->d_inode
21351 +           && h_path.dentry->d_inode != h_dentry->d_inode) {
21352 +               err = vfsub_unlink(h_dir, &h_path, /*force*/0);
21353 +               dput(h_path.dentry);
21354 +               h_path.dentry = NULL;
21355 +               if (!err)
21356 +                       goto again;
21357 +       }
21358 +       if (!err && !h_path.dentry->d_inode)
21359 +               err = vfsub_link(h_dentry, h_dir, &h_path);
21360 +       dput(h_path.dentry);
21361 +
21362 +out:
21363 +       mutex_unlock(&h_dir->i_mutex);
21364 +       return err;
21365 +}
21366 +
21367 +struct do_whplink_args {
21368 +       int *errp;
21369 +       struct qstr *tgt;
21370 +       struct dentry *h_parent;
21371 +       struct dentry *h_dentry;
21372 +       struct au_branch *br;
21373 +};
21374 +
21375 +static void call_do_whplink(void *args)
21376 +{
21377 +       struct do_whplink_args *a = args;
21378 +       *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
21379 +}
21380 +
21381 +static int whplink(struct dentry *h_dentry, struct inode *inode,
21382 +                  aufs_bindex_t bindex, struct au_branch *br)
21383 +{
21384 +       int err, wkq_err;
21385 +       struct au_wbr *wbr;
21386 +       struct dentry *h_parent;
21387 +       struct inode *h_dir;
21388 +       char a[PLINK_NAME_LEN];
21389 +       struct qstr tgtname = QSTR_INIT(a, 0);
21390 +
21391 +       wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
21392 +       h_parent = wbr->wbr_plink;
21393 +       h_dir = h_parent->d_inode;
21394 +       tgtname.len = plink_name(a, sizeof(a), inode, bindex);
21395 +
21396 +       /* always superio. */
21397 +       if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
21398 +               struct do_whplink_args args = {
21399 +                       .errp           = &err,
21400 +                       .tgt            = &tgtname,
21401 +                       .h_parent       = h_parent,
21402 +                       .h_dentry       = h_dentry,
21403 +                       .br             = br
21404 +               };
21405 +               wkq_err = au_wkq_wait(call_do_whplink, &args);
21406 +               if (unlikely(wkq_err))
21407 +                       err = wkq_err;
21408 +       } else
21409 +               err = do_whplink(&tgtname, h_parent, h_dentry, br);
21410 +
21411 +       return err;
21412 +}
21413 +
21414 +/* free a single plink */
21415 +static void do_put_plink(struct pseudo_link *plink, int do_del)
21416 +{
21417 +       if (do_del)
21418 +               list_del(&plink->list);
21419 +       iput(plink->inode);
21420 +       kfree(plink);
21421 +}
21422 +
21423 +static void do_put_plink_rcu(struct rcu_head *rcu)
21424 +{
21425 +       struct pseudo_link *plink;
21426 +
21427 +       plink = container_of(rcu, struct pseudo_link, rcu);
21428 +       iput(plink->inode);
21429 +       kfree(plink);
21430 +}
21431 +
21432 +/*
21433 + * create a new pseudo-link for @h_dentry on @bindex.
21434 + * the linked inode is held in aufs @inode.
21435 + */
21436 +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
21437 +                    struct dentry *h_dentry)
21438 +{
21439 +       struct super_block *sb;
21440 +       struct au_sbinfo *sbinfo;
21441 +       struct list_head *plink_list;
21442 +       struct pseudo_link *plink, *tmp;
21443 +       int found, err, cnt;
21444 +
21445 +       sb = inode->i_sb;
21446 +       sbinfo = au_sbi(sb);
21447 +       AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
21448 +       AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
21449 +
21450 +       cnt = 0;
21451 +       found = 0;
21452 +       plink_list = &sbinfo->si_plink.head;
21453 +       rcu_read_lock();
21454 +       list_for_each_entry_rcu(plink, plink_list, list) {
21455 +               cnt++;
21456 +               if (plink->inode == inode) {
21457 +                       found = 1;
21458 +                       break;
21459 +               }
21460 +       }
21461 +       rcu_read_unlock();
21462 +       if (found)
21463 +               return;
21464 +
21465 +       tmp = kmalloc(sizeof(*plink), GFP_NOFS);
21466 +       if (tmp)
21467 +               tmp->inode = au_igrab(inode);
21468 +       else {
21469 +               err = -ENOMEM;
21470 +               goto out;
21471 +       }
21472 +
21473 +       spin_lock(&sbinfo->si_plink.spin);
21474 +       list_for_each_entry(plink, plink_list, list) {
21475 +               if (plink->inode == inode) {
21476 +                       found = 1;
21477 +                       break;
21478 +               }
21479 +       }
21480 +       if (!found)
21481 +               list_add_rcu(&tmp->list, plink_list);
21482 +       spin_unlock(&sbinfo->si_plink.spin);
21483 +       if (!found) {
21484 +               cnt++;
21485 +               WARN_ONCE(cnt > AUFS_PLINK_WARN,
21486 +                         "unexpectedly many pseudo links, %d\n", cnt);
21487 +               err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
21488 +       } else {
21489 +               do_put_plink(tmp, 0);
21490 +               return;
21491 +       }
21492 +
21493 +out:
21494 +       if (unlikely(err)) {
21495 +               pr_warn("err %d, damaged pseudo link.\n", err);
21496 +               if (tmp) {
21497 +                       au_spl_del_rcu(&tmp->list, &sbinfo->si_plink);
21498 +                       call_rcu(&tmp->rcu, do_put_plink_rcu);
21499 +               }
21500 +       }
21501 +}
21502 +
21503 +/* free all plinks */
21504 +void au_plink_put(struct super_block *sb, int verbose)
21505 +{
21506 +       struct au_sbinfo *sbinfo;
21507 +       struct list_head *plink_list;
21508 +       struct pseudo_link *plink, *tmp;
21509 +
21510 +       SiMustWriteLock(sb);
21511 +
21512 +       sbinfo = au_sbi(sb);
21513 +       AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
21514 +       AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
21515 +
21516 +       plink_list = &sbinfo->si_plink.head;
21517 +       /* no spin_lock since sbinfo is write-locked */
21518 +       WARN(verbose && !list_empty(plink_list), "pseudo-link is not flushed");
21519 +       list_for_each_entry_safe(plink, tmp, plink_list, list)
21520 +               do_put_plink(plink, 0);
21521 +       INIT_LIST_HEAD(plink_list);
21522 +}
21523 +
21524 +void au_plink_clean(struct super_block *sb, int verbose)
21525 +{
21526 +       struct dentry *root;
21527 +
21528 +       root = sb->s_root;
21529 +       aufs_write_lock(root);
21530 +       if (au_opt_test(au_mntflags(sb), PLINK))
21531 +               au_plink_put(sb, verbose);
21532 +       aufs_write_unlock(root);
21533 +}
21534 +
21535 +/* free the plinks on a branch specified by @br_id */
21536 +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
21537 +{
21538 +       struct au_sbinfo *sbinfo;
21539 +       struct list_head *plink_list;
21540 +       struct pseudo_link *plink, *tmp;
21541 +       struct inode *inode;
21542 +       aufs_bindex_t bstart, bend, bindex;
21543 +       unsigned char do_put;
21544 +
21545 +       SiMustWriteLock(sb);
21546 +
21547 +       sbinfo = au_sbi(sb);
21548 +       AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
21549 +       AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
21550 +
21551 +       plink_list = &sbinfo->si_plink.head;
21552 +       /* no spin_lock since sbinfo is write-locked */
21553 +       list_for_each_entry_safe(plink, tmp, plink_list, list) {
21554 +               do_put = 0;
21555 +               inode = au_igrab(plink->inode);
21556 +               ii_write_lock_child(inode);
21557 +               bstart = au_ibstart(inode);
21558 +               bend = au_ibend(inode);
21559 +               if (bstart >= 0) {
21560 +                       for (bindex = bstart; bindex <= bend; bindex++) {
21561 +                               if (!au_h_iptr(inode, bindex)
21562 +                                   || au_ii_br_id(inode, bindex) != br_id)
21563 +                                       continue;
21564 +                               au_set_h_iptr(inode, bindex, NULL, 0);
21565 +                               do_put = 1;
21566 +                               break;
21567 +                       }
21568 +               } else
21569 +                       do_put_plink(plink, 1);
21570 +
21571 +               if (do_put) {
21572 +                       for (bindex = bstart; bindex <= bend; bindex++)
21573 +                               if (au_h_iptr(inode, bindex)) {
21574 +                                       do_put = 0;
21575 +                                       break;
21576 +                               }
21577 +                       if (do_put)
21578 +                               do_put_plink(plink, 1);
21579 +               }
21580 +               ii_write_unlock(inode);
21581 +               iput(inode);
21582 +       }
21583 +}
21584 diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
21585 --- /usr/share/empty/fs/aufs/poll.c     1970-01-01 01:00:00.000000000 +0100
21586 +++ linux/fs/aufs/poll.c        2013-01-11 19:46:12.639281345 +0100
21587 @@ -0,0 +1,56 @@
21588 +/*
21589 + * Copyright (C) 2005-2013 Junjiro R. Okajima
21590 + *
21591 + * This program, aufs is free software; you can redistribute it and/or modify
21592 + * it under the terms of the GNU General Public License as published by
21593 + * the Free Software Foundation; either version 2 of the License, or
21594 + * (at your option) any later version.
21595 + *
21596 + * This program is distributed in the hope that it will be useful,
21597 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21598 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21599 + * GNU General Public License for more details.
21600 + *
21601 + * You should have received a copy of the GNU General Public License
21602 + * along with this program; if not, write to the Free Software
21603 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21604 + */
21605 +
21606 +/*
21607 + * poll operation
21608 + * There is only one filesystem which implements ->poll operation, currently.
21609 + */
21610 +
21611 +#include "aufs.h"
21612 +
21613 +unsigned int aufs_poll(struct file *file, poll_table *wait)
21614 +{
21615 +       unsigned int mask;
21616 +       int err;
21617 +       struct file *h_file;
21618 +       struct dentry *dentry;
21619 +       struct super_block *sb;
21620 +
21621 +       /* We should pretend an error happened. */
21622 +       mask = POLLERR /* | POLLIN | POLLOUT */;
21623 +       dentry = file->f_dentry;
21624 +       sb = dentry->d_sb;
21625 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
21626 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
21627 +       if (unlikely(err))
21628 +               goto out;
21629 +
21630 +       /* it is not an error if h_file has no operation */
21631 +       mask = DEFAULT_POLLMASK;
21632 +       h_file = au_hf_top(file);
21633 +       if (h_file->f_op && h_file->f_op->poll)
21634 +               mask = h_file->f_op->poll(h_file, wait);
21635 +
21636 +       di_read_unlock(dentry, AuLock_IR);
21637 +       fi_read_unlock(file);
21638 +
21639 +out:
21640 +       si_read_unlock(sb);
21641 +       AuTraceErr((int)mask);
21642 +       return mask;
21643 +}
21644 diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
21645 --- /usr/share/empty/fs/aufs/procfs.c   1970-01-01 01:00:00.000000000 +0100
21646 +++ linux/fs/aufs/procfs.c      2013-01-11 19:46:12.639281345 +0100
21647 @@ -0,0 +1,170 @@
21648 +/*
21649 + * Copyright (C) 2010-2013 Junjiro R. Okajima
21650 + *
21651 + * This program, aufs is free software; you can redistribute it and/or modify
21652 + * it under the terms of the GNU General Public License as published by
21653 + * the Free Software Foundation; either version 2 of the License, or
21654 + * (at your option) any later version.
21655 + *
21656 + * This program is distributed in the hope that it will be useful,
21657 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21658 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21659 + * GNU General Public License for more details.
21660 + *
21661 + * You should have received a copy of the GNU General Public License
21662 + * along with this program; if not, write to the Free Software
21663 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21664 + */
21665 +
21666 +/*
21667 + * procfs interfaces
21668 + */
21669 +
21670 +#include <linux/proc_fs.h>
21671 +#include "aufs.h"
21672 +
21673 +static int au_procfs_plm_release(struct inode *inode, struct file *file)
21674 +{
21675 +       struct au_sbinfo *sbinfo;
21676 +
21677 +       sbinfo = file->private_data;
21678 +       if (sbinfo) {
21679 +               au_plink_maint_leave(sbinfo);
21680 +               kobject_put(&sbinfo->si_kobj);
21681 +       }
21682 +
21683 +       return 0;
21684 +}
21685 +
21686 +static void au_procfs_plm_write_clean(struct file *file)
21687 +{
21688 +       struct au_sbinfo *sbinfo;
21689 +
21690 +       sbinfo = file->private_data;
21691 +       if (sbinfo)
21692 +               au_plink_clean(sbinfo->si_sb, /*verbose*/0);
21693 +}
21694 +
21695 +static int au_procfs_plm_write_si(struct file *file, unsigned long id)
21696 +{
21697 +       int err;
21698 +       struct super_block *sb;
21699 +       struct au_sbinfo *sbinfo;
21700 +
21701 +       err = -EBUSY;
21702 +       if (unlikely(file->private_data))
21703 +               goto out;
21704 +
21705 +       sb = NULL;
21706 +       /* don't use au_sbilist_lock() here */
21707 +       spin_lock(&au_sbilist.spin);
21708 +       list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
21709 +               if (id == sysaufs_si_id(sbinfo)) {
21710 +                       kobject_get(&sbinfo->si_kobj);
21711 +                       sb = sbinfo->si_sb;
21712 +                       break;
21713 +               }
21714 +       spin_unlock(&au_sbilist.spin);
21715 +
21716 +       err = -EINVAL;
21717 +       if (unlikely(!sb))
21718 +               goto out;
21719 +
21720 +       err = au_plink_maint_enter(sb);
21721 +       if (!err)
21722 +               /* keep kobject_get() */
21723 +               file->private_data = sbinfo;
21724 +       else
21725 +               kobject_put(&sbinfo->si_kobj);
21726 +out:
21727 +       return err;
21728 +}
21729 +
21730 +/*
21731 + * Accept a valid "si=xxxx" only.
21732 + * Once it is accepted successfully, accept "clean" too.
21733 + */
21734 +static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
21735 +                                  size_t count, loff_t *ppos)
21736 +{
21737 +       ssize_t err;
21738 +       unsigned long id;
21739 +       /* last newline is allowed */
21740 +       char buf[3 + sizeof(unsigned long) * 2 + 1];
21741 +
21742 +       err = -EACCES;
21743 +       if (unlikely(!capable(CAP_SYS_ADMIN)))
21744 +               goto out;
21745 +
21746 +       err = -EINVAL;
21747 +       if (unlikely(count > sizeof(buf)))
21748 +               goto out;
21749 +
21750 +       err = copy_from_user(buf, ubuf, count);
21751 +       if (unlikely(err)) {
21752 +               err = -EFAULT;
21753 +               goto out;
21754 +       }
21755 +       buf[count] = 0;
21756 +
21757 +       err = -EINVAL;
21758 +       if (!strcmp("clean", buf)) {
21759 +               au_procfs_plm_write_clean(file);
21760 +               goto out_success;
21761 +       } else if (unlikely(strncmp("si=", buf, 3)))
21762 +               goto out;
21763 +
21764 +       err = kstrtoul(buf + 3, 16, &id);
21765 +       if (unlikely(err))
21766 +               goto out;
21767 +
21768 +       err = au_procfs_plm_write_si(file, id);
21769 +       if (unlikely(err))
21770 +               goto out;
21771 +
21772 +out_success:
21773 +       err = count; /* success */
21774 +out:
21775 +       return err;
21776 +}
21777 +
21778 +static const struct file_operations au_procfs_plm_fop = {
21779 +       .write          = au_procfs_plm_write,
21780 +       .release        = au_procfs_plm_release,
21781 +       .owner          = THIS_MODULE
21782 +};
21783 +
21784 +/* ---------------------------------------------------------------------- */
21785 +
21786 +static struct proc_dir_entry *au_procfs_dir;
21787 +
21788 +void au_procfs_fin(void)
21789 +{
21790 +       remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
21791 +       remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
21792 +}
21793 +
21794 +int __init au_procfs_init(void)
21795 +{
21796 +       int err;
21797 +       struct proc_dir_entry *entry;
21798 +
21799 +       err = -ENOMEM;
21800 +       au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
21801 +       if (unlikely(!au_procfs_dir))
21802 +               goto out;
21803 +
21804 +       entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
21805 +                           au_procfs_dir, &au_procfs_plm_fop);
21806 +       if (unlikely(!entry))
21807 +               goto out_dir;
21808 +
21809 +       err = 0;
21810 +       goto out; /* success */
21811 +
21812 +
21813 +out_dir:
21814 +       remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
21815 +out:
21816 +       return err;
21817 +}
21818 diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
21819 --- /usr/share/empty/fs/aufs/rdu.c      1970-01-01 01:00:00.000000000 +0100
21820 +++ linux/fs/aufs/rdu.c 2013-01-11 19:46:12.639281345 +0100
21821 @@ -0,0 +1,384 @@
21822 +/*
21823 + * Copyright (C) 2005-2013 Junjiro R. Okajima
21824 + *
21825 + * This program, aufs is free software; you can redistribute it and/or modify
21826 + * it under the terms of the GNU General Public License as published by
21827 + * the Free Software Foundation; either version 2 of the License, or
21828 + * (at your option) any later version.
21829 + *
21830 + * This program is distributed in the hope that it will be useful,
21831 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21832 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21833 + * GNU General Public License for more details.
21834 + *
21835 + * You should have received a copy of the GNU General Public License
21836 + * along with this program; if not, write to the Free Software
21837 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21838 + */
21839 +
21840 +/*
21841 + * readdir in userspace.
21842 + */
21843 +
21844 +#include <linux/compat.h>
21845 +#include <linux/fs_stack.h>
21846 +#include <linux/security.h>
21847 +#include "aufs.h"
21848 +
21849 +/* bits for struct aufs_rdu.flags */
21850 +#define        AuRdu_CALLED    1
21851 +#define        AuRdu_CONT      (1 << 1)
21852 +#define        AuRdu_FULL      (1 << 2)
21853 +#define au_ftest_rdu(flags, name)      ((flags) & AuRdu_##name)
21854 +#define au_fset_rdu(flags, name) \
21855 +       do { (flags) |= AuRdu_##name; } while (0)
21856 +#define au_fclr_rdu(flags, name) \
21857 +       do { (flags) &= ~AuRdu_##name; } while (0)
21858 +
21859 +struct au_rdu_arg {
21860 +       struct aufs_rdu                 *rdu;
21861 +       union au_rdu_ent_ul             ent;
21862 +       unsigned long                   end;
21863 +
21864 +       struct super_block              *sb;
21865 +       int                             err;
21866 +};
21867 +
21868 +static int au_rdu_fill(void *__arg, const char *name, int nlen,
21869 +                      loff_t offset, u64 h_ino, unsigned int d_type)
21870 +{
21871 +       int err, len;
21872 +       struct au_rdu_arg *arg = __arg;
21873 +       struct aufs_rdu *rdu = arg->rdu;
21874 +       struct au_rdu_ent ent;
21875 +
21876 +       err = 0;
21877 +       arg->err = 0;
21878 +       au_fset_rdu(rdu->cookie.flags, CALLED);
21879 +       len = au_rdu_len(nlen);
21880 +       if (arg->ent.ul + len  < arg->end) {
21881 +               ent.ino = h_ino;
21882 +               ent.bindex = rdu->cookie.bindex;
21883 +               ent.type = d_type;
21884 +               ent.nlen = nlen;
21885 +               if (unlikely(nlen > AUFS_MAX_NAMELEN))
21886 +                       ent.type = DT_UNKNOWN;
21887 +
21888 +               /* unnecessary to support mmap_sem since this is a dir */
21889 +               err = -EFAULT;
21890 +               if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
21891 +                       goto out;
21892 +               if (copy_to_user(arg->ent.e->name, name, nlen))
21893 +                       goto out;
21894 +               /* the terminating NULL */
21895 +               if (__put_user(0, arg->ent.e->name + nlen))
21896 +                       goto out;
21897 +               err = 0;
21898 +               /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
21899 +               arg->ent.ul += len;
21900 +               rdu->rent++;
21901 +       } else {
21902 +               err = -EFAULT;
21903 +               au_fset_rdu(rdu->cookie.flags, FULL);
21904 +               rdu->full = 1;
21905 +               rdu->tail = arg->ent;
21906 +       }
21907 +
21908 +out:
21909 +       /* AuTraceErr(err); */
21910 +       return err;
21911 +}
21912 +
21913 +static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
21914 +{
21915 +       int err;
21916 +       loff_t offset;
21917 +       struct au_rdu_cookie *cookie = &arg->rdu->cookie;
21918 +
21919 +       /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
21920 +       offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
21921 +       err = offset;
21922 +       if (unlikely(offset != cookie->h_pos))
21923 +               goto out;
21924 +
21925 +       err = 0;
21926 +       do {
21927 +               arg->err = 0;
21928 +               au_fclr_rdu(cookie->flags, CALLED);
21929 +               /* smp_mb(); */
21930 +               err = vfsub_readdir(h_file, au_rdu_fill, arg);
21931 +               if (err >= 0)
21932 +                       err = arg->err;
21933 +       } while (!err
21934 +                && au_ftest_rdu(cookie->flags, CALLED)
21935 +                && !au_ftest_rdu(cookie->flags, FULL));
21936 +       cookie->h_pos = h_file->f_pos;
21937 +
21938 +out:
21939 +       AuTraceErr(err);
21940 +       return err;
21941 +}
21942 +
21943 +static int au_rdu(struct file *file, struct aufs_rdu *rdu)
21944 +{
21945 +       int err;
21946 +       aufs_bindex_t bend;
21947 +       struct au_rdu_arg arg;
21948 +       struct dentry *dentry;
21949 +       struct inode *inode;
21950 +       struct file *h_file;
21951 +       struct au_rdu_cookie *cookie = &rdu->cookie;
21952 +
21953 +       err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
21954 +       if (unlikely(err)) {
21955 +               err = -EFAULT;
21956 +               AuTraceErr(err);
21957 +               goto out;
21958 +       }
21959 +       rdu->rent = 0;
21960 +       rdu->tail = rdu->ent;
21961 +       rdu->full = 0;
21962 +       arg.rdu = rdu;
21963 +       arg.ent = rdu->ent;
21964 +       arg.end = arg.ent.ul;
21965 +       arg.end += rdu->sz;
21966 +
21967 +       err = -ENOTDIR;
21968 +       if (unlikely(!file->f_op || !file->f_op->readdir))
21969 +               goto out;
21970 +
21971 +       err = security_file_permission(file, MAY_READ);
21972 +       AuTraceErr(err);
21973 +       if (unlikely(err))
21974 +               goto out;
21975 +
21976 +       dentry = file->f_dentry;
21977 +       inode = dentry->d_inode;
21978 +#if 1
21979 +       mutex_lock(&inode->i_mutex);
21980 +#else
21981 +       err = mutex_lock_killable(&inode->i_mutex);
21982 +       AuTraceErr(err);
21983 +       if (unlikely(err))
21984 +               goto out;
21985 +#endif
21986 +
21987 +       arg.sb = inode->i_sb;
21988 +       err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
21989 +       if (unlikely(err))
21990 +               goto out_mtx;
21991 +       err = au_alive_dir(dentry);
21992 +       if (unlikely(err))
21993 +               goto out_si;
21994 +       /* todo: reval? */
21995 +       fi_read_lock(file);
21996 +
21997 +       err = -EAGAIN;
21998 +       if (unlikely(au_ftest_rdu(cookie->flags, CONT)
21999 +                    && cookie->generation != au_figen(file)))
22000 +               goto out_unlock;
22001 +
22002 +       err = 0;
22003 +       if (!rdu->blk) {
22004 +               rdu->blk = au_sbi(arg.sb)->si_rdblk;
22005 +               if (!rdu->blk)
22006 +                       rdu->blk = au_dir_size(file, /*dentry*/NULL);
22007 +       }
22008 +       bend = au_fbstart(file);
22009 +       if (cookie->bindex < bend)
22010 +               cookie->bindex = bend;
22011 +       bend = au_fbend_dir(file);
22012 +       /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
22013 +       for (; !err && cookie->bindex <= bend;
22014 +            cookie->bindex++, cookie->h_pos = 0) {
22015 +               h_file = au_hf_dir(file, cookie->bindex);
22016 +               if (!h_file)
22017 +                       continue;
22018 +
22019 +               au_fclr_rdu(cookie->flags, FULL);
22020 +               err = au_rdu_do(h_file, &arg);
22021 +               AuTraceErr(err);
22022 +               if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
22023 +                       break;
22024 +       }
22025 +       AuDbg("rent %llu\n", rdu->rent);
22026 +
22027 +       if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
22028 +               rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
22029 +               au_fset_rdu(cookie->flags, CONT);
22030 +               cookie->generation = au_figen(file);
22031 +       }
22032 +
22033 +       ii_read_lock_child(inode);
22034 +       fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
22035 +       ii_read_unlock(inode);
22036 +
22037 +out_unlock:
22038 +       fi_read_unlock(file);
22039 +out_si:
22040 +       si_read_unlock(arg.sb);
22041 +out_mtx:
22042 +       mutex_unlock(&inode->i_mutex);
22043 +out:
22044 +       AuTraceErr(err);
22045 +       return err;
22046 +}
22047 +
22048 +static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
22049 +{
22050 +       int err;
22051 +       ino_t ino;
22052 +       unsigned long long nent;
22053 +       union au_rdu_ent_ul *u;
22054 +       struct au_rdu_ent ent;
22055 +       struct super_block *sb;
22056 +
22057 +       err = 0;
22058 +       nent = rdu->nent;
22059 +       u = &rdu->ent;
22060 +       sb = file->f_dentry->d_sb;
22061 +       si_read_lock(sb, AuLock_FLUSH);
22062 +       while (nent-- > 0) {
22063 +               /* unnecessary to support mmap_sem since this is a dir */
22064 +               err = copy_from_user(&ent, u->e, sizeof(ent));
22065 +               if (!err)
22066 +                       err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
22067 +               if (unlikely(err)) {
22068 +                       err = -EFAULT;
22069 +                       AuTraceErr(err);
22070 +                       break;
22071 +               }
22072 +
22073 +               /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
22074 +               if (!ent.wh)
22075 +                       err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
22076 +               else
22077 +                       err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
22078 +                                       &ino);
22079 +               if (unlikely(err)) {
22080 +                       AuTraceErr(err);
22081 +                       break;
22082 +               }
22083 +
22084 +               err = __put_user(ino, &u->e->ino);
22085 +               if (unlikely(err)) {
22086 +                       err = -EFAULT;
22087 +                       AuTraceErr(err);
22088 +                       break;
22089 +               }
22090 +               u->ul += au_rdu_len(ent.nlen);
22091 +       }
22092 +       si_read_unlock(sb);
22093 +
22094 +       return err;
22095 +}
22096 +
22097 +/* ---------------------------------------------------------------------- */
22098 +
22099 +static int au_rdu_verify(struct aufs_rdu *rdu)
22100 +{
22101 +       AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
22102 +             "%llu, b%d, 0x%x, g%u}\n",
22103 +             rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
22104 +             rdu->blk,
22105 +             rdu->rent, rdu->shwh, rdu->full,
22106 +             rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
22107 +             rdu->cookie.generation);
22108 +
22109 +       if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
22110 +               return 0;
22111 +
22112 +       AuDbg("%u:%u\n",
22113 +             rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
22114 +       return -EINVAL;
22115 +}
22116 +
22117 +long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
22118 +{
22119 +       long err, e;
22120 +       struct aufs_rdu rdu;
22121 +       void __user *p = (void __user *)arg;
22122 +
22123 +       err = copy_from_user(&rdu, p, sizeof(rdu));
22124 +       if (unlikely(err)) {
22125 +               err = -EFAULT;
22126 +               AuTraceErr(err);
22127 +               goto out;
22128 +       }
22129 +       err = au_rdu_verify(&rdu);
22130 +       if (unlikely(err))
22131 +               goto out;
22132 +
22133 +       switch (cmd) {
22134 +       case AUFS_CTL_RDU:
22135 +               err = au_rdu(file, &rdu);
22136 +               if (unlikely(err))
22137 +                       break;
22138 +
22139 +               e = copy_to_user(p, &rdu, sizeof(rdu));
22140 +               if (unlikely(e)) {
22141 +                       err = -EFAULT;
22142 +                       AuTraceErr(err);
22143 +               }
22144 +               break;
22145 +       case AUFS_CTL_RDU_INO:
22146 +               err = au_rdu_ino(file, &rdu);
22147 +               break;
22148 +
22149 +       default:
22150 +               /* err = -ENOTTY; */
22151 +               err = -EINVAL;
22152 +       }
22153 +
22154 +out:
22155 +       AuTraceErr(err);
22156 +       return err;
22157 +}
22158 +
22159 +#ifdef CONFIG_COMPAT
22160 +long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
22161 +{
22162 +       long err, e;
22163 +       struct aufs_rdu rdu;
22164 +       void __user *p = compat_ptr(arg);
22165 +
22166 +       /* todo: get_user()? */
22167 +       err = copy_from_user(&rdu, p, sizeof(rdu));
22168 +       if (unlikely(err)) {
22169 +               err = -EFAULT;
22170 +               AuTraceErr(err);
22171 +               goto out;
22172 +       }
22173 +       rdu.ent.e = compat_ptr(rdu.ent.ul);
22174 +       err = au_rdu_verify(&rdu);
22175 +       if (unlikely(err))
22176 +               goto out;
22177 +
22178 +       switch (cmd) {
22179 +       case AUFS_CTL_RDU:
22180 +               err = au_rdu(file, &rdu);
22181 +               if (unlikely(err))
22182 +                       break;
22183 +
22184 +               rdu.ent.ul = ptr_to_compat(rdu.ent.e);
22185 +               rdu.tail.ul = ptr_to_compat(rdu.tail.e);
22186 +               e = copy_to_user(p, &rdu, sizeof(rdu));
22187 +               if (unlikely(e)) {
22188 +                       err = -EFAULT;
22189 +                       AuTraceErr(err);
22190 +               }
22191 +               break;
22192 +       case AUFS_CTL_RDU_INO:
22193 +               err = au_rdu_ino(file, &rdu);
22194 +               break;
22195 +
22196 +       default:
22197 +               /* err = -ENOTTY; */
22198 +               err = -EINVAL;
22199 +       }
22200 +
22201 +out:
22202 +       AuTraceErr(err);
22203 +       return err;
22204 +}
22205 +#endif
22206 diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
22207 --- /usr/share/empty/fs/aufs/rwsem.h    1970-01-01 01:00:00.000000000 +0100
22208 +++ linux/fs/aufs/rwsem.h       2013-01-11 19:46:12.639281345 +0100
22209 @@ -0,0 +1,188 @@
22210 +/*
22211 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22212 + *
22213 + * This program, aufs is free software; you can redistribute it and/or modify
22214 + * it under the terms of the GNU General Public License as published by
22215 + * the Free Software Foundation; either version 2 of the License, or
22216 + * (at your option) any later version.
22217 + *
22218 + * This program is distributed in the hope that it will be useful,
22219 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22220 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22221 + * GNU General Public License for more details.
22222 + *
22223 + * You should have received a copy of the GNU General Public License
22224 + * along with this program; if not, write to the Free Software
22225 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22226 + */
22227 +
22228 +/*
22229 + * simple read-write semaphore wrappers
22230 + */
22231 +
22232 +#ifndef __AUFS_RWSEM_H__
22233 +#define __AUFS_RWSEM_H__
22234 +
22235 +#ifdef __KERNEL__
22236 +
22237 +#include "debug.h"
22238 +
22239 +struct au_rwsem {
22240 +       struct rw_semaphore     rwsem;
22241 +#ifdef CONFIG_AUFS_DEBUG
22242 +       /* just for debugging, not almighty counter */
22243 +       atomic_t                rcnt, wcnt;
22244 +#endif
22245 +};
22246 +
22247 +#ifdef CONFIG_AUFS_DEBUG
22248 +#define AuDbgCntInit(rw) do { \
22249 +       atomic_set(&(rw)->rcnt, 0); \
22250 +       atomic_set(&(rw)->wcnt, 0); \
22251 +       smp_mb(); /* atomic set */ \
22252 +} while (0)
22253 +
22254 +#define AuDbgRcntInc(rw)       atomic_inc(&(rw)->rcnt)
22255 +#define AuDbgRcntDec(rw)       WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
22256 +#define AuDbgWcntInc(rw)       atomic_inc(&(rw)->wcnt)
22257 +#define AuDbgWcntDec(rw)       WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
22258 +#else
22259 +#define AuDbgCntInit(rw)       do {} while (0)
22260 +#define AuDbgRcntInc(rw)       do {} while (0)
22261 +#define AuDbgRcntDec(rw)       do {} while (0)
22262 +#define AuDbgWcntInc(rw)       do {} while (0)
22263 +#define AuDbgWcntDec(rw)       do {} while (0)
22264 +#endif /* CONFIG_AUFS_DEBUG */
22265 +
22266 +/* to debug easier, do not make them inlined functions */
22267 +#define AuRwMustNoWaiters(rw)  AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
22268 +/* rwsem_is_locked() is unusable */
22269 +#define AuRwMustReadLock(rw)   AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
22270 +#define AuRwMustWriteLock(rw)  AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
22271 +#define AuRwMustAnyLock(rw)    AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
22272 +                                       && atomic_read(&(rw)->wcnt) <= 0)
22273 +#define AuRwDestroy(rw)                AuDebugOn(atomic_read(&(rw)->rcnt) \
22274 +                                       || atomic_read(&(rw)->wcnt))
22275 +
22276 +#define au_rw_class(rw, key)   lockdep_set_class(&(rw)->rwsem, key)
22277 +
22278 +static inline void au_rw_init(struct au_rwsem *rw)
22279 +{
22280 +       AuDbgCntInit(rw);
22281 +       init_rwsem(&rw->rwsem);
22282 +}
22283 +
22284 +static inline void au_rw_init_wlock(struct au_rwsem *rw)
22285 +{
22286 +       au_rw_init(rw);
22287 +       down_write(&rw->rwsem);
22288 +       AuDbgWcntInc(rw);
22289 +}
22290 +
22291 +static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
22292 +                                          unsigned int lsc)
22293 +{
22294 +       au_rw_init(rw);
22295 +       down_write_nested(&rw->rwsem, lsc);
22296 +       AuDbgWcntInc(rw);
22297 +}
22298 +
22299 +static inline void au_rw_read_lock(struct au_rwsem *rw)
22300 +{
22301 +       down_read(&rw->rwsem);
22302 +       AuDbgRcntInc(rw);
22303 +}
22304 +
22305 +static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
22306 +{
22307 +       down_read_nested(&rw->rwsem, lsc);
22308 +       AuDbgRcntInc(rw);
22309 +}
22310 +
22311 +static inline void au_rw_read_unlock(struct au_rwsem *rw)
22312 +{
22313 +       AuRwMustReadLock(rw);
22314 +       AuDbgRcntDec(rw);
22315 +       up_read(&rw->rwsem);
22316 +}
22317 +
22318 +static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
22319 +{
22320 +       AuRwMustWriteLock(rw);
22321 +       AuDbgRcntInc(rw);
22322 +       AuDbgWcntDec(rw);
22323 +       downgrade_write(&rw->rwsem);
22324 +}
22325 +
22326 +static inline void au_rw_write_lock(struct au_rwsem *rw)
22327 +{
22328 +       down_write(&rw->rwsem);
22329 +       AuDbgWcntInc(rw);
22330 +}
22331 +
22332 +static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
22333 +                                          unsigned int lsc)
22334 +{
22335 +       down_write_nested(&rw->rwsem, lsc);
22336 +       AuDbgWcntInc(rw);
22337 +}
22338 +
22339 +static inline void au_rw_write_unlock(struct au_rwsem *rw)
22340 +{
22341 +       AuRwMustWriteLock(rw);
22342 +       AuDbgWcntDec(rw);
22343 +       up_write(&rw->rwsem);
22344 +}
22345 +
22346 +/* why is not _nested version defined */
22347 +static inline int au_rw_read_trylock(struct au_rwsem *rw)
22348 +{
22349 +       int ret = down_read_trylock(&rw->rwsem);
22350 +       if (ret)
22351 +               AuDbgRcntInc(rw);
22352 +       return ret;
22353 +}
22354 +
22355 +static inline int au_rw_write_trylock(struct au_rwsem *rw)
22356 +{
22357 +       int ret = down_write_trylock(&rw->rwsem);
22358 +       if (ret)
22359 +               AuDbgWcntInc(rw);
22360 +       return ret;
22361 +}
22362 +
22363 +#undef AuDbgCntInit
22364 +#undef AuDbgRcntInc
22365 +#undef AuDbgRcntDec
22366 +#undef AuDbgWcntInc
22367 +#undef AuDbgWcntDec
22368 +
22369 +#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
22370 +static inline void prefix##_read_lock(param) \
22371 +{ au_rw_read_lock(rwsem); } \
22372 +static inline void prefix##_write_lock(param) \
22373 +{ au_rw_write_lock(rwsem); } \
22374 +static inline int prefix##_read_trylock(param) \
22375 +{ return au_rw_read_trylock(rwsem); } \
22376 +static inline int prefix##_write_trylock(param) \
22377 +{ return au_rw_write_trylock(rwsem); }
22378 +/* why is not _nested version defined */
22379 +/* static inline void prefix##_read_trylock_nested(param, lsc)
22380 +{ au_rw_read_trylock_nested(rwsem, lsc)); }
22381 +static inline void prefix##_write_trylock_nestd(param, lsc)
22382 +{ au_rw_write_trylock_nested(rwsem, lsc); } */
22383 +
22384 +#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
22385 +static inline void prefix##_read_unlock(param) \
22386 +{ au_rw_read_unlock(rwsem); } \
22387 +static inline void prefix##_write_unlock(param) \
22388 +{ au_rw_write_unlock(rwsem); } \
22389 +static inline void prefix##_downgrade_lock(param) \
22390 +{ au_rw_dgrade_lock(rwsem); }
22391 +
22392 +#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
22393 +       AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
22394 +       AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
22395 +
22396 +#endif /* __KERNEL__ */
22397 +#endif /* __AUFS_RWSEM_H__ */
22398 diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
22399 --- /usr/share/empty/fs/aufs/sbinfo.c   1970-01-01 01:00:00.000000000 +0100
22400 +++ linux/fs/aufs/sbinfo.c      2013-01-11 19:46:12.639281345 +0100
22401 @@ -0,0 +1,343 @@
22402 +/*
22403 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22404 + *
22405 + * This program, aufs is free software; you can redistribute it and/or modify
22406 + * it under the terms of the GNU General Public License as published by
22407 + * the Free Software Foundation; either version 2 of the License, or
22408 + * (at your option) any later version.
22409 + *
22410 + * This program is distributed in the hope that it will be useful,
22411 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22412 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22413 + * GNU General Public License for more details.
22414 + *
22415 + * You should have received a copy of the GNU General Public License
22416 + * along with this program; if not, write to the Free Software
22417 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22418 + */
22419 +
22420 +/*
22421 + * superblock private data
22422 + */
22423 +
22424 +#include "aufs.h"
22425 +
22426 +/*
22427 + * they are necessary regardless sysfs is disabled.
22428 + */
22429 +void au_si_free(struct kobject *kobj)
22430 +{
22431 +       struct au_sbinfo *sbinfo;
22432 +       char *locked __maybe_unused; /* debug only */
22433 +
22434 +       sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
22435 +       AuDebugOn(!list_empty(&sbinfo->si_plink.head));
22436 +       AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
22437 +
22438 +       au_rw_write_lock(&sbinfo->si_rwsem);
22439 +       au_br_free(sbinfo);
22440 +       au_rw_write_unlock(&sbinfo->si_rwsem);
22441 +
22442 +       AuDebugOn(radix_tree_gang_lookup
22443 +                 (&sbinfo->au_si_pid.tree, (void **)&locked,
22444 +                  /*first_index*/PID_MAX_DEFAULT - 1,
22445 +                  /*max_items*/sizeof(locked)/sizeof(*locked)));
22446 +
22447 +       kfree(sbinfo->si_branch);
22448 +       kfree(sbinfo->au_si_pid.bitmap);
22449 +       mutex_destroy(&sbinfo->si_xib_mtx);
22450 +       AuRwDestroy(&sbinfo->si_rwsem);
22451 +
22452 +       kfree(sbinfo);
22453 +}
22454 +
22455 +int au_si_alloc(struct super_block *sb)
22456 +{
22457 +       int err;
22458 +       struct au_sbinfo *sbinfo;
22459 +       static struct lock_class_key aufs_si;
22460 +
22461 +       err = -ENOMEM;
22462 +       sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
22463 +       if (unlikely(!sbinfo))
22464 +               goto out;
22465 +
22466 +       BUILD_BUG_ON(sizeof(unsigned long) !=
22467 +                    sizeof(*sbinfo->au_si_pid.bitmap));
22468 +       sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
22469 +                                       sizeof(*sbinfo->au_si_pid.bitmap),
22470 +                                       GFP_NOFS);
22471 +       if (unlikely(!sbinfo->au_si_pid.bitmap))
22472 +               goto out_sbinfo;
22473 +
22474 +       /* will be reallocated separately */
22475 +       sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
22476 +       if (unlikely(!sbinfo->si_branch))
22477 +               goto out_pidmap;
22478 +
22479 +       err = sysaufs_si_init(sbinfo);
22480 +       if (unlikely(err))
22481 +               goto out_br;
22482 +
22483 +       au_nwt_init(&sbinfo->si_nowait);
22484 +       au_rw_init_wlock(&sbinfo->si_rwsem);
22485 +       au_rw_class(&sbinfo->si_rwsem, &aufs_si);
22486 +       spin_lock_init(&sbinfo->au_si_pid.tree_lock);
22487 +       INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
22488 +
22489 +       atomic_long_set(&sbinfo->si_ninodes, 0);
22490 +       atomic_long_set(&sbinfo->si_nfiles, 0);
22491 +
22492 +       sbinfo->si_bend = -1;
22493 +
22494 +       sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
22495 +       sbinfo->si_wbr_create = AuWbrCreate_Def;
22496 +       sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
22497 +       sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
22498 +
22499 +       sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
22500 +
22501 +       mutex_init(&sbinfo->si_xib_mtx);
22502 +       sbinfo->si_xino_brid = -1;
22503 +       /* leave si_xib_last_pindex and si_xib_next_bit */
22504 +
22505 +       sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
22506 +       sbinfo->si_rdblk = AUFS_RDBLK_DEF;
22507 +       sbinfo->si_rdhash = AUFS_RDHASH_DEF;
22508 +       sbinfo->si_dirwh = AUFS_DIRWH_DEF;
22509 +
22510 +       au_spl_init(&sbinfo->si_plink);
22511 +       init_waitqueue_head(&sbinfo->si_plink_wq);
22512 +       spin_lock_init(&sbinfo->si_plink_maint_lock);
22513 +
22514 +       /* leave other members for sysaufs and si_mnt. */
22515 +       sbinfo->si_sb = sb;
22516 +       sb->s_fs_info = sbinfo;
22517 +       si_pid_set(sb);
22518 +       au_debug_sbinfo_init(sbinfo);
22519 +       return 0; /* success */
22520 +
22521 +out_br:
22522 +       kfree(sbinfo->si_branch);
22523 +out_pidmap:
22524 +       kfree(sbinfo->au_si_pid.bitmap);
22525 +out_sbinfo:
22526 +       kfree(sbinfo);
22527 +out:
22528 +       return err;
22529 +}
22530 +
22531 +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
22532 +{
22533 +       int err, sz;
22534 +       struct au_branch **brp;
22535 +
22536 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
22537 +
22538 +       err = -ENOMEM;
22539 +       sz = sizeof(*brp) * (sbinfo->si_bend + 1);
22540 +       if (unlikely(!sz))
22541 +               sz = sizeof(*brp);
22542 +       brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
22543 +       if (brp) {
22544 +               sbinfo->si_branch = brp;
22545 +               err = 0;
22546 +       }
22547 +
22548 +       return err;
22549 +}
22550 +
22551 +/* ---------------------------------------------------------------------- */
22552 +
22553 +unsigned int au_sigen_inc(struct super_block *sb)
22554 +{
22555 +       unsigned int gen;
22556 +
22557 +       SiMustWriteLock(sb);
22558 +
22559 +       gen = ++au_sbi(sb)->si_generation;
22560 +       au_update_digen(sb->s_root);
22561 +       au_update_iigen(sb->s_root->d_inode, /*half*/0);
22562 +       sb->s_root->d_inode->i_version++;
22563 +       return gen;
22564 +}
22565 +
22566 +aufs_bindex_t au_new_br_id(struct super_block *sb)
22567 +{
22568 +       aufs_bindex_t br_id;
22569 +       int i;
22570 +       struct au_sbinfo *sbinfo;
22571 +
22572 +       SiMustWriteLock(sb);
22573 +
22574 +       sbinfo = au_sbi(sb);
22575 +       for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
22576 +               br_id = ++sbinfo->si_last_br_id;
22577 +               AuDebugOn(br_id < 0);
22578 +               if (br_id && au_br_index(sb, br_id) < 0)
22579 +                       return br_id;
22580 +       }
22581 +
22582 +       return -1;
22583 +}
22584 +
22585 +/* ---------------------------------------------------------------------- */
22586 +
22587 +/* it is ok that new 'nwt' tasks are appended while we are sleeping */
22588 +int si_read_lock(struct super_block *sb, int flags)
22589 +{
22590 +       int err;
22591 +
22592 +       err = 0;
22593 +       if (au_ftest_lock(flags, FLUSH))
22594 +               au_nwt_flush(&au_sbi(sb)->si_nowait);
22595 +
22596 +       si_noflush_read_lock(sb);
22597 +       err = au_plink_maint(sb, flags);
22598 +       if (unlikely(err))
22599 +               si_read_unlock(sb);
22600 +
22601 +       return err;
22602 +}
22603 +
22604 +int si_write_lock(struct super_block *sb, int flags)
22605 +{
22606 +       int err;
22607 +
22608 +       if (au_ftest_lock(flags, FLUSH))
22609 +               au_nwt_flush(&au_sbi(sb)->si_nowait);
22610 +
22611 +       si_noflush_write_lock(sb);
22612 +       err = au_plink_maint(sb, flags);
22613 +       if (unlikely(err))
22614 +               si_write_unlock(sb);
22615 +
22616 +       return err;
22617 +}
22618 +
22619 +/* dentry and super_block lock. call at entry point */
22620 +int aufs_read_lock(struct dentry *dentry, int flags)
22621 +{
22622 +       int err;
22623 +       struct super_block *sb;
22624 +
22625 +       sb = dentry->d_sb;
22626 +       err = si_read_lock(sb, flags);
22627 +       if (unlikely(err))
22628 +               goto out;
22629 +
22630 +       if (au_ftest_lock(flags, DW))
22631 +               di_write_lock_child(dentry);
22632 +       else
22633 +               di_read_lock_child(dentry, flags);
22634 +
22635 +       if (au_ftest_lock(flags, GEN)) {
22636 +               err = au_digen_test(dentry, au_sigen(sb));
22637 +               AuDebugOn(!err && au_dbrange_test(dentry));
22638 +               if (unlikely(err))
22639 +                       aufs_read_unlock(dentry, flags);
22640 +       }
22641 +
22642 +out:
22643 +       return err;
22644 +}
22645 +
22646 +void aufs_read_unlock(struct dentry *dentry, int flags)
22647 +{
22648 +       if (au_ftest_lock(flags, DW))
22649 +               di_write_unlock(dentry);
22650 +       else
22651 +               di_read_unlock(dentry, flags);
22652 +       si_read_unlock(dentry->d_sb);
22653 +}
22654 +
22655 +void aufs_write_lock(struct dentry *dentry)
22656 +{
22657 +       si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
22658 +       di_write_lock_child(dentry);
22659 +}
22660 +
22661 +void aufs_write_unlock(struct dentry *dentry)
22662 +{
22663 +       di_write_unlock(dentry);
22664 +       si_write_unlock(dentry->d_sb);
22665 +}
22666 +
22667 +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
22668 +{
22669 +       int err;
22670 +       unsigned int sigen;
22671 +       struct super_block *sb;
22672 +
22673 +       sb = d1->d_sb;
22674 +       err = si_read_lock(sb, flags);
22675 +       if (unlikely(err))
22676 +               goto out;
22677 +
22678 +       di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
22679 +
22680 +       if (au_ftest_lock(flags, GEN)) {
22681 +               sigen = au_sigen(sb);
22682 +               err = au_digen_test(d1, sigen);
22683 +               AuDebugOn(!err && au_dbrange_test(d1));
22684 +               if (!err) {
22685 +                       err = au_digen_test(d2, sigen);
22686 +                       AuDebugOn(!err && au_dbrange_test(d2));
22687 +               }
22688 +               if (unlikely(err))
22689 +                       aufs_read_and_write_unlock2(d1, d2);
22690 +       }
22691 +
22692 +out:
22693 +       return err;
22694 +}
22695 +
22696 +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
22697 +{
22698 +       di_write_unlock2(d1, d2);
22699 +       si_read_unlock(d1->d_sb);
22700 +}
22701 +
22702 +/* ---------------------------------------------------------------------- */
22703 +
22704 +int si_pid_test_slow(struct super_block *sb)
22705 +{
22706 +       void *p;
22707 +
22708 +       rcu_read_lock();
22709 +       p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
22710 +       rcu_read_unlock();
22711 +
22712 +       return (long)!!p;
22713 +}
22714 +
22715 +void si_pid_set_slow(struct super_block *sb)
22716 +{
22717 +       int err;
22718 +       struct au_sbinfo *sbinfo;
22719 +
22720 +       AuDebugOn(si_pid_test_slow(sb));
22721 +
22722 +       sbinfo = au_sbi(sb);
22723 +       err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
22724 +       AuDebugOn(err);
22725 +       spin_lock(&sbinfo->au_si_pid.tree_lock);
22726 +       err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
22727 +                               /*any valid ptr*/sb);
22728 +       spin_unlock(&sbinfo->au_si_pid.tree_lock);
22729 +       AuDebugOn(err);
22730 +       radix_tree_preload_end();
22731 +}
22732 +
22733 +void si_pid_clr_slow(struct super_block *sb)
22734 +{
22735 +       void *p;
22736 +       struct au_sbinfo *sbinfo;
22737 +
22738 +       AuDebugOn(!si_pid_test_slow(sb));
22739 +
22740 +       sbinfo = au_sbi(sb);
22741 +       spin_lock(&sbinfo->au_si_pid.tree_lock);
22742 +       p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
22743 +       spin_unlock(&sbinfo->au_si_pid.tree_lock);
22744 +}
22745 diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
22746 --- /usr/share/empty/fs/aufs/spl.h      1970-01-01 01:00:00.000000000 +0100
22747 +++ linux/fs/aufs/spl.h 2013-01-11 19:46:12.639281345 +0100
22748 @@ -0,0 +1,62 @@
22749 +/*
22750 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22751 + *
22752 + * This program, aufs is free software; you can redistribute it and/or modify
22753 + * it under the terms of the GNU General Public License as published by
22754 + * the Free Software Foundation; either version 2 of the License, or
22755 + * (at your option) any later version.
22756 + *
22757 + * This program is distributed in the hope that it will be useful,
22758 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22759 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22760 + * GNU General Public License for more details.
22761 + *
22762 + * You should have received a copy of the GNU General Public License
22763 + * along with this program; if not, write to the Free Software
22764 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22765 + */
22766 +
22767 +/*
22768 + * simple list protected by a spinlock
22769 + */
22770 +
22771 +#ifndef __AUFS_SPL_H__
22772 +#define __AUFS_SPL_H__
22773 +
22774 +#ifdef __KERNEL__
22775 +
22776 +struct au_splhead {
22777 +       spinlock_t              spin;
22778 +       struct list_head        head;
22779 +};
22780 +
22781 +static inline void au_spl_init(struct au_splhead *spl)
22782 +{
22783 +       spin_lock_init(&spl->spin);
22784 +       INIT_LIST_HEAD(&spl->head);
22785 +}
22786 +
22787 +static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
22788 +{
22789 +       spin_lock(&spl->spin);
22790 +       list_add(list, &spl->head);
22791 +       spin_unlock(&spl->spin);
22792 +}
22793 +
22794 +static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
22795 +{
22796 +       spin_lock(&spl->spin);
22797 +       list_del(list);
22798 +       spin_unlock(&spl->spin);
22799 +}
22800 +
22801 +static inline void au_spl_del_rcu(struct list_head *list,
22802 +                                 struct au_splhead *spl)
22803 +{
22804 +       spin_lock(&spl->spin);
22805 +       list_del_rcu(list);
22806 +       spin_unlock(&spl->spin);
22807 +}
22808 +
22809 +#endif /* __KERNEL__ */
22810 +#endif /* __AUFS_SPL_H__ */
22811 diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
22812 --- /usr/share/empty/fs/aufs/super.c    1970-01-01 01:00:00.000000000 +0100
22813 +++ linux/fs/aufs/super.c       2013-01-11 19:46:12.639281345 +0100
22814 @@ -0,0 +1,993 @@
22815 +/*
22816 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22817 + *
22818 + * This program, aufs is free software; you can redistribute it and/or modify
22819 + * it under the terms of the GNU General Public License as published by
22820 + * the Free Software Foundation; either version 2 of the License, or
22821 + * (at your option) any later version.
22822 + *
22823 + * This program is distributed in the hope that it will be useful,
22824 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22825 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22826 + * GNU General Public License for more details.
22827 + *
22828 + * You should have received a copy of the GNU General Public License
22829 + * along with this program; if not, write to the Free Software
22830 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22831 + */
22832 +
22833 +/*
22834 + * mount and super_block operations
22835 + */
22836 +
22837 +#include <linux/mm.h>
22838 +#include <linux/module.h>
22839 +#include <linux/seq_file.h>
22840 +#include <linux/statfs.h>
22841 +#include <linux/vmalloc.h>
22842 +#include <linux/writeback.h>
22843 +#include "aufs.h"
22844 +
22845 +/*
22846 + * super_operations
22847 + */
22848 +static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
22849 +{
22850 +       struct au_icntnr *c;
22851 +
22852 +       c = au_cache_alloc_icntnr();
22853 +       if (c) {
22854 +               au_icntnr_init(c);
22855 +               c->vfs_inode.i_version = 1; /* sigen(sb); */
22856 +               c->iinfo.ii_hinode = NULL;
22857 +               return &c->vfs_inode;
22858 +       }
22859 +       return NULL;
22860 +}
22861 +
22862 +static void aufs_destroy_inode_cb(struct rcu_head *head)
22863 +{
22864 +       struct inode *inode = container_of(head, struct inode, i_rcu);
22865 +
22866 +       INIT_HLIST_HEAD(&inode->i_dentry);
22867 +       au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
22868 +}
22869 +
22870 +static void aufs_destroy_inode(struct inode *inode)
22871 +{
22872 +       au_iinfo_fin(inode);
22873 +       call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
22874 +}
22875 +
22876 +struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
22877 +{
22878 +       struct inode *inode;
22879 +       int err;
22880 +
22881 +       inode = iget_locked(sb, ino);
22882 +       if (unlikely(!inode)) {
22883 +               inode = ERR_PTR(-ENOMEM);
22884 +               goto out;
22885 +       }
22886 +       if (!(inode->i_state & I_NEW))
22887 +               goto out;
22888 +
22889 +       err = au_xigen_new(inode);
22890 +       if (!err)
22891 +               err = au_iinfo_init(inode);
22892 +       if (!err)
22893 +               inode->i_version++;
22894 +       else {
22895 +               iget_failed(inode);
22896 +               inode = ERR_PTR(err);
22897 +       }
22898 +
22899 +out:
22900 +       /* never return NULL */
22901 +       AuDebugOn(!inode);
22902 +       AuTraceErrPtr(inode);
22903 +       return inode;
22904 +}
22905 +
22906 +/* lock free root dinfo */
22907 +static int au_show_brs(struct seq_file *seq, struct super_block *sb)
22908 +{
22909 +       int err;
22910 +       aufs_bindex_t bindex, bend;
22911 +       struct path path;
22912 +       struct au_hdentry *hdp;
22913 +       struct au_branch *br;
22914 +       char *perm;
22915 +
22916 +       err = 0;
22917 +       bend = au_sbend(sb);
22918 +       hdp = au_di(sb->s_root)->di_hdentry;
22919 +       for (bindex = 0; !err && bindex <= bend; bindex++) {
22920 +               br = au_sbr(sb, bindex);
22921 +               path.mnt = br->br_mnt;
22922 +               path.dentry = hdp[bindex].hd_dentry;
22923 +               err = au_seq_path(seq, &path);
22924 +               if (err > 0) {
22925 +                       perm = au_optstr_br_perm(br->br_perm);
22926 +                       if (perm) {
22927 +                               err = seq_printf(seq, "=%s", perm);
22928 +                               kfree(perm);
22929 +                               if (err == -1)
22930 +                                       err = -E2BIG;
22931 +                       } else
22932 +                               err = -ENOMEM;
22933 +               }
22934 +               if (!err && bindex != bend)
22935 +                       err = seq_putc(seq, ':');
22936 +       }
22937 +
22938 +       return err;
22939 +}
22940 +
22941 +static void au_show_wbr_create(struct seq_file *m, int v,
22942 +                              struct au_sbinfo *sbinfo)
22943 +{
22944 +       const char *pat;
22945 +
22946 +       AuRwMustAnyLock(&sbinfo->si_rwsem);
22947 +
22948 +       seq_printf(m, ",create=");
22949 +       pat = au_optstr_wbr_create(v);
22950 +       switch (v) {
22951 +       case AuWbrCreate_TDP:
22952 +       case AuWbrCreate_RR:
22953 +       case AuWbrCreate_MFS:
22954 +       case AuWbrCreate_PMFS:
22955 +               seq_printf(m, pat);
22956 +               break;
22957 +       case AuWbrCreate_MFSV:
22958 +               seq_printf(m, /*pat*/"mfs:%lu",
22959 +                          jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
22960 +                          / MSEC_PER_SEC);
22961 +               break;
22962 +       case AuWbrCreate_PMFSV:
22963 +               seq_printf(m, /*pat*/"pmfs:%lu",
22964 +                          jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
22965 +                          / MSEC_PER_SEC);
22966 +               break;
22967 +       case AuWbrCreate_MFSRR:
22968 +               seq_printf(m, /*pat*/"mfsrr:%llu",
22969 +                          sbinfo->si_wbr_mfs.mfsrr_watermark);
22970 +               break;
22971 +       case AuWbrCreate_MFSRRV:
22972 +               seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
22973 +                          sbinfo->si_wbr_mfs.mfsrr_watermark,
22974 +                          jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
22975 +                          / MSEC_PER_SEC);
22976 +               break;
22977 +       }
22978 +}
22979 +
22980 +static int au_show_xino(struct seq_file *seq, struct super_block *sb)
22981 +{
22982 +#ifdef CONFIG_SYSFS
22983 +       return 0;
22984 +#else
22985 +       int err;
22986 +       const int len = sizeof(AUFS_XINO_FNAME) - 1;
22987 +       aufs_bindex_t bindex, brid;
22988 +       struct qstr *name;
22989 +       struct file *f;
22990 +       struct dentry *d, *h_root;
22991 +       struct au_hdentry *hdp;
22992 +
22993 +       AuRwMustAnyLock(&sbinfo->si_rwsem);
22994 +
22995 +       err = 0;
22996 +       f = au_sbi(sb)->si_xib;
22997 +       if (!f)
22998 +               goto out;
22999 +
23000 +       /* stop printing the default xino path on the first writable branch */
23001 +       h_root = NULL;
23002 +       brid = au_xino_brid(sb);
23003 +       if (brid >= 0) {
23004 +               bindex = au_br_index(sb, brid);
23005 +               hdp = au_di(sb->s_root)->di_hdentry;
23006 +               h_root = hdp[0 + bindex].hd_dentry;
23007 +       }
23008 +       d = f->f_dentry;
23009 +       name = &d->d_name;
23010 +       /* safe ->d_parent because the file is unlinked */
23011 +       if (d->d_parent == h_root
23012 +           && name->len == len
23013 +           && !memcmp(name->name, AUFS_XINO_FNAME, len))
23014 +               goto out;
23015 +
23016 +       seq_puts(seq, ",xino=");
23017 +       err = au_xino_path(seq, f);
23018 +
23019 +out:
23020 +       return err;
23021 +#endif
23022 +}
23023 +
23024 +/* seq_file will re-call me in case of too long string */
23025 +static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
23026 +{
23027 +       int err;
23028 +       unsigned int mnt_flags, v;
23029 +       struct super_block *sb;
23030 +       struct au_sbinfo *sbinfo;
23031 +
23032 +#define AuBool(name, str) do { \
23033 +       v = au_opt_test(mnt_flags, name); \
23034 +       if (v != au_opt_test(AuOpt_Def, name)) \
23035 +               seq_printf(m, ",%s" #str, v ? "" : "no"); \
23036 +} while (0)
23037 +
23038 +#define AuStr(name, str) do { \
23039 +       v = mnt_flags & AuOptMask_##name; \
23040 +       if (v != (AuOpt_Def & AuOptMask_##name)) \
23041 +               seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
23042 +} while (0)
23043 +
23044 +#define AuUInt(name, str, val) do { \
23045 +       if (val != AUFS_##name##_DEF) \
23046 +               seq_printf(m, "," #str "=%u", val); \
23047 +} while (0)
23048 +
23049 +       /* lock free root dinfo */
23050 +       sb = dentry->d_sb;
23051 +       si_noflush_read_lock(sb);
23052 +       sbinfo = au_sbi(sb);
23053 +       seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
23054 +
23055 +       mnt_flags = au_mntflags(sb);
23056 +       if (au_opt_test(mnt_flags, XINO)) {
23057 +               err = au_show_xino(m, sb);
23058 +               if (unlikely(err))
23059 +                       goto out;
23060 +       } else
23061 +               seq_puts(m, ",noxino");
23062 +
23063 +       AuBool(TRUNC_XINO, trunc_xino);
23064 +       AuStr(UDBA, udba);
23065 +       AuBool(SHWH, shwh);
23066 +       AuBool(PLINK, plink);
23067 +       AuBool(DIO, dio);
23068 +       /* AuBool(DIRPERM1, dirperm1); */
23069 +       /* AuBool(REFROF, refrof); */
23070 +
23071 +       v = sbinfo->si_wbr_create;
23072 +       if (v != AuWbrCreate_Def)
23073 +               au_show_wbr_create(m, v, sbinfo);
23074 +
23075 +       v = sbinfo->si_wbr_copyup;
23076 +       if (v != AuWbrCopyup_Def)
23077 +               seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
23078 +
23079 +       v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
23080 +       if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
23081 +               seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
23082 +
23083 +       AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
23084 +
23085 +       v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
23086 +       AuUInt(RDCACHE, rdcache, v);
23087 +
23088 +       AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
23089 +       AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
23090 +
23091 +       AuBool(SUM, sum);
23092 +       /* AuBool(SUM_W, wsum); */
23093 +       AuBool(WARN_PERM, warn_perm);
23094 +       AuBool(VERBOSE, verbose);
23095 +
23096 +out:
23097 +       /* be sure to print "br:" last */
23098 +       if (!sysaufs_brs) {
23099 +               seq_puts(m, ",br:");
23100 +               au_show_brs(m, sb);
23101 +       }
23102 +       si_read_unlock(sb);
23103 +       return 0;
23104 +
23105 +#undef AuBool
23106 +#undef AuStr
23107 +#undef AuUInt
23108 +}
23109 +
23110 +/* ---------------------------------------------------------------------- */
23111 +
23112 +/* sum mode which returns the summation for statfs(2) */
23113 +
23114 +static u64 au_add_till_max(u64 a, u64 b)
23115 +{
23116 +       u64 old;
23117 +
23118 +       old = a;
23119 +       a += b;
23120 +       if (old <= a)
23121 +               return a;
23122 +       return ULLONG_MAX;
23123 +}
23124 +
23125 +static u64 au_mul_till_max(u64 a, long mul)
23126 +{
23127 +       u64 old;
23128 +
23129 +       old = a;
23130 +       a *= mul;
23131 +       if (old <= a)
23132 +               return a;
23133 +       return ULLONG_MAX;
23134 +}
23135 +
23136 +static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
23137 +{
23138 +       int err;
23139 +       long bsize, factor;
23140 +       u64 blocks, bfree, bavail, files, ffree;
23141 +       aufs_bindex_t bend, bindex, i;
23142 +       unsigned char shared;
23143 +       struct path h_path;
23144 +       struct super_block *h_sb;
23145 +
23146 +       err = 0;
23147 +       bsize = LONG_MAX;
23148 +       files = 0;
23149 +       ffree = 0;
23150 +       blocks = 0;
23151 +       bfree = 0;
23152 +       bavail = 0;
23153 +       bend = au_sbend(sb);
23154 +       for (bindex = 0; bindex <= bend; bindex++) {
23155 +               h_path.mnt = au_sbr_mnt(sb, bindex);
23156 +               h_sb = h_path.mnt->mnt_sb;
23157 +               shared = 0;
23158 +               for (i = 0; !shared && i < bindex; i++)
23159 +                       shared = (au_sbr_sb(sb, i) == h_sb);
23160 +               if (shared)
23161 +                       continue;
23162 +
23163 +               /* sb->s_root for NFS is unreliable */
23164 +               h_path.dentry = h_path.mnt->mnt_root;
23165 +               err = vfs_statfs(&h_path, buf);
23166 +               if (unlikely(err))
23167 +                       goto out;
23168 +
23169 +               if (bsize > buf->f_bsize) {
23170 +                       /*
23171 +                        * we will reduce bsize, so we have to expand blocks
23172 +                        * etc. to match them again
23173 +                        */
23174 +                       factor = (bsize / buf->f_bsize);
23175 +                       blocks = au_mul_till_max(blocks, factor);
23176 +                       bfree = au_mul_till_max(bfree, factor);
23177 +                       bavail = au_mul_till_max(bavail, factor);
23178 +                       bsize = buf->f_bsize;
23179 +               }
23180 +
23181 +               factor = (buf->f_bsize / bsize);
23182 +               blocks = au_add_till_max(blocks,
23183 +                               au_mul_till_max(buf->f_blocks, factor));
23184 +               bfree = au_add_till_max(bfree,
23185 +                               au_mul_till_max(buf->f_bfree, factor));
23186 +               bavail = au_add_till_max(bavail,
23187 +                               au_mul_till_max(buf->f_bavail, factor));
23188 +               files = au_add_till_max(files, buf->f_files);
23189 +               ffree = au_add_till_max(ffree, buf->f_ffree);
23190 +       }
23191 +
23192 +       buf->f_bsize = bsize;
23193 +       buf->f_blocks = blocks;
23194 +       buf->f_bfree = bfree;
23195 +       buf->f_bavail = bavail;
23196 +       buf->f_files = files;
23197 +       buf->f_ffree = ffree;
23198 +       buf->f_frsize = 0;
23199 +
23200 +out:
23201 +       return err;
23202 +}
23203 +
23204 +static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
23205 +{
23206 +       int err;
23207 +       struct path h_path;
23208 +       struct super_block *sb;
23209 +
23210 +       /* lock free root dinfo */
23211 +       sb = dentry->d_sb;
23212 +       si_noflush_read_lock(sb);
23213 +       if (!au_opt_test(au_mntflags(sb), SUM)) {
23214 +               /* sb->s_root for NFS is unreliable */
23215 +               h_path.mnt = au_sbr_mnt(sb, 0);
23216 +               h_path.dentry = h_path.mnt->mnt_root;
23217 +               err = vfs_statfs(&h_path, buf);
23218 +       } else
23219 +               err = au_statfs_sum(sb, buf);
23220 +       si_read_unlock(sb);
23221 +
23222 +       if (!err) {
23223 +               buf->f_type = AUFS_SUPER_MAGIC;
23224 +               buf->f_namelen = AUFS_MAX_NAMELEN;
23225 +               memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
23226 +       }
23227 +       /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
23228 +
23229 +       return err;
23230 +}
23231 +
23232 +/* ---------------------------------------------------------------------- */
23233 +
23234 +static int aufs_sync_fs(struct super_block *sb, int wait)
23235 +{
23236 +       int err, e;
23237 +       aufs_bindex_t bend, bindex;
23238 +       struct au_branch *br;
23239 +       struct super_block *h_sb;
23240 +
23241 +       err = 0;
23242 +       si_noflush_read_lock(sb);
23243 +       bend = au_sbend(sb);
23244 +       for (bindex = 0; bindex <= bend; bindex++) {
23245 +               br = au_sbr(sb, bindex);
23246 +               if (!au_br_writable(br->br_perm))
23247 +                       continue;
23248 +
23249 +               h_sb = au_sbr_sb(sb, bindex);
23250 +               if (h_sb->s_op->sync_fs) {
23251 +                       e = h_sb->s_op->sync_fs(h_sb, wait);
23252 +                       if (unlikely(e && !err))
23253 +                               err = e;
23254 +                       /* go on even if an error happens */
23255 +               }
23256 +       }
23257 +       si_read_unlock(sb);
23258 +
23259 +       return err;
23260 +}
23261 +
23262 +/* ---------------------------------------------------------------------- */
23263 +
23264 +/* final actions when unmounting a file system */
23265 +static void aufs_put_super(struct super_block *sb)
23266 +{
23267 +       struct au_sbinfo *sbinfo;
23268 +
23269 +       sbinfo = au_sbi(sb);
23270 +       if (!sbinfo)
23271 +               return;
23272 +
23273 +       dbgaufs_si_fin(sbinfo);
23274 +       kobject_put(&sbinfo->si_kobj);
23275 +}
23276 +
23277 +/* ---------------------------------------------------------------------- */
23278 +
23279 +void au_array_free(void *array)
23280 +{
23281 +       if (array) {
23282 +               if (!is_vmalloc_addr(array))
23283 +                       kfree(array);
23284 +               else
23285 +                       vfree(array);
23286 +       }
23287 +}
23288 +
23289 +void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
23290 +{
23291 +       void *array;
23292 +       unsigned long long n;
23293 +
23294 +       array = NULL;
23295 +       n = 0;
23296 +       if (!*hint)
23297 +               goto out;
23298 +
23299 +       if (*hint > ULLONG_MAX / sizeof(array)) {
23300 +               array = ERR_PTR(-EMFILE);
23301 +               pr_err("hint %llu\n", *hint);
23302 +               goto out;
23303 +       }
23304 +
23305 +       array = kmalloc(sizeof(array) * *hint, GFP_NOFS);
23306 +       if (unlikely(!array))
23307 +               array = vmalloc(sizeof(array) * *hint);
23308 +       if (unlikely(!array)) {
23309 +               array = ERR_PTR(-ENOMEM);
23310 +               goto out;
23311 +       }
23312 +
23313 +       n = cb(array, *hint, arg);
23314 +       AuDebugOn(n > *hint);
23315 +
23316 +out:
23317 +       *hint = n;
23318 +       return array;
23319 +}
23320 +
23321 +static unsigned long long au_iarray_cb(void *a,
23322 +                                      unsigned long long max __maybe_unused,
23323 +                                      void *arg)
23324 +{
23325 +       unsigned long long n;
23326 +       struct inode **p, *inode;
23327 +       struct list_head *head;
23328 +
23329 +       n = 0;
23330 +       p = a;
23331 +       head = arg;
23332 +       spin_lock(&inode_sb_list_lock);
23333 +       list_for_each_entry(inode, head, i_sb_list) {
23334 +               if (!is_bad_inode(inode)
23335 +                   && au_ii(inode)->ii_bstart >= 0) {
23336 +                       spin_lock(&inode->i_lock);
23337 +                       if (atomic_read(&inode->i_count)) {
23338 +                               au_igrab(inode);
23339 +                               *p++ = inode;
23340 +                               n++;
23341 +                               AuDebugOn(n > max);
23342 +                       }
23343 +                       spin_unlock(&inode->i_lock);
23344 +               }
23345 +       }
23346 +       spin_unlock(&inode_sb_list_lock);
23347 +
23348 +       return n;
23349 +}
23350 +
23351 +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
23352 +{
23353 +       *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
23354 +       return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
23355 +}
23356 +
23357 +void au_iarray_free(struct inode **a, unsigned long long max)
23358 +{
23359 +       unsigned long long ull;
23360 +
23361 +       for (ull = 0; ull < max; ull++)
23362 +               iput(a[ull]);
23363 +       au_array_free(a);
23364 +}
23365 +
23366 +/* ---------------------------------------------------------------------- */
23367 +
23368 +/*
23369 + * refresh dentry and inode at remount time.
23370 + */
23371 +/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
23372 +static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
23373 +                     struct dentry *parent)
23374 +{
23375 +       int err;
23376 +
23377 +       di_write_lock_child(dentry);
23378 +       di_read_lock_parent(parent, AuLock_IR);
23379 +       err = au_refresh_dentry(dentry, parent);
23380 +       if (!err && dir_flags)
23381 +               au_hn_reset(dentry->d_inode, dir_flags);
23382 +       di_read_unlock(parent, AuLock_IR);
23383 +       di_write_unlock(dentry);
23384 +
23385 +       return err;
23386 +}
23387 +
23388 +static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
23389 +                          struct au_sbinfo *sbinfo,
23390 +                          const unsigned int dir_flags)
23391 +{
23392 +       int err;
23393 +       struct dentry *parent;
23394 +       struct inode *inode;
23395 +
23396 +       err = 0;
23397 +       parent = dget_parent(dentry);
23398 +       if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
23399 +               inode = dentry->d_inode;
23400 +               if (inode) {
23401 +                       if (!S_ISDIR(inode->i_mode))
23402 +                               err = au_do_refresh(dentry, /*dir_flags*/0,
23403 +                                                parent);
23404 +                       else {
23405 +                               err = au_do_refresh(dentry, dir_flags, parent);
23406 +                               if (unlikely(err))
23407 +                                       au_fset_si(sbinfo, FAILED_REFRESH_DIR);
23408 +                       }
23409 +               } else
23410 +                       err = au_do_refresh(dentry, /*dir_flags*/0, parent);
23411 +               AuDbgDentry(dentry);
23412 +       }
23413 +       dput(parent);
23414 +
23415 +       AuTraceErr(err);
23416 +       return err;
23417 +}
23418 +
23419 +static int au_refresh_d(struct super_block *sb)
23420 +{
23421 +       int err, i, j, ndentry, e;
23422 +       unsigned int sigen;
23423 +       struct au_dcsub_pages dpages;
23424 +       struct au_dpage *dpage;
23425 +       struct dentry **dentries, *d;
23426 +       struct au_sbinfo *sbinfo;
23427 +       struct dentry *root = sb->s_root;
23428 +       const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
23429 +
23430 +       err = au_dpages_init(&dpages, GFP_NOFS);
23431 +       if (unlikely(err))
23432 +               goto out;
23433 +       err = au_dcsub_pages(&dpages, root, NULL, NULL);
23434 +       if (unlikely(err))
23435 +               goto out_dpages;
23436 +
23437 +       sigen = au_sigen(sb);
23438 +       sbinfo = au_sbi(sb);
23439 +       for (i = 0; i < dpages.ndpage; i++) {
23440 +               dpage = dpages.dpages + i;
23441 +               dentries = dpage->dentries;
23442 +               ndentry = dpage->ndentry;
23443 +               for (j = 0; j < ndentry; j++) {
23444 +                       d = dentries[j];
23445 +                       e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
23446 +                       if (unlikely(e && !err))
23447 +                               err = e;
23448 +                       /* go on even err */
23449 +               }
23450 +       }
23451 +
23452 +out_dpages:
23453 +       au_dpages_free(&dpages);
23454 +out:
23455 +       return err;
23456 +}
23457 +
23458 +static int au_refresh_i(struct super_block *sb)
23459 +{
23460 +       int err, e;
23461 +       unsigned int sigen;
23462 +       unsigned long long max, ull;
23463 +       struct inode *inode, **array;
23464 +
23465 +       array = au_iarray_alloc(sb, &max);
23466 +       err = PTR_ERR(array);
23467 +       if (IS_ERR(array))
23468 +               goto out;
23469 +
23470 +       err = 0;
23471 +       sigen = au_sigen(sb);
23472 +       for (ull = 0; ull < max; ull++) {
23473 +               inode = array[ull];
23474 +               if (au_iigen(inode, NULL) != sigen) {
23475 +                       ii_write_lock_child(inode);
23476 +                       e = au_refresh_hinode_self(inode);
23477 +                       ii_write_unlock(inode);
23478 +                       if (unlikely(e)) {
23479 +                               pr_err("error %d, i%lu\n", e, inode->i_ino);
23480 +                               if (!err)
23481 +                                       err = e;
23482 +                               /* go on even if err */
23483 +                       }
23484 +               }
23485 +       }
23486 +
23487 +       au_iarray_free(array, max);
23488 +
23489 +out:
23490 +       return err;
23491 +}
23492 +
23493 +static void au_remount_refresh(struct super_block *sb)
23494 +{
23495 +       int err, e;
23496 +       unsigned int udba;
23497 +       aufs_bindex_t bindex, bend;
23498 +       struct dentry *root;
23499 +       struct inode *inode;
23500 +       struct au_branch *br;
23501 +
23502 +       au_sigen_inc(sb);
23503 +       au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
23504 +
23505 +       root = sb->s_root;
23506 +       DiMustNoWaiters(root);
23507 +       inode = root->d_inode;
23508 +       IiMustNoWaiters(inode);
23509 +
23510 +       udba = au_opt_udba(sb);
23511 +       bend = au_sbend(sb);
23512 +       for (bindex = 0; bindex <= bend; bindex++) {
23513 +               br = au_sbr(sb, bindex);
23514 +               err = au_hnotify_reset_br(udba, br, br->br_perm);
23515 +               if (unlikely(err))
23516 +                       AuIOErr("hnotify failed on br %d, %d, ignored\n",
23517 +                               bindex, err);
23518 +               /* go on even if err */
23519 +       }
23520 +       au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
23521 +
23522 +       di_write_unlock(root);
23523 +       err = au_refresh_d(sb);
23524 +       e = au_refresh_i(sb);
23525 +       if (unlikely(e && !err))
23526 +               err = e;
23527 +       /* aufs_write_lock() calls ..._child() */
23528 +       di_write_lock_child(root);
23529 +
23530 +       au_cpup_attr_all(inode, /*force*/1);
23531 +
23532 +       if (unlikely(err))
23533 +               AuIOErr("refresh failed, ignored, %d\n", err);
23534 +}
23535 +
23536 +/* stop extra interpretation of errno in mount(8), and strange error messages */
23537 +static int cvt_err(int err)
23538 +{
23539 +       AuTraceErr(err);
23540 +
23541 +       switch (err) {
23542 +       case -ENOENT:
23543 +       case -ENOTDIR:
23544 +       case -EEXIST:
23545 +       case -EIO:
23546 +               err = -EINVAL;
23547 +       }
23548 +       return err;
23549 +}
23550 +
23551 +static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
23552 +{
23553 +       int err, do_dx;
23554 +       unsigned int mntflags;
23555 +       struct au_opts opts;
23556 +       struct dentry *root;
23557 +       struct inode *inode;
23558 +       struct au_sbinfo *sbinfo;
23559 +
23560 +       err = 0;
23561 +       root = sb->s_root;
23562 +       if (!data || !*data) {
23563 +               err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
23564 +               if (!err) {
23565 +                       di_write_lock_child(root);
23566 +                       err = au_opts_verify(sb, *flags, /*pending*/0);
23567 +                       aufs_write_unlock(root);
23568 +               }
23569 +               goto out;
23570 +       }
23571 +
23572 +       err = -ENOMEM;
23573 +       memset(&opts, 0, sizeof(opts));
23574 +       opts.opt = (void *)__get_free_page(GFP_NOFS);
23575 +       if (unlikely(!opts.opt))
23576 +               goto out;
23577 +       opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
23578 +       opts.flags = AuOpts_REMOUNT;
23579 +       opts.sb_flags = *flags;
23580 +
23581 +       /* parse it before aufs lock */
23582 +       err = au_opts_parse(sb, data, &opts);
23583 +       if (unlikely(err))
23584 +               goto out_opts;
23585 +
23586 +       sbinfo = au_sbi(sb);
23587 +       inode = root->d_inode;
23588 +       mutex_lock(&inode->i_mutex);
23589 +       err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
23590 +       if (unlikely(err))
23591 +               goto out_mtx;
23592 +       di_write_lock_child(root);
23593 +
23594 +       /* au_opts_remount() may return an error */
23595 +       err = au_opts_remount(sb, &opts);
23596 +       au_opts_free(&opts);
23597 +
23598 +       if (au_ftest_opts(opts.flags, REFRESH))
23599 +               au_remount_refresh(sb);
23600 +
23601 +       if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
23602 +               mntflags = au_mntflags(sb);
23603 +               do_dx = !!au_opt_test(mntflags, DIO);
23604 +               au_dy_arefresh(do_dx);
23605 +       }
23606 +
23607 +       aufs_write_unlock(root);
23608 +
23609 +out_mtx:
23610 +       mutex_unlock(&inode->i_mutex);
23611 +out_opts:
23612 +       free_page((unsigned long)opts.opt);
23613 +out:
23614 +       err = cvt_err(err);
23615 +       AuTraceErr(err);
23616 +       return err;
23617 +}
23618 +
23619 +static const struct super_operations aufs_sop = {
23620 +       .alloc_inode    = aufs_alloc_inode,
23621 +       .destroy_inode  = aufs_destroy_inode,
23622 +       /* always deleting, no clearing */
23623 +       .drop_inode     = generic_delete_inode,
23624 +       .show_options   = aufs_show_options,
23625 +       .statfs         = aufs_statfs,
23626 +       .put_super      = aufs_put_super,
23627 +       .sync_fs        = aufs_sync_fs,
23628 +       .remount_fs     = aufs_remount_fs
23629 +};
23630 +
23631 +/* ---------------------------------------------------------------------- */
23632 +
23633 +static int alloc_root(struct super_block *sb)
23634 +{
23635 +       int err;
23636 +       struct inode *inode;
23637 +       struct dentry *root;
23638 +
23639 +       err = -ENOMEM;
23640 +       inode = au_iget_locked(sb, AUFS_ROOT_INO);
23641 +       err = PTR_ERR(inode);
23642 +       if (IS_ERR(inode))
23643 +               goto out;
23644 +
23645 +       inode->i_op = &aufs_dir_iop;
23646 +       inode->i_fop = &aufs_dir_fop;
23647 +       inode->i_mode = S_IFDIR;
23648 +       set_nlink(inode, 2);
23649 +       unlock_new_inode(inode);
23650 +
23651 +       root = d_make_root(inode);
23652 +       if (unlikely(!root))
23653 +               goto out;
23654 +       err = PTR_ERR(root);
23655 +       if (IS_ERR(root))
23656 +               goto out;
23657 +
23658 +       err = au_di_init(root);
23659 +       if (!err) {
23660 +               sb->s_root = root;
23661 +               return 0; /* success */
23662 +       }
23663 +       dput(root);
23664 +
23665 +out:
23666 +       return err;
23667 +}
23668 +
23669 +static int aufs_fill_super(struct super_block *sb, void *raw_data,
23670 +                          int silent __maybe_unused)
23671 +{
23672 +       int err;
23673 +       struct au_opts opts;
23674 +       struct dentry *root;
23675 +       struct inode *inode;
23676 +       char *arg = raw_data;
23677 +
23678 +       if (unlikely(!arg || !*arg)) {
23679 +               err = -EINVAL;
23680 +               pr_err("no arg\n");
23681 +               goto out;
23682 +       }
23683 +
23684 +       err = -ENOMEM;
23685 +       memset(&opts, 0, sizeof(opts));
23686 +       opts.opt = (void *)__get_free_page(GFP_NOFS);
23687 +       if (unlikely(!opts.opt))
23688 +               goto out;
23689 +       opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
23690 +       opts.sb_flags = sb->s_flags;
23691 +
23692 +       err = au_si_alloc(sb);
23693 +       if (unlikely(err))
23694 +               goto out_opts;
23695 +
23696 +       /* all timestamps always follow the ones on the branch */
23697 +       sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
23698 +       sb->s_op = &aufs_sop;
23699 +       sb->s_d_op = &aufs_dop;
23700 +       sb->s_magic = AUFS_SUPER_MAGIC;
23701 +       sb->s_maxbytes = 0;
23702 +       au_export_init(sb);
23703 +
23704 +       err = alloc_root(sb);
23705 +       if (unlikely(err)) {
23706 +               si_write_unlock(sb);
23707 +               goto out_info;
23708 +       }
23709 +       root = sb->s_root;
23710 +       inode = root->d_inode;
23711 +
23712 +       /*
23713 +        * actually we can parse options regardless aufs lock here.
23714 +        * but at remount time, parsing must be done before aufs lock.
23715 +        * so we follow the same rule.
23716 +        */
23717 +       ii_write_lock_parent(inode);
23718 +       aufs_write_unlock(root);
23719 +       err = au_opts_parse(sb, arg, &opts);
23720 +       if (unlikely(err))
23721 +               goto out_root;
23722 +
23723 +       /* lock vfs_inode first, then aufs. */
23724 +       mutex_lock(&inode->i_mutex);
23725 +       aufs_write_lock(root);
23726 +       err = au_opts_mount(sb, &opts);
23727 +       au_opts_free(&opts);
23728 +       aufs_write_unlock(root);
23729 +       mutex_unlock(&inode->i_mutex);
23730 +       if (!err)
23731 +               goto out_opts; /* success */
23732 +
23733 +out_root:
23734 +       dput(root);
23735 +       sb->s_root = NULL;
23736 +out_info:
23737 +       dbgaufs_si_fin(au_sbi(sb));
23738 +       kobject_put(&au_sbi(sb)->si_kobj);
23739 +       sb->s_fs_info = NULL;
23740 +out_opts:
23741 +       free_page((unsigned long)opts.opt);
23742 +out:
23743 +       AuTraceErr(err);
23744 +       err = cvt_err(err);
23745 +       AuTraceErr(err);
23746 +       return err;
23747 +}
23748 +
23749 +/* ---------------------------------------------------------------------- */
23750 +
23751 +static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
23752 +                                const char *dev_name __maybe_unused,
23753 +                                void *raw_data)
23754 +{
23755 +       struct dentry *root;
23756 +       struct super_block *sb;
23757 +
23758 +       /* all timestamps always follow the ones on the branch */
23759 +       /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
23760 +       root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
23761 +       if (IS_ERR(root))
23762 +               goto out;
23763 +
23764 +       sb = root->d_sb;
23765 +       si_write_lock(sb, !AuLock_FLUSH);
23766 +       sysaufs_brs_add(sb, 0);
23767 +       si_write_unlock(sb);
23768 +       au_sbilist_add(sb);
23769 +
23770 +out:
23771 +       return root;
23772 +}
23773 +
23774 +static void aufs_kill_sb(struct super_block *sb)
23775 +{
23776 +       struct au_sbinfo *sbinfo;
23777 +
23778 +       sbinfo = au_sbi(sb);
23779 +       if (sbinfo) {
23780 +               au_sbilist_del(sb);
23781 +               aufs_write_lock(sb->s_root);
23782 +               if (sbinfo->si_wbr_create_ops->fin)
23783 +                       sbinfo->si_wbr_create_ops->fin(sb);
23784 +               if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
23785 +                       au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
23786 +                       au_remount_refresh(sb);
23787 +               }
23788 +               if (au_opt_test(sbinfo->si_mntflags, PLINK))
23789 +                       au_plink_put(sb, /*verbose*/1);
23790 +               au_xino_clr(sb);
23791 +               sbinfo->si_sb = NULL;
23792 +               aufs_write_unlock(sb->s_root);
23793 +               au_nwt_flush(&sbinfo->si_nowait);
23794 +       }
23795 +       generic_shutdown_super(sb);
23796 +}
23797 +
23798 +struct file_system_type aufs_fs_type = {
23799 +       .name           = AUFS_FSTYPE,
23800 +       .fs_flags       =
23801 +               FS_RENAME_DOES_D_MOVE   /* a race between rename and others */
23802 +               | FS_REVAL_DOT,         /* for NFS branch and udba */
23803 +       .mount          = aufs_mount,
23804 +       .kill_sb        = aufs_kill_sb,
23805 +       /* no need to __module_get() and module_put(). */
23806 +       .owner          = THIS_MODULE,
23807 +};
23808 diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
23809 --- /usr/share/empty/fs/aufs/super.h    1970-01-01 01:00:00.000000000 +0100
23810 +++ linux/fs/aufs/super.h       2013-01-11 19:46:12.639281345 +0100
23811 @@ -0,0 +1,546 @@
23812 +/*
23813 + * Copyright (C) 2005-2013 Junjiro R. Okajima
23814 + *
23815 + * This program, aufs is free software; you can redistribute it and/or modify
23816 + * it under the terms of the GNU General Public License as published by
23817 + * the Free Software Foundation; either version 2 of the License, or
23818 + * (at your option) any later version.
23819 + *
23820 + * This program is distributed in the hope that it will be useful,
23821 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23822 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23823 + * GNU General Public License for more details.
23824 + *
23825 + * You should have received a copy of the GNU General Public License
23826 + * along with this program; if not, write to the Free Software
23827 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23828 + */
23829 +
23830 +/*
23831 + * super_block operations
23832 + */
23833 +
23834 +#ifndef __AUFS_SUPER_H__
23835 +#define __AUFS_SUPER_H__
23836 +
23837 +#ifdef __KERNEL__
23838 +
23839 +#include <linux/fs.h>
23840 +#include "rwsem.h"
23841 +#include "spl.h"
23842 +#include "wkq.h"
23843 +
23844 +typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
23845 +typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
23846 +                              loff_t *);
23847 +
23848 +/* policies to select one among multiple writable branches */
23849 +struct au_wbr_copyup_operations {
23850 +       int (*copyup)(struct dentry *dentry);
23851 +};
23852 +
23853 +struct au_wbr_create_operations {
23854 +       int (*create)(struct dentry *dentry, int isdir);
23855 +       int (*init)(struct super_block *sb);
23856 +       int (*fin)(struct super_block *sb);
23857 +};
23858 +
23859 +struct au_wbr_mfs {
23860 +       struct mutex    mfs_lock; /* protect this structure */
23861 +       unsigned long   mfs_jiffy;
23862 +       unsigned long   mfs_expire;
23863 +       aufs_bindex_t   mfs_bindex;
23864 +
23865 +       unsigned long long      mfsrr_bytes;
23866 +       unsigned long long      mfsrr_watermark;
23867 +};
23868 +
23869 +struct au_branch;
23870 +struct au_sbinfo {
23871 +       /* nowait tasks in the system-wide workqueue */
23872 +       struct au_nowait_tasks  si_nowait;
23873 +
23874 +       /*
23875 +        * tried sb->s_umount, but failed due to the dependecy between i_mutex.
23876 +        * rwsem for au_sbinfo is necessary.
23877 +        */
23878 +       struct au_rwsem         si_rwsem;
23879 +
23880 +       /* prevent recursive locking in deleting inode */
23881 +       struct {
23882 +               unsigned long           *bitmap;
23883 +               spinlock_t              tree_lock;
23884 +               struct radix_tree_root  tree;
23885 +       } au_si_pid;
23886 +
23887 +       /*
23888 +        * dirty approach to protect sb->sb_inodes and ->s_files from remount.
23889 +        */
23890 +       atomic_long_t           si_ninodes, si_nfiles;
23891 +
23892 +       /* branch management */
23893 +       unsigned int            si_generation;
23894 +
23895 +       /* see above flags */
23896 +       unsigned char           au_si_status;
23897 +
23898 +       aufs_bindex_t           si_bend;
23899 +
23900 +       /* dirty trick to keep br_id plus */
23901 +       unsigned int            si_last_br_id :
23902 +                               sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
23903 +       struct au_branch        **si_branch;
23904 +
23905 +       /* policy to select a writable branch */
23906 +       unsigned char           si_wbr_copyup;
23907 +       unsigned char           si_wbr_create;
23908 +       struct au_wbr_copyup_operations *si_wbr_copyup_ops;
23909 +       struct au_wbr_create_operations *si_wbr_create_ops;
23910 +
23911 +       /* round robin */
23912 +       atomic_t                si_wbr_rr_next;
23913 +
23914 +       /* most free space */
23915 +       struct au_wbr_mfs       si_wbr_mfs;
23916 +
23917 +       /* mount flags */
23918 +       /* include/asm-ia64/siginfo.h defines a macro named si_flags */
23919 +       unsigned int            si_mntflags;
23920 +
23921 +       /* external inode number (bitmap and translation table) */
23922 +       au_readf_t              si_xread;
23923 +       au_writef_t             si_xwrite;
23924 +       struct file             *si_xib;
23925 +       struct mutex            si_xib_mtx; /* protect xib members */
23926 +       unsigned long           *si_xib_buf;
23927 +       unsigned long           si_xib_last_pindex;
23928 +       int                     si_xib_next_bit;
23929 +       aufs_bindex_t           si_xino_brid;
23930 +       /* reserved for future use */
23931 +       /* unsigned long long   si_xib_limit; */        /* Max xib file size */
23932 +
23933 +#ifdef CONFIG_AUFS_EXPORT
23934 +       /* i_generation */
23935 +       struct file             *si_xigen;
23936 +       atomic_t                si_xigen_next;
23937 +#endif
23938 +
23939 +       /* vdir parameters */
23940 +       unsigned long           si_rdcache;     /* max cache time in jiffies */
23941 +       unsigned int            si_rdblk;       /* deblk size */
23942 +       unsigned int            si_rdhash;      /* hash size */
23943 +
23944 +       /*
23945 +        * If the number of whiteouts are larger than si_dirwh, leave all of
23946 +        * them after au_whtmp_ren to reduce the cost of rmdir(2).
23947 +        * future fsck.aufs or kernel thread will remove them later.
23948 +        * Otherwise, remove all whiteouts and the dir in rmdir(2).
23949 +        */
23950 +       unsigned int            si_dirwh;
23951 +
23952 +       /*
23953 +        * rename(2) a directory with all children.
23954 +        */
23955 +       /* reserved for future use */
23956 +       /* int                  si_rendir; */
23957 +
23958 +       /* pseudo_link list */
23959 +       struct au_splhead       si_plink;
23960 +       wait_queue_head_t       si_plink_wq;
23961 +       spinlock_t              si_plink_maint_lock;
23962 +       pid_t                   si_plink_maint_pid;
23963 +
23964 +       /*
23965 +        * sysfs and lifetime management.
23966 +        * this is not a small structure and it may be a waste of memory in case
23967 +        * of sysfs is disabled, particulary when many aufs-es are mounted.
23968 +        * but using sysfs is majority.
23969 +        */
23970 +       struct kobject          si_kobj;
23971 +#ifdef CONFIG_DEBUG_FS
23972 +       struct dentry            *si_dbgaufs, *si_dbgaufs_xib;
23973 +#ifdef CONFIG_AUFS_EXPORT
23974 +       struct dentry            *si_dbgaufs_xigen;
23975 +#endif
23976 +#endif
23977 +
23978 +#ifdef CONFIG_AUFS_SBILIST
23979 +       struct list_head        si_list;
23980 +#endif
23981 +
23982 +       /* dirty, necessary for unmounting, sysfs and sysrq */
23983 +       struct super_block      *si_sb;
23984 +};
23985 +
23986 +/* sbinfo status flags */
23987 +/*
23988 + * set true when refresh_dirs() failed at remount time.
23989 + * then try refreshing dirs at access time again.
23990 + * if it is false, refreshing dirs at access time is unnecesary
23991 + */
23992 +#define AuSi_FAILED_REFRESH_DIR        1
23993 +static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
23994 +                                          unsigned int flag)
23995 +{
23996 +       AuRwMustAnyLock(&sbi->si_rwsem);
23997 +       return sbi->au_si_status & flag;
23998 +}
23999 +#define au_ftest_si(sbinfo, name)      au_do_ftest_si(sbinfo, AuSi_##name)
24000 +#define au_fset_si(sbinfo, name) do { \
24001 +       AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
24002 +       (sbinfo)->au_si_status |= AuSi_##name; \
24003 +} while (0)
24004 +#define au_fclr_si(sbinfo, name) do { \
24005 +       AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
24006 +       (sbinfo)->au_si_status &= ~AuSi_##name; \
24007 +} while (0)
24008 +
24009 +/* ---------------------------------------------------------------------- */
24010 +
24011 +/* policy to select one among writable branches */
24012 +#define AuWbrCopyup(sbinfo, ...) \
24013 +       ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
24014 +#define AuWbrCreate(sbinfo, ...) \
24015 +       ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
24016 +
24017 +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
24018 +#define AuLock_DW              1               /* write-lock dentry */
24019 +#define AuLock_IR              (1 << 1)        /* read-lock inode */
24020 +#define AuLock_IW              (1 << 2)        /* write-lock inode */
24021 +#define AuLock_FLUSH           (1 << 3)        /* wait for 'nowait' tasks */
24022 +#define AuLock_DIR             (1 << 4)        /* target is a dir */
24023 +#define AuLock_NOPLM           (1 << 5)        /* return err in plm mode */
24024 +#define AuLock_NOPLMW          (1 << 6)        /* wait for plm mode ends */
24025 +#define AuLock_GEN             (1 << 7)        /* test digen/iigen */
24026 +#define au_ftest_lock(flags, name)     ((flags) & AuLock_##name)
24027 +#define au_fset_lock(flags, name) \
24028 +       do { (flags) |= AuLock_##name; } while (0)
24029 +#define au_fclr_lock(flags, name) \
24030 +       do { (flags) &= ~AuLock_##name; } while (0)
24031 +
24032 +/* ---------------------------------------------------------------------- */
24033 +
24034 +/* super.c */
24035 +extern struct file_system_type aufs_fs_type;
24036 +struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
24037 +typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
24038 +                                          void *arg);
24039 +void au_array_free(void *array);
24040 +void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
24041 +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
24042 +void au_iarray_free(struct inode **a, unsigned long long max);
24043 +
24044 +/* sbinfo.c */
24045 +void au_si_free(struct kobject *kobj);
24046 +int au_si_alloc(struct super_block *sb);
24047 +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
24048 +
24049 +unsigned int au_sigen_inc(struct super_block *sb);
24050 +aufs_bindex_t au_new_br_id(struct super_block *sb);
24051 +
24052 +int si_read_lock(struct super_block *sb, int flags);
24053 +int si_write_lock(struct super_block *sb, int flags);
24054 +int aufs_read_lock(struct dentry *dentry, int flags);
24055 +void aufs_read_unlock(struct dentry *dentry, int flags);
24056 +void aufs_write_lock(struct dentry *dentry);
24057 +void aufs_write_unlock(struct dentry *dentry);
24058 +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
24059 +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
24060 +
24061 +int si_pid_test_slow(struct super_block *sb);
24062 +void si_pid_set_slow(struct super_block *sb);
24063 +void si_pid_clr_slow(struct super_block *sb);
24064 +
24065 +/* wbr_policy.c */
24066 +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
24067 +extern struct au_wbr_create_operations au_wbr_create_ops[];
24068 +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
24069 +
24070 +/* ---------------------------------------------------------------------- */
24071 +
24072 +static inline struct au_sbinfo *au_sbi(struct super_block *sb)
24073 +{
24074 +       return sb->s_fs_info;
24075 +}
24076 +
24077 +/* ---------------------------------------------------------------------- */
24078 +
24079 +#ifdef CONFIG_AUFS_EXPORT
24080 +void au_export_init(struct super_block *sb);
24081 +
24082 +static inline int au_test_nfsd(void)
24083 +{
24084 +       struct task_struct *tsk = current;
24085 +
24086 +       return (tsk->flags & PF_KTHREAD)
24087 +               && !strcmp(tsk->comm, "nfsd");
24088 +}
24089 +
24090 +void au_xigen_inc(struct inode *inode);
24091 +int au_xigen_new(struct inode *inode);
24092 +int au_xigen_set(struct super_block *sb, struct file *base);
24093 +void au_xigen_clr(struct super_block *sb);
24094 +
24095 +static inline int au_busy_or_stale(void)
24096 +{
24097 +       if (!au_test_nfsd())
24098 +               return -EBUSY;
24099 +       return -ESTALE;
24100 +}
24101 +#else
24102 +AuStubVoid(au_export_init, struct super_block *sb)
24103 +AuStubInt0(au_test_nfsd, void)
24104 +AuStubVoid(au_xigen_inc, struct inode *inode)
24105 +AuStubInt0(au_xigen_new, struct inode *inode)
24106 +AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
24107 +AuStubVoid(au_xigen_clr, struct super_block *sb)
24108 +static inline int au_busy_or_stale(void)
24109 +{
24110 +       return -EBUSY;
24111 +}
24112 +#endif /* CONFIG_AUFS_EXPORT */
24113 +
24114 +/* ---------------------------------------------------------------------- */
24115 +
24116 +#ifdef CONFIG_AUFS_SBILIST
24117 +/* module.c */
24118 +extern struct au_splhead au_sbilist;
24119 +
24120 +static inline void au_sbilist_init(void)
24121 +{
24122 +       au_spl_init(&au_sbilist);
24123 +}
24124 +
24125 +static inline void au_sbilist_add(struct super_block *sb)
24126 +{
24127 +       au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
24128 +}
24129 +
24130 +static inline void au_sbilist_del(struct super_block *sb)
24131 +{
24132 +       au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
24133 +}
24134 +
24135 +#ifdef CONFIG_AUFS_MAGIC_SYSRQ
24136 +static inline void au_sbilist_lock(void)
24137 +{
24138 +       spin_lock(&au_sbilist.spin);
24139 +}
24140 +
24141 +static inline void au_sbilist_unlock(void)
24142 +{
24143 +       spin_unlock(&au_sbilist.spin);
24144 +}
24145 +#define AuGFP_SBILIST  GFP_ATOMIC
24146 +#else
24147 +AuStubVoid(au_sbilist_lock, void)
24148 +AuStubVoid(au_sbilist_unlock, void)
24149 +#define AuGFP_SBILIST  GFP_NOFS
24150 +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
24151 +#else
24152 +AuStubVoid(au_sbilist_init, void)
24153 +AuStubVoid(au_sbilist_add, struct super_block*)
24154 +AuStubVoid(au_sbilist_del, struct super_block*)
24155 +AuStubVoid(au_sbilist_lock, void)
24156 +AuStubVoid(au_sbilist_unlock, void)
24157 +#define AuGFP_SBILIST  GFP_NOFS
24158 +#endif
24159 +
24160 +/* ---------------------------------------------------------------------- */
24161 +
24162 +static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
24163 +{
24164 +       /*
24165 +        * This function is a dynamic '__init' fucntion actually,
24166 +        * so the tiny check for si_rwsem is unnecessary.
24167 +        */
24168 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
24169 +#ifdef CONFIG_DEBUG_FS
24170 +       sbinfo->si_dbgaufs = NULL;
24171 +       sbinfo->si_dbgaufs_xib = NULL;
24172 +#ifdef CONFIG_AUFS_EXPORT
24173 +       sbinfo->si_dbgaufs_xigen = NULL;
24174 +#endif
24175 +#endif
24176 +}
24177 +
24178 +/* ---------------------------------------------------------------------- */
24179 +
24180 +static inline pid_t si_pid_bit(void)
24181 +{
24182 +       /* the origin of pid is 1, but the bitmap's is 0 */
24183 +       return current->pid - 1;
24184 +}
24185 +
24186 +static inline int si_pid_test(struct super_block *sb)
24187 +{
24188 +       pid_t bit = si_pid_bit();
24189 +       if (bit < PID_MAX_DEFAULT)
24190 +               return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24191 +       else
24192 +               return si_pid_test_slow(sb);
24193 +}
24194 +
24195 +static inline void si_pid_set(struct super_block *sb)
24196 +{
24197 +       pid_t bit = si_pid_bit();
24198 +       if (bit < PID_MAX_DEFAULT) {
24199 +               AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
24200 +               set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24201 +               /* smp_mb(); */
24202 +       } else
24203 +               si_pid_set_slow(sb);
24204 +}
24205 +
24206 +static inline void si_pid_clr(struct super_block *sb)
24207 +{
24208 +       pid_t bit = si_pid_bit();
24209 +       if (bit < PID_MAX_DEFAULT) {
24210 +               AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
24211 +               clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24212 +               /* smp_mb(); */
24213 +       } else
24214 +               si_pid_clr_slow(sb);
24215 +}
24216 +
24217 +/* ---------------------------------------------------------------------- */
24218 +
24219 +/* lock superblock. mainly for entry point functions */
24220 +/*
24221 + * __si_read_lock, __si_write_lock,
24222 + * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
24223 + */
24224 +AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
24225 +
24226 +#define SiMustNoWaiters(sb)    AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
24227 +#define SiMustAnyLock(sb)      AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
24228 +#define SiMustWriteLock(sb)    AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
24229 +
24230 +static inline void si_noflush_read_lock(struct super_block *sb)
24231 +{
24232 +       __si_read_lock(sb);
24233 +       si_pid_set(sb);
24234 +}
24235 +
24236 +static inline int si_noflush_read_trylock(struct super_block *sb)
24237 +{
24238 +       int locked = __si_read_trylock(sb);
24239 +       if (locked)
24240 +               si_pid_set(sb);
24241 +       return locked;
24242 +}
24243 +
24244 +static inline void si_noflush_write_lock(struct super_block *sb)
24245 +{
24246 +       __si_write_lock(sb);
24247 +       si_pid_set(sb);
24248 +}
24249 +
24250 +static inline int si_noflush_write_trylock(struct super_block *sb)
24251 +{
24252 +       int locked = __si_write_trylock(sb);
24253 +       if (locked)
24254 +               si_pid_set(sb);
24255 +       return locked;
24256 +}
24257 +
24258 +#if 0 /* unused */
24259 +static inline int si_read_trylock(struct super_block *sb, int flags)
24260 +{
24261 +       if (au_ftest_lock(flags, FLUSH))
24262 +               au_nwt_flush(&au_sbi(sb)->si_nowait);
24263 +       return si_noflush_read_trylock(sb);
24264 +}
24265 +#endif
24266 +
24267 +static inline void si_read_unlock(struct super_block *sb)
24268 +{
24269 +       si_pid_clr(sb);
24270 +       __si_read_unlock(sb);
24271 +}
24272 +
24273 +#if 0 /* unused */
24274 +static inline int si_write_trylock(struct super_block *sb, int flags)
24275 +{
24276 +       if (au_ftest_lock(flags, FLUSH))
24277 +               au_nwt_flush(&au_sbi(sb)->si_nowait);
24278 +       return si_noflush_write_trylock(sb);
24279 +}
24280 +#endif
24281 +
24282 +static inline void si_write_unlock(struct super_block *sb)
24283 +{
24284 +       si_pid_clr(sb);
24285 +       __si_write_unlock(sb);
24286 +}
24287 +
24288 +#if 0 /* unused */
24289 +static inline void si_downgrade_lock(struct super_block *sb)
24290 +{
24291 +       __si_downgrade_lock(sb);
24292 +}
24293 +#endif
24294 +
24295 +/* ---------------------------------------------------------------------- */
24296 +
24297 +static inline aufs_bindex_t au_sbend(struct super_block *sb)
24298 +{
24299 +       SiMustAnyLock(sb);
24300 +       return au_sbi(sb)->si_bend;
24301 +}
24302 +
24303 +static inline unsigned int au_mntflags(struct super_block *sb)
24304 +{
24305 +       SiMustAnyLock(sb);
24306 +       return au_sbi(sb)->si_mntflags;
24307 +}
24308 +
24309 +static inline unsigned int au_sigen(struct super_block *sb)
24310 +{
24311 +       SiMustAnyLock(sb);
24312 +       return au_sbi(sb)->si_generation;
24313 +}
24314 +
24315 +static inline void au_ninodes_inc(struct super_block *sb)
24316 +{
24317 +       atomic_long_inc(&au_sbi(sb)->si_ninodes);
24318 +}
24319 +
24320 +static inline void au_ninodes_dec(struct super_block *sb)
24321 +{
24322 +       AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
24323 +       atomic_long_dec(&au_sbi(sb)->si_ninodes);
24324 +}
24325 +
24326 +static inline void au_nfiles_inc(struct super_block *sb)
24327 +{
24328 +       atomic_long_inc(&au_sbi(sb)->si_nfiles);
24329 +}
24330 +
24331 +static inline void au_nfiles_dec(struct super_block *sb)
24332 +{
24333 +       AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
24334 +       atomic_long_dec(&au_sbi(sb)->si_nfiles);
24335 +}
24336 +
24337 +static inline struct au_branch *au_sbr(struct super_block *sb,
24338 +                                      aufs_bindex_t bindex)
24339 +{
24340 +       SiMustAnyLock(sb);
24341 +       return au_sbi(sb)->si_branch[0 + bindex];
24342 +}
24343 +
24344 +static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
24345 +{
24346 +       SiMustWriteLock(sb);
24347 +       au_sbi(sb)->si_xino_brid = brid;
24348 +}
24349 +
24350 +static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
24351 +{
24352 +       SiMustAnyLock(sb);
24353 +       return au_sbi(sb)->si_xino_brid;
24354 +}
24355 +
24356 +#endif /* __KERNEL__ */
24357 +#endif /* __AUFS_SUPER_H__ */
24358 diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
24359 --- /usr/share/empty/fs/aufs/sysaufs.c  1970-01-01 01:00:00.000000000 +0100
24360 +++ linux/fs/aufs/sysaufs.c     2013-01-11 19:46:12.639281345 +0100
24361 @@ -0,0 +1,105 @@
24362 +/*
24363 + * Copyright (C) 2005-2013 Junjiro R. Okajima
24364 + *
24365 + * This program, aufs is free software; you can redistribute it and/or modify
24366 + * it under the terms of the GNU General Public License as published by
24367 + * the Free Software Foundation; either version 2 of the License, or
24368 + * (at your option) any later version.
24369 + *
24370 + * This program is distributed in the hope that it will be useful,
24371 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24372 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24373 + * GNU General Public License for more details.
24374 + *
24375 + * You should have received a copy of the GNU General Public License
24376 + * along with this program; if not, write to the Free Software
24377 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24378 + */
24379 +
24380 +/*
24381 + * sysfs interface and lifetime management
24382 + * they are necessary regardless sysfs is disabled.
24383 + */
24384 +
24385 +#include <linux/random.h>
24386 +#include "aufs.h"
24387 +
24388 +unsigned long sysaufs_si_mask;
24389 +struct kset *sysaufs_kset;
24390 +
24391 +#define AuSiAttr(_name) { \
24392 +       .attr   = { .name = __stringify(_name), .mode = 0444 }, \
24393 +       .show   = sysaufs_si_##_name,                           \
24394 +}
24395 +
24396 +static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
24397 +struct attribute *sysaufs_si_attrs[] = {
24398 +       &sysaufs_si_attr_xi_path.attr,
24399 +       NULL,
24400 +};
24401 +
24402 +static const struct sysfs_ops au_sbi_ops = {
24403 +       .show   = sysaufs_si_show
24404 +};
24405 +
24406 +static struct kobj_type au_sbi_ktype = {
24407 +       .release        = au_si_free,
24408 +       .sysfs_ops      = &au_sbi_ops,
24409 +       .default_attrs  = sysaufs_si_attrs
24410 +};
24411 +
24412 +/* ---------------------------------------------------------------------- */
24413 +
24414 +int sysaufs_si_init(struct au_sbinfo *sbinfo)
24415 +{
24416 +       int err;
24417 +
24418 +       sbinfo->si_kobj.kset = sysaufs_kset;
24419 +       /* cf. sysaufs_name() */
24420 +       err = kobject_init_and_add
24421 +               (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
24422 +                SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
24423 +
24424 +       dbgaufs_si_null(sbinfo);
24425 +       if (!err) {
24426 +               err = dbgaufs_si_init(sbinfo);
24427 +               if (unlikely(err))
24428 +                       kobject_put(&sbinfo->si_kobj);
24429 +       }
24430 +       return err;
24431 +}
24432 +
24433 +void sysaufs_fin(void)
24434 +{
24435 +       dbgaufs_fin();
24436 +       sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
24437 +       kset_unregister(sysaufs_kset);
24438 +}
24439 +
24440 +int __init sysaufs_init(void)
24441 +{
24442 +       int err;
24443 +
24444 +       do {
24445 +               get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
24446 +       } while (!sysaufs_si_mask);
24447 +
24448 +       err = -EINVAL;
24449 +       sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
24450 +       if (unlikely(!sysaufs_kset))
24451 +               goto out;
24452 +       err = PTR_ERR(sysaufs_kset);
24453 +       if (IS_ERR(sysaufs_kset))
24454 +               goto out;
24455 +       err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
24456 +       if (unlikely(err)) {
24457 +               kset_unregister(sysaufs_kset);
24458 +               goto out;
24459 +       }
24460 +
24461 +       err = dbgaufs_init();
24462 +       if (unlikely(err))
24463 +               sysaufs_fin();
24464 +out:
24465 +       return err;
24466 +}
24467 diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
24468 --- /usr/share/empty/fs/aufs/sysaufs.h  1970-01-01 01:00:00.000000000 +0100
24469 +++ linux/fs/aufs/sysaufs.h     2013-01-11 19:46:12.639281345 +0100
24470 @@ -0,0 +1,104 @@
24471 +/*
24472 + * Copyright (C) 2005-2013 Junjiro R. Okajima
24473 + *
24474 + * This program, aufs is free software; you can redistribute it and/or modify
24475 + * it under the terms of the GNU General Public License as published by
24476 + * the Free Software Foundation; either version 2 of the License, or
24477 + * (at your option) any later version.
24478 + *
24479 + * This program is distributed in the hope that it will be useful,
24480 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24481 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24482 + * GNU General Public License for more details.
24483 + *
24484 + * You should have received a copy of the GNU General Public License
24485 + * along with this program; if not, write to the Free Software
24486 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24487 + */
24488 +
24489 +/*
24490 + * sysfs interface and mount lifetime management
24491 + */
24492 +
24493 +#ifndef __SYSAUFS_H__
24494 +#define __SYSAUFS_H__
24495 +
24496 +#ifdef __KERNEL__
24497 +
24498 +#include <linux/sysfs.h>
24499 +#include "module.h"
24500 +
24501 +struct super_block;
24502 +struct au_sbinfo;
24503 +
24504 +struct sysaufs_si_attr {
24505 +       struct attribute attr;
24506 +       int (*show)(struct seq_file *seq, struct super_block *sb);
24507 +};
24508 +
24509 +/* ---------------------------------------------------------------------- */
24510 +
24511 +/* sysaufs.c */
24512 +extern unsigned long sysaufs_si_mask;
24513 +extern struct kset *sysaufs_kset;
24514 +extern struct attribute *sysaufs_si_attrs[];
24515 +int sysaufs_si_init(struct au_sbinfo *sbinfo);
24516 +int __init sysaufs_init(void);
24517 +void sysaufs_fin(void);
24518 +
24519 +/* ---------------------------------------------------------------------- */
24520 +
24521 +/* some people doesn't like to show a pointer in kernel */
24522 +static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
24523 +{
24524 +       return sysaufs_si_mask ^ (unsigned long)sbinfo;
24525 +}
24526 +
24527 +#define SysaufsSiNamePrefix    "si_"
24528 +#define SysaufsSiNameLen       (sizeof(SysaufsSiNamePrefix) + 16)
24529 +static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
24530 +{
24531 +       snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
24532 +                sysaufs_si_id(sbinfo));
24533 +}
24534 +
24535 +struct au_branch;
24536 +#ifdef CONFIG_SYSFS
24537 +/* sysfs.c */
24538 +extern struct attribute_group *sysaufs_attr_group;
24539 +
24540 +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
24541 +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
24542 +                        char *buf);
24543 +
24544 +void sysaufs_br_init(struct au_branch *br);
24545 +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
24546 +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
24547 +
24548 +#define sysaufs_brs_init()     do {} while (0)
24549 +
24550 +#else
24551 +#define sysaufs_attr_group     NULL
24552 +
24553 +AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
24554 +
24555 +static inline
24556 +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
24557 +                        char *buf)
24558 +{
24559 +       return 0;
24560 +}
24561 +
24562 +AuStubVoid(sysaufs_br_init, struct au_branch *br)
24563 +AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
24564 +AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
24565 +
24566 +static inline void sysaufs_brs_init(void)
24567 +{
24568 +       sysaufs_brs = 0;
24569 +}
24570 +
24571 +#endif /* CONFIG_SYSFS */
24572 +
24573 +#endif /* __KERNEL__ */
24574 +#endif /* __SYSAUFS_H__ */
24575 diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
24576 --- /usr/share/empty/fs/aufs/sysfs.c    1970-01-01 01:00:00.000000000 +0100
24577 +++ linux/fs/aufs/sysfs.c       2013-01-11 19:46:12.642614759 +0100
24578 @@ -0,0 +1,257 @@
24579 +/*
24580 + * Copyright (C) 2005-2013 Junjiro R. Okajima
24581 + *
24582 + * This program, aufs is free software; you can redistribute it and/or modify
24583 + * it under the terms of the GNU General Public License as published by
24584 + * the Free Software Foundation; either version 2 of the License, or
24585 + * (at your option) any later version.
24586 + *
24587 + * This program is distributed in the hope that it will be useful,
24588 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24589 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24590 + * GNU General Public License for more details.
24591 + *
24592 + * You should have received a copy of the GNU General Public License
24593 + * along with this program; if not, write to the Free Software
24594 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24595 + */
24596 +
24597 +/*
24598 + * sysfs interface
24599 + */
24600 +
24601 +#include <linux/seq_file.h>
24602 +#include "aufs.h"
24603 +
24604 +#ifdef CONFIG_AUFS_FS_MODULE
24605 +/* this entry violates the "one line per file" policy of sysfs */
24606 +static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
24607 +                          char *buf)
24608 +{
24609 +       ssize_t err;
24610 +       static char *conf =
24611 +/* this file is generated at compiling */
24612 +#include "conf.str"
24613 +               ;
24614 +
24615 +       err = snprintf(buf, PAGE_SIZE, conf);
24616 +       if (unlikely(err >= PAGE_SIZE))
24617 +               err = -EFBIG;
24618 +       return err;
24619 +}
24620 +
24621 +static struct kobj_attribute au_config_attr = __ATTR_RO(config);
24622 +#endif
24623 +
24624 +static struct attribute *au_attr[] = {
24625 +#ifdef CONFIG_AUFS_FS_MODULE
24626 +       &au_config_attr.attr,
24627 +#endif
24628 +       NULL,   /* need to NULL terminate the list of attributes */
24629 +};
24630 +
24631 +static struct attribute_group sysaufs_attr_group_body = {
24632 +       .attrs = au_attr
24633 +};
24634 +
24635 +struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
24636 +
24637 +/* ---------------------------------------------------------------------- */
24638 +
24639 +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
24640 +{
24641 +       int err;
24642 +
24643 +       SiMustAnyLock(sb);
24644 +
24645 +       err = 0;
24646 +       if (au_opt_test(au_mntflags(sb), XINO)) {
24647 +               err = au_xino_path(seq, au_sbi(sb)->si_xib);
24648 +               seq_putc(seq, '\n');
24649 +       }
24650 +       return err;
24651 +}
24652 +
24653 +/*
24654 + * the lifetime of branch is independent from the entry under sysfs.
24655 + * sysfs handles the lifetime of the entry, and never call ->show() after it is
24656 + * unlinked.
24657 + */
24658 +static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
24659 +                        aufs_bindex_t bindex)
24660 +{
24661 +       int err;
24662 +       struct path path;
24663 +       struct dentry *root;
24664 +       struct au_branch *br;
24665 +       char *perm;
24666 +
24667 +       AuDbg("b%d\n", bindex);
24668 +
24669 +       err = 0;
24670 +       root = sb->s_root;
24671 +       di_read_lock_parent(root, !AuLock_IR);
24672 +       br = au_sbr(sb, bindex);
24673 +       path.mnt = br->br_mnt;
24674 +       path.dentry = au_h_dptr(root, bindex);
24675 +       au_seq_path(seq, &path);
24676 +       di_read_unlock(root, !AuLock_IR);
24677 +       perm = au_optstr_br_perm(br->br_perm);
24678 +       if (perm) {
24679 +               err = seq_printf(seq, "=%s\n", perm);
24680 +               kfree(perm);
24681 +               if (err == -1)
24682 +                       err = -E2BIG;
24683 +       } else
24684 +               err = -ENOMEM;
24685 +       return err;
24686 +}
24687 +
24688 +/* ---------------------------------------------------------------------- */
24689 +
24690 +static struct seq_file *au_seq(char *p, ssize_t len)
24691 +{
24692 +       struct seq_file *seq;
24693 +
24694 +       seq = kzalloc(sizeof(*seq), GFP_NOFS);
24695 +       if (seq) {
24696 +               /* mutex_init(&seq.lock); */
24697 +               seq->buf = p;
24698 +               seq->size = len;
24699 +               return seq; /* success */
24700 +       }
24701 +
24702 +       seq = ERR_PTR(-ENOMEM);
24703 +       return seq;
24704 +}
24705 +
24706 +#define SysaufsBr_PREFIX "br"
24707 +
24708 +/* todo: file size may exceed PAGE_SIZE */
24709 +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
24710 +                       char *buf)
24711 +{
24712 +       ssize_t err;
24713 +       long l;
24714 +       aufs_bindex_t bend;
24715 +       struct au_sbinfo *sbinfo;
24716 +       struct super_block *sb;
24717 +       struct seq_file *seq;
24718 +       char *name;
24719 +       struct attribute **cattr;
24720 +
24721 +       sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
24722 +       sb = sbinfo->si_sb;
24723 +
24724 +       /*
24725 +        * prevent a race condition between sysfs and aufs.
24726 +        * for instance, sysfs_file_read() calls sysfs_get_active_two() which
24727 +        * prohibits maintaining the sysfs entries.
24728 +        * hew we acquire read lock after sysfs_get_active_two().
24729 +        * on the other hand, the remount process may maintain the sysfs/aufs
24730 +        * entries after acquiring write lock.
24731 +        * it can cause a deadlock.
24732 +        * simply we gave up processing read here.
24733 +        */
24734 +       err = -EBUSY;
24735 +       if (unlikely(!si_noflush_read_trylock(sb)))
24736 +               goto out;
24737 +
24738 +       seq = au_seq(buf, PAGE_SIZE);
24739 +       err = PTR_ERR(seq);
24740 +       if (IS_ERR(seq))
24741 +               goto out_unlock;
24742 +
24743 +       name = (void *)attr->name;
24744 +       cattr = sysaufs_si_attrs;
24745 +       while (*cattr) {
24746 +               if (!strcmp(name, (*cattr)->name)) {
24747 +                       err = container_of(*cattr, struct sysaufs_si_attr, attr)
24748 +                               ->show(seq, sb);
24749 +                       goto out_seq;
24750 +               }
24751 +               cattr++;
24752 +       }
24753 +
24754 +       bend = au_sbend(sb);
24755 +       if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) {
24756 +               name += sizeof(SysaufsBr_PREFIX) - 1;
24757 +               err = kstrtol(name, 10, &l);
24758 +               if (!err) {
24759 +                       if (l <= bend)
24760 +                               err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l);
24761 +                       else
24762 +                               err = -ENOENT;
24763 +               }
24764 +               goto out_seq;
24765 +       }
24766 +       BUG();
24767 +
24768 +out_seq:
24769 +       if (!err) {
24770 +               err = seq->count;
24771 +               /* sysfs limit */
24772 +               if (unlikely(err == PAGE_SIZE))
24773 +                       err = -EFBIG;
24774 +       }
24775 +       kfree(seq);
24776 +out_unlock:
24777 +       si_read_unlock(sb);
24778 +out:
24779 +       return err;
24780 +}
24781 +
24782 +/* ---------------------------------------------------------------------- */
24783 +
24784 +void sysaufs_br_init(struct au_branch *br)
24785 +{
24786 +       struct attribute *attr = &br->br_attr;
24787 +
24788 +       sysfs_attr_init(attr);
24789 +       attr->name = br->br_name;
24790 +       attr->mode = S_IRUGO;
24791 +}
24792 +
24793 +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
24794 +{
24795 +       struct au_branch *br;
24796 +       struct kobject *kobj;
24797 +       aufs_bindex_t bend;
24798 +
24799 +       dbgaufs_brs_del(sb, bindex);
24800 +
24801 +       if (!sysaufs_brs)
24802 +               return;
24803 +
24804 +       kobj = &au_sbi(sb)->si_kobj;
24805 +       bend = au_sbend(sb);
24806 +       for (; bindex <= bend; bindex++) {
24807 +               br = au_sbr(sb, bindex);
24808 +               sysfs_remove_file(kobj, &br->br_attr);
24809 +       }
24810 +}
24811 +
24812 +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
24813 +{
24814 +       int err;
24815 +       aufs_bindex_t bend;
24816 +       struct kobject *kobj;
24817 +       struct au_branch *br;
24818 +
24819 +       dbgaufs_brs_add(sb, bindex);
24820 +
24821 +       if (!sysaufs_brs)
24822 +               return;
24823 +
24824 +       kobj = &au_sbi(sb)->si_kobj;
24825 +       bend = au_sbend(sb);
24826 +       for (; bindex <= bend; bindex++) {
24827 +               br = au_sbr(sb, bindex);
24828 +               snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX
24829 +                        "%d", bindex);
24830 +               err = sysfs_create_file(kobj, &br->br_attr);
24831 +               if (unlikely(err))
24832 +                       pr_warn("failed %s under sysfs(%d)\n",
24833 +                               br->br_name, err);
24834 +       }
24835 +}
24836 diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
24837 --- /usr/share/empty/fs/aufs/sysrq.c    1970-01-01 01:00:00.000000000 +0100
24838 +++ linux/fs/aufs/sysrq.c       2013-01-11 19:46:12.642614759 +0100
24839 @@ -0,0 +1,148 @@
24840 +/*
24841 + * Copyright (C) 2005-2013 Junjiro R. Okajima
24842 + *
24843 + * This program, aufs is free software; you can redistribute it and/or modify
24844 + * it under the terms of the GNU General Public License as published by
24845 + * the Free Software Foundation; either version 2 of the License, or
24846 + * (at your option) any later version.
24847 + *
24848 + * This program is distributed in the hope that it will be useful,
24849 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24850 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24851 + * GNU General Public License for more details.
24852 + *
24853 + * You should have received a copy of the GNU General Public License
24854 + * along with this program; if not, write to the Free Software
24855 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24856 + */
24857 +
24858 +/*
24859 + * magic sysrq hanlder
24860 + */
24861 +
24862 +/* #include <linux/sysrq.h> */
24863 +#include <linux/writeback.h>
24864 +#include "aufs.h"
24865 +
24866 +/* ---------------------------------------------------------------------- */
24867 +
24868 +static void sysrq_sb(struct super_block *sb)
24869 +{
24870 +       char *plevel;
24871 +       struct au_sbinfo *sbinfo;
24872 +       struct file *file;
24873 +
24874 +       plevel = au_plevel;
24875 +       au_plevel = KERN_WARNING;
24876 +
24877 +       sbinfo = au_sbi(sb);
24878 +       /* since we define pr_fmt, call printk directly */
24879 +       printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
24880 +       printk(KERN_WARNING AUFS_NAME ": superblock\n");
24881 +       au_dpri_sb(sb);
24882 +
24883 +#if 0
24884 +       printk(KERN_WARNING AUFS_NAME ": root dentry\n");
24885 +       au_dpri_dentry(sb->s_root);
24886 +       printk(KERN_WARNING AUFS_NAME ": root inode\n");
24887 +       au_dpri_inode(sb->s_root->d_inode);
24888 +#endif
24889 +
24890 +#if 0
24891 +       do {
24892 +               int err, i, j, ndentry;
24893 +               struct au_dcsub_pages dpages;
24894 +               struct au_dpage *dpage;
24895 +
24896 +               err = au_dpages_init(&dpages, GFP_ATOMIC);
24897 +               if (unlikely(err))
24898 +                       break;
24899 +               err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
24900 +               if (!err)
24901 +                       for (i = 0; i < dpages.ndpage; i++) {
24902 +                               dpage = dpages.dpages + i;
24903 +                               ndentry = dpage->ndentry;
24904 +                               for (j = 0; j < ndentry; j++)
24905 +                                       au_dpri_dentry(dpage->dentries[j]);
24906 +                       }
24907 +               au_dpages_free(&dpages);
24908 +       } while (0);
24909 +#endif
24910 +
24911 +#if 1
24912 +       {
24913 +               struct inode *i;
24914 +               printk(KERN_WARNING AUFS_NAME ": isolated inode\n");
24915 +               spin_lock(&inode_sb_list_lock);
24916 +               list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
24917 +                       spin_lock(&i->i_lock);
24918 +                       if (1 || hlist_empty(&i->i_dentry))
24919 +                               au_dpri_inode(i);
24920 +                       spin_unlock(&i->i_lock);
24921 +               }
24922 +               spin_unlock(&inode_sb_list_lock);
24923 +       }
24924 +#endif
24925 +       printk(KERN_WARNING AUFS_NAME ": files\n");
24926 +       lg_global_lock(&files_lglock);
24927 +       do_file_list_for_each_entry(sb, file) {
24928 +               umode_t mode;
24929 +               mode = file->f_dentry->d_inode->i_mode;
24930 +               if (!special_file(mode) || au_special_file(mode))
24931 +                       au_dpri_file(file);
24932 +       } while_file_list_for_each_entry;
24933 +       lg_global_unlock(&files_lglock);
24934 +       printk(KERN_WARNING AUFS_NAME ": done\n");
24935 +
24936 +       au_plevel = plevel;
24937 +}
24938 +
24939 +/* ---------------------------------------------------------------------- */
24940 +
24941 +/* module parameter */
24942 +static char *aufs_sysrq_key = "a";
24943 +module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
24944 +MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
24945 +
24946 +static void au_sysrq(int key __maybe_unused)
24947 +{
24948 +       struct au_sbinfo *sbinfo;
24949 +
24950 +       lockdep_off();
24951 +       au_sbilist_lock();
24952 +       list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
24953 +               sysrq_sb(sbinfo->si_sb);
24954 +       au_sbilist_unlock();
24955 +       lockdep_on();
24956 +}
24957 +
24958 +static struct sysrq_key_op au_sysrq_op = {
24959 +       .handler        = au_sysrq,
24960 +       .help_msg       = "Aufs",
24961 +       .action_msg     = "Aufs",
24962 +       .enable_mask    = SYSRQ_ENABLE_DUMP
24963 +};
24964 +
24965 +/* ---------------------------------------------------------------------- */
24966 +
24967 +int __init au_sysrq_init(void)
24968 +{
24969 +       int err;
24970 +       char key;
24971 +
24972 +       err = -1;
24973 +       key = *aufs_sysrq_key;
24974 +       if ('a' <= key && key <= 'z')
24975 +               err = register_sysrq_key(key, &au_sysrq_op);
24976 +       if (unlikely(err))
24977 +               pr_err("err %d, sysrq=%c\n", err, key);
24978 +       return err;
24979 +}
24980 +
24981 +void au_sysrq_fin(void)
24982 +{
24983 +       int err;
24984 +       err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
24985 +       if (unlikely(err))
24986 +               pr_err("err %d (ignored)\n", err);
24987 +}
24988 diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
24989 --- /usr/share/empty/fs/aufs/vdir.c     1970-01-01 01:00:00.000000000 +0100
24990 +++ linux/fs/aufs/vdir.c        2013-01-11 19:46:28.699667650 +0100
24991 @@ -0,0 +1,885 @@
24992 +/*
24993 + * Copyright (C) 2005-2013 Junjiro R. Okajima
24994 + *
24995 + * This program, aufs is free software; you can redistribute it and/or modify
24996 + * it under the terms of the GNU General Public License as published by
24997 + * the Free Software Foundation; either version 2 of the License, or
24998 + * (at your option) any later version.
24999 + *
25000 + * This program is distributed in the hope that it will be useful,
25001 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25002 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25003 + * GNU General Public License for more details.
25004 + *
25005 + * You should have received a copy of the GNU General Public License
25006 + * along with this program; if not, write to the Free Software
25007 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25008 + */
25009 +
25010 +/*
25011 + * virtual or vertical directory
25012 + */
25013 +
25014 +#include "aufs.h"
25015 +
25016 +static unsigned int calc_size(int nlen)
25017 +{
25018 +       return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
25019 +}
25020 +
25021 +static int set_deblk_end(union au_vdir_deblk_p *p,
25022 +                        union au_vdir_deblk_p *deblk_end)
25023 +{
25024 +       if (calc_size(0) <= deblk_end->deblk - p->deblk) {
25025 +               p->de->de_str.len = 0;
25026 +               /* smp_mb(); */
25027 +               return 0;
25028 +       }
25029 +       return -1; /* error */
25030 +}
25031 +
25032 +/* returns true or false */
25033 +static int is_deblk_end(union au_vdir_deblk_p *p,
25034 +                       union au_vdir_deblk_p *deblk_end)
25035 +{
25036 +       if (calc_size(0) <= deblk_end->deblk - p->deblk)
25037 +               return !p->de->de_str.len;
25038 +       return 1;
25039 +}
25040 +
25041 +static unsigned char *last_deblk(struct au_vdir *vdir)
25042 +{
25043 +       return vdir->vd_deblk[vdir->vd_nblk - 1];
25044 +}
25045 +
25046 +/* ---------------------------------------------------------------------- */
25047 +
25048 +/* estimate the apropriate size for name hash table */
25049 +unsigned int au_rdhash_est(loff_t sz)
25050 +{
25051 +       unsigned int n;
25052 +
25053 +       n = UINT_MAX;
25054 +       sz >>= 10;
25055 +       if (sz < n)
25056 +               n = sz;
25057 +       if (sz < AUFS_RDHASH_DEF)
25058 +               n = AUFS_RDHASH_DEF;
25059 +       /* pr_info("n %u\n", n); */
25060 +       return n;
25061 +}
25062 +
25063 +/*
25064 + * the allocated memory has to be freed by
25065 + * au_nhash_wh_free() or au_nhash_de_free().
25066 + */
25067 +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
25068 +{
25069 +       struct hlist_head *head;
25070 +       unsigned int u;
25071 +
25072 +       head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
25073 +       if (head) {
25074 +               nhash->nh_num = num_hash;
25075 +               nhash->nh_head = head;
25076 +               for (u = 0; u < num_hash; u++)
25077 +                       INIT_HLIST_HEAD(head++);
25078 +               return 0; /* success */
25079 +       }
25080 +
25081 +       return -ENOMEM;
25082 +}
25083 +
25084 +static void nhash_count(struct hlist_head *head)
25085 +{
25086 +#if 0
25087 +       unsigned long n;
25088 +       struct hlist_node *pos;
25089 +
25090 +       n = 0;
25091 +       hlist_for_each(pos, head)
25092 +               n++;
25093 +       pr_info("%lu\n", n);
25094 +#endif
25095 +}
25096 +
25097 +static void au_nhash_wh_do_free(struct hlist_head *head)
25098 +{
25099 +       struct au_vdir_wh *tpos;
25100 +       struct hlist_node *pos, *node;
25101 +
25102 +       hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) {
25103 +               /* hlist_del(pos); */
25104 +               kfree(tpos);
25105 +       }
25106 +}
25107 +
25108 +static void au_nhash_de_do_free(struct hlist_head *head)
25109 +{
25110 +       struct au_vdir_dehstr *tpos;
25111 +       struct hlist_node *pos, *node;
25112 +
25113 +       hlist_for_each_entry_safe(tpos, pos, node, head, hash) {
25114 +               /* hlist_del(pos); */
25115 +               au_cache_free_vdir_dehstr(tpos);
25116 +       }
25117 +}
25118 +
25119 +static void au_nhash_do_free(struct au_nhash *nhash,
25120 +                            void (*free)(struct hlist_head *head))
25121 +{
25122 +       unsigned int n;
25123 +       struct hlist_head *head;
25124 +
25125 +       n = nhash->nh_num;
25126 +       if (!n)
25127 +               return;
25128 +
25129 +       head = nhash->nh_head;
25130 +       while (n-- > 0) {
25131 +               nhash_count(head);
25132 +               free(head++);
25133 +       }
25134 +       kfree(nhash->nh_head);
25135 +}
25136 +
25137 +void au_nhash_wh_free(struct au_nhash *whlist)
25138 +{
25139 +       au_nhash_do_free(whlist, au_nhash_wh_do_free);
25140 +}
25141 +
25142 +static void au_nhash_de_free(struct au_nhash *delist)
25143 +{
25144 +       au_nhash_do_free(delist, au_nhash_de_do_free);
25145 +}
25146 +
25147 +/* ---------------------------------------------------------------------- */
25148 +
25149 +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
25150 +                           int limit)
25151 +{
25152 +       int num;
25153 +       unsigned int u, n;
25154 +       struct hlist_head *head;
25155 +       struct au_vdir_wh *tpos;
25156 +       struct hlist_node *pos;
25157 +
25158 +       num = 0;
25159 +       n = whlist->nh_num;
25160 +       head = whlist->nh_head;
25161 +       for (u = 0; u < n; u++, head++)
25162 +               hlist_for_each_entry(tpos, pos, head, wh_hash)
25163 +                       if (tpos->wh_bindex == btgt && ++num > limit)
25164 +                               return 1;
25165 +       return 0;
25166 +}
25167 +
25168 +static struct hlist_head *au_name_hash(struct au_nhash *nhash,
25169 +                                      unsigned char *name,
25170 +                                      unsigned int len)
25171 +{
25172 +       unsigned int v;
25173 +       /* const unsigned int magic_bit = 12; */
25174 +
25175 +       AuDebugOn(!nhash->nh_num || !nhash->nh_head);
25176 +
25177 +       v = 0;
25178 +       while (len--)
25179 +               v += *name++;
25180 +       /* v = hash_long(v, magic_bit); */
25181 +       v %= nhash->nh_num;
25182 +       return nhash->nh_head + v;
25183 +}
25184 +
25185 +static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
25186 +                             int nlen)
25187 +{
25188 +       return str->len == nlen && !memcmp(str->name, name, nlen);
25189 +}
25190 +
25191 +/* returns found or not */
25192 +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
25193 +{
25194 +       struct hlist_head *head;
25195 +       struct au_vdir_wh *tpos;
25196 +       struct hlist_node *pos;
25197 +       struct au_vdir_destr *str;
25198 +
25199 +       head = au_name_hash(whlist, name, nlen);
25200 +       hlist_for_each_entry(tpos, pos, head, wh_hash) {
25201 +               str = &tpos->wh_str;
25202 +               AuDbg("%.*s\n", str->len, str->name);
25203 +               if (au_nhash_test_name(str, name, nlen))
25204 +                       return 1;
25205 +       }
25206 +       return 0;
25207 +}
25208 +
25209 +/* returns found(true) or not */
25210 +static int test_known(struct au_nhash *delist, char *name, int nlen)
25211 +{
25212 +       struct hlist_head *head;
25213 +       struct au_vdir_dehstr *tpos;
25214 +       struct hlist_node *pos;
25215 +       struct au_vdir_destr *str;
25216 +
25217 +       head = au_name_hash(delist, name, nlen);
25218 +       hlist_for_each_entry(tpos, pos, head, hash) {
25219 +               str = tpos->str;
25220 +               AuDbg("%.*s\n", str->len, str->name);
25221 +               if (au_nhash_test_name(str, name, nlen))
25222 +                       return 1;
25223 +       }
25224 +       return 0;
25225 +}
25226 +
25227 +static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
25228 +                           unsigned char d_type)
25229 +{
25230 +#ifdef CONFIG_AUFS_SHWH
25231 +       wh->wh_ino = ino;
25232 +       wh->wh_type = d_type;
25233 +#endif
25234 +}
25235 +
25236 +/* ---------------------------------------------------------------------- */
25237 +
25238 +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
25239 +                      unsigned int d_type, aufs_bindex_t bindex,
25240 +                      unsigned char shwh)
25241 +{
25242 +       int err;
25243 +       struct au_vdir_destr *str;
25244 +       struct au_vdir_wh *wh;
25245 +
25246 +       AuDbg("%.*s\n", nlen, name);
25247 +       AuDebugOn(!whlist->nh_num || !whlist->nh_head);
25248 +
25249 +       err = -ENOMEM;
25250 +       wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
25251 +       if (unlikely(!wh))
25252 +               goto out;
25253 +
25254 +       err = 0;
25255 +       wh->wh_bindex = bindex;
25256 +       if (shwh)
25257 +               au_shwh_init_wh(wh, ino, d_type);
25258 +       str = &wh->wh_str;
25259 +       str->len = nlen;
25260 +       memcpy(str->name, name, nlen);
25261 +       hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
25262 +       /* smp_mb(); */
25263 +
25264 +out:
25265 +       return err;
25266 +}
25267 +
25268 +static int append_deblk(struct au_vdir *vdir)
25269 +{
25270 +       int err;
25271 +       unsigned long ul;
25272 +       const unsigned int deblk_sz = vdir->vd_deblk_sz;
25273 +       union au_vdir_deblk_p p, deblk_end;
25274 +       unsigned char **o;
25275 +
25276 +       err = -ENOMEM;
25277 +       o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
25278 +                    GFP_NOFS);
25279 +       if (unlikely(!o))
25280 +               goto out;
25281 +
25282 +       vdir->vd_deblk = o;
25283 +       p.deblk = kmalloc(deblk_sz, GFP_NOFS);
25284 +       if (p.deblk) {
25285 +               ul = vdir->vd_nblk++;
25286 +               vdir->vd_deblk[ul] = p.deblk;
25287 +               vdir->vd_last.ul = ul;
25288 +               vdir->vd_last.p.deblk = p.deblk;
25289 +               deblk_end.deblk = p.deblk + deblk_sz;
25290 +               err = set_deblk_end(&p, &deblk_end);
25291 +       }
25292 +
25293 +out:
25294 +       return err;
25295 +}
25296 +
25297 +static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
25298 +                    unsigned int d_type, struct au_nhash *delist)
25299 +{
25300 +       int err;
25301 +       unsigned int sz;
25302 +       const unsigned int deblk_sz = vdir->vd_deblk_sz;
25303 +       union au_vdir_deblk_p p, *room, deblk_end;
25304 +       struct au_vdir_dehstr *dehstr;
25305 +
25306 +       p.deblk = last_deblk(vdir);
25307 +       deblk_end.deblk = p.deblk + deblk_sz;
25308 +       room = &vdir->vd_last.p;
25309 +       AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
25310 +                 || !is_deblk_end(room, &deblk_end));
25311 +
25312 +       sz = calc_size(nlen);
25313 +       if (unlikely(sz > deblk_end.deblk - room->deblk)) {
25314 +               err = append_deblk(vdir);
25315 +               if (unlikely(err))
25316 +                       goto out;
25317 +
25318 +               p.deblk = last_deblk(vdir);
25319 +               deblk_end.deblk = p.deblk + deblk_sz;
25320 +               /* smp_mb(); */
25321 +               AuDebugOn(room->deblk != p.deblk);
25322 +       }
25323 +
25324 +       err = -ENOMEM;
25325 +       dehstr = au_cache_alloc_vdir_dehstr();
25326 +       if (unlikely(!dehstr))
25327 +               goto out;
25328 +
25329 +       dehstr->str = &room->de->de_str;
25330 +       hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
25331 +       room->de->de_ino = ino;
25332 +       room->de->de_type = d_type;
25333 +       room->de->de_str.len = nlen;
25334 +       memcpy(room->de->de_str.name, name, nlen);
25335 +
25336 +       err = 0;
25337 +       room->deblk += sz;
25338 +       if (unlikely(set_deblk_end(room, &deblk_end)))
25339 +               err = append_deblk(vdir);
25340 +       /* smp_mb(); */
25341 +
25342 +out:
25343 +       return err;
25344 +}
25345 +
25346 +/* ---------------------------------------------------------------------- */
25347 +
25348 +void au_vdir_free(struct au_vdir *vdir)
25349 +{
25350 +       unsigned char **deblk;
25351 +
25352 +       deblk = vdir->vd_deblk;
25353 +       while (vdir->vd_nblk--)
25354 +               kfree(*deblk++);
25355 +       kfree(vdir->vd_deblk);
25356 +       au_cache_free_vdir(vdir);
25357 +}
25358 +
25359 +static struct au_vdir *alloc_vdir(struct file *file)
25360 +{
25361 +       struct au_vdir *vdir;
25362 +       struct super_block *sb;
25363 +       int err;
25364 +
25365 +       sb = file->f_dentry->d_sb;
25366 +       SiMustAnyLock(sb);
25367 +
25368 +       err = -ENOMEM;
25369 +       vdir = au_cache_alloc_vdir();
25370 +       if (unlikely(!vdir))
25371 +               goto out;
25372 +
25373 +       vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
25374 +       if (unlikely(!vdir->vd_deblk))
25375 +               goto out_free;
25376 +
25377 +       vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
25378 +       if (!vdir->vd_deblk_sz) {
25379 +               /* estimate the apropriate size for deblk */
25380 +               vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
25381 +               /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
25382 +       }
25383 +       vdir->vd_nblk = 0;
25384 +       vdir->vd_version = 0;
25385 +       vdir->vd_jiffy = 0;
25386 +       err = append_deblk(vdir);
25387 +       if (!err)
25388 +               return vdir; /* success */
25389 +
25390 +       kfree(vdir->vd_deblk);
25391 +
25392 +out_free:
25393 +       au_cache_free_vdir(vdir);
25394 +out:
25395 +       vdir = ERR_PTR(err);
25396 +       return vdir;
25397 +}
25398 +
25399 +static int reinit_vdir(struct au_vdir *vdir)
25400 +{
25401 +       int err;
25402 +       union au_vdir_deblk_p p, deblk_end;
25403 +
25404 +       while (vdir->vd_nblk > 1) {
25405 +               kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
25406 +               /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
25407 +               vdir->vd_nblk--;
25408 +       }
25409 +       p.deblk = vdir->vd_deblk[0];
25410 +       deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
25411 +       err = set_deblk_end(&p, &deblk_end);
25412 +       /* keep vd_dblk_sz */
25413 +       vdir->vd_last.ul = 0;
25414 +       vdir->vd_last.p.deblk = vdir->vd_deblk[0];
25415 +       vdir->vd_version = 0;
25416 +       vdir->vd_jiffy = 0;
25417 +       /* smp_mb(); */
25418 +       return err;
25419 +}
25420 +
25421 +/* ---------------------------------------------------------------------- */
25422 +
25423 +#define AuFillVdir_CALLED      1
25424 +#define AuFillVdir_WHABLE      (1 << 1)
25425 +#define AuFillVdir_SHWH                (1 << 2)
25426 +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
25427 +#define au_fset_fillvdir(flags, name) \
25428 +       do { (flags) |= AuFillVdir_##name; } while (0)
25429 +#define au_fclr_fillvdir(flags, name) \
25430 +       do { (flags) &= ~AuFillVdir_##name; } while (0)
25431 +
25432 +#ifndef CONFIG_AUFS_SHWH
25433 +#undef AuFillVdir_SHWH
25434 +#define AuFillVdir_SHWH                0
25435 +#endif
25436 +
25437 +struct fillvdir_arg {
25438 +       struct file             *file;
25439 +       struct au_vdir          *vdir;
25440 +       struct au_nhash         delist;
25441 +       struct au_nhash         whlist;
25442 +       aufs_bindex_t           bindex;
25443 +       unsigned int            flags;
25444 +       int                     err;
25445 +};
25446 +
25447 +static int fillvdir(void *__arg, const char *__name, int nlen,
25448 +                   loff_t offset __maybe_unused, u64 h_ino,
25449 +                   unsigned int d_type)
25450 +{
25451 +       struct fillvdir_arg *arg = __arg;
25452 +       char *name = (void *)__name;
25453 +       struct super_block *sb;
25454 +       ino_t ino;
25455 +       const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
25456 +
25457 +       arg->err = 0;
25458 +       sb = arg->file->f_dentry->d_sb;
25459 +       au_fset_fillvdir(arg->flags, CALLED);
25460 +       /* smp_mb(); */
25461 +       if (nlen <= AUFS_WH_PFX_LEN
25462 +           || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
25463 +               if (test_known(&arg->delist, name, nlen)
25464 +                   || au_nhash_test_known_wh(&arg->whlist, name, nlen))
25465 +                       goto out; /* already exists or whiteouted */
25466 +
25467 +               sb = arg->file->f_dentry->d_sb;
25468 +               arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
25469 +               if (!arg->err) {
25470 +                       if (unlikely(nlen > AUFS_MAX_NAMELEN))
25471 +                               d_type = DT_UNKNOWN;
25472 +                       arg->err = append_de(arg->vdir, name, nlen, ino,
25473 +                                            d_type, &arg->delist);
25474 +               }
25475 +       } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
25476 +               name += AUFS_WH_PFX_LEN;
25477 +               nlen -= AUFS_WH_PFX_LEN;
25478 +               if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
25479 +                       goto out; /* already whiteouted */
25480 +
25481 +               if (shwh)
25482 +                       arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
25483 +                                            &ino);
25484 +               if (!arg->err) {
25485 +                       if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
25486 +                               d_type = DT_UNKNOWN;
25487 +                       arg->err = au_nhash_append_wh
25488 +                               (&arg->whlist, name, nlen, ino, d_type,
25489 +                                arg->bindex, shwh);
25490 +               }
25491 +       }
25492 +
25493 +out:
25494 +       if (!arg->err)
25495 +               arg->vdir->vd_jiffy = jiffies;
25496 +       /* smp_mb(); */
25497 +       AuTraceErr(arg->err);
25498 +       return arg->err;
25499 +}
25500 +
25501 +static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
25502 +                         struct au_nhash *whlist, struct au_nhash *delist)
25503 +{
25504 +#ifdef CONFIG_AUFS_SHWH
25505 +       int err;
25506 +       unsigned int nh, u;
25507 +       struct hlist_head *head;
25508 +       struct au_vdir_wh *tpos;
25509 +       struct hlist_node *pos, *n;
25510 +       char *p, *o;
25511 +       struct au_vdir_destr *destr;
25512 +
25513 +       AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
25514 +
25515 +       err = -ENOMEM;
25516 +       o = p = (void *)__get_free_page(GFP_NOFS);
25517 +       if (unlikely(!p))
25518 +               goto out;
25519 +
25520 +       err = 0;
25521 +       nh = whlist->nh_num;
25522 +       memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
25523 +       p += AUFS_WH_PFX_LEN;
25524 +       for (u = 0; u < nh; u++) {
25525 +               head = whlist->nh_head + u;
25526 +               hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) {
25527 +                       destr = &tpos->wh_str;
25528 +                       memcpy(p, destr->name, destr->len);
25529 +                       err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
25530 +                                       tpos->wh_ino, tpos->wh_type, delist);
25531 +                       if (unlikely(err))
25532 +                               break;
25533 +               }
25534 +       }
25535 +
25536 +       free_page((unsigned long)o);
25537 +
25538 +out:
25539 +       AuTraceErr(err);
25540 +       return err;
25541 +#else
25542 +       return 0;
25543 +#endif
25544 +}
25545 +
25546 +static int au_do_read_vdir(struct fillvdir_arg *arg)
25547 +{
25548 +       int err;
25549 +       unsigned int rdhash;
25550 +       loff_t offset;
25551 +       aufs_bindex_t bend, bindex, bstart;
25552 +       unsigned char shwh;
25553 +       struct file *hf, *file;
25554 +       struct super_block *sb;
25555 +
25556 +       file = arg->file;
25557 +       sb = file->f_dentry->d_sb;
25558 +       SiMustAnyLock(sb);
25559 +
25560 +       rdhash = au_sbi(sb)->si_rdhash;
25561 +       if (!rdhash)
25562 +               rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
25563 +       err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
25564 +       if (unlikely(err))
25565 +               goto out;
25566 +       err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
25567 +       if (unlikely(err))
25568 +               goto out_delist;
25569 +
25570 +       err = 0;
25571 +       arg->flags = 0;
25572 +       shwh = 0;
25573 +       if (au_opt_test(au_mntflags(sb), SHWH)) {
25574 +               shwh = 1;
25575 +               au_fset_fillvdir(arg->flags, SHWH);
25576 +       }
25577 +       bstart = au_fbstart(file);
25578 +       bend = au_fbend_dir(file);
25579 +       for (bindex = bstart; !err && bindex <= bend; bindex++) {
25580 +               hf = au_hf_dir(file, bindex);
25581 +               if (!hf)
25582 +                       continue;
25583 +
25584 +               offset = vfsub_llseek(hf, 0, SEEK_SET);
25585 +               err = offset;
25586 +               if (unlikely(offset))
25587 +                       break;
25588 +
25589 +               arg->bindex = bindex;
25590 +               au_fclr_fillvdir(arg->flags, WHABLE);
25591 +               if (shwh
25592 +                   || (bindex != bend
25593 +                       && au_br_whable(au_sbr_perm(sb, bindex))))
25594 +                       au_fset_fillvdir(arg->flags, WHABLE);
25595 +               do {
25596 +                       arg->err = 0;
25597 +                       au_fclr_fillvdir(arg->flags, CALLED);
25598 +                       /* smp_mb(); */
25599 +                       err = vfsub_readdir(hf, fillvdir, arg);
25600 +                       if (err >= 0)
25601 +                               err = arg->err;
25602 +               } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
25603 +       }
25604 +
25605 +       if (!err && shwh)
25606 +               err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
25607 +
25608 +       au_nhash_wh_free(&arg->whlist);
25609 +
25610 +out_delist:
25611 +       au_nhash_de_free(&arg->delist);
25612 +out:
25613 +       return err;
25614 +}
25615 +
25616 +static int read_vdir(struct file *file, int may_read)
25617 +{
25618 +       int err;
25619 +       unsigned long expire;
25620 +       unsigned char do_read;
25621 +       struct fillvdir_arg arg;
25622 +       struct inode *inode;
25623 +       struct au_vdir *vdir, *allocated;
25624 +
25625 +       err = 0;
25626 +       inode = file->f_dentry->d_inode;
25627 +       IMustLock(inode);
25628 +       SiMustAnyLock(inode->i_sb);
25629 +
25630 +       allocated = NULL;
25631 +       do_read = 0;
25632 +       expire = au_sbi(inode->i_sb)->si_rdcache;
25633 +       vdir = au_ivdir(inode);
25634 +       if (!vdir) {
25635 +               do_read = 1;
25636 +               vdir = alloc_vdir(file);
25637 +               err = PTR_ERR(vdir);
25638 +               if (IS_ERR(vdir))
25639 +                       goto out;
25640 +               err = 0;
25641 +               allocated = vdir;
25642 +       } else if (may_read
25643 +                  && (inode->i_version != vdir->vd_version
25644 +                      || time_after(jiffies, vdir->vd_jiffy + expire))) {
25645 +               do_read = 1;
25646 +               err = reinit_vdir(vdir);
25647 +               if (unlikely(err))
25648 +                       goto out;
25649 +       }
25650 +
25651 +       if (!do_read)
25652 +               return 0; /* success */
25653 +
25654 +       arg.file = file;
25655 +       arg.vdir = vdir;
25656 +       err = au_do_read_vdir(&arg);
25657 +       if (!err) {
25658 +               /* file->f_pos = 0; */
25659 +               vdir->vd_version = inode->i_version;
25660 +               vdir->vd_last.ul = 0;
25661 +               vdir->vd_last.p.deblk = vdir->vd_deblk[0];
25662 +               if (allocated)
25663 +                       au_set_ivdir(inode, allocated);
25664 +       } else if (allocated)
25665 +               au_vdir_free(allocated);
25666 +
25667 +out:
25668 +       return err;
25669 +}
25670 +
25671 +static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
25672 +{
25673 +       int err, rerr;
25674 +       unsigned long ul, n;
25675 +       const unsigned int deblk_sz = src->vd_deblk_sz;
25676 +
25677 +       AuDebugOn(tgt->vd_nblk != 1);
25678 +
25679 +       err = -ENOMEM;
25680 +       if (tgt->vd_nblk < src->vd_nblk) {
25681 +               unsigned char **p;
25682 +
25683 +               p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
25684 +                            GFP_NOFS);
25685 +               if (unlikely(!p))
25686 +                       goto out;
25687 +               tgt->vd_deblk = p;
25688 +       }
25689 +
25690 +       if (tgt->vd_deblk_sz != deblk_sz) {
25691 +               unsigned char *p;
25692 +
25693 +               tgt->vd_deblk_sz = deblk_sz;
25694 +               p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
25695 +               if (unlikely(!p))
25696 +                       goto out;
25697 +               tgt->vd_deblk[0] = p;
25698 +       }
25699 +       memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
25700 +       tgt->vd_version = src->vd_version;
25701 +       tgt->vd_jiffy = src->vd_jiffy;
25702 +
25703 +       n = src->vd_nblk;
25704 +       for (ul = 1; ul < n; ul++) {
25705 +               tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
25706 +                                           GFP_NOFS);
25707 +               if (unlikely(!tgt->vd_deblk[ul]))
25708 +                       goto out;
25709 +               tgt->vd_nblk++;
25710 +       }
25711 +       tgt->vd_nblk = n;
25712 +       tgt->vd_last.ul = tgt->vd_last.ul;
25713 +       tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
25714 +       tgt->vd_last.p.deblk += src->vd_last.p.deblk
25715 +               - src->vd_deblk[src->vd_last.ul];
25716 +       /* smp_mb(); */
25717 +       return 0; /* success */
25718 +
25719 +out:
25720 +       rerr = reinit_vdir(tgt);
25721 +       BUG_ON(rerr);
25722 +       return err;
25723 +}
25724 +
25725 +int au_vdir_init(struct file *file)
25726 +{
25727 +       int err;
25728 +       struct inode *inode;
25729 +       struct au_vdir *vdir_cache, *allocated;
25730 +
25731 +       err = read_vdir(file, !file->f_pos);
25732 +       if (unlikely(err))
25733 +               goto out;
25734 +
25735 +       allocated = NULL;
25736 +       vdir_cache = au_fvdir_cache(file);
25737 +       if (!vdir_cache) {
25738 +               vdir_cache = alloc_vdir(file);
25739 +               err = PTR_ERR(vdir_cache);
25740 +               if (IS_ERR(vdir_cache))
25741 +                       goto out;
25742 +               allocated = vdir_cache;
25743 +       } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
25744 +               err = reinit_vdir(vdir_cache);
25745 +               if (unlikely(err))
25746 +                       goto out;
25747 +       } else
25748 +               return 0; /* success */
25749 +
25750 +       inode = file->f_dentry->d_inode;
25751 +       err = copy_vdir(vdir_cache, au_ivdir(inode));
25752 +       if (!err) {
25753 +               file->f_version = inode->i_version;
25754 +               if (allocated)
25755 +                       au_set_fvdir_cache(file, allocated);
25756 +       } else if (allocated)
25757 +               au_vdir_free(allocated);
25758 +
25759 +out:
25760 +       return err;
25761 +}
25762 +
25763 +static loff_t calc_offset(struct au_vdir *vdir)
25764 +{
25765 +       loff_t offset;
25766 +       union au_vdir_deblk_p p;
25767 +
25768 +       p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
25769 +       offset = vdir->vd_last.p.deblk - p.deblk;
25770 +       offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
25771 +       return offset;
25772 +}
25773 +
25774 +/* returns true or false */
25775 +static int seek_vdir(struct file *file)
25776 +{
25777 +       int valid;
25778 +       unsigned int deblk_sz;
25779 +       unsigned long ul, n;
25780 +       loff_t offset;
25781 +       union au_vdir_deblk_p p, deblk_end;
25782 +       struct au_vdir *vdir_cache;
25783 +
25784 +       valid = 1;
25785 +       vdir_cache = au_fvdir_cache(file);
25786 +       offset = calc_offset(vdir_cache);
25787 +       AuDbg("offset %lld\n", offset);
25788 +       if (file->f_pos == offset)
25789 +               goto out;
25790 +
25791 +       vdir_cache->vd_last.ul = 0;
25792 +       vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
25793 +       if (!file->f_pos)
25794 +               goto out;
25795 +
25796 +       valid = 0;
25797 +       deblk_sz = vdir_cache->vd_deblk_sz;
25798 +       ul = div64_u64(file->f_pos, deblk_sz);
25799 +       AuDbg("ul %lu\n", ul);
25800 +       if (ul >= vdir_cache->vd_nblk)
25801 +               goto out;
25802 +
25803 +       n = vdir_cache->vd_nblk;
25804 +       for (; ul < n; ul++) {
25805 +               p.deblk = vdir_cache->vd_deblk[ul];
25806 +               deblk_end.deblk = p.deblk + deblk_sz;
25807 +               offset = ul;
25808 +               offset *= deblk_sz;
25809 +               while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) {
25810 +                       unsigned int l;
25811 +
25812 +                       l = calc_size(p.de->de_str.len);
25813 +                       offset += l;
25814 +                       p.deblk += l;
25815 +               }
25816 +               if (!is_deblk_end(&p, &deblk_end)) {
25817 +                       valid = 1;
25818 +                       vdir_cache->vd_last.ul = ul;
25819 +                       vdir_cache->vd_last.p = p;
25820 +                       break;
25821 +               }
25822 +       }
25823 +
25824 +out:
25825 +       /* smp_mb(); */
25826 +       AuTraceErr(!valid);
25827 +       return valid;
25828 +}
25829 +
25830 +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir)
25831 +{
25832 +       int err;
25833 +       unsigned int l, deblk_sz;
25834 +       union au_vdir_deblk_p deblk_end;
25835 +       struct au_vdir *vdir_cache;
25836 +       struct au_vdir_de *de;
25837 +
25838 +       vdir_cache = au_fvdir_cache(file);
25839 +       if (!seek_vdir(file))
25840 +               return 0;
25841 +
25842 +       deblk_sz = vdir_cache->vd_deblk_sz;
25843 +       while (1) {
25844 +               deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
25845 +               deblk_end.deblk += deblk_sz;
25846 +               while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
25847 +                       de = vdir_cache->vd_last.p.de;
25848 +                       AuDbg("%.*s, off%lld, i%lu, dt%d\n",
25849 +                             de->de_str.len, de->de_str.name, file->f_pos,
25850 +                             (unsigned long)de->de_ino, de->de_type);
25851 +                       err = filldir(dirent, de->de_str.name, de->de_str.len,
25852 +                                     file->f_pos, de->de_ino, de->de_type);
25853 +                       if (unlikely(err)) {
25854 +                               AuTraceErr(err);
25855 +                               /* todo: ignore the error caused by udba? */
25856 +                               /* return err; */
25857 +                               return 0;
25858 +                       }
25859 +
25860 +                       l = calc_size(de->de_str.len);
25861 +                       vdir_cache->vd_last.p.deblk += l;
25862 +                       file->f_pos += l;
25863 +               }
25864 +               if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
25865 +                       vdir_cache->vd_last.ul++;
25866 +                       vdir_cache->vd_last.p.deblk
25867 +                               = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
25868 +                       file->f_pos = deblk_sz * vdir_cache->vd_last.ul;
25869 +                       continue;
25870 +               }
25871 +               break;
25872 +       }
25873 +
25874 +       /* smp_mb(); */
25875 +       return 0;
25876 +}
25877 diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
25878 --- /usr/share/empty/fs/aufs/vfsub.c    1970-01-01 01:00:00.000000000 +0100
25879 +++ linux/fs/aufs/vfsub.c       2013-01-11 19:46:12.642614759 +0100
25880 @@ -0,0 +1,777 @@
25881 +/*
25882 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25883 + *
25884 + * This program, aufs is free software; you can redistribute it and/or modify
25885 + * it under the terms of the GNU General Public License as published by
25886 + * the Free Software Foundation; either version 2 of the License, or
25887 + * (at your option) any later version.
25888 + *
25889 + * This program is distributed in the hope that it will be useful,
25890 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25891 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25892 + * GNU General Public License for more details.
25893 + *
25894 + * You should have received a copy of the GNU General Public License
25895 + * along with this program; if not, write to the Free Software
25896 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25897 + */
25898 +
25899 +/*
25900 + * sub-routines for VFS
25901 + */
25902 +
25903 +#include <linux/ima.h>
25904 +#include <linux/namei.h>
25905 +#include <linux/security.h>
25906 +#include <linux/splice.h>
25907 +#include "aufs.h"
25908 +
25909 +int vfsub_update_h_iattr(struct path *h_path, int *did)
25910 +{
25911 +       int err;
25912 +       struct kstat st;
25913 +       struct super_block *h_sb;
25914 +
25915 +       /* for remote fs, leave work for its getattr or d_revalidate */
25916 +       /* for bad i_attr fs, handle them in aufs_getattr() */
25917 +       /* still some fs may acquire i_mutex. we need to skip them */
25918 +       err = 0;
25919 +       if (!did)
25920 +               did = &err;
25921 +       h_sb = h_path->dentry->d_sb;
25922 +       *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
25923 +       if (*did)
25924 +               err = vfs_getattr(h_path->mnt, h_path->dentry, &st);
25925 +
25926 +       return err;
25927 +}
25928 +
25929 +/* ---------------------------------------------------------------------- */
25930 +
25931 +struct file *vfsub_dentry_open(struct path *path, int flags)
25932 +{
25933 +       struct file *file;
25934 +
25935 +       file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
25936 +                          current_cred());
25937 +       if (!IS_ERR_OR_NULL(file)
25938 +           && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
25939 +               i_readcount_inc(path->dentry->d_inode);
25940 +
25941 +       return file;
25942 +}
25943 +
25944 +struct file *vfsub_filp_open(const char *path, int oflags, int mode)
25945 +{
25946 +       struct file *file;
25947 +
25948 +       lockdep_off();
25949 +       file = filp_open(path,
25950 +                        oflags /* | __FMODE_NONOTIFY */,
25951 +                        mode);
25952 +       lockdep_on();
25953 +       if (IS_ERR(file))
25954 +               goto out;
25955 +       vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
25956 +
25957 +out:
25958 +       return file;
25959 +}
25960 +
25961 +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
25962 +{
25963 +       int err;
25964 +
25965 +       err = kern_path(name, flags, path);
25966 +       if (!err && path->dentry->d_inode)
25967 +               vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
25968 +       return err;
25969 +}
25970 +
25971 +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
25972 +                                   int len)
25973 +{
25974 +       struct path path = {
25975 +               .mnt = NULL
25976 +       };
25977 +
25978 +       /* VFS checks it too, but by WARN_ON_ONCE() */
25979 +       IMustLock(parent->d_inode);
25980 +
25981 +       path.dentry = lookup_one_len(name, parent, len);
25982 +       if (IS_ERR(path.dentry))
25983 +               goto out;
25984 +       if (path.dentry->d_inode)
25985 +               vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
25986 +
25987 +out:
25988 +       AuTraceErrPtr(path.dentry);
25989 +       return path.dentry;
25990 +}
25991 +
25992 +void vfsub_call_lkup_one(void *args)
25993 +{
25994 +       struct vfsub_lkup_one_args *a = args;
25995 +       *a->errp = vfsub_lkup_one(a->name, a->parent);
25996 +}
25997 +
25998 +/* ---------------------------------------------------------------------- */
25999 +
26000 +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
26001 +                                struct dentry *d2, struct au_hinode *hdir2)
26002 +{
26003 +       struct dentry *d;
26004 +
26005 +       lockdep_off();
26006 +       d = lock_rename(d1, d2);
26007 +       lockdep_on();
26008 +       au_hn_suspend(hdir1);
26009 +       if (hdir1 != hdir2)
26010 +               au_hn_suspend(hdir2);
26011 +
26012 +       return d;
26013 +}
26014 +
26015 +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
26016 +                        struct dentry *d2, struct au_hinode *hdir2)
26017 +{
26018 +       au_hn_resume(hdir1);
26019 +       if (hdir1 != hdir2)
26020 +               au_hn_resume(hdir2);
26021 +       lockdep_off();
26022 +       unlock_rename(d1, d2);
26023 +       lockdep_on();
26024 +}
26025 +
26026 +/* ---------------------------------------------------------------------- */
26027 +
26028 +int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
26029 +{
26030 +       int err;
26031 +       struct dentry *d;
26032 +
26033 +       IMustLock(dir);
26034 +
26035 +       d = path->dentry;
26036 +       path->dentry = d->d_parent;
26037 +       err = security_path_mknod(path, d, mode, 0);
26038 +       path->dentry = d;
26039 +       if (unlikely(err))
26040 +               goto out;
26041 +
26042 +       err = vfs_create(dir, path->dentry, mode, want_excl);
26043 +       if (!err) {
26044 +               struct path tmp = *path;
26045 +               int did;
26046 +
26047 +               vfsub_update_h_iattr(&tmp, &did);
26048 +               if (did) {
26049 +                       tmp.dentry = path->dentry->d_parent;
26050 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26051 +               }
26052 +               /*ignore*/
26053 +       }
26054 +
26055 +out:
26056 +       return err;
26057 +}
26058 +
26059 +int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
26060 +{
26061 +       int err;
26062 +       struct dentry *d;
26063 +
26064 +       IMustLock(dir);
26065 +
26066 +       d = path->dentry;
26067 +       path->dentry = d->d_parent;
26068 +       err = security_path_symlink(path, d, symname);
26069 +       path->dentry = d;
26070 +       if (unlikely(err))
26071 +               goto out;
26072 +
26073 +       err = vfs_symlink(dir, path->dentry, symname);
26074 +       if (!err) {
26075 +               struct path tmp = *path;
26076 +               int did;
26077 +
26078 +               vfsub_update_h_iattr(&tmp, &did);
26079 +               if (did) {
26080 +                       tmp.dentry = path->dentry->d_parent;
26081 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26082 +               }
26083 +               /*ignore*/
26084 +       }
26085 +
26086 +out:
26087 +       return err;
26088 +}
26089 +
26090 +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
26091 +{
26092 +       int err;
26093 +       struct dentry *d;
26094 +
26095 +       IMustLock(dir);
26096 +
26097 +       d = path->dentry;
26098 +       path->dentry = d->d_parent;
26099 +       err = security_path_mknod(path, d, mode, new_encode_dev(dev));
26100 +       path->dentry = d;
26101 +       if (unlikely(err))
26102 +               goto out;
26103 +
26104 +       err = vfs_mknod(dir, path->dentry, mode, dev);
26105 +       if (!err) {
26106 +               struct path tmp = *path;
26107 +               int did;
26108 +
26109 +               vfsub_update_h_iattr(&tmp, &did);
26110 +               if (did) {
26111 +                       tmp.dentry = path->dentry->d_parent;
26112 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26113 +               }
26114 +               /*ignore*/
26115 +       }
26116 +
26117 +out:
26118 +       return err;
26119 +}
26120 +
26121 +static int au_test_nlink(struct inode *inode)
26122 +{
26123 +       const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
26124 +
26125 +       if (!au_test_fs_no_limit_nlink(inode->i_sb)
26126 +           || inode->i_nlink < link_max)
26127 +               return 0;
26128 +       return -EMLINK;
26129 +}
26130 +
26131 +int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
26132 +{
26133 +       int err;
26134 +       struct dentry *d;
26135 +
26136 +       IMustLock(dir);
26137 +
26138 +       err = au_test_nlink(src_dentry->d_inode);
26139 +       if (unlikely(err))
26140 +               return err;
26141 +
26142 +       /* we don't call may_linkat() */
26143 +       d = path->dentry;
26144 +       path->dentry = d->d_parent;
26145 +       err = security_path_link(src_dentry, path, d);
26146 +       path->dentry = d;
26147 +       if (unlikely(err))
26148 +               goto out;
26149 +
26150 +       lockdep_off();
26151 +       err = vfs_link(src_dentry, dir, path->dentry);
26152 +       lockdep_on();
26153 +       if (!err) {
26154 +               struct path tmp = *path;
26155 +               int did;
26156 +
26157 +               /* fuse has different memory inode for the same inumber */
26158 +               vfsub_update_h_iattr(&tmp, &did);
26159 +               if (did) {
26160 +                       tmp.dentry = path->dentry->d_parent;
26161 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26162 +                       tmp.dentry = src_dentry;
26163 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26164 +               }
26165 +               /*ignore*/
26166 +       }
26167 +
26168 +out:
26169 +       return err;
26170 +}
26171 +
26172 +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
26173 +                struct inode *dir, struct path *path)
26174 +{
26175 +       int err;
26176 +       struct path tmp = {
26177 +               .mnt    = path->mnt
26178 +       };
26179 +       struct dentry *d;
26180 +
26181 +       IMustLock(dir);
26182 +       IMustLock(src_dir);
26183 +
26184 +       d = path->dentry;
26185 +       path->dentry = d->d_parent;
26186 +       tmp.dentry = src_dentry->d_parent;
26187 +       err = security_path_rename(&tmp, src_dentry, path, d);
26188 +       path->dentry = d;
26189 +       if (unlikely(err))
26190 +               goto out;
26191 +
26192 +       lockdep_off();
26193 +       err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
26194 +       lockdep_on();
26195 +       if (!err) {
26196 +               int did;
26197 +
26198 +               tmp.dentry = d->d_parent;
26199 +               vfsub_update_h_iattr(&tmp, &did);
26200 +               if (did) {
26201 +                       tmp.dentry = src_dentry;
26202 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26203 +                       tmp.dentry = src_dentry->d_parent;
26204 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26205 +               }
26206 +               /*ignore*/
26207 +       }
26208 +
26209 +out:
26210 +       return err;
26211 +}
26212 +
26213 +int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
26214 +{
26215 +       int err;
26216 +       struct dentry *d;
26217 +
26218 +       IMustLock(dir);
26219 +
26220 +       d = path->dentry;
26221 +       path->dentry = d->d_parent;
26222 +       err = security_path_mkdir(path, d, mode);
26223 +       path->dentry = d;
26224 +       if (unlikely(err))
26225 +               goto out;
26226 +
26227 +       err = vfs_mkdir(dir, path->dentry, mode);
26228 +       if (!err) {
26229 +               struct path tmp = *path;
26230 +               int did;
26231 +
26232 +               vfsub_update_h_iattr(&tmp, &did);
26233 +               if (did) {
26234 +                       tmp.dentry = path->dentry->d_parent;
26235 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26236 +               }
26237 +               /*ignore*/
26238 +       }
26239 +
26240 +out:
26241 +       return err;
26242 +}
26243 +
26244 +int vfsub_rmdir(struct inode *dir, struct path *path)
26245 +{
26246 +       int err;
26247 +       struct dentry *d;
26248 +
26249 +       IMustLock(dir);
26250 +
26251 +       d = path->dentry;
26252 +       path->dentry = d->d_parent;
26253 +       err = security_path_rmdir(path, d);
26254 +       path->dentry = d;
26255 +       if (unlikely(err))
26256 +               goto out;
26257 +
26258 +       lockdep_off();
26259 +       err = vfs_rmdir(dir, path->dentry);
26260 +       lockdep_on();
26261 +       if (!err) {
26262 +               struct path tmp = {
26263 +                       .dentry = path->dentry->d_parent,
26264 +                       .mnt    = path->mnt
26265 +               };
26266 +
26267 +               vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
26268 +       }
26269 +
26270 +out:
26271 +       return err;
26272 +}
26273 +
26274 +/* ---------------------------------------------------------------------- */
26275 +
26276 +/* todo: support mmap_sem? */
26277 +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
26278 +                    loff_t *ppos)
26279 +{
26280 +       ssize_t err;
26281 +
26282 +       lockdep_off();
26283 +       err = vfs_read(file, ubuf, count, ppos);
26284 +       lockdep_on();
26285 +       if (err >= 0)
26286 +               vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26287 +       return err;
26288 +}
26289 +
26290 +/* todo: kernel_read()? */
26291 +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
26292 +                    loff_t *ppos)
26293 +{
26294 +       ssize_t err;
26295 +       mm_segment_t oldfs;
26296 +       union {
26297 +               void *k;
26298 +               char __user *u;
26299 +       } buf;
26300 +
26301 +       buf.k = kbuf;
26302 +       oldfs = get_fs();
26303 +       set_fs(KERNEL_DS);
26304 +       err = vfsub_read_u(file, buf.u, count, ppos);
26305 +       set_fs(oldfs);
26306 +       return err;
26307 +}
26308 +
26309 +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
26310 +                     loff_t *ppos)
26311 +{
26312 +       ssize_t err;
26313 +
26314 +       lockdep_off();
26315 +       err = vfs_write(file, ubuf, count, ppos);
26316 +       lockdep_on();
26317 +       if (err >= 0)
26318 +               vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26319 +       return err;
26320 +}
26321 +
26322 +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
26323 +{
26324 +       ssize_t err;
26325 +       mm_segment_t oldfs;
26326 +       union {
26327 +               void *k;
26328 +               const char __user *u;
26329 +       } buf;
26330 +
26331 +       buf.k = kbuf;
26332 +       oldfs = get_fs();
26333 +       set_fs(KERNEL_DS);
26334 +       err = vfsub_write_u(file, buf.u, count, ppos);
26335 +       set_fs(oldfs);
26336 +       return err;
26337 +}
26338 +
26339 +int vfsub_flush(struct file *file, fl_owner_t id)
26340 +{
26341 +       int err;
26342 +
26343 +       err = 0;
26344 +       if (file->f_op && file->f_op->flush) {
26345 +               if (!au_test_nfs(file->f_dentry->d_sb))
26346 +                       err = file->f_op->flush(file, id);
26347 +               else {
26348 +                       lockdep_off();
26349 +                       err = file->f_op->flush(file, id);
26350 +                       lockdep_on();
26351 +               }
26352 +               if (!err)
26353 +                       vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
26354 +               /*ignore*/
26355 +       }
26356 +       return err;
26357 +}
26358 +
26359 +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
26360 +{
26361 +       int err;
26362 +
26363 +       lockdep_off();
26364 +       err = vfs_readdir(file, filldir, arg);
26365 +       lockdep_on();
26366 +       if (err >= 0)
26367 +               vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26368 +       return err;
26369 +}
26370 +
26371 +long vfsub_splice_to(struct file *in, loff_t *ppos,
26372 +                    struct pipe_inode_info *pipe, size_t len,
26373 +                    unsigned int flags)
26374 +{
26375 +       long err;
26376 +
26377 +       lockdep_off();
26378 +       err = do_splice_to(in, ppos, pipe, len, flags);
26379 +       lockdep_on();
26380 +       file_accessed(in);
26381 +       if (err >= 0)
26382 +               vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
26383 +       return err;
26384 +}
26385 +
26386 +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
26387 +                      loff_t *ppos, size_t len, unsigned int flags)
26388 +{
26389 +       long err;
26390 +
26391 +       lockdep_off();
26392 +       err = do_splice_from(pipe, out, ppos, len, flags);
26393 +       lockdep_on();
26394 +       if (err >= 0)
26395 +               vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
26396 +       return err;
26397 +}
26398 +
26399 +int vfsub_fsync(struct file *file, struct path *path, int datasync)
26400 +{
26401 +       int err;
26402 +
26403 +       /* file can be NULL */
26404 +       lockdep_off();
26405 +       err = vfs_fsync(file, datasync);
26406 +       lockdep_on();
26407 +       if (!err) {
26408 +               if (!path) {
26409 +                       AuDebugOn(!file);
26410 +                       path = &file->f_path;
26411 +               }
26412 +               vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
26413 +       }
26414 +       return err;
26415 +}
26416 +
26417 +/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
26418 +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
26419 +               struct file *h_file)
26420 +{
26421 +       int err;
26422 +       struct inode *h_inode;
26423 +
26424 +       h_inode = h_path->dentry->d_inode;
26425 +       if (!h_file) {
26426 +               err = vfsub_mnt_want_write(h_path->mnt);
26427 +               if (err)
26428 +                       goto out;
26429 +               err = inode_permission(h_inode, MAY_WRITE);
26430 +               if (err)
26431 +                       goto out_mnt;
26432 +               err = get_write_access(h_inode);
26433 +               if (err)
26434 +                       goto out_mnt;
26435 +               err = break_lease(h_inode, O_WRONLY);
26436 +               if (err)
26437 +                       goto out_inode;
26438 +       }
26439 +
26440 +       err = locks_verify_truncate(h_inode, h_file, length);
26441 +       if (!err)
26442 +               err = security_path_truncate(h_path);
26443 +       if (!err) {
26444 +               lockdep_off();
26445 +               err = do_truncate(h_path->dentry, length, attr, h_file);
26446 +               lockdep_on();
26447 +       }
26448 +
26449 +out_inode:
26450 +       if (!h_file)
26451 +               put_write_access(h_inode);
26452 +out_mnt:
26453 +       if (!h_file)
26454 +               vfsub_mnt_drop_write(h_path->mnt);
26455 +out:
26456 +       return err;
26457 +}
26458 +
26459 +/* ---------------------------------------------------------------------- */
26460 +
26461 +struct au_vfsub_mkdir_args {
26462 +       int *errp;
26463 +       struct inode *dir;
26464 +       struct path *path;
26465 +       int mode;
26466 +};
26467 +
26468 +static void au_call_vfsub_mkdir(void *args)
26469 +{
26470 +       struct au_vfsub_mkdir_args *a = args;
26471 +       *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
26472 +}
26473 +
26474 +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
26475 +{
26476 +       int err, do_sio, wkq_err;
26477 +
26478 +       do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
26479 +       if (!do_sio)
26480 +               err = vfsub_mkdir(dir, path, mode);
26481 +       else {
26482 +               struct au_vfsub_mkdir_args args = {
26483 +                       .errp   = &err,
26484 +                       .dir    = dir,
26485 +                       .path   = path,
26486 +                       .mode   = mode
26487 +               };
26488 +               wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
26489 +               if (unlikely(wkq_err))
26490 +                       err = wkq_err;
26491 +       }
26492 +
26493 +       return err;
26494 +}
26495 +
26496 +struct au_vfsub_rmdir_args {
26497 +       int *errp;
26498 +       struct inode *dir;
26499 +       struct path *path;
26500 +};
26501 +
26502 +static void au_call_vfsub_rmdir(void *args)
26503 +{
26504 +       struct au_vfsub_rmdir_args *a = args;
26505 +       *a->errp = vfsub_rmdir(a->dir, a->path);
26506 +}
26507 +
26508 +int vfsub_sio_rmdir(struct inode *dir, struct path *path)
26509 +{
26510 +       int err, do_sio, wkq_err;
26511 +
26512 +       do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
26513 +       if (!do_sio)
26514 +               err = vfsub_rmdir(dir, path);
26515 +       else {
26516 +               struct au_vfsub_rmdir_args args = {
26517 +                       .errp   = &err,
26518 +                       .dir    = dir,
26519 +                       .path   = path
26520 +               };
26521 +               wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
26522 +               if (unlikely(wkq_err))
26523 +                       err = wkq_err;
26524 +       }
26525 +
26526 +       return err;
26527 +}
26528 +
26529 +/* ---------------------------------------------------------------------- */
26530 +
26531 +struct notify_change_args {
26532 +       int *errp;
26533 +       struct path *path;
26534 +       struct iattr *ia;
26535 +};
26536 +
26537 +static void call_notify_change(void *args)
26538 +{
26539 +       struct notify_change_args *a = args;
26540 +       struct inode *h_inode;
26541 +
26542 +       h_inode = a->path->dentry->d_inode;
26543 +       IMustLock(h_inode);
26544 +
26545 +       *a->errp = -EPERM;
26546 +       if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
26547 +               *a->errp = notify_change(a->path->dentry, a->ia);
26548 +               if (!*a->errp)
26549 +                       vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
26550 +       }
26551 +       AuTraceErr(*a->errp);
26552 +}
26553 +
26554 +int vfsub_notify_change(struct path *path, struct iattr *ia)
26555 +{
26556 +       int err;
26557 +       struct notify_change_args args = {
26558 +               .errp   = &err,
26559 +               .path   = path,
26560 +               .ia     = ia
26561 +       };
26562 +
26563 +       call_notify_change(&args);
26564 +
26565 +       return err;
26566 +}
26567 +
26568 +int vfsub_sio_notify_change(struct path *path, struct iattr *ia)
26569 +{
26570 +       int err, wkq_err;
26571 +       struct notify_change_args args = {
26572 +               .errp   = &err,
26573 +               .path   = path,
26574 +               .ia     = ia
26575 +       };
26576 +
26577 +       wkq_err = au_wkq_wait(call_notify_change, &args);
26578 +       if (unlikely(wkq_err))
26579 +               err = wkq_err;
26580 +
26581 +       return err;
26582 +}
26583 +
26584 +/* ---------------------------------------------------------------------- */
26585 +
26586 +struct unlink_args {
26587 +       int *errp;
26588 +       struct inode *dir;
26589 +       struct path *path;
26590 +};
26591 +
26592 +static void call_unlink(void *args)
26593 +{
26594 +       struct unlink_args *a = args;
26595 +       struct dentry *d = a->path->dentry;
26596 +       struct inode *h_inode;
26597 +       const int stop_sillyrename = (au_test_nfs(d->d_sb)
26598 +                                     && d->d_count == 1);
26599 +
26600 +       IMustLock(a->dir);
26601 +
26602 +       a->path->dentry = d->d_parent;
26603 +       *a->errp = security_path_unlink(a->path, d);
26604 +       a->path->dentry = d;
26605 +       if (unlikely(*a->errp))
26606 +               return;
26607 +
26608 +       if (!stop_sillyrename)
26609 +               dget(d);
26610 +       h_inode = d->d_inode;
26611 +       if (h_inode)
26612 +               ihold(h_inode);
26613 +
26614 +       lockdep_off();
26615 +       *a->errp = vfs_unlink(a->dir, d);
26616 +       lockdep_on();
26617 +       if (!*a->errp) {
26618 +               struct path tmp = {
26619 +                       .dentry = d->d_parent,
26620 +                       .mnt    = a->path->mnt
26621 +               };
26622 +               vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
26623 +       }
26624 +
26625 +       if (!stop_sillyrename)
26626 +               dput(d);
26627 +       if (h_inode)
26628 +               iput(h_inode);
26629 +
26630 +       AuTraceErr(*a->errp);
26631 +}
26632 +
26633 +/*
26634 + * @dir: must be locked.
26635 + * @dentry: target dentry.
26636 + */
26637 +int vfsub_unlink(struct inode *dir, struct path *path, int force)
26638 +{
26639 +       int err;
26640 +       struct unlink_args args = {
26641 +               .errp   = &err,
26642 +               .dir    = dir,
26643 +               .path   = path
26644 +       };
26645 +
26646 +       if (!force)
26647 +               call_unlink(&args);
26648 +       else {
26649 +               int wkq_err;
26650 +
26651 +               wkq_err = au_wkq_wait(call_unlink, &args);
26652 +               if (unlikely(wkq_err))
26653 +                       err = wkq_err;
26654 +       }
26655 +
26656 +       return err;
26657 +}
26658 diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
26659 --- /usr/share/empty/fs/aufs/vfsub.h    1970-01-01 01:00:00.000000000 +0100
26660 +++ linux/fs/aufs/vfsub.h       2013-01-11 19:46:12.642614759 +0100
26661 @@ -0,0 +1,284 @@
26662 +/*
26663 + * Copyright (C) 2005-2013 Junjiro R. Okajima
26664 + *
26665 + * This program, aufs is free software; you can redistribute it and/or modify
26666 + * it under the terms of the GNU General Public License as published by
26667 + * the Free Software Foundation; either version 2 of the License, or
26668 + * (at your option) any later version.
26669 + *
26670 + * This program is distributed in the hope that it will be useful,
26671 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
26672 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26673 + * GNU General Public License for more details.
26674 + *
26675 + * You should have received a copy of the GNU General Public License
26676 + * along with this program; if not, write to the Free Software
26677 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
26678 + */
26679 +
26680 +/*
26681 + * sub-routines for VFS
26682 + */
26683 +
26684 +#ifndef __AUFS_VFSUB_H__
26685 +#define __AUFS_VFSUB_H__
26686 +
26687 +#ifdef __KERNEL__
26688 +
26689 +#include <linux/fs.h>
26690 +#include <linux/lglock.h>
26691 +#include <linux/mount.h>
26692 +#include "debug.h"
26693 +
26694 +/* copied from linux/fs/internal.h */
26695 +/* todo: BAD approach!! */
26696 +extern struct lglock vfsmount_lock;
26697 +extern spinlock_t inode_sb_list_lock;
26698 +
26699 +/* copied from linux/fs/file_table.c */
26700 +extern struct lglock files_lglock;
26701 +#ifdef CONFIG_SMP
26702 +/*
26703 + * These macros iterate all files on all CPUs for a given superblock.
26704 + * files_lglock must be held globally.
26705 + */
26706 +#define do_file_list_for_each_entry(__sb, __file)              \
26707 +{                                                              \
26708 +       int i;                                                  \
26709 +       for_each_possible_cpu(i) {                              \
26710 +               struct list_head *list;                         \
26711 +               list = per_cpu_ptr((__sb)->s_files, i);         \
26712 +               list_for_each_entry((__file), list, f_u.fu_list)
26713 +
26714 +#define while_file_list_for_each_entry                         \
26715 +       }                                                       \
26716 +}
26717 +
26718 +#else
26719 +
26720 +#define do_file_list_for_each_entry(__sb, __file)              \
26721 +{                                                              \
26722 +       struct list_head *list;                                 \
26723 +       list = &(sb)->s_files;                                  \
26724 +       list_for_each_entry((__file), list, f_u.fu_list)
26725 +
26726 +#define while_file_list_for_each_entry                         \
26727 +}
26728 +#endif
26729 +
26730 +/* ---------------------------------------------------------------------- */
26731 +
26732 +/* lock subclass for lower inode */
26733 +/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
26734 +/* reduce? gave up. */
26735 +enum {
26736 +       AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
26737 +       AuLsc_I_PARENT,         /* lower inode, parent first */
26738 +       AuLsc_I_PARENT2,        /* copyup dirs */
26739 +       AuLsc_I_PARENT3,        /* copyup wh */
26740 +       AuLsc_I_CHILD,
26741 +       AuLsc_I_CHILD2,
26742 +       AuLsc_I_End
26743 +};
26744 +
26745 +/* to debug easier, do not make them inlined functions */
26746 +#define MtxMustLock(mtx)       AuDebugOn(!mutex_is_locked(mtx))
26747 +#define IMustLock(i)           MtxMustLock(&(i)->i_mutex)
26748 +
26749 +/* ---------------------------------------------------------------------- */
26750 +
26751 +static inline void vfsub_drop_nlink(struct inode *inode)
26752 +{
26753 +       AuDebugOn(!inode->i_nlink);
26754 +       drop_nlink(inode);
26755 +}
26756 +
26757 +static inline void vfsub_dead_dir(struct inode *inode)
26758 +{
26759 +       AuDebugOn(!S_ISDIR(inode->i_mode));
26760 +       inode->i_flags |= S_DEAD;
26761 +       clear_nlink(inode);
26762 +}
26763 +
26764 +/* ---------------------------------------------------------------------- */
26765 +
26766 +/* cf. i_[ug]id_read() in linux/include/fs.h */
26767 +static inline uid_t vfsub_ia_uid(struct iattr *ia)
26768 +{
26769 +       return from_kuid(&init_user_ns, ia->ia_uid);
26770 +}
26771 +
26772 +static inline gid_t vfsub_ia_gid(struct iattr *ia)
26773 +{
26774 +       return from_kgid(&init_user_ns, ia->ia_gid);
26775 +}
26776 +
26777 +/* ---------------------------------------------------------------------- */
26778 +
26779 +int vfsub_update_h_iattr(struct path *h_path, int *did);
26780 +struct file *vfsub_dentry_open(struct path *path, int flags);
26781 +struct file *vfsub_filp_open(const char *path, int oflags, int mode);
26782 +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
26783 +
26784 +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
26785 +                                   int len);
26786 +
26787 +struct vfsub_lkup_one_args {
26788 +       struct dentry **errp;
26789 +       struct qstr *name;
26790 +       struct dentry *parent;
26791 +};
26792 +
26793 +static inline struct dentry *vfsub_lkup_one(struct qstr *name,
26794 +                                           struct dentry *parent)
26795 +{
26796 +       return vfsub_lookup_one_len(name->name, parent, name->len);
26797 +}
26798 +
26799 +void vfsub_call_lkup_one(void *args);
26800 +
26801 +/* ---------------------------------------------------------------------- */
26802 +
26803 +static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
26804 +{
26805 +       int err;
26806 +       lockdep_off();
26807 +       err = mnt_want_write(mnt);
26808 +       lockdep_on();
26809 +       return err;
26810 +}
26811 +
26812 +static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
26813 +{
26814 +       lockdep_off();
26815 +       mnt_drop_write(mnt);
26816 +       lockdep_on();
26817 +}
26818 +
26819 +/* ---------------------------------------------------------------------- */
26820 +
26821 +struct au_hinode;
26822 +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
26823 +                                struct dentry *d2, struct au_hinode *hdir2);
26824 +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
26825 +                        struct dentry *d2, struct au_hinode *hdir2);
26826 +
26827 +int vfsub_create(struct inode *dir, struct path *path, int mode,
26828 +                bool want_excl);
26829 +int vfsub_symlink(struct inode *dir, struct path *path,
26830 +                 const char *symname);
26831 +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
26832 +int vfsub_link(struct dentry *src_dentry, struct inode *dir,
26833 +              struct path *path);
26834 +int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
26835 +                struct inode *hdir, struct path *path);
26836 +int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
26837 +int vfsub_rmdir(struct inode *dir, struct path *path);
26838 +
26839 +/* ---------------------------------------------------------------------- */
26840 +
26841 +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
26842 +                    loff_t *ppos);
26843 +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
26844 +                       loff_t *ppos);
26845 +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
26846 +                     loff_t *ppos);
26847 +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
26848 +                     loff_t *ppos);
26849 +int vfsub_flush(struct file *file, fl_owner_t id);
26850 +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
26851 +
26852 +static inline unsigned int vfsub_file_flags(struct file *file)
26853 +{
26854 +       unsigned int flags;
26855 +
26856 +       spin_lock(&file->f_lock);
26857 +       flags = file->f_flags;
26858 +       spin_unlock(&file->f_lock);
26859 +
26860 +       return flags;
26861 +}
26862 +
26863 +static inline void vfsub_file_accessed(struct file *h_file)
26864 +{
26865 +       file_accessed(h_file);
26866 +       vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
26867 +}
26868 +
26869 +static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
26870 +                                    struct dentry *h_dentry)
26871 +{
26872 +       struct path h_path = {
26873 +               .dentry = h_dentry,
26874 +               .mnt    = h_mnt
26875 +       };
26876 +       touch_atime(&h_path);
26877 +       vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
26878 +}
26879 +
26880 +static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
26881 +                                   int flags)
26882 +{
26883 +       return update_time(h_inode, ts, flags);
26884 +       /* no vfsub_update_h_iattr() since we don't have struct path */
26885 +}
26886 +
26887 +long vfsub_splice_to(struct file *in, loff_t *ppos,
26888 +                    struct pipe_inode_info *pipe, size_t len,
26889 +                    unsigned int flags);
26890 +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
26891 +                      loff_t *ppos, size_t len, unsigned int flags);
26892 +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
26893 +               struct file *h_file);
26894 +int vfsub_fsync(struct file *file, struct path *path, int datasync);
26895 +
26896 +/* ---------------------------------------------------------------------- */
26897 +
26898 +static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
26899 +{
26900 +       loff_t err;
26901 +
26902 +       lockdep_off();
26903 +       err = vfs_llseek(file, offset, origin);
26904 +       lockdep_on();
26905 +       return err;
26906 +}
26907 +
26908 +/* ---------------------------------------------------------------------- */
26909 +
26910 +/* dirty workaround for strict type of fmode_t */
26911 +union vfsub_fmu {
26912 +       fmode_t fm;
26913 +       unsigned int ui;
26914 +};
26915 +
26916 +static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
26917 +{
26918 +       union vfsub_fmu u = {
26919 +               .fm = fm
26920 +       };
26921 +
26922 +       BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
26923 +
26924 +       return u.ui;
26925 +}
26926 +
26927 +static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
26928 +{
26929 +       union vfsub_fmu u = {
26930 +               .ui = ui
26931 +       };
26932 +
26933 +       return u.fm;
26934 +}
26935 +
26936 +/* ---------------------------------------------------------------------- */
26937 +
26938 +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
26939 +int vfsub_sio_rmdir(struct inode *dir, struct path *path);
26940 +int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
26941 +int vfsub_notify_change(struct path *path, struct iattr *ia);
26942 +int vfsub_unlink(struct inode *dir, struct path *path, int force);
26943 +
26944 +#endif /* __KERNEL__ */
26945 +#endif /* __AUFS_VFSUB_H__ */
26946 diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
26947 --- /usr/share/empty/fs/aufs/wbr_policy.c       1970-01-01 01:00:00.000000000 +0100
26948 +++ linux/fs/aufs/wbr_policy.c  2013-01-11 19:46:12.642614759 +0100
26949 @@ -0,0 +1,700 @@
26950 +/*
26951 + * Copyright (C) 2005-2013 Junjiro R. Okajima
26952 + *
26953 + * This program, aufs is free software; you can redistribute it and/or modify
26954 + * it under the terms of the GNU General Public License as published by
26955 + * the Free Software Foundation; either version 2 of the License, or
26956 + * (at your option) any later version.
26957 + *
26958 + * This program is distributed in the hope that it will be useful,
26959 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
26960 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26961 + * GNU General Public License for more details.
26962 + *
26963 + * You should have received a copy of the GNU General Public License
26964 + * along with this program; if not, write to the Free Software
26965 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
26966 + */
26967 +
26968 +/*
26969 + * policies for selecting one among multiple writable branches
26970 + */
26971 +
26972 +#include <linux/statfs.h>
26973 +#include "aufs.h"
26974 +
26975 +/* subset of cpup_attr() */
26976 +static noinline_for_stack
26977 +int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
26978 +{
26979 +       int err, sbits;
26980 +       struct iattr ia;
26981 +       struct inode *h_isrc;
26982 +
26983 +       h_isrc = h_src->d_inode;
26984 +       ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
26985 +       ia.ia_mode = h_isrc->i_mode;
26986 +       ia.ia_uid = h_isrc->i_uid;
26987 +       ia.ia_gid = h_isrc->i_gid;
26988 +       sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
26989 +       au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc);
26990 +       err = vfsub_sio_notify_change(h_path, &ia);
26991 +
26992 +       /* is this nfs only? */
26993 +       if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
26994 +               ia.ia_valid = ATTR_FORCE | ATTR_MODE;
26995 +               ia.ia_mode = h_isrc->i_mode;
26996 +               err = vfsub_sio_notify_change(h_path, &ia);
26997 +       }
26998 +
26999 +       return err;
27000 +}
27001 +
27002 +#define AuCpdown_PARENT_OPQ    1
27003 +#define AuCpdown_WHED          (1 << 1)
27004 +#define AuCpdown_MADE_DIR      (1 << 2)
27005 +#define AuCpdown_DIROPQ                (1 << 3)
27006 +#define au_ftest_cpdown(flags, name)   ((flags) & AuCpdown_##name)
27007 +#define au_fset_cpdown(flags, name) \
27008 +       do { (flags) |= AuCpdown_##name; } while (0)
27009 +#define au_fclr_cpdown(flags, name) \
27010 +       do { (flags) &= ~AuCpdown_##name; } while (0)
27011 +
27012 +struct au_cpdown_dir_args {
27013 +       struct dentry *parent;
27014 +       unsigned int flags;
27015 +};
27016 +
27017 +static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
27018 +                            struct au_cpdown_dir_args *a)
27019 +{
27020 +       int err;
27021 +       struct dentry *opq_dentry;
27022 +
27023 +       opq_dentry = au_diropq_create(dentry, bdst);
27024 +       err = PTR_ERR(opq_dentry);
27025 +       if (IS_ERR(opq_dentry))
27026 +               goto out;
27027 +       dput(opq_dentry);
27028 +       au_fset_cpdown(a->flags, DIROPQ);
27029 +
27030 +out:
27031 +       return err;
27032 +}
27033 +
27034 +static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
27035 +                           struct inode *dir, aufs_bindex_t bdst)
27036 +{
27037 +       int err;
27038 +       struct path h_path;
27039 +       struct au_branch *br;
27040 +
27041 +       br = au_sbr(dentry->d_sb, bdst);
27042 +       h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
27043 +       err = PTR_ERR(h_path.dentry);
27044 +       if (IS_ERR(h_path.dentry))
27045 +               goto out;
27046 +
27047 +       err = 0;
27048 +       if (h_path.dentry->d_inode) {
27049 +               h_path.mnt = br->br_mnt;
27050 +               err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
27051 +                                         dentry);
27052 +       }
27053 +       dput(h_path.dentry);
27054 +
27055 +out:
27056 +       return err;
27057 +}
27058 +
27059 +static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
27060 +                        struct dentry *h_parent, void *arg)
27061 +{
27062 +       int err, rerr;
27063 +       aufs_bindex_t bopq, bstart;
27064 +       struct path h_path;
27065 +       struct dentry *parent;
27066 +       struct inode *h_dir, *h_inode, *inode, *dir;
27067 +       struct au_cpdown_dir_args *args = arg;
27068 +
27069 +       bstart = au_dbstart(dentry);
27070 +       /* dentry is di-locked */
27071 +       parent = dget_parent(dentry);
27072 +       dir = parent->d_inode;
27073 +       h_dir = h_parent->d_inode;
27074 +       AuDebugOn(h_dir != au_h_iptr(dir, bdst));
27075 +       IMustLock(h_dir);
27076 +
27077 +       err = au_lkup_neg(dentry, bdst);
27078 +       if (unlikely(err < 0))
27079 +               goto out;
27080 +       h_path.dentry = au_h_dptr(dentry, bdst);
27081 +       h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
27082 +       err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
27083 +                             S_IRWXU | S_IRUGO | S_IXUGO);
27084 +       if (unlikely(err))
27085 +               goto out_put;
27086 +       au_fset_cpdown(args->flags, MADE_DIR);
27087 +
27088 +       bopq = au_dbdiropq(dentry);
27089 +       au_fclr_cpdown(args->flags, WHED);
27090 +       au_fclr_cpdown(args->flags, DIROPQ);
27091 +       if (au_dbwh(dentry) == bdst)
27092 +               au_fset_cpdown(args->flags, WHED);
27093 +       if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst)
27094 +               au_fset_cpdown(args->flags, PARENT_OPQ);
27095 +       h_inode = h_path.dentry->d_inode;
27096 +       mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
27097 +       if (au_ftest_cpdown(args->flags, WHED)) {
27098 +               err = au_cpdown_dir_opq(dentry, bdst, args);
27099 +               if (unlikely(err)) {
27100 +                       mutex_unlock(&h_inode->i_mutex);
27101 +                       goto out_dir;
27102 +               }
27103 +       }
27104 +
27105 +       err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
27106 +       mutex_unlock(&h_inode->i_mutex);
27107 +       if (unlikely(err))
27108 +               goto out_opq;
27109 +
27110 +       if (au_ftest_cpdown(args->flags, WHED)) {
27111 +               err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
27112 +               if (unlikely(err))
27113 +                       goto out_opq;
27114 +       }
27115 +
27116 +       inode = dentry->d_inode;
27117 +       if (au_ibend(inode) < bdst)
27118 +               au_set_ibend(inode, bdst);
27119 +       au_set_h_iptr(inode, bdst, au_igrab(h_inode),
27120 +                     au_hi_flags(inode, /*isdir*/1));
27121 +       goto out; /* success */
27122 +
27123 +       /* revert */
27124 +out_opq:
27125 +       if (au_ftest_cpdown(args->flags, DIROPQ)) {
27126 +               mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
27127 +               rerr = au_diropq_remove(dentry, bdst);
27128 +               mutex_unlock(&h_inode->i_mutex);
27129 +               if (unlikely(rerr)) {
27130 +                       AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
27131 +                               AuDLNPair(dentry), bdst, rerr);
27132 +                       err = -EIO;
27133 +                       goto out;
27134 +               }
27135 +       }
27136 +out_dir:
27137 +       if (au_ftest_cpdown(args->flags, MADE_DIR)) {
27138 +               rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
27139 +               if (unlikely(rerr)) {
27140 +                       AuIOErr("failed removing %.*s b%d (%d)\n",
27141 +                               AuDLNPair(dentry), bdst, rerr);
27142 +                       err = -EIO;
27143 +               }
27144 +       }
27145 +out_put:
27146 +       au_set_h_dptr(dentry, bdst, NULL);
27147 +       if (au_dbend(dentry) == bdst)
27148 +               au_update_dbend(dentry);
27149 +out:
27150 +       dput(parent);
27151 +       return err;
27152 +}
27153 +
27154 +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
27155 +{
27156 +       int err;
27157 +       struct au_cpdown_dir_args args = {
27158 +               .parent = dget_parent(dentry),
27159 +               .flags  = 0
27160 +       };
27161 +
27162 +       err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args);
27163 +       dput(args.parent);
27164 +
27165 +       return err;
27166 +}
27167 +
27168 +/* ---------------------------------------------------------------------- */
27169 +
27170 +/* policies for create */
27171 +
27172 +static int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
27173 +{
27174 +       int err, i, j, ndentry;
27175 +       aufs_bindex_t bopq;
27176 +       struct au_dcsub_pages dpages;
27177 +       struct au_dpage *dpage;
27178 +       struct dentry **dentries, *parent, *d;
27179 +
27180 +       err = au_dpages_init(&dpages, GFP_NOFS);
27181 +       if (unlikely(err))
27182 +               goto out;
27183 +       parent = dget_parent(dentry);
27184 +       err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
27185 +       if (unlikely(err))
27186 +               goto out_free;
27187 +
27188 +       err = bindex;
27189 +       for (i = 0; i < dpages.ndpage; i++) {
27190 +               dpage = dpages.dpages + i;
27191 +               dentries = dpage->dentries;
27192 +               ndentry = dpage->ndentry;
27193 +               for (j = 0; j < ndentry; j++) {
27194 +                       d = dentries[j];
27195 +                       di_read_lock_parent2(d, !AuLock_IR);
27196 +                       bopq = au_dbdiropq(d);
27197 +                       di_read_unlock(d, !AuLock_IR);
27198 +                       if (bopq >= 0 && bopq < err)
27199 +                               err = bopq;
27200 +               }
27201 +       }
27202 +
27203 +out_free:
27204 +       dput(parent);
27205 +       au_dpages_free(&dpages);
27206 +out:
27207 +       return err;
27208 +}
27209 +
27210 +static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
27211 +{
27212 +       for (; bindex >= 0; bindex--)
27213 +               if (!au_br_rdonly(au_sbr(sb, bindex)))
27214 +                       return bindex;
27215 +       return -EROFS;
27216 +}
27217 +
27218 +/* top down parent */
27219 +static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused)
27220 +{
27221 +       int err;
27222 +       aufs_bindex_t bstart, bindex;
27223 +       struct super_block *sb;
27224 +       struct dentry *parent, *h_parent;
27225 +
27226 +       sb = dentry->d_sb;
27227 +       bstart = au_dbstart(dentry);
27228 +       err = bstart;
27229 +       if (!au_br_rdonly(au_sbr(sb, bstart)))
27230 +               goto out;
27231 +
27232 +       err = -EROFS;
27233 +       parent = dget_parent(dentry);
27234 +       for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
27235 +               h_parent = au_h_dptr(parent, bindex);
27236 +               if (!h_parent || !h_parent->d_inode)
27237 +                       continue;
27238 +
27239 +               if (!au_br_rdonly(au_sbr(sb, bindex))) {
27240 +                       err = bindex;
27241 +                       break;
27242 +               }
27243 +       }
27244 +       dput(parent);
27245 +
27246 +       /* bottom up here */
27247 +       if (unlikely(err < 0)) {
27248 +               err = au_wbr_bu(sb, bstart - 1);
27249 +               if (err >= 0)
27250 +                       err = au_wbr_nonopq(dentry, err);
27251 +       }
27252 +
27253 +out:
27254 +       AuDbg("b%d\n", err);
27255 +       return err;
27256 +}
27257 +
27258 +/* ---------------------------------------------------------------------- */
27259 +
27260 +/* an exception for the policy other than tdp */
27261 +static int au_wbr_create_exp(struct dentry *dentry)
27262 +{
27263 +       int err;
27264 +       aufs_bindex_t bwh, bdiropq;
27265 +       struct dentry *parent;
27266 +
27267 +       err = -1;
27268 +       bwh = au_dbwh(dentry);
27269 +       parent = dget_parent(dentry);
27270 +       bdiropq = au_dbdiropq(parent);
27271 +       if (bwh >= 0) {
27272 +               if (bdiropq >= 0)
27273 +                       err = min(bdiropq, bwh);
27274 +               else
27275 +                       err = bwh;
27276 +               AuDbg("%d\n", err);
27277 +       } else if (bdiropq >= 0) {
27278 +               err = bdiropq;
27279 +               AuDbg("%d\n", err);
27280 +       }
27281 +       dput(parent);
27282 +
27283 +       if (err >= 0)
27284 +               err = au_wbr_nonopq(dentry, err);
27285 +
27286 +       if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
27287 +               err = -1;
27288 +
27289 +       AuDbg("%d\n", err);
27290 +       return err;
27291 +}
27292 +
27293 +/* ---------------------------------------------------------------------- */
27294 +
27295 +/* round robin */
27296 +static int au_wbr_create_init_rr(struct super_block *sb)
27297 +{
27298 +       int err;
27299 +
27300 +       err = au_wbr_bu(sb, au_sbend(sb));
27301 +       atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
27302 +       /* smp_mb(); */
27303 +
27304 +       AuDbg("b%d\n", err);
27305 +       return err;
27306 +}
27307 +
27308 +static int au_wbr_create_rr(struct dentry *dentry, int isdir)
27309 +{
27310 +       int err, nbr;
27311 +       unsigned int u;
27312 +       aufs_bindex_t bindex, bend;
27313 +       struct super_block *sb;
27314 +       atomic_t *next;
27315 +
27316 +       err = au_wbr_create_exp(dentry);
27317 +       if (err >= 0)
27318 +               goto out;
27319 +
27320 +       sb = dentry->d_sb;
27321 +       next = &au_sbi(sb)->si_wbr_rr_next;
27322 +       bend = au_sbend(sb);
27323 +       nbr = bend + 1;
27324 +       for (bindex = 0; bindex <= bend; bindex++) {
27325 +               if (!isdir) {
27326 +                       err = atomic_dec_return(next) + 1;
27327 +                       /* modulo for 0 is meaningless */
27328 +                       if (unlikely(!err))
27329 +                               err = atomic_dec_return(next) + 1;
27330 +               } else
27331 +                       err = atomic_read(next);
27332 +               AuDbg("%d\n", err);
27333 +               u = err;
27334 +               err = u % nbr;
27335 +               AuDbg("%d\n", err);
27336 +               if (!au_br_rdonly(au_sbr(sb, err)))
27337 +                       break;
27338 +               err = -EROFS;
27339 +       }
27340 +
27341 +       if (err >= 0)
27342 +               err = au_wbr_nonopq(dentry, err);
27343 +
27344 +out:
27345 +       AuDbg("%d\n", err);
27346 +       return err;
27347 +}
27348 +
27349 +/* ---------------------------------------------------------------------- */
27350 +
27351 +/* most free space */
27352 +static void au_mfs(struct dentry *dentry)
27353 +{
27354 +       struct super_block *sb;
27355 +       struct au_branch *br;
27356 +       struct au_wbr_mfs *mfs;
27357 +       aufs_bindex_t bindex, bend;
27358 +       int err;
27359 +       unsigned long long b, bavail;
27360 +       struct path h_path;
27361 +       /* reduce the stack usage */
27362 +       struct kstatfs *st;
27363 +
27364 +       st = kmalloc(sizeof(*st), GFP_NOFS);
27365 +       if (unlikely(!st)) {
27366 +               AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
27367 +               return;
27368 +       }
27369 +
27370 +       bavail = 0;
27371 +       sb = dentry->d_sb;
27372 +       mfs = &au_sbi(sb)->si_wbr_mfs;
27373 +       MtxMustLock(&mfs->mfs_lock);
27374 +       mfs->mfs_bindex = -EROFS;
27375 +       mfs->mfsrr_bytes = 0;
27376 +       bend = au_sbend(sb);
27377 +       for (bindex = 0; bindex <= bend; bindex++) {
27378 +               br = au_sbr(sb, bindex);
27379 +               if (au_br_rdonly(br))
27380 +                       continue;
27381 +
27382 +               /* sb->s_root for NFS is unreliable */
27383 +               h_path.mnt = br->br_mnt;
27384 +               h_path.dentry = h_path.mnt->mnt_root;
27385 +               err = vfs_statfs(&h_path, st);
27386 +               if (unlikely(err)) {
27387 +                       AuWarn1("failed statfs, b%d, %d\n", bindex, err);
27388 +                       continue;
27389 +               }
27390 +
27391 +               /* when the available size is equal, select the lower one */
27392 +               BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
27393 +                            || sizeof(b) < sizeof(st->f_bsize));
27394 +               b = st->f_bavail * st->f_bsize;
27395 +               br->br_wbr->wbr_bytes = b;
27396 +               if (b >= bavail) {
27397 +                       bavail = b;
27398 +                       mfs->mfs_bindex = bindex;
27399 +                       mfs->mfs_jiffy = jiffies;
27400 +               }
27401 +       }
27402 +
27403 +       mfs->mfsrr_bytes = bavail;
27404 +       AuDbg("b%d\n", mfs->mfs_bindex);
27405 +       kfree(st);
27406 +}
27407 +
27408 +static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused)
27409 +{
27410 +       int err;
27411 +       struct super_block *sb;
27412 +       struct au_wbr_mfs *mfs;
27413 +
27414 +       err = au_wbr_create_exp(dentry);
27415 +       if (err >= 0)
27416 +               goto out;
27417 +
27418 +       sb = dentry->d_sb;
27419 +       mfs = &au_sbi(sb)->si_wbr_mfs;
27420 +       mutex_lock(&mfs->mfs_lock);
27421 +       if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
27422 +           || mfs->mfs_bindex < 0
27423 +           || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
27424 +               au_mfs(dentry);
27425 +       mutex_unlock(&mfs->mfs_lock);
27426 +       err = mfs->mfs_bindex;
27427 +
27428 +       if (err >= 0)
27429 +               err = au_wbr_nonopq(dentry, err);
27430 +
27431 +out:
27432 +       AuDbg("b%d\n", err);
27433 +       return err;
27434 +}
27435 +
27436 +static int au_wbr_create_init_mfs(struct super_block *sb)
27437 +{
27438 +       struct au_wbr_mfs *mfs;
27439 +
27440 +       mfs = &au_sbi(sb)->si_wbr_mfs;
27441 +       mutex_init(&mfs->mfs_lock);
27442 +       mfs->mfs_jiffy = 0;
27443 +       mfs->mfs_bindex = -EROFS;
27444 +
27445 +       return 0;
27446 +}
27447 +
27448 +static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
27449 +{
27450 +       mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
27451 +       return 0;
27452 +}
27453 +
27454 +/* ---------------------------------------------------------------------- */
27455 +
27456 +/* most free space and then round robin */
27457 +static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir)
27458 +{
27459 +       int err;
27460 +       struct au_wbr_mfs *mfs;
27461 +
27462 +       err = au_wbr_create_mfs(dentry, isdir);
27463 +       if (err >= 0) {
27464 +               mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
27465 +               mutex_lock(&mfs->mfs_lock);
27466 +               if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
27467 +                       err = au_wbr_create_rr(dentry, isdir);
27468 +               mutex_unlock(&mfs->mfs_lock);
27469 +       }
27470 +
27471 +       AuDbg("b%d\n", err);
27472 +       return err;
27473 +}
27474 +
27475 +static int au_wbr_create_init_mfsrr(struct super_block *sb)
27476 +{
27477 +       int err;
27478 +
27479 +       au_wbr_create_init_mfs(sb); /* ignore */
27480 +       err = au_wbr_create_init_rr(sb);
27481 +
27482 +       return err;
27483 +}
27484 +
27485 +/* ---------------------------------------------------------------------- */
27486 +
27487 +/* top down parent and most free space */
27488 +static int au_wbr_create_pmfs(struct dentry *dentry, int isdir)
27489 +{
27490 +       int err, e2;
27491 +       unsigned long long b;
27492 +       aufs_bindex_t bindex, bstart, bend;
27493 +       struct super_block *sb;
27494 +       struct dentry *parent, *h_parent;
27495 +       struct au_branch *br;
27496 +
27497 +       err = au_wbr_create_tdp(dentry, isdir);
27498 +       if (unlikely(err < 0))
27499 +               goto out;
27500 +       parent = dget_parent(dentry);
27501 +       bstart = au_dbstart(parent);
27502 +       bend = au_dbtaildir(parent);
27503 +       if (bstart == bend)
27504 +               goto out_parent; /* success */
27505 +
27506 +       e2 = au_wbr_create_mfs(dentry, isdir);
27507 +       if (e2 < 0)
27508 +               goto out_parent; /* success */
27509 +
27510 +       /* when the available size is equal, select upper one */
27511 +       sb = dentry->d_sb;
27512 +       br = au_sbr(sb, err);
27513 +       b = br->br_wbr->wbr_bytes;
27514 +       AuDbg("b%d, %llu\n", err, b);
27515 +
27516 +       for (bindex = bstart; bindex <= bend; bindex++) {
27517 +               h_parent = au_h_dptr(parent, bindex);
27518 +               if (!h_parent || !h_parent->d_inode)
27519 +                       continue;
27520 +
27521 +               br = au_sbr(sb, bindex);
27522 +               if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
27523 +                       b = br->br_wbr->wbr_bytes;
27524 +                       err = bindex;
27525 +                       AuDbg("b%d, %llu\n", err, b);
27526 +               }
27527 +       }
27528 +
27529 +       if (err >= 0)
27530 +               err = au_wbr_nonopq(dentry, err);
27531 +
27532 +out_parent:
27533 +       dput(parent);
27534 +out:
27535 +       AuDbg("b%d\n", err);
27536 +       return err;
27537 +}
27538 +
27539 +/* ---------------------------------------------------------------------- */
27540 +
27541 +/* policies for copyup */
27542 +
27543 +/* top down parent */
27544 +static int au_wbr_copyup_tdp(struct dentry *dentry)
27545 +{
27546 +       return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0);
27547 +}
27548 +
27549 +/* bottom up parent */
27550 +static int au_wbr_copyup_bup(struct dentry *dentry)
27551 +{
27552 +       int err;
27553 +       aufs_bindex_t bindex, bstart;
27554 +       struct dentry *parent, *h_parent;
27555 +       struct super_block *sb;
27556 +
27557 +       err = -EROFS;
27558 +       sb = dentry->d_sb;
27559 +       parent = dget_parent(dentry);
27560 +       bstart = au_dbstart(parent);
27561 +       for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
27562 +               h_parent = au_h_dptr(parent, bindex);
27563 +               if (!h_parent || !h_parent->d_inode)
27564 +                       continue;
27565 +
27566 +               if (!au_br_rdonly(au_sbr(sb, bindex))) {
27567 +                       err = bindex;
27568 +                       break;
27569 +               }
27570 +       }
27571 +       dput(parent);
27572 +
27573 +       /* bottom up here */
27574 +       if (unlikely(err < 0))
27575 +               err = au_wbr_bu(sb, bstart - 1);
27576 +
27577 +       AuDbg("b%d\n", err);
27578 +       return err;
27579 +}
27580 +
27581 +/* bottom up */
27582 +static int au_wbr_copyup_bu(struct dentry *dentry)
27583 +{
27584 +       int err;
27585 +       aufs_bindex_t bstart;
27586 +
27587 +       bstart = au_dbstart(dentry);
27588 +       err = au_wbr_bu(dentry->d_sb, bstart);
27589 +       AuDbg("b%d\n", err);
27590 +       if (err > bstart)
27591 +               err = au_wbr_nonopq(dentry, err);
27592 +
27593 +       AuDbg("b%d\n", err);
27594 +       return err;
27595 +}
27596 +
27597 +/* ---------------------------------------------------------------------- */
27598 +
27599 +struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
27600 +       [AuWbrCopyup_TDP] = {
27601 +               .copyup = au_wbr_copyup_tdp
27602 +       },
27603 +       [AuWbrCopyup_BUP] = {
27604 +               .copyup = au_wbr_copyup_bup
27605 +       },
27606 +       [AuWbrCopyup_BU] = {
27607 +               .copyup = au_wbr_copyup_bu
27608 +       }
27609 +};
27610 +
27611 +struct au_wbr_create_operations au_wbr_create_ops[] = {
27612 +       [AuWbrCreate_TDP] = {
27613 +               .create = au_wbr_create_tdp
27614 +       },
27615 +       [AuWbrCreate_RR] = {
27616 +               .create = au_wbr_create_rr,
27617 +               .init   = au_wbr_create_init_rr
27618 +       },
27619 +       [AuWbrCreate_MFS] = {
27620 +               .create = au_wbr_create_mfs,
27621 +               .init   = au_wbr_create_init_mfs,
27622 +               .fin    = au_wbr_create_fin_mfs
27623 +       },
27624 +       [AuWbrCreate_MFSV] = {
27625 +               .create = au_wbr_create_mfs,
27626 +               .init   = au_wbr_create_init_mfs,
27627 +               .fin    = au_wbr_create_fin_mfs
27628 +       },
27629 +       [AuWbrCreate_MFSRR] = {
27630 +               .create = au_wbr_create_mfsrr,
27631 +               .init   = au_wbr_create_init_mfsrr,
27632 +               .fin    = au_wbr_create_fin_mfs
27633 +       },
27634 +       [AuWbrCreate_MFSRRV] = {
27635 +               .create = au_wbr_create_mfsrr,
27636 +               .init   = au_wbr_create_init_mfsrr,
27637 +               .fin    = au_wbr_create_fin_mfs
27638 +       },
27639 +       [AuWbrCreate_PMFS] = {
27640 +               .create = au_wbr_create_pmfs,
27641 +               .init   = au_wbr_create_init_mfs,
27642 +               .fin    = au_wbr_create_fin_mfs
27643 +       },
27644 +       [AuWbrCreate_PMFSV] = {
27645 +               .create = au_wbr_create_pmfs,
27646 +               .init   = au_wbr_create_init_mfs,
27647 +               .fin    = au_wbr_create_fin_mfs
27648 +       }
27649 +};
27650 diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
27651 --- /usr/share/empty/fs/aufs/whout.c    1970-01-01 01:00:00.000000000 +0100
27652 +++ linux/fs/aufs/whout.c       2013-01-11 19:46:28.699667650 +0100
27653 @@ -0,0 +1,1042 @@
27654 +/*
27655 + * Copyright (C) 2005-2013 Junjiro R. Okajima
27656 + *
27657 + * This program, aufs is free software; you can redistribute it and/or modify
27658 + * it under the terms of the GNU General Public License as published by
27659 + * the Free Software Foundation; either version 2 of the License, or
27660 + * (at your option) any later version.
27661 + *
27662 + * This program is distributed in the hope that it will be useful,
27663 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27664 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27665 + * GNU General Public License for more details.
27666 + *
27667 + * You should have received a copy of the GNU General Public License
27668 + * along with this program; if not, write to the Free Software
27669 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27670 + */
27671 +
27672 +/*
27673 + * whiteout for logical deletion and opaque directory
27674 + */
27675 +
27676 +#include "aufs.h"
27677 +
27678 +#define WH_MASK                        S_IRUGO
27679 +
27680 +/*
27681 + * If a directory contains this file, then it is opaque.  We start with the
27682 + * .wh. flag so that it is blocked by lookup.
27683 + */
27684 +static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
27685 +                                          sizeof(AUFS_WH_DIROPQ) - 1);
27686 +
27687 +/*
27688 + * generate whiteout name, which is NOT terminated by NULL.
27689 + * @name: original d_name.name
27690 + * @len: original d_name.len
27691 + * @wh: whiteout qstr
27692 + * returns zero when succeeds, otherwise error.
27693 + * succeeded value as wh->name should be freed by kfree().
27694 + */
27695 +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
27696 +{
27697 +       char *p;
27698 +
27699 +       if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
27700 +               return -ENAMETOOLONG;
27701 +
27702 +       wh->len = name->len + AUFS_WH_PFX_LEN;
27703 +       p = kmalloc(wh->len, GFP_NOFS);
27704 +       wh->name = p;
27705 +       if (p) {
27706 +               memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
27707 +               memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
27708 +               /* smp_mb(); */
27709 +               return 0;
27710 +       }
27711 +       return -ENOMEM;
27712 +}
27713 +
27714 +/* ---------------------------------------------------------------------- */
27715 +
27716 +/*
27717 + * test if the @wh_name exists under @h_parent.
27718 + * @try_sio specifies the necessary of super-io.
27719 + */
27720 +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
27721 +              struct au_branch *br, int try_sio)
27722 +{
27723 +       int err;
27724 +       struct dentry *wh_dentry;
27725 +
27726 +       if (!try_sio)
27727 +               wh_dentry = vfsub_lkup_one(wh_name, h_parent);
27728 +       else
27729 +               wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
27730 +       err = PTR_ERR(wh_dentry);
27731 +       if (IS_ERR(wh_dentry))
27732 +               goto out;
27733 +
27734 +       err = 0;
27735 +       if (!wh_dentry->d_inode)
27736 +               goto out_wh; /* success */
27737 +
27738 +       err = 1;
27739 +       if (S_ISREG(wh_dentry->d_inode->i_mode))
27740 +               goto out_wh; /* success */
27741 +
27742 +       err = -EIO;
27743 +       AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
27744 +               AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
27745 +
27746 +out_wh:
27747 +       dput(wh_dentry);
27748 +out:
27749 +       return err;
27750 +}
27751 +
27752 +/*
27753 + * test if the @h_dentry sets opaque or not.
27754 + */
27755 +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
27756 +{
27757 +       int err;
27758 +       struct inode *h_dir;
27759 +
27760 +       h_dir = h_dentry->d_inode;
27761 +       err = au_wh_test(h_dentry, &diropq_name, br,
27762 +                        au_test_h_perm_sio(h_dir, MAY_EXEC));
27763 +       return err;
27764 +}
27765 +
27766 +/*
27767 + * returns a negative dentry whose name is unique and temporary.
27768 + */
27769 +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
27770 +                            struct qstr *prefix)
27771 +{
27772 +       struct dentry *dentry;
27773 +       int i;
27774 +       char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
27775 +               *name, *p;
27776 +       /* strict atomic_t is unnecessary here */
27777 +       static unsigned short cnt;
27778 +       struct qstr qs;
27779 +
27780 +       BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
27781 +
27782 +       name = defname;
27783 +       qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
27784 +       if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
27785 +               dentry = ERR_PTR(-ENAMETOOLONG);
27786 +               if (unlikely(qs.len > NAME_MAX))
27787 +                       goto out;
27788 +               dentry = ERR_PTR(-ENOMEM);
27789 +               name = kmalloc(qs.len + 1, GFP_NOFS);
27790 +               if (unlikely(!name))
27791 +                       goto out;
27792 +       }
27793 +
27794 +       /* doubly whiteout-ed */
27795 +       memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
27796 +       p = name + AUFS_WH_PFX_LEN * 2;
27797 +       memcpy(p, prefix->name, prefix->len);
27798 +       p += prefix->len;
27799 +       *p++ = '.';
27800 +       AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
27801 +
27802 +       qs.name = name;
27803 +       for (i = 0; i < 3; i++) {
27804 +               sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
27805 +               dentry = au_sio_lkup_one(&qs, h_parent, br);
27806 +               if (IS_ERR(dentry) || !dentry->d_inode)
27807 +                       goto out_name;
27808 +               dput(dentry);
27809 +       }
27810 +       /* pr_warn("could not get random name\n"); */
27811 +       dentry = ERR_PTR(-EEXIST);
27812 +       AuDbg("%.*s\n", AuLNPair(&qs));
27813 +       BUG();
27814 +
27815 +out_name:
27816 +       if (name != defname)
27817 +               kfree(name);
27818 +out:
27819 +       AuTraceErrPtr(dentry);
27820 +       return dentry;
27821 +}
27822 +
27823 +/*
27824 + * rename the @h_dentry on @br to the whiteouted temporary name.
27825 + */
27826 +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
27827 +{
27828 +       int err;
27829 +       struct path h_path = {
27830 +               .mnt = br->br_mnt
27831 +       };
27832 +       struct inode *h_dir;
27833 +       struct dentry *h_parent;
27834 +
27835 +       h_parent = h_dentry->d_parent; /* dir inode is locked */
27836 +       h_dir = h_parent->d_inode;
27837 +       IMustLock(h_dir);
27838 +
27839 +       h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
27840 +       err = PTR_ERR(h_path.dentry);
27841 +       if (IS_ERR(h_path.dentry))
27842 +               goto out;
27843 +
27844 +       /* under the same dir, no need to lock_rename() */
27845 +       err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
27846 +       AuTraceErr(err);
27847 +       dput(h_path.dentry);
27848 +
27849 +out:
27850 +       AuTraceErr(err);
27851 +       return err;
27852 +}
27853 +
27854 +/* ---------------------------------------------------------------------- */
27855 +/*
27856 + * functions for removing a whiteout
27857 + */
27858 +
27859 +static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
27860 +{
27861 +       int force;
27862 +
27863 +       /*
27864 +        * forces superio when the dir has a sticky bit.
27865 +        * this may be a violation of unix fs semantics.
27866 +        */
27867 +       force = (h_dir->i_mode & S_ISVTX)
27868 +               && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
27869 +       return vfsub_unlink(h_dir, h_path, force);
27870 +}
27871 +
27872 +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
27873 +                       struct dentry *dentry)
27874 +{
27875 +       int err;
27876 +
27877 +       err = do_unlink_wh(h_dir, h_path);
27878 +       if (!err && dentry)
27879 +               au_set_dbwh(dentry, -1);
27880 +
27881 +       return err;
27882 +}
27883 +
27884 +static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
27885 +                         struct au_branch *br)
27886 +{
27887 +       int err;
27888 +       struct path h_path = {
27889 +               .mnt = br->br_mnt
27890 +       };
27891 +
27892 +       err = 0;
27893 +       h_path.dentry = vfsub_lkup_one(wh, h_parent);
27894 +       if (IS_ERR(h_path.dentry))
27895 +               err = PTR_ERR(h_path.dentry);
27896 +       else {
27897 +               if (h_path.dentry->d_inode
27898 +                   && S_ISREG(h_path.dentry->d_inode->i_mode))
27899 +                       err = do_unlink_wh(h_parent->d_inode, &h_path);
27900 +               dput(h_path.dentry);
27901 +       }
27902 +
27903 +       return err;
27904 +}
27905 +
27906 +/* ---------------------------------------------------------------------- */
27907 +/*
27908 + * initialize/clean whiteout for a branch
27909 + */
27910 +
27911 +static void au_wh_clean(struct inode *h_dir, struct path *whpath,
27912 +                       const int isdir)
27913 +{
27914 +       int err;
27915 +
27916 +       if (!whpath->dentry->d_inode)
27917 +               return;
27918 +
27919 +       err = vfsub_mnt_want_write(whpath->mnt);
27920 +       if (!err) {
27921 +               if (isdir)
27922 +                       err = vfsub_rmdir(h_dir, whpath);
27923 +               else
27924 +                       err = vfsub_unlink(h_dir, whpath, /*force*/0);
27925 +               vfsub_mnt_drop_write(whpath->mnt);
27926 +       }
27927 +       if (unlikely(err))
27928 +               pr_warn("failed removing %.*s (%d), ignored.\n",
27929 +                       AuDLNPair(whpath->dentry), err);
27930 +}
27931 +
27932 +static int test_linkable(struct dentry *h_root)
27933 +{
27934 +       struct inode *h_dir = h_root->d_inode;
27935 +
27936 +       if (h_dir->i_op->link)
27937 +               return 0;
27938 +
27939 +       pr_err("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
27940 +              AuDLNPair(h_root), au_sbtype(h_root->d_sb));
27941 +       return -ENOSYS;
27942 +}
27943 +
27944 +/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
27945 +static int au_whdir(struct inode *h_dir, struct path *path)
27946 +{
27947 +       int err;
27948 +
27949 +       err = -EEXIST;
27950 +       if (!path->dentry->d_inode) {
27951 +               int mode = S_IRWXU;
27952 +
27953 +               if (au_test_nfs(path->dentry->d_sb))
27954 +                       mode |= S_IXUGO;
27955 +               err = vfsub_mnt_want_write(path->mnt);
27956 +               if (!err) {
27957 +                       err = vfsub_mkdir(h_dir, path, mode);
27958 +                       vfsub_mnt_drop_write(path->mnt);
27959 +               }
27960 +       } else if (S_ISDIR(path->dentry->d_inode->i_mode))
27961 +               err = 0;
27962 +       else
27963 +               pr_err("unknown %.*s exists\n", AuDLNPair(path->dentry));
27964 +
27965 +       return err;
27966 +}
27967 +
27968 +struct au_wh_base {
27969 +       const struct qstr *name;
27970 +       struct dentry *dentry;
27971 +};
27972 +
27973 +static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
27974 +                         struct path *h_path)
27975 +{
27976 +       h_path->dentry = base[AuBrWh_BASE].dentry;
27977 +       au_wh_clean(h_dir, h_path, /*isdir*/0);
27978 +       h_path->dentry = base[AuBrWh_PLINK].dentry;
27979 +       au_wh_clean(h_dir, h_path, /*isdir*/1);
27980 +       h_path->dentry = base[AuBrWh_ORPH].dentry;
27981 +       au_wh_clean(h_dir, h_path, /*isdir*/1);
27982 +}
27983 +
27984 +/*
27985 + * returns tri-state,
27986 + * minus: error, caller should print the mesage
27987 + * zero: succuess
27988 + * plus: error, caller should NOT print the mesage
27989 + */
27990 +static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
27991 +                               int do_plink, struct au_wh_base base[],
27992 +                               struct path *h_path)
27993 +{
27994 +       int err;
27995 +       struct inode *h_dir;
27996 +
27997 +       h_dir = h_root->d_inode;
27998 +       h_path->dentry = base[AuBrWh_BASE].dentry;
27999 +       au_wh_clean(h_dir, h_path, /*isdir*/0);
28000 +       h_path->dentry = base[AuBrWh_PLINK].dentry;
28001 +       if (do_plink) {
28002 +               err = test_linkable(h_root);
28003 +               if (unlikely(err)) {
28004 +                       err = 1;
28005 +                       goto out;
28006 +               }
28007 +
28008 +               err = au_whdir(h_dir, h_path);
28009 +               if (unlikely(err))
28010 +                       goto out;
28011 +               wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
28012 +       } else
28013 +               au_wh_clean(h_dir, h_path, /*isdir*/1);
28014 +       h_path->dentry = base[AuBrWh_ORPH].dentry;
28015 +       err = au_whdir(h_dir, h_path);
28016 +       if (unlikely(err))
28017 +               goto out;
28018 +       wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
28019 +
28020 +out:
28021 +       return err;
28022 +}
28023 +
28024 +/*
28025 + * for the moment, aufs supports the branch filesystem which does not support
28026 + * link(2). testing on FAT which does not support i_op->setattr() fully either,
28027 + * copyup failed. finally, such filesystem will not be used as the writable
28028 + * branch.
28029 + *
28030 + * returns tri-state, see above.
28031 + */
28032 +static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
28033 +                        int do_plink, struct au_wh_base base[],
28034 +                        struct path *h_path)
28035 +{
28036 +       int err;
28037 +       struct inode *h_dir;
28038 +
28039 +       WbrWhMustWriteLock(wbr);
28040 +
28041 +       err = test_linkable(h_root);
28042 +       if (unlikely(err)) {
28043 +               err = 1;
28044 +               goto out;
28045 +       }
28046 +
28047 +       /*
28048 +        * todo: should this create be done in /sbin/mount.aufs helper?
28049 +        */
28050 +       err = -EEXIST;
28051 +       h_dir = h_root->d_inode;
28052 +       if (!base[AuBrWh_BASE].dentry->d_inode) {
28053 +               err = vfsub_mnt_want_write(h_path->mnt);
28054 +               if (!err) {
28055 +                       h_path->dentry = base[AuBrWh_BASE].dentry;
28056 +                       err = vfsub_create(h_dir, h_path, WH_MASK,
28057 +                                          /*want_excl*/true);
28058 +                       vfsub_mnt_drop_write(h_path->mnt);
28059 +               }
28060 +       } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
28061 +               err = 0;
28062 +       else
28063 +               pr_err("unknown %.*s/%.*s exists\n",
28064 +                      AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
28065 +       if (unlikely(err))
28066 +               goto out;
28067 +
28068 +       h_path->dentry = base[AuBrWh_PLINK].dentry;
28069 +       if (do_plink) {
28070 +               err = au_whdir(h_dir, h_path);
28071 +               if (unlikely(err))
28072 +                       goto out;
28073 +               wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
28074 +       } else
28075 +               au_wh_clean(h_dir, h_path, /*isdir*/1);
28076 +       wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
28077 +
28078 +       h_path->dentry = base[AuBrWh_ORPH].dentry;
28079 +       err = au_whdir(h_dir, h_path);
28080 +       if (unlikely(err))
28081 +               goto out;
28082 +       wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
28083 +
28084 +out:
28085 +       return err;
28086 +}
28087 +
28088 +/*
28089 + * initialize the whiteout base file/dir for @br.
28090 + */
28091 +int au_wh_init(struct dentry *h_root, struct au_branch *br,
28092 +              struct super_block *sb)
28093 +{
28094 +       int err, i;
28095 +       const unsigned char do_plink
28096 +               = !!au_opt_test(au_mntflags(sb), PLINK);
28097 +       struct path path = {
28098 +               .mnt = br->br_mnt
28099 +       };
28100 +       struct inode *h_dir;
28101 +       struct au_wbr *wbr = br->br_wbr;
28102 +       static const struct qstr base_name[] = {
28103 +               [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
28104 +                                         sizeof(AUFS_BASE_NAME) - 1),
28105 +               [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
28106 +                                          sizeof(AUFS_PLINKDIR_NAME) - 1),
28107 +               [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
28108 +                                         sizeof(AUFS_ORPHDIR_NAME) - 1)
28109 +       };
28110 +       struct au_wh_base base[] = {
28111 +               [AuBrWh_BASE] = {
28112 +                       .name   = base_name + AuBrWh_BASE,
28113 +                       .dentry = NULL
28114 +               },
28115 +               [AuBrWh_PLINK] = {
28116 +                       .name   = base_name + AuBrWh_PLINK,
28117 +                       .dentry = NULL
28118 +               },
28119 +               [AuBrWh_ORPH] = {
28120 +                       .name   = base_name + AuBrWh_ORPH,
28121 +                       .dentry = NULL
28122 +               }
28123 +       };
28124 +
28125 +       if (wbr)
28126 +               WbrWhMustWriteLock(wbr);
28127 +
28128 +       for (i = 0; i < AuBrWh_Last; i++) {
28129 +               /* doubly whiteouted */
28130 +               struct dentry *d;
28131 +
28132 +               d = au_wh_lkup(h_root, (void *)base[i].name, br);
28133 +               err = PTR_ERR(d);
28134 +               if (IS_ERR(d))
28135 +                       goto out;
28136 +
28137 +               base[i].dentry = d;
28138 +               AuDebugOn(wbr
28139 +                         && wbr->wbr_wh[i]
28140 +                         && wbr->wbr_wh[i] != base[i].dentry);
28141 +       }
28142 +
28143 +       if (wbr)
28144 +               for (i = 0; i < AuBrWh_Last; i++) {
28145 +                       dput(wbr->wbr_wh[i]);
28146 +                       wbr->wbr_wh[i] = NULL;
28147 +               }
28148 +
28149 +       err = 0;
28150 +       if (!au_br_writable(br->br_perm)) {
28151 +               h_dir = h_root->d_inode;
28152 +               au_wh_init_ro(h_dir, base, &path);
28153 +       } else if (!au_br_wh_linkable(br->br_perm)) {
28154 +               err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
28155 +               if (err > 0)
28156 +                       goto out;
28157 +               else if (err)
28158 +                       goto out_err;
28159 +       } else {
28160 +               err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
28161 +               if (err > 0)
28162 +                       goto out;
28163 +               else if (err)
28164 +                       goto out_err;
28165 +       }
28166 +       goto out; /* success */
28167 +
28168 +out_err:
28169 +       pr_err("an error(%d) on the writable branch %.*s(%s)\n",
28170 +              err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
28171 +out:
28172 +       for (i = 0; i < AuBrWh_Last; i++)
28173 +               dput(base[i].dentry);
28174 +       return err;
28175 +}
28176 +
28177 +/* ---------------------------------------------------------------------- */
28178 +/*
28179 + * whiteouts are all hard-linked usually.
28180 + * when its link count reaches a ceiling, we create a new whiteout base
28181 + * asynchronously.
28182 + */
28183 +
28184 +struct reinit_br_wh {
28185 +       struct super_block *sb;
28186 +       struct au_branch *br;
28187 +};
28188 +
28189 +static void reinit_br_wh(void *arg)
28190 +{
28191 +       int err;
28192 +       aufs_bindex_t bindex;
28193 +       struct path h_path;
28194 +       struct reinit_br_wh *a = arg;
28195 +       struct au_wbr *wbr;
28196 +       struct inode *dir;
28197 +       struct dentry *h_root;
28198 +       struct au_hinode *hdir;
28199 +
28200 +       err = 0;
28201 +       wbr = a->br->br_wbr;
28202 +       /* big aufs lock */
28203 +       si_noflush_write_lock(a->sb);
28204 +       if (!au_br_writable(a->br->br_perm))
28205 +               goto out;
28206 +       bindex = au_br_index(a->sb, a->br->br_id);
28207 +       if (unlikely(bindex < 0))
28208 +               goto out;
28209 +
28210 +       di_read_lock_parent(a->sb->s_root, AuLock_IR);
28211 +       dir = a->sb->s_root->d_inode;
28212 +       hdir = au_hi(dir, bindex);
28213 +       h_root = au_h_dptr(a->sb->s_root, bindex);
28214 +
28215 +       au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
28216 +       wbr_wh_write_lock(wbr);
28217 +       err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
28218 +                         h_root, a->br);
28219 +       if (!err) {
28220 +               err = vfsub_mnt_want_write(a->br->br_mnt);
28221 +               if (!err) {
28222 +                       h_path.dentry = wbr->wbr_whbase;
28223 +                       h_path.mnt = a->br->br_mnt;
28224 +                       err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
28225 +                       vfsub_mnt_drop_write(a->br->br_mnt);
28226 +               }
28227 +       } else {
28228 +               pr_warn("%.*s is moved, ignored\n",
28229 +                       AuDLNPair(wbr->wbr_whbase));
28230 +               err = 0;
28231 +       }
28232 +       dput(wbr->wbr_whbase);
28233 +       wbr->wbr_whbase = NULL;
28234 +       if (!err)
28235 +               err = au_wh_init(h_root, a->br, a->sb);
28236 +       wbr_wh_write_unlock(wbr);
28237 +       au_hn_imtx_unlock(hdir);
28238 +       di_read_unlock(a->sb->s_root, AuLock_IR);
28239 +
28240 +out:
28241 +       if (wbr)
28242 +               atomic_dec(&wbr->wbr_wh_running);
28243 +       atomic_dec(&a->br->br_count);
28244 +       si_write_unlock(a->sb);
28245 +       au_nwt_done(&au_sbi(a->sb)->si_nowait);
28246 +       kfree(arg);
28247 +       if (unlikely(err))
28248 +               AuIOErr("err %d\n", err);
28249 +}
28250 +
28251 +static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
28252 +{
28253 +       int do_dec, wkq_err;
28254 +       struct reinit_br_wh *arg;
28255 +
28256 +       do_dec = 1;
28257 +       if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
28258 +               goto out;
28259 +
28260 +       /* ignore ENOMEM */
28261 +       arg = kmalloc(sizeof(*arg), GFP_NOFS);
28262 +       if (arg) {
28263 +               /*
28264 +                * dec(wh_running), kfree(arg) and dec(br_count)
28265 +                * in reinit function
28266 +                */
28267 +               arg->sb = sb;
28268 +               arg->br = br;
28269 +               atomic_inc(&br->br_count);
28270 +               wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
28271 +               if (unlikely(wkq_err)) {
28272 +                       atomic_dec(&br->br_wbr->wbr_wh_running);
28273 +                       atomic_dec(&br->br_count);
28274 +                       kfree(arg);
28275 +               }
28276 +               do_dec = 0;
28277 +       }
28278 +
28279 +out:
28280 +       if (do_dec)
28281 +               atomic_dec(&br->br_wbr->wbr_wh_running);
28282 +}
28283 +
28284 +/* ---------------------------------------------------------------------- */
28285 +
28286 +/*
28287 + * create the whiteout @wh.
28288 + */
28289 +static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
28290 +                            struct dentry *wh)
28291 +{
28292 +       int err;
28293 +       struct path h_path = {
28294 +               .dentry = wh
28295 +       };
28296 +       struct au_branch *br;
28297 +       struct au_wbr *wbr;
28298 +       struct dentry *h_parent;
28299 +       struct inode *h_dir;
28300 +
28301 +       h_parent = wh->d_parent; /* dir inode is locked */
28302 +       h_dir = h_parent->d_inode;
28303 +       IMustLock(h_dir);
28304 +
28305 +       br = au_sbr(sb, bindex);
28306 +       h_path.mnt = br->br_mnt;
28307 +       wbr = br->br_wbr;
28308 +       wbr_wh_read_lock(wbr);
28309 +       if (wbr->wbr_whbase) {
28310 +               err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
28311 +               if (!err || err != -EMLINK)
28312 +                       goto out;
28313 +
28314 +               /* link count full. re-initialize br_whbase. */
28315 +               kick_reinit_br_wh(sb, br);
28316 +       }
28317 +
28318 +       /* return this error in this context */
28319 +       err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
28320 +
28321 +out:
28322 +       wbr_wh_read_unlock(wbr);
28323 +       return err;
28324 +}
28325 +
28326 +/* ---------------------------------------------------------------------- */
28327 +
28328 +/*
28329 + * create or remove the diropq.
28330 + */
28331 +static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
28332 +                               unsigned int flags)
28333 +{
28334 +       struct dentry *opq_dentry, *h_dentry;
28335 +       struct super_block *sb;
28336 +       struct au_branch *br;
28337 +       int err;
28338 +
28339 +       sb = dentry->d_sb;
28340 +       br = au_sbr(sb, bindex);
28341 +       h_dentry = au_h_dptr(dentry, bindex);
28342 +       opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
28343 +       if (IS_ERR(opq_dentry))
28344 +               goto out;
28345 +
28346 +       if (au_ftest_diropq(flags, CREATE)) {
28347 +               err = link_or_create_wh(sb, bindex, opq_dentry);
28348 +               if (!err) {
28349 +                       au_set_dbdiropq(dentry, bindex);
28350 +                       goto out; /* success */
28351 +               }
28352 +       } else {
28353 +               struct path tmp = {
28354 +                       .dentry = opq_dentry,
28355 +                       .mnt    = br->br_mnt
28356 +               };
28357 +               err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
28358 +               if (!err)
28359 +                       au_set_dbdiropq(dentry, -1);
28360 +       }
28361 +       dput(opq_dentry);
28362 +       opq_dentry = ERR_PTR(err);
28363 +
28364 +out:
28365 +       return opq_dentry;
28366 +}
28367 +
28368 +struct do_diropq_args {
28369 +       struct dentry **errp;
28370 +       struct dentry *dentry;
28371 +       aufs_bindex_t bindex;
28372 +       unsigned int flags;
28373 +};
28374 +
28375 +static void call_do_diropq(void *args)
28376 +{
28377 +       struct do_diropq_args *a = args;
28378 +       *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
28379 +}
28380 +
28381 +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
28382 +                            unsigned int flags)
28383 +{
28384 +       struct dentry *diropq, *h_dentry;
28385 +
28386 +       h_dentry = au_h_dptr(dentry, bindex);
28387 +       if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
28388 +               diropq = do_diropq(dentry, bindex, flags);
28389 +       else {
28390 +               int wkq_err;
28391 +               struct do_diropq_args args = {
28392 +                       .errp           = &diropq,
28393 +                       .dentry         = dentry,
28394 +                       .bindex         = bindex,
28395 +                       .flags          = flags
28396 +               };
28397 +
28398 +               wkq_err = au_wkq_wait(call_do_diropq, &args);
28399 +               if (unlikely(wkq_err))
28400 +                       diropq = ERR_PTR(wkq_err);
28401 +       }
28402 +
28403 +       return diropq;
28404 +}
28405 +
28406 +/* ---------------------------------------------------------------------- */
28407 +
28408 +/*
28409 + * lookup whiteout dentry.
28410 + * @h_parent: lower parent dentry which must exist and be locked
28411 + * @base_name: name of dentry which will be whiteouted
28412 + * returns dentry for whiteout.
28413 + */
28414 +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
28415 +                         struct au_branch *br)
28416 +{
28417 +       int err;
28418 +       struct qstr wh_name;
28419 +       struct dentry *wh_dentry;
28420 +
28421 +       err = au_wh_name_alloc(&wh_name, base_name);
28422 +       wh_dentry = ERR_PTR(err);
28423 +       if (!err) {
28424 +               wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
28425 +               kfree(wh_name.name);
28426 +       }
28427 +       return wh_dentry;
28428 +}
28429 +
28430 +/*
28431 + * link/create a whiteout for @dentry on @bindex.
28432 + */
28433 +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
28434 +                           struct dentry *h_parent)
28435 +{
28436 +       struct dentry *wh_dentry;
28437 +       struct super_block *sb;
28438 +       int err;
28439 +
28440 +       sb = dentry->d_sb;
28441 +       wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
28442 +       if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
28443 +               err = link_or_create_wh(sb, bindex, wh_dentry);
28444 +               if (!err)
28445 +                       au_set_dbwh(dentry, bindex);
28446 +               else {
28447 +                       dput(wh_dentry);
28448 +                       wh_dentry = ERR_PTR(err);
28449 +               }
28450 +       }
28451 +
28452 +       return wh_dentry;
28453 +}
28454 +
28455 +/* ---------------------------------------------------------------------- */
28456 +
28457 +/* Delete all whiteouts in this directory on branch bindex. */
28458 +static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
28459 +                          aufs_bindex_t bindex, struct au_branch *br)
28460 +{
28461 +       int err;
28462 +       unsigned long ul, n;
28463 +       struct qstr wh_name;
28464 +       char *p;
28465 +       struct hlist_head *head;
28466 +       struct au_vdir_wh *tpos;
28467 +       struct hlist_node *pos;
28468 +       struct au_vdir_destr *str;
28469 +
28470 +       err = -ENOMEM;
28471 +       p = (void *)__get_free_page(GFP_NOFS);
28472 +       wh_name.name = p;
28473 +       if (unlikely(!wh_name.name))
28474 +               goto out;
28475 +
28476 +       err = 0;
28477 +       memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
28478 +       p += AUFS_WH_PFX_LEN;
28479 +       n = whlist->nh_num;
28480 +       head = whlist->nh_head;
28481 +       for (ul = 0; !err && ul < n; ul++, head++) {
28482 +               hlist_for_each_entry(tpos, pos, head, wh_hash) {
28483 +                       if (tpos->wh_bindex != bindex)
28484 +                               continue;
28485 +
28486 +                       str = &tpos->wh_str;
28487 +                       if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
28488 +                               memcpy(p, str->name, str->len);
28489 +                               wh_name.len = AUFS_WH_PFX_LEN + str->len;
28490 +                               err = unlink_wh_name(h_dentry, &wh_name, br);
28491 +                               if (!err)
28492 +                                       continue;
28493 +                               break;
28494 +                       }
28495 +                       AuIOErr("whiteout name too long %.*s\n",
28496 +                               str->len, str->name);
28497 +                       err = -EIO;
28498 +                       break;
28499 +               }
28500 +       }
28501 +       free_page((unsigned long)wh_name.name);
28502 +
28503 +out:
28504 +       return err;
28505 +}
28506 +
28507 +struct del_wh_children_args {
28508 +       int *errp;
28509 +       struct dentry *h_dentry;
28510 +       struct au_nhash *whlist;
28511 +       aufs_bindex_t bindex;
28512 +       struct au_branch *br;
28513 +};
28514 +
28515 +static void call_del_wh_children(void *args)
28516 +{
28517 +       struct del_wh_children_args *a = args;
28518 +       *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
28519 +}
28520 +
28521 +/* ---------------------------------------------------------------------- */
28522 +
28523 +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
28524 +{
28525 +       struct au_whtmp_rmdir *whtmp;
28526 +       int err;
28527 +       unsigned int rdhash;
28528 +
28529 +       SiMustAnyLock(sb);
28530 +
28531 +       whtmp = kmalloc(sizeof(*whtmp), gfp);
28532 +       if (unlikely(!whtmp)) {
28533 +               whtmp = ERR_PTR(-ENOMEM);
28534 +               goto out;
28535 +       }
28536 +
28537 +       whtmp->dir = NULL;
28538 +       whtmp->br = NULL;
28539 +       whtmp->wh_dentry = NULL;
28540 +       /* no estimation for dir size */
28541 +       rdhash = au_sbi(sb)->si_rdhash;
28542 +       if (!rdhash)
28543 +               rdhash = AUFS_RDHASH_DEF;
28544 +       err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
28545 +       if (unlikely(err)) {
28546 +               kfree(whtmp);
28547 +               whtmp = ERR_PTR(err);
28548 +       }
28549 +
28550 +out:
28551 +       return whtmp;
28552 +}
28553 +
28554 +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
28555 +{
28556 +       if (whtmp->br)
28557 +               atomic_dec(&whtmp->br->br_count);
28558 +       dput(whtmp->wh_dentry);
28559 +       iput(whtmp->dir);
28560 +       au_nhash_wh_free(&whtmp->whlist);
28561 +       kfree(whtmp);
28562 +}
28563 +
28564 +/*
28565 + * rmdir the whiteouted temporary named dir @h_dentry.
28566 + * @whlist: whiteouted children.
28567 + */
28568 +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
28569 +                  struct dentry *wh_dentry, struct au_nhash *whlist)
28570 +{
28571 +       int err;
28572 +       struct path h_tmp;
28573 +       struct inode *wh_inode, *h_dir;
28574 +       struct au_branch *br;
28575 +
28576 +       h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
28577 +       IMustLock(h_dir);
28578 +
28579 +       br = au_sbr(dir->i_sb, bindex);
28580 +       wh_inode = wh_dentry->d_inode;
28581 +       mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
28582 +
28583 +       /*
28584 +        * someone else might change some whiteouts while we were sleeping.
28585 +        * it means this whlist may have an obsoleted entry.
28586 +        */
28587 +       if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
28588 +               err = del_wh_children(wh_dentry, whlist, bindex, br);
28589 +       else {
28590 +               int wkq_err;
28591 +               struct del_wh_children_args args = {
28592 +                       .errp           = &err,
28593 +                       .h_dentry       = wh_dentry,
28594 +                       .whlist         = whlist,
28595 +                       .bindex         = bindex,
28596 +                       .br             = br
28597 +               };
28598 +
28599 +               wkq_err = au_wkq_wait(call_del_wh_children, &args);
28600 +               if (unlikely(wkq_err))
28601 +                       err = wkq_err;
28602 +       }
28603 +       mutex_unlock(&wh_inode->i_mutex);
28604 +
28605 +       if (!err) {
28606 +               h_tmp.dentry = wh_dentry;
28607 +               h_tmp.mnt = br->br_mnt;
28608 +               err = vfsub_rmdir(h_dir, &h_tmp);
28609 +       }
28610 +
28611 +       if (!err) {
28612 +               if (au_ibstart(dir) == bindex) {
28613 +                       /* todo: dir->i_mutex is necessary */
28614 +                       au_cpup_attr_timesizes(dir);
28615 +                       vfsub_drop_nlink(dir);
28616 +               }
28617 +               return 0; /* success */
28618 +       }
28619 +
28620 +       pr_warn("failed removing %.*s(%d), ignored\n",
28621 +               AuDLNPair(wh_dentry), err);
28622 +       return err;
28623 +}
28624 +
28625 +static void call_rmdir_whtmp(void *args)
28626 +{
28627 +       int err;
28628 +       aufs_bindex_t bindex;
28629 +       struct au_whtmp_rmdir *a = args;
28630 +       struct super_block *sb;
28631 +       struct dentry *h_parent;
28632 +       struct inode *h_dir;
28633 +       struct au_hinode *hdir;
28634 +
28635 +       /* rmdir by nfsd may cause deadlock with this i_mutex */
28636 +       /* mutex_lock(&a->dir->i_mutex); */
28637 +       err = -EROFS;
28638 +       sb = a->dir->i_sb;
28639 +       si_read_lock(sb, !AuLock_FLUSH);
28640 +       if (!au_br_writable(a->br->br_perm))
28641 +               goto out;
28642 +       bindex = au_br_index(sb, a->br->br_id);
28643 +       if (unlikely(bindex < 0))
28644 +               goto out;
28645 +
28646 +       err = -EIO;
28647 +       ii_write_lock_parent(a->dir);
28648 +       h_parent = dget_parent(a->wh_dentry);
28649 +       h_dir = h_parent->d_inode;
28650 +       hdir = au_hi(a->dir, bindex);
28651 +       au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
28652 +       err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
28653 +                         a->br);
28654 +       if (!err) {
28655 +               err = vfsub_mnt_want_write(a->br->br_mnt);
28656 +               if (!err) {
28657 +                       err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry,
28658 +                                            &a->whlist);
28659 +                       vfsub_mnt_drop_write(a->br->br_mnt);
28660 +               }
28661 +       }
28662 +       au_hn_imtx_unlock(hdir);
28663 +       dput(h_parent);
28664 +       ii_write_unlock(a->dir);
28665 +
28666 +out:
28667 +       /* mutex_unlock(&a->dir->i_mutex); */
28668 +       au_whtmp_rmdir_free(a);
28669 +       si_read_unlock(sb);
28670 +       au_nwt_done(&au_sbi(sb)->si_nowait);
28671 +       if (unlikely(err))
28672 +               AuIOErr("err %d\n", err);
28673 +}
28674 +
28675 +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
28676 +                        struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
28677 +{
28678 +       int wkq_err;
28679 +       struct super_block *sb;
28680 +
28681 +       IMustLock(dir);
28682 +
28683 +       /* all post-process will be done in do_rmdir_whtmp(). */
28684 +       sb = dir->i_sb;
28685 +       args->dir = au_igrab(dir);
28686 +       args->br = au_sbr(sb, bindex);
28687 +       atomic_inc(&args->br->br_count);
28688 +       args->wh_dentry = dget(wh_dentry);
28689 +       wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
28690 +       if (unlikely(wkq_err)) {
28691 +               pr_warn("rmdir error %.*s (%d), ignored\n",
28692 +                       AuDLNPair(wh_dentry), wkq_err);
28693 +               au_whtmp_rmdir_free(args);
28694 +       }
28695 +}
28696 diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
28697 --- /usr/share/empty/fs/aufs/whout.h    1970-01-01 01:00:00.000000000 +0100
28698 +++ linux/fs/aufs/whout.h       2013-01-11 19:46:12.659281826 +0100
28699 @@ -0,0 +1,88 @@
28700 +/*
28701 + * Copyright (C) 2005-2013 Junjiro R. Okajima
28702 + *
28703 + * This program, aufs is free software; you can redistribute it and/or modify
28704 + * it under the terms of the GNU General Public License as published by
28705 + * the Free Software Foundation; either version 2 of the License, or
28706 + * (at your option) any later version.
28707 + *
28708 + * This program is distributed in the hope that it will be useful,
28709 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28710 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28711 + * GNU General Public License for more details.
28712 + *
28713 + * You should have received a copy of the GNU General Public License
28714 + * along with this program; if not, write to the Free Software
28715 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28716 + */
28717 +
28718 +/*
28719 + * whiteout for logical deletion and opaque directory
28720 + */
28721 +
28722 +#ifndef __AUFS_WHOUT_H__
28723 +#define __AUFS_WHOUT_H__
28724 +
28725 +#ifdef __KERNEL__
28726 +
28727 +#include "dir.h"
28728 +
28729 +/* whout.c */
28730 +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
28731 +struct au_branch;
28732 +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
28733 +              struct au_branch *br, int try_sio);
28734 +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
28735 +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
28736 +                            struct qstr *prefix);
28737 +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
28738 +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
28739 +                       struct dentry *dentry);
28740 +int au_wh_init(struct dentry *h_parent, struct au_branch *br,
28741 +              struct super_block *sb);
28742 +
28743 +/* diropq flags */
28744 +#define AuDiropq_CREATE        1
28745 +#define au_ftest_diropq(flags, name)   ((flags) & AuDiropq_##name)
28746 +#define au_fset_diropq(flags, name) \
28747 +       do { (flags) |= AuDiropq_##name; } while (0)
28748 +#define au_fclr_diropq(flags, name) \
28749 +       do { (flags) &= ~AuDiropq_##name; } while (0)
28750 +
28751 +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
28752 +                            unsigned int flags);
28753 +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
28754 +                         struct au_branch *br);
28755 +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
28756 +                           struct dentry *h_parent);
28757 +
28758 +/* real rmdir for the whiteout-ed dir */
28759 +struct au_whtmp_rmdir {
28760 +       struct inode *dir;
28761 +       struct au_branch *br;
28762 +       struct dentry *wh_dentry;
28763 +       struct au_nhash whlist;
28764 +};
28765 +
28766 +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
28767 +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
28768 +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
28769 +                  struct dentry *wh_dentry, struct au_nhash *whlist);
28770 +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
28771 +                        struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
28772 +
28773 +/* ---------------------------------------------------------------------- */
28774 +
28775 +static inline struct dentry *au_diropq_create(struct dentry *dentry,
28776 +                                             aufs_bindex_t bindex)
28777 +{
28778 +       return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
28779 +}
28780 +
28781 +static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
28782 +{
28783 +       return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
28784 +}
28785 +
28786 +#endif /* __KERNEL__ */
28787 +#endif /* __AUFS_WHOUT_H__ */
28788 diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
28789 --- /usr/share/empty/fs/aufs/wkq.c      1970-01-01 01:00:00.000000000 +0100
28790 +++ linux/fs/aufs/wkq.c 2013-01-11 19:46:12.659281826 +0100
28791 @@ -0,0 +1,214 @@
28792 +/*
28793 + * Copyright (C) 2005-2013 Junjiro R. Okajima
28794 + *
28795 + * This program, aufs is free software; you can redistribute it and/or modify
28796 + * it under the terms of the GNU General Public License as published by
28797 + * the Free Software Foundation; either version 2 of the License, or
28798 + * (at your option) any later version.
28799 + *
28800 + * This program is distributed in the hope that it will be useful,
28801 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28802 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28803 + * GNU General Public License for more details.
28804 + *
28805 + * You should have received a copy of the GNU General Public License
28806 + * along with this program; if not, write to the Free Software
28807 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28808 + */
28809 +
28810 +/*
28811 + * workqueue for asynchronous/super-io operations
28812 + * todo: try new dredential scheme
28813 + */
28814 +
28815 +#include <linux/module.h>
28816 +#include "aufs.h"
28817 +
28818 +/* internal workqueue named AUFS_WKQ_NAME */
28819 +
28820 +static struct workqueue_struct *au_wkq;
28821 +
28822 +struct au_wkinfo {
28823 +       struct work_struct wk;
28824 +       struct kobject *kobj;
28825 +
28826 +       unsigned int flags; /* see wkq.h */
28827 +
28828 +       au_wkq_func_t func;
28829 +       void *args;
28830 +
28831 +       struct completion *comp;
28832 +};
28833 +
28834 +/* ---------------------------------------------------------------------- */
28835 +
28836 +static void wkq_func(struct work_struct *wk)
28837 +{
28838 +       struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
28839 +
28840 +       AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
28841 +       AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
28842 +
28843 +       wkinfo->func(wkinfo->args);
28844 +       if (au_ftest_wkq(wkinfo->flags, WAIT))
28845 +               complete(wkinfo->comp);
28846 +       else {
28847 +               kobject_put(wkinfo->kobj);
28848 +               module_put(THIS_MODULE); /* todo: ?? */
28849 +               kfree(wkinfo);
28850 +       }
28851 +}
28852 +
28853 +/*
28854 + * Since struct completion is large, try allocating it dynamically.
28855 + */
28856 +#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS)
28857 +#define AuWkqCompDeclare(name) struct completion *comp = NULL
28858 +
28859 +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
28860 +{
28861 +       *comp = kmalloc(sizeof(**comp), GFP_NOFS);
28862 +       if (*comp) {
28863 +               init_completion(*comp);
28864 +               wkinfo->comp = *comp;
28865 +               return 0;
28866 +       }
28867 +       return -ENOMEM;
28868 +}
28869 +
28870 +static void au_wkq_comp_free(struct completion *comp)
28871 +{
28872 +       kfree(comp);
28873 +}
28874 +
28875 +#else
28876 +
28877 +/* no braces */
28878 +#define AuWkqCompDeclare(name) \
28879 +       DECLARE_COMPLETION_ONSTACK(_ ## name); \
28880 +       struct completion *comp = &_ ## name
28881 +
28882 +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
28883 +{
28884 +       wkinfo->comp = *comp;
28885 +       return 0;
28886 +}
28887 +
28888 +static void au_wkq_comp_free(struct completion *comp __maybe_unused)
28889 +{
28890 +       /* empty */
28891 +}
28892 +#endif /* 4KSTACKS */
28893 +
28894 +static void au_wkq_run(struct au_wkinfo *wkinfo)
28895 +{
28896 +       if (au_ftest_wkq(wkinfo->flags, NEST)) {
28897 +               if (au_wkq_test()) {
28898 +                       AuWarn1("wkq from wkq, due to a dead dir by UDBA?\n");
28899 +                       AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
28900 +               }
28901 +       } else
28902 +               au_dbg_verify_kthread();
28903 +
28904 +       if (au_ftest_wkq(wkinfo->flags, WAIT)) {
28905 +               INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
28906 +               queue_work(au_wkq, &wkinfo->wk);
28907 +       } else {
28908 +               INIT_WORK(&wkinfo->wk, wkq_func);
28909 +               schedule_work(&wkinfo->wk);
28910 +       }
28911 +}
28912 +
28913 +/*
28914 + * Be careful. It is easy to make deadlock happen.
28915 + * processA: lock, wkq and wait
28916 + * processB: wkq and wait, lock in wkq
28917 + * --> deadlock
28918 + */
28919 +int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
28920 +{
28921 +       int err;
28922 +       AuWkqCompDeclare(comp);
28923 +       struct au_wkinfo wkinfo = {
28924 +               .flags  = flags,
28925 +               .func   = func,
28926 +               .args   = args
28927 +       };
28928 +
28929 +       err = au_wkq_comp_alloc(&wkinfo, &comp);
28930 +       if (!err) {
28931 +               au_wkq_run(&wkinfo);
28932 +               /* no timeout, no interrupt */
28933 +               wait_for_completion(wkinfo.comp);
28934 +               au_wkq_comp_free(comp);
28935 +               destroy_work_on_stack(&wkinfo.wk);
28936 +       }
28937 +
28938 +       return err;
28939 +
28940 +}
28941 +
28942 +/*
28943 + * Note: dget/dput() in func for aufs dentries are not supported. It will be a
28944 + * problem in a concurrent umounting.
28945 + */
28946 +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
28947 +                 unsigned int flags)
28948 +{
28949 +       int err;
28950 +       struct au_wkinfo *wkinfo;
28951 +
28952 +       atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
28953 +
28954 +       /*
28955 +        * wkq_func() must free this wkinfo.
28956 +        * it highly depends upon the implementation of workqueue.
28957 +        */
28958 +       err = 0;
28959 +       wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
28960 +       if (wkinfo) {
28961 +               wkinfo->kobj = &au_sbi(sb)->si_kobj;
28962 +               wkinfo->flags = flags & ~AuWkq_WAIT;
28963 +               wkinfo->func = func;
28964 +               wkinfo->args = args;
28965 +               wkinfo->comp = NULL;
28966 +               kobject_get(wkinfo->kobj);
28967 +               __module_get(THIS_MODULE); /* todo: ?? */
28968 +
28969 +               au_wkq_run(wkinfo);
28970 +       } else {
28971 +               err = -ENOMEM;
28972 +               au_nwt_done(&au_sbi(sb)->si_nowait);
28973 +       }
28974 +
28975 +       return err;
28976 +}
28977 +
28978 +/* ---------------------------------------------------------------------- */
28979 +
28980 +void au_nwt_init(struct au_nowait_tasks *nwt)
28981 +{
28982 +       atomic_set(&nwt->nw_len, 0);
28983 +       /* smp_mb(); */ /* atomic_set */
28984 +       init_waitqueue_head(&nwt->nw_wq);
28985 +}
28986 +
28987 +void au_wkq_fin(void)
28988 +{
28989 +       destroy_workqueue(au_wkq);
28990 +}
28991 +
28992 +int __init au_wkq_init(void)
28993 +{
28994 +       int err;
28995 +
28996 +       err = 0;
28997 +       BUILD_BUG_ON(!WQ_RESCUER);
28998 +       au_wkq = alloc_workqueue(AUFS_WKQ_NAME, !WQ_RESCUER, WQ_DFL_ACTIVE);
28999 +       if (IS_ERR(au_wkq))
29000 +               err = PTR_ERR(au_wkq);
29001 +       else if (!au_wkq)
29002 +               err = -ENOMEM;
29003 +
29004 +       return err;
29005 +}
29006 diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
29007 --- /usr/share/empty/fs/aufs/wkq.h      1970-01-01 01:00:00.000000000 +0100
29008 +++ linux/fs/aufs/wkq.h 2013-01-11 19:46:12.659281826 +0100
29009 @@ -0,0 +1,92 @@
29010 +/*
29011 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29012 + *
29013 + * This program, aufs is free software; you can redistribute it and/or modify
29014 + * it under the terms of the GNU General Public License as published by
29015 + * the Free Software Foundation; either version 2 of the License, or
29016 + * (at your option) any later version.
29017 + *
29018 + * This program is distributed in the hope that it will be useful,
29019 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29020 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29021 + * GNU General Public License for more details.
29022 + *
29023 + * You should have received a copy of the GNU General Public License
29024 + * along with this program; if not, write to the Free Software
29025 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
29026 + */
29027 +
29028 +/*
29029 + * workqueue for asynchronous/super-io operations
29030 + * todo: try new credentials management scheme
29031 + */
29032 +
29033 +#ifndef __AUFS_WKQ_H__
29034 +#define __AUFS_WKQ_H__
29035 +
29036 +#ifdef __KERNEL__
29037 +
29038 +struct super_block;
29039 +
29040 +/* ---------------------------------------------------------------------- */
29041 +
29042 +/*
29043 + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
29044 + */
29045 +struct au_nowait_tasks {
29046 +       atomic_t                nw_len;
29047 +       wait_queue_head_t       nw_wq;
29048 +};
29049 +
29050 +/* ---------------------------------------------------------------------- */
29051 +
29052 +typedef void (*au_wkq_func_t)(void *args);
29053 +
29054 +/* wkq flags */
29055 +#define AuWkq_WAIT     1
29056 +#define AuWkq_NEST     (1 << 1)
29057 +#define au_ftest_wkq(flags, name)      ((flags) & AuWkq_##name)
29058 +#define au_fset_wkq(flags, name) \
29059 +       do { (flags) |= AuWkq_##name; } while (0)
29060 +#define au_fclr_wkq(flags, name) \
29061 +       do { (flags) &= ~AuWkq_##name; } while (0)
29062 +
29063 +#ifndef CONFIG_AUFS_HNOTIFY
29064 +#undef AuWkq_NEST
29065 +#define AuWkq_NEST     0
29066 +#endif
29067 +
29068 +/* wkq.c */
29069 +int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
29070 +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
29071 +                 unsigned int flags);
29072 +void au_nwt_init(struct au_nowait_tasks *nwt);
29073 +int __init au_wkq_init(void);
29074 +void au_wkq_fin(void);
29075 +
29076 +/* ---------------------------------------------------------------------- */
29077 +
29078 +static inline int au_wkq_test(void)
29079 +{
29080 +       return current->flags & PF_WQ_WORKER;
29081 +}
29082 +
29083 +static inline int au_wkq_wait(au_wkq_func_t func, void *args)
29084 +{
29085 +       return au_wkq_do_wait(AuWkq_WAIT, func, args);
29086 +}
29087 +
29088 +static inline void au_nwt_done(struct au_nowait_tasks *nwt)
29089 +{
29090 +       if (atomic_dec_and_test(&nwt->nw_len))
29091 +               wake_up_all(&nwt->nw_wq);
29092 +}
29093 +
29094 +static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
29095 +{
29096 +       wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
29097 +       return 0;
29098 +}
29099 +
29100 +#endif /* __KERNEL__ */
29101 +#endif /* __AUFS_WKQ_H__ */
29102 diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
29103 --- /usr/share/empty/fs/aufs/xino.c     1970-01-01 01:00:00.000000000 +0100
29104 +++ linux/fs/aufs/xino.c        2013-01-11 19:46:28.699667650 +0100
29105 @@ -0,0 +1,1264 @@
29106 +/*
29107 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29108 + *
29109 + * This program, aufs is free software; you can redistribute it and/or modify
29110 + * it under the terms of the GNU General Public License as published by
29111 + * the Free Software Foundation; either version 2 of the License, or
29112 + * (at your option) any later version.
29113 + *
29114 + * This program is distributed in the hope that it will be useful,
29115 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29116 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29117 + * GNU General Public License for more details.
29118 + *
29119 + * You should have received a copy of the GNU General Public License
29120 + * along with this program; if not, write to the Free Software
29121 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
29122 + */
29123 +
29124 +/*
29125 + * external inode number translation table and bitmap
29126 + */
29127 +
29128 +#include <linux/seq_file.h>
29129 +#include "aufs.h"
29130 +
29131 +/* todo: unnecessary to support mmap_sem since kernel-space? */
29132 +ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
29133 +                  loff_t *pos)
29134 +{
29135 +       ssize_t err;
29136 +       mm_segment_t oldfs;
29137 +       union {
29138 +               void *k;
29139 +               char __user *u;
29140 +       } buf;
29141 +
29142 +       buf.k = kbuf;
29143 +       oldfs = get_fs();
29144 +       set_fs(KERNEL_DS);
29145 +       do {
29146 +               /* todo: signal_pending? */
29147 +               err = func(file, buf.u, size, pos);
29148 +       } while (err == -EAGAIN || err == -EINTR);
29149 +       set_fs(oldfs);
29150 +
29151 +#if 0 /* reserved for future use */
29152 +       if (err > 0)
29153 +               fsnotify_access(file->f_dentry);
29154 +#endif
29155 +
29156 +       return err;
29157 +}
29158 +
29159 +/* ---------------------------------------------------------------------- */
29160 +
29161 +static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
29162 +                             size_t size, loff_t *pos)
29163 +{
29164 +       ssize_t err;
29165 +       mm_segment_t oldfs;
29166 +       union {
29167 +               void *k;
29168 +               const char __user *u;
29169 +       } buf;
29170 +
29171 +       buf.k = kbuf;
29172 +       oldfs = get_fs();
29173 +       set_fs(KERNEL_DS);
29174 +       do {
29175 +               /* todo: signal_pending? */
29176 +               err = func(file, buf.u, size, pos);
29177 +       } while (err == -EAGAIN || err == -EINTR);
29178 +       set_fs(oldfs);
29179 +
29180 +#if 0 /* reserved for future use */
29181 +       if (err > 0)
29182 +               fsnotify_modify(file->f_dentry);
29183 +#endif
29184 +
29185 +       return err;
29186 +}
29187 +
29188 +struct do_xino_fwrite_args {
29189 +       ssize_t *errp;
29190 +       au_writef_t func;
29191 +       struct file *file;
29192 +       void *buf;
29193 +       size_t size;
29194 +       loff_t *pos;
29195 +};
29196 +
29197 +static void call_do_xino_fwrite(void *args)
29198 +{
29199 +       struct do_xino_fwrite_args *a = args;
29200 +       *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
29201 +}
29202 +
29203 +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
29204 +                   loff_t *pos)
29205 +{
29206 +       ssize_t err;
29207 +
29208 +       /* todo: signal block and no wkq? */
29209 +       if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
29210 +               lockdep_off();
29211 +               err = do_xino_fwrite(func, file, buf, size, pos);
29212 +               lockdep_on();
29213 +       } else {
29214 +               /*
29215 +                * it breaks RLIMIT_FSIZE and normal user's limit,
29216 +                * users should care about quota and real 'filesystem full.'
29217 +                */
29218 +               int wkq_err;
29219 +               struct do_xino_fwrite_args args = {
29220 +                       .errp   = &err,
29221 +                       .func   = func,
29222 +                       .file   = file,
29223 +                       .buf    = buf,
29224 +                       .size   = size,
29225 +                       .pos    = pos
29226 +               };
29227 +
29228 +               wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
29229 +               if (unlikely(wkq_err))
29230 +                       err = wkq_err;
29231 +       }
29232 +
29233 +       return err;
29234 +}
29235 +
29236 +/* ---------------------------------------------------------------------- */
29237 +
29238 +/*
29239 + * create a new xinofile at the same place/path as @base_file.
29240 + */
29241 +struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
29242 +{
29243 +       struct file *file;
29244 +       struct dentry *base, *parent;
29245 +       struct inode *dir;
29246 +       struct qstr *name;
29247 +       struct path path;
29248 +       int err;
29249 +
29250 +       base = base_file->f_dentry;
29251 +       parent = base->d_parent; /* dir inode is locked */
29252 +       dir = parent->d_inode;
29253 +       IMustLock(dir);
29254 +
29255 +       file = ERR_PTR(-EINVAL);
29256 +       name = &base->d_name;
29257 +       path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
29258 +       if (IS_ERR(path.dentry)) {
29259 +               file = (void *)path.dentry;
29260 +               pr_err("%.*s lookup err %ld\n",
29261 +                      AuLNPair(name), PTR_ERR(path.dentry));
29262 +               goto out;
29263 +       }
29264 +
29265 +       /* no need to mnt_want_write() since we call dentry_open() later */
29266 +       err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
29267 +       if (unlikely(err)) {
29268 +               file = ERR_PTR(err);
29269 +               pr_err("%.*s create err %d\n", AuLNPair(name), err);
29270 +               goto out_dput;
29271 +       }
29272 +
29273 +       path.mnt = base_file->f_vfsmnt;
29274 +       file = vfsub_dentry_open(&path,
29275 +                                O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
29276 +                                /* | __FMODE_NONOTIFY */);
29277 +       if (IS_ERR(file)) {
29278 +               pr_err("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
29279 +               goto out_dput;
29280 +       }
29281 +
29282 +       err = vfsub_unlink(dir, &file->f_path, /*force*/0);
29283 +       if (unlikely(err)) {
29284 +               pr_err("%.*s unlink err %d\n", AuLNPair(name), err);
29285 +               goto out_fput;
29286 +       }
29287 +
29288 +       if (copy_src) {
29289 +               /* no one can touch copy_src xino */
29290 +               err = au_copy_file(file, copy_src,
29291 +                                  i_size_read(copy_src->f_dentry->d_inode));
29292 +               if (unlikely(err)) {
29293 +                       pr_err("%.*s copy err %d\n", AuLNPair(name), err);
29294 +                       goto out_fput;
29295 +               }
29296 +       }
29297 +       goto out_dput; /* success */
29298 +
29299 +out_fput:
29300 +       fput(file);
29301 +       file = ERR_PTR(err);
29302 +out_dput:
29303 +       dput(path.dentry);
29304 +out:
29305 +       return file;
29306 +}
29307 +
29308 +struct au_xino_lock_dir {
29309 +       struct au_hinode *hdir;
29310 +       struct dentry *parent;
29311 +       struct mutex *mtx;
29312 +};
29313 +
29314 +static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
29315 +                            struct au_xino_lock_dir *ldir)
29316 +{
29317 +       aufs_bindex_t brid, bindex;
29318 +
29319 +       ldir->hdir = NULL;
29320 +       bindex = -1;
29321 +       brid = au_xino_brid(sb);
29322 +       if (brid >= 0)
29323 +               bindex = au_br_index(sb, brid);
29324 +       if (bindex >= 0) {
29325 +               ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
29326 +               au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
29327 +       } else {
29328 +               ldir->parent = dget_parent(xino->f_dentry);
29329 +               ldir->mtx = &ldir->parent->d_inode->i_mutex;
29330 +               mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
29331 +       }
29332 +}
29333 +
29334 +static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
29335 +{
29336 +       if (ldir->hdir)
29337 +               au_hn_imtx_unlock(ldir->hdir);
29338 +       else {
29339 +               mutex_unlock(ldir->mtx);
29340 +               dput(ldir->parent);
29341 +       }
29342 +}
29343 +
29344 +/* ---------------------------------------------------------------------- */
29345 +
29346 +/* trucate xino files asynchronously */
29347 +
29348 +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
29349 +{
29350 +       int err;
29351 +       aufs_bindex_t bi, bend;
29352 +       struct au_branch *br;
29353 +       struct file *new_xino, *file;
29354 +       struct super_block *h_sb;
29355 +       struct au_xino_lock_dir ldir;
29356 +
29357 +       err = -EINVAL;
29358 +       bend = au_sbend(sb);
29359 +       if (unlikely(bindex < 0 || bend < bindex))
29360 +               goto out;
29361 +       br = au_sbr(sb, bindex);
29362 +       file = br->br_xino.xi_file;
29363 +       if (!file)
29364 +               goto out;
29365 +
29366 +       au_xino_lock_dir(sb, file, &ldir);
29367 +       /* mnt_want_write() is unnecessary here */
29368 +       new_xino = au_xino_create2(file, file);
29369 +       au_xino_unlock_dir(&ldir);
29370 +       err = PTR_ERR(new_xino);
29371 +       if (IS_ERR(new_xino))
29372 +               goto out;
29373 +       err = 0;
29374 +       fput(file);
29375 +       br->br_xino.xi_file = new_xino;
29376 +
29377 +       h_sb = br->br_mnt->mnt_sb;
29378 +       for (bi = 0; bi <= bend; bi++) {
29379 +               if (unlikely(bi == bindex))
29380 +                       continue;
29381 +               br = au_sbr(sb, bi);
29382 +               if (br->br_mnt->mnt_sb != h_sb)
29383 +                       continue;
29384 +
29385 +               fput(br->br_xino.xi_file);
29386 +               br->br_xino.xi_file = new_xino;
29387 +               get_file(new_xino);
29388 +       }
29389 +
29390 +out:
29391 +       return err;
29392 +}
29393 +
29394 +struct xino_do_trunc_args {
29395 +       struct super_block *sb;
29396 +       struct au_branch *br;
29397 +};
29398 +
29399 +static void xino_do_trunc(void *_args)
29400 +{
29401 +       struct xino_do_trunc_args *args = _args;
29402 +       struct super_block *sb;
29403 +       struct au_branch *br;
29404 +       struct inode *dir;
29405 +       int err;
29406 +       aufs_bindex_t bindex;
29407 +
29408 +       err = 0;
29409 +       sb = args->sb;
29410 +       dir = sb->s_root->d_inode;
29411 +       br = args->br;
29412 +
29413 +       si_noflush_write_lock(sb);
29414 +       ii_read_lock_parent(dir);
29415 +       bindex = au_br_index(sb, br->br_id);
29416 +       err = au_xino_trunc(sb, bindex);
29417 +       if (!err
29418 +           && br->br_xino.xi_file->f_dentry->d_inode->i_blocks
29419 +           >= br->br_xino_upper)
29420 +               br->br_xino_upper += AUFS_XINO_TRUNC_STEP;
29421 +
29422 +       ii_read_unlock(dir);
29423 +       if (unlikely(err))
29424 +               pr_warn("err b%d, (%d)\n", bindex, err);
29425 +       atomic_dec(&br->br_xino_running);
29426 +       atomic_dec(&br->br_count);
29427 +       si_write_unlock(sb);
29428 +       au_nwt_done(&au_sbi(sb)->si_nowait);
29429 +       kfree(args);
29430 +}
29431 +
29432 +static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
29433 +{
29434 +       struct xino_do_trunc_args *args;
29435 +       int wkq_err;
29436 +
29437 +       if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks
29438 +           < br->br_xino_upper)
29439 +               return;
29440 +
29441 +       if (atomic_inc_return(&br->br_xino_running) > 1)
29442 +               goto out;
29443 +
29444 +       /* lock and kfree() will be called in trunc_xino() */
29445 +       args = kmalloc(sizeof(*args), GFP_NOFS);
29446 +       if (unlikely(!args)) {
29447 +               AuErr1("no memory\n");
29448 +               goto out_args;
29449 +       }
29450 +
29451 +       atomic_inc(&br->br_count);
29452 +       args->sb = sb;
29453 +       args->br = br;
29454 +       wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
29455 +       if (!wkq_err)
29456 +               return; /* success */
29457 +
29458 +       pr_err("wkq %d\n", wkq_err);
29459 +       atomic_dec(&br->br_count);
29460 +
29461 +out_args:
29462 +       kfree(args);
29463 +out:
29464 +       atomic_dec(&br->br_xino_running);
29465 +}
29466 +
29467 +/* ---------------------------------------------------------------------- */
29468 +
29469 +static int au_xino_do_write(au_writef_t write, struct file *file,
29470 +                           ino_t h_ino, ino_t ino)
29471 +{
29472 +       loff_t pos;
29473 +       ssize_t sz;
29474 +
29475 +       pos = h_ino;
29476 +       if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
29477 +               AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
29478 +               return -EFBIG;
29479 +       }
29480 +       pos *= sizeof(ino);
29481 +       sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
29482 +       if (sz == sizeof(ino))
29483 +               return 0; /* success */
29484 +
29485 +       AuIOErr("write failed (%zd)\n", sz);
29486 +       return -EIO;
29487 +}
29488 +
29489 +/*
29490 + * write @ino to the xinofile for the specified branch{@sb, @bindex}
29491 + * at the position of @h_ino.
29492 + * even if @ino is zero, it is written to the xinofile and means no entry.
29493 + * if the size of the xino file on a specific filesystem exceeds the watermark,
29494 + * try truncating it.
29495 + */
29496 +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
29497 +                 ino_t ino)
29498 +{
29499 +       int err;
29500 +       unsigned int mnt_flags;
29501 +       struct au_branch *br;
29502 +
29503 +       BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
29504 +                    || ((loff_t)-1) > 0);
29505 +       SiMustAnyLock(sb);
29506 +
29507 +       mnt_flags = au_mntflags(sb);
29508 +       if (!au_opt_test(mnt_flags, XINO))
29509 +               return 0;
29510 +
29511 +       br = au_sbr(sb, bindex);
29512 +       err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
29513 +                              h_ino, ino);
29514 +       if (!err) {
29515 +               if (au_opt_test(mnt_flags, TRUNC_XINO)
29516 +                   && au_test_fs_trunc_xino(br->br_mnt->mnt_sb))
29517 +                       xino_try_trunc(sb, br);
29518 +               return 0; /* success */
29519 +       }
29520 +
29521 +       AuIOErr("write failed (%d)\n", err);
29522 +       return -EIO;
29523 +}
29524 +
29525 +/* ---------------------------------------------------------------------- */
29526 +
29527 +/* aufs inode number bitmap */
29528 +
29529 +static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
29530 +static ino_t xib_calc_ino(unsigned long pindex, int bit)
29531 +{
29532 +       ino_t ino;
29533 +
29534 +       AuDebugOn(bit < 0 || page_bits <= bit);
29535 +       ino = AUFS_FIRST_INO + pindex * page_bits + bit;
29536 +       return ino;
29537 +}
29538 +
29539 +static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
29540 +{
29541 +       AuDebugOn(ino < AUFS_FIRST_INO);
29542 +       ino -= AUFS_FIRST_INO;
29543 +       *pindex = ino / page_bits;
29544 +       *bit = ino % page_bits;
29545 +}
29546 +
29547 +static int xib_pindex(struct super_block *sb, unsigned long pindex)
29548 +{
29549 +       int err;
29550 +       loff_t pos;
29551 +       ssize_t sz;
29552 +       struct au_sbinfo *sbinfo;
29553 +       struct file *xib;
29554 +       unsigned long *p;
29555 +
29556 +       sbinfo = au_sbi(sb);
29557 +       MtxMustLock(&sbinfo->si_xib_mtx);
29558 +       AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
29559 +                 || !au_opt_test(sbinfo->si_mntflags, XINO));
29560 +
29561 +       if (pindex == sbinfo->si_xib_last_pindex)
29562 +               return 0;
29563 +
29564 +       xib = sbinfo->si_xib;
29565 +       p = sbinfo->si_xib_buf;
29566 +       pos = sbinfo->si_xib_last_pindex;
29567 +       pos *= PAGE_SIZE;
29568 +       sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
29569 +       if (unlikely(sz != PAGE_SIZE))
29570 +               goto out;
29571 +
29572 +       pos = pindex;
29573 +       pos *= PAGE_SIZE;
29574 +       if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE)
29575 +               sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
29576 +       else {
29577 +               memset(p, 0, PAGE_SIZE);
29578 +               sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
29579 +       }
29580 +       if (sz == PAGE_SIZE) {
29581 +               sbinfo->si_xib_last_pindex = pindex;
29582 +               return 0; /* success */
29583 +       }
29584 +
29585 +out:
29586 +       AuIOErr1("write failed (%zd)\n", sz);
29587 +       err = sz;
29588 +       if (sz >= 0)
29589 +               err = -EIO;
29590 +       return err;
29591 +}
29592 +
29593 +/* ---------------------------------------------------------------------- */
29594 +
29595 +static void au_xib_clear_bit(struct inode *inode)
29596 +{
29597 +       int err, bit;
29598 +       unsigned long pindex;
29599 +       struct super_block *sb;
29600 +       struct au_sbinfo *sbinfo;
29601 +
29602 +       AuDebugOn(inode->i_nlink);
29603 +
29604 +       sb = inode->i_sb;
29605 +       xib_calc_bit(inode->i_ino, &pindex, &bit);
29606 +       AuDebugOn(page_bits <= bit);
29607 +       sbinfo = au_sbi(sb);
29608 +       mutex_lock(&sbinfo->si_xib_mtx);
29609 +       err = xib_pindex(sb, pindex);
29610 +       if (!err) {
29611 +               clear_bit(bit, sbinfo->si_xib_buf);
29612 +               sbinfo->si_xib_next_bit = bit;
29613 +       }
29614 +       mutex_unlock(&sbinfo->si_xib_mtx);
29615 +}
29616 +
29617 +/* for s_op->delete_inode() */
29618 +void au_xino_delete_inode(struct inode *inode, const int unlinked)
29619 +{
29620 +       int err;
29621 +       unsigned int mnt_flags;
29622 +       aufs_bindex_t bindex, bend, bi;
29623 +       unsigned char try_trunc;
29624 +       struct au_iinfo *iinfo;
29625 +       struct super_block *sb;
29626 +       struct au_hinode *hi;
29627 +       struct inode *h_inode;
29628 +       struct au_branch *br;
29629 +       au_writef_t xwrite;
29630 +
29631 +       sb = inode->i_sb;
29632 +       mnt_flags = au_mntflags(sb);
29633 +       if (!au_opt_test(mnt_flags, XINO)
29634 +           || inode->i_ino == AUFS_ROOT_INO)
29635 +               return;
29636 +
29637 +       if (unlinked) {
29638 +               au_xigen_inc(inode);
29639 +               au_xib_clear_bit(inode);
29640 +       }
29641 +
29642 +       iinfo = au_ii(inode);
29643 +       if (!iinfo)
29644 +               return;
29645 +
29646 +       bindex = iinfo->ii_bstart;
29647 +       if (bindex < 0)
29648 +               return;
29649 +
29650 +       xwrite = au_sbi(sb)->si_xwrite;
29651 +       try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
29652 +       hi = iinfo->ii_hinode + bindex;
29653 +       bend = iinfo->ii_bend;
29654 +       for (; bindex <= bend; bindex++, hi++) {
29655 +               h_inode = hi->hi_inode;
29656 +               if (!h_inode
29657 +                   || (!unlinked && h_inode->i_nlink))
29658 +                       continue;
29659 +
29660 +               /* inode may not be revalidated */
29661 +               bi = au_br_index(sb, hi->hi_id);
29662 +               if (bi < 0)
29663 +                       continue;
29664 +
29665 +               br = au_sbr(sb, bi);
29666 +               err = au_xino_do_write(xwrite, br->br_xino.xi_file,
29667 +                                      h_inode->i_ino, /*ino*/0);
29668 +               if (!err && try_trunc
29669 +                   && au_test_fs_trunc_xino(br->br_mnt->mnt_sb))
29670 +                       xino_try_trunc(sb, br);
29671 +       }
29672 +}
29673 +
29674 +/* get an unused inode number from bitmap */
29675 +ino_t au_xino_new_ino(struct super_block *sb)
29676 +{
29677 +       ino_t ino;
29678 +       unsigned long *p, pindex, ul, pend;
29679 +       struct au_sbinfo *sbinfo;
29680 +       struct file *file;
29681 +       int free_bit, err;
29682 +
29683 +       if (!au_opt_test(au_mntflags(sb), XINO))
29684 +               return iunique(sb, AUFS_FIRST_INO);
29685 +
29686 +       sbinfo = au_sbi(sb);
29687 +       mutex_lock(&sbinfo->si_xib_mtx);
29688 +       p = sbinfo->si_xib_buf;
29689 +       free_bit = sbinfo->si_xib_next_bit;
29690 +       if (free_bit < page_bits && !test_bit(free_bit, p))
29691 +               goto out; /* success */
29692 +       free_bit = find_first_zero_bit(p, page_bits);
29693 +       if (free_bit < page_bits)
29694 +               goto out; /* success */
29695 +
29696 +       pindex = sbinfo->si_xib_last_pindex;
29697 +       for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
29698 +               err = xib_pindex(sb, ul);
29699 +               if (unlikely(err))
29700 +                       goto out_err;
29701 +               free_bit = find_first_zero_bit(p, page_bits);
29702 +               if (free_bit < page_bits)
29703 +                       goto out; /* success */
29704 +       }
29705 +
29706 +       file = sbinfo->si_xib;
29707 +       pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE;
29708 +       for (ul = pindex + 1; ul <= pend; ul++) {
29709 +               err = xib_pindex(sb, ul);
29710 +               if (unlikely(err))
29711 +                       goto out_err;
29712 +               free_bit = find_first_zero_bit(p, page_bits);
29713 +               if (free_bit < page_bits)
29714 +                       goto out; /* success */
29715 +       }
29716 +       BUG();
29717 +
29718 +out:
29719 +       set_bit(free_bit, p);
29720 +       sbinfo->si_xib_next_bit = free_bit + 1;
29721 +       pindex = sbinfo->si_xib_last_pindex;
29722 +       mutex_unlock(&sbinfo->si_xib_mtx);
29723 +       ino = xib_calc_ino(pindex, free_bit);
29724 +       AuDbg("i%lu\n", (unsigned long)ino);
29725 +       return ino;
29726 +out_err:
29727 +       mutex_unlock(&sbinfo->si_xib_mtx);
29728 +       AuDbg("i0\n");
29729 +       return 0;
29730 +}
29731 +
29732 +/*
29733 + * read @ino from xinofile for the specified branch{@sb, @bindex}
29734 + * at the position of @h_ino.
29735 + * if @ino does not exist and @do_new is true, get new one.
29736 + */
29737 +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
29738 +                ino_t *ino)
29739 +{
29740 +       int err;
29741 +       ssize_t sz;
29742 +       loff_t pos;
29743 +       struct file *file;
29744 +       struct au_sbinfo *sbinfo;
29745 +
29746 +       *ino = 0;
29747 +       if (!au_opt_test(au_mntflags(sb), XINO))
29748 +               return 0; /* no xino */
29749 +
29750 +       err = 0;
29751 +       sbinfo = au_sbi(sb);
29752 +       pos = h_ino;
29753 +       if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
29754 +               AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
29755 +               return -EFBIG;
29756 +       }
29757 +       pos *= sizeof(*ino);
29758 +
29759 +       file = au_sbr(sb, bindex)->br_xino.xi_file;
29760 +       if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*ino))
29761 +               return 0; /* no ino */
29762 +
29763 +       sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
29764 +       if (sz == sizeof(*ino))
29765 +               return 0; /* success */
29766 +
29767 +       err = sz;
29768 +       if (unlikely(sz >= 0)) {
29769 +               err = -EIO;
29770 +               AuIOErr("xino read error (%zd)\n", sz);
29771 +       }
29772 +
29773 +       return err;
29774 +}
29775 +
29776 +/* ---------------------------------------------------------------------- */
29777 +
29778 +/* create and set a new xino file */
29779 +
29780 +struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
29781 +{
29782 +       struct file *file;
29783 +       struct dentry *h_parent, *d;
29784 +       struct inode *h_dir;
29785 +       int err;
29786 +
29787 +       /*
29788 +        * at mount-time, and the xino file is the default path,
29789 +        * hnotify is disabled so we have no notify events to ignore.
29790 +        * when a user specified the xino, we cannot get au_hdir to be ignored.
29791 +        */
29792 +       file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
29793 +                              /* | __FMODE_NONOTIFY */,
29794 +                              S_IRUGO | S_IWUGO);
29795 +       if (IS_ERR(file)) {
29796 +               if (!silent)
29797 +                       pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
29798 +               return file;
29799 +       }
29800 +
29801 +       /* keep file count */
29802 +       h_parent = dget_parent(file->f_dentry);
29803 +       h_dir = h_parent->d_inode;
29804 +       mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
29805 +       /* mnt_want_write() is unnecessary here */
29806 +       err = vfsub_unlink(h_dir, &file->f_path, /*force*/0);
29807 +       mutex_unlock(&h_dir->i_mutex);
29808 +       dput(h_parent);
29809 +       if (unlikely(err)) {
29810 +               if (!silent)
29811 +                       pr_err("unlink %s(%d)\n", fname, err);
29812 +               goto out;
29813 +       }
29814 +
29815 +       err = -EINVAL;
29816 +       d = file->f_dentry;
29817 +       if (unlikely(sb == d->d_sb)) {
29818 +               if (!silent)
29819 +                       pr_err("%s must be outside\n", fname);
29820 +               goto out;
29821 +       }
29822 +       if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
29823 +               if (!silent)
29824 +                       pr_err("xino doesn't support %s(%s)\n",
29825 +                              fname, au_sbtype(d->d_sb));
29826 +               goto out;
29827 +       }
29828 +       return file; /* success */
29829 +
29830 +out:
29831 +       fput(file);
29832 +       file = ERR_PTR(err);
29833 +       return file;
29834 +}
29835 +
29836 +/*
29837 + * find another branch who is on the same filesystem of the specified
29838 + * branch{@btgt}. search until @bend.
29839 + */
29840 +static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
29841 +                       aufs_bindex_t bend)
29842 +{
29843 +       aufs_bindex_t bindex;
29844 +       struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
29845 +
29846 +       for (bindex = 0; bindex < btgt; bindex++)
29847 +               if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
29848 +                       return bindex;
29849 +       for (bindex++; bindex <= bend; bindex++)
29850 +               if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
29851 +                       return bindex;
29852 +       return -1;
29853 +}
29854 +
29855 +/* ---------------------------------------------------------------------- */
29856 +
29857 +/*
29858 + * initialize the xinofile for the specified branch @br
29859 + * at the place/path where @base_file indicates.
29860 + * test whether another branch is on the same filesystem or not,
29861 + * if @do_test is true.
29862 + */
29863 +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
29864 +              struct file *base_file, int do_test)
29865 +{
29866 +       int err;
29867 +       ino_t ino;
29868 +       aufs_bindex_t bend, bindex;
29869 +       struct au_branch *shared_br, *b;
29870 +       struct file *file;
29871 +       struct super_block *tgt_sb;
29872 +
29873 +       shared_br = NULL;
29874 +       bend = au_sbend(sb);
29875 +       if (do_test) {
29876 +               tgt_sb = br->br_mnt->mnt_sb;
29877 +               for (bindex = 0; bindex <= bend; bindex++) {
29878 +                       b = au_sbr(sb, bindex);
29879 +                       if (tgt_sb == b->br_mnt->mnt_sb) {
29880 +                               shared_br = b;
29881 +                               break;
29882 +                       }
29883 +               }
29884 +       }
29885 +
29886 +       if (!shared_br || !shared_br->br_xino.xi_file) {
29887 +               struct au_xino_lock_dir ldir;
29888 +
29889 +               au_xino_lock_dir(sb, base_file, &ldir);
29890 +               /* mnt_want_write() is unnecessary here */
29891 +               file = au_xino_create2(base_file, NULL);
29892 +               au_xino_unlock_dir(&ldir);
29893 +               err = PTR_ERR(file);
29894 +               if (IS_ERR(file))
29895 +                       goto out;
29896 +               br->br_xino.xi_file = file;
29897 +       } else {
29898 +               br->br_xino.xi_file = shared_br->br_xino.xi_file;
29899 +               get_file(br->br_xino.xi_file);
29900 +       }
29901 +
29902 +       ino = AUFS_ROOT_INO;
29903 +       err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
29904 +                              h_ino, ino);
29905 +       if (unlikely(err)) {
29906 +               fput(br->br_xino.xi_file);
29907 +               br->br_xino.xi_file = NULL;
29908 +       }
29909 +
29910 +out:
29911 +       return err;
29912 +}
29913 +
29914 +/* ---------------------------------------------------------------------- */
29915 +
29916 +/* trucate a xino bitmap file */
29917 +
29918 +/* todo: slow */
29919 +static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
29920 +{
29921 +       int err, bit;
29922 +       ssize_t sz;
29923 +       unsigned long pindex;
29924 +       loff_t pos, pend;
29925 +       struct au_sbinfo *sbinfo;
29926 +       au_readf_t func;
29927 +       ino_t *ino;
29928 +       unsigned long *p;
29929 +
29930 +       err = 0;
29931 +       sbinfo = au_sbi(sb);
29932 +       MtxMustLock(&sbinfo->si_xib_mtx);
29933 +       p = sbinfo->si_xib_buf;
29934 +       func = sbinfo->si_xread;
29935 +       pend = i_size_read(file->f_dentry->d_inode);
29936 +       pos = 0;
29937 +       while (pos < pend) {
29938 +               sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
29939 +               err = sz;
29940 +               if (unlikely(sz <= 0))
29941 +                       goto out;
29942 +
29943 +               err = 0;
29944 +               for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
29945 +                       if (unlikely(*ino < AUFS_FIRST_INO))
29946 +                               continue;
29947 +
29948 +                       xib_calc_bit(*ino, &pindex, &bit);
29949 +                       AuDebugOn(page_bits <= bit);
29950 +                       err = xib_pindex(sb, pindex);
29951 +                       if (!err)
29952 +                               set_bit(bit, p);
29953 +                       else
29954 +                               goto out;
29955 +               }
29956 +       }
29957 +
29958 +out:
29959 +       return err;
29960 +}
29961 +
29962 +static int xib_restore(struct super_block *sb)
29963 +{
29964 +       int err;
29965 +       aufs_bindex_t bindex, bend;
29966 +       void *page;
29967 +
29968 +       err = -ENOMEM;
29969 +       page = (void *)__get_free_page(GFP_NOFS);
29970 +       if (unlikely(!page))
29971 +               goto out;
29972 +
29973 +       err = 0;
29974 +       bend = au_sbend(sb);
29975 +       for (bindex = 0; !err && bindex <= bend; bindex++)
29976 +               if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
29977 +                       err = do_xib_restore
29978 +                               (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
29979 +               else
29980 +                       AuDbg("b%d\n", bindex);
29981 +       free_page((unsigned long)page);
29982 +
29983 +out:
29984 +       return err;
29985 +}
29986 +
29987 +int au_xib_trunc(struct super_block *sb)
29988 +{
29989 +       int err;
29990 +       ssize_t sz;
29991 +       loff_t pos;
29992 +       struct au_xino_lock_dir ldir;
29993 +       struct au_sbinfo *sbinfo;
29994 +       unsigned long *p;
29995 +       struct file *file;
29996 +
29997 +       SiMustWriteLock(sb);
29998 +
29999 +       err = 0;
30000 +       sbinfo = au_sbi(sb);
30001 +       if (!au_opt_test(sbinfo->si_mntflags, XINO))
30002 +               goto out;
30003 +
30004 +       file = sbinfo->si_xib;
30005 +       if (i_size_read(file->f_dentry->d_inode) <= PAGE_SIZE)
30006 +               goto out;
30007 +
30008 +       au_xino_lock_dir(sb, file, &ldir);
30009 +       /* mnt_want_write() is unnecessary here */
30010 +       file = au_xino_create2(sbinfo->si_xib, NULL);
30011 +       au_xino_unlock_dir(&ldir);
30012 +       err = PTR_ERR(file);
30013 +       if (IS_ERR(file))
30014 +               goto out;
30015 +       fput(sbinfo->si_xib);
30016 +       sbinfo->si_xib = file;
30017 +
30018 +       p = sbinfo->si_xib_buf;
30019 +       memset(p, 0, PAGE_SIZE);
30020 +       pos = 0;
30021 +       sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
30022 +       if (unlikely(sz != PAGE_SIZE)) {
30023 +               err = sz;
30024 +               AuIOErr("err %d\n", err);
30025 +               if (sz >= 0)
30026 +                       err = -EIO;
30027 +               goto out;
30028 +       }
30029 +
30030 +       mutex_lock(&sbinfo->si_xib_mtx);
30031 +       /* mnt_want_write() is unnecessary here */
30032 +       err = xib_restore(sb);
30033 +       mutex_unlock(&sbinfo->si_xib_mtx);
30034 +
30035 +out:
30036 +       return err;
30037 +}
30038 +
30039 +/* ---------------------------------------------------------------------- */
30040 +
30041 +/*
30042 + * xino mount option handlers
30043 + */
30044 +static au_readf_t find_readf(struct file *h_file)
30045 +{
30046 +       const struct file_operations *fop = h_file->f_op;
30047 +
30048 +       if (fop) {
30049 +               if (fop->read)
30050 +                       return fop->read;
30051 +               if (fop->aio_read)
30052 +                       return do_sync_read;
30053 +       }
30054 +       return ERR_PTR(-ENOSYS);
30055 +}
30056 +
30057 +static au_writef_t find_writef(struct file *h_file)
30058 +{
30059 +       const struct file_operations *fop = h_file->f_op;
30060 +
30061 +       if (fop) {
30062 +               if (fop->write)
30063 +                       return fop->write;
30064 +               if (fop->aio_write)
30065 +                       return do_sync_write;
30066 +       }
30067 +       return ERR_PTR(-ENOSYS);
30068 +}
30069 +
30070 +/* xino bitmap */
30071 +static void xino_clear_xib(struct super_block *sb)
30072 +{
30073 +       struct au_sbinfo *sbinfo;
30074 +
30075 +       SiMustWriteLock(sb);
30076 +
30077 +       sbinfo = au_sbi(sb);
30078 +       sbinfo->si_xread = NULL;
30079 +       sbinfo->si_xwrite = NULL;
30080 +       if (sbinfo->si_xib)
30081 +               fput(sbinfo->si_xib);
30082 +       sbinfo->si_xib = NULL;
30083 +       free_page((unsigned long)sbinfo->si_xib_buf);
30084 +       sbinfo->si_xib_buf = NULL;
30085 +}
30086 +
30087 +static int au_xino_set_xib(struct super_block *sb, struct file *base)
30088 +{
30089 +       int err;
30090 +       loff_t pos;
30091 +       struct au_sbinfo *sbinfo;
30092 +       struct file *file;
30093 +
30094 +       SiMustWriteLock(sb);
30095 +
30096 +       sbinfo = au_sbi(sb);
30097 +       file = au_xino_create2(base, sbinfo->si_xib);
30098 +       err = PTR_ERR(file);
30099 +       if (IS_ERR(file))
30100 +               goto out;
30101 +       if (sbinfo->si_xib)
30102 +               fput(sbinfo->si_xib);
30103 +       sbinfo->si_xib = file;
30104 +       sbinfo->si_xread = find_readf(file);
30105 +       sbinfo->si_xwrite = find_writef(file);
30106 +
30107 +       err = -ENOMEM;
30108 +       if (!sbinfo->si_xib_buf)
30109 +               sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
30110 +       if (unlikely(!sbinfo->si_xib_buf))
30111 +               goto out_unset;
30112 +
30113 +       sbinfo->si_xib_last_pindex = 0;
30114 +       sbinfo->si_xib_next_bit = 0;
30115 +       if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) {
30116 +               pos = 0;
30117 +               err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
30118 +                                 PAGE_SIZE, &pos);
30119 +               if (unlikely(err != PAGE_SIZE))
30120 +                       goto out_free;
30121 +       }
30122 +       err = 0;
30123 +       goto out; /* success */
30124 +
30125 +out_free:
30126 +       free_page((unsigned long)sbinfo->si_xib_buf);
30127 +       sbinfo->si_xib_buf = NULL;
30128 +       if (err >= 0)
30129 +               err = -EIO;
30130 +out_unset:
30131 +       fput(sbinfo->si_xib);
30132 +       sbinfo->si_xib = NULL;
30133 +       sbinfo->si_xread = NULL;
30134 +       sbinfo->si_xwrite = NULL;
30135 +out:
30136 +       return err;
30137 +}
30138 +
30139 +/* xino for each branch */
30140 +static void xino_clear_br(struct super_block *sb)
30141 +{
30142 +       aufs_bindex_t bindex, bend;
30143 +       struct au_branch *br;
30144 +
30145 +       bend = au_sbend(sb);
30146 +       for (bindex = 0; bindex <= bend; bindex++) {
30147 +               br = au_sbr(sb, bindex);
30148 +               if (!br || !br->br_xino.xi_file)
30149 +                       continue;
30150 +
30151 +               fput(br->br_xino.xi_file);
30152 +               br->br_xino.xi_file = NULL;
30153 +       }
30154 +}
30155 +
30156 +static int au_xino_set_br(struct super_block *sb, struct file *base)
30157 +{
30158 +       int err;
30159 +       ino_t ino;
30160 +       aufs_bindex_t bindex, bend, bshared;
30161 +       struct {
30162 +               struct file *old, *new;
30163 +       } *fpair, *p;
30164 +       struct au_branch *br;
30165 +       struct inode *inode;
30166 +       au_writef_t writef;
30167 +
30168 +       SiMustWriteLock(sb);
30169 +
30170 +       err = -ENOMEM;
30171 +       bend = au_sbend(sb);
30172 +       fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
30173 +       if (unlikely(!fpair))
30174 +               goto out;
30175 +
30176 +       inode = sb->s_root->d_inode;
30177 +       ino = AUFS_ROOT_INO;
30178 +       writef = au_sbi(sb)->si_xwrite;
30179 +       for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
30180 +               br = au_sbr(sb, bindex);
30181 +               bshared = is_sb_shared(sb, bindex, bindex - 1);
30182 +               if (bshared >= 0) {
30183 +                       /* shared xino */
30184 +                       *p = fpair[bshared];
30185 +                       get_file(p->new);
30186 +               }
30187 +
30188 +               if (!p->new) {
30189 +                       /* new xino */
30190 +                       p->old = br->br_xino.xi_file;
30191 +                       p->new = au_xino_create2(base, br->br_xino.xi_file);
30192 +                       err = PTR_ERR(p->new);
30193 +                       if (IS_ERR(p->new)) {
30194 +                               p->new = NULL;
30195 +                               goto out_pair;
30196 +                       }
30197 +               }
30198 +
30199 +               err = au_xino_do_write(writef, p->new,
30200 +                                      au_h_iptr(inode, bindex)->i_ino, ino);
30201 +               if (unlikely(err))
30202 +                       goto out_pair;
30203 +       }
30204 +
30205 +       for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
30206 +               br = au_sbr(sb, bindex);
30207 +               if (br->br_xino.xi_file)
30208 +                       fput(br->br_xino.xi_file);
30209 +               get_file(p->new);
30210 +               br->br_xino.xi_file = p->new;
30211 +       }
30212 +
30213 +out_pair:
30214 +       for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
30215 +               if (p->new)
30216 +                       fput(p->new);
30217 +               else
30218 +                       break;
30219 +       kfree(fpair);
30220 +out:
30221 +       return err;
30222 +}
30223 +
30224 +void au_xino_clr(struct super_block *sb)
30225 +{
30226 +       struct au_sbinfo *sbinfo;
30227 +
30228 +       au_xigen_clr(sb);
30229 +       xino_clear_xib(sb);
30230 +       xino_clear_br(sb);
30231 +       sbinfo = au_sbi(sb);
30232 +       /* lvalue, do not call au_mntflags() */
30233 +       au_opt_clr(sbinfo->si_mntflags, XINO);
30234 +}
30235 +
30236 +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
30237 +{
30238 +       int err, skip;
30239 +       struct dentry *parent, *cur_parent;
30240 +       struct qstr *dname, *cur_name;
30241 +       struct file *cur_xino;
30242 +       struct inode *dir;
30243 +       struct au_sbinfo *sbinfo;
30244 +
30245 +       SiMustWriteLock(sb);
30246 +
30247 +       err = 0;
30248 +       sbinfo = au_sbi(sb);
30249 +       parent = dget_parent(xino->file->f_dentry);
30250 +       if (remount) {
30251 +               skip = 0;
30252 +               dname = &xino->file->f_dentry->d_name;
30253 +               cur_xino = sbinfo->si_xib;
30254 +               if (cur_xino) {
30255 +                       cur_parent = dget_parent(cur_xino->f_dentry);
30256 +                       cur_name = &cur_xino->f_dentry->d_name;
30257 +                       skip = (cur_parent == parent
30258 +                               && dname->len == cur_name->len
30259 +                               && !memcmp(dname->name, cur_name->name,
30260 +                                          dname->len));
30261 +                       dput(cur_parent);
30262 +               }
30263 +               if (skip)
30264 +                       goto out;
30265 +       }
30266 +
30267 +       au_opt_set(sbinfo->si_mntflags, XINO);
30268 +       dir = parent->d_inode;
30269 +       mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
30270 +       /* mnt_want_write() is unnecessary here */
30271 +       err = au_xino_set_xib(sb, xino->file);
30272 +       if (!err)
30273 +               err = au_xigen_set(sb, xino->file);
30274 +       if (!err)
30275 +               err = au_xino_set_br(sb, xino->file);
30276 +       mutex_unlock(&dir->i_mutex);
30277 +       if (!err)
30278 +               goto out; /* success */
30279 +
30280 +       /* reset all */
30281 +       AuIOErr("failed creating xino(%d).\n", err);
30282 +
30283 +out:
30284 +       dput(parent);
30285 +       return err;
30286 +}
30287 +
30288 +/* ---------------------------------------------------------------------- */
30289 +
30290 +/*
30291 + * create a xinofile at the default place/path.
30292 + */
30293 +struct file *au_xino_def(struct super_block *sb)
30294 +{
30295 +       struct file *file;
30296 +       char *page, *p;
30297 +       struct au_branch *br;
30298 +       struct super_block *h_sb;
30299 +       struct path path;
30300 +       aufs_bindex_t bend, bindex, bwr;
30301 +
30302 +       br = NULL;
30303 +       bend = au_sbend(sb);
30304 +       bwr = -1;
30305 +       for (bindex = 0; bindex <= bend; bindex++) {
30306 +               br = au_sbr(sb, bindex);
30307 +               if (au_br_writable(br->br_perm)
30308 +                   && !au_test_fs_bad_xino(br->br_mnt->mnt_sb)) {
30309 +                       bwr = bindex;
30310 +                       break;
30311 +               }
30312 +       }
30313 +
30314 +       if (bwr >= 0) {
30315 +               file = ERR_PTR(-ENOMEM);
30316 +               page = (void *)__get_free_page(GFP_NOFS);
30317 +               if (unlikely(!page))
30318 +                       goto out;
30319 +               path.mnt = br->br_mnt;
30320 +               path.dentry = au_h_dptr(sb->s_root, bwr);
30321 +               p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
30322 +               file = (void *)p;
30323 +               if (!IS_ERR(p)) {
30324 +                       strcat(p, "/" AUFS_XINO_FNAME);
30325 +                       AuDbg("%s\n", p);
30326 +                       file = au_xino_create(sb, p, /*silent*/0);
30327 +                       if (!IS_ERR(file))
30328 +                               au_xino_brid_set(sb, br->br_id);
30329 +               }
30330 +               free_page((unsigned long)page);
30331 +       } else {
30332 +               file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
30333 +               if (IS_ERR(file))
30334 +                       goto out;
30335 +               h_sb = file->f_dentry->d_sb;
30336 +               if (unlikely(au_test_fs_bad_xino(h_sb))) {
30337 +                       pr_err("xino doesn't support %s(%s)\n",
30338 +                              AUFS_XINO_DEFPATH, au_sbtype(h_sb));
30339 +                       fput(file);
30340 +                       file = ERR_PTR(-EINVAL);
30341 +               }
30342 +               if (!IS_ERR(file))
30343 +                       au_xino_brid_set(sb, -1);
30344 +       }
30345 +
30346 +out:
30347 +       return file;
30348 +}
30349 +
30350 +/* ---------------------------------------------------------------------- */
30351 +
30352 +int au_xino_path(struct seq_file *seq, struct file *file)
30353 +{
30354 +       int err;
30355 +
30356 +       err = au_seq_path(seq, &file->f_path);
30357 +       if (unlikely(err < 0))
30358 +               goto out;
30359 +
30360 +       err = 0;
30361 +#define Deleted "\\040(deleted)"
30362 +       seq->count -= sizeof(Deleted) - 1;
30363 +       AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
30364 +                        sizeof(Deleted) - 1));
30365 +#undef Deleted
30366 +
30367 +out:
30368 +       return err;
30369 +}
30370 diff -urN /usr/share/empty/include/linux/aufs_type.h linux/include/linux/aufs_type.h
30371 --- /usr/share/empty/include/linux/aufs_type.h  1970-01-01 01:00:00.000000000 +0100
30372 +++ linux/include/linux/aufs_type.h     2013-01-11 19:46:28.699667650 +0100
30373 @@ -0,0 +1,19 @@
30374 +/*
30375 + * Copyright (C) 2012-2013 Junjiro R. Okajima
30376 + *
30377 + * This program, aufs is free software; you can redistribute it and/or modify
30378 + * it under the terms of the GNU General Public License as published by
30379 + * the Free Software Foundation; either version 2 of the License, or
30380 + * (at your option) any later version.
30381 + *
30382 + * This program is distributed in the hope that it will be useful,
30383 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
30384 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30385 + * GNU General Public License for more details.
30386 + *
30387 + * You should have received a copy of the GNU General Public License
30388 + * along with this program; if not, write to the Free Software
30389 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
30390 + */
30391 +
30392 +#include <uapi/linux/aufs_type.h>
30393 diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
30394 --- /usr/share/empty/include/uapi/linux/aufs_type.h     1970-01-01 01:00:00.000000000 +0100
30395 +++ linux/include/uapi/linux/aufs_type.h        2013-01-11 19:46:28.699667650 +0100
30396 @@ -0,0 +1,233 @@
30397 +/*
30398 + * Copyright (C) 2005-2013 Junjiro R. Okajima
30399 + *
30400 + * This program, aufs is free software; you can redistribute it and/or modify
30401 + * it under the terms of the GNU General Public License as published by
30402 + * the Free Software Foundation; either version 2 of the License, or
30403 + * (at your option) any later version.
30404 + *
30405 + * This program is distributed in the hope that it will be useful,
30406 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
30407 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30408 + * GNU General Public License for more details.
30409 + *
30410 + * You should have received a copy of the GNU General Public License
30411 + * along with this program; if not, write to the Free Software
30412 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
30413 + */
30414 +
30415 +#ifndef __AUFS_TYPE_H__
30416 +#define __AUFS_TYPE_H__
30417 +
30418 +#define AUFS_NAME      "aufs"
30419 +
30420 +#ifdef __KERNEL__
30421 +/*
30422 + * define it before including all other headers.
30423 + * sched.h may use pr_* macros before defining "current", so define the
30424 + * no-current version first, and re-define later.
30425 + */
30426 +#define pr_fmt(fmt)    AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
30427 +#include <linux/sched.h>
30428 +#undef pr_fmt
30429 +#define pr_fmt(fmt)    AUFS_NAME " %s:%d:%s[%d]: " fmt, \
30430 +               __func__, __LINE__, current->comm, current->pid
30431 +#else
30432 +#include <stdint.h>
30433 +#include <sys/types.h>
30434 +#endif /* __KERNEL__ */
30435 +
30436 +#include <linux/limits.h>
30437 +
30438 +#define AUFS_VERSION   "3.7-20130107"
30439 +
30440 +/* todo? move this to linux-2.6.19/include/magic.h */
30441 +#define AUFS_SUPER_MAGIC       ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
30442 +
30443 +/* ---------------------------------------------------------------------- */
30444 +
30445 +#ifdef CONFIG_AUFS_BRANCH_MAX_127
30446 +typedef int8_t aufs_bindex_t;
30447 +#define AUFS_BRANCH_MAX 127
30448 +#else
30449 +typedef int16_t aufs_bindex_t;
30450 +#ifdef CONFIG_AUFS_BRANCH_MAX_511
30451 +#define AUFS_BRANCH_MAX 511
30452 +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
30453 +#define AUFS_BRANCH_MAX 1023
30454 +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
30455 +#define AUFS_BRANCH_MAX 32767
30456 +#endif
30457 +#endif
30458 +
30459 +#ifdef __KERNEL__
30460 +#ifndef AUFS_BRANCH_MAX
30461 +#error unknown CONFIG_AUFS_BRANCH_MAX value
30462 +#endif
30463 +#endif /* __KERNEL__ */
30464 +
30465 +/* ---------------------------------------------------------------------- */
30466 +
30467 +#define AUFS_FSTYPE            AUFS_NAME
30468 +
30469 +#define AUFS_ROOT_INO          2
30470 +#define AUFS_FIRST_INO         11
30471 +
30472 +#define AUFS_WH_PFX            ".wh."
30473 +#define AUFS_WH_PFX_LEN                ((int)sizeof(AUFS_WH_PFX) - 1)
30474 +#define AUFS_WH_TMP_LEN                4
30475 +/* a limit for rmdir/rename a dir */
30476 +#define AUFS_MAX_NAMELEN       (NAME_MAX \
30477 +                               - AUFS_WH_PFX_LEN * 2   /* doubly whiteouted */\
30478 +                               - 1                     /* dot */\
30479 +                               - AUFS_WH_TMP_LEN)      /* hex */
30480 +#define AUFS_XINO_FNAME                "." AUFS_NAME ".xino"
30481 +#define AUFS_XINO_DEFPATH      "/tmp/" AUFS_XINO_FNAME
30482 +#define AUFS_XINO_TRUNC_INIT   64 /* blocks */
30483 +#define AUFS_XINO_TRUNC_STEP   4  /* blocks */
30484 +#define AUFS_DIRWH_DEF         3
30485 +#define AUFS_RDCACHE_DEF       10 /* seconds */
30486 +#define AUFS_RDCACHE_MAX       3600 /* seconds */
30487 +#define AUFS_RDBLK_DEF         512 /* bytes */
30488 +#define AUFS_RDHASH_DEF                32
30489 +#define AUFS_WKQ_NAME          AUFS_NAME "d"
30490 +#define AUFS_MFS_DEF_SEC       30 /* seconds */
30491 +#define AUFS_MFS_MAX_SEC       3600 /* seconds */
30492 +#define AUFS_PLINK_WARN                100 /* number of plinks */
30493 +
30494 +/* pseudo-link maintenace under /proc */
30495 +#define AUFS_PLINK_MAINT_NAME  "plink_maint"
30496 +#define AUFS_PLINK_MAINT_DIR   "fs/" AUFS_NAME
30497 +#define AUFS_PLINK_MAINT_PATH  AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
30498 +
30499 +#define AUFS_DIROPQ_NAME       AUFS_WH_PFX ".opq" /* whiteouted doubly */
30500 +#define AUFS_WH_DIROPQ         AUFS_WH_PFX AUFS_DIROPQ_NAME
30501 +
30502 +#define AUFS_BASE_NAME         AUFS_WH_PFX AUFS_NAME
30503 +#define AUFS_PLINKDIR_NAME     AUFS_WH_PFX "plnk"
30504 +#define AUFS_ORPHDIR_NAME      AUFS_WH_PFX "orph"
30505 +
30506 +/* doubly whiteouted */
30507 +#define AUFS_WH_BASE           AUFS_WH_PFX AUFS_BASE_NAME
30508 +#define AUFS_WH_PLINKDIR       AUFS_WH_PFX AUFS_PLINKDIR_NAME
30509 +#define AUFS_WH_ORPHDIR                AUFS_WH_PFX AUFS_ORPHDIR_NAME
30510 +
30511 +/* branch permissions and attributes */
30512 +#define AUFS_BRPERM_RW         "rw"
30513 +#define AUFS_BRPERM_RO         "ro"
30514 +#define AUFS_BRPERM_RR         "rr"
30515 +#define AUFS_BRRATTR_WH                "wh"
30516 +#define AUFS_BRWATTR_NLWH      "nolwh"
30517 +
30518 +/* ---------------------------------------------------------------------- */
30519 +
30520 +/* ioctl */
30521 +enum {
30522 +       /* readdir in userspace */
30523 +       AuCtl_RDU,
30524 +       AuCtl_RDU_INO,
30525 +
30526 +       /* pathconf wrapper */
30527 +       AuCtl_WBR_FD,
30528 +
30529 +       /* busy inode */
30530 +       AuCtl_IBUSY
30531 +};
30532 +
30533 +/* borrowed from linux/include/linux/kernel.h */
30534 +#ifndef ALIGN
30535 +#define ALIGN(x, a)            __ALIGN_MASK(x, (typeof(x))(a)-1)
30536 +#define __ALIGN_MASK(x, mask)  (((x)+(mask))&~(mask))
30537 +#endif
30538 +
30539 +/* borrowed from linux/include/linux/compiler-gcc3.h */
30540 +#ifndef __aligned
30541 +#define __aligned(x)                   __attribute__((aligned(x)))
30542 +#endif
30543 +
30544 +#ifdef __KERNEL__
30545 +#ifndef __packed
30546 +#define __packed                       __attribute__((packed))
30547 +#endif
30548 +#endif
30549 +
30550 +struct au_rdu_cookie {
30551 +       uint64_t        h_pos;
30552 +       int16_t         bindex;
30553 +       uint8_t         flags;
30554 +       uint8_t         pad;
30555 +       uint32_t        generation;
30556 +} __aligned(8);
30557 +
30558 +struct au_rdu_ent {
30559 +       uint64_t        ino;
30560 +       int16_t         bindex;
30561 +       uint8_t         type;
30562 +       uint8_t         nlen;
30563 +       uint8_t         wh;
30564 +       char            name[0];
30565 +} __aligned(8);
30566 +
30567 +static inline int au_rdu_len(int nlen)
30568 +{
30569 +       /* include the terminating NULL */
30570 +       return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
30571 +                    sizeof(uint64_t));
30572 +}
30573 +
30574 +union au_rdu_ent_ul {
30575 +       struct au_rdu_ent __user        *e;
30576 +       uint64_t                        ul;
30577 +};
30578 +
30579 +enum {
30580 +       AufsCtlRduV_SZ,
30581 +       AufsCtlRduV_End
30582 +};
30583 +
30584 +struct aufs_rdu {
30585 +       /* input */
30586 +       union {
30587 +               uint64_t        sz;     /* AuCtl_RDU */
30588 +               uint64_t        nent;   /* AuCtl_RDU_INO */
30589 +       };
30590 +       union au_rdu_ent_ul     ent;
30591 +       uint16_t                verify[AufsCtlRduV_End];
30592 +
30593 +       /* input/output */
30594 +       uint32_t                blk;
30595 +
30596 +       /* output */
30597 +       union au_rdu_ent_ul     tail;
30598 +       /* number of entries which were added in a single call */
30599 +       uint64_t                rent;
30600 +       uint8_t                 full;
30601 +       uint8_t                 shwh;
30602 +
30603 +       struct au_rdu_cookie    cookie;
30604 +} __aligned(8);
30605 +
30606 +/* ---------------------------------------------------------------------- */
30607 +
30608 +struct aufs_wbr_fd {
30609 +       uint32_t        oflags;
30610 +       int16_t         brid;
30611 +} __aligned(8);
30612 +
30613 +/* ---------------------------------------------------------------------- */
30614 +
30615 +struct aufs_ibusy {
30616 +       uint64_t        ino, h_ino;
30617 +       int16_t         bindex;
30618 +} __aligned(8);
30619 +
30620 +/* ---------------------------------------------------------------------- */
30621 +
30622 +#define AuCtlType              'A'
30623 +#define AUFS_CTL_RDU           _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
30624 +#define AUFS_CTL_RDU_INO       _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
30625 +#define AUFS_CTL_WBR_FD                _IOW(AuCtlType, AuCtl_WBR_FD, \
30626 +                                    struct aufs_wbr_fd)
30627 +#define AUFS_CTL_IBUSY         _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
30628 +
30629 +#endif /* __AUFS_TYPE_H__ */
30630
This page took 2.135792 seconds and 2 git commands to generate.