]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-aufs3.patch
- aufs from 3.10 branch
[packages/kernel.git] / kernel-aufs3.patch
1 aufs3.10 kbuild patch
2
3 diff --git a/fs/Kconfig b/fs/Kconfig
4 index c229f82..397b473 100644
5 --- a/fs/Kconfig
6 +++ b/fs/Kconfig
7 @@ -212,6 +212,7 @@ source "fs/ufs/Kconfig"
8  source "fs/exofs/Kconfig"
9  source "fs/f2fs/Kconfig"
10  source "fs/efivarfs/Kconfig"
11 +source "fs/aufs/Kconfig"
12  
13  endif # MISC_FILESYSTEMS
14  
15 diff --git a/fs/Makefile b/fs/Makefile
16 index 4fe6df3..4a57676 100644
17 --- a/fs/Makefile
18 +++ b/fs/Makefile
19 @@ -126,3 +126,4 @@ obj-y                               += exofs/ # Multiple modules
20  obj-$(CONFIG_CEPH_FS)          += ceph/
21  obj-$(CONFIG_PSTORE)           += pstore/
22  obj-$(CONFIG_EFIVAR_FS)                += efivarfs/
23 +obj-$(CONFIG_AUFS_FS)           += aufs/
24 diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
25 index bdc6e87..349600c 100644
26 --- a/include/uapi/linux/Kbuild
27 +++ b/include/uapi/linux/Kbuild
28 @@ -56,6 +56,7 @@ header-y += atmppp.h
29  header-y += atmsap.h
30  header-y += atmsvc.h
31  header-y += audit.h
32 +header-y += aufs_type.h
33  header-y += auto_fs.h
34  header-y += auto_fs4.h
35  header-y += auxvec.h
36 aufs3.10 base patch
37
38 diff --git a/fs/file_table.c b/fs/file_table.c
39 index 485dc0e..8db8096 100644
40 --- a/fs/file_table.c
41 +++ b/fs/file_table.c
42 @@ -36,7 +36,7 @@ struct files_stat_struct files_stat = {
43         .max_files = NR_FILE
44  };
45  
46 -DEFINE_STATIC_LGLOCK(files_lglock);
47 +DEFINE_LGLOCK(files_lglock);
48  
49  /* SLAB cache for file structures */
50  static struct kmem_cache *filp_cachep __read_mostly;
51 diff --git a/fs/inode.c b/fs/inode.c
52 index 00d5fc3..f324521 100644
53 --- a/fs/inode.c
54 +++ b/fs/inode.c
55 @@ -1498,7 +1498,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
56   * This does the actual work of updating an inodes time or version.  Must have
57   * had called mnt_want_write() before calling this.
58   */
59 -static int update_time(struct inode *inode, struct timespec *time, int flags)
60 +int update_time(struct inode *inode, struct timespec *time, int flags)
61  {
62         if (inode->i_op->update_time)
63                 return inode->i_op->update_time(inode, time, flags);
64 diff --git a/fs/splice.c b/fs/splice.c
65 index d37431d..987346f 100644
66 --- a/fs/splice.c
67 +++ b/fs/splice.c
68 @@ -1093,8 +1093,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
69  /*
70   * Attempt to initiate a splice from pipe to file.
71   */
72 -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
73 -                          loff_t *ppos, size_t len, unsigned int flags)
74 +long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
75 +                   loff_t *ppos, size_t len, unsigned int flags)
76  {
77         ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
78                                 loff_t *, size_t, unsigned int);
79 @@ -1124,9 +1124,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
80  /*
81   * Attempt to initiate a splice from a file to a pipe.
82   */
83 -static long do_splice_to(struct file *in, loff_t *ppos,
84 -                        struct pipe_inode_info *pipe, size_t len,
85 -                        unsigned int flags)
86 +long do_splice_to(struct file *in, loff_t *ppos,
87 +                 struct pipe_inode_info *pipe, size_t len,
88 +                 unsigned int flags)
89  {
90         ssize_t (*splice_read)(struct file *, loff_t *,
91                                struct pipe_inode_info *, size_t, unsigned int);
92 diff --git a/include/linux/fs.h b/include/linux/fs.h
93 index 65c2be2..0148214 100644
94 --- a/include/linux/fs.h
95 +++ b/include/linux/fs.h
96 @@ -2574,6 +2574,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
97  extern int inode_newsize_ok(const struct inode *, loff_t offset);
98  extern void setattr_copy(struct inode *inode, const struct iattr *attr);
99  
100 +extern int update_time(struct inode *, struct timespec *, int);
101  extern int file_update_time(struct file *file);
102  
103  extern int generic_show_options(struct seq_file *m, struct dentry *root);
104 diff --git a/include/linux/splice.h b/include/linux/splice.h
105 index 74575cb..bfc6fb6 100644
106 --- a/include/linux/splice.h
107 +++ b/include/linux/splice.h
108 @@ -92,4 +92,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
109  extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
110  
111  extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
112 +
113 +extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
114 +                          loff_t *ppos, size_t len, unsigned int flags);
115 +extern long do_splice_to(struct file *in, loff_t *ppos,
116 +                        struct pipe_inode_info *pipe, size_t len,
117 +                        unsigned int flags);
118  #endif
119 aufs3.10 standalone patch
120
121 diff --git a/fs/file_table.c b/fs/file_table.c
122 index 8db8096..e271e28 100644
123 --- a/fs/file_table.c
124 +++ b/fs/file_table.c
125 @@ -37,6 +37,7 @@ struct files_stat_struct files_stat = {
126  };
127  
128  DEFINE_LGLOCK(files_lglock);
129 +EXPORT_SYMBOL(files_lglock);
130  
131  /* SLAB cache for file structures */
132  static struct kmem_cache *filp_cachep __read_mostly;
133 @@ -405,6 +406,8 @@ void file_sb_list_del(struct file *file)
134         }
135  }
136  
137 +EXPORT_SYMBOL(file_sb_list_del);
138 +
139  #ifdef CONFIG_SMP
140  
141  /*
142 diff --git a/fs/inode.c b/fs/inode.c
143 index f324521..bff7670 100644
144 --- a/fs/inode.c
145 +++ b/fs/inode.c
146 @@ -56,6 +56,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
147  static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
148  
149  __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
150 +EXPORT_SYMBOL(inode_sb_list_lock);
151  
152  /*
153   * Empty aops. Can be used for the cases where the user does not
154 @@ -1514,6 +1515,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
155         mark_inode_dirty_sync(inode);
156         return 0;
157  }
158 +EXPORT_SYMBOL(update_time);
159  
160  /**
161   *     touch_atime     -       update the access time
162 diff --git a/fs/namespace.c b/fs/namespace.c
163 index 7b1ca9b..51db6ad 100644
164 --- a/fs/namespace.c
165 +++ b/fs/namespace.c
166 @@ -54,6 +54,7 @@ EXPORT_SYMBOL_GPL(fs_kobj);
167   * tree or hash is modified or when a vfsmount structure is modified.
168   */
169  DEFINE_BRLOCK(vfsmount_lock);
170 +EXPORT_SYMBOL(vfsmount_lock);
171  
172  static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
173  {
174 @@ -427,6 +428,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
175         mnt_dec_writers(real_mount(mnt));
176         preempt_enable();
177  }
178 +EXPORT_SYMBOL_GPL(__mnt_drop_write);
179  
180  /**
181   * mnt_drop_write - give up write access to a mount
182 @@ -1456,6 +1458,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
183         }
184         return 0;
185  }
186 +EXPORT_SYMBOL(iterate_mounts);
187  
188  static void cleanup_group_ids(struct mount *mnt, struct mount *end)
189  {
190 diff --git a/fs/notify/group.c b/fs/notify/group.c
191 index bd2625b..2ff2a0f 100644
192 --- a/fs/notify/group.c
193 +++ b/fs/notify/group.c
194 @@ -22,6 +22,7 @@
195  #include <linux/srcu.h>
196  #include <linux/rculist.h>
197  #include <linux/wait.h>
198 +#include <linux/module.h>
199  
200  #include <linux/fsnotify_backend.h>
201  #include "fsnotify.h"
202 @@ -65,6 +66,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
203  {
204         atomic_inc(&group->refcnt);
205  }
206 +EXPORT_SYMBOL(fsnotify_get_group);
207  
208  /*
209   * Drop a reference to a group.  Free it if it's through.
210 @@ -74,6 +76,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
211         if (atomic_dec_and_test(&group->refcnt))
212                 fsnotify_final_destroy_group(group);
213  }
214 +EXPORT_SYMBOL(fsnotify_put_group);
215  
216  /*
217   * Create a new fsnotify_group and hold a reference for the group returned.
218 @@ -102,6 +105,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
219  
220         return group;
221  }
222 +EXPORT_SYMBOL(fsnotify_alloc_group);
223  
224  int fsnotify_fasync(int fd, struct file *file, int on)
225  {
226 diff --git a/fs/notify/mark.c b/fs/notify/mark.c
227 index fc6b49b..a6bb87d 100644
228 --- a/fs/notify/mark.c
229 +++ b/fs/notify/mark.c
230 @@ -115,6 +115,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
231                 mark->free_mark(mark);
232         }
233  }
234 +EXPORT_SYMBOL(fsnotify_put_mark);
235  
236  /*
237   * Any time a mark is getting freed we end up here.
238 @@ -197,6 +198,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
239         fsnotify_destroy_mark_locked(mark, group);
240         mutex_unlock(&group->mark_mutex);
241  }
242 +EXPORT_SYMBOL(fsnotify_destroy_mark);
243  
244  void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
245  {
246 @@ -281,6 +283,7 @@ err:
247  
248         return ret;
249  }
250 +EXPORT_SYMBOL(fsnotify_add_mark);
251  
252  int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
253                       struct inode *inode, struct vfsmount *mnt, int allow_dups)
254 @@ -342,6 +345,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
255         atomic_set(&mark->refcnt, 1);
256         mark->free_mark = free_mark;
257  }
258 +EXPORT_SYMBOL(fsnotify_init_mark);
259  
260  static int fsnotify_mark_destroy(void *ignored)
261  {
262 diff --git a/fs/open.c b/fs/open.c
263 index 8c74100..be563cd 100644
264 --- a/fs/open.c
265 +++ b/fs/open.c
266 @@ -61,6 +61,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
267         mutex_unlock(&dentry->d_inode->i_mutex);
268         return ret;
269  }
270 +EXPORT_SYMBOL(do_truncate);
271  
272  long vfs_truncate(struct path *path, loff_t length)
273  {
274 diff --git a/fs/splice.c b/fs/splice.c
275 index 987346f..8d6a045 100644
276 --- a/fs/splice.c
277 +++ b/fs/splice.c
278 @@ -1120,6 +1120,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
279         file_end_write(out);
280         return ret;
281  }
282 +EXPORT_SYMBOL(do_splice_from);
283  
284  /*
285   * Attempt to initiate a splice from a file to a pipe.
286 @@ -1146,6 +1147,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
287  
288         return splice_read(in, ppos, pipe, len, flags);
289  }
290 +EXPORT_SYMBOL(do_splice_to);
291  
292  /**
293   * splice_direct_to_actor - splices data directly between two non-pipes
294 diff --git a/security/commoncap.c b/security/commoncap.c
295 index c44b6fe..d78b003 100644
296 --- a/security/commoncap.c
297 +++ b/security/commoncap.c
298 @@ -988,9 +988,11 @@ int cap_mmap_addr(unsigned long addr)
299         }
300         return ret;
301  }
302 +EXPORT_SYMBOL(cap_mmap_addr);
303  
304  int cap_mmap_file(struct file *file, unsigned long reqprot,
305                   unsigned long prot, unsigned long flags)
306  {
307         return 0;
308  }
309 +EXPORT_SYMBOL(cap_mmap_file);
310 diff --git a/security/device_cgroup.c b/security/device_cgroup.c
311 index dd0dc57..9760ecb6 100644
312 --- a/security/device_cgroup.c
313 +++ b/security/device_cgroup.c
314 @@ -7,6 +7,7 @@
315  #include <linux/device_cgroup.h>
316  #include <linux/cgroup.h>
317  #include <linux/ctype.h>
318 +#include <linux/export.h>
319  #include <linux/list.h>
320  #include <linux/uaccess.h>
321  #include <linux/seq_file.h>
322 @@ -789,6 +790,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
323         return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
324                         access);
325  }
326 +EXPORT_SYMBOL(__devcgroup_inode_permission);
327  
328  int devcgroup_inode_mknod(int mode, dev_t dev)
329  {
330 diff --git a/security/security.c b/security/security.c
331 index a3dce87..06a6ea6 100644
332 --- a/security/security.c
333 +++ b/security/security.c
334 @@ -396,6 +396,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
335                 return 0;
336         return security_ops->path_rmdir(dir, dentry);
337  }
338 +EXPORT_SYMBOL(security_path_rmdir);
339  
340  int security_path_unlink(struct path *dir, struct dentry *dentry)
341  {
342 @@ -412,6 +413,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
343                 return 0;
344         return security_ops->path_symlink(dir, dentry, old_name);
345  }
346 +EXPORT_SYMBOL(security_path_symlink);
347  
348  int security_path_link(struct dentry *old_dentry, struct path *new_dir,
349                        struct dentry *new_dentry)
350 @@ -420,6 +422,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
351                 return 0;
352         return security_ops->path_link(old_dentry, new_dir, new_dentry);
353  }
354 +EXPORT_SYMBOL(security_path_link);
355  
356  int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
357                          struct path *new_dir, struct dentry *new_dentry)
358 @@ -438,6 +441,7 @@ int security_path_truncate(struct path *path)
359                 return 0;
360         return security_ops->path_truncate(path);
361  }
362 +EXPORT_SYMBOL(security_path_truncate);
363  
364  int security_path_chmod(struct path *path, umode_t mode)
365  {
366 @@ -445,6 +449,7 @@ int security_path_chmod(struct path *path, umode_t mode)
367                 return 0;
368         return security_ops->path_chmod(path, mode);
369  }
370 +EXPORT_SYMBOL(security_path_chmod);
371  
372  int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
373  {
374 @@ -452,6 +457,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
375                 return 0;
376         return security_ops->path_chown(path, uid, gid);
377  }
378 +EXPORT_SYMBOL(security_path_chown);
379  
380  int security_path_chroot(struct path *path)
381  {
382 @@ -528,6 +534,7 @@ int security_inode_readlink(struct dentry *dentry)
383                 return 0;
384         return security_ops->inode_readlink(dentry);
385  }
386 +EXPORT_SYMBOL(security_inode_readlink);
387  
388  int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
389  {
390 @@ -542,6 +549,7 @@ int security_inode_permission(struct inode *inode, int mask)
391                 return 0;
392         return security_ops->inode_permission(inode, mask);
393  }
394 +EXPORT_SYMBOL(security_inode_permission);
395  
396  int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
397  {
398 @@ -663,6 +671,7 @@ int security_file_permission(struct file *file, int mask)
399  
400         return fsnotify_perm(file, mask);
401  }
402 +EXPORT_SYMBOL(security_file_permission);
403  
404  int security_file_alloc(struct file *file)
405  {
406 @@ -723,6 +732,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
407                 return ret;
408         return ima_file_mmap(file, prot);
409  }
410 +EXPORT_SYMBOL(security_mmap_file);
411  
412  int security_mmap_addr(unsigned long addr)
413  {
414 diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
415 --- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs     1970-01-01 01:00:00.000000000 +0100
416 +++ linux/Documentation/ABI/testing/debugfs-aufs        2013-07-06 13:20:47.716863966 +0200
417 @@ -0,0 +1,50 @@
418 +What:          /debug/aufs/si_<id>/
419 +Date:          March 2009
420 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
421 +Description:
422 +               Under /debug/aufs, a directory named si_<id> is created
423 +               per aufs mount, where <id> is a unique id generated
424 +               internally.
425 +
426 +What:          /debug/aufs/si_<id>/plink
427 +Date:          Apr 2013
428 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
429 +Description:
430 +               It has three lines and shows the information about the
431 +               pseudo-link. The first line is a single number
432 +               representing a number of buckets. The second line is a
433 +               number of pseudo-links per buckets (separated by a
434 +               blank). The last line is a single number representing a
435 +               total number of psedo-links.
436 +               When the aufs mount option 'noplink' is specified, it
437 +               will show "1\n0\n0\n".
438 +
439 +What:          /debug/aufs/si_<id>/xib
440 +Date:          March 2009
441 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
442 +Description:
443 +               It shows the consumed blocks by xib (External Inode Number
444 +               Bitmap), its block size and file size.
445 +               When the aufs mount option 'noxino' is specified, it
446 +               will be empty. About XINO files, see the aufs manual.
447 +
448 +What:          /debug/aufs/si_<id>/xino0, xino1 ... xinoN
449 +Date:          March 2009
450 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
451 +Description:
452 +               It shows the consumed blocks by xino (External Inode Number
453 +               Translation Table), its link count, block size and file
454 +               size.
455 +               When the aufs mount option 'noxino' is specified, it
456 +               will be empty. About XINO files, see the aufs manual.
457 +
458 +What:          /debug/aufs/si_<id>/xigen
459 +Date:          March 2009
460 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
461 +Description:
462 +               It shows the consumed blocks by xigen (External Inode
463 +               Generation Table), its block size and file size.
464 +               If CONFIG_AUFS_EXPORT is disabled, this entry will not
465 +               be created.
466 +               When the aufs mount option 'noxino' is specified, it
467 +               will be empty. About XINO files, see the aufs manual.
468 diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
469 --- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs       1970-01-01 01:00:00.000000000 +0100
470 +++ linux/Documentation/ABI/testing/sysfs-aufs  2013-07-06 13:20:47.730197761 +0200
471 @@ -0,0 +1,24 @@
472 +What:          /sys/fs/aufs/si_<id>/
473 +Date:          March 2009
474 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
475 +Description:
476 +               Under /sys/fs/aufs, a directory named si_<id> is created
477 +               per aufs mount, where <id> is a unique id generated
478 +               internally.
479 +
480 +What:          /sys/fs/aufs/si_<id>/br0, br1 ... brN
481 +Date:          March 2009
482 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
483 +Description:
484 +               It shows the abolute path of a member directory (which
485 +               is called branch) in aufs, and its permission.
486 +
487 +What:          /sys/fs/aufs/si_<id>/xi_path
488 +Date:          March 2009
489 +Contact:       J. R. Okajima <hooanon05@yahoo.co.jp>
490 +Description:
491 +               It shows the abolute path of XINO (External Inode Number
492 +               Bitmap, Translation Table and Generation Table) file
493 +               even if it is the default path.
494 +               When the aufs mount option 'noxino' is specified, it
495 +               will be empty. About XINO files, see the aufs manual.
496 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
497 --- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt  1970-01-01 01:00:00.000000000 +0100
498 +++ linux/Documentation/filesystems/aufs/design/01intro.txt     2013-07-06 13:20:47.730197761 +0200
499 @@ -0,0 +1,162 @@
500 +
501 +# Copyright (C) 2005-2013 Junjiro R. Okajima
502 +# 
503 +# This program is free software; you can redistribute it and/or modify
504 +# it under the terms of the GNU General Public License as published by
505 +# the Free Software Foundation; either version 2 of the License, or
506 +# (at your option) any later version.
507 +# 
508 +# This program is distributed in the hope that it will be useful,
509 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
510 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
511 +# GNU General Public License for more details.
512 +# 
513 +# You should have received a copy of the GNU General Public License
514 +# along with this program; if not, write to the Free Software
515 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
516 +
517 +Introduction
518 +----------------------------------------
519 +
520 +aufs [ei ju: ef es] | [a u f s]
521 +1. abbrev. for "advanced multi-layered unification filesystem".
522 +2. abbrev. for "another unionfs".
523 +3. abbrev. for "auf das" in German which means "on the" in English.
524 +   Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
525 +   But "Filesystem aufs Filesystem" is hard to understand.
526 +
527 +AUFS is a filesystem with features:
528 +- multi layered stackable unification filesystem, the member directory
529 +  is called as a branch.
530 +- branch permission and attribute, 'readonly', 'real-readonly',
531 +  'readwrite', 'whiteout-able', 'link-able whiteout' and their
532 +  combination.
533 +- internal "file copy-on-write".
534 +- logical deletion, whiteout.
535 +- dynamic branch manipulation, adding, deleting and changing permission.
536 +- allow bypassing aufs, user's direct branch access.
537 +- external inode number translation table and bitmap which maintains the
538 +  persistent aufs inode number.
539 +- seekable directory, including NFS readdir.
540 +- file mapping, mmap and sharing pages.
541 +- pseudo-link, hardlink over branches.
542 +- loopback mounted filesystem as a branch.
543 +- several policies to select one among multiple writable branches.
544 +- revert a single systemcall when an error occurs in aufs.
545 +- and more...
546 +
547 +
548 +Multi Layered Stackable Unification Filesystem
549 +----------------------------------------------------------------------
550 +Most people already knows what it is.
551 +It is a filesystem which unifies several directories and provides a
552 +merged single directory. When users access a file, the access will be
553 +passed/re-directed/converted (sorry, I am not sure which English word is
554 +correct) to the real file on the member filesystem. The member
555 +filesystem is called 'lower filesystem' or 'branch' and has a mode
556 +'readonly' and 'readwrite.' And the deletion for a file on the lower
557 +readonly branch is handled by creating 'whiteout' on the upper writable
558 +branch.
559 +
560 +On LKML, there have been discussions about UnionMount (Jan Blunck,
561 +Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
562 +different approaches to implement the merged-view.
563 +The former tries putting it into VFS, and the latter implements as a
564 +separate filesystem.
565 +(If I misunderstand about these implementations, please let me know and
566 +I shall correct it. Because it is a long time ago when I read their
567 +source files last time).
568 +
569 +UnionMount's approach will be able to small, but may be hard to share
570 +branches between several UnionMount since the whiteout in it is
571 +implemented in the inode on branch filesystem and always
572 +shared. According to Bharata's post, readdir does not seems to be
573 +finished yet.
574 +There are several missing features known in this implementations such as
575 +- for users, the inode number may change silently. eg. copy-up.
576 +- link(2) may break by copy-up.
577 +- read(2) may get an obsoleted filedata (fstat(2) too).
578 +- fcntl(F_SETLK) may be broken by copy-up.
579 +- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
580 +  open(O_RDWR).
581 +
582 +Unionfs has a longer history. When I started implementing a stacking filesystem
583 +(Aug 2005), it already existed. It has virtual super_block, inode,
584 +dentry and file objects and they have an array pointing lower same kind
585 +objects. After contributing many patches for Unionfs, I re-started my
586 +project AUFS (Jun 2006).
587 +
588 +In AUFS, the structure of filesystem resembles to Unionfs, but I
589 +implemented my own ideas, approaches and enhancements and it became
590 +totally different one.
591 +
592 +Comparing DM snapshot and fs based implementation
593 +- the number of bytes to be copied between devices is much smaller.
594 +- the type of filesystem must be one and only.
595 +- the fs must be writable, no readonly fs, even for the lower original
596 +  device. so the compression fs will not be usable. but if we use
597 +  loopback mount, we may address this issue.
598 +  for instance,
599 +       mount /cdrom/squashfs.img /sq
600 +       losetup /sq/ext2.img
601 +       losetup /somewhere/cow
602 +       dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
603 +- it will be difficult (or needs more operations) to extract the
604 +  difference between the original device and COW.
605 +- DM snapshot-merge may help a lot when users try merging. in the
606 +  fs-layer union, users will use rsync(1).
607 +
608 +
609 +Several characters/aspects of aufs
610 +----------------------------------------------------------------------
611 +
612 +Aufs has several characters or aspects.
613 +1. a filesystem, callee of VFS helper
614 +2. sub-VFS, caller of VFS helper for branches
615 +3. a virtual filesystem which maintains persistent inode number
616 +4. reader/writer of files on branches such like an application
617 +
618 +1. Callee of VFS Helper
619 +As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
620 +unlink(2) from an application reaches sys_unlink() kernel function and
621 +then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
622 +calls filesystem specific unlink operation. Actually aufs implements the
623 +unlink operation but it behaves like a redirector.
624 +
625 +2. Caller of VFS Helper for Branches
626 +aufs_unlink() passes the unlink request to the branch filesystem as if
627 +it were called from VFS. So the called unlink operation of the branch
628 +filesystem acts as usual. As a caller of VFS helper, aufs should handle
629 +every necessary pre/post operation for the branch filesystem.
630 +- acquire the lock for the parent dir on a branch
631 +- lookup in a branch
632 +- revalidate dentry on a branch
633 +- mnt_want_write() for a branch
634 +- vfs_unlink() for a branch
635 +- mnt_drop_write() for a branch
636 +- release the lock on a branch
637 +
638 +3. Persistent Inode Number
639 +One of the most important issue for a filesystem is to maintain inode
640 +numbers. This is particularly important to support exporting a
641 +filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
642 +backend block device for its own. But some storage is necessary to
643 +maintain inode number. It may be a large space and may not suit to keep
644 +in memory. Aufs rents some space from its first writable branch
645 +filesystem (by default) and creates file(s) on it. These files are
646 +created by aufs internally and removed soon (currently) keeping opened.
647 +Note: Because these files are removed, they are totally gone after
648 +      unmounting aufs. It means the inode numbers are not persistent
649 +      across unmount or reboot. I have a plan to make them really
650 +      persistent which will be important for aufs on NFS server.
651 +
652 +4. Read/Write Files Internally (copy-on-write)
653 +Because a branch can be readonly, when you write a file on it, aufs will
654 +"copy-up" it to the upper writable branch internally. And then write the
655 +originally requested thing to the file. Generally kernel doesn't
656 +open/read/write file actively. In aufs, even a single write may cause a
657 +internal "file copy". This behaviour is very similar to cp(1) command.
658 +
659 +Some people may think it is better to pass such work to user space
660 +helper, instead of doing in kernel space. Actually I am still thinking
661 +about it. But currently I have implemented it in kernel space.
662 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
663 --- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
664 +++ linux/Documentation/filesystems/aufs/design/02struct.txt    2013-07-06 13:20:47.730197761 +0200
665 @@ -0,0 +1,226 @@
666 +
667 +# Copyright (C) 2005-2013 Junjiro R. Okajima
668 +# 
669 +# This program is free software; you can redistribute it and/or modify
670 +# it under the terms of the GNU General Public License as published by
671 +# the Free Software Foundation; either version 2 of the License, or
672 +# (at your option) any later version.
673 +# 
674 +# This program is distributed in the hope that it will be useful,
675 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
676 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
677 +# GNU General Public License for more details.
678 +# 
679 +# You should have received a copy of the GNU General Public License
680 +# along with this program; if not, write to the Free Software
681 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
682 +
683 +Basic Aufs Internal Structure
684 +
685 +Superblock/Inode/Dentry/File Objects
686 +----------------------------------------------------------------------
687 +As like an ordinary filesystem, aufs has its own
688 +superblock/inode/dentry/file objects. All these objects have a
689 +dynamically allocated array and store the same kind of pointers to the
690 +lower filesystem, branch.
691 +For example, when you build a union with one readwrite branch and one
692 +readonly, mounted /au, /rw and /ro respectively.
693 +- /au = /rw + /ro
694 +- /ro/fileA exists but /rw/fileA
695 +
696 +Aufs lookup operation finds /ro/fileA and gets dentry for that. These
697 +pointers are stored in a aufs dentry. The array in aufs dentry will be,
698 +- [0] = NULL
699 +- [1] = /ro/fileA
700 +
701 +This style of an array is essentially same to the aufs
702 +superblock/inode/dentry/file objects.
703 +
704 +Because aufs supports manipulating branches, ie. add/delete/change
705 +dynamically, these objects has its own generation. When branches are
706 +changed, the generation in aufs superblock is incremented. And a
707 +generation in other object are compared when it is accessed.
708 +When a generation in other objects are obsoleted, aufs refreshes the
709 +internal array.
710 +
711 +
712 +Superblock
713 +----------------------------------------------------------------------
714 +Additionally aufs superblock has some data for policies to select one
715 +among multiple writable branches, XIB files, pseudo-links and kobject.
716 +See below in detail.
717 +About the policies which supports copy-down a directory, see policy.txt
718 +too.
719 +
720 +
721 +Branch and XINO(External Inode Number Translation Table)
722 +----------------------------------------------------------------------
723 +Every branch has its own xino (external inode number translation table)
724 +file. The xino file is created and unlinked by aufs internally. When two
725 +members of a union exist on the same filesystem, they share the single
726 +xino file.
727 +The struct of a xino file is simple, just a sequence of aufs inode
728 +numbers which is indexed by the lower inode number.
729 +In the above sample, assume the inode number of /ro/fileA is i111 and
730 +aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
731 +4(8) bytes at 111 * 4(8) bytes offset in the xino file.
732 +
733 +When the inode numbers are not contiguous, the xino file will be sparse
734 +which has a hole in it and doesn't consume as much disk space as it
735 +might appear. If your branch filesystem consumes disk space for such
736 +holes, then you should specify 'xino=' option at mounting aufs.
737 +
738 +Also a writable branch has three kinds of "whiteout bases". All these
739 +are existed when the branch is joined to aufs and the names are
740 +whiteout-ed doubly, so that users will never see their names in aufs
741 +hierarchy.
742 +1. a regular file which will be linked to all whiteouts.
743 +2. a directory to store a pseudo-link.
744 +3. a directory to store an "orphan-ed" file temporary.
745 +
746 +1. Whiteout Base
747 +   When you remove a file on a readonly branch, aufs handles it as a
748 +   logical deletion and creates a whiteout on the upper writable branch
749 +   as a hardlink of this file in order not to consume inode on the
750 +   writable branch.
751 +2. Pseudo-link Dir
752 +   See below, Pseudo-link.
753 +3. Step-Parent Dir
754 +   When "fileC" exists on the lower readonly branch only and it is
755 +   opened and removed with its parent dir, and then user writes
756 +   something into it, then aufs copies-up fileC to this
757 +   directory. Because there is no other dir to store fileC. After
758 +   creating a file under this dir, the file is unlinked.
759 +
760 +Because aufs supports manipulating branches, ie. add/delete/change
761 +dynamically, a branch has its own id. When the branch order changes, aufs
762 +finds the new index by searching the branch id.
763 +
764 +
765 +Pseudo-link
766 +----------------------------------------------------------------------
767 +Assume "fileA" exists on the lower readonly branch only and it is
768 +hardlinked to "fileB" on the branch. When you write something to fileA,
769 +aufs copies-up it to the upper writable branch. Additionally aufs
770 +creates a hardlink under the Pseudo-link Directory of the writable
771 +branch. The inode of a pseudo-link is kept in aufs super_block as a
772 +simple list. If fileB is read after unlinking fileA, aufs returns
773 +filedata from the pseudo-link instead of the lower readonly
774 +branch. Because the pseudo-link is based upon the inode, to keep the
775 +inode number by xino (see above) is important.
776 +
777 +All the hardlinks under the Pseudo-link Directory of the writable branch
778 +should be restored in a proper location later. Aufs provides a utility
779 +to do this. The userspace helpers executed at remounting and unmounting
780 +aufs by default.
781 +During this utility is running, it puts aufs into the pseudo-link
782 +maintenance mode. In this mode, only the process which began the
783 +maintenance mode (and its child processes) is allowed to operate in
784 +aufs. Some other processes which are not related to the pseudo-link will
785 +be allowed to run too, but the rest have to return an error or wait
786 +until the maintenance mode ends. If a process already acquires an inode
787 +mutex (in VFS), it has to return an error.
788 +
789 +
790 +XIB(external inode number bitmap)
791 +----------------------------------------------------------------------
792 +Addition to the xino file per a branch, aufs has an external inode number
793 +bitmap in a superblock object. It is also a file such like a xino file.
794 +It is a simple bitmap to mark whether the aufs inode number is in-use or
795 +not.
796 +To reduce the file I/O, aufs prepares a single memory page to cache xib.
797 +
798 +Aufs implements a feature to truncate/refresh both of xino and xib to
799 +reduce the number of consumed disk blocks for these files.
800 +
801 +
802 +Virtual or Vertical Dir, and Readdir in Userspace
803 +----------------------------------------------------------------------
804 +In order to support multiple layers (branches), aufs readdir operation
805 +constructs a virtual dir block on memory. For readdir, aufs calls
806 +vfs_readdir() internally for each dir on branches, merges their entries
807 +with eliminating the whiteout-ed ones, and sets it to file (dir)
808 +object. So the file object has its entry list until it is closed. The
809 +entry list will be updated when the file position is zero and becomes
810 +old. This decision is made in aufs automatically.
811 +
812 +The dynamically allocated memory block for the name of entries has a
813 +unit of 512 bytes (by default) and stores the names contiguously (no
814 +padding). Another block for each entry is handled by kmem_cache too.
815 +During building dir blocks, aufs creates hash list and judging whether
816 +the entry is whiteouted by its upper branch or already listed.
817 +The merged result is cached in the corresponding inode object and
818 +maintained by a customizable life-time option.
819 +
820 +Some people may call it can be a security hole or invite DoS attack
821 +since the opened and once readdir-ed dir (file object) holds its entry
822 +list and becomes a pressure for system memory. But I'd say it is similar
823 +to files under /proc or /sys. The virtual files in them also holds a
824 +memory page (generally) while they are opened. When an idea to reduce
825 +memory for them is introduced, it will be applied to aufs too.
826 +For those who really hate this situation, I've developed readdir(3)
827 +library which operates this merging in userspace. You just need to set
828 +LD_PRELOAD environment variable, and aufs will not consume no memory in
829 +kernel space for readdir(3).
830 +
831 +
832 +Workqueue
833 +----------------------------------------------------------------------
834 +Aufs sometimes requires privilege access to a branch. For instance,
835 +in copy-up/down operation. When a user process is going to make changes
836 +to a file which exists in the lower readonly branch only, and the mode
837 +of one of ancestor directories may not be writable by a user
838 +process. Here aufs copy-up the file with its ancestors and they may
839 +require privilege to set its owner/group/mode/etc.
840 +This is a typical case of a application character of aufs (see
841 +Introduction).
842 +
843 +Aufs uses workqueue synchronously for this case. It creates its own
844 +workqueue. The workqueue is a kernel thread and has privilege. Aufs
845 +passes the request to call mkdir or write (for example), and wait for
846 +its completion. This approach solves a problem of a signal handler
847 +simply.
848 +If aufs didn't adopt the workqueue and changed the privilege of the
849 +process, and if the mkdir/write call arises SIGXFSZ or other signal,
850 +then the user process might gain a privilege or the generated core file
851 +was owned by a superuser.
852 +
853 +Also aufs uses the system global workqueue ("events" kernel thread) too
854 +for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
855 +whiteout base and etc. This is unrelated to a privilege.
856 +Most of aufs operation tries acquiring a rw_semaphore for aufs
857 +superblock at the beginning, at the same time waits for the completion
858 +of all queued asynchronous tasks.
859 +
860 +
861 +Whiteout
862 +----------------------------------------------------------------------
863 +The whiteout in aufs is very similar to Unionfs's. That is represented
864 +by its filename. UnionMount takes an approach of a file mode, but I am
865 +afraid several utilities (find(1) or something) will have to support it.
866 +
867 +Basically the whiteout represents "logical deletion" which stops aufs to
868 +lookup further, but also it represents "dir is opaque" which also stop
869 +lookup.
870 +
871 +In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
872 +In order to make several functions in a single systemcall to be
873 +revertible, aufs adopts an approach to rename a directory to a temporary
874 +unique whiteouted name.
875 +For example, in rename(2) dir where the target dir already existed, aufs
876 +renames the target dir to a temporary unique whiteouted name before the
877 +actual rename on a branch and then handles other actions (make it opaque,
878 +update the attributes, etc). If an error happens in these actions, aufs
879 +simply renames the whiteouted name back and returns an error. If all are
880 +succeeded, aufs registers a function to remove the whiteouted unique
881 +temporary name completely and asynchronously to the system global
882 +workqueue.
883 +
884 +
885 +Copy-up
886 +----------------------------------------------------------------------
887 +It is a well-known feature or concept.
888 +When user modifies a file on a readonly branch, aufs operate "copy-up"
889 +internally and makes change to the new file on the upper writable branch.
890 +When the trigger systemcall does not update the timestamps of the parent
891 +dir, aufs reverts it after copy-up.
892 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
893 --- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
894 +++ linux/Documentation/filesystems/aufs/design/03lookup.txt    2013-07-06 13:20:47.730197761 +0200
895 @@ -0,0 +1,106 @@
896 +
897 +# Copyright (C) 2005-2013 Junjiro R. Okajima
898 +# 
899 +# This program is free software; you can redistribute it and/or modify
900 +# it under the terms of the GNU General Public License as published by
901 +# the Free Software Foundation; either version 2 of the License, or
902 +# (at your option) any later version.
903 +# 
904 +# This program is distributed in the hope that it will be useful,
905 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
906 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
907 +# GNU General Public License for more details.
908 +# 
909 +# You should have received a copy of the GNU General Public License
910 +# along with this program; if not, write to the Free Software
911 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
912 +
913 +Lookup in a Branch
914 +----------------------------------------------------------------------
915 +Since aufs has a character of sub-VFS (see Introduction), it operates
916 +lookup for branches as VFS does. It may be a heavy work. Generally
917 +speaking struct nameidata is a bigger structure and includes many
918 +information. But almost all lookup operation in aufs is the simplest
919 +case, ie. lookup only an entry directly connected to its parent. Digging
920 +down the directory hierarchy is unnecessary.
921 +
922 +VFS has a function lookup_one_len() for that use, but it is not usable
923 +for a branch filesystem which requires struct nameidata. So aufs
924 +implements a simple lookup wrapper function. When a branch filesystem
925 +allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
926 +a simplest nameidata and calls lookup_hash().
927 +Here aufs applies "a principle in NFSD", ie. if the filesystem supports
928 +NFS-export, then it has to support NULL as a nameidata parameter for
929 +->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
930 +aufs tests if ->s_export_op in the branch is NULL or not.
931 +
932 +When a branch is a remote filesystem, aufs basically trusts its
933 +->d_revalidate(), also aufs forces the hardest revalidate tests for
934 +them.
935 +For d_revalidate, aufs implements three levels of revalidate tests. See
936 +"Revalidate Dentry and UDBA" in detail.
937 +
938 +
939 +Loopback Mount
940 +----------------------------------------------------------------------
941 +Basically aufs supports any type of filesystem and block device for a
942 +branch (actually there are some exceptions). But it is prohibited to add
943 +a loopback mounted one whose backend file exists in a filesystem which is
944 +already added to aufs. The reason is to protect aufs from a recursive
945 +lookup. If it was allowed, the aufs lookup operation might re-enter a
946 +lookup for the loopback mounted branch in the same context, and will
947 +cause a deadlock.
948 +
949 +
950 +Revalidate Dentry and UDBA (User's Direct Branch Access)
951 +----------------------------------------------------------------------
952 +Generally VFS helpers re-validate a dentry as a part of lookup.
953 +0. digging down the directory hierarchy.
954 +1. lock the parent dir by its i_mutex.
955 +2. lookup the final (child) entry.
956 +3. revalidate it.
957 +4. call the actual operation (create, unlink, etc.)
958 +5. unlock the parent dir
959 +
960 +If the filesystem implements its ->d_revalidate() (step 3), then it is
961 +called. Actually aufs implements it and checks the dentry on a branch is
962 +still valid.
963 +But it is not enough. Because aufs has to release the lock for the
964 +parent dir on a branch at the end of ->lookup() (step 2) and
965 +->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
966 +held by VFS.
967 +If the file on a branch is changed directly, eg. bypassing aufs, after
968 +aufs released the lock, then the subsequent operation may cause
969 +something unpleasant result.
970 +
971 +This situation is a result of VFS architecture, ->lookup() and
972 +->d_revalidate() is separated. But I never say it is wrong. It is a good
973 +design from VFS's point of view. It is just not suitable for sub-VFS
974 +character in aufs.
975 +
976 +Aufs supports such case by three level of revalidation which is
977 +selectable by user.
978 +1. Simple Revalidate
979 +   Addition to the native flow in VFS's, confirm the child-parent
980 +   relationship on the branch just after locking the parent dir on the
981 +   branch in the "actual operation" (step 4). When this validation
982 +   fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
983 +   checks the validation of the dentry on branches.
984 +2. Monitor Changes Internally by Inotify/Fsnotify
985 +   Addition to above, in the "actual operation" (step 4) aufs re-lookup
986 +   the dentry on the branch, and returns EBUSY if it finds different
987 +   dentry.
988 +   Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
989 +   during it is in cache. When the event is notified, aufs registers a
990 +   function to kernel 'events' thread by schedule_work(). And the
991 +   function sets some special status to the cached aufs dentry and inode
992 +   private data. If they are not cached, then aufs has nothing to
993 +   do. When the same file is accessed through aufs (step 0-3) later,
994 +   aufs will detect the status and refresh all necessary data.
995 +   In this mode, aufs has to ignore the event which is fired by aufs
996 +   itself.
997 +3. No Extra Validation
998 +   This is the simplest test and doesn't add any additional revalidation
999 +   test, and skip therevalidatin in step 4. It is useful and improves
1000 +   aufs performance when system surely hide the aufs branches from user,
1001 +   by over-mounting something (or another method).
1002 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1003 --- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
1004 +++ linux/Documentation/filesystems/aufs/design/04branch.txt    2013-07-06 13:20:47.730197761 +0200
1005 @@ -0,0 +1,76 @@
1006 +
1007 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1008 +# 
1009 +# This program is free software; you can redistribute it and/or modify
1010 +# it under the terms of the GNU General Public License as published by
1011 +# the Free Software Foundation; either version 2 of the License, or
1012 +# (at your option) any later version.
1013 +# 
1014 +# This program is distributed in the hope that it will be useful,
1015 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1016 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1017 +# GNU General Public License for more details.
1018 +# 
1019 +# You should have received a copy of the GNU General Public License
1020 +# along with this program; if not, write to the Free Software
1021 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1022 +
1023 +Branch Manipulation
1024 +
1025 +Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1026 +and changing its permission/attribute, there are a lot of works to do.
1027 +
1028 +
1029 +Add a Branch
1030 +----------------------------------------------------------------------
1031 +o Confirm the adding dir exists outside of aufs, including loopback
1032 +  mount.
1033 +- and other various attributes...
1034 +o Initialize the xino file and whiteout bases if necessary.
1035 +  See struct.txt.
1036 +
1037 +o Check the owner/group/mode of the directory
1038 +  When the owner/group/mode of the adding directory differs from the
1039 +  existing branch, aufs issues a warning because it may impose a
1040 +  security risk.
1041 +  For example, when a upper writable branch has a world writable empty
1042 +  top directory, a malicious user can create any files on the writable
1043 +  branch directly, like copy-up and modify manually. If something like
1044 +  /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1045 +  writable branch, and the writable branch is world-writable, then a
1046 +  malicious guy may create /etc/passwd on the writable branch directly
1047 +  and the infected file will be valid in aufs.
1048 +  I am afraid it can be a security issue, but nothing to do except
1049 +  producing a warning.
1050 +
1051 +
1052 +Delete a Branch
1053 +----------------------------------------------------------------------
1054 +o Confirm the deleting branch is not busy
1055 +  To be general, there is one merit to adopt "remount" interface to
1056 +  manipulate branches. It is to discard caches. At deleting a branch,
1057 +  aufs checks the still cached (and connected) dentries and inodes. If
1058 +  there are any, then they are all in-use. An inode without its
1059 +  corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1060 +
1061 +  For the cached one, aufs checks whether the same named entry exists on
1062 +  other branches.
1063 +  If the cached one is a directory, because aufs provides a merged view
1064 +  to users, as long as one dir is left on any branch aufs can show the
1065 +  dir to users. In this case, the branch can be removed from aufs.
1066 +  Otherwise aufs rejects deleting the branch.
1067 +
1068 +  If any file on the deleting branch is opened by aufs, then aufs
1069 +  rejects deleting.
1070 +
1071 +
1072 +Modify the Permission of a Branch
1073 +----------------------------------------------------------------------
1074 +o Re-initialize or remove the xino file and whiteout bases if necessary.
1075 +  See struct.txt.
1076 +
1077 +o rw --> ro: Confirm the modifying branch is not busy
1078 +  Aufs rejects the request if any of these conditions are true.
1079 +  - a file on the branch is mmap-ed.
1080 +  - a regular file on the branch is opened for write and there is no
1081 +    same named entry on the upper branch.
1082 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1083 --- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt     1970-01-01 01:00:00.000000000 +0100
1084 +++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt        2013-07-06 13:20:47.730197761 +0200
1085 @@ -0,0 +1,65 @@
1086 +
1087 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1088 +# 
1089 +# This program is free software; you can redistribute it and/or modify
1090 +# it under the terms of the GNU General Public License as published by
1091 +# the Free Software Foundation; either version 2 of the License, or
1092 +# (at your option) any later version.
1093 +# 
1094 +# This program is distributed in the hope that it will be useful,
1095 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1096 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1097 +# GNU General Public License for more details.
1098 +# 
1099 +# You should have received a copy of the GNU General Public License
1100 +# along with this program; if not, write to the Free Software
1101 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1102 +
1103 +Policies to Select One among Multiple Writable Branches
1104 +----------------------------------------------------------------------
1105 +When the number of writable branch is more than one, aufs has to decide
1106 +the target branch for file creation or copy-up. By default, the highest
1107 +writable branch which has the parent (or ancestor) dir of the target
1108 +file is chosen (top-down-parent policy).
1109 +By user's request, aufs implements some other policies to select the
1110 +writable branch, for file creation two policies, round-robin and
1111 +most-free-space policies. For copy-up three policies, top-down-parent,
1112 +bottom-up-parent and bottom-up policies.
1113 +
1114 +As expected, the round-robin policy selects the branch in circular. When
1115 +you have two writable branches and creates 10 new files, 5 files will be
1116 +created for each branch. mkdir(2) systemcall is an exception. When you
1117 +create 10 new directories, all will be created on the same branch.
1118 +And the most-free-space policy selects the one which has most free
1119 +space among the writable branches. The amount of free space will be
1120 +checked by aufs internally, and users can specify its time interval.
1121 +
1122 +The policies for copy-up is more simple,
1123 +top-down-parent is equivalent to the same named on in create policy,
1124 +bottom-up-parent selects the writable branch where the parent dir
1125 +exists and the nearest upper one from the copyup-source,
1126 +bottom-up selects the nearest upper writable branch from the
1127 +copyup-source, regardless the existence of the parent dir.
1128 +
1129 +There are some rules or exceptions to apply these policies.
1130 +- If there is a readonly branch above the policy-selected branch and
1131 +  the parent dir is marked as opaque (a variation of whiteout), or the
1132 +  target (creating) file is whiteout-ed on the upper readonly branch,
1133 +  then the result of the policy is ignored and the target file will be
1134 +  created on the nearest upper writable branch than the readonly branch.
1135 +- If there is a writable branch above the policy-selected branch and
1136 +  the parent dir is marked as opaque or the target file is whiteouted
1137 +  on the branch, then the result of the policy is ignored and the target
1138 +  file will be created on the highest one among the upper writable
1139 +  branches who has diropq or whiteout. In case of whiteout, aufs removes
1140 +  it as usual.
1141 +- link(2) and rename(2) systemcalls are exceptions in every policy.
1142 +  They try selecting the branch where the source exists as possible
1143 +  since copyup a large file will take long time. If it can't be,
1144 +  ie. the branch where the source exists is readonly, then they will
1145 +  follow the copyup policy.
1146 +- There is an exception for rename(2) when the target exists.
1147 +  If the rename target exists, aufs compares the index of the branches
1148 +  where the source and the target exists and selects the higher
1149 +  one. If the selected branch is readonly, then aufs follows the
1150 +  copyup policy.
1151 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1152 --- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt   1970-01-01 01:00:00.000000000 +0100
1153 +++ linux/Documentation/filesystems/aufs/design/06mmap.txt      2013-07-06 13:20:47.730197761 +0200
1154 @@ -0,0 +1,47 @@
1155 +
1156 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1157 +# 
1158 +# This program is free software; you can redistribute it and/or modify
1159 +# it under the terms of the GNU General Public License as published by
1160 +# the Free Software Foundation; either version 2 of the License, or
1161 +# (at your option) any later version.
1162 +# 
1163 +# This program is distributed in the hope that it will be useful,
1164 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1165 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1166 +# GNU General Public License for more details.
1167 +# 
1168 +# You should have received a copy of the GNU General Public License
1169 +# along with this program; if not, write to the Free Software
1170 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1171 +
1172 +mmap(2) -- File Memory Mapping
1173 +----------------------------------------------------------------------
1174 +In aufs, the file-mapped pages are handled by a branch fs directly, no
1175 +interaction with aufs. It means aufs_mmap() calls the branch fs's
1176 +->mmap().
1177 +This approach is simple and good, but there is one problem.
1178 +Under /proc, several entries show the mmap-ped files by its path (with
1179 +device and inode number), and the printed path will be the path on the
1180 +branch fs's instead of virtual aufs's.
1181 +This is not a problem in most cases, but some utilities lsof(1) (and its
1182 +user) may expect the path on aufs.
1183 +
1184 +To address this issue, aufs adds a new member called vm_prfile in struct
1185 +vm_area_struct (and struct vm_region). The original vm_file points to
1186 +the file on the branch fs in order to handle everything correctly as
1187 +usual. The new vm_prfile points to a virtual file in aufs, and the
1188 +show-functions in procfs refers to vm_prfile if it is set.
1189 +Also we need to maintain several other places where touching vm_file
1190 +such like
1191 +- fork()/clone() copies vma and the reference count of vm_file is
1192 +  incremented.
1193 +- merging vma maintains the ref count too.
1194 +
1195 +This is not a good approach. It just faking the printed path. But it
1196 +leaves all behaviour around f_mapping unchanged. This is surely an
1197 +advantage.
1198 +Actually aufs had adopted another complicated approach which calls
1199 +generic_file_mmap() and handles struct vm_operations_struct. In this
1200 +approach, aufs met a hard problem and I could not solve it without
1201 +switching the approach.
1202 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1203 --- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
1204 +++ linux/Documentation/filesystems/aufs/design/07export.txt    2013-07-06 13:20:47.736864659 +0200
1205 @@ -0,0 +1,59 @@
1206 +
1207 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1208 +# 
1209 +# This program is free software; you can redistribute it and/or modify
1210 +# it under the terms of the GNU General Public License as published by
1211 +# the Free Software Foundation; either version 2 of the License, or
1212 +# (at your option) any later version.
1213 +# 
1214 +# This program is distributed in the hope that it will be useful,
1215 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1216 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1217 +# GNU General Public License for more details.
1218 +# 
1219 +# You should have received a copy of the GNU General Public License
1220 +# along with this program; if not, write to the Free Software
1221 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1222 +
1223 +Export Aufs via NFS
1224 +----------------------------------------------------------------------
1225 +Here is an approach.
1226 +- like xino/xib, add a new file 'xigen' which stores aufs inode
1227 +  generation.
1228 +- iget_locked(): initialize aufs inode generation for a new inode, and
1229 +  store it in xigen file.
1230 +- destroy_inode(): increment aufs inode generation and store it in xigen
1231 +  file. it is necessary even if it is not unlinked, because any data of
1232 +  inode may be changed by UDBA.
1233 +- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
1234 +  build file handle by
1235 +  + branch id (4 bytes)
1236 +  + superblock generation (4 bytes)
1237 +  + inode number (4 or 8 bytes)
1238 +  + parent dir inode number (4 or 8 bytes)
1239 +  + inode generation (4 bytes))
1240 +  + return value of exportfs_encode_fh() for the parent on a branch (4
1241 +    bytes)
1242 +  + file handle for a branch (by exportfs_encode_fh())
1243 +- fh_to_dentry():
1244 +  + find the index of a branch from its id in handle, and check it is
1245 +    still exist in aufs.
1246 +  + 1st level: get the inode number from handle and search it in cache.
1247 +  + 2nd level: if not found, get the parent inode number from handle and
1248 +    search it in cache. and then open the parent dir, find the matching
1249 +    inode number by vfs_readdir() and get its name, and call
1250 +    lookup_one_len() for the target dentry.
1251 +  + 3rd level: if the parent dir is not cached, call
1252 +    exportfs_decode_fh() for a branch and get the parent on a branch,
1253 +    build a pathname of it, convert it a pathname in aufs, call
1254 +    path_lookup(). now aufs gets a parent dir dentry, then handle it as
1255 +    the 2nd level.
1256 +  + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
1257 +    for every branch, but not itself. to get this, (currently) aufs
1258 +    searches in current->nsproxy->mnt_ns list. it may not be a good
1259 +    idea, but I didn't get other approach.
1260 +  + test the generation of the gotten inode.
1261 +- every inode operation: they may get EBUSY due to UDBA. in this case,
1262 +  convert it into ESTALE for NFSD.
1263 +- readdir(): call lockdep_on/off() because filldir in NFSD calls
1264 +  lookup_one_len(), vfs_getattr(), encode_fh() and others.
1265 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
1266 --- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt   1970-01-01 01:00:00.000000000 +0100
1267 +++ linux/Documentation/filesystems/aufs/design/08shwh.txt      2013-07-06 13:20:47.736864659 +0200
1268 @@ -0,0 +1,53 @@
1269 +
1270 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1271 +# 
1272 +# This program is free software; you can redistribute it and/or modify
1273 +# it under the terms of the GNU General Public License as published by
1274 +# the Free Software Foundation; either version 2 of the License, or
1275 +# (at your option) any later version.
1276 +# 
1277 +# This program is distributed in the hope that it will be useful,
1278 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1279 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1280 +# GNU General Public License for more details.
1281 +# 
1282 +# You should have received a copy of the GNU General Public License
1283 +# along with this program; if not, write to the Free Software
1284 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1285 +
1286 +Show Whiteout Mode (shwh)
1287 +----------------------------------------------------------------------
1288 +Generally aufs hides the name of whiteouts. But in some cases, to show
1289 +them is very useful for users. For instance, creating a new middle layer
1290 +(branch) by merging existing layers.
1291 +
1292 +(borrowing aufs1 HOW-TO from a user, Michael Towers)
1293 +When you have three branches,
1294 +- Bottom: 'system', squashfs (underlying base system), read-only
1295 +- Middle: 'mods', squashfs, read-only
1296 +- Top: 'overlay', ram (tmpfs), read-write
1297 +
1298 +The top layer is loaded at boot time and saved at shutdown, to preserve
1299 +the changes made to the system during the session.
1300 +When larger changes have been made, or smaller changes have accumulated,
1301 +the size of the saved top layer data grows. At this point, it would be
1302 +nice to be able to merge the two overlay branches ('mods' and 'overlay')
1303 +and rewrite the 'mods' squashfs, clearing the top layer and thus
1304 +restoring save and load speed.
1305 +
1306 +This merging is simplified by the use of another aufs mount, of just the
1307 +two overlay branches using the 'shwh' option.
1308 +# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
1309 +       aufs /livesys/merge_union
1310 +
1311 +A merged view of these two branches is then available at
1312 +/livesys/merge_union, and the new feature is that the whiteouts are
1313 +visible!
1314 +Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
1315 +writing to all branches. Also the default mode for all branches is 'ro'.
1316 +It is now possible to save the combined contents of the two overlay
1317 +branches to a new squashfs, e.g.:
1318 +# mksquashfs /livesys/merge_union /path/to/newmods.squash
1319 +
1320 +This new squashfs archive can be stored on the boot device and the
1321 +initramfs will use it to replace the old one at the next boot.
1322 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
1323 --- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt  1970-01-01 01:00:00.000000000 +0100
1324 +++ linux/Documentation/filesystems/aufs/design/10dynop.txt     2013-07-06 13:20:47.736864659 +0200
1325 @@ -0,0 +1,47 @@
1326 +
1327 +# Copyright (C) 2010-2013 Junjiro R. Okajima
1328 +#
1329 +# This program is free software; you can redistribute it and/or modify
1330 +# it under the terms of the GNU General Public License as published by
1331 +# the Free Software Foundation; either version 2 of the License, or
1332 +# (at your option) any later version.
1333 +#
1334 +# This program is distributed in the hope that it will be useful,
1335 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1336 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1337 +# GNU General Public License for more details.
1338 +#
1339 +# You should have received a copy of the GNU General Public License
1340 +# along with this program; if not, write to the Free Software
1341 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1342 +
1343 +Dynamically customizable FS operations
1344 +----------------------------------------------------------------------
1345 +Generally FS operations (struct inode_operations, struct
1346 +address_space_operations, struct file_operations, etc.) are defined as
1347 +"static const", but it never means that FS have only one set of
1348 +operation. Some FS have multiple sets of them. For instance, ext2 has
1349 +three sets, one for XIP, for NOBH, and for normal.
1350 +Since aufs overrides and redirects these operations, sometimes aufs has
1351 +to change its behaviour according to the branch FS type. More imporantly
1352 +VFS acts differently if a function (member in the struct) is set or
1353 +not. It means aufs should have several sets of operations and select one
1354 +among them according to the branch FS definition.
1355 +
1356 +In order to solve this problem and not to affect the behavour of VFS,
1357 +aufs defines these operations dynamically. For instance, aufs defines
1358 +aio_read function for struct file_operations, but it may not be set to
1359 +the file_operations. When the branch FS doesn't have it, aufs doesn't
1360 +set it to its file_operations while the function definition itself is
1361 +still alive. So the behaviour of io_submit(2) will not change, and it
1362 +will return an error when aio_read is not defined.
1363 +
1364 +The lifetime of these dynamically generated operation object is
1365 +maintained by aufs branch object. When the branch is removed from aufs,
1366 +the reference counter of the object is decremented. When it reaches
1367 +zero, the dynamically generated operation object will be freed.
1368 +
1369 +This approach is designed to support AIO (io_submit), Direcit I/O and
1370 +XIP mainly.
1371 +Currently this approach is applied to file_operations and
1372 +vm_operations_struct for regular files only.
1373 diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
1374 --- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt   1970-01-01 01:00:00.000000000 +0100
1375 +++ linux/Documentation/filesystems/aufs/design/99plan.txt      2013-07-06 13:20:47.736864659 +0200
1376 @@ -0,0 +1,96 @@
1377 +
1378 +# Copyright (C) 2005-2013 Junjiro R. Okajima
1379 +# 
1380 +# This program is free software; you can redistribute it and/or modify
1381 +# it under the terms of the GNU General Public License as published by
1382 +# the Free Software Foundation; either version 2 of the License, or
1383 +# (at your option) any later version.
1384 +# 
1385 +# This program is distributed in the hope that it will be useful,
1386 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1387 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1388 +# GNU General Public License for more details.
1389 +# 
1390 +# You should have received a copy of the GNU General Public License
1391 +# along with this program; if not, write to the Free Software
1392 +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1393 +
1394 +Plan
1395 +
1396 +Restoring some features which was implemented in aufs1.
1397 +They were dropped in aufs2 in order to make source files simpler and
1398 +easier to be reviewed.
1399 +
1400 +
1401 +Test Only the Highest One for the Directory Permission (dirperm1 option)
1402 +----------------------------------------------------------------------
1403 +Let's try case study.
1404 +- aufs has two branches, upper readwrite and lower readonly.
1405 +  /au = /rw + /ro
1406 +- "dirA" exists under /ro, but /rw. and its mode is 0700.
1407 +- user invoked "chmod a+rx /au/dirA"
1408 +- then "dirA" becomes world readable?
1409 +
1410 +In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1411 +or it may be a natively readonly filesystem. If aufs respects the lower
1412 +branch, it should not respond readdir request from other users. But user
1413 +allowed it by chmod. Should really aufs rejects showing the entries
1414 +under /ro/dirA?
1415 +
1416 +To be honest, I don't have a best solution for this case. So I
1417 +implemented 'dirperm1' and 'nodirperm1' option in aufs1, and leave it to
1418 +users.
1419 +When dirperm1 is specified, aufs checks only the highest one for the
1420 +directory permission, and shows the entries. Otherwise, as usual, checks
1421 +every dir existing on all branches and rejects the request.
1422 +
1423 +As a side effect, dirperm1 option improves the performance of aufs
1424 +because the number of permission check is reduced.
1425 +
1426 +
1427 +Being Another Aufs's Readonly Branch (robr)
1428 +----------------------------------------------------------------------
1429 +Aufs1 allows aufs to be another aufs's readonly branch.
1430 +This feature was developed by a user's request. But it may not be used
1431 +currecnly.
1432 +
1433 +
1434 +Copy-up on Open (coo=)
1435 +----------------------------------------------------------------------
1436 +By default the internal copy-up is executed when it is really necessary.
1437 +It is not done when a file is opened for writing, but when write(2) is
1438 +done. Users who have many (over 100) branches want to know and analyse
1439 +when and what file is copied-up. To insert a new upper branch which
1440 +contains such files only may improve the performance of aufs.
1441 +
1442 +Aufs1 implemented "coo=none | leaf | all" option.
1443 +
1444 +
1445 +Refresh the Opened File (refrof)
1446 +----------------------------------------------------------------------
1447 +This option is implemented in aufs1 but incomplete.
1448 +
1449 +When user reads from a file, he expects to get its latest filedata
1450 +generally. If the file is removed and a new same named file is created,
1451 +the content he gets is unchanged, ie. the unlinked filedata.
1452 +
1453 +Let's try case study again.
1454 +- aufs has two branches.
1455 +  /au = /rw + /ro
1456 +- "fileA" exists under /ro, but /rw.
1457 +- user opened "/au/fileA".
1458 +- he or someone else inserts a branch (/new) between /rw and /ro.
1459 +  /au = /rw + /new + /ro
1460 +- the new branch has "fileA".
1461 +- user reads from the opened "fileA"
1462 +- which filedata should aufs return, from /ro or /new?
1463 +
1464 +Some people says it has to be "from /ro" and it is a semantics of Unix.
1465 +The others say it should be "from /new" because the file is not removed
1466 +and it is equivalent to the case of someone else modifies the file.
1467 +
1468 +Here again I don't have a best and final answer. I got an idea to
1469 +implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
1470 +Opened File) is specified (by default), aufs returns the filedata from
1471 +/new.
1472 +Otherwise from /new.
1473 diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
1474 --- /usr/share/empty/Documentation/filesystems/aufs/README      1970-01-01 01:00:00.000000000 +0100
1475 +++ linux/Documentation/filesystems/aufs/README 2013-07-30 22:42:46.229279157 +0200
1476 @@ -0,0 +1,346 @@
1477 +
1478 +Aufs3 -- advanced multi layered unification filesystem version 3.x
1479 +http://aufs.sf.net
1480 +Junjiro R. Okajima
1481 +
1482 +
1483 +0. Introduction
1484 +----------------------------------------
1485 +In the early days, aufs was entirely re-designed and re-implemented
1486 +Unionfs Version 1.x series. After many original ideas, approaches,
1487 +improvements and implementations, it becomes totally different from
1488 +Unionfs while keeping the basic features.
1489 +Recently, Unionfs Version 2.x series begin taking some of the same
1490 +approaches to aufs1's.
1491 +Unionfs is being developed by Professor Erez Zadok at Stony Brook
1492 +University and his team.
1493 +
1494 +Aufs3 supports linux-3.0 and later.
1495 +If you want older kernel version support, try aufs2-2.6.git or
1496 +aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
1497 +
1498 +Note: it becomes clear that "Aufs was rejected. Let's give it up."
1499 +According to Christoph Hellwig, linux rejects all union-type filesystems
1500 +but UnionMount.
1501 +<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
1502 +
1503 +
1504 +1. Features
1505 +----------------------------------------
1506 +- unite several directories into a single virtual filesystem. The member
1507 +  directory is called as a branch.
1508 +- you can specify the permission flags to the branch, which are 'readonly',
1509 +  'readwrite' and 'whiteout-able.'
1510 +- by upper writable branch, internal copyup and whiteout, files/dirs on
1511 +  readonly branch are modifiable logically.
1512 +- dynamic branch manipulation, add, del.
1513 +- etc...
1514 +
1515 +Also there are many enhancements in aufs1, such as:
1516 +- readdir(3) in userspace.
1517 +- keep inode number by external inode number table
1518 +- keep the timestamps of file/dir in internal copyup operation
1519 +- seekable directory, supporting NFS readdir.
1520 +- whiteout is hardlinked in order to reduce the consumption of inodes
1521 +  on branch
1522 +- do not copyup, nor create a whiteout when it is unnecessary
1523 +- revert a single systemcall when an error occurs in aufs
1524 +- remount interface instead of ioctl
1525 +- maintain /etc/mtab by an external command, /sbin/mount.aufs.
1526 +- loopback mounted filesystem as a branch
1527 +- kernel thread for removing the dir who has a plenty of whiteouts
1528 +- support copyup sparse file (a file which has a 'hole' in it)
1529 +- default permission flags for branches
1530 +- selectable permission flags for ro branch, whether whiteout can
1531 +  exist or not
1532 +- export via NFS.
1533 +- support <sysfs>/fs/aufs and <debugfs>/aufs.
1534 +- support multiple writable branches, some policies to select one
1535 +  among multiple writable branches.
1536 +- a new semantics for link(2) and rename(2) to support multiple
1537 +  writable branches.
1538 +- no glibc changes are required.
1539 +- pseudo hardlink (hardlink over branches)
1540 +- allow a direct access manually to a file on branch, e.g. bypassing aufs.
1541 +  including NFS or remote filesystem branch.
1542 +- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
1543 +- and more...
1544 +
1545 +Currently these features are dropped temporary from aufs3.
1546 +See design/08plan.txt in detail.
1547 +- test only the highest one for the directory permission (dirperm1)
1548 +- copyup on open (coo=)
1549 +- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
1550 +  (robr)
1551 +- statistics of aufs thread (/sys/fs/aufs/stat)
1552 +- delegation mode (dlgt)
1553 +  a delegation of the internal branch access to support task I/O
1554 +  accounting, which also supports Linux Security Modules (LSM) mainly
1555 +  for Suse AppArmor.
1556 +- intent.open/create (file open in a single lookup)
1557 +
1558 +Features or just an idea in the future (see also design/*.txt),
1559 +- reorder the branch index without del/re-add.
1560 +- permanent xino files for NFSD
1561 +- an option for refreshing the opened files after add/del branches
1562 +- 'move' policy for copy-up between two writable branches, after
1563 +  checking free space.
1564 +- light version, without branch manipulation. (unnecessary?)
1565 +- copyup in userspace
1566 +- inotify in userspace
1567 +- readv/writev
1568 +- xattr, acl
1569 +
1570 +
1571 +2. Download
1572 +----------------------------------------
1573 +There were three GIT trees for aufs3, aufs3-linux.git,
1574 +aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
1575 +"aufs-util.git."
1576 +While the aufs-util is always necessary, you need either of aufs3-linux
1577 +or aufs3-standalone.
1578 +
1579 +The aufs3-linux tree includes the whole linux mainline GIT tree,
1580 +git://git.kernel.org/.../torvalds/linux.git.
1581 +And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
1582 +build aufs3 as an external kernel module.
1583 +
1584 +On the other hand, the aufs3-standalone tree has only aufs source files
1585 +and necessary patches, and you can select CONFIG_AUFS_FS=m.
1586 +
1587 +You will find GIT branches whose name is in form of "aufs3.x" where "x"
1588 +represents the linux kernel version, "linux-3.x". For instance,
1589 +"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
1590 +"aufs3.x-rcN" branch.
1591 +
1592 +o aufs3-linux tree
1593 +$ git clone --reference /your/linux/git/tree \
1594 +       git://git.code.sf.net/p/aufs/aufs3-linux aufs-aufs3-linux \
1595 +       aufs3-linux.git
1596 +- if you don't have linux GIT tree, then remove "--reference ..."
1597 +$ cd aufs3-linux.git
1598 +$ git checkout origin/aufs3.0
1599 +
1600 +o aufs3-standalone tree
1601 +$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
1602 +       aufs3-standalone.git
1603 +$ cd aufs3-standalone.git
1604 +$ git checkout origin/aufs3.0
1605 +
1606 +o aufs-util tree
1607 +$ git clone git://git.code.sf.net/p/aufs/aufs-util \
1608 +       aufs-util.git
1609 +$ cd aufs-util.git
1610 +$ git checkout origin/aufs3.0
1611 +
1612 +Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
1613 +The minor version number, 'x' in '3.x', of aufs may not always
1614 +follow the minor version number of the kernel.
1615 +Because changes in the kernel that cause the use of a new
1616 +minor version number do not always require changes to aufs-util.
1617 +
1618 +Since aufs-util has its own minor version number, you may not be
1619 +able to find a GIT branch in aufs-util for your kernel's
1620 +exact minor version number.
1621 +In this case, you should git-checkout the branch for the
1622 +nearest lower number.
1623 +
1624 +For (an unreleased) example:
1625 +If you are using "linux-3.10" and the "aufs3.10" branch
1626 +does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
1627 +or something numerically smaller is the branch for your kernel.
1628 +
1629 +Also you can view all branches by
1630 +       $ git branch -a
1631 +
1632 +
1633 +3. Configuration and Compilation
1634 +----------------------------------------
1635 +Make sure you have git-checkout'ed the correct branch.
1636 +
1637 +For aufs3-linux tree,
1638 +- enable CONFIG_AUFS_FS.
1639 +- set other aufs configurations if necessary.
1640 +
1641 +For aufs3-standalone tree,
1642 +There are several ways to build.
1643 +
1644 +1.
1645 +- apply ./aufs3-kbuild.patch to your kernel source files.
1646 +- apply ./aufs3-base.patch too.
1647 +- apply ./aufs3-proc_map.patch too, if you want to make /proc/PID/maps (and
1648 +  others including lsof(1)) show the file path on aufs instead of the
1649 +  path on the branch fs.
1650 +- apply ./aufs3-standalone.patch too, if you have a plan to set
1651 +  CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
1652 +- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
1653 +  kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
1654 +- enable CONFIG_AUFS_FS, you can select either
1655 +  =m or =y.
1656 +- and build your kernel as usual.
1657 +- install the built kernel.
1658 +  Note: Since linux-3.9, every filesystem module requires an alias
1659 +  "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
1660 +  modules.aliases file if you set CONFIG_AUFS_FS=m.
1661 +- install the header files too by "make headers_install" to the
1662 +  directory where you specify. By default, it is $PWD/usr.
1663 +  "make help" shows a brief note for headers_install.
1664 +- and reboot your system.
1665 +
1666 +2.
1667 +- module only (CONFIG_AUFS_FS=m).
1668 +- apply ./aufs3-base.patch to your kernel source files.
1669 +- apply ./aufs3-proc_map.patch too to your kernel source files,
1670 +  if you want to make /proc/PID/maps (and others including lsof(1)) show
1671 +  the file path on aufs instead of the path on the branch fs.
1672 +- apply ./aufs3-standalone.patch too.
1673 +- build your kernel, don't forget "make headers_install", and reboot.
1674 +- edit ./config.mk and set other aufs configurations if necessary.
1675 +  Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
1676 +  every aufs configurations.
1677 +- build the module by simple "make".
1678 +  Note: Since linux-3.9, every filesystem module requires an alias
1679 +  "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
1680 +  modules.aliases file.
1681 +- you can specify ${KDIR} make variable which points to your kernel
1682 +  source tree.
1683 +- install the files
1684 +  + run "make install" to install the aufs module, or copy the built
1685 +    $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
1686 +  + run "make install_headers" (instead of headers_install) to install
1687 +    the modified aufs header file (you can specify DESTDIR which is
1688 +    available in aufs standalone version's Makefile only), or copy
1689 +    $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
1690 +    you like manually. By default, the target directory is $PWD/usr.
1691 +- no need to apply aufs3-kbuild.patch, nor copying source files to your
1692 +  kernel source tree.
1693 +
1694 +Note: The header file aufs_type.h is necessary to build aufs-util
1695 +      as well as "make headers_install" in the kernel source tree.
1696 +      headers_install is subject to be forgotten, but it is essentially
1697 +      necessary, not only for building aufs-util.
1698 +      You may not meet problems without headers_install in some older
1699 +      version though.
1700 +
1701 +And then,
1702 +- read README in aufs-util, build and install it
1703 +- note that your distribution may contain an obsoleted version of
1704 +  aufs_type.h in /usr/include/linux or something. When you build aufs
1705 +  utilities, make sure that your compiler refers the correct aufs header
1706 +  file which is built by "make headers_install."
1707 +- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
1708 +  then run "make install_ulib" too. And refer to the aufs manual in
1709 +  detail.
1710 +
1711 +
1712 +4. Usage
1713 +----------------------------------------
1714 +At first, make sure aufs-util are installed, and please read the aufs
1715 +manual, aufs.5 in aufs-util.git tree.
1716 +$ man -l aufs.5
1717 +
1718 +And then,
1719 +$ mkdir /tmp/rw /tmp/aufs
1720 +# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
1721 +
1722 +Here is another example. The result is equivalent.
1723 +# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
1724 +  Or
1725 +# mount -t aufs -o br:/tmp/rw none /tmp/aufs
1726 +# mount -o remount,append:${HOME} /tmp/aufs
1727 +
1728 +Then, you can see whole tree of your home dir through /tmp/aufs. If
1729 +you modify a file under /tmp/aufs, the one on your home directory is
1730 +not affected, instead the same named file will be newly created under
1731 +/tmp/rw. And all of your modification to a file will be applied to
1732 +the one under /tmp/rw. This is called the file based Copy on Write
1733 +(COW) method.
1734 +Aufs mount options are described in aufs.5.
1735 +If you run chroot or something and make your aufs as a root directory,
1736 +then you need to customize the shutdown script. See the aufs manual in
1737 +detail.
1738 +
1739 +Additionally, there are some sample usages of aufs which are a
1740 +diskless system with network booting, and LiveCD over NFS.
1741 +See sample dir in CVS tree on SourceForge.
1742 +
1743 +
1744 +5. Contact
1745 +----------------------------------------
1746 +When you have any problems or strange behaviour in aufs, please let me
1747 +know with:
1748 +- /proc/mounts (instead of the output of mount(8))
1749 +- /sys/module/aufs/*
1750 +- /sys/fs/aufs/* (if you have them)
1751 +- /debug/aufs/* (if you have them)
1752 +- linux kernel version
1753 +  if your kernel is not plain, for example modified by distributor,
1754 +  the url where i can download its source is necessary too.
1755 +- aufs version which was printed at loading the module or booting the
1756 +  system, instead of the date you downloaded.
1757 +- configuration (define/undefine CONFIG_AUFS_xxx)
1758 +- kernel configuration or /proc/config.gz (if you have it)
1759 +- behaviour which you think to be incorrect
1760 +- actual operation, reproducible one is better
1761 +- mailto: aufs-users at lists.sourceforge.net
1762 +
1763 +Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
1764 +and Feature Requests) on SourceForge. Please join and write to
1765 +aufs-users ML.
1766 +
1767 +
1768 +6. Acknowledgements
1769 +----------------------------------------
1770 +Thanks to everyone who have tried and are using aufs, whoever
1771 +have reported a bug or any feedback.
1772 +
1773 +Especially donators:
1774 +Tomas Matejicek(slax.org) made a donation (much more than once).
1775 +       Since Apr 2010, Tomas M (the author of Slax and Linux Live
1776 +       scripts) is making "doubling" donations.
1777 +       Unfortunately I cannot list all of the donators, but I really
1778 +       appreciate.
1779 +       It ends Aug 2010, but the ordinary donation URL is still available.
1780 +       <http://sourceforge.net/donate/index.php?group_id=167503>
1781 +Dai Itasaka made a donation (2007/8).
1782 +Chuck Smith made a donation (2008/4, 10 and 12).
1783 +Henk Schoneveld made a donation (2008/9).
1784 +Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
1785 +Francois Dupoux made a donation (2008/11).
1786 +Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
1787 +       aufs2 GIT tree (2009/2).
1788 +William Grant made a donation (2009/3).
1789 +Patrick Lane made a donation (2009/4).
1790 +The Mail Archive (mail-archive.com) made donations (2009/5).
1791 +Nippy Networks (Ed Wildgoose) made a donation (2009/7).
1792 +New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
1793 +Pavel Pronskiy made a donation (2011/2).
1794 +Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
1795 +       Networks (Ed Wildgoose) made a donation for hardware (2011/3).
1796 +Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
1797 +11).
1798 +Sam Liddicott made a donation (2011/9).
1799 +Era Scarecrow made a donation (2013/4).
1800 +Bor Ratajc made a donation (2013/4).
1801 +Alessandro Gorreta made a donation (2013/4).
1802 +POIRETTE Marc made a donation (2013/4).
1803 +Alessandro Gorreta made a donation (2013/4).
1804 +lauri kasvandik made a donation (2013/5).
1805 +pemasu from Finland made a donation (2013/7).
1806 +
1807 +Thank you very much.
1808 +Donations are always, including future donations, very important and
1809 +helpful for me to keep on developing aufs.
1810 +
1811 +
1812 +7.
1813 +----------------------------------------
1814 +If you are an experienced user, no explanation is needed. Aufs is
1815 +just a linux filesystem.
1816 +
1817 +
1818 +Enjoy!
1819 +
1820 +# Local variables: ;
1821 +# mode: text;
1822 +# End: ;
1823 diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
1824 --- /usr/share/empty/fs/aufs/aufs.h     1970-01-01 01:00:00.000000000 +0100
1825 +++ linux/fs/aufs/aufs.h        2013-07-06 13:20:47.736864659 +0200
1826 @@ -0,0 +1,60 @@
1827 +/*
1828 + * Copyright (C) 2005-2013 Junjiro R. Okajima
1829 + *
1830 + * This program, aufs is free software; you can redistribute it and/or modify
1831 + * it under the terms of the GNU General Public License as published by
1832 + * the Free Software Foundation; either version 2 of the License, or
1833 + * (at your option) any later version.
1834 + *
1835 + * This program is distributed in the hope that it will be useful,
1836 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1837 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1838 + * GNU General Public License for more details.
1839 + *
1840 + * You should have received a copy of the GNU General Public License
1841 + * along with this program; if not, write to the Free Software
1842 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1843 + */
1844 +
1845 +/*
1846 + * all header files
1847 + */
1848 +
1849 +#ifndef __AUFS_H__
1850 +#define __AUFS_H__
1851 +
1852 +#ifdef __KERNEL__
1853 +
1854 +#define AuStub(type, name, body, ...) \
1855 +       static inline type name(__VA_ARGS__) { body; }
1856 +
1857 +#define AuStubVoid(name, ...) \
1858 +       AuStub(void, name, , __VA_ARGS__)
1859 +#define AuStubInt0(name, ...) \
1860 +       AuStub(int, name, return 0, __VA_ARGS__)
1861 +
1862 +#include "debug.h"
1863 +
1864 +#include "branch.h"
1865 +#include "cpup.h"
1866 +#include "dcsub.h"
1867 +#include "dbgaufs.h"
1868 +#include "dentry.h"
1869 +#include "dir.h"
1870 +#include "dynop.h"
1871 +#include "file.h"
1872 +#include "fstype.h"
1873 +#include "inode.h"
1874 +#include "loop.h"
1875 +#include "module.h"
1876 +#include "opts.h"
1877 +#include "rwsem.h"
1878 +#include "spl.h"
1879 +#include "super.h"
1880 +#include "sysaufs.h"
1881 +#include "vfsub.h"
1882 +#include "whout.h"
1883 +#include "wkq.h"
1884 +
1885 +#endif /* __KERNEL__ */
1886 +#endif /* __AUFS_H__ */
1887 diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
1888 --- /usr/share/empty/fs/aufs/branch.c   1970-01-01 01:00:00.000000000 +0100
1889 +++ linux/fs/aufs/branch.c      2013-07-30 22:42:55.839613269 +0200
1890 @@ -0,0 +1,1213 @@
1891 +/*
1892 + * Copyright (C) 2005-2013 Junjiro R. Okajima
1893 + *
1894 + * This program, aufs is free software; you can redistribute it and/or modify
1895 + * it under the terms of the GNU General Public License as published by
1896 + * the Free Software Foundation; either version 2 of the License, or
1897 + * (at your option) any later version.
1898 + *
1899 + * This program is distributed in the hope that it will be useful,
1900 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1901 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1902 + * GNU General Public License for more details.
1903 + *
1904 + * You should have received a copy of the GNU General Public License
1905 + * along with this program; if not, write to the Free Software
1906 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1907 + */
1908 +
1909 +/*
1910 + * branch management
1911 + */
1912 +
1913 +#include <linux/compat.h>
1914 +#include <linux/statfs.h>
1915 +#include "aufs.h"
1916 +
1917 +/*
1918 + * free a single branch
1919 + */
1920 +
1921 +/* prohibit rmdir to the root of the branch */
1922 +/* todo: another new flag? */
1923 +static void au_br_dflags_force(struct au_branch *br)
1924 +{
1925 +       struct dentry *h_dentry;
1926 +
1927 +       h_dentry = au_br_dentry(br);
1928 +       spin_lock(&h_dentry->d_lock);
1929 +       br->br_dflags = h_dentry->d_flags & DCACHE_MOUNTED;
1930 +       h_dentry->d_flags |= DCACHE_MOUNTED;
1931 +       spin_unlock(&h_dentry->d_lock);
1932 +}
1933 +
1934 +/* restore its d_flags */
1935 +static void au_br_dflags_restore(struct au_branch *br)
1936 +{
1937 +       struct dentry *h_dentry;
1938 +
1939 +       if (br->br_dflags)
1940 +               return;
1941 +
1942 +       h_dentry = au_br_dentry(br);
1943 +       spin_lock(&h_dentry->d_lock);
1944 +       h_dentry->d_flags &= ~DCACHE_MOUNTED;
1945 +       spin_unlock(&h_dentry->d_lock);
1946 +}
1947 +
1948 +static void au_br_do_free(struct au_branch *br)
1949 +{
1950 +       int i;
1951 +       struct au_wbr *wbr;
1952 +       struct au_dykey **key;
1953 +
1954 +       au_hnotify_fin_br(br);
1955 +
1956 +       if (br->br_xino.xi_file)
1957 +               fput(br->br_xino.xi_file);
1958 +       mutex_destroy(&br->br_xino.xi_nondir_mtx);
1959 +
1960 +       AuDebugOn(atomic_read(&br->br_count));
1961 +
1962 +       wbr = br->br_wbr;
1963 +       if (wbr) {
1964 +               for (i = 0; i < AuBrWh_Last; i++)
1965 +                       dput(wbr->wbr_wh[i]);
1966 +               AuDebugOn(atomic_read(&wbr->wbr_wh_running));
1967 +               AuRwDestroy(&wbr->wbr_wh_rwsem);
1968 +       }
1969 +
1970 +       key = br->br_dykey;
1971 +       for (i = 0; i < AuBrDynOp; i++, key++)
1972 +               if (*key)
1973 +                       au_dy_put(*key);
1974 +               else
1975 +                       break;
1976 +
1977 +       au_br_dflags_restore(br);
1978 +
1979 +       /* recursive lock, s_umount of branch's */
1980 +       lockdep_off();
1981 +       path_put(&br->br_path);
1982 +       lockdep_on();
1983 +       kfree(wbr);
1984 +       kfree(br);
1985 +}
1986 +
1987 +/*
1988 + * frees all branches
1989 + */
1990 +void au_br_free(struct au_sbinfo *sbinfo)
1991 +{
1992 +       aufs_bindex_t bmax;
1993 +       struct au_branch **br;
1994 +
1995 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
1996 +
1997 +       bmax = sbinfo->si_bend + 1;
1998 +       br = sbinfo->si_branch;
1999 +       while (bmax--)
2000 +               au_br_do_free(*br++);
2001 +}
2002 +
2003 +/*
2004 + * find the index of a branch which is specified by @br_id.
2005 + */
2006 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2007 +{
2008 +       aufs_bindex_t bindex, bend;
2009 +
2010 +       bend = au_sbend(sb);
2011 +       for (bindex = 0; bindex <= bend; bindex++)
2012 +               if (au_sbr_id(sb, bindex) == br_id)
2013 +                       return bindex;
2014 +       return -1;
2015 +}
2016 +
2017 +/* ---------------------------------------------------------------------- */
2018 +
2019 +/*
2020 + * add a branch
2021 + */
2022 +
2023 +static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2024 +                       struct dentry *h_root)
2025 +{
2026 +       if (unlikely(h_adding == h_root
2027 +                    || au_test_loopback_overlap(sb, h_adding)))
2028 +               return 1;
2029 +       if (h_adding->d_sb != h_root->d_sb)
2030 +               return 0;
2031 +       return au_test_subdir(h_adding, h_root)
2032 +               || au_test_subdir(h_root, h_adding);
2033 +}
2034 +
2035 +/*
2036 + * returns a newly allocated branch. @new_nbranch is a number of branches
2037 + * after adding a branch.
2038 + */
2039 +static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2040 +                                    int perm)
2041 +{
2042 +       struct au_branch *add_branch;
2043 +       struct dentry *root;
2044 +       int err;
2045 +
2046 +       err = -ENOMEM;
2047 +       root = sb->s_root;
2048 +       add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2049 +       if (unlikely(!add_branch))
2050 +               goto out;
2051 +
2052 +       err = au_hnotify_init_br(add_branch, perm);
2053 +       if (unlikely(err))
2054 +               goto out_br;
2055 +
2056 +       add_branch->br_wbr = NULL;
2057 +       if (au_br_writable(perm)) {
2058 +               /* may be freed separately at changing the branch permission */
2059 +               add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2060 +                                            GFP_NOFS);
2061 +               if (unlikely(!add_branch->br_wbr))
2062 +                       goto out_hnotify;
2063 +       }
2064 +
2065 +       err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2066 +       if (!err)
2067 +               err = au_di_realloc(au_di(root), new_nbranch);
2068 +       if (!err)
2069 +               err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
2070 +       if (!err)
2071 +               return add_branch; /* success */
2072 +
2073 +       kfree(add_branch->br_wbr);
2074 +
2075 +out_hnotify:
2076 +       au_hnotify_fin_br(add_branch);
2077 +out_br:
2078 +       kfree(add_branch);
2079 +out:
2080 +       return ERR_PTR(err);
2081 +}
2082 +
2083 +/*
2084 + * test if the branch permission is legal or not.
2085 + */
2086 +static int test_br(struct inode *inode, int brperm, char *path)
2087 +{
2088 +       int err;
2089 +
2090 +       err = (au_br_writable(brperm) && IS_RDONLY(inode));
2091 +       if (!err)
2092 +               goto out;
2093 +
2094 +       err = -EINVAL;
2095 +       pr_err("write permission for readonly mount or inode, %s\n", path);
2096 +
2097 +out:
2098 +       return err;
2099 +}
2100 +
2101 +/*
2102 + * returns:
2103 + * 0: success, the caller will add it
2104 + * plus: success, it is already unified, the caller should ignore it
2105 + * minus: error
2106 + */
2107 +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2108 +{
2109 +       int err;
2110 +       aufs_bindex_t bend, bindex;
2111 +       struct dentry *root;
2112 +       struct inode *inode, *h_inode;
2113 +
2114 +       root = sb->s_root;
2115 +       bend = au_sbend(sb);
2116 +       if (unlikely(bend >= 0
2117 +                    && au_find_dbindex(root, add->path.dentry) >= 0)) {
2118 +               err = 1;
2119 +               if (!remount) {
2120 +                       err = -EINVAL;
2121 +                       pr_err("%s duplicated\n", add->pathname);
2122 +               }
2123 +               goto out;
2124 +       }
2125 +
2126 +       err = -ENOSPC; /* -E2BIG; */
2127 +       if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2128 +                    || AUFS_BRANCH_MAX - 1 <= bend)) {
2129 +               pr_err("number of branches exceeded %s\n", add->pathname);
2130 +               goto out;
2131 +       }
2132 +
2133 +       err = -EDOM;
2134 +       if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
2135 +               pr_err("bad index %d\n", add->bindex);
2136 +               goto out;
2137 +       }
2138 +
2139 +       inode = add->path.dentry->d_inode;
2140 +       err = -ENOENT;
2141 +       if (unlikely(!inode->i_nlink)) {
2142 +               pr_err("no existence %s\n", add->pathname);
2143 +               goto out;
2144 +       }
2145 +
2146 +       err = -EINVAL;
2147 +       if (unlikely(inode->i_sb == sb)) {
2148 +               pr_err("%s must be outside\n", add->pathname);
2149 +               goto out;
2150 +       }
2151 +
2152 +       if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
2153 +               pr_err("unsupported filesystem, %s (%s)\n",
2154 +                      add->pathname, au_sbtype(inode->i_sb));
2155 +               goto out;
2156 +       }
2157 +
2158 +       err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2159 +       if (unlikely(err))
2160 +               goto out;
2161 +
2162 +       if (bend < 0)
2163 +               return 0; /* success */
2164 +
2165 +       err = -EINVAL;
2166 +       for (bindex = 0; bindex <= bend; bindex++)
2167 +               if (unlikely(test_overlap(sb, add->path.dentry,
2168 +                                         au_h_dptr(root, bindex)))) {
2169 +                       pr_err("%s is overlapped\n", add->pathname);
2170 +                       goto out;
2171 +               }
2172 +
2173 +       err = 0;
2174 +       if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2175 +               h_inode = au_h_dptr(root, 0)->d_inode;
2176 +               if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
2177 +                   || !uid_eq(h_inode->i_uid, inode->i_uid)
2178 +                   || !gid_eq(h_inode->i_gid, inode->i_gid))
2179 +                       pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2180 +                               add->pathname,
2181 +                               i_uid_read(inode), i_gid_read(inode),
2182 +                               (inode->i_mode & S_IALLUGO),
2183 +                               i_uid_read(h_inode), i_gid_read(h_inode),
2184 +                               (h_inode->i_mode & S_IALLUGO));
2185 +       }
2186 +
2187 +out:
2188 +       return err;
2189 +}
2190 +
2191 +/*
2192 + * initialize or clean the whiteouts for an adding branch
2193 + */
2194 +static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
2195 +                        int new_perm)
2196 +{
2197 +       int err, old_perm;
2198 +       aufs_bindex_t bindex;
2199 +       struct mutex *h_mtx;
2200 +       struct au_wbr *wbr;
2201 +       struct au_hinode *hdir;
2202 +
2203 +       err = vfsub_mnt_want_write(au_br_mnt(br));
2204 +       if (unlikely(err))
2205 +               goto out;
2206 +
2207 +       wbr = br->br_wbr;
2208 +       old_perm = br->br_perm;
2209 +       br->br_perm = new_perm;
2210 +       hdir = NULL;
2211 +       h_mtx = NULL;
2212 +       bindex = au_br_index(sb, br->br_id);
2213 +       if (0 <= bindex) {
2214 +               hdir = au_hi(sb->s_root->d_inode, bindex);
2215 +               au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
2216 +       } else {
2217 +               h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
2218 +               mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2219 +       }
2220 +       if (!wbr)
2221 +               err = au_wh_init(br, sb);
2222 +       else {
2223 +               wbr_wh_write_lock(wbr);
2224 +               err = au_wh_init(br, sb);
2225 +               wbr_wh_write_unlock(wbr);
2226 +       }
2227 +       if (hdir)
2228 +               au_hn_imtx_unlock(hdir);
2229 +       else
2230 +               mutex_unlock(h_mtx);
2231 +       vfsub_mnt_drop_write(au_br_mnt(br));
2232 +       br->br_perm = old_perm;
2233 +
2234 +       if (!err && wbr && !au_br_writable(new_perm)) {
2235 +               kfree(wbr);
2236 +               br->br_wbr = NULL;
2237 +       }
2238 +
2239 +out:
2240 +       return err;
2241 +}
2242 +
2243 +static int au_wbr_init(struct au_branch *br, struct super_block *sb,
2244 +                      int perm)
2245 +{
2246 +       int err;
2247 +       struct kstatfs kst;
2248 +       struct au_wbr *wbr;
2249 +
2250 +       wbr = br->br_wbr;
2251 +       au_rw_init(&wbr->wbr_wh_rwsem);
2252 +       memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2253 +       atomic_set(&wbr->wbr_wh_running, 0);
2254 +       wbr->wbr_bytes = 0;
2255 +
2256 +       /*
2257 +        * a limit for rmdir/rename a dir
2258 +        * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h
2259 +        */
2260 +       err = vfs_statfs(&br->br_path, &kst);
2261 +       if (unlikely(err))
2262 +               goto out;
2263 +       err = -EINVAL;
2264 +       if (kst.f_namelen >= NAME_MAX)
2265 +               err = au_br_init_wh(sb, br, perm);
2266 +       else
2267 +               pr_err("%.*s(%s), unsupported namelen %ld\n",
2268 +                      AuDLNPair(au_br_dentry(br)),
2269 +                      au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
2270 +
2271 +out:
2272 +       return err;
2273 +}
2274 +
2275 +/* intialize a new branch */
2276 +static int au_br_init(struct au_branch *br, struct super_block *sb,
2277 +                     struct au_opt_add *add)
2278 +{
2279 +       int err;
2280 +
2281 +       err = 0;
2282 +       memset(&br->br_xino, 0, sizeof(br->br_xino));
2283 +       mutex_init(&br->br_xino.xi_nondir_mtx);
2284 +       br->br_perm = add->perm;
2285 +       BUILD_BUG_ON(sizeof(br->br_dflags)
2286 +                    != sizeof(br->br_path.dentry->d_flags));
2287 +       br->br_dflags = DCACHE_MOUNTED;
2288 +       br->br_path = add->path; /* set first, path_get() later */
2289 +       spin_lock_init(&br->br_dykey_lock);
2290 +       memset(br->br_dykey, 0, sizeof(br->br_dykey));
2291 +       atomic_set(&br->br_count, 0);
2292 +       br->br_xino_upper = AUFS_XINO_TRUNC_INIT;
2293 +       atomic_set(&br->br_xino_running, 0);
2294 +       br->br_id = au_new_br_id(sb);
2295 +       AuDebugOn(br->br_id < 0);
2296 +
2297 +       if (au_br_writable(add->perm)) {
2298 +               err = au_wbr_init(br, sb, add->perm);
2299 +               if (unlikely(err))
2300 +                       goto out_err;
2301 +       }
2302 +
2303 +       if (au_opt_test(au_mntflags(sb), XINO)) {
2304 +               err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
2305 +                                au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
2306 +               if (unlikely(err)) {
2307 +                       AuDebugOn(br->br_xino.xi_file);
2308 +                       goto out_err;
2309 +               }
2310 +       }
2311 +
2312 +       sysaufs_br_init(br);
2313 +       path_get(&br->br_path);
2314 +       goto out; /* success */
2315 +
2316 +out_err:
2317 +       memset(&br->br_path, 0, sizeof(br->br_path));
2318 +out:
2319 +       return err;
2320 +}
2321 +
2322 +static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
2323 +                            struct au_branch *br, aufs_bindex_t bend,
2324 +                            aufs_bindex_t amount)
2325 +{
2326 +       struct au_branch **brp;
2327 +
2328 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
2329 +
2330 +       brp = sbinfo->si_branch + bindex;
2331 +       memmove(brp + 1, brp, sizeof(*brp) * amount);
2332 +       *brp = br;
2333 +       sbinfo->si_bend++;
2334 +       if (unlikely(bend < 0))
2335 +               sbinfo->si_bend = 0;
2336 +}
2337 +
2338 +static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
2339 +                            aufs_bindex_t bend, aufs_bindex_t amount)
2340 +{
2341 +       struct au_hdentry *hdp;
2342 +
2343 +       AuRwMustWriteLock(&dinfo->di_rwsem);
2344 +
2345 +       hdp = dinfo->di_hdentry + bindex;
2346 +       memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
2347 +       au_h_dentry_init(hdp);
2348 +       dinfo->di_bend++;
2349 +       if (unlikely(bend < 0))
2350 +               dinfo->di_bstart = 0;
2351 +}
2352 +
2353 +static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
2354 +                            aufs_bindex_t bend, aufs_bindex_t amount)
2355 +{
2356 +       struct au_hinode *hip;
2357 +
2358 +       AuRwMustWriteLock(&iinfo->ii_rwsem);
2359 +
2360 +       hip = iinfo->ii_hinode + bindex;
2361 +       memmove(hip + 1, hip, sizeof(*hip) * amount);
2362 +       hip->hi_inode = NULL;
2363 +       au_hn_init(hip);
2364 +       iinfo->ii_bend++;
2365 +       if (unlikely(bend < 0))
2366 +               iinfo->ii_bstart = 0;
2367 +}
2368 +
2369 +static void au_br_do_add(struct super_block *sb, struct au_branch *br,
2370 +                        aufs_bindex_t bindex)
2371 +{
2372 +       struct dentry *root, *h_dentry;
2373 +       struct inode *root_inode;
2374 +       aufs_bindex_t bend, amount;
2375 +
2376 +       au_br_dflags_force(br);
2377 +
2378 +       root = sb->s_root;
2379 +       root_inode = root->d_inode;
2380 +       bend = au_sbend(sb);
2381 +       amount = bend + 1 - bindex;
2382 +       h_dentry = au_br_dentry(br);
2383 +       au_sbilist_lock();
2384 +       au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
2385 +       au_br_do_add_hdp(au_di(root), bindex, bend, amount);
2386 +       au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
2387 +       au_set_h_dptr(root, bindex, dget(h_dentry));
2388 +       au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
2389 +                     /*flags*/0);
2390 +       au_sbilist_unlock();
2391 +}
2392 +
2393 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
2394 +{
2395 +       int err;
2396 +       aufs_bindex_t bend, add_bindex;
2397 +       struct dentry *root, *h_dentry;
2398 +       struct inode *root_inode;
2399 +       struct au_branch *add_branch;
2400 +
2401 +       root = sb->s_root;
2402 +       root_inode = root->d_inode;
2403 +       IMustLock(root_inode);
2404 +       err = test_add(sb, add, remount);
2405 +       if (unlikely(err < 0))
2406 +               goto out;
2407 +       if (err) {
2408 +               err = 0;
2409 +               goto out; /* success */
2410 +       }
2411 +
2412 +       bend = au_sbend(sb);
2413 +       add_branch = au_br_alloc(sb, bend + 2, add->perm);
2414 +       err = PTR_ERR(add_branch);
2415 +       if (IS_ERR(add_branch))
2416 +               goto out;
2417 +
2418 +       err = au_br_init(add_branch, sb, add);
2419 +       if (unlikely(err)) {
2420 +               au_br_do_free(add_branch);
2421 +               goto out;
2422 +       }
2423 +
2424 +       add_bindex = add->bindex;
2425 +       if (!remount)
2426 +               au_br_do_add(sb, add_branch, add_bindex);
2427 +       else {
2428 +               sysaufs_brs_del(sb, add_bindex);
2429 +               au_br_do_add(sb, add_branch, add_bindex);
2430 +               sysaufs_brs_add(sb, add_bindex);
2431 +       }
2432 +
2433 +       h_dentry = add->path.dentry;
2434 +       if (!add_bindex) {
2435 +               au_cpup_attr_all(root_inode, /*force*/1);
2436 +               sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
2437 +       } else
2438 +               au_add_nlink(root_inode, h_dentry->d_inode);
2439 +
2440 +       /*
2441 +        * this test/set prevents aufs from handling unnecesary notify events
2442 +        * of xino files, in case of re-adding a writable branch which was
2443 +        * once detached from aufs.
2444 +        */
2445 +       if (au_xino_brid(sb) < 0
2446 +           && au_br_writable(add_branch->br_perm)
2447 +           && !au_test_fs_bad_xino(h_dentry->d_sb)
2448 +           && add_branch->br_xino.xi_file
2449 +           && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
2450 +               au_xino_brid_set(sb, add_branch->br_id);
2451 +
2452 +out:
2453 +       return err;
2454 +}
2455 +
2456 +/* ---------------------------------------------------------------------- */
2457 +
2458 +/*
2459 + * delete a branch
2460 + */
2461 +
2462 +/* to show the line number, do not make it inlined function */
2463 +#define AuVerbose(do_info, fmt, ...) do { \
2464 +       if (do_info) \
2465 +               pr_info(fmt, ##__VA_ARGS__); \
2466 +} while (0)
2467 +
2468 +static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
2469 +                        aufs_bindex_t bend)
2470 +{
2471 +       return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
2472 +}
2473 +
2474 +static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
2475 +                        aufs_bindex_t bend)
2476 +{
2477 +       return au_test_ibusy(dentry->d_inode, bstart, bend);
2478 +}
2479 +
2480 +/*
2481 + * test if the branch is deletable or not.
2482 + */
2483 +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
2484 +                           unsigned int sigen, const unsigned int verbose)
2485 +{
2486 +       int err, i, j, ndentry;
2487 +       aufs_bindex_t bstart, bend;
2488 +       struct au_dcsub_pages dpages;
2489 +       struct au_dpage *dpage;
2490 +       struct dentry *d;
2491 +
2492 +       err = au_dpages_init(&dpages, GFP_NOFS);
2493 +       if (unlikely(err))
2494 +               goto out;
2495 +       err = au_dcsub_pages(&dpages, root, NULL, NULL);
2496 +       if (unlikely(err))
2497 +               goto out_dpages;
2498 +
2499 +       for (i = 0; !err && i < dpages.ndpage; i++) {
2500 +               dpage = dpages.dpages + i;
2501 +               ndentry = dpage->ndentry;
2502 +               for (j = 0; !err && j < ndentry; j++) {
2503 +                       d = dpage->dentries[j];
2504 +                       AuDebugOn(!d->d_count);
2505 +                       if (!au_digen_test(d, sigen)) {
2506 +                               di_read_lock_child(d, AuLock_IR);
2507 +                               if (unlikely(au_dbrange_test(d))) {
2508 +                                       di_read_unlock(d, AuLock_IR);
2509 +                                       continue;
2510 +                               }
2511 +                       } else {
2512 +                               di_write_lock_child(d);
2513 +                               if (unlikely(au_dbrange_test(d))) {
2514 +                                       di_write_unlock(d);
2515 +                                       continue;
2516 +                               }
2517 +                               err = au_reval_dpath(d, sigen);
2518 +                               if (!err)
2519 +                                       di_downgrade_lock(d, AuLock_IR);
2520 +                               else {
2521 +                                       di_write_unlock(d);
2522 +                                       break;
2523 +                               }
2524 +                       }
2525 +
2526 +                       /* AuDbgDentry(d); */
2527 +                       bstart = au_dbstart(d);
2528 +                       bend = au_dbend(d);
2529 +                       if (bstart <= bindex
2530 +                           && bindex <= bend
2531 +                           && au_h_dptr(d, bindex)
2532 +                           && au_test_dbusy(d, bstart, bend)) {
2533 +                               err = -EBUSY;
2534 +                               AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
2535 +                               AuDbgDentry(d);
2536 +                       }
2537 +                       di_read_unlock(d, AuLock_IR);
2538 +               }
2539 +       }
2540 +
2541 +out_dpages:
2542 +       au_dpages_free(&dpages);
2543 +out:
2544 +       return err;
2545 +}
2546 +
2547 +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
2548 +                          unsigned int sigen, const unsigned int verbose)
2549 +{
2550 +       int err;
2551 +       unsigned long long max, ull;
2552 +       struct inode *i, **array;
2553 +       aufs_bindex_t bstart, bend;
2554 +
2555 +       array = au_iarray_alloc(sb, &max);
2556 +       err = PTR_ERR(array);
2557 +       if (IS_ERR(array))
2558 +               goto out;
2559 +
2560 +       err = 0;
2561 +       AuDbg("b%d\n", bindex);
2562 +       for (ull = 0; !err && ull < max; ull++) {
2563 +               i = array[ull];
2564 +               if (i->i_ino == AUFS_ROOT_INO)
2565 +                       continue;
2566 +
2567 +               /* AuDbgInode(i); */
2568 +               if (au_iigen(i, NULL) == sigen)
2569 +                       ii_read_lock_child(i);
2570 +               else {
2571 +                       ii_write_lock_child(i);
2572 +                       err = au_refresh_hinode_self(i);
2573 +                       au_iigen_dec(i);
2574 +                       if (!err)
2575 +                               ii_downgrade_lock(i);
2576 +                       else {
2577 +                               ii_write_unlock(i);
2578 +                               break;
2579 +                       }
2580 +               }
2581 +
2582 +               bstart = au_ibstart(i);
2583 +               bend = au_ibend(i);
2584 +               if (bstart <= bindex
2585 +                   && bindex <= bend
2586 +                   && au_h_iptr(i, bindex)
2587 +                   && au_test_ibusy(i, bstart, bend)) {
2588 +                       err = -EBUSY;
2589 +                       AuVerbose(verbose, "busy i%lu\n", i->i_ino);
2590 +                       AuDbgInode(i);
2591 +               }
2592 +               ii_read_unlock(i);
2593 +       }
2594 +       au_iarray_free(array, max);
2595 +
2596 +out:
2597 +       return err;
2598 +}
2599 +
2600 +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
2601 +                             const unsigned int verbose)
2602 +{
2603 +       int err;
2604 +       unsigned int sigen;
2605 +
2606 +       sigen = au_sigen(root->d_sb);
2607 +       DiMustNoWaiters(root);
2608 +       IiMustNoWaiters(root->d_inode);
2609 +       di_write_unlock(root);
2610 +       err = test_dentry_busy(root, bindex, sigen, verbose);
2611 +       if (!err)
2612 +               err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
2613 +       di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
2614 +
2615 +       return err;
2616 +}
2617 +
2618 +static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
2619 +                            const aufs_bindex_t bindex,
2620 +                            const aufs_bindex_t bend)
2621 +{
2622 +       struct au_branch **brp, **p;
2623 +
2624 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
2625 +
2626 +       brp = sbinfo->si_branch + bindex;
2627 +       if (bindex < bend)
2628 +               memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
2629 +       sbinfo->si_branch[0 + bend] = NULL;
2630 +       sbinfo->si_bend--;
2631 +
2632 +       p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
2633 +       if (p)
2634 +               sbinfo->si_branch = p;
2635 +       /* harmless error */
2636 +}
2637 +
2638 +static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
2639 +                            const aufs_bindex_t bend)
2640 +{
2641 +       struct au_hdentry *hdp, *p;
2642 +
2643 +       AuRwMustWriteLock(&dinfo->di_rwsem);
2644 +
2645 +       hdp = dinfo->di_hdentry;
2646 +       if (bindex < bend)
2647 +               memmove(hdp + bindex, hdp + bindex + 1,
2648 +                       sizeof(*hdp) * (bend - bindex));
2649 +       hdp[0 + bend].hd_dentry = NULL;
2650 +       dinfo->di_bend--;
2651 +
2652 +       p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
2653 +       if (p)
2654 +               dinfo->di_hdentry = p;
2655 +       /* harmless error */
2656 +}
2657 +
2658 +static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
2659 +                            const aufs_bindex_t bend)
2660 +{
2661 +       struct au_hinode *hip, *p;
2662 +
2663 +       AuRwMustWriteLock(&iinfo->ii_rwsem);
2664 +
2665 +       hip = iinfo->ii_hinode + bindex;
2666 +       if (bindex < bend)
2667 +               memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
2668 +       iinfo->ii_hinode[0 + bend].hi_inode = NULL;
2669 +       au_hn_init(iinfo->ii_hinode + bend);
2670 +       iinfo->ii_bend--;
2671 +
2672 +       p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
2673 +       if (p)
2674 +               iinfo->ii_hinode = p;
2675 +       /* harmless error */
2676 +}
2677 +
2678 +static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
2679 +                        struct au_branch *br)
2680 +{
2681 +       aufs_bindex_t bend;
2682 +       struct au_sbinfo *sbinfo;
2683 +       struct dentry *root, *h_root;
2684 +       struct inode *inode, *h_inode;
2685 +       struct au_hinode *hinode;
2686 +
2687 +       SiMustWriteLock(sb);
2688 +
2689 +       root = sb->s_root;
2690 +       inode = root->d_inode;
2691 +       sbinfo = au_sbi(sb);
2692 +       bend = sbinfo->si_bend;
2693 +
2694 +       h_root = au_h_dptr(root, bindex);
2695 +       hinode = au_hi(inode, bindex);
2696 +       h_inode = au_igrab(hinode->hi_inode);
2697 +       au_hiput(hinode);
2698 +
2699 +       au_sbilist_lock();
2700 +       au_br_do_del_brp(sbinfo, bindex, bend);
2701 +       au_br_do_del_hdp(au_di(root), bindex, bend);
2702 +       au_br_do_del_hip(au_ii(inode), bindex, bend);
2703 +       au_sbilist_unlock();
2704 +
2705 +       dput(h_root);
2706 +       iput(h_inode);
2707 +       au_br_do_free(br);
2708 +}
2709 +
2710 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
2711 +{
2712 +       int err, rerr, i;
2713 +       unsigned int mnt_flags;
2714 +       aufs_bindex_t bindex, bend, br_id;
2715 +       unsigned char do_wh, verbose;
2716 +       struct au_branch *br;
2717 +       struct au_wbr *wbr;
2718 +
2719 +       err = 0;
2720 +       bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
2721 +       if (bindex < 0) {
2722 +               if (remount)
2723 +                       goto out; /* success */
2724 +               err = -ENOENT;
2725 +               pr_err("%s no such branch\n", del->pathname);
2726 +               goto out;
2727 +       }
2728 +       AuDbg("bindex b%d\n", bindex);
2729 +
2730 +       err = -EBUSY;
2731 +       mnt_flags = au_mntflags(sb);
2732 +       verbose = !!au_opt_test(mnt_flags, VERBOSE);
2733 +       bend = au_sbend(sb);
2734 +       if (unlikely(!bend)) {
2735 +               AuVerbose(verbose, "no more branches left\n");
2736 +               goto out;
2737 +       }
2738 +       br = au_sbr(sb, bindex);
2739 +       AuDebugOn(!path_equal(&br->br_path, &del->h_path));
2740 +       i = atomic_read(&br->br_count);
2741 +       if (unlikely(i)) {
2742 +               AuVerbose(verbose, "%d file(s) opened\n", i);
2743 +               goto out;
2744 +       }
2745 +
2746 +       wbr = br->br_wbr;
2747 +       do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
2748 +       if (do_wh) {
2749 +               /* instead of WbrWhMustWriteLock(wbr) */
2750 +               SiMustWriteLock(sb);
2751 +               for (i = 0; i < AuBrWh_Last; i++) {
2752 +                       dput(wbr->wbr_wh[i]);
2753 +                       wbr->wbr_wh[i] = NULL;
2754 +               }
2755 +       }
2756 +
2757 +       err = test_children_busy(sb->s_root, bindex, verbose);
2758 +       if (unlikely(err)) {
2759 +               if (do_wh)
2760 +                       goto out_wh;
2761 +               goto out;
2762 +       }
2763 +
2764 +       err = 0;
2765 +       br_id = br->br_id;
2766 +       if (!remount)
2767 +               au_br_do_del(sb, bindex, br);
2768 +       else {
2769 +               sysaufs_brs_del(sb, bindex);
2770 +               au_br_do_del(sb, bindex, br);
2771 +               sysaufs_brs_add(sb, bindex);
2772 +       }
2773 +
2774 +       if (!bindex) {
2775 +               au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
2776 +               sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
2777 +       } else
2778 +               au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
2779 +       if (au_opt_test(mnt_flags, PLINK))
2780 +               au_plink_half_refresh(sb, br_id);
2781 +
2782 +       if (au_xino_brid(sb) == br_id)
2783 +               au_xino_brid_set(sb, -1);
2784 +       goto out; /* success */
2785 +
2786 +out_wh:
2787 +       /* revert */
2788 +       rerr = au_br_init_wh(sb, br, br->br_perm);
2789 +       if (rerr)
2790 +               pr_warn("failed re-creating base whiteout, %s. (%d)\n",
2791 +                       del->pathname, rerr);
2792 +out:
2793 +       return err;
2794 +}
2795 +
2796 +/* ---------------------------------------------------------------------- */
2797 +
2798 +static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
2799 +{
2800 +       int err;
2801 +       aufs_bindex_t bstart, bend;
2802 +       struct aufs_ibusy ibusy;
2803 +       struct inode *inode, *h_inode;
2804 +
2805 +       err = -EPERM;
2806 +       if (unlikely(!capable(CAP_SYS_ADMIN)))
2807 +               goto out;
2808 +
2809 +       err = copy_from_user(&ibusy, arg, sizeof(ibusy));
2810 +       if (!err)
2811 +               err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
2812 +       if (unlikely(err)) {
2813 +               err = -EFAULT;
2814 +               AuTraceErr(err);
2815 +               goto out;
2816 +       }
2817 +
2818 +       err = -EINVAL;
2819 +       si_read_lock(sb, AuLock_FLUSH);
2820 +       if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
2821 +               goto out_unlock;
2822 +
2823 +       err = 0;
2824 +       ibusy.h_ino = 0; /* invalid */
2825 +       inode = ilookup(sb, ibusy.ino);
2826 +       if (!inode
2827 +           || inode->i_ino == AUFS_ROOT_INO
2828 +           || is_bad_inode(inode))
2829 +               goto out_unlock;
2830 +
2831 +       ii_read_lock_child(inode);
2832 +       bstart = au_ibstart(inode);
2833 +       bend = au_ibend(inode);
2834 +       if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
2835 +               h_inode = au_h_iptr(inode, ibusy.bindex);
2836 +               if (h_inode && au_test_ibusy(inode, bstart, bend))
2837 +                       ibusy.h_ino = h_inode->i_ino;
2838 +       }
2839 +       ii_read_unlock(inode);
2840 +       iput(inode);
2841 +
2842 +out_unlock:
2843 +       si_read_unlock(sb);
2844 +       if (!err) {
2845 +               err = __put_user(ibusy.h_ino, &arg->h_ino);
2846 +               if (unlikely(err)) {
2847 +                       err = -EFAULT;
2848 +                       AuTraceErr(err);
2849 +               }
2850 +       }
2851 +out:
2852 +       return err;
2853 +}
2854 +
2855 +long au_ibusy_ioctl(struct file *file, unsigned long arg)
2856 +{
2857 +       return au_ibusy(file->f_dentry->d_sb, (void __user *)arg);
2858 +}
2859 +
2860 +#ifdef CONFIG_COMPAT
2861 +long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
2862 +{
2863 +       return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg));
2864 +}
2865 +#endif
2866 +
2867 +/* ---------------------------------------------------------------------- */
2868 +
2869 +/*
2870 + * change a branch permission
2871 + */
2872 +
2873 +static void au_warn_ima(void)
2874 +{
2875 +#ifdef CONFIG_IMA
2876 +       /* since it doesn't support mark_files_ro() */
2877 +       AuWarn1("RW -> RO makes IMA to produce wrong message\n");
2878 +#endif
2879 +}
2880 +
2881 +static int do_need_sigen_inc(int a, int b)
2882 +{
2883 +       return au_br_whable(a) && !au_br_whable(b);
2884 +}
2885 +
2886 +static int need_sigen_inc(int old, int new)
2887 +{
2888 +       return do_need_sigen_inc(old, new)
2889 +               || do_need_sigen_inc(new, old);
2890 +}
2891 +
2892 +static unsigned long long au_farray_cb(void *a,
2893 +                                      unsigned long long max __maybe_unused,
2894 +                                      void *arg)
2895 +{
2896 +       unsigned long long n;
2897 +       struct file **p, *f;
2898 +       struct super_block *sb = arg;
2899 +
2900 +       n = 0;
2901 +       p = a;
2902 +       lg_global_lock(&files_lglock);
2903 +       do_file_list_for_each_entry(sb, f) {
2904 +               if (au_fi(f)
2905 +                   && file_count(f)
2906 +                   && !special_file(file_inode(f)->i_mode)) {
2907 +                       get_file(f);
2908 +                       *p++ = f;
2909 +                       n++;
2910 +                       AuDebugOn(n > max);
2911 +               }
2912 +       } while_file_list_for_each_entry;
2913 +       lg_global_unlock(&files_lglock);
2914 +
2915 +       return n;
2916 +}
2917 +
2918 +static struct file **au_farray_alloc(struct super_block *sb,
2919 +                                    unsigned long long *max)
2920 +{
2921 +       *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
2922 +       return au_array_alloc(max, au_farray_cb, sb);
2923 +}
2924 +
2925 +static void au_farray_free(struct file **a, unsigned long long max)
2926 +{
2927 +       unsigned long long ull;
2928 +
2929 +       for (ull = 0; ull < max; ull++)
2930 +               if (a[ull])
2931 +                       fput(a[ull]);
2932 +       au_array_free(a);
2933 +}
2934 +
2935 +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
2936 +{
2937 +       int err, do_warn;
2938 +       unsigned int mnt_flags;
2939 +       unsigned long long ull, max;
2940 +       aufs_bindex_t br_id;
2941 +       unsigned char verbose;
2942 +       struct file *file, *hf, **array;
2943 +       struct inode *inode;
2944 +       struct au_hfile *hfile;
2945 +
2946 +       mnt_flags = au_mntflags(sb);
2947 +       verbose = !!au_opt_test(mnt_flags, VERBOSE);
2948 +
2949 +       array = au_farray_alloc(sb, &max);
2950 +       err = PTR_ERR(array);
2951 +       if (IS_ERR(array))
2952 +               goto out;
2953 +
2954 +       do_warn = 0;
2955 +       br_id = au_sbr_id(sb, bindex);
2956 +       for (ull = 0; ull < max; ull++) {
2957 +               file = array[ull];
2958 +
2959 +               /* AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); */
2960 +               fi_read_lock(file);
2961 +               if (unlikely(au_test_mmapped(file))) {
2962 +                       err = -EBUSY;
2963 +                       AuVerbose(verbose, "mmapped %.*s\n",
2964 +                                 AuDLNPair(file->f_dentry));
2965 +                       AuDbgFile(file);
2966 +                       FiMustNoWaiters(file);
2967 +                       fi_read_unlock(file);
2968 +                       goto out_array;
2969 +               }
2970 +
2971 +               inode = file_inode(file);
2972 +               hfile = &au_fi(file)->fi_htop;
2973 +               hf = hfile->hf_file;
2974 +               if (!S_ISREG(inode->i_mode)
2975 +                   || !(file->f_mode & FMODE_WRITE)
2976 +                   || hfile->hf_br->br_id != br_id
2977 +                   || !(hf->f_mode & FMODE_WRITE))
2978 +                       array[ull] = NULL;
2979 +               else {
2980 +                       do_warn = 1;
2981 +                       get_file(file);
2982 +               }
2983 +
2984 +               FiMustNoWaiters(file);
2985 +               fi_read_unlock(file);
2986 +               fput(file);
2987 +       }
2988 +
2989 +       err = 0;
2990 +       if (do_warn)
2991 +               au_warn_ima();
2992 +
2993 +       for (ull = 0; ull < max; ull++) {
2994 +               file = array[ull];
2995 +               if (!file)
2996 +                       continue;
2997 +
2998 +               /* todo: already flushed? */
2999 +               /* cf. fs/super.c:mark_files_ro() */
3000 +               /* fi_read_lock(file); */
3001 +               hfile = &au_fi(file)->fi_htop;
3002 +               hf = hfile->hf_file;
3003 +               /* fi_read_unlock(file); */
3004 +               spin_lock(&hf->f_lock);
3005 +               hf->f_mode &= ~FMODE_WRITE;
3006 +               spin_unlock(&hf->f_lock);
3007 +               if (!file_check_writeable(hf)) {
3008 +                       __mnt_drop_write(hf->f_path.mnt);
3009 +                       file_release_write(hf);
3010 +               }
3011 +       }
3012 +
3013 +out_array:
3014 +       au_farray_free(array, max);
3015 +out:
3016 +       AuTraceErr(err);
3017 +       return err;
3018 +}
3019 +
3020 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
3021 +             int *do_refresh)
3022 +{
3023 +       int err, rerr;
3024 +       aufs_bindex_t bindex;
3025 +       struct dentry *root;
3026 +       struct au_branch *br;
3027 +
3028 +       root = sb->s_root;
3029 +       bindex = au_find_dbindex(root, mod->h_root);
3030 +       if (bindex < 0) {
3031 +               if (remount)
3032 +                       return 0; /* success */
3033 +               err = -ENOENT;
3034 +               pr_err("%s no such branch\n", mod->path);
3035 +               goto out;
3036 +       }
3037 +       AuDbg("bindex b%d\n", bindex);
3038 +
3039 +       err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
3040 +       if (unlikely(err))
3041 +               goto out;
3042 +
3043 +       br = au_sbr(sb, bindex);
3044 +       AuDebugOn(mod->h_root != au_br_dentry(br));
3045 +       if (br->br_perm == mod->perm)
3046 +               return 0; /* success */
3047 +
3048 +       if (au_br_writable(br->br_perm)) {
3049 +               /* remove whiteout base */
3050 +               err = au_br_init_wh(sb, br, mod->perm);
3051 +               if (unlikely(err))
3052 +                       goto out;
3053 +
3054 +               if (!au_br_writable(mod->perm)) {
3055 +                       /* rw --> ro, file might be mmapped */
3056 +                       DiMustNoWaiters(root);
3057 +                       IiMustNoWaiters(root->d_inode);
3058 +                       di_write_unlock(root);
3059 +                       err = au_br_mod_files_ro(sb, bindex);
3060 +                       /* aufs_write_lock() calls ..._child() */
3061 +                       di_write_lock_child(root);
3062 +
3063 +                       if (unlikely(err)) {
3064 +                               rerr = -ENOMEM;
3065 +                               br->br_wbr = kmalloc(sizeof(*br->br_wbr),
3066 +                                                    GFP_NOFS);
3067 +                               if (br->br_wbr)
3068 +                                       rerr = au_wbr_init(br, sb, br->br_perm);
3069 +                               if (unlikely(rerr)) {
3070 +                                       AuIOErr("nested error %d (%d)\n",
3071 +                                               rerr, err);
3072 +                                       br->br_perm = mod->perm;
3073 +                               }
3074 +                       }
3075 +               }
3076 +       } else if (au_br_writable(mod->perm)) {
3077 +               /* ro --> rw */
3078 +               err = -ENOMEM;
3079 +               br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
3080 +               if (br->br_wbr) {
3081 +                       err = au_wbr_init(br, sb, mod->perm);
3082 +                       if (unlikely(err)) {
3083 +                               kfree(br->br_wbr);
3084 +                               br->br_wbr = NULL;
3085 +                       }
3086 +               }
3087 +       }
3088 +
3089 +       if (!err) {
3090 +               if ((br->br_perm & AuBrAttr_UNPIN)
3091 +                   && !(mod->perm & AuBrAttr_UNPIN))
3092 +                       au_br_dflags_force(br);
3093 +               else if (!(br->br_perm & AuBrAttr_UNPIN)
3094 +                        && (mod->perm & AuBrAttr_UNPIN))
3095 +                       au_br_dflags_restore(br);
3096 +               *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
3097 +               br->br_perm = mod->perm;
3098 +       }
3099 +
3100 +out:
3101 +       AuTraceErr(err);
3102 +       return err;
3103 +}
3104 diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
3105 --- /usr/share/empty/fs/aufs/branch.h   1970-01-01 01:00:00.000000000 +0100
3106 +++ linux/fs/aufs/branch.h      2013-07-06 13:20:47.740198107 +0200
3107 @@ -0,0 +1,255 @@
3108 +/*
3109 + * Copyright (C) 2005-2013 Junjiro R. Okajima
3110 + *
3111 + * This program, aufs is free software; you can redistribute it and/or modify
3112 + * it under the terms of the GNU General Public License as published by
3113 + * the Free Software Foundation; either version 2 of the License, or
3114 + * (at your option) any later version.
3115 + *
3116 + * This program is distributed in the hope that it will be useful,
3117 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3118 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3119 + * GNU General Public License for more details.
3120 + *
3121 + * You should have received a copy of the GNU General Public License
3122 + * along with this program; if not, write to the Free Software
3123 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
3124 + */
3125 +
3126 +/*
3127 + * branch filesystems and xino for them
3128 + */
3129 +
3130 +#ifndef __AUFS_BRANCH_H__
3131 +#define __AUFS_BRANCH_H__
3132 +
3133 +#ifdef __KERNEL__
3134 +
3135 +#include <linux/mount.h>
3136 +#include "dynop.h"
3137 +#include "rwsem.h"
3138 +#include "super.h"
3139 +
3140 +/* ---------------------------------------------------------------------- */
3141 +
3142 +/* a xino file */
3143 +struct au_xino_file {
3144 +       struct file             *xi_file;
3145 +       struct mutex            xi_nondir_mtx;
3146 +
3147 +       /* todo: make xino files an array to support huge inode number */
3148 +
3149 +#ifdef CONFIG_DEBUG_FS
3150 +       struct dentry            *xi_dbgaufs;
3151 +#endif
3152 +};
3153 +
3154 +/* members for writable branch only */
3155 +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
3156 +struct au_wbr {
3157 +       struct au_rwsem         wbr_wh_rwsem;
3158 +       struct dentry           *wbr_wh[AuBrWh_Last];
3159 +       atomic_t                wbr_wh_running;
3160 +#define wbr_whbase             wbr_wh[AuBrWh_BASE]     /* whiteout base */
3161 +#define wbr_plink              wbr_wh[AuBrWh_PLINK]    /* pseudo-link dir */
3162 +#define wbr_orph               wbr_wh[AuBrWh_ORPH]     /* dir for orphans */
3163 +
3164 +       /* mfs mode */
3165 +       unsigned long long      wbr_bytes;
3166 +};
3167 +
3168 +/* ext2 has 3 types of operations at least, ext3 has 4 */
3169 +#define AuBrDynOp (AuDyLast * 4)
3170 +
3171 +#ifdef CONFIG_AUFS_HFSNOTIFY
3172 +/* support for asynchronous destruction */
3173 +struct au_br_hfsnotify {
3174 +       struct fsnotify_group   *hfsn_group;
3175 +};
3176 +#endif
3177 +
3178 +/* protected by superblock rwsem */
3179 +struct au_branch {
3180 +       struct au_xino_file     br_xino;
3181 +
3182 +       aufs_bindex_t           br_id;
3183 +
3184 +       int                     br_perm;
3185 +       unsigned int            br_dflags;
3186 +       struct path             br_path;
3187 +       spinlock_t              br_dykey_lock;
3188 +       struct au_dykey         *br_dykey[AuBrDynOp];
3189 +       atomic_t                br_count;
3190 +
3191 +       struct au_wbr           *br_wbr;
3192 +
3193 +       /* xino truncation */
3194 +       blkcnt_t                br_xino_upper;  /* watermark in blocks */
3195 +       atomic_t                br_xino_running;
3196 +
3197 +#ifdef CONFIG_AUFS_HFSNOTIFY
3198 +       struct au_br_hfsnotify  *br_hfsn;
3199 +#endif
3200 +
3201 +#ifdef CONFIG_SYSFS
3202 +       /* an entry under sysfs per mount-point */
3203 +       char                    br_name[8];
3204 +       struct attribute        br_attr;
3205 +#endif
3206 +};
3207 +
3208 +/* ---------------------------------------------------------------------- */
3209 +
3210 +static inline struct vfsmount *au_br_mnt(struct au_branch *br)
3211 +{
3212 +       return br->br_path.mnt;
3213 +}
3214 +
3215 +static inline struct dentry *au_br_dentry(struct au_branch *br)
3216 +{
3217 +       return br->br_path.dentry;
3218 +}
3219 +
3220 +static inline struct super_block *au_br_sb(struct au_branch *br)
3221 +{
3222 +       return au_br_mnt(br)->mnt_sb;
3223 +}
3224 +
3225 +/* branch permissions and attributes */
3226 +#define AuBrPerm_RW            1               /* writable, hardlinkable wh */
3227 +#define AuBrPerm_RO            (1 << 1)        /* readonly */
3228 +#define AuBrPerm_RR            (1 << 2)        /* natively readonly */
3229 +#define AuBrPerm_Mask          (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
3230 +
3231 +#define AuBrRAttr_WH           (1 << 3)        /* whiteout-able */
3232 +
3233 +#define AuBrWAttr_NoLinkWH     (1 << 4)        /* un-hardlinkable whiteouts */
3234 +
3235 +#define AuBrAttr_UNPIN         (1 << 5)        /* rename-able top dir of
3236 +                                                  branch */
3237 +
3238 +static inline int au_br_writable(int brperm)
3239 +{
3240 +       return brperm & AuBrPerm_RW;
3241 +}
3242 +
3243 +static inline int au_br_whable(int brperm)
3244 +{
3245 +       return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
3246 +}
3247 +
3248 +static inline int au_br_wh_linkable(int brperm)
3249 +{
3250 +       return !(brperm & AuBrWAttr_NoLinkWH);
3251 +}
3252 +
3253 +static inline int au_br_rdonly(struct au_branch *br)
3254 +{
3255 +       return ((au_br_sb(br)->s_flags & MS_RDONLY)
3256 +               || !au_br_writable(br->br_perm))
3257 +               ? -EROFS : 0;
3258 +}
3259 +
3260 +static inline int au_br_hnotifyable(int brperm __maybe_unused)
3261 +{
3262 +#ifdef CONFIG_AUFS_HNOTIFY
3263 +       return !(brperm & AuBrPerm_RR);
3264 +#else
3265 +       return 0;
3266 +#endif
3267 +}
3268 +
3269 +/* ---------------------------------------------------------------------- */
3270 +
3271 +/* branch.c */
3272 +struct au_sbinfo;
3273 +void au_br_free(struct au_sbinfo *sinfo);
3274 +int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
3275 +struct au_opt_add;
3276 +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
3277 +struct au_opt_del;
3278 +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
3279 +long au_ibusy_ioctl(struct file *file, unsigned long arg);
3280 +#ifdef CONFIG_COMPAT
3281 +long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
3282 +#endif
3283 +struct au_opt_mod;
3284 +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
3285 +             int *do_refresh);
3286 +
3287 +/* xino.c */
3288 +static const loff_t au_loff_max = LLONG_MAX;
3289 +
3290 +int au_xib_trunc(struct super_block *sb);
3291 +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
3292 +                  loff_t *pos);
3293 +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
3294 +                   loff_t *pos);
3295 +struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
3296 +struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
3297 +ino_t au_xino_new_ino(struct super_block *sb);
3298 +void au_xino_delete_inode(struct inode *inode, const int unlinked);
3299 +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3300 +                 ino_t ino);
3301 +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3302 +                ino_t *ino);
3303 +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
3304 +              struct file *base_file, int do_test);
3305 +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
3306 +
3307 +struct au_opt_xino;
3308 +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
3309 +void au_xino_clr(struct super_block *sb);
3310 +struct file *au_xino_def(struct super_block *sb);
3311 +int au_xino_path(struct seq_file *seq, struct file *file);
3312 +
3313 +/* ---------------------------------------------------------------------- */
3314 +
3315 +/* Superblock to branch */
3316 +static inline
3317 +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
3318 +{
3319 +       return au_sbr(sb, bindex)->br_id;
3320 +}
3321 +
3322 +static inline
3323 +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
3324 +{
3325 +       return au_br_mnt(au_sbr(sb, bindex));
3326 +}
3327 +
3328 +static inline
3329 +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
3330 +{
3331 +       return au_br_sb(au_sbr(sb, bindex));
3332 +}
3333 +
3334 +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
3335 +{
3336 +       atomic_dec(&au_sbr(sb, bindex)->br_count);
3337 +}
3338 +
3339 +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
3340 +{
3341 +       return au_sbr(sb, bindex)->br_perm;
3342 +}
3343 +
3344 +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
3345 +{
3346 +       return au_br_whable(au_sbr_perm(sb, bindex));
3347 +}
3348 +
3349 +/* ---------------------------------------------------------------------- */
3350 +
3351 +/*
3352 + * wbr_wh_read_lock, wbr_wh_write_lock
3353 + * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
3354 + */
3355 +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
3356 +
3357 +#define WbrWhMustNoWaiters(wbr)        AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
3358 +#define WbrWhMustAnyLock(wbr)  AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
3359 +#define WbrWhMustWriteLock(wbr)        AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
3360 +
3361 +#endif /* __KERNEL__ */
3362 +#endif /* __AUFS_BRANCH_H__ */
3363 diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
3364 --- /usr/share/empty/fs/aufs/conf.mk    1970-01-01 01:00:00.000000000 +0100
3365 +++ linux/fs/aufs/conf.mk       2013-07-06 13:20:47.740198107 +0200
3366 @@ -0,0 +1,38 @@
3367 +
3368 +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
3369 +
3370 +define AuConf
3371 +ifdef ${1}
3372 +AuConfStr += ${1}=${${1}}
3373 +endif
3374 +endef
3375 +
3376 +AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
3377 +       SBILIST \
3378 +       HNOTIFY HFSNOTIFY \
3379 +       EXPORT INO_T_64 \
3380 +       RDU \
3381 +       PROC_MAP \
3382 +       SP_IATTR \
3383 +       SHWH \
3384 +       BR_RAMFS \
3385 +       BR_FUSE POLL \
3386 +       BR_HFSPLUS \
3387 +       BDEV_LOOP \
3388 +       DEBUG MAGIC_SYSRQ
3389 +$(foreach i, ${AuConfAll}, \
3390 +       $(eval $(call AuConf,CONFIG_AUFS_${i})))
3391 +
3392 +AuConfName = ${obj}/conf.str
3393 +${AuConfName}.tmp: FORCE
3394 +       @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
3395 +${AuConfName}: ${AuConfName}.tmp
3396 +       @diff -q $< $@ > /dev/null 2>&1 || { \
3397 +       echo '  GEN    ' $@; \
3398 +       cp -p $< $@; \
3399 +       }
3400 +FORCE:
3401 +clean-files += ${AuConfName} ${AuConfName}.tmp
3402 +${obj}/sysfs.o: ${AuConfName}
3403 +
3404 +-include ${srctree}/${src}/conf_priv.mk
3405 diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
3406 --- /usr/share/empty/fs/aufs/cpup.c     1970-01-01 01:00:00.000000000 +0100
3407 +++ linux/fs/aufs/cpup.c        2013-07-30 22:42:46.232612606 +0200
3408 @@ -0,0 +1,1247 @@
3409 +/*
3410 + * Copyright (C) 2005-2013 Junjiro R. Okajima
3411 + *
3412 + * This program, aufs is free software; you can redistribute it and/or modify
3413 + * it under the terms of the GNU General Public License as published by
3414 + * the Free Software Foundation; either version 2 of the License, or
3415 + * (at your option) any later version.
3416 + *
3417 + * This program is distributed in the hope that it will be useful,
3418 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3419 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3420 + * GNU General Public License for more details.
3421 + *
3422 + * You should have received a copy of the GNU General Public License
3423 + * along with this program; if not, write to the Free Software
3424 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
3425 + */
3426 +
3427 +/*
3428 + * copy-up functions, see wbr_policy.c for copy-down
3429 + */
3430 +
3431 +#include <linux/fs_stack.h>
3432 +#include <linux/mm.h>
3433 +#include "aufs.h"
3434 +
3435 +void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
3436 +{
3437 +       const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
3438 +               | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
3439 +
3440 +       BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
3441 +
3442 +       dst->i_flags |= iflags & ~mask;
3443 +       if (au_test_fs_notime(dst->i_sb))
3444 +               dst->i_flags |= S_NOATIME | S_NOCMTIME;
3445 +}
3446 +
3447 +void au_cpup_attr_timesizes(struct inode *inode)
3448 +{
3449 +       struct inode *h_inode;
3450 +
3451 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
3452 +       fsstack_copy_attr_times(inode, h_inode);
3453 +       fsstack_copy_inode_size(inode, h_inode);
3454 +}
3455 +
3456 +void au_cpup_attr_nlink(struct inode *inode, int force)
3457 +{
3458 +       struct inode *h_inode;
3459 +       struct super_block *sb;
3460 +       aufs_bindex_t bindex, bend;
3461 +
3462 +       sb = inode->i_sb;
3463 +       bindex = au_ibstart(inode);
3464 +       h_inode = au_h_iptr(inode, bindex);
3465 +       if (!force
3466 +           && !S_ISDIR(h_inode->i_mode)
3467 +           && au_opt_test(au_mntflags(sb), PLINK)
3468 +           && au_plink_test(inode))
3469 +               return;
3470 +
3471 +       /*
3472 +        * 0 can happen in revalidating.
3473 +        * h_inode->i_mutex is not held, but it is harmless since once i_nlink
3474 +        * reaches 0, it will never become positive.
3475 +        */
3476 +       set_nlink(inode, h_inode->i_nlink);
3477 +
3478 +       /*
3479 +        * fewer nlink makes find(1) noisy, but larger nlink doesn't.
3480 +        * it may includes whplink directory.
3481 +        */
3482 +       if (S_ISDIR(h_inode->i_mode)) {
3483 +               bend = au_ibend(inode);
3484 +               for (bindex++; bindex <= bend; bindex++) {
3485 +                       h_inode = au_h_iptr(inode, bindex);
3486 +                       if (h_inode)
3487 +                               au_add_nlink(inode, h_inode);
3488 +               }
3489 +       }
3490 +}
3491 +
3492 +void au_cpup_attr_changeable(struct inode *inode)
3493 +{
3494 +       struct inode *h_inode;
3495 +
3496 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
3497 +       inode->i_mode = h_inode->i_mode;
3498 +       inode->i_uid = h_inode->i_uid;
3499 +       inode->i_gid = h_inode->i_gid;
3500 +       au_cpup_attr_timesizes(inode);
3501 +       au_cpup_attr_flags(inode, h_inode->i_flags);
3502 +}
3503 +
3504 +void au_cpup_igen(struct inode *inode, struct inode *h_inode)
3505 +{
3506 +       struct au_iinfo *iinfo = au_ii(inode);
3507 +
3508 +       IiMustWriteLock(inode);
3509 +
3510 +       iinfo->ii_higen = h_inode->i_generation;
3511 +       iinfo->ii_hsb1 = h_inode->i_sb;
3512 +}
3513 +
3514 +void au_cpup_attr_all(struct inode *inode, int force)
3515 +{
3516 +       struct inode *h_inode;
3517 +
3518 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
3519 +       au_cpup_attr_changeable(inode);
3520 +       if (inode->i_nlink > 0)
3521 +               au_cpup_attr_nlink(inode, force);
3522 +       inode->i_rdev = h_inode->i_rdev;
3523 +       inode->i_blkbits = h_inode->i_blkbits;
3524 +       au_cpup_igen(inode, h_inode);
3525 +}
3526 +
3527 +/* ---------------------------------------------------------------------- */
3528 +
3529 +/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
3530 +
3531 +/* keep the timestamps of the parent dir when cpup */
3532 +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
3533 +                   struct path *h_path)
3534 +{
3535 +       struct inode *h_inode;
3536 +
3537 +       dt->dt_dentry = dentry;
3538 +       dt->dt_h_path = *h_path;
3539 +       h_inode = h_path->dentry->d_inode;
3540 +       dt->dt_atime = h_inode->i_atime;
3541 +       dt->dt_mtime = h_inode->i_mtime;
3542 +       /* smp_mb(); */
3543 +}
3544 +
3545 +void au_dtime_revert(struct au_dtime *dt)
3546 +{
3547 +       struct iattr attr;
3548 +       int err;
3549 +
3550 +       attr.ia_atime = dt->dt_atime;
3551 +       attr.ia_mtime = dt->dt_mtime;
3552 +       attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
3553 +               | ATTR_ATIME | ATTR_ATIME_SET;
3554 +
3555 +       err = vfsub_notify_change(&dt->dt_h_path, &attr);
3556 +       if (unlikely(err))
3557 +               pr_warn("restoring timestamps failed(%d). ignored\n", err);
3558 +}
3559 +
3560 +/* ---------------------------------------------------------------------- */
3561 +
3562 +/* internal use only */
3563 +struct au_cpup_reg_attr {
3564 +       int             valid;
3565 +       struct kstat    st;
3566 +       unsigned int    iflags; /* inode->i_flags */
3567 +};
3568 +
3569 +static noinline_for_stack
3570 +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
3571 +              struct au_cpup_reg_attr *h_src_attr)
3572 +{
3573 +       int err, sbits;
3574 +       struct iattr ia;
3575 +       struct path h_path;
3576 +       struct inode *h_isrc, *h_idst;
3577 +       struct kstat *h_st;
3578 +
3579 +       h_path.dentry = au_h_dptr(dst, bindex);
3580 +       h_idst = h_path.dentry->d_inode;
3581 +       h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
3582 +       h_isrc = h_src->d_inode;
3583 +       ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
3584 +               | ATTR_ATIME | ATTR_MTIME
3585 +               | ATTR_ATIME_SET | ATTR_MTIME_SET;
3586 +       if (h_src_attr && h_src_attr->valid) {
3587 +               h_st = &h_src_attr->st;
3588 +               ia.ia_uid = h_st->uid;
3589 +               ia.ia_gid = h_st->gid;
3590 +               ia.ia_atime = h_st->atime;
3591 +               ia.ia_mtime = h_st->mtime;
3592 +               if (h_idst->i_mode != h_st->mode
3593 +                   && !S_ISLNK(h_idst->i_mode)) {
3594 +                       ia.ia_valid |= ATTR_MODE;
3595 +                       ia.ia_mode = h_st->mode;
3596 +               }
3597 +               sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
3598 +               au_cpup_attr_flags(h_idst, h_src_attr->iflags);
3599 +       } else {
3600 +               ia.ia_uid = h_isrc->i_uid;
3601 +               ia.ia_gid = h_isrc->i_gid;
3602 +               ia.ia_atime = h_isrc->i_atime;
3603 +               ia.ia_mtime = h_isrc->i_mtime;
3604 +               if (h_idst->i_mode != h_isrc->i_mode
3605 +                   && !S_ISLNK(h_idst->i_mode)) {
3606 +                       ia.ia_valid |= ATTR_MODE;
3607 +                       ia.ia_mode = h_isrc->i_mode;
3608 +               }
3609 +               sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
3610 +               au_cpup_attr_flags(h_idst, h_isrc->i_flags);
3611 +       }
3612 +       err = vfsub_notify_change(&h_path, &ia);
3613 +
3614 +       /* is this nfs only? */
3615 +       if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
3616 +               ia.ia_valid = ATTR_FORCE | ATTR_MODE;
3617 +               ia.ia_mode = h_isrc->i_mode;
3618 +               err = vfsub_notify_change(&h_path, &ia);
3619 +       }
3620 +
3621 +       return err;
3622 +}
3623 +
3624 +/* ---------------------------------------------------------------------- */
3625 +
3626 +static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
3627 +                          char *buf, unsigned long blksize)
3628 +{
3629 +       int err;
3630 +       size_t sz, rbytes, wbytes;
3631 +       unsigned char all_zero;
3632 +       char *p, *zp;
3633 +       struct mutex *h_mtx;
3634 +       /* reduce stack usage */
3635 +       struct iattr *ia;
3636 +
3637 +       zp = page_address(ZERO_PAGE(0));
3638 +       if (unlikely(!zp))
3639 +               return -ENOMEM; /* possible? */
3640 +
3641 +       err = 0;
3642 +       all_zero = 0;
3643 +       while (len) {
3644 +               AuDbg("len %lld\n", len);
3645 +               sz = blksize;
3646 +               if (len < blksize)
3647 +                       sz = len;
3648 +
3649 +               rbytes = 0;
3650 +               /* todo: signal_pending? */
3651 +               while (!rbytes || err == -EAGAIN || err == -EINTR) {
3652 +                       rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
3653 +                       err = rbytes;
3654 +               }
3655 +               if (unlikely(err < 0))
3656 +                       break;
3657 +
3658 +               all_zero = 0;
3659 +               if (len >= rbytes && rbytes == blksize)
3660 +                       all_zero = !memcmp(buf, zp, rbytes);
3661 +               if (!all_zero) {
3662 +                       wbytes = rbytes;
3663 +                       p = buf;
3664 +                       while (wbytes) {
3665 +                               size_t b;
3666 +
3667 +                               b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
3668 +                               err = b;
3669 +                               /* todo: signal_pending? */
3670 +                               if (unlikely(err == -EAGAIN || err == -EINTR))
3671 +                                       continue;
3672 +                               if (unlikely(err < 0))
3673 +                                       break;
3674 +                               wbytes -= b;
3675 +                               p += b;
3676 +                       }
3677 +               } else {
3678 +                       loff_t res;
3679 +
3680 +                       AuLabel(hole);
3681 +                       res = vfsub_llseek(dst, rbytes, SEEK_CUR);
3682 +                       err = res;
3683 +                       if (unlikely(res < 0))
3684 +                               break;
3685 +               }
3686 +               len -= rbytes;
3687 +               err = 0;
3688 +       }
3689 +
3690 +       /* the last block may be a hole */
3691 +       if (!err && all_zero) {
3692 +               AuLabel(last hole);
3693 +
3694 +               err = 1;
3695 +               if (au_test_nfs(dst->f_dentry->d_sb)) {
3696 +                       /* nfs requires this step to make last hole */
3697 +                       /* is this only nfs? */
3698 +                       do {
3699 +                               /* todo: signal_pending? */
3700 +                               err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
3701 +                       } while (err == -EAGAIN || err == -EINTR);
3702 +                       if (err == 1)
3703 +                               dst->f_pos--;
3704 +               }
3705 +
3706 +               if (err == 1) {
3707 +                       ia = (void *)buf;
3708 +                       ia->ia_size = dst->f_pos;
3709 +                       ia->ia_valid = ATTR_SIZE | ATTR_FILE;
3710 +                       ia->ia_file = dst;
3711 +                       h_mtx = &file_inode(dst)->i_mutex;
3712 +                       mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
3713 +                       err = vfsub_notify_change(&dst->f_path, ia);
3714 +                       mutex_unlock(h_mtx);
3715 +               }
3716 +       }
3717 +
3718 +       return err;
3719 +}
3720 +
3721 +int au_copy_file(struct file *dst, struct file *src, loff_t len)
3722 +{
3723 +       int err;
3724 +       unsigned long blksize;
3725 +       unsigned char do_kfree;
3726 +       char *buf;
3727 +
3728 +       err = -ENOMEM;
3729 +       blksize = dst->f_dentry->d_sb->s_blocksize;
3730 +       if (!blksize || PAGE_SIZE < blksize)
3731 +               blksize = PAGE_SIZE;
3732 +       AuDbg("blksize %lu\n", blksize);
3733 +       do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
3734 +       if (do_kfree)
3735 +               buf = kmalloc(blksize, GFP_NOFS);
3736 +       else
3737 +               buf = (void *)__get_free_page(GFP_NOFS);
3738 +       if (unlikely(!buf))
3739 +               goto out;
3740 +
3741 +       if (len > (1 << 22))
3742 +               AuDbg("copying a large file %lld\n", (long long)len);
3743 +
3744 +       src->f_pos = 0;
3745 +       dst->f_pos = 0;
3746 +       err = au_do_copy_file(dst, src, len, buf, blksize);
3747 +       if (do_kfree)
3748 +               kfree(buf);
3749 +       else
3750 +               free_page((unsigned long)buf);
3751 +
3752 +out:
3753 +       return err;
3754 +}
3755 +
3756 +/* internal use only */
3757 +struct au_cpup_basic {
3758 +       struct dentry *dentry;
3759 +       aufs_bindex_t bdst, bsrc;
3760 +       loff_t len;
3761 +};
3762 +
3763 +/*
3764 + * to support a sparse file which is opened with O_APPEND,
3765 + * we need to close the file.
3766 + */
3767 +static int au_cp_regular(struct au_cpup_basic *basic)
3768 +{
3769 +       int err, i;
3770 +       enum { SRC, DST };
3771 +       struct {
3772 +               aufs_bindex_t bindex;
3773 +               unsigned int flags;
3774 +               struct dentry *dentry;
3775 +               struct file *file;
3776 +               void *label, *label_file;
3777 +       } *f, file[] = {
3778 +               {
3779 +                       .bindex = basic->bsrc,
3780 +                       .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
3781 +                       .file = NULL,
3782 +                       .label = &&out,
3783 +                       .label_file = &&out_src
3784 +               },
3785 +               {
3786 +                       .bindex = basic->bdst,
3787 +                       .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
3788 +                       .file = NULL,
3789 +                       .label = &&out_src,
3790 +                       .label_file = &&out_dst
3791 +               }
3792 +       };
3793 +       struct super_block *sb;
3794 +
3795 +       /* bsrc branch can be ro/rw. */
3796 +       sb = basic->dentry->d_sb;
3797 +       f = file;
3798 +       for (i = 0; i < 2; i++, f++) {
3799 +               f->dentry = au_h_dptr(basic->dentry, f->bindex);
3800 +               f->file = au_h_open(basic->dentry, f->bindex, f->flags,
3801 +                                   /*file*/NULL);
3802 +               err = PTR_ERR(f->file);
3803 +               if (IS_ERR(f->file))
3804 +                       goto *f->label;
3805 +               err = -EINVAL;
3806 +               if (unlikely(!f->file->f_op))
3807 +                       goto *f->label_file;
3808 +       }
3809 +
3810 +       /* try stopping to update while we copyup */
3811 +       IMustLock(file[SRC].dentry->d_inode);
3812 +       err = au_copy_file(file[DST].file, file[SRC].file, basic->len);
3813 +
3814 +out_dst:
3815 +       fput(file[DST].file);
3816 +       au_sbr_put(sb, file[DST].bindex);
3817 +out_src:
3818 +       fput(file[SRC].file);
3819 +       au_sbr_put(sb, file[SRC].bindex);
3820 +out:
3821 +       return err;
3822 +}
3823 +
3824 +static int au_do_cpup_regular(struct au_cpup_basic *basic, struct au_pin *pin,
3825 +                             struct au_cpup_reg_attr *h_src_attr)
3826 +{
3827 +       int err, rerr;
3828 +       loff_t l;
3829 +       struct path h_path;
3830 +       struct inode *h_src_inode;
3831 +
3832 +       err = 0;
3833 +       h_src_inode = au_h_iptr(basic->dentry->d_inode, basic->bsrc);
3834 +       l = i_size_read(h_src_inode);
3835 +       if (basic->len == -1 || l < basic->len)
3836 +               basic->len = l;
3837 +       if (basic->len) {
3838 +               /* try stopping to update while we are referencing */
3839 +               mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
3840 +               au_pin_hdir_unlock(pin);
3841 +
3842 +               h_path.dentry = au_h_dptr(basic->dentry, basic->bsrc);
3843 +               h_path.mnt = au_sbr_mnt(basic->dentry->d_sb, basic->bsrc);
3844 +               h_src_attr->iflags = h_src_inode->i_flags;
3845 +               err = vfs_getattr(&h_path, &h_src_attr->st);
3846 +               if (unlikely(err)) {
3847 +                       mutex_unlock(&h_src_inode->i_mutex);
3848 +                       goto out;
3849 +               }
3850 +               h_src_attr->valid = 1;
3851 +               err = au_cp_regular(basic);
3852 +               mutex_unlock(&h_src_inode->i_mutex);
3853 +               rerr = au_pin_hdir_relock(pin);
3854 +               if (!err && rerr)
3855 +                       err = rerr;
3856 +       }
3857 +
3858 +out:
3859 +       return err;
3860 +}
3861 +
3862 +static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
3863 +                             struct inode *h_dir)
3864 +{
3865 +       int err, symlen;
3866 +       mm_segment_t old_fs;
3867 +       union {
3868 +               char *k;
3869 +               char __user *u;
3870 +       } sym;
3871 +
3872 +       err = -ENOSYS;
3873 +       if (unlikely(!h_src->d_inode->i_op->readlink))
3874 +               goto out;
3875 +
3876 +       err = -ENOMEM;
3877 +       sym.k = (void *)__get_free_page(GFP_NOFS);
3878 +       if (unlikely(!sym.k))
3879 +               goto out;
3880 +
3881 +       /* unnecessary to support mmap_sem since symlink is not mmap-able */
3882 +       old_fs = get_fs();
3883 +       set_fs(KERNEL_DS);
3884 +       symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
3885 +       err = symlen;
3886 +       set_fs(old_fs);
3887 +
3888 +       if (symlen > 0) {
3889 +               sym.k[symlen] = 0;
3890 +               err = vfsub_symlink(h_dir, h_path, sym.k);
3891 +       }
3892 +       free_page((unsigned long)sym.k);
3893 +
3894 +out:
3895 +       return err;
3896 +}
3897 +
3898 +static noinline_for_stack
3899 +int cpup_entry(struct au_cpup_basic *basic, unsigned int flags,
3900 +              struct dentry *dst_parent, struct au_pin *pin,
3901 +              struct au_cpup_reg_attr *h_src_attr)
3902 +{
3903 +       int err;
3904 +       umode_t mode;
3905 +       unsigned int mnt_flags;
3906 +       unsigned char isdir;
3907 +       const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME);
3908 +       struct au_dtime dt;
3909 +       struct path h_path;
3910 +       struct dentry *h_src, *h_dst, *h_parent;
3911 +       struct inode *h_inode, *h_dir;
3912 +       struct super_block *sb;
3913 +
3914 +       /* bsrc branch can be ro/rw. */
3915 +       h_src = au_h_dptr(basic->dentry, basic->bsrc);
3916 +       h_inode = h_src->d_inode;
3917 +       AuDebugOn(h_inode != au_h_iptr(basic->dentry->d_inode, basic->bsrc));
3918 +
3919 +       /* try stopping to be referenced while we are creating */
3920 +       h_dst = au_h_dptr(basic->dentry, basic->bdst);
3921 +       if (au_ftest_cpup(flags, RENAME))
3922 +               AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
3923 +                                 AUFS_WH_PFX_LEN));
3924 +       h_parent = h_dst->d_parent; /* dir inode is locked */
3925 +       h_dir = h_parent->d_inode;
3926 +       IMustLock(h_dir);
3927 +       AuDebugOn(h_parent != h_dst->d_parent);
3928 +
3929 +       sb = basic->dentry->d_sb;
3930 +       h_path.mnt = au_sbr_mnt(sb, basic->bdst);
3931 +       if (do_dt) {
3932 +               h_path.dentry = h_parent;
3933 +               au_dtime_store(&dt, dst_parent, &h_path);
3934 +       }
3935 +       h_path.dentry = h_dst;
3936 +
3937 +       isdir = 0;
3938 +       mode = h_inode->i_mode;
3939 +       switch (mode & S_IFMT) {
3940 +       case S_IFREG:
3941 +               err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
3942 +                                  /*want_excl*/true);
3943 +               if (!err)
3944 +                       err = au_do_cpup_regular(basic, pin, h_src_attr);
3945 +               break;
3946 +       case S_IFDIR:
3947 +               isdir = 1;
3948 +               err = vfsub_mkdir(h_dir, &h_path, mode);
3949 +               if (!err) {
3950 +                       /*
3951 +                        * strange behaviour from the users view,
3952 +                        * particularry setattr case
3953 +                        */
3954 +                       if (au_ibstart(dst_parent->d_inode) == basic->bdst)
3955 +                               au_cpup_attr_nlink(dst_parent->d_inode,
3956 +                                                  /*force*/1);
3957 +                       au_cpup_attr_nlink(basic->dentry->d_inode, /*force*/1);
3958 +               }
3959 +               break;
3960 +       case S_IFLNK:
3961 +               err = au_do_cpup_symlink(&h_path, h_src, h_dir);
3962 +               break;
3963 +       case S_IFCHR:
3964 +       case S_IFBLK:
3965 +               AuDebugOn(!capable(CAP_MKNOD));
3966 +               /*FALLTHROUGH*/
3967 +       case S_IFIFO:
3968 +       case S_IFSOCK:
3969 +               err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
3970 +               break;
3971 +       default:
3972 +               AuIOErr("Unknown inode type 0%o\n", mode);
3973 +               err = -EIO;
3974 +       }
3975 +
3976 +       mnt_flags = au_mntflags(sb);
3977 +       if (!au_opt_test(mnt_flags, UDBA_NONE)
3978 +           && !isdir
3979 +           && au_opt_test(mnt_flags, XINO)
3980 +           && h_inode->i_nlink == 1
3981 +           /* todo: unnecessary? */
3982 +           /* && basic->dentry->d_inode->i_nlink == 1 */
3983 +           && basic->bdst < basic->bsrc
3984 +           && !au_ftest_cpup(flags, KEEPLINO))
3985 +               au_xino_write(sb, basic->bsrc, h_inode->i_ino, /*ino*/0);
3986 +               /* ignore this error */
3987 +
3988 +       if (do_dt)
3989 +               au_dtime_revert(&dt);
3990 +       return err;
3991 +}
3992 +
3993 +static int au_do_ren_after_cpup(struct dentry *dentry, aufs_bindex_t bdst,
3994 +                               struct path *h_path)
3995 +{
3996 +       int err;
3997 +       struct dentry *h_dentry, *h_parent;
3998 +       struct inode *h_dir;
3999 +
4000 +       h_dentry = dget(au_h_dptr(dentry, bdst));
4001 +       au_set_h_dptr(dentry, bdst, NULL);
4002 +       err = au_lkup_neg(dentry, bdst, /*wh*/0);
4003 +       if (unlikely(err)) {
4004 +               au_set_h_dptr(dentry, bdst, h_dentry);
4005 +               goto out;
4006 +       }
4007 +
4008 +       h_path->dentry = dget(au_h_dptr(dentry, bdst));
4009 +       au_set_h_dptr(dentry, bdst, h_dentry);
4010 +       h_parent = h_dentry->d_parent; /* dir inode is locked */
4011 +       h_dir = h_parent->d_inode;
4012 +       IMustLock(h_dir);
4013 +       AuDbg("%.*s %.*s\n", AuDLNPair(h_dentry), AuDLNPair(h_path->dentry));
4014 +       err = vfsub_rename(h_dir, h_dentry, h_dir, h_path);
4015 +       dput(h_path->dentry);
4016 +
4017 +out:
4018 +       return err;
4019 +}
4020 +
4021 +/*
4022 + * copyup the @dentry from @bsrc to @bdst.
4023 + * the caller must set the both of lower dentries.
4024 + * @len is for truncating when it is -1 copyup the entire file.
4025 + * in link/rename cases, @dst_parent may be different from the real one.
4026 + */
4027 +static int au_cpup_single(struct au_cpup_basic *basic, unsigned int flags,
4028 +                         struct dentry *dst_parent, struct au_pin *pin)
4029 +{
4030 +       int err, rerr;
4031 +       aufs_bindex_t old_ibstart;
4032 +       unsigned char isdir, plink;
4033 +       struct au_dtime dt;
4034 +       struct path h_path;
4035 +       struct dentry *h_src, *h_dst, *h_parent;
4036 +       struct inode *dst_inode, *h_dir, *inode;
4037 +       struct super_block *sb;
4038 +       struct au_branch *br;
4039 +       struct au_cpup_reg_attr h_src_attr = {
4040 +               .valid = 0
4041 +       };
4042 +
4043 +       AuDebugOn(basic->bsrc <= basic->bdst);
4044 +
4045 +       sb = basic->dentry->d_sb;
4046 +       br = au_sbr(sb, basic->bdst);
4047 +       h_path.mnt = au_br_mnt(br);
4048 +       h_dst = au_h_dptr(basic->dentry, basic->bdst);
4049 +       h_parent = h_dst->d_parent; /* dir inode is locked */
4050 +       h_dir = h_parent->d_inode;
4051 +       IMustLock(h_dir);
4052 +
4053 +       h_src = au_h_dptr(basic->dentry, basic->bsrc);
4054 +       inode = basic->dentry->d_inode;
4055 +
4056 +       if (!dst_parent)
4057 +               dst_parent = dget_parent(basic->dentry);
4058 +       else
4059 +               dget(dst_parent);
4060 +
4061 +       plink = !!au_opt_test(au_mntflags(sb), PLINK);
4062 +       dst_inode = au_h_iptr(inode, basic->bdst);
4063 +       if (dst_inode) {
4064 +               if (unlikely(!plink)) {
4065 +                       err = -EIO;
4066 +                       AuIOErr("hi%lu(i%lu) exists on b%d "
4067 +                               "but plink is disabled\n",
4068 +                               dst_inode->i_ino, inode->i_ino, basic->bdst);
4069 +                       goto out;
4070 +               }
4071 +
4072 +               if (dst_inode->i_nlink) {
4073 +                       const int do_dt = au_ftest_cpup(flags, DTIME);
4074 +
4075 +                       h_src = au_plink_lkup(inode, basic->bdst);
4076 +                       err = PTR_ERR(h_src);
4077 +                       if (IS_ERR(h_src))
4078 +                               goto out;
4079 +                       if (unlikely(!h_src->d_inode)) {
4080 +                               err = -EIO;
4081 +                               AuIOErr("i%lu exists on a upper branch "
4082 +                                       "but not pseudo-linked\n",
4083 +                                       inode->i_ino);
4084 +                               dput(h_src);
4085 +                               goto out;
4086 +                       }
4087 +
4088 +                       if (do_dt) {
4089 +                               h_path.dentry = h_parent;
4090 +                               au_dtime_store(&dt, dst_parent, &h_path);
4091 +                       }
4092 +
4093 +                       h_path.dentry = h_dst;
4094 +                       err = vfsub_link(h_src, h_dir, &h_path);
4095 +                       if (!err && au_ftest_cpup(flags, RENAME))
4096 +                               err = au_do_ren_after_cpup
4097 +                                       (basic->dentry, basic->bdst, &h_path);
4098 +                       if (do_dt)
4099 +                               au_dtime_revert(&dt);
4100 +                       dput(h_src);
4101 +                       goto out;
4102 +               } else
4103 +                       /* todo: cpup_wh_file? */
4104 +                       /* udba work */
4105 +                       au_update_ibrange(inode, /*do_put_zero*/1);
4106 +       }
4107 +
4108 +       isdir = S_ISDIR(inode->i_mode);
4109 +       old_ibstart = au_ibstart(inode);
4110 +       err = cpup_entry(basic, flags, dst_parent, pin, &h_src_attr);
4111 +       if (unlikely(err))
4112 +               goto out_rev;
4113 +       dst_inode = h_dst->d_inode;
4114 +       mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
4115 +       /* todo: necessary? */
4116 +       /* au_pin_hdir_unlock(pin); */
4117 +
4118 +       err = cpup_iattr(basic->dentry, basic->bdst, h_src, &h_src_attr);
4119 +       if (unlikely(err)) {
4120 +               /* todo: necessary? */
4121 +               /* au_pin_hdir_relock(pin); */ /* ignore an error */
4122 +               mutex_unlock(&dst_inode->i_mutex);
4123 +               goto out_rev;
4124 +       }
4125 +
4126 +       if (basic->bdst < old_ibstart) {
4127 +               if (S_ISREG(inode->i_mode)) {
4128 +                       err = au_dy_iaop(inode, basic->bdst, dst_inode);
4129 +                       if (unlikely(err)) {
4130 +                               /* au_pin_hdir_relock(pin); ignore an error */
4131 +                               mutex_unlock(&dst_inode->i_mutex);
4132 +                               goto out_rev;
4133 +                       }
4134 +               }
4135 +               au_set_ibstart(inode, basic->bdst);
4136 +       }
4137 +       au_set_h_iptr(inode, basic->bdst, au_igrab(dst_inode),
4138 +                     au_hi_flags(inode, isdir));
4139 +
4140 +       /* todo: necessary? */
4141 +       /* err = au_pin_hdir_relock(pin); */
4142 +       mutex_unlock(&dst_inode->i_mutex);
4143 +       if (unlikely(err))
4144 +               goto out_rev;
4145 +
4146 +       if (!isdir
4147 +           && h_src->d_inode->i_nlink > 1
4148 +           && plink)
4149 +               au_plink_append(inode, basic->bdst, h_dst);
4150 +
4151 +       if (au_ftest_cpup(flags, RENAME)) {
4152 +               h_path.dentry = h_dst;
4153 +               err = au_do_ren_after_cpup(basic->dentry, basic->bdst, &h_path);
4154 +       }
4155 +       if (!err)
4156 +               goto out; /* success */
4157 +
4158 +       /* revert */
4159 +out_rev:
4160 +       h_path.dentry = h_parent;
4161 +       au_dtime_store(&dt, dst_parent, &h_path);
4162 +       h_path.dentry = h_dst;
4163 +       rerr = 0;
4164 +       if (h_dst->d_inode) {
4165 +               if (!isdir)
4166 +                       rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
4167 +               else
4168 +                       rerr = vfsub_rmdir(h_dir, &h_path);
4169 +       }
4170 +       au_dtime_revert(&dt);
4171 +       if (rerr) {
4172 +               AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
4173 +               err = -EIO;
4174 +       }
4175 +out:
4176 +       dput(dst_parent);
4177 +       return err;
4178 +}
4179 +
4180 +struct au_cpup_single_args {
4181 +       int *errp;
4182 +       struct au_cpup_basic *basic;
4183 +       unsigned int flags;
4184 +       struct dentry *dst_parent;
4185 +       struct au_pin *pin;
4186 +};
4187 +
4188 +static void au_call_cpup_single(void *args)
4189 +{
4190 +       struct au_cpup_single_args *a = args;
4191 +
4192 +       au_pin_hdir_acquire_nest(a->pin);
4193 +       *a->errp = au_cpup_single(a->basic, a->flags, a->dst_parent, a->pin);
4194 +       au_pin_hdir_release(a->pin);
4195 +}
4196 +
4197 +/*
4198 + * prevent SIGXFSZ in copy-up.
4199 + * testing CAP_MKNOD is for generic fs,
4200 + * but CAP_FSETID is for xfs only, currently.
4201 + */
4202 +static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
4203 +{
4204 +       int do_sio;
4205 +       struct super_block *sb;
4206 +       struct inode *h_dir;
4207 +
4208 +       do_sio = 0;
4209 +       sb = au_pinned_parent(pin)->d_sb;
4210 +       if (!au_wkq_test()
4211 +           && (!au_sbi(sb)->si_plink_maint_pid
4212 +               || au_plink_maint(sb, AuLock_NOPLM))) {
4213 +               switch (mode & S_IFMT) {
4214 +               case S_IFREG:
4215 +                       /* no condition about RLIMIT_FSIZE and the file size */
4216 +                       do_sio = 1;
4217 +                       break;
4218 +               case S_IFCHR:
4219 +               case S_IFBLK:
4220 +                       do_sio = !capable(CAP_MKNOD);
4221 +                       break;
4222 +               }
4223 +               if (!do_sio)
4224 +                       do_sio = ((mode & (S_ISUID | S_ISGID))
4225 +                                 && !capable(CAP_FSETID));
4226 +               /* this workaround may be removed in the future */
4227 +               if (!do_sio) {
4228 +                       h_dir = au_pinned_h_dir(pin);
4229 +                       do_sio = h_dir->i_mode & S_ISVTX;
4230 +               }
4231 +       }
4232 +
4233 +       return do_sio;
4234 +}
4235 +
4236 +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
4237 +                      aufs_bindex_t bsrc, loff_t len, unsigned int flags,
4238 +                      struct dentry *dst_parent, struct au_pin *pin)
4239 +{
4240 +       int err, wkq_err;
4241 +       struct dentry *h_dentry;
4242 +       struct au_cpup_basic basic = {
4243 +               .dentry = dentry,
4244 +               .bdst   = bdst,
4245 +               .bsrc   = bsrc,
4246 +               .len    = len
4247 +       };
4248 +
4249 +       h_dentry = au_h_dptr(dentry, bsrc);
4250 +       if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
4251 +               err = au_cpup_single(&basic, flags, dst_parent, pin);
4252 +       else {
4253 +               struct au_cpup_single_args args = {
4254 +                       .errp           = &err,
4255 +                       .basic          = &basic,
4256 +                       .flags          = flags,
4257 +                       .dst_parent     = dst_parent,
4258 +                       .pin            = pin
4259 +               };
4260 +               wkq_err = au_wkq_wait(au_call_cpup_single, &args);
4261 +               if (unlikely(wkq_err))
4262 +                       err = wkq_err;
4263 +       }
4264 +
4265 +       return err;
4266 +}
4267 +
4268 +/*
4269 + * copyup the @dentry from the first active lower branch to @bdst,
4270 + * using au_cpup_single().
4271 + */
4272 +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4273 +                         unsigned int flags, struct au_pin *pin)
4274 +{
4275 +       int err;
4276 +       aufs_bindex_t bsrc, bend;
4277 +       struct dentry *h_dentry;
4278 +
4279 +       DiMustWriteLock(dentry);
4280 +       bend = au_dbend(dentry);
4281 +       for (bsrc = bdst + 1; bsrc <= bend; bsrc++) {
4282 +               h_dentry = au_h_dptr(dentry, bsrc);
4283 +               if (h_dentry) {
4284 +                       AuDebugOn(!h_dentry->d_inode);
4285 +                       break;
4286 +               }
4287 +       }
4288 +       AuDebugOn(bsrc > bend);
4289 +
4290 +       err = au_lkup_neg(dentry, bdst, /*wh*/1);
4291 +       if (!err) {
4292 +               struct au_cpup_basic basic = {
4293 +                       .dentry = dentry,
4294 +                       .bdst   = bdst,
4295 +                       .bsrc   = bsrc,
4296 +                       .len    = len
4297 +               };
4298 +               err = au_cpup_single(&basic, flags | AuCpup_RENAME, NULL, pin);
4299 +               if (!err)
4300 +                       return 0; /* success */
4301 +
4302 +               /* revert */
4303 +               au_set_h_dptr(dentry, bdst, NULL);
4304 +               au_set_dbstart(dentry, bsrc);
4305 +       }
4306 +
4307 +       return err;
4308 +}
4309 +
4310 +struct au_cpup_simple_args {
4311 +       int *errp;
4312 +       struct dentry *dentry;
4313 +       aufs_bindex_t bdst;
4314 +       loff_t len;
4315 +       unsigned int flags;
4316 +       struct au_pin *pin;
4317 +};
4318 +
4319 +static void au_call_cpup_simple(void *args)
4320 +{
4321 +       struct au_cpup_simple_args *a = args;
4322 +
4323 +       au_pin_hdir_acquire_nest(a->pin);
4324 +       *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags, a->pin);
4325 +       au_pin_hdir_release(a->pin);
4326 +}
4327 +
4328 +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4329 +                      unsigned int flags, struct au_pin *pin)
4330 +{
4331 +       int err, wkq_err;
4332 +       struct dentry *parent;
4333 +       struct inode *h_dir;
4334 +
4335 +       parent = dget_parent(dentry);
4336 +       h_dir = au_h_iptr(parent->d_inode, bdst);
4337 +       if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
4338 +           && !au_cpup_sio_test(pin, dentry->d_inode->i_mode))
4339 +               err = au_cpup_simple(dentry, bdst, len, flags, pin);
4340 +       else {
4341 +               struct au_cpup_simple_args args = {
4342 +                       .errp           = &err,
4343 +                       .dentry         = dentry,
4344 +                       .bdst           = bdst,
4345 +                       .len            = len,
4346 +                       .flags          = flags,
4347 +                       .pin            = pin
4348 +               };
4349 +               wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
4350 +               if (unlikely(wkq_err))
4351 +                       err = wkq_err;
4352 +       }
4353 +
4354 +       dput(parent);
4355 +       return err;
4356 +}
4357 +
4358 +/* generalized cpup_simple() with h_open_pre/post() calls */
4359 +int au_sio_cpup_simple_h_open(struct dentry *dentry, aufs_bindex_t bdst,
4360 +                             loff_t len, unsigned int flags,
4361 +                             struct au_pin *pin, aufs_bindex_t bsrc)
4362 +{
4363 +       int err;
4364 +       struct file *h_file;
4365 +
4366 +       h_file = au_h_open_pre(dentry, bsrc);
4367 +       if (IS_ERR(h_file))
4368 +               err = PTR_ERR(h_file);
4369 +       else {
4370 +               err = au_sio_cpup_simple(dentry, bdst, len, flags, pin);
4371 +               au_h_open_post(dentry, bsrc, h_file);
4372 +       }
4373 +
4374 +       return err;
4375 +}
4376 +
4377 +/* ---------------------------------------------------------------------- */
4378 +
4379 +/*
4380 + * copyup the deleted file for writing.
4381 + */
4382 +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst,
4383 +                        struct dentry *wh_dentry, struct file *file,
4384 +                        loff_t len, struct au_pin *pin)
4385 +{
4386 +       int err;
4387 +       struct au_cpup_basic basic = {
4388 +               .dentry = dentry,
4389 +               .bdst   = bdst,
4390 +               .bsrc   = -1,
4391 +               .len    = len
4392 +       };
4393 +       struct au_dinfo *dinfo;
4394 +       struct dentry *h_d_dst, *h_d_start;
4395 +       struct au_hdentry *hdp;
4396 +
4397 +       dinfo = au_di(dentry);
4398 +       AuRwMustWriteLock(&dinfo->di_rwsem);
4399 +
4400 +       basic.bsrc = dinfo->di_bstart;
4401 +       hdp = dinfo->di_hdentry;
4402 +       h_d_dst = hdp[0 + bdst].hd_dentry;
4403 +       dinfo->di_bstart = bdst;
4404 +       hdp[0 + bdst].hd_dentry = wh_dentry;
4405 +       h_d_start = NULL;
4406 +       if (file) {
4407 +               h_d_start = hdp[0 + basic.bsrc].hd_dentry;
4408 +               hdp[0 + basic.bsrc].hd_dentry = au_hf_top(file)->f_dentry;
4409 +       }
4410 +       err = au_cpup_single(&basic, !AuCpup_DTIME, /*h_parent*/NULL, pin);
4411 +       if (file) {
4412 +               if (!err)
4413 +                       err = au_reopen_nondir(file);
4414 +               hdp[0 + basic.bsrc].hd_dentry = h_d_start;
4415 +       }
4416 +       hdp[0 + bdst].hd_dentry = h_d_dst;
4417 +       dinfo->di_bstart = basic.bsrc;
4418 +
4419 +       return err;
4420 +}
4421 +
4422 +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4423 +                     struct file *file, struct au_pin *pin)
4424 +{
4425 +       int err;
4426 +       struct au_dtime dt;
4427 +       struct dentry *parent, *h_parent, *wh_dentry;
4428 +       struct au_branch *br;
4429 +       struct path h_path;
4430 +
4431 +       br = au_sbr(dentry->d_sb, bdst);
4432 +       parent = dget_parent(dentry);
4433 +       h_parent = au_h_dptr(parent, bdst);
4434 +       wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
4435 +       err = PTR_ERR(wh_dentry);
4436 +       if (IS_ERR(wh_dentry))
4437 +               goto out;
4438 +
4439 +       h_path.dentry = h_parent;
4440 +       h_path.mnt = au_br_mnt(br);
4441 +       au_dtime_store(&dt, parent, &h_path);
4442 +       err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len, pin);
4443 +       if (unlikely(err))
4444 +               goto out_wh;
4445 +
4446 +       dget(wh_dentry);
4447 +       h_path.dentry = wh_dentry;
4448 +       if (!S_ISDIR(wh_dentry->d_inode->i_mode))
4449 +               err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0);
4450 +       else
4451 +               err = vfsub_rmdir(h_parent->d_inode, &h_path);
4452 +       if (unlikely(err)) {
4453 +               AuIOErr("failed remove copied-up tmp file %.*s(%d)\n",
4454 +                       AuDLNPair(wh_dentry), err);
4455 +               err = -EIO;
4456 +       }
4457 +       au_dtime_revert(&dt);
4458 +       au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
4459 +
4460 +out_wh:
4461 +       dput(wh_dentry);
4462 +out:
4463 +       dput(parent);
4464 +       return err;
4465 +}
4466 +
4467 +struct au_cpup_wh_args {
4468 +       int *errp;
4469 +       struct dentry *dentry;
4470 +       aufs_bindex_t bdst;
4471 +       loff_t len;
4472 +       struct file *file;
4473 +       struct au_pin *pin;
4474 +};
4475 +
4476 +static void au_call_cpup_wh(void *args)
4477 +{
4478 +       struct au_cpup_wh_args *a = args;
4479 +
4480 +       au_pin_hdir_acquire_nest(a->pin);
4481 +       *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file, a->pin);
4482 +       au_pin_hdir_release(a->pin);
4483 +}
4484 +
4485 +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4486 +                  struct file *file, struct au_pin *pin)
4487 +{
4488 +       int err, wkq_err;
4489 +       struct dentry *parent, *h_orph, *h_parent, *h_dentry;
4490 +       struct inode *dir, *h_dir, *h_tmpdir;
4491 +       struct au_wbr *wbr;
4492 +       struct au_pin wh_pin;
4493 +
4494 +       parent = dget_parent(dentry);
4495 +       dir = parent->d_inode;
4496 +       h_orph = NULL;
4497 +       h_parent = NULL;
4498 +       h_dir = au_igrab(au_h_iptr(dir, bdst));
4499 +       h_tmpdir = h_dir;
4500 +       if (!h_dir->i_nlink) {
4501 +               wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
4502 +               h_orph = wbr->wbr_orph;
4503 +
4504 +               h_parent = dget(au_h_dptr(parent, bdst));
4505 +               au_set_h_dptr(parent, bdst, dget(h_orph));
4506 +               h_tmpdir = h_orph->d_inode;
4507 +               au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
4508 +
4509 +               if (file)
4510 +                       h_dentry = au_hf_top(file)->f_dentry;
4511 +               else
4512 +                       h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
4513 +               mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4514 +               /* todo: au_h_open_pre()? */
4515 +
4516 +               au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
4517 +                           AuLsc_I_PARENT3, pin->udba, AuPin_DI_LOCKED);
4518 +               pin = &wh_pin;
4519 +       }
4520 +
4521 +       if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
4522 +           && !au_cpup_sio_test(pin, dentry->d_inode->i_mode))
4523 +               err = au_cpup_wh(dentry, bdst, len, file, pin);
4524 +       else {
4525 +               struct au_cpup_wh_args args = {
4526 +                       .errp   = &err,
4527 +                       .dentry = dentry,
4528 +                       .bdst   = bdst,
4529 +                       .len    = len,
4530 +                       .file   = file,
4531 +                       .pin    = pin
4532 +               };
4533 +               wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
4534 +               if (unlikely(wkq_err))
4535 +                       err = wkq_err;
4536 +       }
4537 +
4538 +       if (h_orph) {
4539 +               mutex_unlock(&h_tmpdir->i_mutex);
4540 +               /* todo: au_h_open_post()? */
4541 +               au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
4542 +               au_set_h_dptr(parent, bdst, h_parent);
4543 +       }
4544 +       iput(h_dir);
4545 +       dput(parent);
4546 +
4547 +       return err;
4548 +}
4549 +
4550 +/* ---------------------------------------------------------------------- */
4551 +
4552 +/*
4553 + * generic routine for both of copy-up and copy-down.
4554 + */
4555 +/* cf. revalidate function in file.c */
4556 +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4557 +              int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
4558 +                        struct au_pin *pin,
4559 +                        struct dentry *h_parent, void *arg),
4560 +              void *arg)
4561 +{
4562 +       int err;
4563 +       struct au_pin pin;
4564 +       struct dentry *d, *parent, *h_parent, *real_parent;
4565 +
4566 +       err = 0;
4567 +       parent = dget_parent(dentry);
4568 +       if (IS_ROOT(parent))
4569 +               goto out;
4570 +
4571 +       au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
4572 +                   au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
4573 +
4574 +       /* do not use au_dpage */
4575 +       real_parent = parent;
4576 +       while (1) {
4577 +               dput(parent);
4578 +               parent = dget_parent(dentry);
4579 +               h_parent = au_h_dptr(parent, bdst);
4580 +               if (h_parent)
4581 +                       goto out; /* success */
4582 +
4583 +               /* find top dir which is necessary to cpup */
4584 +               do {
4585 +                       d = parent;
4586 +                       dput(parent);
4587 +                       parent = dget_parent(d);
4588 +                       di_read_lock_parent3(parent, !AuLock_IR);
4589 +                       h_parent = au_h_dptr(parent, bdst);
4590 +                       di_read_unlock(parent, !AuLock_IR);
4591 +               } while (!h_parent);
4592 +
4593 +               if (d != real_parent)
4594 +                       di_write_lock_child3(d);
4595 +
4596 +               /* somebody else might create while we were sleeping */
4597 +               if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
4598 +                       if (au_h_dptr(d, bdst))
4599 +                               au_update_dbstart(d);
4600 +
4601 +                       au_pin_set_dentry(&pin, d);
4602 +                       err = au_do_pin(&pin);
4603 +                       if (!err) {
4604 +                               err = cp(d, bdst, &pin, h_parent, arg);
4605 +                               au_unpin(&pin);
4606 +                       }
4607 +               }
4608 +
4609 +               if (d != real_parent)
4610 +                       di_write_unlock(d);
4611 +               if (unlikely(err))
4612 +                       break;
4613 +       }
4614 +
4615 +out:
4616 +       dput(parent);
4617 +       return err;
4618 +}
4619 +
4620 +static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
4621 +                      struct au_pin *pin,
4622 +                      struct dentry *h_parent __maybe_unused ,
4623 +                      void *arg __maybe_unused)
4624 +{
4625 +       return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME, pin);
4626 +}
4627 +
4628 +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4629 +{
4630 +       return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
4631 +}
4632 +
4633 +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
4634 +{
4635 +       int err;
4636 +       struct dentry *parent;
4637 +       struct inode *dir;
4638 +
4639 +       parent = dget_parent(dentry);
4640 +       dir = parent->d_inode;
4641 +       err = 0;
4642 +       if (au_h_iptr(dir, bdst))
4643 +               goto out;
4644 +
4645 +       di_read_unlock(parent, AuLock_IR);
4646 +       di_write_lock_parent(parent);
4647 +       /* someone else might change our inode while we were sleeping */
4648 +       if (!au_h_iptr(dir, bdst))
4649 +               err = au_cpup_dirs(dentry, bdst);
4650 +       di_downgrade_lock(parent, AuLock_IR);
4651 +
4652 +out:
4653 +       dput(parent);
4654 +       return err;
4655 +}
4656 diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
4657 --- /usr/share/empty/fs/aufs/cpup.h     1970-01-01 01:00:00.000000000 +0100
4658 +++ linux/fs/aufs/cpup.h        2013-07-30 22:42:46.232612606 +0200
4659 @@ -0,0 +1,87 @@
4660 +/*
4661 + * Copyright (C) 2005-2013 Junjiro R. Okajima
4662 + *
4663 + * This program, aufs is free software; you can redistribute it and/or modify
4664 + * it under the terms of the GNU General Public License as published by
4665 + * the Free Software Foundation; either version 2 of the License, or
4666 + * (at your option) any later version.
4667 + *
4668 + * This program is distributed in the hope that it will be useful,
4669 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4670 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4671 + * GNU General Public License for more details.
4672 + *
4673 + * You should have received a copy of the GNU General Public License
4674 + * along with this program; if not, write to the Free Software
4675 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
4676 + */
4677 +
4678 +/*
4679 + * copy-up/down functions
4680 + */
4681 +
4682 +#ifndef __AUFS_CPUP_H__
4683 +#define __AUFS_CPUP_H__
4684 +
4685 +#ifdef __KERNEL__
4686 +
4687 +#include <linux/path.h>
4688 +
4689 +struct inode;
4690 +struct file;
4691 +struct au_pin;
4692 +
4693 +void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
4694 +void au_cpup_attr_timesizes(struct inode *inode);
4695 +void au_cpup_attr_nlink(struct inode *inode, int force);
4696 +void au_cpup_attr_changeable(struct inode *inode);
4697 +void au_cpup_igen(struct inode *inode, struct inode *h_inode);
4698 +void au_cpup_attr_all(struct inode *inode, int force);
4699 +
4700 +/* ---------------------------------------------------------------------- */
4701 +
4702 +/* cpup flags */
4703 +#define AuCpup_DTIME   1               /* do dtime_store/revert */
4704 +#define AuCpup_KEEPLINO        (1 << 1)        /* do not clear the lower xino,
4705 +                                          for link(2) */
4706 +#define AuCpup_RENAME  (1 << 2)        /* rename after cpup */
4707 +#define au_ftest_cpup(flags, name)     ((flags) & AuCpup_##name)
4708 +#define au_fset_cpup(flags, name) \
4709 +       do { (flags) |= AuCpup_##name; } while (0)
4710 +#define au_fclr_cpup(flags, name) \
4711 +       do { (flags) &= ~AuCpup_##name; } while (0)
4712 +
4713 +int au_copy_file(struct file *dst, struct file *src, loff_t len);
4714 +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
4715 +                      aufs_bindex_t bsrc, loff_t len, unsigned int flags,
4716 +                      struct dentry *dst_parent, struct au_pin *pin);
4717 +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4718 +                      unsigned int flags, struct au_pin *pin);
4719 +int au_sio_cpup_simple_h_open(struct dentry *dentry, aufs_bindex_t bdst,
4720 +                             loff_t len, unsigned int flags,
4721 +                             struct au_pin *pin, aufs_bindex_t bsrc);
4722 +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
4723 +                  struct file *file, struct au_pin *pin);
4724 +
4725 +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4726 +              int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
4727 +                        struct au_pin *pin,
4728 +                        struct dentry *h_parent, void *arg),
4729 +              void *arg);
4730 +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4731 +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
4732 +
4733 +/* ---------------------------------------------------------------------- */
4734 +
4735 +/* keep timestamps when copyup */
4736 +struct au_dtime {
4737 +       struct dentry *dt_dentry;
4738 +       struct path dt_h_path;
4739 +       struct timespec dt_atime, dt_mtime;
4740 +};
4741 +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4742 +                   struct path *h_path);
4743 +void au_dtime_revert(struct au_dtime *dt);
4744 +
4745 +#endif /* __KERNEL__ */
4746 +#endif /* __AUFS_CPUP_H__ */
4747 diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
4748 --- /usr/share/empty/fs/aufs/dbgaufs.c  1970-01-01 01:00:00.000000000 +0100
4749 +++ linux/fs/aufs/dbgaufs.c     2013-07-06 13:20:47.740198107 +0200
4750 @@ -0,0 +1,433 @@
4751 +/*
4752 + * Copyright (C) 2005-2013 Junjiro R. Okajima
4753 + *
4754 + * This program, aufs is free software; you can redistribute it and/or modify
4755 + * it under the terms of the GNU General Public License as published by
4756 + * the Free Software Foundation; either version 2 of the License, or
4757 + * (at your option) any later version.
4758 + *
4759 + * This program is distributed in the hope that it will be useful,
4760 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4761 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4762 + * GNU General Public License for more details.
4763 + *
4764 + * You should have received a copy of the GNU General Public License
4765 + * along with this program; if not, write to the Free Software
4766 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
4767 + */
4768 +
4769 +/*
4770 + * debugfs interface
4771 + */
4772 +
4773 +#include <linux/debugfs.h>
4774 +#include "aufs.h"
4775 +
4776 +#ifndef CONFIG_SYSFS
4777 +#error DEBUG_FS depends upon SYSFS
4778 +#endif
4779 +
4780 +static struct dentry *dbgaufs;
4781 +static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
4782 +
4783 +/* 20 is max digits length of ulong 64 */
4784 +struct dbgaufs_arg {
4785 +       int n;
4786 +       char a[20 * 4];
4787 +};
4788 +
4789 +/*
4790 + * common function for all XINO files
4791 + */
4792 +static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
4793 +                             struct file *file)
4794 +{
4795 +       kfree(file->private_data);
4796 +       return 0;
4797 +}
4798 +
4799 +static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
4800 +{
4801 +       int err;
4802 +       struct kstat st;
4803 +       struct dbgaufs_arg *p;
4804 +
4805 +       err = -ENOMEM;
4806 +       p = kmalloc(sizeof(*p), GFP_NOFS);
4807 +       if (unlikely(!p))
4808 +               goto out;
4809 +
4810 +       err = 0;
4811 +       p->n = 0;
4812 +       file->private_data = p;
4813 +       if (!xf)
4814 +               goto out;
4815 +
4816 +       err = vfs_getattr(&xf->f_path, &st);
4817 +       if (!err) {
4818 +               if (do_fcnt)
4819 +                       p->n = snprintf
4820 +                               (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
4821 +                                (long)file_count(xf), st.blocks, st.blksize,
4822 +                                (long long)st.size);
4823 +               else
4824 +                       p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
4825 +                                       st.blocks, st.blksize,
4826 +                                       (long long)st.size);
4827 +               AuDebugOn(p->n >= sizeof(p->a));
4828 +       } else {
4829 +               p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
4830 +               err = 0;
4831 +       }
4832 +
4833 +out:
4834 +       return err;
4835 +
4836 +}
4837 +
4838 +static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
4839 +                              size_t count, loff_t *ppos)
4840 +{
4841 +       struct dbgaufs_arg *p;
4842 +
4843 +       p = file->private_data;
4844 +       return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
4845 +}
4846 +
4847 +/* ---------------------------------------------------------------------- */
4848 +
4849 +struct dbgaufs_plink_arg {
4850 +       int n;
4851 +       char a[];
4852 +};
4853 +
4854 +static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
4855 +                                struct file *file)
4856 +{
4857 +       free_page((unsigned long)file->private_data);
4858 +       return 0;
4859 +}
4860 +
4861 +static int dbgaufs_plink_open(struct inode *inode, struct file *file)
4862 +{
4863 +       int err, i, limit;
4864 +       unsigned long n, sum;
4865 +       struct dbgaufs_plink_arg *p;
4866 +       struct au_sbinfo *sbinfo;
4867 +       struct super_block *sb;
4868 +       struct au_sphlhead *sphl;
4869 +
4870 +       err = -ENOMEM;
4871 +       p = (void *)get_zeroed_page(GFP_NOFS);
4872 +       if (unlikely(!p))
4873 +               goto out;
4874 +
4875 +       err = -EFBIG;
4876 +       sbinfo = inode->i_private;
4877 +       sb = sbinfo->si_sb;
4878 +       si_noflush_read_lock(sb);
4879 +       if (au_opt_test(au_mntflags(sb), PLINK)) {
4880 +               limit = PAGE_SIZE - sizeof(p->n);
4881 +
4882 +               /* the number of buckets */
4883 +               n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
4884 +               p->n += n;
4885 +               limit -= n;
4886 +
4887 +               sum = 0;
4888 +               for (i = 0, sphl = sbinfo->si_plink;
4889 +                    i < AuPlink_NHASH;
4890 +                    i++, sphl++) {
4891 +                       n = au_sphl_count(sphl);
4892 +                       sum += n;
4893 +
4894 +                       n = snprintf(p->a + p->n, limit, "%lu ", n);
4895 +                       p->n += n;
4896 +                       limit -= n;
4897 +                       if (unlikely(limit <= 0))
4898 +                               goto out_free;
4899 +               }
4900 +               p->a[p->n - 1] = '\n';
4901 +
4902 +               /* the sum of plinks */
4903 +               n = snprintf(p->a + p->n, limit, "%lu\n", sum);
4904 +               p->n += n;
4905 +               limit -= n;
4906 +               if (unlikely(limit <= 0))
4907 +                       goto out_free;
4908 +       } else {
4909 +#define str "1\n0\n0\n"
4910 +               p->n = sizeof(str) - 1;
4911 +               strcpy(p->a, str);
4912 +#undef str
4913 +       }
4914 +       si_read_unlock(sb);
4915 +
4916 +       err = 0;
4917 +       file->private_data = p;
4918 +       goto out; /* success */
4919 +
4920 +out_free:
4921 +       free_page((unsigned long)p);
4922 +out:
4923 +       return err;
4924 +}
4925 +
4926 +static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
4927 +                                 size_t count, loff_t *ppos)
4928 +{
4929 +       struct dbgaufs_plink_arg *p;
4930 +
4931 +       p = file->private_data;
4932 +       return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
4933 +}
4934 +
4935 +static const struct file_operations dbgaufs_plink_fop = {
4936 +       .owner          = THIS_MODULE,
4937 +       .open           = dbgaufs_plink_open,
4938 +       .release        = dbgaufs_plink_release,
4939 +       .read           = dbgaufs_plink_read
4940 +};
4941 +
4942 +/* ---------------------------------------------------------------------- */
4943 +
4944 +static int dbgaufs_xib_open(struct inode *inode, struct file *file)
4945 +{
4946 +       int err;
4947 +       struct au_sbinfo *sbinfo;
4948 +       struct super_block *sb;
4949 +
4950 +       sbinfo = inode->i_private;
4951 +       sb = sbinfo->si_sb;
4952 +       si_noflush_read_lock(sb);
4953 +       err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
4954 +       si_read_unlock(sb);
4955 +       return err;
4956 +}
4957 +
4958 +static const struct file_operations dbgaufs_xib_fop = {
4959 +       .owner          = THIS_MODULE,
4960 +       .open           = dbgaufs_xib_open,
4961 +       .release        = dbgaufs_xi_release,
4962 +       .read           = dbgaufs_xi_read
4963 +};
4964 +
4965 +/* ---------------------------------------------------------------------- */
4966 +
4967 +#define DbgaufsXi_PREFIX "xi"
4968 +
4969 +static int dbgaufs_xino_open(struct inode *inode, struct file *file)
4970 +{
4971 +       int err;
4972 +       long l;
4973 +       struct au_sbinfo *sbinfo;
4974 +       struct super_block *sb;
4975 +       struct file *xf;
4976 +       struct qstr *name;
4977 +
4978 +       err = -ENOENT;
4979 +       xf = NULL;
4980 +       name = &file->f_dentry->d_name;
4981 +       if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
4982 +                    || memcmp(name->name, DbgaufsXi_PREFIX,
4983 +                              sizeof(DbgaufsXi_PREFIX) - 1)))
4984 +               goto out;
4985 +       err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
4986 +       if (unlikely(err))
4987 +               goto out;
4988 +
4989 +       sbinfo = inode->i_private;
4990 +       sb = sbinfo->si_sb;
4991 +       si_noflush_read_lock(sb);
4992 +       if (l <= au_sbend(sb)) {
4993 +               xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
4994 +               err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
4995 +       } else
4996 +               err = -ENOENT;
4997 +       si_read_unlock(sb);
4998 +
4999 +out:
5000 +       return err;
5001 +}
5002 +
5003 +static const struct file_operations dbgaufs_xino_fop = {
5004 +       .owner          = THIS_MODULE,
5005 +       .open           = dbgaufs_xino_open,
5006 +       .release        = dbgaufs_xi_release,
5007 +       .read           = dbgaufs_xi_read
5008 +};
5009 +
5010 +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
5011 +{
5012 +       aufs_bindex_t bend;
5013 +       struct au_branch *br;
5014 +       struct au_xino_file *xi;
5015 +
5016 +       if (!au_sbi(sb)->si_dbgaufs)
5017 +               return;
5018 +
5019 +       bend = au_sbend(sb);
5020 +       for (; bindex <= bend; bindex++) {
5021 +               br = au_sbr(sb, bindex);
5022 +               xi = &br->br_xino;
5023 +               debugfs_remove(xi->xi_dbgaufs);
5024 +               xi->xi_dbgaufs = NULL;
5025 +       }
5026 +}
5027 +
5028 +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
5029 +{
5030 +       struct au_sbinfo *sbinfo;
5031 +       struct dentry *parent;
5032 +       struct au_branch *br;
5033 +       struct au_xino_file *xi;
5034 +       aufs_bindex_t bend;
5035 +       char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
5036 +
5037 +       sbinfo = au_sbi(sb);
5038 +       parent = sbinfo->si_dbgaufs;
5039 +       if (!parent)
5040 +               return;
5041 +
5042 +       bend = au_sbend(sb);
5043 +       for (; bindex <= bend; bindex++) {
5044 +               snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
5045 +               br = au_sbr(sb, bindex);
5046 +               xi = &br->br_xino;
5047 +               AuDebugOn(xi->xi_dbgaufs);
5048 +               xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
5049 +                                                    sbinfo, &dbgaufs_xino_fop);
5050 +               /* ignore an error */
5051 +               if (unlikely(!xi->xi_dbgaufs))
5052 +                       AuWarn1("failed %s under debugfs\n", name);
5053 +       }
5054 +}
5055 +
5056 +/* ---------------------------------------------------------------------- */
5057 +
5058 +#ifdef CONFIG_AUFS_EXPORT
5059 +static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
5060 +{
5061 +       int err;
5062 +       struct au_sbinfo *sbinfo;
5063 +       struct super_block *sb;
5064 +
5065 +       sbinfo = inode->i_private;
5066 +       sb = sbinfo->si_sb;
5067 +       si_noflush_read_lock(sb);
5068 +       err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
5069 +       si_read_unlock(sb);
5070 +       return err;
5071 +}
5072 +
5073 +static const struct file_operations dbgaufs_xigen_fop = {
5074 +       .owner          = THIS_MODULE,
5075 +       .open           = dbgaufs_xigen_open,
5076 +       .release        = dbgaufs_xi_release,
5077 +       .read           = dbgaufs_xi_read
5078 +};
5079 +
5080 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5081 +{
5082 +       int err;
5083 +
5084 +       /*
5085 +        * This function is a dynamic '__init' fucntion actually,
5086 +        * so the tiny check for si_rwsem is unnecessary.
5087 +        */
5088 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5089 +
5090 +       err = -EIO;
5091 +       sbinfo->si_dbgaufs_xigen = debugfs_create_file
5092 +               ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5093 +                &dbgaufs_xigen_fop);
5094 +       if (sbinfo->si_dbgaufs_xigen)
5095 +               err = 0;
5096 +
5097 +       return err;
5098 +}
5099 +#else
5100 +static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5101 +{
5102 +       return 0;
5103 +}
5104 +#endif /* CONFIG_AUFS_EXPORT */
5105 +
5106 +/* ---------------------------------------------------------------------- */
5107 +
5108 +void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
5109 +{
5110 +       /*
5111 +        * This function is a dynamic '__init' fucntion actually,
5112 +        * so the tiny check for si_rwsem is unnecessary.
5113 +        */
5114 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5115 +
5116 +       debugfs_remove_recursive(sbinfo->si_dbgaufs);
5117 +       sbinfo->si_dbgaufs = NULL;
5118 +       kobject_put(&sbinfo->si_kobj);
5119 +}
5120 +
5121 +int dbgaufs_si_init(struct au_sbinfo *sbinfo)
5122 +{
5123 +       int err;
5124 +       char name[SysaufsSiNameLen];
5125 +
5126 +       /*
5127 +        * This function is a dynamic '__init' fucntion actually,
5128 +        * so the tiny check for si_rwsem is unnecessary.
5129 +        */
5130 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5131 +
5132 +       err = -ENOENT;
5133 +       if (!dbgaufs) {
5134 +               AuErr1("/debug/aufs is uninitialized\n");
5135 +               goto out;
5136 +       }
5137 +
5138 +       err = -EIO;
5139 +       sysaufs_name(sbinfo, name);
5140 +       sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
5141 +       if (unlikely(!sbinfo->si_dbgaufs))
5142 +               goto out;
5143 +       kobject_get(&sbinfo->si_kobj);
5144 +
5145 +       sbinfo->si_dbgaufs_xib = debugfs_create_file
5146 +               ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5147 +                &dbgaufs_xib_fop);
5148 +       if (unlikely(!sbinfo->si_dbgaufs_xib))
5149 +               goto out_dir;
5150 +
5151 +       sbinfo->si_dbgaufs_plink = debugfs_create_file
5152 +               ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5153 +                &dbgaufs_plink_fop);
5154 +       if (unlikely(!sbinfo->si_dbgaufs_plink))
5155 +               goto out_dir;
5156 +
5157 +       err = dbgaufs_xigen_init(sbinfo);
5158 +       if (!err)
5159 +               goto out; /* success */
5160 +
5161 +out_dir:
5162 +       dbgaufs_si_fin(sbinfo);
5163 +out:
5164 +       return err;
5165 +}
5166 +
5167 +/* ---------------------------------------------------------------------- */
5168 +
5169 +void dbgaufs_fin(void)
5170 +{
5171 +       debugfs_remove(dbgaufs);
5172 +}
5173 +
5174 +int __init dbgaufs_init(void)
5175 +{
5176 +       int err;
5177 +
5178 +       err = -EIO;
5179 +       dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
5180 +       if (dbgaufs)
5181 +               err = 0;
5182 +       return err;
5183 +}
5184 diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
5185 --- /usr/share/empty/fs/aufs/dbgaufs.h  1970-01-01 01:00:00.000000000 +0100
5186 +++ linux/fs/aufs/dbgaufs.h     2013-07-06 13:20:47.740198107 +0200
5187 @@ -0,0 +1,49 @@
5188 +/*
5189 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5190 + *
5191 + * This program, aufs is free software; you can redistribute it and/or modify
5192 + * it under the terms of the GNU General Public License as published by
5193 + * the Free Software Foundation; either version 2 of the License, or
5194 + * (at your option) any later version.
5195 + *
5196 + * This program is distributed in the hope that it will be useful,
5197 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5198 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5199 + * GNU General Public License for more details.
5200 + *
5201 + * You should have received a copy of the GNU General Public License
5202 + * along with this program; if not, write to the Free Software
5203 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
5204 + */
5205 +
5206 +/*
5207 + * debugfs interface
5208 + */
5209 +
5210 +#ifndef __DBGAUFS_H__
5211 +#define __DBGAUFS_H__
5212 +
5213 +#ifdef __KERNEL__
5214 +
5215 +struct super_block;
5216 +struct au_sbinfo;
5217 +
5218 +#ifdef CONFIG_DEBUG_FS
5219 +/* dbgaufs.c */
5220 +void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
5221 +void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
5222 +void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
5223 +int dbgaufs_si_init(struct au_sbinfo *sbinfo);
5224 +void dbgaufs_fin(void);
5225 +int __init dbgaufs_init(void);
5226 +#else
5227 +AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
5228 +AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
5229 +AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
5230 +AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
5231 +AuStubVoid(dbgaufs_fin, void)
5232 +AuStubInt0(__init dbgaufs_init, void)
5233 +#endif /* CONFIG_DEBUG_FS */
5234 +
5235 +#endif /* __KERNEL__ */
5236 +#endif /* __DBGAUFS_H__ */
5237 diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
5238 --- /usr/share/empty/fs/aufs/dcsub.c    1970-01-01 01:00:00.000000000 +0100
5239 +++ linux/fs/aufs/dcsub.c       2013-07-30 22:42:55.839613269 +0200
5240 @@ -0,0 +1,243 @@
5241 +/*
5242 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5243 + *
5244 + * This program, aufs is free software; you can redistribute it and/or modify
5245 + * it under the terms of the GNU General Public License as published by
5246 + * the Free Software Foundation; either version 2 of the License, or
5247 + * (at your option) any later version.
5248 + *
5249 + * This program is distributed in the hope that it will be useful,
5250 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5251 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5252 + * GNU General Public License for more details.
5253 + *
5254 + * You should have received a copy of the GNU General Public License
5255 + * along with this program; if not, write to the Free Software
5256 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
5257 + */
5258 +
5259 +/*
5260 + * sub-routines for dentry cache
5261 + */
5262 +
5263 +#include "aufs.h"
5264 +
5265 +static void au_dpage_free(struct au_dpage *dpage)
5266 +{
5267 +       int i;
5268 +       struct dentry **p;
5269 +
5270 +       p = dpage->dentries;
5271 +       for (i = 0; i < dpage->ndentry; i++)
5272 +               dput(*p++);
5273 +       free_page((unsigned long)dpage->dentries);
5274 +}
5275 +
5276 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
5277 +{
5278 +       int err;
5279 +       void *p;
5280 +
5281 +       err = -ENOMEM;
5282 +       dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
5283 +       if (unlikely(!dpages->dpages))
5284 +               goto out;
5285 +
5286 +       p = (void *)__get_free_page(gfp);
5287 +       if (unlikely(!p))
5288 +               goto out_dpages;
5289 +
5290 +       dpages->dpages[0].ndentry = 0;
5291 +       dpages->dpages[0].dentries = p;
5292 +       dpages->ndpage = 1;
5293 +       return 0; /* success */
5294 +
5295 +out_dpages:
5296 +       kfree(dpages->dpages);
5297 +out:
5298 +       return err;
5299 +}
5300 +
5301 +void au_dpages_free(struct au_dcsub_pages *dpages)
5302 +{
5303 +       int i;
5304 +       struct au_dpage *p;
5305 +
5306 +       p = dpages->dpages;
5307 +       for (i = 0; i < dpages->ndpage; i++)
5308 +               au_dpage_free(p++);
5309 +       kfree(dpages->dpages);
5310 +}
5311 +
5312 +static int au_dpages_append(struct au_dcsub_pages *dpages,
5313 +                           struct dentry *dentry, gfp_t gfp)
5314 +{
5315 +       int err, sz;
5316 +       struct au_dpage *dpage;
5317 +       void *p;
5318 +
5319 +       dpage = dpages->dpages + dpages->ndpage - 1;
5320 +       sz = PAGE_SIZE / sizeof(dentry);
5321 +       if (unlikely(dpage->ndentry >= sz)) {
5322 +               AuLabel(new dpage);
5323 +               err = -ENOMEM;
5324 +               sz = dpages->ndpage * sizeof(*dpages->dpages);
5325 +               p = au_kzrealloc(dpages->dpages, sz,
5326 +                                sz + sizeof(*dpages->dpages), gfp);
5327 +               if (unlikely(!p))
5328 +                       goto out;
5329 +
5330 +               dpages->dpages = p;
5331 +               dpage = dpages->dpages + dpages->ndpage;
5332 +               p = (void *)__get_free_page(gfp);
5333 +               if (unlikely(!p))
5334 +                       goto out;
5335 +
5336 +               dpage->ndentry = 0;
5337 +               dpage->dentries = p;
5338 +               dpages->ndpage++;
5339 +       }
5340 +
5341 +       AuDebugOn(!dentry->d_count);
5342 +       dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
5343 +       return 0; /* success */
5344 +
5345 +out:
5346 +       return err;
5347 +}
5348 +
5349 +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5350 +                  au_dpages_test test, void *arg)
5351 +{
5352 +       int err;
5353 +       struct dentry *this_parent;
5354 +       struct list_head *next;
5355 +       struct super_block *sb = root->d_sb;
5356 +
5357 +       err = 0;
5358 +       write_seqlock(&rename_lock);
5359 +       this_parent = root;
5360 +       spin_lock(&this_parent->d_lock);
5361 +repeat:
5362 +       next = this_parent->d_subdirs.next;
5363 +resume:
5364 +       if (this_parent->d_sb == sb
5365 +           && !IS_ROOT(this_parent)
5366 +           && au_di(this_parent)
5367 +           && this_parent->d_count
5368 +           && (!test || test(this_parent, arg))) {
5369 +               err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
5370 +               if (unlikely(err))
5371 +                       goto out;
5372 +       }
5373 +
5374 +       while (next != &this_parent->d_subdirs) {
5375 +               struct list_head *tmp = next;
5376 +               struct dentry *dentry = list_entry(tmp, struct dentry,
5377 +                                                  d_u.d_child);
5378 +
5379 +               next = tmp->next;
5380 +               spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
5381 +               if (dentry->d_count) {
5382 +                       if (!list_empty(&dentry->d_subdirs)) {
5383 +                               spin_unlock(&this_parent->d_lock);
5384 +                               spin_release(&dentry->d_lock.dep_map, 1,
5385 +                                            _RET_IP_);
5386 +                               this_parent = dentry;
5387 +                               spin_acquire(&this_parent->d_lock.dep_map, 0, 1,
5388 +                                            _RET_IP_);
5389 +                               goto repeat;
5390 +                       }
5391 +                       if (dentry->d_sb == sb
5392 +                           && au_di(dentry)
5393 +                           && (!test || test(dentry, arg)))
5394 +                               err = au_dpages_append(dpages, dentry,
5395 +                                                      GFP_ATOMIC);
5396 +               }
5397 +               spin_unlock(&dentry->d_lock);
5398 +               if (unlikely(err))
5399 +                       goto out;
5400 +       }
5401 +
5402 +       if (this_parent != root) {
5403 +               struct dentry *tmp;
5404 +               struct dentry *child;
5405 +
5406 +               tmp = this_parent->d_parent;
5407 +               rcu_read_lock();
5408 +               spin_unlock(&this_parent->d_lock);
5409 +               child = this_parent;
5410 +               this_parent = tmp;
5411 +               spin_lock(&this_parent->d_lock);
5412 +               rcu_read_unlock();
5413 +               next = child->d_u.d_child.next;
5414 +               goto resume;
5415 +       }
5416 +
5417 +out:
5418 +       spin_unlock(&this_parent->d_lock);
5419 +       write_sequnlock(&rename_lock);
5420 +       return err;
5421 +}
5422 +
5423 +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5424 +                      int do_include, au_dpages_test test, void *arg)
5425 +{
5426 +       int err;
5427 +
5428 +       err = 0;
5429 +       write_seqlock(&rename_lock);
5430 +       spin_lock(&dentry->d_lock);
5431 +       if (do_include
5432 +           && dentry->d_count
5433 +           && (!test || test(dentry, arg)))
5434 +               err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
5435 +       spin_unlock(&dentry->d_lock);
5436 +       if (unlikely(err))
5437 +               goto out;
5438 +
5439 +       /*
5440 +        * vfsmount_lock is unnecessary since this is a traverse in a single
5441 +        * mount
5442 +        */
5443 +       while (!IS_ROOT(dentry)) {
5444 +               dentry = dentry->d_parent; /* rename_lock is locked */
5445 +               spin_lock(&dentry->d_lock);
5446 +               if (dentry->d_count
5447 +                   && (!test || test(dentry, arg)))
5448 +                       err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
5449 +               spin_unlock(&dentry->d_lock);
5450 +               if (unlikely(err))
5451 +                       break;
5452 +       }
5453 +
5454 +out:
5455 +       write_sequnlock(&rename_lock);
5456 +       return err;
5457 +}
5458 +
5459 +static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
5460 +{
5461 +       return au_di(dentry) && dentry->d_sb == arg;
5462 +}
5463 +
5464 +int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5465 +                           struct dentry *dentry, int do_include)
5466 +{
5467 +       return au_dcsub_pages_rev(dpages, dentry, do_include,
5468 +                                 au_dcsub_dpages_aufs, dentry->d_sb);
5469 +}
5470 +
5471 +int au_test_subdir(struct dentry *d1, struct dentry *d2)
5472 +{
5473 +       struct path path[2] = {
5474 +               {
5475 +                       .dentry = d1
5476 +               },
5477 +               {
5478 +                       .dentry = d2
5479 +               }
5480 +       };
5481 +
5482 +       return path_is_under(path + 0, path + 1);
5483 +}
5484 diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
5485 --- /usr/share/empty/fs/aufs/dcsub.h    1970-01-01 01:00:00.000000000 +0100
5486 +++ linux/fs/aufs/dcsub.h       2013-07-06 13:20:47.740198107 +0200
5487 @@ -0,0 +1,94 @@
5488 +/*
5489 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5490 + *
5491 + * This program, aufs is free software; you can redistribute it and/or modify
5492 + * it under the terms of the GNU General Public License as published by
5493 + * the Free Software Foundation; either version 2 of the License, or
5494 + * (at your option) any later version.
5495 + *
5496 + * This program is distributed in the hope that it will be useful,
5497 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5498 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5499 + * GNU General Public License for more details.
5500 + *
5501 + * You should have received a copy of the GNU General Public License
5502 + * along with this program; if not, write to the Free Software
5503 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
5504 + */
5505 +
5506 +/*
5507 + * sub-routines for dentry cache
5508 + */
5509 +
5510 +#ifndef __AUFS_DCSUB_H__
5511 +#define __AUFS_DCSUB_H__
5512 +
5513 +#ifdef __KERNEL__
5514 +
5515 +#include <linux/dcache.h>
5516 +#include <linux/fs.h>
5517 +
5518 +struct dentry;
5519 +
5520 +struct au_dpage {
5521 +       int ndentry;
5522 +       struct dentry **dentries;
5523 +};
5524 +
5525 +struct au_dcsub_pages {
5526 +       int ndpage;
5527 +       struct au_dpage *dpages;
5528 +};
5529 +
5530 +/* ---------------------------------------------------------------------- */
5531 +
5532 +/* dcsub.c */
5533 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
5534 +void au_dpages_free(struct au_dcsub_pages *dpages);
5535 +typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
5536 +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5537 +                  au_dpages_test test, void *arg);
5538 +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5539 +                      int do_include, au_dpages_test test, void *arg);
5540 +int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5541 +                           struct dentry *dentry, int do_include);
5542 +int au_test_subdir(struct dentry *d1, struct dentry *d2);
5543 +
5544 +/* ---------------------------------------------------------------------- */
5545 +
5546 +static inline int au_d_hashed_positive(struct dentry *d)
5547 +{
5548 +       int err;
5549 +       struct inode *inode = d->d_inode;
5550 +       err = 0;
5551 +       if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
5552 +               err = -ENOENT;
5553 +       return err;
5554 +}
5555 +
5556 +static inline int au_d_alive(struct dentry *d)
5557 +{
5558 +       int err;
5559 +       struct inode *inode;
5560 +       err = 0;
5561 +       if (!IS_ROOT(d))
5562 +               err = au_d_hashed_positive(d);
5563 +       else {
5564 +               inode = d->d_inode;
5565 +               if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
5566 +                       err = -ENOENT;
5567 +       }
5568 +       return err;
5569 +}
5570 +
5571 +static inline int au_alive_dir(struct dentry *d)
5572 +{
5573 +       int err;
5574 +       err = au_d_alive(d);
5575 +       if (unlikely(err || IS_DEADDIR(d->d_inode)))
5576 +               err = -ENOENT;
5577 +       return err;
5578 +}
5579 +
5580 +#endif /* __KERNEL__ */
5581 +#endif /* __AUFS_DCSUB_H__ */
5582 diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
5583 --- /usr/share/empty/fs/aufs/debug.c    1970-01-01 01:00:00.000000000 +0100
5584 +++ linux/fs/aufs/debug.c       2013-07-30 22:42:55.839613269 +0200
5585 @@ -0,0 +1,491 @@
5586 +/*
5587 + * Copyright (C) 2005-2013 Junjiro R. Okajima
5588 + *
5589 + * This program, aufs is free software; you can redistribute it and/or modify
5590 + * it under the terms of the GNU General Public License as published by
5591 + * the Free Software Foundation; either version 2 of the License, or
5592 + * (at your option) any later version.
5593 + *
5594 + * This program is distributed in the hope that it will be useful,
5595 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5596 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5597 + * GNU General Public License for more details.
5598 + *
5599 + * You should have received a copy of the GNU General Public License
5600 + * along with this program; if not, write to the Free Software
5601 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
5602 + */
5603 +
5604 +/*
5605 + * debug print functions
5606 + */
5607 +
5608 +#include <linux/vt_kern.h>
5609 +#include "aufs.h"
5610 +
5611 +int aufs_debug;
5612 +MODULE_PARM_DESC(debug, "debug print");
5613 +module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP);
5614 +
5615 +char *au_plevel = KERN_DEBUG;
5616 +#define dpri(fmt, ...) do {                                    \
5617 +       if ((au_plevel                                          \
5618 +            && strcmp(au_plevel, KERN_DEBUG))                  \
5619 +           || au_debug_test())                                 \
5620 +               printk("%s" fmt, au_plevel, ##__VA_ARGS__);     \
5621 +} while (0)
5622 +
5623 +/* ---------------------------------------------------------------------- */
5624 +
5625 +void au_dpri_whlist(struct au_nhash *whlist)
5626 +{
5627 +       unsigned long ul, n;
5628 +       struct hlist_head *head;
5629 +       struct au_vdir_wh *pos;
5630 +
5631 +       n = whlist->nh_num;
5632 +       head = whlist->nh_head;
5633 +       for (ul = 0; ul < n; ul++) {
5634 +               hlist_for_each_entry(pos, head, wh_hash)
5635 +                       dpri("b%d, %.*s, %d\n",
5636 +                            pos->wh_bindex,
5637 +                            pos->wh_str.len, pos->wh_str.name,
5638 +                            pos->wh_str.len);
5639 +               head++;
5640 +       }
5641 +}
5642 +
5643 +void au_dpri_vdir(struct au_vdir *vdir)
5644 +{
5645 +       unsigned long ul;
5646 +       union au_vdir_deblk_p p;
5647 +       unsigned char *o;
5648 +
5649 +       if (!vdir || IS_ERR(vdir)) {
5650 +               dpri("err %ld\n", PTR_ERR(vdir));
5651 +               return;
5652 +       }
5653 +
5654 +       dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
5655 +            vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
5656 +            vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
5657 +       for (ul = 0; ul < vdir->vd_nblk; ul++) {
5658 +               p.deblk = vdir->vd_deblk[ul];
5659 +               o = p.deblk;
5660 +               dpri("[%lu]: %p\n", ul, o);
5661 +       }
5662 +}
5663 +
5664 +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
5665 +                       struct dentry *wh)
5666 +{
5667 +       char *n = NULL;
5668 +       int l = 0;
5669 +
5670 +       if (!inode || IS_ERR(inode)) {
5671 +               dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
5672 +               return -1;
5673 +       }
5674 +
5675 +       /* the type of i_blocks depends upon CONFIG_LSF */
5676 +       BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
5677 +                    && sizeof(inode->i_blocks) != sizeof(u64));
5678 +       if (wh) {
5679 +               n = (void *)wh->d_name.name;
5680 +               l = wh->d_name.len;
5681 +       }
5682 +
5683 +       dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
5684 +            " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
5685 +            bindex, inode,
5686 +            inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
5687 +            atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
5688 +            i_size_read(inode), (unsigned long long)inode->i_blocks,
5689 +            hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
5690 +            inode->i_mapping ? inode->i_mapping->nrpages : 0,
5691 +            inode->i_state, inode->i_flags, inode->i_version,
5692 +            inode->i_generation,
5693 +            l ? ", wh " : "", l, n);
5694 +       return 0;
5695 +}
5696 +
5697 +void au_dpri_inode(struct inode *inode)
5698 +{
5699 +       struct au_iinfo *iinfo;
5700 +       aufs_bindex_t bindex;
5701 +       int err, hn;
5702 +
5703 +       err = do_pri_inode(-1, inode, -1, NULL);
5704 +       if (err || !au_test_aufs(inode->i_sb))
5705 +               return;
5706 +
5707 +       iinfo = au_ii(inode);
5708 +       if (!iinfo)
5709 +               return;
5710 +       dpri("i-1: bstart %d, bend %d, gen %d\n",
5711 +            iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
5712 +       if (iinfo->ii_bstart < 0)
5713 +               return;
5714 +       hn = 0;
5715 +       for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
5716 +               hn = !!au_hn(iinfo->ii_hinode + bindex);
5717 +               do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
5718 +                            iinfo->ii_hinode[0 + bindex].hi_whdentry);
5719 +       }
5720 +}
5721 +
5722 +void au_dpri_dalias(struct inode *inode)
5723 +{
5724 +       struct dentry *d;
5725 +
5726 +       spin_lock(&inode->i_lock);
5727 +       hlist_for_each_entry(d, &inode->i_dentry, d_alias)
5728 +               au_dpri_dentry(d);
5729 +       spin_unlock(&inode->i_lock);
5730 +}
5731 +
5732 +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
5733 +{
5734 +       struct dentry *wh = NULL;
5735 +       int hn;
5736 +
5737 +       if (!dentry || IS_ERR(dentry)) {
5738 +               dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
5739 +               return -1;
5740 +       }
5741 +       /* do not call dget_parent() here */
5742 +       /* note: access d_xxx without d_lock */
5743 +       dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n",
5744 +            bindex,
5745 +            AuDLNPair(dentry->d_parent), AuDLNPair(dentry),
5746 +            dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
5747 +            dentry->d_count, dentry->d_flags);
5748 +       hn = -1;
5749 +       if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
5750 +               struct au_iinfo *iinfo = au_ii(dentry->d_inode);
5751 +               if (iinfo) {
5752 +                       hn = !!au_hn(iinfo->ii_hinode + bindex);
5753 +                       wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
5754 +               }
5755 +       }
5756 +       do_pri_inode(bindex, dentry->d_inode, hn, wh);
5757 +       return 0;
5758 +}
5759 +
5760 +void au_dpri_dentry(struct dentry *dentry)
5761 +{
5762 +       struct au_dinfo *dinfo;
5763 +       aufs_bindex_t bindex;
5764 +       int err;
5765 +       struct au_hdentry *hdp;
5766 +
5767 +       err = do_pri_dentry(-1, dentry);
5768 +       if (err || !au_test_aufs(dentry->d_sb))
5769 +               return;
5770 +
5771 +       dinfo = au_di(dentry);
5772 +       if (!dinfo)
5773 +               return;
5774 +       dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
5775 +            dinfo->di_bstart, dinfo->di_bend,
5776 +            dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
5777 +       if (dinfo->di_bstart < 0)
5778 +               return;
5779 +       hdp = dinfo->di_hdentry;
5780 +       for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
5781 +               do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
5782 +}
5783 +
5784 +static int do_pri_file(aufs_bindex_t bindex, struct file *file)
5785 +{
5786 +       char a[32];
5787 +
5788 +       if (!file || IS_ERR(file)) {
5789 +               dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
5790 +               return -1;
5791 +       }
5792 +       a[0] = 0;
5793 +       if (bindex < 0
5794 +           && file->f_dentry
5795 +           && au_test_aufs(file->f_dentry->d_sb)
5796 +           && au_fi(file))
5797 +               snprintf(a, sizeof(a), ", gen %d, mmapped %d",
5798 +                        au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
5799 +       dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
5800 +            bindex, file->f_mode, file->f_flags, (long)file_count(file),
5801 +            file->f_version, file->f_pos, a);
5802 +       if (file->f_dentry)
5803 +               do_pri_dentry(bindex, file->f_dentry);
5804 +       return 0;
5805 +}
5806 +
5807 +void au_dpri_file(struct file *file)
5808 +{
5809 +       struct au_finfo *finfo;
5810 +       struct au_fidir *fidir;
5811 +       struct au_hfile *hfile;
5812 +       aufs_bindex_t bindex;
5813 +       int err;
5814 +
5815 +       err = do_pri_file(-1, file);
5816 +       if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
5817 +               return;
5818 +
5819 +       finfo = au_fi(file);
5820 +       if (!finfo)
5821 +               return;
5822 +       if (finfo->fi_btop < 0)
5823 +               return;
5824 +       fidir = finfo->fi_hdir;
5825 +       if (!fidir)
5826 +               do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
5827 +       else
5828 +               for (bindex = finfo->fi_btop;
5829 +                    bindex >= 0 && bindex <= fidir->fd_bbot;
5830 +                    bindex++) {
5831 +                       hfile = fidir->fd_hfile + bindex;
5832 +                       do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
5833 +               }
5834 +}
5835 +
5836 +static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
5837 +{
5838 +       struct vfsmount *mnt;
5839 +       struct super_block *sb;
5840 +
5841 +       if (!br || IS_ERR(br))
5842 +               goto out;
5843 +       mnt = au_br_mnt(br);
5844 +       if (!mnt || IS_ERR(mnt))
5845 +               goto out;
5846 +       sb = mnt->mnt_sb;
5847 +       if (!sb || IS_ERR(sb))
5848 +               goto out;
5849 +
5850 +       dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
5851 +            "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
5852 +            "xino %d\n",
5853 +            bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
5854 +            br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
5855 +            sb->s_flags, sb->s_count,
5856 +            atomic_read(&sb->s_active), !!br->br_xino.xi_file);
5857 +       return 0;
5858 +
5859 +out:
5860 +       dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
5861 +       return -1;
5862 +}
5863 +
5864 +void au_dpri_sb(struct super_block *sb)
5865 +{
5866 +       struct au_sbinfo *sbinfo;
5867 +       aufs_bindex_t bindex;
5868 +       int err;
5869 +       /* to reuduce stack size */
5870 +       struct {
5871 +               struct vfsmount mnt;
5872 +               struct au_branch fake;
5873 +       } *a;
5874 +
5875 +       /* this function can be called from magic sysrq */
5876 +       a = kzalloc(sizeof(*a), GFP_ATOMIC);
5877 +       if (unlikely(!a)) {
5878 +               dpri("no memory\n");
5879 +               return;
5880 +       }
5881 +
5882 +       a->mnt.mnt_sb = sb;
5883 +       a->fake.br_perm = 0;
5884 +       a->fake.br_path.mnt = &a->mnt;
5885 +       a->fake.br_xino.xi_file = NULL;
5886 +       atomic_set(&a->fake.br_count, 0);
5887 +       smp_mb(); /* atomic_set */
5888 +       err = do_pri_br(-1, &a->fake);
5889 +       kfree(a);
5890 +       dpri("dev 0x%x\n", sb->s_dev);
5891 +       if (err || !au_test_aufs(sb))
5892 +               return;
5893 +
5894 +       sbinfo = au_sbi(sb);
5895 +       if (!sbinfo)
5896 +               return;
5897 +       dpri("nw %d, gen %u, kobj %d\n",
5898 +            atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
5899 +            atomic_read(&sbinfo->si_kobj.kref.refcount));
5900 +       for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
5901 +               do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
5902 +}
5903 +
5904 +/* ---------------------------------------------------------------------- */
5905 +
5906 +void au_dbg_sleep_jiffy(int jiffy)
5907 +{
5908 +       while (jiffy)
5909 +               jiffy = schedule_timeout_uninterruptible(jiffy);
5910 +}
5911 +
5912 +void au_dbg_iattr(struct iattr *ia)
5913 +{
5914 +#define AuBit(name)                                    \
5915 +       do {                                            \
5916 +               if (ia->ia_valid & ATTR_ ## name)       \
5917 +                       dpri(#name "\n");               \
5918 +       } while (0)
5919 +       AuBit(MODE);
5920 +       AuBit(UID);
5921 +       AuBit(GID);
5922 +       AuBit(SIZE);
5923 +       AuBit(ATIME);
5924 +       AuBit(MTIME);
5925 +       AuBit(CTIME);
5926 +       AuBit(ATIME_SET);
5927 +       AuBit(MTIME_SET);
5928 +       AuBit(FORCE);
5929 +       AuBit(ATTR_FLAG);
5930 +       AuBit(KILL_SUID);
5931 +       AuBit(KILL_SGID);
5932 +       AuBit(FILE);
5933 +       AuBit(KILL_PRIV);
5934 +       AuBit(OPEN);
5935 +       AuBit(TIMES_SET);
5936 +#undef AuBit
5937 +       dpri("ia_file %p\n", ia->ia_file);
5938 +}
5939 +
5940 +/* ---------------------------------------------------------------------- */
5941 +
5942 +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
5943 +{
5944 +       struct inode *h_inode, *inode = dentry->d_inode;
5945 +       struct dentry *h_dentry;
5946 +       aufs_bindex_t bindex, bend, bi;
5947 +
5948 +       if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
5949 +               return;
5950 +
5951 +       bend = au_dbend(dentry);
5952 +       bi = au_ibend(inode);
5953 +       if (bi < bend)
5954 +               bend = bi;
5955 +       bindex = au_dbstart(dentry);
5956 +       bi = au_ibstart(inode);
5957 +       if (bi > bindex)
5958 +               bindex = bi;
5959 +
5960 +       for (; bindex <= bend; bindex++) {
5961 +               h_dentry = au_h_dptr(dentry, bindex);
5962 +               if (!h_dentry)
5963 +                       continue;
5964 +               h_inode = au_h_iptr(inode, bindex);
5965 +               if (unlikely(h_inode != h_dentry->d_inode)) {
5966 +                       int old = au_debug_test();
5967 +                       if (!old)
5968 +                               au_debug(1);
5969 +                       AuDbg("b%d, %s:%d\n", bindex, func, line);
5970 +                       AuDbgDentry(dentry);
5971 +                       AuDbgInode(inode);
5972 +                       if (!old)
5973 +                               au_debug(0);
5974 +                       BUG();
5975 +               }
5976 +       }
5977 +}
5978 +
5979 +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
5980 +{
5981 +       struct dentry *parent;
5982 +
5983 +       parent = dget_parent(dentry);
5984 +       AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
5985 +       AuDebugOn(IS_ROOT(dentry));
5986 +       AuDebugOn(au_digen_test(parent, sigen));
5987 +       dput(parent);
5988 +}
5989 +
5990 +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
5991 +{
5992 +       struct dentry *parent;
5993 +       struct inode *inode;
5994 +
5995 +       parent = dget_parent(dentry);
5996 +       inode = dentry->d_inode;
5997 +       AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
5998 +       AuDebugOn(au_digen_test(parent, sigen));
5999 +       dput(parent);
6000 +}
6001 +
6002 +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
6003 +{
6004 +       int err, i, j;
6005 +       struct au_dcsub_pages dpages;
6006 +       struct au_dpage *dpage;
6007 +       struct dentry **dentries;
6008 +
6009 +       err = au_dpages_init(&dpages, GFP_NOFS);
6010 +       AuDebugOn(err);
6011 +       err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
6012 +       AuDebugOn(err);
6013 +       for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
6014 +               dpage = dpages.dpages + i;
6015 +               dentries = dpage->dentries;
6016 +               for (j = dpage->ndentry - 1; !err && j >= 0; j--)
6017 +                       AuDebugOn(au_digen_test(dentries[j], sigen));
6018 +       }
6019 +       au_dpages_free(&dpages);
6020 +}
6021 +
6022 +void au_dbg_verify_kthread(void)
6023 +{
6024 +       if (au_wkq_test()) {
6025 +               au_dbg_blocked();
6026 +               /*
6027 +                * It may be recursive, but udba=notify between two aufs mounts,
6028 +                * where a single ro branch is shared, is not a problem.
6029 +                */
6030 +               /* WARN_ON(1); */
6031 +       }
6032 +}
6033 +
6034 +/* ---------------------------------------------------------------------- */
6035 +
6036 +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
6037 +{
6038 +#ifdef AuForceNoPlink
6039 +       au_opt_clr(sbinfo->si_mntflags, PLINK);
6040 +#endif
6041 +#ifdef AuForceNoXino
6042 +       au_opt_clr(sbinfo->si_mntflags, XINO);
6043 +#endif
6044 +#ifdef AuForceNoRefrof
6045 +       au_opt_clr(sbinfo->si_mntflags, REFROF);
6046 +#endif
6047 +#ifdef AuForceHnotify
6048 +       au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
6049 +#endif
6050 +#ifdef AuForceRd0
6051 +       sbinfo->si_rdblk = 0;
6052 +       sbinfo->si_rdhash = 0;
6053 +#endif
6054 +}
6055 +
6056 +int __init au_debug_init(void)
6057 +{
6058 +       aufs_bindex_t bindex;
6059 +       struct au_vdir_destr destr;
6060 +
6061 +       bindex = -1;
6062 +       AuDebugOn(bindex >= 0);
6063 +
6064 +       destr.len = -1;
6065 +       AuDebugOn(destr.len < NAME_MAX);
6066 +
6067 +#ifdef CONFIG_4KSTACKS
6068 +       pr_warn("CONFIG_4KSTACKS is defined.\n");
6069 +#endif
6070 +
6071 +#ifdef AuForceNoBrs
6072 +       sysaufs_brs = 0;
6073 +#endif
6074 +
6075 +       return 0;
6076 +}
6077 diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
6078 --- /usr/share/empty/fs/aufs/debug.h    1970-01-01 01:00:00.000000000 +0100
6079 +++ linux/fs/aufs/debug.h       2013-07-06 13:20:47.740198107 +0200
6080 @@ -0,0 +1,242 @@
6081 +/*
6082 + * Copyright (C) 2005-2013 Junjiro R. Okajima
6083 + *
6084 + * This program, aufs is free software; you can redistribute it and/or modify
6085 + * it under the terms of the GNU General Public License as published by
6086 + * the Free Software Foundation; either version 2 of the License, or
6087 + * (at your option) any later version.
6088 + *
6089 + * This program is distributed in the hope that it will be useful,
6090 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6091 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6092 + * GNU General Public License for more details.
6093 + *
6094 + * You should have received a copy of the GNU General Public License
6095 + * along with this program; if not, write to the Free Software
6096 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
6097 + */
6098 +
6099 +/*
6100 + * debug print functions
6101 + */
6102 +
6103 +#ifndef __AUFS_DEBUG_H__
6104 +#define __AUFS_DEBUG_H__
6105 +
6106 +#ifdef __KERNEL__
6107 +
6108 +#include <linux/module.h>
6109 +#include <linux/kallsyms.h>
6110 +#include <linux/sysrq.h>
6111 +
6112 +#ifdef CONFIG_AUFS_DEBUG
6113 +#define AuDebugOn(a)           BUG_ON(a)
6114 +
6115 +/* module parameter */
6116 +extern int aufs_debug;
6117 +static inline void au_debug(int n)
6118 +{
6119 +       aufs_debug = n;
6120 +       smp_mb();
6121 +}
6122 +
6123 +static inline int au_debug_test(void)
6124 +{
6125 +       return aufs_debug;
6126 +}
6127 +#else
6128 +#define AuDebugOn(a)           do {} while (0)
6129 +AuStubVoid(au_debug, int n)
6130 +AuStubInt0(au_debug_test, void)
6131 +#endif /* CONFIG_AUFS_DEBUG */
6132 +
6133 +/* ---------------------------------------------------------------------- */
6134 +
6135 +/* debug print */
6136 +
6137 +#define AuDbg(fmt, ...) do { \
6138 +       if (au_debug_test()) \
6139 +               pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
6140 +} while (0)
6141 +#define AuLabel(l)             AuDbg(#l "\n")
6142 +#define AuIOErr(fmt, ...)      pr_err("I/O Error, " fmt, ##__VA_ARGS__)
6143 +#define AuWarn1(fmt, ...) do { \
6144 +       static unsigned char _c; \
6145 +       if (!_c++) \
6146 +               pr_warn(fmt, ##__VA_ARGS__); \
6147 +} while (0)
6148 +
6149 +#define AuErr1(fmt, ...) do { \
6150 +       static unsigned char _c; \
6151 +       if (!_c++) \
6152 +               pr_err(fmt, ##__VA_ARGS__); \
6153 +} while (0)
6154 +
6155 +#define AuIOErr1(fmt, ...) do { \
6156 +       static unsigned char _c; \
6157 +       if (!_c++) \
6158 +               AuIOErr(fmt, ##__VA_ARGS__); \
6159 +} while (0)
6160 +
6161 +#define AuUnsupportMsg "This operation is not supported." \
6162 +                       " Please report this application to aufs-users ML."
6163 +#define AuUnsupport(fmt, ...) do { \
6164 +       pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
6165 +       dump_stack(); \
6166 +} while (0)
6167 +
6168 +#define AuTraceErr(e) do { \
6169 +       if (unlikely((e) < 0)) \
6170 +               AuDbg("err %d\n", (int)(e)); \
6171 +} while (0)
6172 +
6173 +#define AuTraceErrPtr(p) do { \
6174 +       if (IS_ERR(p)) \
6175 +               AuDbg("err %ld\n", PTR_ERR(p)); \
6176 +} while (0)
6177 +
6178 +/* dirty macros for debug print, use with "%.*s" and caution */
6179 +#define AuLNPair(qstr)         (qstr)->len, (qstr)->name
6180 +#define AuDLNPair(d)           AuLNPair(&(d)->d_name)
6181 +
6182 +/* ---------------------------------------------------------------------- */
6183 +
6184 +struct au_sbinfo;
6185 +struct au_finfo;
6186 +struct dentry;
6187 +#ifdef CONFIG_AUFS_DEBUG
6188 +extern char *au_plevel;
6189 +struct au_nhash;
6190 +void au_dpri_whlist(struct au_nhash *whlist);
6191 +struct au_vdir;
6192 +void au_dpri_vdir(struct au_vdir *vdir);
6193 +struct inode;
6194 +void au_dpri_inode(struct inode *inode);
6195 +void au_dpri_dalias(struct inode *inode);
6196 +void au_dpri_dentry(struct dentry *dentry);
6197 +struct file;
6198 +void au_dpri_file(struct file *filp);
6199 +struct super_block;
6200 +void au_dpri_sb(struct super_block *sb);
6201 +
6202 +void au_dbg_sleep_jiffy(int jiffy);
6203 +struct iattr;
6204 +void au_dbg_iattr(struct iattr *ia);
6205 +
6206 +#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
6207 +void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
6208 +void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
6209 +void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
6210 +void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
6211 +void au_dbg_verify_kthread(void);
6212 +
6213 +int __init au_debug_init(void);
6214 +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
6215 +#define AuDbgWhlist(w) do { \
6216 +       AuDbg(#w "\n"); \
6217 +       au_dpri_whlist(w); \
6218 +} while (0)
6219 +
6220 +#define AuDbgVdir(v) do { \
6221 +       AuDbg(#v "\n"); \
6222 +       au_dpri_vdir(v); \
6223 +} while (0)
6224 +
6225 +#define AuDbgInode(i) do { \
6226 +       AuDbg(#i "\n"); \
6227 +       au_dpri_inode(i); \
6228 +} while (0)
6229 +
6230 +#define AuDbgDAlias(i) do { \
6231 +       AuDbg(#i "\n"); \
6232 +       au_dpri_dalias(i); \
6233 +} while (0)
6234 +
6235 +#define AuDbgDentry(d) do { \
6236 +       AuDbg(#d "\n"); \
6237 +       au_dpri_dentry(d); \
6238 +} while (0)
6239 +
6240 +#define AuDbgFile(f) do { \
6241 +       AuDbg(#f "\n"); \
6242 +       au_dpri_file(f); \
6243 +} while (0)
6244 +
6245 +#define AuDbgSb(sb) do { \
6246 +       AuDbg(#sb "\n"); \
6247 +       au_dpri_sb(sb); \
6248 +} while (0)
6249 +
6250 +#define AuDbgSleep(sec) do { \
6251 +       AuDbg("sleep %d sec\n", sec); \
6252 +       ssleep(sec); \
6253 +} while (0)
6254 +
6255 +#define AuDbgSleepJiffy(jiffy) do { \
6256 +       AuDbg("sleep %d jiffies\n", jiffy); \
6257 +       au_dbg_sleep_jiffy(jiffy); \
6258 +} while (0)
6259 +
6260 +#define AuDbgIAttr(ia) do { \
6261 +       AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
6262 +       au_dbg_iattr(ia); \
6263 +} while (0)
6264 +
6265 +#define AuDbgSym(addr) do {                            \
6266 +       char sym[KSYM_SYMBOL_LEN];                      \
6267 +       sprint_symbol(sym, (unsigned long)addr);        \
6268 +       AuDbg("%s\n", sym);                             \
6269 +} while (0)
6270 +
6271 +#define AuInfoSym(addr) do {                           \
6272 +       char sym[KSYM_SYMBOL_LEN];                      \
6273 +       sprint_symbol(sym, (unsigned long)addr);        \
6274 +       AuInfo("%s\n", sym);                            \
6275 +} while (0)
6276 +#else
6277 +AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
6278 +AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
6279 +AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
6280 +          unsigned int sigen)
6281 +AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
6282 +AuStubVoid(au_dbg_verify_kthread, void)
6283 +AuStubInt0(__init au_debug_init, void)
6284 +AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
6285 +
6286 +#define AuDbgWhlist(w)         do {} while (0)
6287 +#define AuDbgVdir(v)           do {} while (0)
6288 +#define AuDbgInode(i)          do {} while (0)
6289 +#define AuDbgDAlias(i)         do {} while (0)
6290 +#define AuDbgDentry(d)         do {} while (0)
6291 +#define AuDbgFile(f)           do {} while (0)
6292 +#define AuDbgSb(sb)            do {} while (0)
6293 +#define AuDbgSleep(sec)                do {} while (0)
6294 +#define AuDbgSleepJiffy(jiffy) do {} while (0)
6295 +#define AuDbgIAttr(ia)         do {} while (0)
6296 +#define AuDbgSym(addr)         do {} while (0)
6297 +#define AuInfoSym(addr)                do {} while (0)
6298 +#endif /* CONFIG_AUFS_DEBUG */
6299 +
6300 +/* ---------------------------------------------------------------------- */
6301 +
6302 +#ifdef CONFIG_AUFS_MAGIC_SYSRQ
6303 +int __init au_sysrq_init(void);
6304 +void au_sysrq_fin(void);
6305 +
6306 +#ifdef CONFIG_HW_CONSOLE
6307 +#define au_dbg_blocked() do { \
6308 +       WARN_ON(1); \
6309 +       handle_sysrq('w'); \
6310 +} while (0)
6311 +#else
6312 +AuStubVoid(au_dbg_blocked, void)
6313 +#endif
6314 +
6315 +#else
6316 +AuStubInt0(__init au_sysrq_init, void)
6317 +AuStubVoid(au_sysrq_fin, void)
6318 +AuStubVoid(au_dbg_blocked, void)
6319 +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
6320 +
6321 +#endif /* __KERNEL__ */
6322 +#endif /* __AUFS_DEBUG_H__ */
6323 diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
6324 --- /usr/share/empty/fs/aufs/dentry.c   1970-01-01 01:00:00.000000000 +0100
6325 +++ linux/fs/aufs/dentry.c      2013-07-06 13:20:47.740198107 +0200
6326 @@ -0,0 +1,1065 @@
6327 +/*
6328 + * Copyright (C) 2005-2013 Junjiro R. Okajima
6329 + *
6330 + * This program, aufs is free software; you can redistribute it and/or modify
6331 + * it under the terms of the GNU General Public License as published by
6332 + * the Free Software Foundation; either version 2 of the License, or
6333 + * (at your option) any later version.
6334 + *
6335 + * This program is distributed in the hope that it will be useful,
6336 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6337 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6338 + * GNU General Public License for more details.
6339 + *
6340 + * You should have received a copy of the GNU General Public License
6341 + * along with this program; if not, write to the Free Software
6342 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
6343 + */
6344 +
6345 +/*
6346 + * lookup and dentry operations
6347 + */
6348 +
6349 +#include <linux/namei.h>
6350 +#include "aufs.h"
6351 +
6352 +#define AuLkup_ALLOW_NEG       1
6353 +#define au_ftest_lkup(flags, name)     ((flags) & AuLkup_##name)
6354 +#define au_fset_lkup(flags, name) \
6355 +       do { (flags) |= AuLkup_##name; } while (0)
6356 +#define au_fclr_lkup(flags, name) \
6357 +       do { (flags) &= ~AuLkup_##name; } while (0)
6358 +
6359 +struct au_do_lookup_args {
6360 +       unsigned int            flags;
6361 +       mode_t                  type;
6362 +};
6363 +
6364 +/*
6365 + * returns positive/negative dentry, NULL or an error.
6366 + * NULL means whiteout-ed or not-found.
6367 + */
6368 +static struct dentry*
6369 +au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
6370 +            aufs_bindex_t bindex, struct qstr *wh_name,
6371 +            struct au_do_lookup_args *args)
6372 +{
6373 +       struct dentry *h_dentry;
6374 +       struct inode *h_inode, *inode;
6375 +       struct au_branch *br;
6376 +       int wh_found, opq;
6377 +       unsigned char wh_able;
6378 +       const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
6379 +
6380 +       wh_found = 0;
6381 +       br = au_sbr(dentry->d_sb, bindex);
6382 +       wh_able = !!au_br_whable(br->br_perm);
6383 +       if (wh_able)
6384 +               wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
6385 +       h_dentry = ERR_PTR(wh_found);
6386 +       if (!wh_found)
6387 +               goto real_lookup;
6388 +       if (unlikely(wh_found < 0))
6389 +               goto out;
6390 +
6391 +       /* We found a whiteout */
6392 +       /* au_set_dbend(dentry, bindex); */
6393 +       au_set_dbwh(dentry, bindex);
6394 +       if (!allow_neg)
6395 +               return NULL; /* success */
6396 +
6397 +real_lookup:
6398 +       h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
6399 +       if (IS_ERR(h_dentry))
6400 +               goto out;
6401 +
6402 +       h_inode = h_dentry->d_inode;
6403 +       if (!h_inode) {
6404 +               if (!allow_neg)
6405 +                       goto out_neg;
6406 +       } else if (wh_found
6407 +                  || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
6408 +               goto out_neg;
6409 +
6410 +       if (au_dbend(dentry) <= bindex)
6411 +               au_set_dbend(dentry, bindex);
6412 +       if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
6413 +               au_set_dbstart(dentry, bindex);
6414 +       au_set_h_dptr(dentry, bindex, h_dentry);
6415 +
6416 +       inode = dentry->d_inode;
6417 +       if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
6418 +           || (inode && !S_ISDIR(inode->i_mode)))
6419 +               goto out; /* success */
6420 +
6421 +       mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
6422 +       opq = au_diropq_test(h_dentry, br);
6423 +       mutex_unlock(&h_inode->i_mutex);
6424 +       if (opq > 0)
6425 +               au_set_dbdiropq(dentry, bindex);
6426 +       else if (unlikely(opq < 0)) {
6427 +               au_set_h_dptr(dentry, bindex, NULL);
6428 +               h_dentry = ERR_PTR(opq);
6429 +       }
6430 +       goto out;
6431 +
6432 +out_neg:
6433 +       dput(h_dentry);
6434 +       h_dentry = NULL;
6435 +out:
6436 +       return h_dentry;
6437 +}
6438 +
6439 +static int au_test_shwh(struct super_block *sb, const struct qstr *name)
6440 +{
6441 +       if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
6442 +                    && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
6443 +               return -EPERM;
6444 +       return 0;
6445 +}
6446 +
6447 +/*
6448 + * returns the number of lower positive dentries,
6449 + * otherwise an error.
6450 + * can be called at unlinking with @type is zero.
6451 + */
6452 +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
6453 +{
6454 +       int npositive, err;
6455 +       aufs_bindex_t bindex, btail, bdiropq;
6456 +       unsigned char isdir;
6457 +       struct qstr whname;
6458 +       struct au_do_lookup_args args = {
6459 +               .flags          = 0,
6460 +               .type           = type
6461 +       };
6462 +       const struct qstr *name = &dentry->d_name;
6463 +       struct dentry *parent;
6464 +       struct inode *inode;
6465 +
6466 +       err = au_test_shwh(dentry->d_sb, name);
6467 +       if (unlikely(err))
6468 +               goto out;
6469 +
6470 +       err = au_wh_name_alloc(&whname, name);
6471 +       if (unlikely(err))
6472 +               goto out;
6473 +
6474 +       inode = dentry->d_inode;
6475 +       isdir = !!(inode && S_ISDIR(inode->i_mode));
6476 +       if (!type)
6477 +               au_fset_lkup(args.flags, ALLOW_NEG);
6478 +
6479 +       npositive = 0;
6480 +       parent = dget_parent(dentry);
6481 +       btail = au_dbtaildir(parent);
6482 +       for (bindex = bstart; bindex <= btail; bindex++) {
6483 +               struct dentry *h_parent, *h_dentry;
6484 +               struct inode *h_inode, *h_dir;
6485 +
6486 +               h_dentry = au_h_dptr(dentry, bindex);
6487 +               if (h_dentry) {
6488 +                       if (h_dentry->d_inode)
6489 +                               npositive++;
6490 +                       if (type != S_IFDIR)
6491 +                               break;
6492 +                       continue;
6493 +               }
6494 +               h_parent = au_h_dptr(parent, bindex);
6495 +               if (!h_parent)
6496 +                       continue;
6497 +               h_dir = h_parent->d_inode;
6498 +               if (!h_dir || !S_ISDIR(h_dir->i_mode))
6499 +                       continue;
6500 +
6501 +               mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
6502 +               h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
6503 +                                       &args);
6504 +               mutex_unlock(&h_dir->i_mutex);
6505 +               err = PTR_ERR(h_dentry);
6506 +               if (IS_ERR(h_dentry))
6507 +                       goto out_parent;
6508 +               au_fclr_lkup(args.flags, ALLOW_NEG);
6509 +
6510 +               if (au_dbwh(dentry) >= 0)
6511 +                       break;
6512 +               if (!h_dentry)
6513 +                       continue;
6514 +               h_inode = h_dentry->d_inode;
6515 +               if (!h_inode)
6516 +                       continue;
6517 +               npositive++;
6518 +               if (!args.type)
6519 +                       args.type = h_inode->i_mode & S_IFMT;
6520 +               if (args.type != S_IFDIR)
6521 +                       break;
6522 +               else if (isdir) {
6523 +                       /* the type of lower may be different */
6524 +                       bdiropq = au_dbdiropq(dentry);
6525 +                       if (bdiropq >= 0 && bdiropq <= bindex)
6526 +                               break;
6527 +               }
6528 +       }
6529 +
6530 +       if (npositive) {
6531 +               AuLabel(positive);
6532 +               au_update_dbstart(dentry);
6533 +       }
6534 +       err = npositive;
6535 +       if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
6536 +                    && au_dbstart(dentry) < 0)) {
6537 +               err = -EIO;
6538 +               AuIOErr("both of real entry and whiteout found, %.*s, err %d\n",
6539 +                       AuDLNPair(dentry), err);
6540 +       }
6541 +
6542 +out_parent:
6543 +       dput(parent);
6544 +       kfree(whname.name);
6545 +out:
6546 +       return err;
6547 +}
6548 +
6549 +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
6550 +                              struct au_branch *br)
6551 +{
6552 +       struct dentry *dentry;
6553 +       int wkq_err;
6554 +
6555 +       if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
6556 +               dentry = vfsub_lkup_one(name, parent);
6557 +       else {
6558 +               struct vfsub_lkup_one_args args = {
6559 +                       .errp   = &dentry,
6560 +                       .name   = name,
6561 +                       .parent = parent
6562 +               };
6563 +
6564 +               wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
6565 +               if (unlikely(wkq_err))
6566 +                       dentry = ERR_PTR(wkq_err);
6567 +       }
6568 +
6569 +       return dentry;
6570 +}
6571 +
6572 +/*
6573 + * lookup @dentry on @bindex which should be negative.
6574 + */
6575 +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
6576 +{
6577 +       int err;
6578 +       struct dentry *parent, *h_parent, *h_dentry;
6579 +       struct au_branch *br;
6580 +
6581 +       parent = dget_parent(dentry);
6582 +       h_parent = au_h_dptr(parent, bindex);
6583 +       br = au_sbr(dentry->d_sb, bindex);
6584 +       if (wh)
6585 +               h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
6586 +       else
6587 +               h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent, br);
6588 +       err = PTR_ERR(h_dentry);
6589 +       if (IS_ERR(h_dentry))
6590 +               goto out;
6591 +       if (unlikely(h_dentry->d_inode)) {
6592 +               err = -EIO;
6593 +               AuIOErr("%.*s should be negative on b%d.\n",
6594 +                       AuDLNPair(h_dentry), bindex);
6595 +               dput(h_dentry);
6596 +               goto out;
6597 +       }
6598 +
6599 +       err = 0;
6600 +       if (bindex < au_dbstart(dentry))
6601 +               au_set_dbstart(dentry, bindex);
6602 +       if (au_dbend(dentry) < bindex)
6603 +               au_set_dbend(dentry, bindex);
6604 +       au_set_h_dptr(dentry, bindex, h_dentry);
6605 +
6606 +out:
6607 +       dput(parent);
6608 +       return err;
6609 +}
6610 +
6611 +/* ---------------------------------------------------------------------- */
6612 +
6613 +/* subset of struct inode */
6614 +struct au_iattr {
6615 +       unsigned long           i_ino;
6616 +       /* unsigned int         i_nlink; */
6617 +       kuid_t                  i_uid;
6618 +       kgid_t                  i_gid;
6619 +       u64                     i_version;
6620 +/*
6621 +       loff_t                  i_size;
6622 +       blkcnt_t                i_blocks;
6623 +*/
6624 +       umode_t                 i_mode;
6625 +};
6626 +
6627 +static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
6628 +{
6629 +       ia->i_ino = h_inode->i_ino;
6630 +       /* ia->i_nlink = h_inode->i_nlink; */
6631 +       ia->i_uid = h_inode->i_uid;
6632 +       ia->i_gid = h_inode->i_gid;
6633 +       ia->i_version = h_inode->i_version;
6634 +/*
6635 +       ia->i_size = h_inode->i_size;
6636 +       ia->i_blocks = h_inode->i_blocks;
6637 +*/
6638 +       ia->i_mode = (h_inode->i_mode & S_IFMT);
6639 +}
6640 +
6641 +static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
6642 +{
6643 +       return ia->i_ino != h_inode->i_ino
6644 +               /* || ia->i_nlink != h_inode->i_nlink */
6645 +               || !uid_eq(ia->i_uid, h_inode->i_uid)
6646 +               || !gid_eq(ia->i_gid, h_inode->i_gid)
6647 +               || ia->i_version != h_inode->i_version
6648 +/*
6649 +               || ia->i_size != h_inode->i_size
6650 +               || ia->i_blocks != h_inode->i_blocks
6651 +*/
6652 +               || ia->i_mode != (h_inode->i_mode & S_IFMT);
6653 +}
6654 +
6655 +static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
6656 +                             struct au_branch *br)
6657 +{
6658 +       int err;
6659 +       struct au_iattr ia;
6660 +       struct inode *h_inode;
6661 +       struct dentry *h_d;
6662 +       struct super_block *h_sb;
6663 +
6664 +       err = 0;
6665 +       memset(&ia, -1, sizeof(ia));
6666 +       h_sb = h_dentry->d_sb;
6667 +       h_inode = h_dentry->d_inode;
6668 +       if (h_inode)
6669 +               au_iattr_save(&ia, h_inode);
6670 +       else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
6671 +               /* nfs d_revalidate may return 0 for negative dentry */
6672 +               /* fuse d_revalidate always return 0 for negative dentry */
6673 +               goto out;
6674 +
6675 +       /* main purpose is namei.c:cached_lookup() and d_revalidate */
6676 +       h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
6677 +       err = PTR_ERR(h_d);
6678 +       if (IS_ERR(h_d))
6679 +               goto out;
6680 +
6681 +       err = 0;
6682 +       if (unlikely(h_d != h_dentry
6683 +                    || h_d->d_inode != h_inode
6684 +                    || (h_inode && au_iattr_test(&ia, h_inode))))
6685 +               err = au_busy_or_stale();
6686 +       dput(h_d);
6687 +
6688 +out:
6689 +       AuTraceErr(err);
6690 +       return err;
6691 +}
6692 +
6693 +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
6694 +               struct dentry *h_parent, struct au_branch *br)
6695 +{
6696 +       int err;
6697 +
6698 +       err = 0;
6699 +       if (udba == AuOpt_UDBA_REVAL
6700 +           && !au_test_fs_remote(h_dentry->d_sb)) {
6701 +               IMustLock(h_dir);
6702 +               err = (h_dentry->d_parent->d_inode != h_dir);
6703 +       } else if (udba != AuOpt_UDBA_NONE)
6704 +               err = au_h_verify_dentry(h_dentry, h_parent, br);
6705 +
6706 +       return err;
6707 +}
6708 +
6709 +/* ---------------------------------------------------------------------- */
6710 +
6711 +static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
6712 +{
6713 +       int err;
6714 +       aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
6715 +       struct au_hdentry tmp, *p, *q;
6716 +       struct au_dinfo *dinfo;
6717 +       struct super_block *sb;
6718 +
6719 +       DiMustWriteLock(dentry);
6720 +
6721 +       sb = dentry->d_sb;
6722 +       dinfo = au_di(dentry);
6723 +       bend = dinfo->di_bend;
6724 +       bwh = dinfo->di_bwh;
6725 +       bdiropq = dinfo->di_bdiropq;
6726 +       p = dinfo->di_hdentry + dinfo->di_bstart;
6727 +       for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
6728 +               if (!p->hd_dentry)
6729 +                       continue;
6730 +
6731 +               new_bindex = au_br_index(sb, p->hd_id);
6732 +               if (new_bindex == bindex)
6733 +                       continue;
6734 +
6735 +               if (dinfo->di_bwh == bindex)
6736 +                       bwh = new_bindex;
6737 +               if (dinfo->di_bdiropq == bindex)
6738 +                       bdiropq = new_bindex;
6739 +               if (new_bindex < 0) {
6740 +                       au_hdput(p);
6741 +                       p->hd_dentry = NULL;
6742 +                       continue;
6743 +               }
6744 +
6745 +               /* swap two lower dentries, and loop again */
6746 +               q = dinfo->di_hdentry + new_bindex;
6747 +               tmp = *q;
6748 +               *q = *p;
6749 +               *p = tmp;
6750 +               if (tmp.hd_dentry) {
6751 +                       bindex--;
6752 +                       p--;
6753 +               }
6754 +       }
6755 +
6756 +       dinfo->di_bwh = -1;
6757 +       if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
6758 +               dinfo->di_bwh = bwh;
6759 +
6760 +       dinfo->di_bdiropq = -1;
6761 +       if (bdiropq >= 0
6762 +           && bdiropq <= au_sbend(sb)
6763 +           && au_sbr_whable(sb, bdiropq))
6764 +               dinfo->di_bdiropq = bdiropq;
6765 +
6766 +       err = -EIO;
6767 +       dinfo->di_bstart = -1;
6768 +       dinfo->di_bend = -1;
6769 +       bend = au_dbend(parent);
6770 +       p = dinfo->di_hdentry;
6771 +       for (bindex = 0; bindex <= bend; bindex++, p++)
6772 +               if (p->hd_dentry) {
6773 +                       dinfo->di_bstart = bindex;
6774 +                       break;
6775 +               }
6776 +
6777 +       if (dinfo->di_bstart >= 0) {
6778 +               p = dinfo->di_hdentry + bend;
6779 +               for (bindex = bend; bindex >= 0; bindex--, p--)
6780 +                       if (p->hd_dentry) {
6781 +                               dinfo->di_bend = bindex;
6782 +                               err = 0;
6783 +                               break;
6784 +                       }
6785 +       }
6786 +
6787 +       return err;
6788 +}
6789 +
6790 +static void au_do_hide(struct dentry *dentry)
6791 +{
6792 +       struct inode *inode;
6793 +
6794 +       inode = dentry->d_inode;
6795 +       if (inode) {
6796 +               if (!S_ISDIR(inode->i_mode)) {
6797 +                       if (inode->i_nlink && !d_unhashed(dentry))
6798 +                               drop_nlink(inode);
6799 +               } else {
6800 +                       clear_nlink(inode);
6801 +                       /* stop next lookup */
6802 +                       inode->i_flags |= S_DEAD;
6803 +               }
6804 +               smp_mb(); /* necessary? */
6805 +       }
6806 +       d_drop(dentry);
6807 +}
6808 +
6809 +static int au_hide_children(struct dentry *parent)
6810 +{
6811 +       int err, i, j, ndentry;
6812 +       struct au_dcsub_pages dpages;
6813 +       struct au_dpage *dpage;
6814 +       struct dentry *dentry;
6815 +
6816 +       err = au_dpages_init(&dpages, GFP_NOFS);
6817 +       if (unlikely(err))
6818 +               goto out;
6819 +       err = au_dcsub_pages(&dpages, parent, NULL, NULL);
6820 +       if (unlikely(err))
6821 +               goto out_dpages;
6822 +
6823 +       /* in reverse order */
6824 +       for (i = dpages.ndpage - 1; i >= 0; i--) {
6825 +               dpage = dpages.dpages + i;
6826 +               ndentry = dpage->ndentry;
6827 +               for (j = ndentry - 1; j >= 0; j--) {
6828 +                       dentry = dpage->dentries[j];
6829 +                       if (dentry != parent)
6830 +                               au_do_hide(dentry);
6831 +               }
6832 +       }
6833 +
6834 +out_dpages:
6835 +       au_dpages_free(&dpages);
6836 +out:
6837 +       return err;
6838 +}
6839 +
6840 +static void au_hide(struct dentry *dentry)
6841 +{
6842 +       int err;
6843 +       struct inode *inode;
6844 +
6845 +       AuDbgDentry(dentry);
6846 +       inode = dentry->d_inode;
6847 +       if (inode && S_ISDIR(inode->i_mode)) {
6848 +               /* shrink_dcache_parent(dentry); */
6849 +               err = au_hide_children(dentry);
6850 +               if (unlikely(err))
6851 +                       AuIOErr("%.*s, failed hiding children, ignored %d\n",
6852 +                               AuDLNPair(dentry), err);
6853 +       }
6854 +       au_do_hide(dentry);
6855 +}
6856 +
6857 +/*
6858 + * By adding a dirty branch, a cached dentry may be affected in various ways.
6859 + *
6860 + * a dirty branch is added
6861 + * - on the top of layers
6862 + * - in the middle of layers
6863 + * - to the bottom of layers
6864 + *
6865 + * on the added branch there exists
6866 + * - a whiteout
6867 + * - a diropq
6868 + * - a same named entry
6869 + *   + exist
6870 + *     * negative --> positive
6871 + *     * positive --> positive
6872 + *      - type is unchanged
6873 + *      - type is changed
6874 + *   + doesn't exist
6875 + *     * negative --> negative
6876 + *     * positive --> negative (rejected by au_br_del() for non-dir case)
6877 + * - none
6878 + */
6879 +static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
6880 +                              struct au_dinfo *tmp)
6881 +{
6882 +       int err;
6883 +       aufs_bindex_t bindex, bend;
6884 +       struct {
6885 +               struct dentry *dentry;
6886 +               struct inode *inode;
6887 +               mode_t mode;
6888 +       } orig_h, tmp_h;
6889 +       struct au_hdentry *hd;
6890 +       struct inode *inode, *h_inode;
6891 +       struct dentry *h_dentry;
6892 +
6893 +       err = 0;
6894 +       AuDebugOn(dinfo->di_bstart < 0);
6895 +       orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
6896 +       orig_h.inode = orig_h.dentry->d_inode;
6897 +       orig_h.mode = 0;
6898 +       if (orig_h.inode)
6899 +               orig_h.mode = orig_h.inode->i_mode & S_IFMT;
6900 +       memset(&tmp_h, 0, sizeof(tmp_h));
6901 +       if (tmp->di_bstart >= 0) {
6902 +               tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
6903 +               tmp_h.inode = tmp_h.dentry->d_inode;
6904 +               if (tmp_h.inode)
6905 +                       tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
6906 +       }
6907 +
6908 +       inode = dentry->d_inode;
6909 +       if (!orig_h.inode) {
6910 +               AuDbg("nagative originally\n");
6911 +               if (inode) {
6912 +                       au_hide(dentry);
6913 +                       goto out;
6914 +               }
6915 +               AuDebugOn(inode);
6916 +               AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
6917 +               AuDebugOn(dinfo->di_bdiropq != -1);
6918 +
6919 +               if (!tmp_h.inode) {
6920 +                       AuDbg("negative --> negative\n");
6921 +                       /* should have only one negative lower */
6922 +                       if (tmp->di_bstart >= 0
6923 +                           && tmp->di_bstart < dinfo->di_bstart) {
6924 +                               AuDebugOn(tmp->di_bstart != tmp->di_bend);
6925 +                               AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
6926 +                               au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
6927 +                               au_di_cp(dinfo, tmp);
6928 +                               hd = tmp->di_hdentry + tmp->di_bstart;
6929 +                               au_set_h_dptr(dentry, tmp->di_bstart,
6930 +                                             dget(hd->hd_dentry));
6931 +                       }
6932 +                       au_dbg_verify_dinode(dentry);
6933 +               } else {
6934 +                       AuDbg("negative --> positive\n");
6935 +                       /*
6936 +                        * similar to the behaviour of creating with bypassing
6937 +                        * aufs.
6938 +                        * unhash it in order to force an error in the
6939 +                        * succeeding create operation.
6940 +                        * we should not set S_DEAD here.
6941 +                        */
6942 +                       d_drop(dentry);
6943 +                       /* au_di_swap(tmp, dinfo); */
6944 +                       au_dbg_verify_dinode(dentry);
6945 +               }
6946 +       } else {
6947 +               AuDbg("positive originally\n");
6948 +               /* inode may be NULL */
6949 +               AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
6950 +               if (!tmp_h.inode) {
6951 +                       AuDbg("positive --> negative\n");
6952 +                       /* or bypassing aufs */
6953 +                       au_hide(dentry);
6954 +                       if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
6955 +                               dinfo->di_bwh = tmp->di_bwh;
6956 +                       if (inode)
6957 +                               err = au_refresh_hinode_self(inode);
6958 +                       au_dbg_verify_dinode(dentry);
6959 +               } else if (orig_h.mode == tmp_h.mode) {
6960 +                       AuDbg("positive --> positive, same type\n");
6961 +                       if (!S_ISDIR(orig_h.mode)
6962 +                           && dinfo->di_bstart > tmp->di_bstart) {
6963 +                               /*
6964 +                                * similar to the behaviour of removing and
6965 +                                * creating.
6966 +                                */
6967 +                               au_hide(dentry);
6968 +                               if (inode)
6969 +                                       err = au_refresh_hinode_self(inode);
6970 +                               au_dbg_verify_dinode(dentry);
6971 +                       } else {
6972 +                               /* fill empty slots */
6973 +                               if (dinfo->di_bstart > tmp->di_bstart)
6974 +                                       dinfo->di_bstart = tmp->di_bstart;
6975 +                               if (dinfo->di_bend < tmp->di_bend)
6976 +                                       dinfo->di_bend = tmp->di_bend;
6977 +                               dinfo->di_bwh = tmp->di_bwh;
6978 +                               dinfo->di_bdiropq = tmp->di_bdiropq;
6979 +                               hd = tmp->di_hdentry;
6980 +                               bend = dinfo->di_bend;
6981 +                               for (bindex = tmp->di_bstart; bindex <= bend;
6982 +                                    bindex++) {
6983 +                                       if (au_h_dptr(dentry, bindex))
6984 +                                               continue;
6985 +                                       h_dentry = hd[bindex].hd_dentry;
6986 +                                       if (!h_dentry)
6987 +                                               continue;
6988 +                                       h_inode = h_dentry->d_inode;
6989 +                                       AuDebugOn(!h_inode);
6990 +                                       AuDebugOn(orig_h.mode
6991 +                                                 != (h_inode->i_mode
6992 +                                                     & S_IFMT));
6993 +                                       au_set_h_dptr(dentry, bindex,
6994 +                                                     dget(h_dentry));
6995 +                               }
6996 +                               err = au_refresh_hinode(inode, dentry);
6997 +                               au_dbg_verify_dinode(dentry);
6998 +                       }
6999 +               } else {
7000 +                       AuDbg("positive --> positive, different type\n");
7001 +                       /* similar to the behaviour of removing and creating */
7002 +                       au_hide(dentry);
7003 +                       if (inode)
7004 +                               err = au_refresh_hinode_self(inode);
7005 +                       au_dbg_verify_dinode(dentry);
7006 +               }
7007 +       }
7008 +
7009 +out:
7010 +       return err;
7011 +}
7012 +
7013 +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
7014 +{
7015 +       int err, ebrange;
7016 +       unsigned int sigen;
7017 +       struct au_dinfo *dinfo, *tmp;
7018 +       struct super_block *sb;
7019 +       struct inode *inode;
7020 +
7021 +       DiMustWriteLock(dentry);
7022 +       AuDebugOn(IS_ROOT(dentry));
7023 +       AuDebugOn(!parent->d_inode);
7024 +
7025 +       sb = dentry->d_sb;
7026 +       inode = dentry->d_inode;
7027 +       sigen = au_sigen(sb);
7028 +       err = au_digen_test(parent, sigen);
7029 +       if (unlikely(err))
7030 +               goto out;
7031 +
7032 +       dinfo = au_di(dentry);
7033 +       err = au_di_realloc(dinfo, au_sbend(sb) + 1);
7034 +       if (unlikely(err))
7035 +               goto out;
7036 +       ebrange = au_dbrange_test(dentry);
7037 +       if (!ebrange)
7038 +               ebrange = au_do_refresh_hdentry(dentry, parent);
7039 +
7040 +       if (d_unhashed(dentry) || ebrange) {
7041 +               AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
7042 +               if (inode)
7043 +                       err = au_refresh_hinode_self(inode);
7044 +               au_dbg_verify_dinode(dentry);
7045 +               if (!err)
7046 +                       goto out_dgen; /* success */
7047 +               goto out;
7048 +       }
7049 +
7050 +       /* temporary dinfo */
7051 +       AuDbgDentry(dentry);
7052 +       err = -ENOMEM;
7053 +       tmp = au_di_alloc(sb, AuLsc_DI_TMP);
7054 +       if (unlikely(!tmp))
7055 +               goto out;
7056 +       au_di_swap(tmp, dinfo);
7057 +       /* returns the number of positive dentries */
7058 +       /*
7059 +        * if current working dir is removed, it returns an error.
7060 +        * but the dentry is legal.
7061 +        */
7062 +       err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
7063 +       AuDbgDentry(dentry);
7064 +       au_di_swap(tmp, dinfo);
7065 +       if (err == -ENOENT)
7066 +               err = 0;
7067 +       if (err >= 0) {
7068 +               /* compare/refresh by dinfo */
7069 +               AuDbgDentry(dentry);
7070 +               err = au_refresh_by_dinfo(dentry, dinfo, tmp);
7071 +               au_dbg_verify_dinode(dentry);
7072 +               AuTraceErr(err);
7073 +       }
7074 +       au_rw_write_unlock(&tmp->di_rwsem);
7075 +       au_di_free(tmp);
7076 +       if (unlikely(err))
7077 +               goto out;
7078 +
7079 +out_dgen:
7080 +       au_update_digen(dentry);
7081 +out:
7082 +       if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
7083 +               AuIOErr("failed refreshing %.*s, %d\n",
7084 +                       AuDLNPair(dentry), err);
7085 +               AuDbgDentry(dentry);
7086 +       }
7087 +       AuTraceErr(err);
7088 +       return err;
7089 +}
7090 +
7091 +static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
7092 +                          struct dentry *dentry, aufs_bindex_t bindex)
7093 +{
7094 +       int err, valid;
7095 +
7096 +       err = 0;
7097 +       if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
7098 +               goto out;
7099 +
7100 +       AuDbg("b%d\n", bindex);
7101 +       /*
7102 +        * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
7103 +        * due to whiteout and branch permission.
7104 +        */
7105 +       flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
7106 +                  | LOOKUP_FOLLOW | LOOKUP_EXCL);
7107 +       /* it may return tri-state */
7108 +       valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
7109 +
7110 +       if (unlikely(valid < 0))
7111 +               err = valid;
7112 +       else if (!valid)
7113 +               err = -EINVAL;
7114 +
7115 +out:
7116 +       AuTraceErr(err);
7117 +       return err;
7118 +}
7119 +
7120 +/* todo: remove this */
7121 +static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
7122 +                         unsigned int flags, int do_udba)
7123 +{
7124 +       int err;
7125 +       umode_t mode, h_mode;
7126 +       aufs_bindex_t bindex, btail, bstart, ibs, ibe;
7127 +       unsigned char plus, unhashed, is_root, h_plus;
7128 +       struct inode *h_inode, *h_cached_inode;
7129 +       struct dentry *h_dentry;
7130 +       struct qstr *name, *h_name;
7131 +
7132 +       err = 0;
7133 +       plus = 0;
7134 +       mode = 0;
7135 +       ibs = -1;
7136 +       ibe = -1;
7137 +       unhashed = !!d_unhashed(dentry);
7138 +       is_root = !!IS_ROOT(dentry);
7139 +       name = &dentry->d_name;
7140 +
7141 +       /*
7142 +        * Theoretically, REVAL test should be unnecessary in case of
7143 +        * {FS,I}NOTIFY.
7144 +        * But {fs,i}notify doesn't fire some necessary events,
7145 +        *      IN_ATTRIB for atime/nlink/pageio
7146 +        *      IN_DELETE for NFS dentry
7147 +        * Let's do REVAL test too.
7148 +        */
7149 +       if (do_udba && inode) {
7150 +               mode = (inode->i_mode & S_IFMT);
7151 +               plus = (inode->i_nlink > 0);
7152 +               ibs = au_ibstart(inode);
7153 +               ibe = au_ibend(inode);
7154 +       }
7155 +
7156 +       bstart = au_dbstart(dentry);
7157 +       btail = bstart;
7158 +       if (inode && S_ISDIR(inode->i_mode))
7159 +               btail = au_dbtaildir(dentry);
7160 +       for (bindex = bstart; bindex <= btail; bindex++) {
7161 +               h_dentry = au_h_dptr(dentry, bindex);
7162 +               if (!h_dentry)
7163 +                       continue;
7164 +
7165 +               AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry));
7166 +               spin_lock(&h_dentry->d_lock);
7167 +               h_name = &h_dentry->d_name;
7168 +               if (unlikely(do_udba
7169 +                            && !is_root
7170 +                            && (unhashed != !!d_unhashed(h_dentry)
7171 +                                || name->len != h_name->len
7172 +                                || memcmp(name->name, h_name->name, name->len))
7173 +                           )) {
7174 +                       AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n",
7175 +                                 unhashed, d_unhashed(h_dentry),
7176 +                                 AuDLNPair(dentry), AuDLNPair(h_dentry));
7177 +                       spin_unlock(&h_dentry->d_lock);
7178 +                       goto err;
7179 +               }
7180 +               spin_unlock(&h_dentry->d_lock);
7181 +
7182 +               err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
7183 +               if (unlikely(err))
7184 +                       /* do not goto err, to keep the errno */
7185 +                       break;
7186 +
7187 +               /* todo: plink too? */
7188 +               if (!do_udba)
7189 +                       continue;
7190 +
7191 +               /* UDBA tests */
7192 +               h_inode = h_dentry->d_inode;
7193 +               if (unlikely(!!inode != !!h_inode))
7194 +                       goto err;
7195 +
7196 +               h_plus = plus;
7197 +               h_mode = mode;
7198 +               h_cached_inode = h_inode;
7199 +               if (h_inode) {
7200 +                       h_mode = (h_inode->i_mode & S_IFMT);
7201 +                       h_plus = (h_inode->i_nlink > 0);
7202 +               }
7203 +               if (inode && ibs <= bindex && bindex <= ibe)
7204 +                       h_cached_inode = au_h_iptr(inode, bindex);
7205 +
7206 +               if (unlikely(plus != h_plus
7207 +                            || mode != h_mode
7208 +                            || h_cached_inode != h_inode))
7209 +                       goto err;
7210 +               continue;
7211 +
7212 +       err:
7213 +               err = -EINVAL;
7214 +               break;
7215 +       }
7216 +
7217 +       return err;
7218 +}
7219 +
7220 +/* todo: consolidate with do_refresh() and au_reval_for_attr() */
7221 +static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
7222 +{
7223 +       int err;
7224 +       struct dentry *parent;
7225 +
7226 +       if (!au_digen_test(dentry, sigen))
7227 +               return 0;
7228 +
7229 +       parent = dget_parent(dentry);
7230 +       di_read_lock_parent(parent, AuLock_IR);
7231 +       AuDebugOn(au_digen_test(parent, sigen));
7232 +       au_dbg_verify_gen(parent, sigen);
7233 +       err = au_refresh_dentry(dentry, parent);
7234 +       di_read_unlock(parent, AuLock_IR);
7235 +       dput(parent);
7236 +       AuTraceErr(err);
7237 +       return err;
7238 +}
7239 +
7240 +int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
7241 +{
7242 +       int err;
7243 +       struct dentry *d, *parent;
7244 +       struct inode *inode;
7245 +
7246 +       if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
7247 +               return simple_reval_dpath(dentry, sigen);
7248 +
7249 +       /* slow loop, keep it simple and stupid */
7250 +       /* cf: au_cpup_dirs() */
7251 +       err = 0;
7252 +       parent = NULL;
7253 +       while (au_digen_test(dentry, sigen)) {
7254 +               d = dentry;
7255 +               while (1) {
7256 +                       dput(parent);
7257 +                       parent = dget_parent(d);
7258 +                       if (!au_digen_test(parent, sigen))
7259 +                               break;
7260 +                       d = parent;
7261 +               }
7262 +
7263 +               inode = d->d_inode;
7264 +               if (d != dentry)
7265 +                       di_write_lock_child2(d);
7266 +
7267 +               /* someone might update our dentry while we were sleeping */
7268 +               if (au_digen_test(d, sigen)) {
7269 +                       /*
7270 +                        * todo: consolidate with simple_reval_dpath(),
7271 +                        * do_refresh() and au_reval_for_attr().
7272 +                        */
7273 +                       di_read_lock_parent(parent, AuLock_IR);
7274 +                       err = au_refresh_dentry(d, parent);
7275 +                       di_read_unlock(parent, AuLock_IR);
7276 +               }
7277 +
7278 +               if (d != dentry)
7279 +                       di_write_unlock(d);
7280 +               dput(parent);
7281 +               if (unlikely(err))
7282 +                       break;
7283 +       }
7284 +
7285 +       return err;
7286 +}
7287 +
7288 +/*
7289 + * if valid returns 1, otherwise 0.
7290 + */
7291 +static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
7292 +{
7293 +       int valid, err;
7294 +       unsigned int sigen;
7295 +       unsigned char do_udba;
7296 +       struct super_block *sb;
7297 +       struct inode *inode;
7298 +
7299 +       /* todo: support rcu-walk? */
7300 +       if (flags & LOOKUP_RCU)
7301 +               return -ECHILD;
7302 +
7303 +       valid = 0;
7304 +       if (unlikely(!au_di(dentry)))
7305 +               goto out;
7306 +
7307 +       inode = dentry->d_inode;
7308 +       if (inode && is_bad_inode(inode))
7309 +               goto out;
7310 +
7311 +       valid = 1;
7312 +       sb = dentry->d_sb;
7313 +       /*
7314 +        * todo: very ugly
7315 +        * i_mutex of parent dir may be held,
7316 +        * but we should not return 'invalid' due to busy.
7317 +        */
7318 +       err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
7319 +       if (unlikely(err)) {
7320 +               valid = err;
7321 +               AuTraceErr(err);
7322 +               goto out;
7323 +       }
7324 +       if (unlikely(au_dbrange_test(dentry))) {
7325 +               err = -EINVAL;
7326 +               AuTraceErr(err);
7327 +               goto out_dgrade;
7328 +       }
7329 +
7330 +       sigen = au_sigen(sb);
7331 +       if (au_digen_test(dentry, sigen)) {
7332 +               AuDebugOn(IS_ROOT(dentry));
7333 +               err = au_reval_dpath(dentry, sigen);
7334 +               if (unlikely(err)) {
7335 +                       AuTraceErr(err);
7336 +                       goto out_dgrade;
7337 +               }
7338 +       }
7339 +       di_downgrade_lock(dentry, AuLock_IR);
7340 +
7341 +       err = -EINVAL;
7342 +       if (inode && (IS_DEADDIR(inode) || !inode->i_nlink))
7343 +               goto out_inval;
7344 +
7345 +       do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
7346 +       if (do_udba && inode) {
7347 +               aufs_bindex_t bstart = au_ibstart(inode);
7348 +               struct inode *h_inode;
7349 +
7350 +               if (bstart >= 0) {
7351 +                       h_inode = au_h_iptr(inode, bstart);
7352 +                       if (h_inode && au_test_higen(inode, h_inode))
7353 +                               goto out_inval;
7354 +               }
7355 +       }
7356 +
7357 +       err = h_d_revalidate(dentry, inode, flags, do_udba);
7358 +       if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
7359 +               err = -EIO;
7360 +               AuDbg("both of real entry and whiteout found, %.*s, err %d\n",
7361 +                     AuDLNPair(dentry), err);
7362 +       }
7363 +       goto out_inval;
7364 +
7365 +out_dgrade:
7366 +       di_downgrade_lock(dentry, AuLock_IR);
7367 +out_inval:
7368 +       aufs_read_unlock(dentry, AuLock_IR);
7369 +       AuTraceErr(err);
7370 +       valid = !err;
7371 +out:
7372 +       if (!valid) {
7373 +               AuDbg("%.*s invalid, %d\n", AuDLNPair(dentry), valid);
7374 +               d_drop(dentry);
7375 +       }
7376 +       return valid;
7377 +}
7378 +
7379 +static void aufs_d_release(struct dentry *dentry)
7380 +{
7381 +       if (au_di(dentry)) {
7382 +               au_di_fin(dentry);
7383 +               au_hn_di_reinit(dentry);
7384 +       }
7385 +}
7386 +
7387 +const struct dentry_operations aufs_dop = {
7388 +       .d_revalidate           = aufs_d_revalidate,
7389 +       .d_weak_revalidate      = aufs_d_revalidate,
7390 +       .d_release              = aufs_d_release
7391 +};
7392 diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
7393 --- /usr/share/empty/fs/aufs/dentry.h   1970-01-01 01:00:00.000000000 +0100
7394 +++ linux/fs/aufs/dentry.h      2013-07-06 13:20:47.740198107 +0200
7395 @@ -0,0 +1,234 @@
7396 +/*
7397 + * Copyright (C) 2005-2013 Junjiro R. Okajima
7398 + *
7399 + * This program, aufs is free software; you can redistribute it and/or modify
7400 + * it under the terms of the GNU General Public License as published by
7401 + * the Free Software Foundation; either version 2 of the License, or
7402 + * (at your option) any later version.
7403 + *
7404 + * This program is distributed in the hope that it will be useful,
7405 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7406 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7407 + * GNU General Public License for more details.
7408 + *
7409 + * You should have received a copy of the GNU General Public License
7410 + * along with this program; if not, write to the Free Software
7411 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
7412 + */
7413 +
7414 +/*
7415 + * lookup and dentry operations
7416 + */
7417 +
7418 +#ifndef __AUFS_DENTRY_H__
7419 +#define __AUFS_DENTRY_H__
7420 +
7421 +#ifdef __KERNEL__
7422 +
7423 +#include <linux/dcache.h>
7424 +#include "rwsem.h"
7425 +
7426 +struct au_hdentry {
7427 +       struct dentry           *hd_dentry;
7428 +       aufs_bindex_t           hd_id;
7429 +};
7430 +
7431 +struct au_dinfo {
7432 +       atomic_t                di_generation;
7433 +
7434 +       struct au_rwsem         di_rwsem;
7435 +       aufs_bindex_t           di_bstart, di_bend, di_bwh, di_bdiropq;
7436 +       struct au_hdentry       *di_hdentry;
7437 +} ____cacheline_aligned_in_smp;
7438 +
7439 +/* ---------------------------------------------------------------------- */
7440 +
7441 +/* dentry.c */
7442 +extern const struct dentry_operations aufs_dop;
7443 +struct au_branch;
7444 +struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
7445 +                              struct au_branch *br);
7446 +int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7447 +               struct dentry *h_parent, struct au_branch *br);
7448 +
7449 +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
7450 +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
7451 +int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
7452 +int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
7453 +
7454 +/* dinfo.c */
7455 +void au_di_init_once(void *_di);
7456 +struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
7457 +void au_di_free(struct au_dinfo *dinfo);
7458 +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
7459 +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
7460 +int au_di_init(struct dentry *dentry);
7461 +void au_di_fin(struct dentry *dentry);
7462 +int au_di_realloc(struct au_dinfo *dinfo, int nbr);
7463 +
7464 +void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
7465 +void di_read_unlock(struct dentry *d, int flags);
7466 +void di_downgrade_lock(struct dentry *d, int flags);
7467 +void di_write_lock(struct dentry *d, unsigned int lsc);
7468 +void di_write_unlock(struct dentry *d);
7469 +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
7470 +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
7471 +void di_write_unlock2(struct dentry *d1, struct dentry *d2);
7472 +
7473 +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
7474 +struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
7475 +aufs_bindex_t au_dbtail(struct dentry *dentry);
7476 +aufs_bindex_t au_dbtaildir(struct dentry *dentry);
7477 +
7478 +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
7479 +                  struct dentry *h_dentry);
7480 +int au_digen_test(struct dentry *dentry, unsigned int sigen);
7481 +int au_dbrange_test(struct dentry *dentry);
7482 +void au_update_digen(struct dentry *dentry);
7483 +void au_update_dbrange(struct dentry *dentry, int do_put_zero);
7484 +void au_update_dbstart(struct dentry *dentry);
7485 +void au_update_dbend(struct dentry *dentry);
7486 +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
7487 +
7488 +/* ---------------------------------------------------------------------- */
7489 +
7490 +static inline struct au_dinfo *au_di(struct dentry *dentry)
7491 +{
7492 +       return dentry->d_fsdata;
7493 +}
7494 +
7495 +/* ---------------------------------------------------------------------- */
7496 +
7497 +/* lock subclass for dinfo */
7498 +enum {
7499 +       AuLsc_DI_CHILD,         /* child first */
7500 +       AuLsc_DI_CHILD2,        /* rename(2), link(2), and cpup at hnotify */
7501 +       AuLsc_DI_CHILD3,        /* copyup dirs */
7502 +       AuLsc_DI_PARENT,
7503 +       AuLsc_DI_PARENT2,
7504 +       AuLsc_DI_PARENT3,
7505 +       AuLsc_DI_TMP            /* temp for replacing dinfo */
7506 +};
7507 +
7508 +/*
7509 + * di_read_lock_child, di_write_lock_child,
7510 + * di_read_lock_child2, di_write_lock_child2,
7511 + * di_read_lock_child3, di_write_lock_child3,
7512 + * di_read_lock_parent, di_write_lock_parent,
7513 + * di_read_lock_parent2, di_write_lock_parent2,
7514 + * di_read_lock_parent3, di_write_lock_parent3,
7515 + */
7516 +#define AuReadLockFunc(name, lsc) \
7517 +static inline void di_read_lock_##name(struct dentry *d, int flags) \
7518 +{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
7519 +
7520 +#define AuWriteLockFunc(name, lsc) \
7521 +static inline void di_write_lock_##name(struct dentry *d) \
7522 +{ di_write_lock(d, AuLsc_DI_##lsc); }
7523 +
7524 +#define AuRWLockFuncs(name, lsc) \
7525 +       AuReadLockFunc(name, lsc) \
7526 +       AuWriteLockFunc(name, lsc)
7527 +
7528 +AuRWLockFuncs(child, CHILD);
7529 +AuRWLockFuncs(child2, CHILD2);
7530 +AuRWLockFuncs(child3, CHILD3);
7531 +AuRWLockFuncs(parent, PARENT);
7532 +AuRWLockFuncs(parent2, PARENT2);
7533 +AuRWLockFuncs(parent3, PARENT3);
7534 +
7535 +#undef AuReadLockFunc
7536 +#undef AuWriteLockFunc
7537 +#undef AuRWLockFuncs
7538 +
7539 +#define DiMustNoWaiters(d)     AuRwMustNoWaiters(&au_di(d)->di_rwsem)
7540 +#define DiMustAnyLock(d)       AuRwMustAnyLock(&au_di(d)->di_rwsem)
7541 +#define DiMustWriteLock(d)     AuRwMustWriteLock(&au_di(d)->di_rwsem)
7542 +
7543 +/* ---------------------------------------------------------------------- */
7544 +
7545 +/* todo: memory barrier? */
7546 +static inline unsigned int au_digen(struct dentry *d)
7547 +{
7548 +       return atomic_read(&au_di(d)->di_generation);
7549 +}
7550 +
7551 +static inline void au_h_dentry_init(struct au_hdentry *hdentry)
7552 +{
7553 +       hdentry->hd_dentry = NULL;
7554 +}
7555 +
7556 +static inline void au_hdput(struct au_hdentry *hd)
7557 +{
7558 +       if (hd)
7559 +               dput(hd->hd_dentry);
7560 +}
7561 +
7562 +static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
7563 +{
7564 +       DiMustAnyLock(dentry);
7565 +       return au_di(dentry)->di_bstart;
7566 +}
7567 +
7568 +static inline aufs_bindex_t au_dbend(struct dentry *dentry)
7569 +{
7570 +       DiMustAnyLock(dentry);
7571 +       return au_di(dentry)->di_bend;
7572 +}
7573 +
7574 +static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
7575 +{
7576 +       DiMustAnyLock(dentry);
7577 +       return au_di(dentry)->di_bwh;
7578 +}
7579 +
7580 +static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
7581 +{
7582 +       DiMustAnyLock(dentry);
7583 +       return au_di(dentry)->di_bdiropq;
7584 +}
7585 +
7586 +/* todo: hard/soft set? */
7587 +static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
7588 +{
7589 +       DiMustWriteLock(dentry);
7590 +       au_di(dentry)->di_bstart = bindex;
7591 +}
7592 +
7593 +static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
7594 +{
7595 +       DiMustWriteLock(dentry);
7596 +       au_di(dentry)->di_bend = bindex;
7597 +}
7598 +
7599 +static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
7600 +{
7601 +       DiMustWriteLock(dentry);
7602 +       /* dbwh can be outside of bstart - bend range */
7603 +       au_di(dentry)->di_bwh = bindex;
7604 +}
7605 +
7606 +static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
7607 +{
7608 +       DiMustWriteLock(dentry);
7609 +       au_di(dentry)->di_bdiropq = bindex;
7610 +}
7611 +
7612 +/* ---------------------------------------------------------------------- */
7613 +
7614 +#ifdef CONFIG_AUFS_HNOTIFY
7615 +static inline void au_digen_dec(struct dentry *d)
7616 +{
7617 +       atomic_dec(&au_di(d)->di_generation);
7618 +}
7619 +
7620 +static inline void au_hn_di_reinit(struct dentry *dentry)
7621 +{
7622 +       dentry->d_fsdata = NULL;
7623 +}
7624 +#else
7625 +AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
7626 +#endif /* CONFIG_AUFS_HNOTIFY */
7627 +
7628 +#endif /* __KERNEL__ */
7629 +#endif /* __AUFS_DENTRY_H__ */
7630 diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
7631 --- /usr/share/empty/fs/aufs/dinfo.c    1970-01-01 01:00:00.000000000 +0100
7632 +++ linux/fs/aufs/dinfo.c       2013-07-30 22:42:55.839613269 +0200
7633 @@ -0,0 +1,543 @@
7634 +/*
7635 + * Copyright (C) 2005-2013 Junjiro R. Okajima
7636 + *
7637 + * This program, aufs is free software; you can redistribute it and/or modify
7638 + * it under the terms of the GNU General Public License as published by
7639 + * the Free Software Foundation; either version 2 of the License, or
7640 + * (at your option) any later version.
7641 + *
7642 + * This program is distributed in the hope that it will be useful,
7643 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7644 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7645 + * GNU General Public License for more details.
7646 + *
7647 + * You should have received a copy of the GNU General Public License
7648 + * along with this program; if not, write to the Free Software
7649 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
7650 + */
7651 +
7652 +/*
7653 + * dentry private data
7654 + */
7655 +
7656 +#include "aufs.h"
7657 +
7658 +void au_di_init_once(void *_dinfo)
7659 +{
7660 +       struct au_dinfo *dinfo = _dinfo;
7661 +       static struct lock_class_key aufs_di;
7662 +
7663 +       au_rw_init(&dinfo->di_rwsem);
7664 +       au_rw_class(&dinfo->di_rwsem, &aufs_di);
7665 +}
7666 +
7667 +struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
7668 +{
7669 +       struct au_dinfo *dinfo;
7670 +       int nbr, i;
7671 +
7672 +       dinfo = au_cache_alloc_dinfo();
7673 +       if (unlikely(!dinfo))
7674 +               goto out;
7675 +
7676 +       nbr = au_sbend(sb) + 1;
7677 +       if (nbr <= 0)
7678 +               nbr = 1;
7679 +       dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
7680 +       if (dinfo->di_hdentry) {
7681 +               au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
7682 +               dinfo->di_bstart = -1;
7683 +               dinfo->di_bend = -1;
7684 +               dinfo->di_bwh = -1;
7685 +               dinfo->di_bdiropq = -1;
7686 +               for (i = 0; i < nbr; i++)
7687 +                       dinfo->di_hdentry[i].hd_id = -1;
7688 +               goto out;
7689 +       }
7690 +
7691 +       au_cache_free_dinfo(dinfo);
7692 +       dinfo = NULL;
7693 +
7694 +out:
7695 +       return dinfo;
7696 +}
7697 +
7698 +void au_di_free(struct au_dinfo *dinfo)
7699 +{
7700 +       struct au_hdentry *p;
7701 +       aufs_bindex_t bend, bindex;
7702 +
7703 +       /* dentry may not be revalidated */
7704 +       bindex = dinfo->di_bstart;
7705 +       if (bindex >= 0) {
7706 +               bend = dinfo->di_bend;
7707 +               p = dinfo->di_hdentry + bindex;
7708 +               while (bindex++ <= bend)
7709 +                       au_hdput(p++);
7710 +       }
7711 +       kfree(dinfo->di_hdentry);
7712 +       au_cache_free_dinfo(dinfo);
7713 +}
7714 +
7715 +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
7716 +{
7717 +       struct au_hdentry *p;
7718 +       aufs_bindex_t bi;
7719 +
7720 +       AuRwMustWriteLock(&a->di_rwsem);
7721 +       AuRwMustWriteLock(&b->di_rwsem);
7722 +
7723 +#define DiSwap(v, name)                                \
7724 +       do {                                    \
7725 +               v = a->di_##name;               \
7726 +               a->di_##name = b->di_##name;    \
7727 +               b->di_##name = v;               \
7728 +       } while (0)
7729 +
7730 +       DiSwap(p, hdentry);
7731 +       DiSwap(bi, bstart);
7732 +       DiSwap(bi, bend);
7733 +       DiSwap(bi, bwh);
7734 +       DiSwap(bi, bdiropq);
7735 +       /* smp_mb(); */
7736 +
7737 +#undef DiSwap
7738 +}
7739 +
7740 +void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
7741 +{
7742 +       AuRwMustWriteLock(&dst->di_rwsem);
7743 +       AuRwMustWriteLock(&src->di_rwsem);
7744 +
7745 +       dst->di_bstart = src->di_bstart;
7746 +       dst->di_bend = src->di_bend;
7747 +       dst->di_bwh = src->di_bwh;
7748 +       dst->di_bdiropq = src->di_bdiropq;
7749 +       /* smp_mb(); */
7750 +}
7751 +
7752 +int au_di_init(struct dentry *dentry)
7753 +{
7754 +       int err;
7755 +       struct super_block *sb;
7756 +       struct au_dinfo *dinfo;
7757 +
7758 +       err = 0;
7759 +       sb = dentry->d_sb;
7760 +       dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
7761 +       if (dinfo) {
7762 +               atomic_set(&dinfo->di_generation, au_sigen(sb));
7763 +               /* smp_mb(); */ /* atomic_set */
7764 +               dentry->d_fsdata = dinfo;
7765 +       } else
7766 +               err = -ENOMEM;
7767 +
7768 +       return err;
7769 +}
7770 +
7771 +void au_di_fin(struct dentry *dentry)
7772 +{
7773 +       struct au_dinfo *dinfo;
7774 +
7775 +       dinfo = au_di(dentry);
7776 +       AuRwDestroy(&dinfo->di_rwsem);
7777 +       au_di_free(dinfo);
7778 +}
7779 +
7780 +int au_di_realloc(struct au_dinfo *dinfo, int nbr)
7781 +{
7782 +       int err, sz;
7783 +       struct au_hdentry *hdp;
7784 +
7785 +       AuRwMustWriteLock(&dinfo->di_rwsem);
7786 +
7787 +       err = -ENOMEM;
7788 +       sz = sizeof(*hdp) * (dinfo->di_bend + 1);
7789 +       if (!sz)
7790 +               sz = sizeof(*hdp);
7791 +       hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
7792 +       if (hdp) {
7793 +               dinfo->di_hdentry = hdp;
7794 +               err = 0;
7795 +       }
7796 +
7797 +       return err;
7798 +}
7799 +
7800 +/* ---------------------------------------------------------------------- */
7801 +
7802 +static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
7803 +{
7804 +       switch (lsc) {
7805 +       case AuLsc_DI_CHILD:
7806 +               ii_write_lock_child(inode);
7807 +               break;
7808 +       case AuLsc_DI_CHILD2:
7809 +               ii_write_lock_child2(inode);
7810 +               break;
7811 +       case AuLsc_DI_CHILD3:
7812 +               ii_write_lock_child3(inode);
7813 +               break;
7814 +       case AuLsc_DI_PARENT:
7815 +               ii_write_lock_parent(inode);
7816 +               break;
7817 +       case AuLsc_DI_PARENT2:
7818 +               ii_write_lock_parent2(inode);
7819 +               break;
7820 +       case AuLsc_DI_PARENT3:
7821 +               ii_write_lock_parent3(inode);
7822 +               break;
7823 +       default:
7824 +               BUG();
7825 +       }
7826 +}
7827 +
7828 +static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
7829 +{
7830 +       switch (lsc) {
7831 +       case AuLsc_DI_CHILD:
7832 +               ii_read_lock_child(inode);
7833 +               break;
7834 +       case AuLsc_DI_CHILD2:
7835 +               ii_read_lock_child2(inode);
7836 +               break;
7837 +       case AuLsc_DI_CHILD3:
7838 +               ii_read_lock_child3(inode);
7839 +               break;
7840 +       case AuLsc_DI_PARENT:
7841 +               ii_read_lock_parent(inode);
7842 +               break;
7843 +       case AuLsc_DI_PARENT2:
7844 +               ii_read_lock_parent2(inode);
7845 +               break;
7846 +       case AuLsc_DI_PARENT3:
7847 +               ii_read_lock_parent3(inode);
7848 +               break;
7849 +       default:
7850 +               BUG();
7851 +       }
7852 +}
7853 +
7854 +void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
7855 +{
7856 +       au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
7857 +       if (d->d_inode) {
7858 +               if (au_ftest_lock(flags, IW))
7859 +                       do_ii_write_lock(d->d_inode, lsc);
7860 +               else if (au_ftest_lock(flags, IR))
7861 +                       do_ii_read_lock(d->d_inode, lsc);
7862 +       }
7863 +}
7864 +
7865 +void di_read_unlock(struct dentry *d, int flags)
7866 +{
7867 +       if (d->d_inode) {
7868 +               if (au_ftest_lock(flags, IW)) {
7869 +                       au_dbg_verify_dinode(d);
7870 +                       ii_write_unlock(d->d_inode);
7871 +               } else if (au_ftest_lock(flags, IR)) {
7872 +                       au_dbg_verify_dinode(d);
7873 +                       ii_read_unlock(d->d_inode);
7874 +               }
7875 +       }
7876 +       au_rw_read_unlock(&au_di(d)->di_rwsem);
7877 +}
7878 +
7879 +void di_downgrade_lock(struct dentry *d, int flags)
7880 +{
7881 +       if (d->d_inode && au_ftest_lock(flags, IR))
7882 +               ii_downgrade_lock(d->d_inode);
7883 +       au_rw_dgrade_lock(&au_di(d)->di_rwsem);
7884 +}
7885 +
7886 +void di_write_lock(struct dentry *d, unsigned int lsc)
7887 +{
7888 +       au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
7889 +       if (d->d_inode)
7890 +               do_ii_write_lock(d->d_inode, lsc);
7891 +}
7892 +
7893 +void di_write_unlock(struct dentry *d)
7894 +{
7895 +       au_dbg_verify_dinode(d);
7896 +       if (d->d_inode)
7897 +               ii_write_unlock(d->d_inode);
7898 +       au_rw_write_unlock(&au_di(d)->di_rwsem);
7899 +}
7900 +
7901 +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
7902 +{
7903 +       AuDebugOn(d1 == d2
7904 +                 || d1->d_inode == d2->d_inode
7905 +                 || d1->d_sb != d2->d_sb);
7906 +
7907 +       if (isdir && au_test_subdir(d1, d2)) {
7908 +               di_write_lock_child(d1);
7909 +               di_write_lock_child2(d2);
7910 +       } else {
7911 +               /* there should be no races */
7912 +               di_write_lock_child(d2);
7913 +               di_write_lock_child2(d1);
7914 +       }
7915 +}
7916 +
7917 +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
7918 +{
7919 +       AuDebugOn(d1 == d2
7920 +                 || d1->d_inode == d2->d_inode
7921 +                 || d1->d_sb != d2->d_sb);
7922 +
7923 +       if (isdir && au_test_subdir(d1, d2)) {
7924 +               di_write_lock_parent(d1);
7925 +               di_write_lock_parent2(d2);
7926 +       } else {
7927 +               /* there should be no races */
7928 +               di_write_lock_parent(d2);
7929 +               di_write_lock_parent2(d1);
7930 +       }
7931 +}
7932 +
7933 +void di_write_unlock2(struct dentry *d1, struct dentry *d2)
7934 +{
7935 +       di_write_unlock(d1);
7936 +       if (d1->d_inode == d2->d_inode)
7937 +               au_rw_write_unlock(&au_di(d2)->di_rwsem);
7938 +       else
7939 +               di_write_unlock(d2);
7940 +}
7941 +
7942 +/* ---------------------------------------------------------------------- */
7943 +
7944 +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
7945 +{
7946 +       struct dentry *d;
7947 +
7948 +       DiMustAnyLock(dentry);
7949 +
7950 +       if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
7951 +               return NULL;
7952 +       AuDebugOn(bindex < 0);
7953 +       d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
7954 +       AuDebugOn(d && d->d_count <= 0);
7955 +       return d;
7956 +}
7957 +
7958 +/*
7959 + * extended version of au_h_dptr().
7960 + * returns a hashed and positive h_dentry in bindex, NULL, or error.
7961 + */
7962 +struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
7963 +{
7964 +       struct dentry *h_dentry;
7965 +       struct inode *inode, *h_inode;
7966 +
7967 +       inode = dentry->d_inode;
7968 +       AuDebugOn(!inode);
7969 +
7970 +       h_dentry = NULL;
7971 +       if (au_dbstart(dentry) <= bindex
7972 +           && bindex <= au_dbend(dentry))
7973 +               h_dentry = au_h_dptr(dentry, bindex);
7974 +       if (h_dentry && !au_d_hashed_positive(h_dentry)) {
7975 +               dget(h_dentry);
7976 +               goto out; /* success */
7977 +       }
7978 +
7979 +       AuDebugOn(bindex < au_ibstart(inode));
7980 +       AuDebugOn(au_ibend(inode) < bindex);
7981 +       h_inode = au_h_iptr(inode, bindex);
7982 +       h_dentry = d_find_alias(h_inode);
7983 +       if (h_dentry) {
7984 +               if (!IS_ERR(h_dentry)) {
7985 +                       if (!au_d_hashed_positive(h_dentry))
7986 +                               goto out; /* success */
7987 +                       dput(h_dentry);
7988 +               } else
7989 +                       goto out;
7990 +       }
7991 +
7992 +       if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
7993 +               h_dentry = au_plink_lkup(inode, bindex);
7994 +               AuDebugOn(!h_dentry);
7995 +               if (!IS_ERR(h_dentry)) {
7996 +                       if (!au_d_hashed_positive(h_dentry))
7997 +                               goto out; /* success */
7998 +                       dput(h_dentry);
7999 +                       h_dentry = NULL;
8000 +               }
8001 +       }
8002 +
8003 +out:
8004 +       AuDbgDentry(h_dentry);
8005 +       return h_dentry;
8006 +}
8007 +
8008 +aufs_bindex_t au_dbtail(struct dentry *dentry)
8009 +{
8010 +       aufs_bindex_t bend, bwh;
8011 +
8012 +       bend = au_dbend(dentry);
8013 +       if (0 <= bend) {
8014 +               bwh = au_dbwh(dentry);
8015 +               if (!bwh)
8016 +                       return bwh;
8017 +               if (0 < bwh && bwh < bend)
8018 +                       return bwh - 1;
8019 +       }
8020 +       return bend;
8021 +}
8022 +
8023 +aufs_bindex_t au_dbtaildir(struct dentry *dentry)
8024 +{
8025 +       aufs_bindex_t bend, bopq;
8026 +
8027 +       bend = au_dbtail(dentry);
8028 +       if (0 <= bend) {
8029 +               bopq = au_dbdiropq(dentry);
8030 +               if (0 <= bopq && bopq < bend)
8031 +                       bend = bopq;
8032 +       }
8033 +       return bend;
8034 +}
8035 +
8036 +/* ---------------------------------------------------------------------- */
8037 +
8038 +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8039 +                  struct dentry *h_dentry)
8040 +{
8041 +       struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
8042 +       struct au_branch *br;
8043 +
8044 +       DiMustWriteLock(dentry);
8045 +
8046 +       au_hdput(hd);
8047 +       hd->hd_dentry = h_dentry;
8048 +       if (h_dentry) {
8049 +               br = au_sbr(dentry->d_sb, bindex);
8050 +               hd->hd_id = br->br_id;
8051 +       }
8052 +}
8053 +
8054 +int au_dbrange_test(struct dentry *dentry)
8055 +{
8056 +       int err;
8057 +       aufs_bindex_t bstart, bend;
8058 +
8059 +       err = 0;
8060 +       bstart = au_dbstart(dentry);
8061 +       bend = au_dbend(dentry);
8062 +       if (bstart >= 0)
8063 +               AuDebugOn(bend < 0 && bstart > bend);
8064 +       else {
8065 +               err = -EIO;
8066 +               AuDebugOn(bend >= 0);
8067 +       }
8068 +
8069 +       return err;
8070 +}
8071 +
8072 +int au_digen_test(struct dentry *dentry, unsigned int sigen)
8073 +{
8074 +       int err;
8075 +
8076 +       err = 0;
8077 +       if (unlikely(au_digen(dentry) != sigen
8078 +                    || au_iigen_test(dentry->d_inode, sigen)))
8079 +               err = -EIO;
8080 +
8081 +       return err;
8082 +}
8083 +
8084 +void au_update_digen(struct dentry *dentry)
8085 +{
8086 +       atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
8087 +       /* smp_mb(); */ /* atomic_set */
8088 +}
8089 +
8090 +void au_update_dbrange(struct dentry *dentry, int do_put_zero)
8091 +{
8092 +       struct au_dinfo *dinfo;
8093 +       struct dentry *h_d;
8094 +       struct au_hdentry *hdp;
8095 +
8096 +       DiMustWriteLock(dentry);
8097 +
8098 +       dinfo = au_di(dentry);
8099 +       if (!dinfo || dinfo->di_bstart < 0)
8100 +               return;
8101 +
8102 +       hdp = dinfo->di_hdentry;
8103 +       if (do_put_zero) {
8104 +               aufs_bindex_t bindex, bend;
8105 +
8106 +               bend = dinfo->di_bend;
8107 +               for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
8108 +                       h_d = hdp[0 + bindex].hd_dentry;
8109 +                       if (h_d && !h_d->d_inode)
8110 +                               au_set_h_dptr(dentry, bindex, NULL);
8111 +               }
8112 +       }
8113 +
8114 +       dinfo->di_bstart = -1;
8115 +       while (++dinfo->di_bstart <= dinfo->di_bend)
8116 +               if (hdp[0 + dinfo->di_bstart].hd_dentry)
8117 +                       break;
8118 +       if (dinfo->di_bstart > dinfo->di_bend) {
8119 +               dinfo->di_bstart = -1;
8120 +               dinfo->di_bend = -1;
8121 +               return;
8122 +       }
8123 +
8124 +       dinfo->di_bend++;
8125 +       while (0 <= --dinfo->di_bend)
8126 +               if (hdp[0 + dinfo->di_bend].hd_dentry)
8127 +                       break;
8128 +       AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
8129 +}
8130 +
8131 +void au_update_dbstart(struct dentry *dentry)
8132 +{
8133 +       aufs_bindex_t bindex, bend;
8134 +       struct dentry *h_dentry;
8135 +
8136 +       bend = au_dbend(dentry);
8137 +       for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
8138 +               h_dentry = au_h_dptr(dentry, bindex);
8139 +               if (!h_dentry)
8140 +                       continue;
8141 +               if (h_dentry->d_inode) {
8142 +                       au_set_dbstart(dentry, bindex);
8143 +                       return;
8144 +               }
8145 +               au_set_h_dptr(dentry, bindex, NULL);
8146 +       }
8147 +}
8148 +
8149 +void au_update_dbend(struct dentry *dentry)
8150 +{
8151 +       aufs_bindex_t bindex, bstart;
8152 +       struct dentry *h_dentry;
8153 +
8154 +       bstart = au_dbstart(dentry);
8155 +       for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
8156 +               h_dentry = au_h_dptr(dentry, bindex);
8157 +               if (!h_dentry)
8158 +                       continue;
8159 +               if (h_dentry->d_inode) {
8160 +                       au_set_dbend(dentry, bindex);
8161 +                       return;
8162 +               }
8163 +               au_set_h_dptr(dentry, bindex, NULL);
8164 +       }
8165 +}
8166 +
8167 +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
8168 +{
8169 +       aufs_bindex_t bindex, bend;
8170 +
8171 +       bend = au_dbend(dentry);
8172 +       for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
8173 +               if (au_h_dptr(dentry, bindex) == h_dentry)
8174 +                       return bindex;
8175 +       return -1;
8176 +}
8177 diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
8178 --- /usr/share/empty/fs/aufs/dir.c      1970-01-01 01:00:00.000000000 +0100
8179 +++ linux/fs/aufs/dir.c 2013-07-30 22:42:55.839613269 +0200
8180 @@ -0,0 +1,632 @@
8181 +/*
8182 + * Copyright (C) 2005-2013 Junjiro R. Okajima
8183 + *
8184 + * This program, aufs is free software; you can redistribute it and/or modify
8185 + * it under the terms of the GNU General Public License as published by
8186 + * the Free Software Foundation; either version 2 of the License, or
8187 + * (at your option) any later version.
8188 + *
8189 + * This program is distributed in the hope that it will be useful,
8190 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8191 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8192 + * GNU General Public License for more details.
8193 + *
8194 + * You should have received a copy of the GNU General Public License
8195 + * along with this program; if not, write to the Free Software
8196 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
8197 + */
8198 +
8199 +/*
8200 + * directory operations
8201 + */
8202 +
8203 +#include <linux/fs_stack.h>
8204 +#include "aufs.h"
8205 +
8206 +void au_add_nlink(struct inode *dir, struct inode *h_dir)
8207 +{
8208 +       unsigned int nlink;
8209 +
8210 +       AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8211 +
8212 +       nlink = dir->i_nlink;
8213 +       nlink += h_dir->i_nlink - 2;
8214 +       if (h_dir->i_nlink < 2)
8215 +               nlink += 2;
8216 +       smp_mb();
8217 +       /* 0 can happen in revaliding */
8218 +       set_nlink(dir, nlink);
8219 +}
8220 +
8221 +void au_sub_nlink(struct inode *dir, struct inode *h_dir)
8222 +{
8223 +       unsigned int nlink;
8224 +
8225 +       AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8226 +
8227 +       nlink = dir->i_nlink;
8228 +       nlink -= h_dir->i_nlink - 2;
8229 +       if (h_dir->i_nlink < 2)
8230 +               nlink -= 2;
8231 +       smp_mb();
8232 +       /* nlink == 0 means the branch-fs is broken */
8233 +       set_nlink(dir, nlink);
8234 +}
8235 +
8236 +loff_t au_dir_size(struct file *file, struct dentry *dentry)
8237 +{
8238 +       loff_t sz;
8239 +       aufs_bindex_t bindex, bend;
8240 +       struct file *h_file;
8241 +       struct dentry *h_dentry;
8242 +
8243 +       sz = 0;
8244 +       if (file) {
8245 +               AuDebugOn(!file_inode(file));
8246 +               AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
8247 +
8248 +               bend = au_fbend_dir(file);
8249 +               for (bindex = au_fbstart(file);
8250 +                    bindex <= bend && sz < KMALLOC_MAX_SIZE;
8251 +                    bindex++) {
8252 +                       h_file = au_hf_dir(file, bindex);
8253 +                       if (h_file && file_inode(h_file))
8254 +                               sz += vfsub_f_size_read(h_file);
8255 +               }
8256 +       } else {
8257 +               AuDebugOn(!dentry);
8258 +               AuDebugOn(!dentry->d_inode);
8259 +               AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
8260 +
8261 +               bend = au_dbtaildir(dentry);
8262 +               for (bindex = au_dbstart(dentry);
8263 +                    bindex <= bend && sz < KMALLOC_MAX_SIZE;
8264 +                    bindex++) {
8265 +                       h_dentry = au_h_dptr(dentry, bindex);
8266 +                       if (h_dentry && h_dentry->d_inode)
8267 +                               sz += i_size_read(h_dentry->d_inode);
8268 +               }
8269 +       }
8270 +       if (sz < KMALLOC_MAX_SIZE)
8271 +               sz = roundup_pow_of_two(sz);
8272 +       if (sz > KMALLOC_MAX_SIZE)
8273 +               sz = KMALLOC_MAX_SIZE;
8274 +       else if (sz < NAME_MAX) {
8275 +               BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
8276 +               sz = AUFS_RDBLK_DEF;
8277 +       }
8278 +       return sz;
8279 +}
8280 +
8281 +/* ---------------------------------------------------------------------- */
8282 +
8283 +static int reopen_dir(struct file *file)
8284 +{
8285 +       int err;
8286 +       unsigned int flags;
8287 +       aufs_bindex_t bindex, btail, bstart;
8288 +       struct dentry *dentry, *h_dentry;
8289 +       struct file *h_file;
8290 +
8291 +       /* open all lower dirs */
8292 +       dentry = file->f_dentry;
8293 +       bstart = au_dbstart(dentry);
8294 +       for (bindex = au_fbstart(file); bindex < bstart; bindex++)
8295 +               au_set_h_fptr(file, bindex, NULL);
8296 +       au_set_fbstart(file, bstart);
8297 +
8298 +       btail = au_dbtaildir(dentry);
8299 +       for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
8300 +               au_set_h_fptr(file, bindex, NULL);
8301 +       au_set_fbend_dir(file, btail);
8302 +
8303 +       flags = vfsub_file_flags(file);
8304 +       for (bindex = bstart; bindex <= btail; bindex++) {
8305 +               h_dentry = au_h_dptr(dentry, bindex);
8306 +               if (!h_dentry)
8307 +                       continue;
8308 +               h_file = au_hf_dir(file, bindex);
8309 +               if (h_file)
8310 +                       continue;
8311 +
8312 +               h_file = au_h_open(dentry, bindex, flags, file);
8313 +               err = PTR_ERR(h_file);
8314 +               if (IS_ERR(h_file))
8315 +                       goto out; /* close all? */
8316 +               au_set_h_fptr(file, bindex, h_file);
8317 +       }
8318 +       au_update_figen(file);
8319 +       /* todo: necessary? */
8320 +       /* file->f_ra = h_file->f_ra; */
8321 +       err = 0;
8322 +
8323 +out:
8324 +       return err;
8325 +}
8326 +
8327 +static int do_open_dir(struct file *file, int flags)
8328 +{
8329 +       int err;
8330 +       aufs_bindex_t bindex, btail;
8331 +       struct dentry *dentry, *h_dentry;
8332 +       struct file *h_file;
8333 +
8334 +       FiMustWriteLock(file);
8335 +
8336 +       dentry = file->f_dentry;
8337 +       err = au_alive_dir(dentry);
8338 +       if (unlikely(err))
8339 +               goto out;
8340 +
8341 +       file->f_version = dentry->d_inode->i_version;
8342 +       bindex = au_dbstart(dentry);
8343 +       au_set_fbstart(file, bindex);
8344 +       btail = au_dbtaildir(dentry);
8345 +       au_set_fbend_dir(file, btail);
8346 +       for (; !err && bindex <= btail; bindex++) {
8347 +               h_dentry = au_h_dptr(dentry, bindex);
8348 +               if (!h_dentry)
8349 +                       continue;
8350 +
8351 +               h_file = au_h_open(dentry, bindex, flags, file);
8352 +               if (IS_ERR(h_file)) {
8353 +                       err = PTR_ERR(h_file);
8354 +                       break;
8355 +               }
8356 +               au_set_h_fptr(file, bindex, h_file);
8357 +       }
8358 +       au_update_figen(file);
8359 +       /* todo: necessary? */
8360 +       /* file->f_ra = h_file->f_ra; */
8361 +       if (!err)
8362 +               return 0; /* success */
8363 +
8364 +       /* close all */
8365 +       for (bindex = au_fbstart(file); bindex <= btail; bindex++)
8366 +               au_set_h_fptr(file, bindex, NULL);
8367 +       au_set_fbstart(file, -1);
8368 +       au_set_fbend_dir(file, -1);
8369 +
8370 +out:
8371 +       return err;
8372 +}
8373 +
8374 +static int aufs_open_dir(struct inode *inode __maybe_unused,
8375 +                        struct file *file)
8376 +{
8377 +       int err;
8378 +       struct super_block *sb;
8379 +       struct au_fidir *fidir;
8380 +
8381 +       err = -ENOMEM;
8382 +       sb = file->f_dentry->d_sb;
8383 +       si_read_lock(sb, AuLock_FLUSH);
8384 +       fidir = au_fidir_alloc(sb);
8385 +       if (fidir) {
8386 +               err = au_do_open(file, do_open_dir, fidir);
8387 +               if (unlikely(err))
8388 +                       kfree(fidir);
8389 +       }
8390 +       si_read_unlock(sb);
8391 +       return err;
8392 +}
8393 +
8394 +static int aufs_release_dir(struct inode *inode __maybe_unused,
8395 +                           struct file *file)
8396 +{
8397 +       struct au_vdir *vdir_cache;
8398 +       struct au_finfo *finfo;
8399 +       struct au_fidir *fidir;
8400 +       aufs_bindex_t bindex, bend;
8401 +
8402 +       finfo = au_fi(file);
8403 +       fidir = finfo->fi_hdir;
8404 +       if (fidir) {
8405 +               vdir_cache = fidir->fd_vdir_cache; /* lock-free */
8406 +               if (vdir_cache)
8407 +                       au_vdir_free(vdir_cache);
8408 +
8409 +               bindex = finfo->fi_btop;
8410 +               if (bindex >= 0) {
8411 +                       /*
8412 +                        * calls fput() instead of filp_close(),
8413 +                        * since no dnotify or lock for the lower file.
8414 +                        */
8415 +                       bend = fidir->fd_bbot;
8416 +                       for (; bindex <= bend; bindex++)
8417 +                               au_set_h_fptr(file, bindex, NULL);
8418 +               }
8419 +               kfree(fidir);
8420 +               finfo->fi_hdir = NULL;
8421 +       }
8422 +       au_finfo_fin(file);
8423 +       return 0;
8424 +}
8425 +
8426 +/* ---------------------------------------------------------------------- */
8427 +
8428 +static int au_do_flush_dir(struct file *file, fl_owner_t id)
8429 +{
8430 +       int err;
8431 +       aufs_bindex_t bindex, bend;
8432 +       struct file *h_file;
8433 +
8434 +       err = 0;
8435 +       bend = au_fbend_dir(file);
8436 +       for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8437 +               h_file = au_hf_dir(file, bindex);
8438 +               if (h_file)
8439 +                       err = vfsub_flush(h_file, id);
8440 +       }
8441 +       return err;
8442 +}
8443 +
8444 +static int aufs_flush_dir(struct file *file, fl_owner_t id)
8445 +{
8446 +       return au_do_flush(file, id, au_do_flush_dir);
8447 +}
8448 +
8449 +/* ---------------------------------------------------------------------- */
8450 +
8451 +static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
8452 +{
8453 +       int err;
8454 +       aufs_bindex_t bend, bindex;
8455 +       struct inode *inode;
8456 +       struct super_block *sb;
8457 +
8458 +       err = 0;
8459 +       sb = dentry->d_sb;
8460 +       inode = dentry->d_inode;
8461 +       IMustLock(inode);
8462 +       bend = au_dbend(dentry);
8463 +       for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
8464 +               struct path h_path;
8465 +
8466 +               if (au_test_ro(sb, bindex, inode))
8467 +                       continue;
8468 +               h_path.dentry = au_h_dptr(dentry, bindex);
8469 +               if (!h_path.dentry)
8470 +                       continue;
8471 +
8472 +               h_path.mnt = au_sbr_mnt(sb, bindex);
8473 +               err = vfsub_fsync(NULL, &h_path, datasync);
8474 +       }
8475 +
8476 +       return err;
8477 +}
8478 +
8479 +static int au_do_fsync_dir(struct file *file, int datasync)
8480 +{
8481 +       int err;
8482 +       aufs_bindex_t bend, bindex;
8483 +       struct file *h_file;
8484 +       struct super_block *sb;
8485 +       struct inode *inode;
8486 +
8487 +       err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8488 +       if (unlikely(err))
8489 +               goto out;
8490 +
8491 +       sb = file->f_dentry->d_sb;
8492 +       inode = file_inode(file);
8493 +       bend = au_fbend_dir(file);
8494 +       for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8495 +               h_file = au_hf_dir(file, bindex);
8496 +               if (!h_file || au_test_ro(sb, bindex, inode))
8497 +                       continue;
8498 +
8499 +               err = vfsub_fsync(h_file, &h_file->f_path, datasync);
8500 +       }
8501 +
8502 +out:
8503 +       return err;
8504 +}
8505 +
8506 +/*
8507 + * @file may be NULL
8508 + */
8509 +static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
8510 +                         int datasync)
8511 +{
8512 +       int err;
8513 +       struct dentry *dentry;
8514 +       struct super_block *sb;
8515 +       struct mutex *mtx;
8516 +
8517 +       err = 0;
8518 +       dentry = file->f_dentry;
8519 +       mtx = &dentry->d_inode->i_mutex;
8520 +       mutex_lock(mtx);
8521 +       sb = dentry->d_sb;
8522 +       si_noflush_read_lock(sb);
8523 +       if (file)
8524 +               err = au_do_fsync_dir(file, datasync);
8525 +       else {
8526 +               di_write_lock_child(dentry);
8527 +               err = au_do_fsync_dir_no_file(dentry, datasync);
8528 +       }
8529 +       au_cpup_attr_timesizes(dentry->d_inode);
8530 +       di_write_unlock(dentry);
8531 +       if (file)
8532 +               fi_write_unlock(file);
8533 +
8534 +       si_read_unlock(sb);
8535 +       mutex_unlock(mtx);
8536 +       return err;
8537 +}
8538 +
8539 +/* ---------------------------------------------------------------------- */
8540 +
8541 +static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir)
8542 +{
8543 +       int err;
8544 +       struct dentry *dentry;
8545 +       struct inode *inode, *h_inode;
8546 +       struct super_block *sb;
8547 +
8548 +       dentry = file->f_dentry;
8549 +       inode = dentry->d_inode;
8550 +       IMustLock(inode);
8551 +
8552 +       sb = dentry->d_sb;
8553 +       si_read_lock(sb, AuLock_FLUSH);
8554 +       err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8555 +       if (unlikely(err))
8556 +               goto out;
8557 +       err = au_alive_dir(dentry);
8558 +       if (!err)
8559 +               err = au_vdir_init(file);
8560 +       di_downgrade_lock(dentry, AuLock_IR);
8561 +       if (unlikely(err))
8562 +               goto out_unlock;
8563 +
8564 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
8565 +       if (!au_test_nfsd()) {
8566 +               err = au_vdir_fill_de(file, dirent, filldir);
8567 +               fsstack_copy_attr_atime(inode, h_inode);
8568 +       } else {
8569 +               /*
8570 +                * nfsd filldir may call lookup_one_len(), vfs_getattr(),
8571 +                * encode_fh() and others.
8572 +                */
8573 +               atomic_inc(&h_inode->i_count);
8574 +               di_read_unlock(dentry, AuLock_IR);
8575 +               si_read_unlock(sb);
8576 +               err = au_vdir_fill_de(file, dirent, filldir);
8577 +               fsstack_copy_attr_atime(inode, h_inode);
8578 +               fi_write_unlock(file);
8579 +               iput(h_inode);
8580 +
8581 +               AuTraceErr(err);
8582 +               return err;
8583 +       }
8584 +
8585 +out_unlock:
8586 +       di_read_unlock(dentry, AuLock_IR);
8587 +       fi_write_unlock(file);
8588 +out:
8589 +       si_read_unlock(sb);
8590 +       return err;
8591 +}
8592 +
8593 +/* ---------------------------------------------------------------------- */
8594 +
8595 +#define AuTestEmpty_WHONLY     1
8596 +#define AuTestEmpty_CALLED     (1 << 1)
8597 +#define AuTestEmpty_SHWH       (1 << 2)
8598 +#define au_ftest_testempty(flags, name)        ((flags) & AuTestEmpty_##name)
8599 +#define au_fset_testempty(flags, name) \
8600 +       do { (flags) |= AuTestEmpty_##name; } while (0)
8601 +#define au_fclr_testempty(flags, name) \
8602 +       do { (flags) &= ~AuTestEmpty_##name; } while (0)
8603 +
8604 +#ifndef CONFIG_AUFS_SHWH
8605 +#undef AuTestEmpty_SHWH
8606 +#define AuTestEmpty_SHWH       0
8607 +#endif
8608 +
8609 +struct test_empty_arg {
8610 +       struct au_nhash *whlist;
8611 +       unsigned int flags;
8612 +       int err;
8613 +       aufs_bindex_t bindex;
8614 +};
8615 +
8616 +static int test_empty_cb(void *__arg, const char *__name, int namelen,
8617 +                        loff_t offset __maybe_unused, u64 ino,
8618 +                        unsigned int d_type)
8619 +{
8620 +       struct test_empty_arg *arg = __arg;
8621 +       char *name = (void *)__name;
8622 +
8623 +       arg->err = 0;
8624 +       au_fset_testempty(arg->flags, CALLED);
8625 +       /* smp_mb(); */
8626 +       if (name[0] == '.'
8627 +           && (namelen == 1 || (name[1] == '.' && namelen == 2)))
8628 +               goto out; /* success */
8629 +
8630 +       if (namelen <= AUFS_WH_PFX_LEN
8631 +           || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
8632 +               if (au_ftest_testempty(arg->flags, WHONLY)
8633 +                   && !au_nhash_test_known_wh(arg->whlist, name, namelen))
8634 +                       arg->err = -ENOTEMPTY;
8635 +               goto out;
8636 +       }
8637 +
8638 +       name += AUFS_WH_PFX_LEN;
8639 +       namelen -= AUFS_WH_PFX_LEN;
8640 +       if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
8641 +               arg->err = au_nhash_append_wh
8642 +                       (arg->whlist, name, namelen, ino, d_type, arg->bindex,
8643 +                        au_ftest_testempty(arg->flags, SHWH));
8644 +
8645 +out:
8646 +       /* smp_mb(); */
8647 +       AuTraceErr(arg->err);
8648 +       return arg->err;
8649 +}
8650 +
8651 +static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8652 +{
8653 +       int err;
8654 +       struct file *h_file;
8655 +
8656 +       h_file = au_h_open(dentry, arg->bindex,
8657 +                          O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
8658 +                          /*file*/NULL);
8659 +       err = PTR_ERR(h_file);
8660 +       if (IS_ERR(h_file))
8661 +               goto out;
8662 +
8663 +       err = 0;
8664 +       if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
8665 +           && !file_inode(h_file)->i_nlink)
8666 +               goto out_put;
8667 +
8668 +       do {
8669 +               arg->err = 0;
8670 +               au_fclr_testempty(arg->flags, CALLED);
8671 +               /* smp_mb(); */
8672 +               err = vfsub_readdir(h_file, test_empty_cb, arg);
8673 +               if (err >= 0)
8674 +                       err = arg->err;
8675 +       } while (!err && au_ftest_testempty(arg->flags, CALLED));
8676 +
8677 +out_put:
8678 +       fput(h_file);
8679 +       au_sbr_put(dentry->d_sb, arg->bindex);
8680 +out:
8681 +       return err;
8682 +}
8683 +
8684 +struct do_test_empty_args {
8685 +       int *errp;
8686 +       struct dentry *dentry;
8687 +       struct test_empty_arg *arg;
8688 +};
8689 +
8690 +static void call_do_test_empty(void *args)
8691 +{
8692 +       struct do_test_empty_args *a = args;
8693 +       *a->errp = do_test_empty(a->dentry, a->arg);
8694 +}
8695 +
8696 +static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
8697 +{
8698 +       int err, wkq_err;
8699 +       struct dentry *h_dentry;
8700 +       struct inode *h_inode;
8701 +
8702 +       h_dentry = au_h_dptr(dentry, arg->bindex);
8703 +       h_inode = h_dentry->d_inode;
8704 +       /* todo: i_mode changes anytime? */
8705 +       mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
8706 +       err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
8707 +       mutex_unlock(&h_inode->i_mutex);
8708 +       if (!err)
8709 +               err = do_test_empty(dentry, arg);
8710 +       else {
8711 +               struct do_test_empty_args args = {
8712 +                       .errp   = &err,
8713 +                       .dentry = dentry,
8714 +                       .arg    = arg
8715 +               };
8716 +               unsigned int flags = arg->flags;
8717 +
8718 +               wkq_err = au_wkq_wait(call_do_test_empty, &args);
8719 +               if (unlikely(wkq_err))
8720 +                       err = wkq_err;
8721 +               arg->flags = flags;
8722 +       }
8723 +
8724 +       return err;
8725 +}
8726 +
8727 +int au_test_empty_lower(struct dentry *dentry)
8728 +{
8729 +       int err;
8730 +       unsigned int rdhash;
8731 +       aufs_bindex_t bindex, bstart, btail;
8732 +       struct au_nhash whlist;
8733 +       struct test_empty_arg arg;
8734 +
8735 +       SiMustAnyLock(dentry->d_sb);
8736 +
8737 +       rdhash = au_sbi(dentry->d_sb)->si_rdhash;
8738 +       if (!rdhash)
8739 +               rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
8740 +       err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
8741 +       if (unlikely(err))
8742 +               goto out;
8743 +
8744 +       arg.flags = 0;
8745 +       arg.whlist = &whlist;
8746 +       bstart = au_dbstart(dentry);
8747 +       if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8748 +               au_fset_testempty(arg.flags, SHWH);
8749 +       arg.bindex = bstart;
8750 +       err = do_test_empty(dentry, &arg);
8751 +       if (unlikely(err))
8752 +               goto out_whlist;
8753 +
8754 +       au_fset_testempty(arg.flags, WHONLY);
8755 +       btail = au_dbtaildir(dentry);
8756 +       for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
8757 +               struct dentry *h_dentry;
8758 +
8759 +               h_dentry = au_h_dptr(dentry, bindex);
8760 +               if (h_dentry && h_dentry->d_inode) {
8761 +                       arg.bindex = bindex;
8762 +                       err = do_test_empty(dentry, &arg);
8763 +               }
8764 +       }
8765 +
8766 +out_whlist:
8767 +       au_nhash_wh_free(&whlist);
8768 +out:
8769 +       return err;
8770 +}
8771 +
8772 +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
8773 +{
8774 +       int err;
8775 +       struct test_empty_arg arg;
8776 +       aufs_bindex_t bindex, btail;
8777 +
8778 +       err = 0;
8779 +       arg.whlist = whlist;
8780 +       arg.flags = AuTestEmpty_WHONLY;
8781 +       if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8782 +               au_fset_testempty(arg.flags, SHWH);
8783 +       btail = au_dbtaildir(dentry);
8784 +       for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
8785 +               struct dentry *h_dentry;
8786 +
8787 +               h_dentry = au_h_dptr(dentry, bindex);
8788 +               if (h_dentry && h_dentry->d_inode) {
8789 +                       arg.bindex = bindex;
8790 +                       err = sio_test_empty(dentry, &arg);
8791 +               }
8792 +       }
8793 +
8794 +       return err;
8795 +}
8796 +
8797 +/* ---------------------------------------------------------------------- */
8798 +
8799 +const struct file_operations aufs_dir_fop = {
8800 +       .owner          = THIS_MODULE,
8801 +       .llseek         = default_llseek,
8802 +       .read           = generic_read_dir,
8803 +       .readdir        = aufs_readdir,
8804 +       .unlocked_ioctl = aufs_ioctl_dir,
8805 +#ifdef CONFIG_COMPAT
8806 +       .compat_ioctl   = aufs_compat_ioctl_dir,
8807 +#endif
8808 +       .open           = aufs_open_dir,
8809 +       .release        = aufs_release_dir,
8810 +       .flush          = aufs_flush_dir,
8811 +       .fsync          = aufs_fsync_dir
8812 +};
8813 diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
8814 --- /usr/share/empty/fs/aufs/dir.h      1970-01-01 01:00:00.000000000 +0100
8815 +++ linux/fs/aufs/dir.h 2013-07-30 22:42:55.839613269 +0200
8816 @@ -0,0 +1,137 @@
8817 +/*
8818 + * Copyright (C) 2005-2013 Junjiro R. Okajima
8819 + *
8820 + * This program, aufs is free software; you can redistribute it and/or modify
8821 + * it under the terms of the GNU General Public License as published by
8822 + * the Free Software Foundation; either version 2 of the License, or
8823 + * (at your option) any later version.
8824 + *
8825 + * This program is distributed in the hope that it will be useful,
8826 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8827 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8828 + * GNU General Public License for more details.
8829 + *
8830 + * You should have received a copy of the GNU General Public License
8831 + * along with this program; if not, write to the Free Software
8832 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
8833 + */
8834 +
8835 +/*
8836 + * directory operations
8837 + */
8838 +
8839 +#ifndef __AUFS_DIR_H__
8840 +#define __AUFS_DIR_H__
8841 +
8842 +#ifdef __KERNEL__
8843 +
8844 +#include <linux/fs.h>
8845 +
8846 +/* ---------------------------------------------------------------------- */
8847 +
8848 +/* need to be faster and smaller */
8849 +
8850 +struct au_nhash {
8851 +       unsigned int            nh_num;
8852 +       struct hlist_head       *nh_head;
8853 +};
8854 +
8855 +struct au_vdir_destr {
8856 +       unsigned char   len;
8857 +       unsigned char   name[0];
8858 +} __packed;
8859 +
8860 +struct au_vdir_dehstr {
8861 +       struct hlist_node       hash;
8862 +       struct au_vdir_destr    *str;
8863 +} ____cacheline_aligned_in_smp;
8864 +
8865 +struct au_vdir_de {
8866 +       ino_t                   de_ino;
8867 +       unsigned char           de_type;
8868 +       /* caution: packed */
8869 +       struct au_vdir_destr    de_str;
8870 +} __packed;
8871 +
8872 +struct au_vdir_wh {
8873 +       struct hlist_node       wh_hash;
8874 +#ifdef CONFIG_AUFS_SHWH
8875 +       ino_t                   wh_ino;
8876 +       aufs_bindex_t           wh_bindex;
8877 +       unsigned char           wh_type;
8878 +#else
8879 +       aufs_bindex_t           wh_bindex;
8880 +#endif
8881 +       /* caution: packed */
8882 +       struct au_vdir_destr    wh_str;
8883 +} __packed;
8884 +
8885 +union au_vdir_deblk_p {
8886 +       unsigned char           *deblk;
8887 +       struct au_vdir_de       *de;
8888 +};
8889 +
8890 +struct au_vdir {
8891 +       unsigned char   **vd_deblk;
8892 +       unsigned long   vd_nblk;
8893 +       struct {
8894 +               unsigned long           ul;
8895 +               union au_vdir_deblk_p   p;
8896 +       } vd_last;
8897 +
8898 +       unsigned long   vd_version;
8899 +       unsigned int    vd_deblk_sz;
8900 +       unsigned long   vd_jiffy;
8901 +} ____cacheline_aligned_in_smp;
8902 +
8903 +/* ---------------------------------------------------------------------- */
8904 +
8905 +/* dir.c */
8906 +extern const struct file_operations aufs_dir_fop;
8907 +void au_add_nlink(struct inode *dir, struct inode *h_dir);
8908 +void au_sub_nlink(struct inode *dir, struct inode *h_dir);
8909 +loff_t au_dir_size(struct file *file, struct dentry *dentry);
8910 +int au_test_empty_lower(struct dentry *dentry);
8911 +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
8912 +
8913 +/* vdir.c */
8914 +unsigned int au_rdhash_est(loff_t sz);
8915 +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
8916 +void au_nhash_wh_free(struct au_nhash *whlist);
8917 +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
8918 +                           int limit);
8919 +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
8920 +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
8921 +                      unsigned int d_type, aufs_bindex_t bindex,
8922 +                      unsigned char shwh);
8923 +void au_vdir_free(struct au_vdir *vdir);
8924 +int au_vdir_init(struct file *file);
8925 +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir);
8926 +
8927 +/* ioctl.c */
8928 +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
8929 +
8930 +#ifdef CONFIG_AUFS_RDU
8931 +/* rdu.c */
8932 +long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
8933 +#ifdef CONFIG_COMPAT
8934 +long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
8935 +                        unsigned long arg);
8936 +#endif
8937 +#else
8938 +static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
8939 +                               unsigned long arg)
8940 +{
8941 +       return -EINVAL;
8942 +}
8943 +#ifdef CONFIG_COMPAT
8944 +static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
8945 +                                      unsigned long arg)
8946 +{
8947 +       return -EINVAL;
8948 +}
8949 +#endif
8950 +#endif
8951 +
8952 +#endif /* __KERNEL__ */
8953 +#endif /* __AUFS_DIR_H__ */
8954 diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
8955 --- /usr/share/empty/fs/aufs/dynop.c    1970-01-01 01:00:00.000000000 +0100
8956 +++ linux/fs/aufs/dynop.c       2013-07-30 22:42:55.839613269 +0200
8957 @@ -0,0 +1,379 @@
8958 +/*
8959 + * Copyright (C) 2010-2013 Junjiro R. Okajima
8960 + *
8961 + * This program, aufs is free software; you can redistribute it and/or modify
8962 + * it under the terms of the GNU General Public License as published by
8963 + * the Free Software Foundation; either version 2 of the License, or
8964 + * (at your option) any later version.
8965 + *
8966 + * This program is distributed in the hope that it will be useful,
8967 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8968 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8969 + * GNU General Public License for more details.
8970 + *
8971 + * You should have received a copy of the GNU General Public License
8972 + * along with this program; if not, write to the Free Software
8973 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
8974 + */
8975 +
8976 +/*
8977 + * dynamically customizable operations for regular files
8978 + */
8979 +
8980 +#include "aufs.h"
8981 +
8982 +#define DyPrSym(key)   AuDbgSym(key->dk_op.dy_hop)
8983 +
8984 +/*
8985 + * How large will these lists be?
8986 + * Usually just a few elements, 20-30 at most for each, I guess.
8987 + */
8988 +static struct au_splhead dynop[AuDyLast];
8989 +
8990 +static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
8991 +{
8992 +       struct au_dykey *key, *tmp;
8993 +       struct list_head *head;
8994 +
8995 +       key = NULL;
8996 +       head = &spl->head;
8997 +       rcu_read_lock();
8998 +       list_for_each_entry_rcu(tmp, head, dk_list)
8999 +               if (tmp->dk_op.dy_hop == h_op) {
9000 +                       key = tmp;
9001 +                       kref_get(&key->dk_kref);
9002 +                       break;
9003 +               }
9004 +       rcu_read_unlock();
9005 +
9006 +       return key;
9007 +}
9008 +
9009 +static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
9010 +{
9011 +       struct au_dykey **k, *found;
9012 +       const void *h_op = key->dk_op.dy_hop;
9013 +       int i;
9014 +
9015 +       found = NULL;
9016 +       k = br->br_dykey;
9017 +       for (i = 0; i < AuBrDynOp; i++)
9018 +               if (k[i]) {
9019 +                       if (k[i]->dk_op.dy_hop == h_op) {
9020 +                               found = k[i];
9021 +                               break;
9022 +                       }
9023 +               } else
9024 +                       break;
9025 +       if (!found) {
9026 +               spin_lock(&br->br_dykey_lock);
9027 +               for (; i < AuBrDynOp; i++)
9028 +                       if (k[i]) {
9029 +                               if (k[i]->dk_op.dy_hop == h_op) {
9030 +                                       found = k[i];
9031 +                                       break;
9032 +                               }
9033 +                       } else {
9034 +                               k[i] = key;
9035 +                               break;
9036 +                       }
9037 +               spin_unlock(&br->br_dykey_lock);
9038 +               BUG_ON(i == AuBrDynOp); /* expand the array */
9039 +       }
9040 +
9041 +       return found;
9042 +}
9043 +
9044 +/* kref_get() if @key is already added */
9045 +static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
9046 +{
9047 +       struct au_dykey *tmp, *found;
9048 +       struct list_head *head;
9049 +       const void *h_op = key->dk_op.dy_hop;
9050 +
9051 +       found = NULL;
9052 +       head = &spl->head;
9053 +       spin_lock(&spl->spin);
9054 +       list_for_each_entry(tmp, head, dk_list)
9055 +               if (tmp->dk_op.dy_hop == h_op) {
9056 +                       kref_get(&tmp->dk_kref);
9057 +                       found = tmp;
9058 +                       break;
9059 +               }
9060 +       if (!found)
9061 +               list_add_rcu(&key->dk_list, head);
9062 +       spin_unlock(&spl->spin);
9063 +
9064 +       if (!found)
9065 +               DyPrSym(key);
9066 +       return found;
9067 +}
9068 +
9069 +static void dy_free_rcu(struct rcu_head *rcu)
9070 +{
9071 +       struct au_dykey *key;
9072 +
9073 +       key = container_of(rcu, struct au_dykey, dk_rcu);
9074 +       DyPrSym(key);
9075 +       kfree(key);
9076 +}
9077 +
9078 +static void dy_free(struct kref *kref)
9079 +{
9080 +       struct au_dykey *key;
9081 +       struct au_splhead *spl;
9082 +
9083 +       key = container_of(kref, struct au_dykey, dk_kref);
9084 +       spl = dynop + key->dk_op.dy_type;
9085 +       au_spl_del_rcu(&key->dk_list, spl);
9086 +       call_rcu(&key->dk_rcu, dy_free_rcu);
9087 +}
9088 +
9089 +void au_dy_put(struct au_dykey *key)
9090 +{
9091 +       kref_put(&key->dk_kref, dy_free);
9092 +}
9093 +
9094 +/* ---------------------------------------------------------------------- */
9095 +
9096 +#define DyDbgSize(cnt, op)     AuDebugOn(cnt != sizeof(op)/sizeof(void *))
9097 +
9098 +#ifdef CONFIG_AUFS_DEBUG
9099 +#define DyDbgDeclare(cnt)      unsigned int cnt = 0
9100 +#define DyDbgInc(cnt)          do { cnt++; } while (0)
9101 +#else
9102 +#define DyDbgDeclare(cnt)      do {} while (0)
9103 +#define DyDbgInc(cnt)          do {} while (0)
9104 +#endif
9105 +
9106 +#define DySet(func, dst, src, h_op, h_sb) do {                         \
9107 +       DyDbgInc(cnt);                                                  \
9108 +       if (h_op->func) {                                               \
9109 +               if (src.func)                                           \
9110 +                       dst.func = src.func;                            \
9111 +               else                                                    \
9112 +                       AuDbg("%s %s\n", au_sbtype(h_sb), #func);       \
9113 +       }                                                               \
9114 +} while (0)
9115 +
9116 +#define DySetForce(func, dst, src) do {                \
9117 +       AuDebugOn(!src.func);                   \
9118 +       DyDbgInc(cnt);                          \
9119 +       dst.func = src.func;                    \
9120 +} while (0)
9121 +
9122 +#define DySetAop(func) \
9123 +       DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
9124 +#define DySetAopForce(func) \
9125 +       DySetForce(func, dyaop->da_op, aufs_aop)
9126 +
9127 +static void dy_aop(struct au_dykey *key, const void *h_op,
9128 +                  struct super_block *h_sb __maybe_unused)
9129 +{
9130 +       struct au_dyaop *dyaop = (void *)key;
9131 +       const struct address_space_operations *h_aop = h_op;
9132 +       DyDbgDeclare(cnt);
9133 +
9134 +       AuDbg("%s\n", au_sbtype(h_sb));
9135 +
9136 +       DySetAop(writepage);
9137 +       DySetAopForce(readpage);        /* force */
9138 +       DySetAop(writepages);
9139 +       DySetAop(set_page_dirty);
9140 +       DySetAop(readpages);
9141 +       DySetAop(write_begin);
9142 +       DySetAop(write_end);
9143 +       DySetAop(bmap);
9144 +       DySetAop(invalidatepage);
9145 +       DySetAop(releasepage);
9146 +       DySetAop(freepage);
9147 +       /* these two will be changed according to an aufs mount option */
9148 +       DySetAop(direct_IO);
9149 +       DySetAop(get_xip_mem);
9150 +       DySetAop(migratepage);
9151 +       DySetAop(launder_page);
9152 +       DySetAop(is_partially_uptodate);
9153 +       DySetAop(error_remove_page);
9154 +       DySetAop(swap_activate);
9155 +       DySetAop(swap_deactivate);
9156 +
9157 +       DyDbgSize(cnt, *h_aop);
9158 +       dyaop->da_get_xip_mem = h_aop->get_xip_mem;
9159 +}
9160 +
9161 +/* ---------------------------------------------------------------------- */
9162 +
9163 +static void dy_bug(struct kref *kref)
9164 +{
9165 +       BUG();
9166 +}
9167 +
9168 +static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
9169 +{
9170 +       struct au_dykey *key, *old;
9171 +       struct au_splhead *spl;
9172 +       struct op {
9173 +               unsigned int sz;
9174 +               void (*set)(struct au_dykey *key, const void *h_op,
9175 +                           struct super_block *h_sb __maybe_unused);
9176 +       };
9177 +       static const struct op a[] = {
9178 +               [AuDy_AOP] = {
9179 +                       .sz     = sizeof(struct au_dyaop),
9180 +                       .set    = dy_aop
9181 +               }
9182 +       };
9183 +       const struct op *p;
9184 +
9185 +       spl = dynop + op->dy_type;
9186 +       key = dy_gfind_get(spl, op->dy_hop);
9187 +       if (key)
9188 +               goto out_add; /* success */
9189 +
9190 +       p = a + op->dy_type;
9191 +       key = kzalloc(p->sz, GFP_NOFS);
9192 +       if (unlikely(!key)) {
9193 +               key = ERR_PTR(-ENOMEM);
9194 +               goto out;
9195 +       }
9196 +
9197 +       key->dk_op.dy_hop = op->dy_hop;
9198 +       kref_init(&key->dk_kref);
9199 +       p->set(key, op->dy_hop, au_br_sb(br));
9200 +       old = dy_gadd(spl, key);
9201 +       if (old) {
9202 +               kfree(key);
9203 +               key = old;
9204 +       }
9205 +
9206 +out_add:
9207 +       old = dy_bradd(br, key);
9208 +       if (old)
9209 +               /* its ref-count should never be zero here */
9210 +               kref_put(&key->dk_kref, dy_bug);
9211 +out:
9212 +       return key;
9213 +}
9214 +
9215 +/* ---------------------------------------------------------------------- */
9216 +/*
9217 + * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
9218 + * This behaviour is neccessary to return an error from open(O_DIRECT) instead
9219 + * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
9220 + * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
9221 + * See the aufs manual in detail.
9222 + *
9223 + * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
9224 + * performance of fadvise() and madvise() may be affected.
9225 + */
9226 +static void dy_adx(struct au_dyaop *dyaop, int do_dx)
9227 +{
9228 +       if (!do_dx) {
9229 +               dyaop->da_op.direct_IO = NULL;
9230 +               dyaop->da_op.get_xip_mem = NULL;
9231 +       } else {
9232 +               dyaop->da_op.direct_IO = aufs_aop.direct_IO;
9233 +               dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
9234 +               if (!dyaop->da_get_xip_mem)
9235 +                       dyaop->da_op.get_xip_mem = NULL;
9236 +       }
9237 +}
9238 +
9239 +static struct au_dyaop *dy_aget(struct au_branch *br,
9240 +                               const struct address_space_operations *h_aop,
9241 +                               int do_dx)
9242 +{
9243 +       struct au_dyaop *dyaop;
9244 +       struct au_dynop op;
9245 +
9246 +       op.dy_type = AuDy_AOP;
9247 +       op.dy_haop = h_aop;
9248 +       dyaop = (void *)dy_get(&op, br);
9249 +       if (IS_ERR(dyaop))
9250 +               goto out;
9251 +       dy_adx(dyaop, do_dx);
9252 +
9253 +out:
9254 +       return dyaop;
9255 +}
9256 +
9257 +int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9258 +               struct inode *h_inode)
9259 +{
9260 +       int err, do_dx;
9261 +       struct super_block *sb;
9262 +       struct au_branch *br;
9263 +       struct au_dyaop *dyaop;
9264 +
9265 +       AuDebugOn(!S_ISREG(h_inode->i_mode));
9266 +       IiMustWriteLock(inode);
9267 +
9268 +       sb = inode->i_sb;
9269 +       br = au_sbr(sb, bindex);
9270 +       do_dx = !!au_opt_test(au_mntflags(sb), DIO);
9271 +       dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
9272 +       err = PTR_ERR(dyaop);
9273 +       if (IS_ERR(dyaop))
9274 +               /* unnecessary to call dy_fput() */
9275 +               goto out;
9276 +
9277 +       err = 0;
9278 +       inode->i_mapping->a_ops = &dyaop->da_op;
9279 +
9280 +out:
9281 +       return err;
9282 +}
9283 +
9284 +/*
9285 + * Is it safe to replace a_ops during the inode/file is in operation?
9286 + * Yes, I hope so.
9287 + */
9288 +int au_dy_irefresh(struct inode *inode)
9289 +{
9290 +       int err;
9291 +       aufs_bindex_t bstart;
9292 +       struct inode *h_inode;
9293 +
9294 +       err = 0;
9295 +       if (S_ISREG(inode->i_mode)) {
9296 +               bstart = au_ibstart(inode);
9297 +               h_inode = au_h_iptr(inode, bstart);
9298 +               err = au_dy_iaop(inode, bstart, h_inode);
9299 +       }
9300 +       return err;
9301 +}
9302 +
9303 +void au_dy_arefresh(int do_dx)
9304 +{
9305 +       struct au_splhead *spl;
9306 +       struct list_head *head;
9307 +       struct au_dykey *key;
9308 +
9309 +       spl = dynop + AuDy_AOP;
9310 +       head = &spl->head;
9311 +       spin_lock(&spl->spin);
9312 +       list_for_each_entry(key, head, dk_list)
9313 +               dy_adx((void *)key, do_dx);
9314 +       spin_unlock(&spl->spin);
9315 +}
9316 +
9317 +/* ---------------------------------------------------------------------- */
9318 +
9319 +void __init au_dy_init(void)
9320 +{
9321 +       int i;
9322 +
9323 +       /* make sure that 'struct au_dykey *' can be any type */
9324 +       BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
9325 +
9326 +       for (i = 0; i < AuDyLast; i++)
9327 +               au_spl_init(dynop + i);
9328 +}
9329 +
9330 +void au_dy_fin(void)
9331 +{
9332 +       int i;
9333 +
9334 +       for (i = 0; i < AuDyLast; i++)
9335 +               WARN_ON(!list_empty(&dynop[i].head));
9336 +}
9337 diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
9338 --- /usr/share/empty/fs/aufs/dynop.h    1970-01-01 01:00:00.000000000 +0100
9339 +++ linux/fs/aufs/dynop.h       2013-07-06 13:20:47.740198107 +0200
9340 @@ -0,0 +1,76 @@
9341 +/*
9342 + * Copyright (C) 2010-2013 Junjiro R. Okajima
9343 + *
9344 + * This program, aufs is free software; you can redistribute it and/or modify
9345 + * it under the terms of the GNU General Public License as published by
9346 + * the Free Software Foundation; either version 2 of the License, or
9347 + * (at your option) any later version.
9348 + *
9349 + * This program is distributed in the hope that it will be useful,
9350 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9351 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9352 + * GNU General Public License for more details.
9353 + *
9354 + * You should have received a copy of the GNU General Public License
9355 + * along with this program; if not, write to the Free Software
9356 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
9357 + */
9358 +
9359 +/*
9360 + * dynamically customizable operations (for regular files only)
9361 + */
9362 +
9363 +#ifndef __AUFS_DYNOP_H__
9364 +#define __AUFS_DYNOP_H__
9365 +
9366 +#ifdef __KERNEL__
9367 +
9368 +#include "inode.h"
9369 +
9370 +enum {AuDy_AOP, AuDyLast};
9371 +
9372 +struct au_dynop {
9373 +       int                                             dy_type;
9374 +       union {
9375 +               const void                              *dy_hop;
9376 +               const struct address_space_operations   *dy_haop;
9377 +       };
9378 +};
9379 +
9380 +struct au_dykey {
9381 +       union {
9382 +               struct list_head        dk_list;
9383 +               struct rcu_head         dk_rcu;
9384 +       };
9385 +       struct au_dynop         dk_op;
9386 +
9387 +       /*
9388 +        * during I am in the branch local array, kref is gotten. when the
9389 +        * branch is removed, kref is put.
9390 +        */
9391 +       struct kref             dk_kref;
9392 +};
9393 +
9394 +/* stop unioning since their sizes are very different from each other */
9395 +struct au_dyaop {
9396 +       struct au_dykey                 da_key;
9397 +       struct address_space_operations da_op; /* not const */
9398 +       int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
9399 +                             void **, unsigned long *);
9400 +};
9401 +
9402 +/* ---------------------------------------------------------------------- */
9403 +
9404 +/* dynop.c */
9405 +struct au_branch;
9406 +void au_dy_put(struct au_dykey *key);
9407 +int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9408 +               struct inode *h_inode);
9409 +int au_dy_irefresh(struct inode *inode);
9410 +void au_dy_arefresh(int do_dio);
9411 +
9412 +void __init au_dy_init(void);
9413 +void au_dy_fin(void);
9414 +
9415 +#endif /* __KERNEL__ */
9416 +#endif /* __AUFS_DYNOP_H__ */
9417 diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
9418 --- /usr/share/empty/fs/aufs/export.c   1970-01-01 01:00:00.000000000 +0100
9419 +++ linux/fs/aufs/export.c      2013-07-30 22:42:55.839613269 +0200
9420 @@ -0,0 +1,826 @@
9421 +/*
9422 + * Copyright (C) 2005-2013 Junjiro R. Okajima
9423 + *
9424 + * This program, aufs is free software; you can redistribute it and/or modify
9425 + * it under the terms of the GNU General Public License as published by
9426 + * the Free Software Foundation; either version 2 of the License, or
9427 + * (at your option) any later version.
9428 + *
9429 + * This program is distributed in the hope that it will be useful,
9430 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9431 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9432 + * GNU General Public License for more details.
9433 + *
9434 + * You should have received a copy of the GNU General Public License
9435 + * along with this program; if not, write to the Free Software
9436 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
9437 + */
9438 +
9439 +/*
9440 + * export via nfs
9441 + */
9442 +
9443 +#include <linux/exportfs.h>
9444 +#include <linux/fs_struct.h>
9445 +#include <linux/namei.h>
9446 +#include <linux/nsproxy.h>
9447 +#include <linux/random.h>
9448 +#include <linux/writeback.h>
9449 +#include "../fs/mount.h"
9450 +#include "aufs.h"
9451 +
9452 +union conv {
9453 +#ifdef CONFIG_AUFS_INO_T_64
9454 +       __u32 a[2];
9455 +#else
9456 +       __u32 a[1];
9457 +#endif
9458 +       ino_t ino;
9459 +};
9460 +
9461 +static ino_t decode_ino(__u32 *a)
9462 +{
9463 +       union conv u;
9464 +
9465 +       BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
9466 +       u.a[0] = a[0];
9467 +#ifdef CONFIG_AUFS_INO_T_64
9468 +       u.a[1] = a[1];
9469 +#endif
9470 +       return u.ino;
9471 +}
9472 +
9473 +static void encode_ino(__u32 *a, ino_t ino)
9474 +{
9475 +       union conv u;
9476 +
9477 +       u.ino = ino;
9478 +       a[0] = u.a[0];
9479 +#ifdef CONFIG_AUFS_INO_T_64
9480 +       a[1] = u.a[1];
9481 +#endif
9482 +}
9483 +
9484 +/* NFS file handle */
9485 +enum {
9486 +       Fh_br_id,
9487 +       Fh_sigen,
9488 +#ifdef CONFIG_AUFS_INO_T_64
9489 +       /* support 64bit inode number */
9490 +       Fh_ino1,
9491 +       Fh_ino2,
9492 +       Fh_dir_ino1,
9493 +       Fh_dir_ino2,
9494 +#else
9495 +       Fh_ino1,
9496 +       Fh_dir_ino1,
9497 +#endif
9498 +       Fh_igen,
9499 +       Fh_h_type,
9500 +       Fh_tail,
9501 +
9502 +       Fh_ino = Fh_ino1,
9503 +       Fh_dir_ino = Fh_dir_ino1
9504 +};
9505 +
9506 +static int au_test_anon(struct dentry *dentry)
9507 +{
9508 +       /* note: read d_flags without d_lock */
9509 +       return !!(dentry->d_flags & DCACHE_DISCONNECTED);
9510 +}
9511 +
9512 +int au_test_nfsd(void)
9513 +{
9514 +       int ret;
9515 +       struct task_struct *tsk = current;
9516 +       char comm[sizeof(tsk->comm)];
9517 +
9518 +       ret = 0;
9519 +       if (tsk->flags & PF_KTHREAD) {
9520 +               get_task_comm(comm, tsk);
9521 +               ret = !strcmp(comm, "nfsd");
9522 +       }
9523 +
9524 +       return ret;
9525 +}
9526 +
9527 +/* ---------------------------------------------------------------------- */
9528 +/* inode generation external table */
9529 +
9530 +void au_xigen_inc(struct inode *inode)
9531 +{
9532 +       loff_t pos;
9533 +       ssize_t sz;
9534 +       __u32 igen;
9535 +       struct super_block *sb;
9536 +       struct au_sbinfo *sbinfo;
9537 +
9538 +       sb = inode->i_sb;
9539 +       AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
9540 +
9541 +       sbinfo = au_sbi(sb);
9542 +       pos = inode->i_ino;
9543 +       pos *= sizeof(igen);
9544 +       igen = inode->i_generation + 1;
9545 +       sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
9546 +                        sizeof(igen), &pos);
9547 +       if (sz == sizeof(igen))
9548 +               return; /* success */
9549 +
9550 +       if (unlikely(sz >= 0))
9551 +               AuIOErr("xigen error (%zd)\n", sz);
9552 +}
9553 +
9554 +int au_xigen_new(struct inode *inode)
9555 +{
9556 +       int err;
9557 +       loff_t pos;
9558 +       ssize_t sz;
9559 +       struct super_block *sb;
9560 +       struct au_sbinfo *sbinfo;
9561 +       struct file *file;
9562 +
9563 +       err = 0;
9564 +       /* todo: dirty, at mount time */
9565 +       if (inode->i_ino == AUFS_ROOT_INO)
9566 +               goto out;
9567 +       sb = inode->i_sb;
9568 +       SiMustAnyLock(sb);
9569 +       if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
9570 +               goto out;
9571 +
9572 +       err = -EFBIG;
9573 +       pos = inode->i_ino;
9574 +       if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
9575 +               AuIOErr1("too large i%lld\n", pos);
9576 +               goto out;
9577 +       }
9578 +       pos *= sizeof(inode->i_generation);
9579 +
9580 +       err = 0;
9581 +       sbinfo = au_sbi(sb);
9582 +       file = sbinfo->si_xigen;
9583 +       BUG_ON(!file);
9584 +
9585 +       if (vfsub_f_size_read(file)
9586 +           < pos + sizeof(inode->i_generation)) {
9587 +               inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
9588 +               sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
9589 +                                sizeof(inode->i_generation), &pos);
9590 +       } else
9591 +               sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
9592 +                               sizeof(inode->i_generation), &pos);
9593 +       if (sz == sizeof(inode->i_generation))
9594 +               goto out; /* success */
9595 +
9596 +       err = sz;
9597 +       if (unlikely(sz >= 0)) {
9598 +               err = -EIO;
9599 +               AuIOErr("xigen error (%zd)\n", sz);
9600 +       }
9601 +
9602 +out:
9603 +       return err;
9604 +}
9605 +
9606 +int au_xigen_set(struct super_block *sb, struct file *base)
9607 +{
9608 +       int err;
9609 +       struct au_sbinfo *sbinfo;
9610 +       struct file *file;
9611 +
9612 +       SiMustWriteLock(sb);
9613 +
9614 +       sbinfo = au_sbi(sb);
9615 +       file = au_xino_create2(base, sbinfo->si_xigen);
9616 +       err = PTR_ERR(file);
9617 +       if (IS_ERR(file))
9618 +               goto out;
9619 +       err = 0;
9620 +       if (sbinfo->si_xigen)
9621 +               fput(sbinfo->si_xigen);
9622 +       sbinfo->si_xigen = file;
9623 +
9624 +out:
9625 +       return err;
9626 +}
9627 +
9628 +void au_xigen_clr(struct super_block *sb)
9629 +{
9630 +       struct au_sbinfo *sbinfo;
9631 +
9632 +       SiMustWriteLock(sb);
9633 +
9634 +       sbinfo = au_sbi(sb);
9635 +       if (sbinfo->si_xigen) {
9636 +               fput(sbinfo->si_xigen);
9637 +               sbinfo->si_xigen = NULL;
9638 +       }
9639 +}
9640 +
9641 +/* ---------------------------------------------------------------------- */
9642 +
9643 +static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
9644 +                                   ino_t dir_ino)
9645 +{
9646 +       struct dentry *dentry, *d;
9647 +       struct inode *inode;
9648 +       unsigned int sigen;
9649 +
9650 +       dentry = NULL;
9651 +       inode = ilookup(sb, ino);
9652 +       if (!inode)
9653 +               goto out;
9654 +
9655 +       dentry = ERR_PTR(-ESTALE);
9656 +       sigen = au_sigen(sb);
9657 +       if (unlikely(is_bad_inode(inode)
9658 +                    || IS_DEADDIR(inode)
9659 +                    || sigen != au_iigen(inode, NULL)))
9660 +               goto out_iput;
9661 +
9662 +       dentry = NULL;
9663 +       if (!dir_ino || S_ISDIR(inode->i_mode))
9664 +               dentry = d_find_alias(inode);
9665 +       else {
9666 +               spin_lock(&inode->i_lock);
9667 +               hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
9668 +                       spin_lock(&d->d_lock);
9669 +                       if (!au_test_anon(d)
9670 +                           && d->d_parent->d_inode->i_ino == dir_ino) {
9671 +                               dentry = dget_dlock(d);
9672 +                               spin_unlock(&d->d_lock);
9673 +                               break;
9674 +                       }
9675 +                       spin_unlock(&d->d_lock);
9676 +               }
9677 +               spin_unlock(&inode->i_lock);
9678 +       }
9679 +       if (unlikely(dentry && au_digen_test(dentry, sigen))) {
9680 +               /* need to refresh */
9681 +               dput(dentry);
9682 +               dentry = NULL;
9683 +       }
9684 +
9685 +out_iput:
9686 +       iput(inode);
9687 +out:
9688 +       AuTraceErrPtr(dentry);
9689 +       return dentry;
9690 +}
9691 +
9692 +/* ---------------------------------------------------------------------- */
9693 +
9694 +/* todo: dirty? */
9695 +/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
9696 +
9697 +struct au_compare_mnt_args {
9698 +       /* input */
9699 +       struct super_block *sb;
9700 +
9701 +       /* output */
9702 +       struct vfsmount *mnt;
9703 +};
9704 +
9705 +static int au_compare_mnt(struct vfsmount *mnt, void *arg)
9706 +{
9707 +       struct au_compare_mnt_args *a = arg;
9708 +
9709 +       if (mnt->mnt_sb != a->sb)
9710 +               return 0;
9711 +       a->mnt = mntget(mnt);
9712 +       return 1;
9713 +}
9714 +
9715 +static struct vfsmount *au_mnt_get(struct super_block *sb)
9716 +{
9717 +       int err;
9718 +       struct path root;
9719 +       struct au_compare_mnt_args args = {
9720 +               .sb = sb
9721 +       };
9722 +
9723 +       get_fs_root(current->fs, &root);
9724 +       br_read_lock(&vfsmount_lock);
9725 +       err = iterate_mounts(au_compare_mnt, &args, root.mnt);
9726 +       br_read_unlock(&vfsmount_lock);
9727 +       path_put(&root);
9728 +       AuDebugOn(!err);
9729 +       AuDebugOn(!args.mnt);
9730 +       return args.mnt;
9731 +}
9732 +
9733 +struct au_nfsd_si_lock {
9734 +       unsigned int sigen;
9735 +       aufs_bindex_t bindex, br_id;
9736 +       unsigned char force_lock;
9737 +};
9738 +
9739 +static int si_nfsd_read_lock(struct super_block *sb,
9740 +                            struct au_nfsd_si_lock *nsi_lock)
9741 +{
9742 +       int err;
9743 +       aufs_bindex_t bindex;
9744 +
9745 +       si_read_lock(sb, AuLock_FLUSH);
9746 +
9747 +       /* branch id may be wrapped around */
9748 +       err = 0;
9749 +       bindex = au_br_index(sb, nsi_lock->br_id);
9750 +       if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
9751 +               goto out; /* success */
9752 +
9753 +       err = -ESTALE;
9754 +       bindex = -1;
9755 +       if (!nsi_lock->force_lock)
9756 +               si_read_unlock(sb);
9757 +
9758 +out:
9759 +       nsi_lock->bindex = bindex;
9760 +       return err;
9761 +}
9762 +
9763 +struct find_name_by_ino {
9764 +       int called, found;
9765 +       ino_t ino;
9766 +       char *name;
9767 +       int namelen;
9768 +};
9769 +
9770 +static int
9771 +find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
9772 +                u64 ino, unsigned int d_type)
9773 +{
9774 +       struct find_name_by_ino *a = arg;
9775 +
9776 +       a->called++;
9777 +       if (a->ino != ino)
9778 +               return 0;
9779 +
9780 +       memcpy(a->name, name, namelen);
9781 +       a->namelen = namelen;
9782 +       a->found = 1;
9783 +       return 1;
9784 +}
9785 +
9786 +static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
9787 +                                    struct au_nfsd_si_lock *nsi_lock)
9788 +{
9789 +       struct dentry *dentry, *parent;
9790 +       struct file *file;
9791 +       struct inode *dir;
9792 +       struct find_name_by_ino arg;
9793 +       int err;
9794 +
9795 +       parent = path->dentry;
9796 +       if (nsi_lock)
9797 +               si_read_unlock(parent->d_sb);
9798 +       file = vfsub_dentry_open(path, au_dir_roflags);
9799 +       dentry = (void *)file;
9800 +       if (IS_ERR(file))
9801 +               goto out;
9802 +
9803 +       dentry = ERR_PTR(-ENOMEM);
9804 +       arg.name = (void *)__get_free_page(GFP_NOFS);
9805 +       if (unlikely(!arg.name))
9806 +               goto out_file;
9807 +       arg.ino = ino;
9808 +       arg.found = 0;
9809 +       do {
9810 +               arg.called = 0;
9811 +               /* smp_mb(); */
9812 +               err = vfsub_readdir(file, find_name_by_ino, &arg);
9813 +       } while (!err && !arg.found && arg.called);
9814 +       dentry = ERR_PTR(err);
9815 +       if (unlikely(err))
9816 +               goto out_name;
9817 +       /* instead of ENOENT */
9818 +       dentry = ERR_PTR(-ESTALE);
9819 +       if (!arg.found)
9820 +               goto out_name;
9821 +
9822 +       /* do not call vfsub_lkup_one() */
9823 +       dir = parent->d_inode;
9824 +       mutex_lock(&dir->i_mutex);
9825 +       dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
9826 +       mutex_unlock(&dir->i_mutex);
9827 +       AuTraceErrPtr(dentry);
9828 +       if (IS_ERR(dentry))
9829 +               goto out_name;
9830 +       AuDebugOn(au_test_anon(dentry));
9831 +       if (unlikely(!dentry->d_inode)) {
9832 +               dput(dentry);
9833 +               dentry = ERR_PTR(-ENOENT);
9834 +       }
9835 +
9836 +out_name:
9837 +       free_page((unsigned long)arg.name);
9838 +out_file:
9839 +       fput(file);
9840 +out:
9841 +       if (unlikely(nsi_lock
9842 +                    && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
9843 +               if (!IS_ERR(dentry)) {
9844 +                       dput(dentry);
9845 +                       dentry = ERR_PTR(-ESTALE);
9846 +               }
9847 +       AuTraceErrPtr(dentry);
9848 +       return dentry;
9849 +}
9850 +
9851 +static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
9852 +                                       ino_t dir_ino,
9853 +                                       struct au_nfsd_si_lock *nsi_lock)
9854 +{
9855 +       struct dentry *dentry;
9856 +       struct path path;
9857 +
9858 +       if (dir_ino != AUFS_ROOT_INO) {
9859 +               path.dentry = decode_by_ino(sb, dir_ino, 0);
9860 +               dentry = path.dentry;
9861 +               if (!path.dentry || IS_ERR(path.dentry))
9862 +                       goto out;
9863 +               AuDebugOn(au_test_anon(path.dentry));
9864 +       } else
9865 +               path.dentry = dget(sb->s_root);
9866 +
9867 +       path.mnt = au_mnt_get(sb);
9868 +       dentry = au_lkup_by_ino(&path, ino, nsi_lock);
9869 +       path_put(&path);
9870 +
9871 +out:
9872 +       AuTraceErrPtr(dentry);
9873 +       return dentry;
9874 +}
9875 +
9876 +/* ---------------------------------------------------------------------- */
9877 +
9878 +static int h_acceptable(void *expv, struct dentry *dentry)
9879 +{
9880 +       return 1;
9881 +}
9882 +
9883 +static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
9884 +                          char *buf, int len, struct super_block *sb)
9885 +{
9886 +       char *p;
9887 +       int n;
9888 +       struct path path;
9889 +
9890 +       p = d_path(h_rootpath, buf, len);
9891 +       if (IS_ERR(p))
9892 +               goto out;
9893 +       n = strlen(p);
9894 +
9895 +       path.mnt = h_rootpath->mnt;
9896 +       path.dentry = h_parent;
9897 +       p = d_path(&path, buf, len);
9898 +       if (IS_ERR(p))
9899 +               goto out;
9900 +       if (n != 1)
9901 +               p += n;
9902 +
9903 +       path.mnt = au_mnt_get(sb);
9904 +       path.dentry = sb->s_root;
9905 +       p = d_path(&path, buf, len - strlen(p));
9906 +       mntput(path.mnt);
9907 +       if (IS_ERR(p))
9908 +               goto out;
9909 +       if (n != 1)
9910 +               p[strlen(p)] = '/';
9911 +
9912 +out:
9913 +       AuTraceErrPtr(p);
9914 +       return p;
9915 +}
9916 +
9917 +static
9918 +struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
9919 +                             int fh_len, struct au_nfsd_si_lock *nsi_lock)
9920 +{
9921 +       struct dentry *dentry, *h_parent, *root;
9922 +       struct super_block *h_sb;
9923 +       char *pathname, *p;
9924 +       struct vfsmount *h_mnt;
9925 +       struct au_branch *br;
9926 +       int err;
9927 +       struct path path;
9928 +
9929 +       br = au_sbr(sb, nsi_lock->bindex);
9930 +       h_mnt = au_br_mnt(br);
9931 +       h_sb = h_mnt->mnt_sb;
9932 +       /* todo: call lower fh_to_dentry()? fh_to_parent()? */
9933 +       h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
9934 +                                     fh_len - Fh_tail, fh[Fh_h_type],
9935 +                                     h_acceptable, /*context*/NULL);
9936 +       dentry = h_parent;
9937 +       if (unlikely(!h_parent || IS_ERR(h_parent))) {
9938 +               AuWarn1("%s decode_fh failed, %ld\n",
9939 +                       au_sbtype(h_sb), PTR_ERR(h_parent));
9940 +               goto out;
9941 +       }
9942 +       dentry = NULL;
9943 +       if (unlikely(au_test_anon(h_parent))) {
9944 +               AuWarn1("%s decode_fh returned a disconnected dentry\n",
9945 +                       au_sbtype(h_sb));
9946 +               goto out_h_parent;
9947 +       }
9948 +
9949 +       dentry = ERR_PTR(-ENOMEM);
9950 +       pathname = (void *)__get_free_page(GFP_NOFS);
9951 +       if (unlikely(!pathname))
9952 +               goto out_h_parent;
9953 +
9954 +       root = sb->s_root;
9955 +       path.mnt = h_mnt;
9956 +       di_read_lock_parent(root, !AuLock_IR);
9957 +       path.dentry = au_h_dptr(root, nsi_lock->bindex);
9958 +       di_read_unlock(root, !AuLock_IR);
9959 +       p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
9960 +       dentry = (void *)p;
9961 +       if (IS_ERR(p))
9962 +               goto out_pathname;
9963 +
9964 +       si_read_unlock(sb);
9965 +       err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
9966 +       dentry = ERR_PTR(err);
9967 +       if (unlikely(err))
9968 +               goto out_relock;
9969 +
9970 +       dentry = ERR_PTR(-ENOENT);
9971 +       AuDebugOn(au_test_anon(path.dentry));
9972 +       if (unlikely(!path.dentry->d_inode))
9973 +               goto out_path;
9974 +
9975 +       if (ino != path.dentry->d_inode->i_ino)
9976 +               dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
9977 +       else
9978 +               dentry = dget(path.dentry);
9979 +
9980 +out_path:
9981 +       path_put(&path);
9982 +out_relock:
9983 +       if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
9984 +               if (!IS_ERR(dentry)) {
9985 +                       dput(dentry);
9986 +                       dentry = ERR_PTR(-ESTALE);
9987 +               }
9988 +out_pathname:
9989 +       free_page((unsigned long)pathname);
9990 +out_h_parent:
9991 +       dput(h_parent);
9992 +out:
9993 +       AuTraceErrPtr(dentry);
9994 +       return dentry;
9995 +}
9996 +
9997 +/* ---------------------------------------------------------------------- */
9998 +
9999 +static struct dentry *
10000 +aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
10001 +                 int fh_type)
10002 +{
10003 +       struct dentry *dentry;
10004 +       __u32 *fh = fid->raw;
10005 +       struct au_branch *br;
10006 +       ino_t ino, dir_ino;
10007 +       struct au_nfsd_si_lock nsi_lock = {
10008 +               .force_lock     = 0
10009 +       };
10010 +
10011 +       dentry = ERR_PTR(-ESTALE);
10012 +       /* it should never happen, but the file handle is unreliable */
10013 +       if (unlikely(fh_len < Fh_tail))
10014 +               goto out;
10015 +       nsi_lock.sigen = fh[Fh_sigen];
10016 +       nsi_lock.br_id = fh[Fh_br_id];
10017 +
10018 +       /* branch id may be wrapped around */
10019 +       br = NULL;
10020 +       if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
10021 +               goto out;
10022 +       nsi_lock.force_lock = 1;
10023 +
10024 +       /* is this inode still cached? */
10025 +       ino = decode_ino(fh + Fh_ino);
10026 +       /* it should never happen */
10027 +       if (unlikely(ino == AUFS_ROOT_INO))
10028 +               goto out;
10029 +
10030 +       dir_ino = decode_ino(fh + Fh_dir_ino);
10031 +       dentry = decode_by_ino(sb, ino, dir_ino);
10032 +       if (IS_ERR(dentry))
10033 +               goto out_unlock;
10034 +       if (dentry)
10035 +               goto accept;
10036 +
10037 +       /* is the parent dir cached? */
10038 +       br = au_sbr(sb, nsi_lock.bindex);
10039 +       atomic_inc(&br->br_count);
10040 +       dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
10041 +       if (IS_ERR(dentry))
10042 +               goto out_unlock;
10043 +       if (dentry)
10044 +               goto accept;
10045 +
10046 +       /* lookup path */
10047 +       dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
10048 +       if (IS_ERR(dentry))
10049 +               goto out_unlock;
10050 +       if (unlikely(!dentry))
10051 +               /* todo?: make it ESTALE */
10052 +               goto out_unlock;
10053 +
10054 +accept:
10055 +       if (!au_digen_test(dentry, au_sigen(sb))
10056 +           && dentry->d_inode->i_generation == fh[Fh_igen])
10057 +               goto out_unlock; /* success */
10058 +
10059 +       dput(dentry);
10060 +       dentry = ERR_PTR(-ESTALE);
10061 +out_unlock:
10062 +       if (br)
10063 +               atomic_dec(&br->br_count);
10064 +       si_read_unlock(sb);
10065 +out:
10066 +       AuTraceErrPtr(dentry);
10067 +       return dentry;
10068 +}
10069 +
10070 +#if 0 /* reserved for future use */
10071 +/* support subtreecheck option */
10072 +static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
10073 +                                       int fh_len, int fh_type)
10074 +{
10075 +       struct dentry *parent;
10076 +       __u32 *fh = fid->raw;
10077 +       ino_t dir_ino;
10078 +
10079 +       dir_ino = decode_ino(fh + Fh_dir_ino);
10080 +       parent = decode_by_ino(sb, dir_ino, 0);
10081 +       if (IS_ERR(parent))
10082 +               goto out;
10083 +       if (!parent)
10084 +               parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
10085 +                                       dir_ino, fh, fh_len);
10086 +
10087 +out:
10088 +       AuTraceErrPtr(parent);
10089 +       return parent;
10090 +}
10091 +#endif
10092 +
10093 +/* ---------------------------------------------------------------------- */
10094 +
10095 +static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
10096 +                         struct inode *dir)
10097 +{
10098 +       int err;
10099 +       aufs_bindex_t bindex;
10100 +       struct super_block *sb, *h_sb;
10101 +       struct dentry *dentry, *parent, *h_parent;
10102 +       struct inode *h_dir;
10103 +       struct au_branch *br;
10104 +
10105 +       err = -ENOSPC;
10106 +       if (unlikely(*max_len <= Fh_tail)) {
10107 +               AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
10108 +               goto out;
10109 +       }
10110 +
10111 +       err = FILEID_ROOT;
10112 +       if (inode->i_ino == AUFS_ROOT_INO) {
10113 +               AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
10114 +               goto out;
10115 +       }
10116 +
10117 +       h_parent = NULL;
10118 +       sb = inode->i_sb;
10119 +       err = si_read_lock(sb, AuLock_FLUSH);
10120 +       if (unlikely(err))
10121 +               goto out;
10122 +
10123 +#ifdef CONFIG_AUFS_DEBUG
10124 +       if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10125 +               AuWarn1("NFS-exporting requires xino\n");
10126 +#endif
10127 +       err = -EIO;
10128 +       parent = NULL;
10129 +       ii_read_lock_child(inode);
10130 +       bindex = au_ibstart(inode);
10131 +       if (!dir) {
10132 +               dentry = d_find_alias(inode);
10133 +               if (unlikely(!dentry))
10134 +                       goto out_unlock;
10135 +               AuDebugOn(au_test_anon(dentry));
10136 +               parent = dget_parent(dentry);
10137 +               dput(dentry);
10138 +               if (unlikely(!parent))
10139 +                       goto out_unlock;
10140 +               dir = parent->d_inode;
10141 +       }
10142 +
10143 +       ii_read_lock_parent(dir);
10144 +       h_dir = au_h_iptr(dir, bindex);
10145 +       ii_read_unlock(dir);
10146 +       if (unlikely(!h_dir))
10147 +               goto out_parent;
10148 +       h_parent = d_find_alias(h_dir);
10149 +       if (unlikely(!h_parent))
10150 +               goto out_hparent;
10151 +
10152 +       err = -EPERM;
10153 +       br = au_sbr(sb, bindex);
10154 +       h_sb = au_br_sb(br);
10155 +       if (unlikely(!h_sb->s_export_op)) {
10156 +               AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
10157 +               goto out_hparent;
10158 +       }
10159 +
10160 +       fh[Fh_br_id] = br->br_id;
10161 +       fh[Fh_sigen] = au_sigen(sb);
10162 +       encode_ino(fh + Fh_ino, inode->i_ino);
10163 +       encode_ino(fh + Fh_dir_ino, dir->i_ino);
10164 +       fh[Fh_igen] = inode->i_generation;
10165 +
10166 +       *max_len -= Fh_tail;
10167 +       fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
10168 +                                          max_len,
10169 +                                          /*connectable or subtreecheck*/0);
10170 +       err = fh[Fh_h_type];
10171 +       *max_len += Fh_tail;
10172 +       /* todo: macros? */
10173 +       if (err != FILEID_INVALID)
10174 +               err = 99;
10175 +       else
10176 +               AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
10177 +
10178 +out_hparent:
10179 +       dput(h_parent);
10180 +out_parent:
10181 +       dput(parent);
10182 +out_unlock:
10183 +       ii_read_unlock(inode);
10184 +       si_read_unlock(sb);
10185 +out:
10186 +       if (unlikely(err < 0))
10187 +               err = FILEID_INVALID;
10188 +       return err;
10189 +}
10190 +
10191 +/* ---------------------------------------------------------------------- */
10192 +
10193 +static int aufs_commit_metadata(struct inode *inode)
10194 +{
10195 +       int err;
10196 +       aufs_bindex_t bindex;
10197 +       struct super_block *sb;
10198 +       struct inode *h_inode;
10199 +       int (*f)(struct inode *inode);
10200 +
10201 +       sb = inode->i_sb;
10202 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
10203 +       ii_write_lock_child(inode);
10204 +       bindex = au_ibstart(inode);
10205 +       AuDebugOn(bindex < 0);
10206 +       h_inode = au_h_iptr(inode, bindex);
10207 +
10208 +       f = h_inode->i_sb->s_export_op->commit_metadata;
10209 +       if (f)
10210 +               err = f(h_inode);
10211 +       else {
10212 +               struct writeback_control wbc = {
10213 +                       .sync_mode      = WB_SYNC_ALL,
10214 +                       .nr_to_write    = 0 /* metadata only */
10215 +               };
10216 +
10217 +               err = sync_inode(h_inode, &wbc);
10218 +       }
10219 +
10220 +       au_cpup_attr_timesizes(inode);
10221 +       ii_write_unlock(inode);
10222 +       si_read_unlock(sb);
10223 +       return err;
10224 +}
10225 +
10226 +/* ---------------------------------------------------------------------- */
10227 +
10228 +static struct export_operations aufs_export_op = {
10229 +       .fh_to_dentry           = aufs_fh_to_dentry,
10230 +       /* .fh_to_parent        = aufs_fh_to_parent, */
10231 +       .encode_fh              = aufs_encode_fh,
10232 +       .commit_metadata        = aufs_commit_metadata
10233 +};
10234 +
10235 +void au_export_init(struct super_block *sb)
10236 +{
10237 +       struct au_sbinfo *sbinfo;
10238 +       __u32 u;
10239 +
10240 +       sb->s_export_op = &aufs_export_op;
10241 +       sbinfo = au_sbi(sb);
10242 +       sbinfo->si_xigen = NULL;
10243 +       get_random_bytes(&u, sizeof(u));
10244 +       BUILD_BUG_ON(sizeof(u) != sizeof(int));
10245 +       atomic_set(&sbinfo->si_xigen_next, u);
10246 +}
10247 diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
10248 --- /usr/share/empty/fs/aufs/file.c     1970-01-01 01:00:00.000000000 +0100
10249 +++ linux/fs/aufs/file.c        2013-07-30 22:42:55.842946719 +0200
10250 @@ -0,0 +1,689 @@
10251 +/*
10252 + * Copyright (C) 2005-2013 Junjiro R. Okajima
10253 + *
10254 + * This program, aufs is free software; you can redistribute it and/or modify
10255 + * it under the terms of the GNU General Public License as published by
10256 + * the Free Software Foundation; either version 2 of the License, or
10257 + * (at your option) any later version.
10258 + *
10259 + * This program is distributed in the hope that it will be useful,
10260 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10261 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10262 + * GNU General Public License for more details.
10263 + *
10264 + * You should have received a copy of the GNU General Public License
10265 + * along with this program; if not, write to the Free Software
10266 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
10267 + */
10268 +
10269 +/*
10270 + * handling file/dir, and address_space operation
10271 + */
10272 +
10273 +#ifdef CONFIG_AUFS_DEBUG
10274 +#include <linux/migrate.h>
10275 +#endif
10276 +#include <linux/pagemap.h>
10277 +#include "aufs.h"
10278 +
10279 +/* drop flags for writing */
10280 +unsigned int au_file_roflags(unsigned int flags)
10281 +{
10282 +       flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
10283 +       flags |= O_RDONLY | O_NOATIME;
10284 +       return flags;
10285 +}
10286 +
10287 +/* common functions to regular file and dir */
10288 +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
10289 +                      struct file *file)
10290 +{
10291 +       struct file *h_file;
10292 +       struct dentry *h_dentry;
10293 +       struct inode *h_inode;
10294 +       struct super_block *sb;
10295 +       struct au_branch *br;
10296 +       struct path h_path;
10297 +       int err, exec_flag;
10298 +
10299 +       /* a race condition can happen between open and unlink/rmdir */
10300 +       h_file = ERR_PTR(-ENOENT);
10301 +       h_dentry = au_h_dptr(dentry, bindex);
10302 +       if (au_test_nfsd() && !h_dentry)
10303 +               goto out;
10304 +       h_inode = h_dentry->d_inode;
10305 +       if (au_test_nfsd() && !h_inode)
10306 +               goto out;
10307 +       spin_lock(&h_dentry->d_lock);
10308 +       err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
10309 +               || !h_inode
10310 +               /* || !dentry->d_inode->i_nlink */
10311 +               ;
10312 +       spin_unlock(&h_dentry->d_lock);
10313 +       if (unlikely(err))
10314 +               goto out;
10315 +
10316 +       sb = dentry->d_sb;
10317 +       br = au_sbr(sb, bindex);
10318 +       h_file = ERR_PTR(-EACCES);
10319 +       exec_flag = flags & __FMODE_EXEC;
10320 +       if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
10321 +               goto out;
10322 +
10323 +       /* drop flags for writing */
10324 +       if (au_test_ro(sb, bindex, dentry->d_inode))
10325 +               flags = au_file_roflags(flags);
10326 +       flags &= ~O_CREAT;
10327 +       atomic_inc(&br->br_count);
10328 +       h_path.dentry = h_dentry;
10329 +       h_path.mnt = au_br_mnt(br);
10330 +       if (!au_special_file(h_inode->i_mode))
10331 +               h_file = vfsub_dentry_open(&h_path, flags);
10332 +       else {
10333 +               /* this block depends upon the configuration */
10334 +               di_read_unlock(dentry, AuLock_IR);
10335 +               fi_write_unlock(file);
10336 +               si_read_unlock(sb);
10337 +               h_file = vfsub_dentry_open(&h_path, flags);
10338 +               si_noflush_read_lock(sb);
10339 +               fi_write_lock(file);
10340 +               di_read_lock_child(dentry, AuLock_IR);
10341 +       }
10342 +       if (IS_ERR(h_file))
10343 +               goto out_br;
10344 +
10345 +       if (exec_flag) {
10346 +               err = deny_write_access(h_file);
10347 +               if (unlikely(err)) {
10348 +                       fput(h_file);
10349 +                       h_file = ERR_PTR(err);
10350 +                       goto out_br;
10351 +               }
10352 +       }
10353 +       fsnotify_open(h_file);
10354 +       goto out; /* success */
10355 +
10356 +out_br:
10357 +       atomic_dec(&br->br_count);
10358 +out:
10359 +       return h_file;
10360 +}
10361 +
10362 +int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
10363 +              struct au_fidir *fidir)
10364 +{
10365 +       int err;
10366 +       struct dentry *dentry;
10367 +
10368 +       err = au_finfo_init(file, fidir);
10369 +       if (unlikely(err))
10370 +               goto out;
10371 +
10372 +       dentry = file->f_dentry;
10373 +       di_read_lock_child(dentry, AuLock_IR);
10374 +       err = open(file, vfsub_file_flags(file));
10375 +       di_read_unlock(dentry, AuLock_IR);
10376 +
10377 +       fi_write_unlock(file);
10378 +       if (unlikely(err)) {
10379 +               au_fi(file)->fi_hdir = NULL;
10380 +               au_finfo_fin(file);
10381 +       }
10382 +
10383 +out:
10384 +       return err;
10385 +}
10386 +
10387 +int au_reopen_nondir(struct file *file)
10388 +{
10389 +       int err;
10390 +       aufs_bindex_t bstart;
10391 +       struct dentry *dentry;
10392 +       struct file *h_file, *h_file_tmp;
10393 +
10394 +       dentry = file->f_dentry;
10395 +       AuDebugOn(au_special_file(dentry->d_inode->i_mode));
10396 +       bstart = au_dbstart(dentry);
10397 +       h_file_tmp = NULL;
10398 +       if (au_fbstart(file) == bstart) {
10399 +               h_file = au_hf_top(file);
10400 +               if (file->f_mode == h_file->f_mode)
10401 +                       return 0; /* success */
10402 +               h_file_tmp = h_file;
10403 +               get_file(h_file_tmp);
10404 +               au_set_h_fptr(file, bstart, NULL);
10405 +       }
10406 +       AuDebugOn(au_fi(file)->fi_hdir);
10407 +       /*
10408 +        * it can happen
10409 +        * file exists on both of rw and ro
10410 +        * open --> dbstart and fbstart are both 0
10411 +        * prepend a branch as rw, "rw" become ro
10412 +        * remove rw/file
10413 +        * delete the top branch, "rw" becomes rw again
10414 +        *      --> dbstart is 1, fbstart is still 0
10415 +        * write --> fbstart is 0 but dbstart is 1
10416 +        */
10417 +       /* AuDebugOn(au_fbstart(file) < bstart); */
10418 +
10419 +       h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
10420 +                          file);
10421 +       err = PTR_ERR(h_file);
10422 +       if (IS_ERR(h_file)) {
10423 +               if (h_file_tmp) {
10424 +                       atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
10425 +                       au_set_h_fptr(file, bstart, h_file_tmp);
10426 +                       h_file_tmp = NULL;
10427 +               }
10428 +               goto out; /* todo: close all? */
10429 +       }
10430 +
10431 +       err = 0;
10432 +       au_set_fbstart(file, bstart);
10433 +       au_set_h_fptr(file, bstart, h_file);
10434 +       au_update_figen(file);
10435 +       /* todo: necessary? */
10436 +       /* file->f_ra = h_file->f_ra; */
10437 +
10438 +out:
10439 +       if (h_file_tmp)
10440 +               fput(h_file_tmp);
10441 +       return err;
10442 +}
10443 +
10444 +/* ---------------------------------------------------------------------- */
10445 +
10446 +static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
10447 +                       struct dentry *hi_wh)
10448 +{
10449 +       int err;
10450 +       aufs_bindex_t bstart;
10451 +       struct au_dinfo *dinfo;
10452 +       struct dentry *h_dentry;
10453 +       struct au_hdentry *hdp;
10454 +
10455 +       dinfo = au_di(file->f_dentry);
10456 +       AuRwMustWriteLock(&dinfo->di_rwsem);
10457 +
10458 +       bstart = dinfo->di_bstart;
10459 +       dinfo->di_bstart = btgt;
10460 +       hdp = dinfo->di_hdentry;
10461 +       h_dentry = hdp[0 + btgt].hd_dentry;
10462 +       hdp[0 + btgt].hd_dentry = hi_wh;
10463 +       err = au_reopen_nondir(file);
10464 +       hdp[0 + btgt].hd_dentry = h_dentry;
10465 +       dinfo->di_bstart = bstart;
10466 +
10467 +       return err;
10468 +}
10469 +
10470 +static int au_ready_to_write_wh(struct file *file, loff_t len,
10471 +                               aufs_bindex_t bcpup, struct au_pin *pin)
10472 +{
10473 +       int err;
10474 +       struct inode *inode, *h_inode;
10475 +       struct dentry *dentry, *h_dentry, *hi_wh;
10476 +
10477 +       dentry = file->f_dentry;
10478 +       au_update_dbstart(dentry);
10479 +       inode = dentry->d_inode;
10480 +       h_inode = NULL;
10481 +       if (au_dbstart(dentry) <= bcpup && au_dbend(dentry) >= bcpup) {
10482 +               h_dentry = au_h_dptr(dentry, bcpup);
10483 +               if (h_dentry)
10484 +                       h_inode = h_dentry->d_inode;
10485 +       }
10486 +       hi_wh = au_hi_wh(inode, bcpup);
10487 +       if (!hi_wh && !h_inode)
10488 +               err = au_sio_cpup_wh(dentry, bcpup, len, file, pin);
10489 +       else
10490 +               /* already copied-up after unlink */
10491 +               err = au_reopen_wh(file, bcpup, hi_wh);
10492 +
10493 +       if (!err
10494 +           && inode->i_nlink > 1
10495 +           && au_opt_test(au_mntflags(dentry->d_sb), PLINK))
10496 +               au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup));
10497 +
10498 +       return err;
10499 +}
10500 +
10501 +/*
10502 + * prepare the @file for writing.
10503 + */
10504 +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
10505 +{
10506 +       int err;
10507 +       aufs_bindex_t bstart, bcpup, dbstart;
10508 +       struct dentry *dentry, *parent, *h_dentry;
10509 +       struct inode *inode;
10510 +       struct super_block *sb;
10511 +       struct file *h_file;
10512 +
10513 +       dentry = file->f_dentry;
10514 +       sb = dentry->d_sb;
10515 +       inode = dentry->d_inode;
10516 +       AuDebugOn(au_special_file(inode->i_mode));
10517 +       bstart = au_fbstart(file);
10518 +       err = au_test_ro(sb, bstart, inode);
10519 +       if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
10520 +               err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0);
10521 +               goto out;
10522 +       }
10523 +
10524 +       /* need to cpup or reopen */
10525 +       parent = dget_parent(dentry);
10526 +       di_write_lock_parent(parent);
10527 +       err = AuWbrCopyup(au_sbi(sb), dentry);
10528 +       bcpup = err;
10529 +       if (unlikely(err < 0))
10530 +               goto out_dgrade;
10531 +       err = 0;
10532 +
10533 +       if (!d_unhashed(dentry) && !au_h_dptr(parent, bcpup)) {
10534 +               err = au_cpup_dirs(dentry, bcpup);
10535 +               if (unlikely(err))
10536 +                       goto out_dgrade;
10537 +       }
10538 +
10539 +       err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE,
10540 +                    AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10541 +       if (unlikely(err))
10542 +               goto out_dgrade;
10543 +
10544 +       h_dentry = au_hf_top(file)->f_dentry;
10545 +       dbstart = au_dbstart(dentry);
10546 +       if (dbstart <= bcpup) {
10547 +               h_dentry = au_h_dptr(dentry, bcpup);
10548 +               AuDebugOn(!h_dentry);
10549 +               bstart = bcpup;
10550 +       }
10551 +
10552 +       if (dbstart <= bcpup            /* just reopen */
10553 +           || !d_unhashed(dentry)      /* copyup and reopen */
10554 +               ) {
10555 +               h_file = au_h_open_pre(dentry, bstart);
10556 +               if (IS_ERR(h_file))
10557 +                       err = PTR_ERR(h_file);
10558 +               else {
10559 +                       di_downgrade_lock(parent, AuLock_IR);
10560 +                       if (dbstart > bcpup)
10561 +                               err = au_sio_cpup_simple(dentry, bcpup, len,
10562 +                                                        AuCpup_DTIME, pin);
10563 +                       if (!err)
10564 +                               err = au_reopen_nondir(file);
10565 +                       au_h_open_post(dentry, bstart, h_file);
10566 +               }
10567 +       } else {                        /* copyup as wh and reopen */
10568 +               /*
10569 +                * since writable hfsplus branch is not supported,
10570 +                * h_open_pre/post() are unnecessary.
10571 +                */
10572 +               err = au_ready_to_write_wh(file, len, bcpup, pin);
10573 +               di_downgrade_lock(parent, AuLock_IR);
10574 +       }
10575 +
10576 +       if (!err) {
10577 +               au_pin_set_parent_lflag(pin, /*lflag*/0);
10578 +               goto out_dput; /* success */
10579 +       }
10580 +       au_unpin(pin);
10581 +       goto out_unlock;
10582 +
10583 +out_dgrade:
10584 +       di_downgrade_lock(parent, AuLock_IR);
10585 +out_unlock:
10586 +       di_read_unlock(parent, AuLock_IR);
10587 +out_dput:
10588 +       dput(parent);
10589 +out:
10590 +       return err;
10591 +}
10592 +
10593 +/* ---------------------------------------------------------------------- */
10594 +
10595 +int au_do_flush(struct file *file, fl_owner_t id,
10596 +               int (*flush)(struct file *file, fl_owner_t id))
10597 +{
10598 +       int err;
10599 +       struct super_block *sb;
10600 +       struct inode *inode;
10601 +
10602 +       inode = file_inode(file);
10603 +       sb = inode->i_sb;
10604 +       si_noflush_read_lock(sb);
10605 +       fi_read_lock(file);
10606 +       ii_read_lock_child(inode);
10607 +
10608 +       err = flush(file, id);
10609 +       au_cpup_attr_timesizes(inode);
10610 +
10611 +       ii_read_unlock(inode);
10612 +       fi_read_unlock(file);
10613 +       si_read_unlock(sb);
10614 +       return err;
10615 +}
10616 +
10617 +/* ---------------------------------------------------------------------- */
10618 +
10619 +static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
10620 +{
10621 +       int err;
10622 +       aufs_bindex_t bstart;
10623 +       struct au_pin pin;
10624 +       struct au_finfo *finfo;
10625 +       struct dentry *dentry, *parent, *hi_wh;
10626 +       struct inode *inode;
10627 +       struct super_block *sb;
10628 +
10629 +       FiMustWriteLock(file);
10630 +
10631 +       err = 0;
10632 +       finfo = au_fi(file);
10633 +       dentry = file->f_dentry;
10634 +       sb = dentry->d_sb;
10635 +       inode = dentry->d_inode;
10636 +       bstart = au_ibstart(inode);
10637 +       if (bstart == finfo->fi_btop || IS_ROOT(dentry))
10638 +               goto out;
10639 +
10640 +       parent = dget_parent(dentry);
10641 +       if (au_test_ro(sb, bstart, inode)) {
10642 +               di_read_lock_parent(parent, !AuLock_IR);
10643 +               err = AuWbrCopyup(au_sbi(sb), dentry);
10644 +               bstart = err;
10645 +               di_read_unlock(parent, !AuLock_IR);
10646 +               if (unlikely(err < 0))
10647 +                       goto out_parent;
10648 +               err = 0;
10649 +       }
10650 +
10651 +       di_read_lock_parent(parent, AuLock_IR);
10652 +       hi_wh = au_hi_wh(inode, bstart);
10653 +       if (!S_ISDIR(inode->i_mode)
10654 +           && au_opt_test(au_mntflags(sb), PLINK)
10655 +           && au_plink_test(inode)
10656 +           && !d_unhashed(dentry)
10657 +           && bstart < au_dbstart(dentry)) {
10658 +               err = au_test_and_cpup_dirs(dentry, bstart);
10659 +               if (unlikely(err))
10660 +                       goto out_unlock;
10661 +
10662 +               /* always superio. */
10663 +               err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE,
10664 +                            AuPin_DI_LOCKED | AuPin_MNT_WRITE);
10665 +               if (!err) {
10666 +                       err = au_sio_cpup_simple(dentry, bstart, -1,
10667 +                                                AuCpup_DTIME, &pin);
10668 +                       au_unpin(&pin);
10669 +               }
10670 +       } else if (hi_wh) {
10671 +               /* already copied-up after unlink */
10672 +               err = au_reopen_wh(file, bstart, hi_wh);
10673 +               *need_reopen = 0;
10674 +       }
10675 +
10676 +out_unlock:
10677 +       di_read_unlock(parent, AuLock_IR);
10678 +out_parent:
10679 +       dput(parent);
10680 +out:
10681 +       return err;
10682 +}
10683 +
10684 +static void au_do_refresh_dir(struct file *file)
10685 +{
10686 +       aufs_bindex_t bindex, bend, new_bindex, brid;
10687 +       struct au_hfile *p, tmp, *q;
10688 +       struct au_finfo *finfo;
10689 +       struct super_block *sb;
10690 +       struct au_fidir *fidir;
10691 +
10692 +       FiMustWriteLock(file);
10693 +
10694 +       sb = file->f_dentry->d_sb;
10695 +       finfo = au_fi(file);
10696 +       fidir = finfo->fi_hdir;
10697 +       AuDebugOn(!fidir);
10698 +       p = fidir->fd_hfile + finfo->fi_btop;
10699 +       brid = p->hf_br->br_id;
10700 +       bend = fidir->fd_bbot;
10701 +       for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
10702 +               if (!p->hf_file)
10703 +                       continue;
10704 +
10705 +               new_bindex = au_br_index(sb, p->hf_br->br_id);
10706 +               if (new_bindex == bindex)
10707 +                       continue;
10708 +               if (new_bindex < 0) {
10709 +                       au_set_h_fptr(file, bindex, NULL);
10710 +                       continue;
10711 +               }
10712 +
10713 +               /* swap two lower inode, and loop again */
10714 +               q = fidir->fd_hfile + new_bindex;
10715 +               tmp = *q;
10716 +               *q = *p;
10717 +               *p = tmp;
10718 +               if (tmp.hf_file) {
10719 +                       bindex--;
10720 +                       p--;
10721 +               }
10722 +       }
10723 +
10724 +       p = fidir->fd_hfile;
10725 +       if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
10726 +               bend = au_sbend(sb);
10727 +               for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
10728 +                    finfo->fi_btop++, p++)
10729 +                       if (p->hf_file) {
10730 +                               if (file_inode(p->hf_file))
10731 +                                       break;
10732 +                               else
10733 +                                       au_hfput(p, file);
10734 +                       }
10735 +       } else {
10736 +               bend = au_br_index(sb, brid);
10737 +               for (finfo->fi_btop = 0; finfo->fi_btop < bend;
10738 +                    finfo->fi_btop++, p++)
10739 +                       if (p->hf_file)
10740 +                               au_hfput(p, file);
10741 +               bend = au_sbend(sb);
10742 +       }
10743 +
10744 +       p = fidir->fd_hfile + bend;
10745 +       for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
10746 +            fidir->fd_bbot--, p--)
10747 +               if (p->hf_file) {
10748 +                       if (file_inode(p->hf_file))
10749 +                               break;
10750 +                       else
10751 +                               au_hfput(p, file);
10752 +               }
10753 +       AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
10754 +}
10755 +
10756 +/*
10757 + * after branch manipulating, refresh the file.
10758 + */
10759 +static int refresh_file(struct file *file, int (*reopen)(struct file *file))
10760 +{
10761 +       int err, need_reopen;
10762 +       aufs_bindex_t bend, bindex;
10763 +       struct dentry *dentry;
10764 +       struct au_finfo *finfo;
10765 +       struct au_hfile *hfile;
10766 +
10767 +       dentry = file->f_dentry;
10768 +       finfo = au_fi(file);
10769 +       if (!finfo->fi_hdir) {
10770 +               hfile = &finfo->fi_htop;
10771 +               AuDebugOn(!hfile->hf_file);
10772 +               bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
10773 +               AuDebugOn(bindex < 0);
10774 +               if (bindex != finfo->fi_btop)
10775 +                       au_set_fbstart(file, bindex);
10776 +       } else {
10777 +               err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
10778 +               if (unlikely(err))
10779 +                       goto out;
10780 +               au_do_refresh_dir(file);
10781 +       }
10782 +
10783 +       err = 0;
10784 +       need_reopen = 1;
10785 +       if (!au_test_mmapped(file))
10786 +               err = au_file_refresh_by_inode(file, &need_reopen);
10787 +       if (!err && need_reopen && !d_unlinked(dentry))
10788 +               err = reopen(file);
10789 +       if (!err) {
10790 +               au_update_figen(file);
10791 +               goto out; /* success */
10792 +       }
10793 +
10794 +       /* error, close all lower files */
10795 +       if (finfo->fi_hdir) {
10796 +               bend = au_fbend_dir(file);
10797 +               for (bindex = au_fbstart(file); bindex <= bend; bindex++)
10798 +                       au_set_h_fptr(file, bindex, NULL);
10799 +       }
10800 +
10801 +out:
10802 +       return err;
10803 +}
10804 +
10805 +/* common function to regular file and dir */
10806 +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
10807 +                         int wlock)
10808 +{
10809 +       int err;
10810 +       unsigned int sigen, figen;
10811 +       aufs_bindex_t bstart;
10812 +       unsigned char pseudo_link;
10813 +       struct dentry *dentry;
10814 +       struct inode *inode;
10815 +
10816 +       err = 0;
10817 +       dentry = file->f_dentry;
10818 +       inode = dentry->d_inode;
10819 +       AuDebugOn(au_special_file(inode->i_mode));
10820 +       sigen = au_sigen(dentry->d_sb);
10821 +       fi_write_lock(file);
10822 +       figen = au_figen(file);
10823 +       di_write_lock_child(dentry);
10824 +       bstart = au_dbstart(dentry);
10825 +       pseudo_link = (bstart != au_ibstart(inode));
10826 +       if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
10827 +               if (!wlock) {
10828 +                       di_downgrade_lock(dentry, AuLock_IR);
10829 +                       fi_downgrade_lock(file);
10830 +               }
10831 +               goto out; /* success */
10832 +       }
10833 +
10834 +       AuDbg("sigen %d, figen %d\n", sigen, figen);
10835 +       if (au_digen_test(dentry, sigen)) {
10836 +               err = au_reval_dpath(dentry, sigen);
10837 +               AuDebugOn(!err && au_digen_test(dentry, sigen));
10838 +       }
10839 +
10840 +       if (!err)
10841 +               err = refresh_file(file, reopen);
10842 +       if (!err) {
10843 +               if (!wlock) {
10844 +                       di_downgrade_lock(dentry, AuLock_IR);
10845 +                       fi_downgrade_lock(file);
10846 +               }
10847 +       } else {
10848 +               di_write_unlock(dentry);
10849 +               fi_write_unlock(file);
10850 +       }
10851 +
10852 +out:
10853 +       return err;
10854 +}
10855 +
10856 +/* ---------------------------------------------------------------------- */
10857 +
10858 +/* cf. aufs_nopage() */
10859 +/* for madvise(2) */
10860 +static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
10861 +{
10862 +       unlock_page(page);
10863 +       return 0;
10864 +}
10865 +
10866 +/* it will never be called, but necessary to support O_DIRECT */
10867 +static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
10868 +                             const struct iovec *iov, loff_t offset,
10869 +                             unsigned long nr_segs)
10870 +{ BUG(); return 0; }
10871 +
10872 +/*
10873 + * it will never be called, but madvise and fadvise behaves differently
10874 + * when get_xip_mem is defined
10875 + */
10876 +static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
10877 +                           int create, void **kmem, unsigned long *pfn)
10878 +{ BUG(); return 0; }
10879 +
10880 +/* they will never be called. */
10881 +#ifdef CONFIG_AUFS_DEBUG
10882 +static int aufs_write_begin(struct file *file, struct address_space *mapping,
10883 +                           loff_t pos, unsigned len, unsigned flags,
10884 +                           struct page **pagep, void **fsdata)
10885 +{ AuUnsupport(); return 0; }
10886 +static int aufs_write_end(struct file *file, struct address_space *mapping,
10887 +                         loff_t pos, unsigned len, unsigned copied,
10888 +                         struct page *page, void *fsdata)
10889 +{ AuUnsupport(); return 0; }
10890 +static int aufs_writepage(struct page *page, struct writeback_control *wbc)
10891 +{ AuUnsupport(); return 0; }
10892 +
10893 +static int aufs_set_page_dirty(struct page *page)
10894 +{ AuUnsupport(); return 0; }
10895 +static void aufs_invalidatepage(struct page *page, unsigned long offset)
10896 +{ AuUnsupport(); }
10897 +static int aufs_releasepage(struct page *page, gfp_t gfp)
10898 +{ AuUnsupport(); return 0; }
10899 +static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
10900 +                           struct page *page, enum migrate_mode mode)
10901 +{ AuUnsupport(); return 0; }
10902 +static int aufs_launder_page(struct page *page)
10903 +{ AuUnsupport(); return 0; }
10904 +static int aufs_is_partially_uptodate(struct page *page,
10905 +                                     read_descriptor_t *desc,
10906 +                                     unsigned long from)
10907 +{ AuUnsupport(); return 0; }
10908 +static int aufs_error_remove_page(struct address_space *mapping,
10909 +                                 struct page *page)
10910 +{ AuUnsupport(); return 0; }
10911 +static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
10912 +                             sector_t *span)
10913 +{ AuUnsupport(); return 0; }
10914 +static void aufs_swap_deactivate(struct file *file)
10915 +{ AuUnsupport(); }
10916 +#endif /* CONFIG_AUFS_DEBUG */
10917 +
10918 +const struct address_space_operations aufs_aop = {
10919 +       .readpage               = aufs_readpage,
10920 +       .direct_IO              = aufs_direct_IO,
10921 +       .get_xip_mem            = aufs_get_xip_mem,
10922 +#ifdef CONFIG_AUFS_DEBUG
10923 +       .writepage              = aufs_writepage,
10924 +       /* no writepages, because of writepage */
10925 +       .set_page_dirty         = aufs_set_page_dirty,
10926 +       /* no readpages, because of readpage */
10927 +       .write_begin            = aufs_write_begin,
10928 +       .write_end              = aufs_write_end,
10929 +       /* no bmap, no block device */
10930 +       .invalidatepage         = aufs_invalidatepage,
10931 +       .releasepage            = aufs_releasepage,
10932 +       .migratepage            = aufs_migratepage,
10933 +       .launder_page           = aufs_launder_page,
10934 +       .is_partially_uptodate  = aufs_is_partially_uptodate,
10935 +       .error_remove_page      = aufs_error_remove_page,
10936 +       .swap_activate          = aufs_swap_activate,
10937 +       .swap_deactivate        = aufs_swap_deactivate
10938 +#endif /* CONFIG_AUFS_DEBUG */
10939 +};
10940 diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
10941 --- /usr/share/empty/fs/aufs/file.h     1970-01-01 01:00:00.000000000 +0100
10942 +++ linux/fs/aufs/file.h        2013-07-06 13:20:47.750198454 +0200
10943 @@ -0,0 +1,308 @@
10944 +/*
10945 + * Copyright (C) 2005-2013 Junjiro R. Okajima
10946 + *
10947 + * This program, aufs is free software; you can redistribute it and/or modify
10948 + * it under the terms of the GNU General Public License as published by
10949 + * the Free Software Foundation; either version 2 of the License, or
10950 + * (at your option) any later version.
10951 + *
10952 + * This program is distributed in the hope that it will be useful,
10953 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10954 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10955 + * GNU General Public License for more details.
10956 + *
10957 + * You should have received a copy of the GNU General Public License
10958 + * along with this program; if not, write to the Free Software
10959 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
10960 + */
10961 +
10962 +/*
10963 + * file operations
10964 + */
10965 +
10966 +#ifndef __AUFS_FILE_H__
10967 +#define __AUFS_FILE_H__
10968 +
10969 +#ifdef __KERNEL__
10970 +
10971 +#include <linux/file.h>
10972 +#include <linux/fs.h>
10973 +#include <linux/poll.h>
10974 +#include "rwsem.h"
10975 +
10976 +struct au_branch;
10977 +struct au_hfile {
10978 +       struct file             *hf_file;
10979 +       struct au_branch        *hf_br;
10980 +};
10981 +
10982 +struct au_vdir;
10983 +struct au_fidir {
10984 +       aufs_bindex_t           fd_bbot;
10985 +       aufs_bindex_t           fd_nent;
10986 +       struct au_vdir          *fd_vdir_cache;
10987 +       struct au_hfile         fd_hfile[];
10988 +};
10989 +
10990 +static inline int au_fidir_sz(int nent)
10991 +{
10992 +       AuDebugOn(nent < 0);
10993 +       return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
10994 +}
10995 +
10996 +struct au_finfo {
10997 +       atomic_t                fi_generation;
10998 +
10999 +       struct au_rwsem         fi_rwsem;
11000 +       aufs_bindex_t           fi_btop;
11001 +
11002 +       /* do not union them */
11003 +       struct {                                /* for non-dir */
11004 +               struct au_hfile                 fi_htop;
11005 +               atomic_t                        fi_mmapped;
11006 +       };
11007 +       struct au_fidir         *fi_hdir;       /* for dir only */
11008 +} ____cacheline_aligned_in_smp;
11009 +
11010 +/* ---------------------------------------------------------------------- */
11011 +
11012 +/* file.c */
11013 +extern const struct address_space_operations aufs_aop;
11014 +unsigned int au_file_roflags(unsigned int flags);
11015 +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
11016 +                      struct file *file);
11017 +int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
11018 +              struct au_fidir *fidir);
11019 +int au_reopen_nondir(struct file *file);
11020 +struct au_pin;
11021 +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
11022 +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
11023 +                         int wlock);
11024 +int au_do_flush(struct file *file, fl_owner_t id,
11025 +               int (*flush)(struct file *file, fl_owner_t id));
11026 +
11027 +/* poll.c */
11028 +#ifdef CONFIG_AUFS_POLL
11029 +unsigned int aufs_poll(struct file *file, poll_table *wait);
11030 +#endif
11031 +
11032 +#ifdef CONFIG_AUFS_BR_HFSPLUS
11033 +/* hfsplus.c */
11034 +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex);
11035 +void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
11036 +                   struct file *h_file);
11037 +#else
11038 +static inline
11039 +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
11040 +{
11041 +       return NULL;
11042 +}
11043 +
11044 +AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
11045 +          struct file *h_file);
11046 +#endif
11047 +
11048 +/* f_op.c */
11049 +extern const struct file_operations aufs_file_fop;
11050 +int au_do_open_nondir(struct file *file, int flags);
11051 +int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
11052 +
11053 +#ifdef CONFIG_AUFS_SP_IATTR
11054 +/* f_op_sp.c */
11055 +struct au_finfo *au_fi_sp(struct file *file);
11056 +int au_special_file(umode_t mode);
11057 +void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
11058 +#else
11059 +static inline struct au_finfo *au_fi_sp(struct file *file)
11060 +{
11061 +       return NULL;
11062 +}
11063 +AuStubInt0(au_special_file, umode_t mode)
11064 +static inline void au_init_special_fop(struct inode *inode, umode_t mode,
11065 +                                      dev_t rdev)
11066 +{
11067 +       init_special_inode(inode, mode, rdev);
11068 +}
11069 +#endif
11070 +
11071 +/* finfo.c */
11072 +void au_hfput(struct au_hfile *hf, struct file *file);
11073 +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
11074 +                  struct file *h_file);
11075 +
11076 +void au_update_figen(struct file *file);
11077 +struct au_fidir *au_fidir_alloc(struct super_block *sb);
11078 +int au_fidir_realloc(struct au_finfo *finfo, int nbr);
11079 +
11080 +void au_fi_init_once(void *_fi);
11081 +void au_finfo_fin(struct file *file);
11082 +int au_finfo_init(struct file *file, struct au_fidir *fidir);
11083 +
11084 +/* ioctl.c */
11085 +long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
11086 +#ifdef CONFIG_COMPAT
11087 +long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
11088 +                          unsigned long arg);
11089 +#endif
11090 +
11091 +/* ---------------------------------------------------------------------- */
11092 +
11093 +static inline struct au_finfo *au_fi(struct file *file)
11094 +{
11095 +       struct au_finfo *finfo;
11096 +
11097 +       finfo = au_fi_sp(file);
11098 +       if (!finfo)
11099 +               finfo = file->private_data;
11100 +       return finfo;
11101 +}
11102 +
11103 +/* ---------------------------------------------------------------------- */
11104 +
11105 +/*
11106 + * fi_read_lock, fi_write_lock,
11107 + * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
11108 + */
11109 +AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
11110 +
11111 +#define FiMustNoWaiters(f)     AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
11112 +#define FiMustAnyLock(f)       AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
11113 +#define FiMustWriteLock(f)     AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
11114 +
11115 +/* ---------------------------------------------------------------------- */
11116 +
11117 +/* todo: hard/soft set? */
11118 +static inline aufs_bindex_t au_fbstart(struct file *file)
11119 +{
11120 +       FiMustAnyLock(file);
11121 +       return au_fi(file)->fi_btop;
11122 +}
11123 +
11124 +static inline aufs_bindex_t au_fbend_dir(struct file *file)
11125 +{
11126 +       FiMustAnyLock(file);
11127 +       AuDebugOn(!au_fi(file)->fi_hdir);
11128 +       return au_fi(file)->fi_hdir->fd_bbot;
11129 +}
11130 +
11131 +static inline struct au_vdir *au_fvdir_cache(struct file *file)
11132 +{
11133 +       FiMustAnyLock(file);
11134 +       AuDebugOn(!au_fi(file)->fi_hdir);
11135 +       return au_fi(file)->fi_hdir->fd_vdir_cache;
11136 +}
11137 +
11138 +static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
11139 +{
11140 +       FiMustWriteLock(file);
11141 +       au_fi(file)->fi_btop = bindex;
11142 +}
11143 +
11144 +static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
11145 +{
11146 +       FiMustWriteLock(file);
11147 +       AuDebugOn(!au_fi(file)->fi_hdir);
11148 +       au_fi(file)->fi_hdir->fd_bbot = bindex;
11149 +}
11150 +
11151 +static inline void au_set_fvdir_cache(struct file *file,
11152 +                                     struct au_vdir *vdir_cache)
11153 +{
11154 +       FiMustWriteLock(file);
11155 +       AuDebugOn(!au_fi(file)->fi_hdir);
11156 +       au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
11157 +}
11158 +
11159 +static inline struct file *au_hf_top(struct file *file)
11160 +{
11161 +       FiMustAnyLock(file);
11162 +       AuDebugOn(au_fi(file)->fi_hdir);
11163 +       return au_fi(file)->fi_htop.hf_file;
11164 +}
11165 +
11166 +static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
11167 +{
11168 +       FiMustAnyLock(file);
11169 +       AuDebugOn(!au_fi(file)->fi_hdir);
11170 +       return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
11171 +}
11172 +
11173 +/* todo: memory barrier? */
11174 +static inline unsigned int au_figen(struct file *f)
11175 +{
11176 +       return atomic_read(&au_fi(f)->fi_generation);
11177 +}
11178 +
11179 +static inline void au_set_mmapped(struct file *f)
11180 +{
11181 +       if (atomic_inc_return(&au_fi(f)->fi_mmapped))
11182 +               return;
11183 +       pr_warn("fi_mmapped wrapped around\n");
11184 +       while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
11185 +               ;
11186 +}
11187 +
11188 +static inline void au_unset_mmapped(struct file *f)
11189 +{
11190 +       atomic_dec(&au_fi(f)->fi_mmapped);
11191 +}
11192 +
11193 +static inline int au_test_mmapped(struct file *f)
11194 +{
11195 +       return atomic_read(&au_fi(f)->fi_mmapped);
11196 +}
11197 +
11198 +/* customize vma->vm_file */
11199 +
11200 +static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
11201 +                                      struct file *file)
11202 +{
11203 +       struct file *f;
11204 +
11205 +       f = vma->vm_file;
11206 +       get_file(file);
11207 +       vma->vm_file = file;
11208 +       fput(f);
11209 +}
11210 +
11211 +#ifdef CONFIG_MMU
11212 +#define AuDbgVmRegion(file, vma) do {} while (0)
11213 +
11214 +static inline void au_vm_file_reset(struct vm_area_struct *vma,
11215 +                                   struct file *file)
11216 +{
11217 +       au_do_vm_file_reset(vma, file);
11218 +}
11219 +#else
11220 +#define AuDbgVmRegion(file, vma) \
11221 +       AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
11222 +
11223 +static inline void au_vm_file_reset(struct vm_area_struct *vma,
11224 +                                   struct file *file)
11225 +{
11226 +       struct file *f;
11227 +
11228 +       au_do_vm_file_reset(vma, file);
11229 +       f = vma->vm_region->vm_file;
11230 +       get_file(file);
11231 +       vma->vm_region->vm_file = file;
11232 +       fput(f);
11233 +}
11234 +#endif /* CONFIG_MMU */
11235 +
11236 +/* handle vma->vm_prfile */
11237 +static inline void au_vm_prfile_set(struct vm_area_struct *vma,
11238 +                                   struct file *file)
11239 +{
11240 +#ifdef CONFIG_AUFS_PROC_MAP
11241 +       get_file(file);
11242 +       vma->vm_prfile = file;
11243 +#ifndef CONFIG_MMU
11244 +       get_file(file);
11245 +       vma->vm_region->vm_prfile = file;
11246 +#endif
11247 +#endif
11248 +}
11249 +
11250 +#endif /* __KERNEL__ */
11251 +#endif /* __AUFS_FILE_H__ */
11252 diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
11253 --- /usr/share/empty/fs/aufs/finfo.c    1970-01-01 01:00:00.000000000 +0100
11254 +++ linux/fs/aufs/finfo.c       2013-07-06 13:20:47.750198454 +0200
11255 @@ -0,0 +1,157 @@
11256 +/*
11257 + * Copyright (C) 2005-2013 Junjiro R. Okajima
11258 + *
11259 + * This program, aufs is free software; you can redistribute it and/or modify
11260 + * it under the terms of the GNU General Public License as published by
11261 + * the Free Software Foundation; either version 2 of the License, or
11262 + * (at your option) any later version.
11263 + *
11264 + * This program is distributed in the hope that it will be useful,
11265 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11266 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11267 + * GNU General Public License for more details.
11268 + *
11269 + * You should have received a copy of the GNU General Public License
11270 + * along with this program; if not, write to the Free Software
11271 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
11272 + */
11273 +
11274 +/*
11275 + * file private data
11276 + */
11277 +
11278 +#include "aufs.h"
11279 +
11280 +void au_hfput(struct au_hfile *hf, struct file *file)
11281 +{
11282 +       /* todo: direct access f_flags */
11283 +       if (vfsub_file_flags(file) & __FMODE_EXEC)
11284 +               allow_write_access(hf->hf_file);
11285 +       fput(hf->hf_file);
11286 +       hf->hf_file = NULL;
11287 +       atomic_dec(&hf->hf_br->br_count);
11288 +       hf->hf_br = NULL;
11289 +}
11290 +
11291 +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
11292 +{
11293 +       struct au_finfo *finfo = au_fi(file);
11294 +       struct au_hfile *hf;
11295 +       struct au_fidir *fidir;
11296 +
11297 +       fidir = finfo->fi_hdir;
11298 +       if (!fidir) {
11299 +               AuDebugOn(finfo->fi_btop != bindex);
11300 +               hf = &finfo->fi_htop;
11301 +       } else
11302 +               hf = fidir->fd_hfile + bindex;
11303 +
11304 +       if (hf && hf->hf_file)
11305 +               au_hfput(hf, file);
11306 +       if (val) {
11307 +               FiMustWriteLock(file);
11308 +               hf->hf_file = val;
11309 +               hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
11310 +       }
11311 +}
11312 +
11313 +void au_update_figen(struct file *file)
11314 +{
11315 +       atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
11316 +       /* smp_mb(); */ /* atomic_set */
11317 +}
11318 +
11319 +/* ---------------------------------------------------------------------- */
11320 +
11321 +struct au_fidir *au_fidir_alloc(struct super_block *sb)
11322 +{
11323 +       struct au_fidir *fidir;
11324 +       int nbr;
11325 +
11326 +       nbr = au_sbend(sb) + 1;
11327 +       if (nbr < 2)
11328 +               nbr = 2; /* initial allocate for 2 branches */
11329 +       fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
11330 +       if (fidir) {
11331 +               fidir->fd_bbot = -1;
11332 +               fidir->fd_nent = nbr;
11333 +               fidir->fd_vdir_cache = NULL;
11334 +       }
11335 +
11336 +       return fidir;
11337 +}
11338 +
11339 +int au_fidir_realloc(struct au_finfo *finfo, int nbr)
11340 +{
11341 +       int err;
11342 +       struct au_fidir *fidir, *p;
11343 +
11344 +       AuRwMustWriteLock(&finfo->fi_rwsem);
11345 +       fidir = finfo->fi_hdir;
11346 +       AuDebugOn(!fidir);
11347 +
11348 +       err = -ENOMEM;
11349 +       p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
11350 +                        GFP_NOFS);
11351 +       if (p) {
11352 +               p->fd_nent = nbr;
11353 +               finfo->fi_hdir = p;
11354 +               err = 0;
11355 +       }
11356 +
11357 +       return err;
11358 +}
11359 +
11360 +/* ---------------------------------------------------------------------- */
11361 +
11362 +void au_finfo_fin(struct file *file)
11363 +{
11364 +       struct au_finfo *finfo;
11365 +
11366 +       au_nfiles_dec(file->f_dentry->d_sb);
11367 +
11368 +       finfo = au_fi(file);
11369 +       AuDebugOn(finfo->fi_hdir);
11370 +       AuRwDestroy(&finfo->fi_rwsem);
11371 +       au_cache_free_finfo(finfo);
11372 +}
11373 +
11374 +void au_fi_init_once(void *_finfo)
11375 +{
11376 +       struct au_finfo *finfo = _finfo;
11377 +       static struct lock_class_key aufs_fi;
11378 +
11379 +       au_rw_init(&finfo->fi_rwsem);
11380 +       au_rw_class(&finfo->fi_rwsem, &aufs_fi);
11381 +}
11382 +
11383 +int au_finfo_init(struct file *file, struct au_fidir *fidir)
11384 +{
11385 +       int err;
11386 +       struct au_finfo *finfo;
11387 +       struct dentry *dentry;
11388 +
11389 +       err = -ENOMEM;
11390 +       dentry = file->f_dentry;
11391 +       finfo = au_cache_alloc_finfo();
11392 +       if (unlikely(!finfo))
11393 +               goto out;
11394 +
11395 +       err = 0;
11396 +       au_nfiles_inc(dentry->d_sb);
11397 +       /* verbose coding for lock class name */
11398 +       if (!fidir)
11399 +               au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
11400 +       else
11401 +               au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
11402 +       au_rw_write_lock(&finfo->fi_rwsem);
11403 +       finfo->fi_btop = -1;
11404 +       finfo->fi_hdir = fidir;
11405 +       atomic_set(&finfo->fi_generation, au_digen(dentry));
11406 +       /* smp_mb(); */ /* atomic_set */
11407 +
11408 +       file->private_data = finfo;
11409 +
11410 +out:
11411 +       return err;
11412 +}
11413 diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
11414 --- /usr/share/empty/fs/aufs/f_op.c     1970-01-01 01:00:00.000000000 +0100
11415 +++ linux/fs/aufs/f_op.c        2013-07-30 22:42:55.839613269 +0200
11416 @@ -0,0 +1,721 @@
11417 +/*
11418 + * Copyright (C) 2005-2013 Junjiro R. Okajima
11419 + *
11420 + * This program, aufs is free software; you can redistribute it and/or modify
11421 + * it under the terms of the GNU General Public License as published by
11422 + * the Free Software Foundation; either version 2 of the License, or
11423 + * (at your option) any later version.
11424 + *
11425 + * This program is distributed in the hope that it will be useful,
11426 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11427 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11428 + * GNU General Public License for more details.
11429 + *
11430 + * You should have received a copy of the GNU General Public License
11431 + * along with this program; if not, write to the Free Software
11432 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
11433 + */
11434 +
11435 +/*
11436 + * file and vm operations
11437 + */
11438 +
11439 +#include <linux/aio.h>
11440 +#include <linux/fs_stack.h>
11441 +#include <linux/mman.h>
11442 +#include <linux/security.h>
11443 +#include "aufs.h"
11444 +
11445 +int au_do_open_nondir(struct file *file, int flags)
11446 +{
11447 +       int err;
11448 +       aufs_bindex_t bindex;
11449 +       struct file *h_file;
11450 +       struct dentry *dentry;
11451 +       struct au_finfo *finfo;
11452 +
11453 +       FiMustWriteLock(file);
11454 +
11455 +       dentry = file->f_dentry;
11456 +       err = au_d_alive(dentry);
11457 +       if (unlikely(err))
11458 +               goto out;
11459 +
11460 +       finfo = au_fi(file);
11461 +       memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
11462 +       atomic_set(&finfo->fi_mmapped, 0);
11463 +       bindex = au_dbstart(dentry);
11464 +       h_file = au_h_open(dentry, bindex, flags, file);
11465 +       if (IS_ERR(h_file))
11466 +               err = PTR_ERR(h_file);
11467 +       else {
11468 +               au_set_fbstart(file, bindex);
11469 +               au_set_h_fptr(file, bindex, h_file);
11470 +               au_update_figen(file);
11471 +               /* todo: necessary? */
11472 +               /* file->f_ra = h_file->f_ra; */
11473 +       }
11474 +
11475 +out:
11476 +       return err;
11477 +}
11478 +
11479 +static int aufs_open_nondir(struct inode *inode __maybe_unused,
11480 +                           struct file *file)
11481 +{
11482 +       int err;
11483 +       struct super_block *sb;
11484 +
11485 +       AuDbg("%.*s, f_flags 0x%x, f_mode 0x%x\n",
11486 +             AuDLNPair(file->f_dentry), vfsub_file_flags(file),
11487 +             file->f_mode);
11488 +
11489 +       sb = file->f_dentry->d_sb;
11490 +       si_read_lock(sb, AuLock_FLUSH);
11491 +       err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
11492 +       si_read_unlock(sb);
11493 +       return err;
11494 +}
11495 +
11496 +int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
11497 +{
11498 +       struct au_finfo *finfo;
11499 +       aufs_bindex_t bindex;
11500 +
11501 +       finfo = au_fi(file);
11502 +       bindex = finfo->fi_btop;
11503 +       if (bindex >= 0)
11504 +               au_set_h_fptr(file, bindex, NULL);
11505 +
11506 +       au_finfo_fin(file);
11507 +       return 0;
11508 +}
11509 +
11510 +/* ---------------------------------------------------------------------- */
11511 +
11512 +static int au_do_flush_nondir(struct file *file, fl_owner_t id)
11513 +{
11514 +       int err;
11515 +       struct file *h_file;
11516 +
11517 +       err = 0;
11518 +       h_file = au_hf_top(file);
11519 +       if (h_file)
11520 +               err = vfsub_flush(h_file, id);
11521 +       return err;
11522 +}
11523 +
11524 +static int aufs_flush_nondir(struct file *file, fl_owner_t id)
11525 +{
11526 +       return au_do_flush(file, id, au_do_flush_nondir);
11527 +}
11528 +
11529 +/* ---------------------------------------------------------------------- */
11530 +/*
11531 + * read and write functions acquire [fdi]_rwsem once, but release before
11532 + * mmap_sem. This is because to stop a race condition between mmap(2).
11533 + * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
11534 + * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
11535 + * read functions after [fdi]_rwsem are released, but it should be harmless.
11536 + */
11537 +
11538 +static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
11539 +                        loff_t *ppos)
11540 +{
11541 +       ssize_t err;
11542 +       struct dentry *dentry;
11543 +       struct file *h_file;
11544 +       struct super_block *sb;
11545 +
11546 +       dentry = file->f_dentry;
11547 +       sb = dentry->d_sb;
11548 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11549 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11550 +       if (unlikely(err))
11551 +               goto out;
11552 +
11553 +       h_file = au_hf_top(file);
11554 +       get_file(h_file);
11555 +       di_read_unlock(dentry, AuLock_IR);
11556 +       fi_read_unlock(file);
11557 +
11558 +       /* filedata may be obsoleted by concurrent copyup, but no problem */
11559 +       err = vfsub_read_u(h_file, buf, count, ppos);
11560 +       /* todo: necessary? */
11561 +       /* file->f_ra = h_file->f_ra; */
11562 +       /* update without lock, I don't think it a problem */
11563 +       fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
11564 +       fput(h_file);
11565 +
11566 +out:
11567 +       si_read_unlock(sb);
11568 +       return err;
11569 +}
11570 +
11571 +/*
11572 + * todo: very ugly
11573 + * it locks both of i_mutex and si_rwsem for read in safe.
11574 + * if the plink maintenance mode continues forever (that is the problem),
11575 + * may loop forever.
11576 + */
11577 +static void au_mtx_and_read_lock(struct inode *inode)
11578 +{
11579 +       int err;
11580 +       struct super_block *sb = inode->i_sb;
11581 +
11582 +       while (1) {
11583 +               mutex_lock(&inode->i_mutex);
11584 +               err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11585 +               if (!err)
11586 +                       break;
11587 +               mutex_unlock(&inode->i_mutex);
11588 +               si_read_lock(sb, AuLock_NOPLMW);
11589 +               si_read_unlock(sb);
11590 +       }
11591 +}
11592 +
11593 +static ssize_t aufs_write(struct file *file, const char __user *ubuf,
11594 +                         size_t count, loff_t *ppos)
11595 +{
11596 +       ssize_t err;
11597 +       struct au_pin pin;
11598 +       struct dentry *dentry;
11599 +       struct super_block *sb;
11600 +       struct inode *inode;
11601 +       struct file *h_file;
11602 +       char __user *buf = (char __user *)ubuf;
11603 +
11604 +       dentry = file->f_dentry;
11605 +       sb = dentry->d_sb;
11606 +       inode = dentry->d_inode;
11607 +       au_mtx_and_read_lock(inode);
11608 +
11609 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11610 +       if (unlikely(err))
11611 +               goto out;
11612 +
11613 +       err = au_ready_to_write(file, -1, &pin);
11614 +       di_downgrade_lock(dentry, AuLock_IR);
11615 +       if (unlikely(err)) {
11616 +               di_read_unlock(dentry, AuLock_IR);
11617 +               fi_write_unlock(file);
11618 +               goto out;
11619 +       }
11620 +
11621 +       h_file = au_hf_top(file);
11622 +       get_file(h_file);
11623 +       au_unpin(&pin);
11624 +       di_read_unlock(dentry, AuLock_IR);
11625 +       fi_write_unlock(file);
11626 +
11627 +       err = vfsub_write_u(h_file, buf, count, ppos);
11628 +       ii_write_lock_child(inode);
11629 +       au_cpup_attr_timesizes(inode);
11630 +       inode->i_mode = file_inode(h_file)->i_mode;
11631 +       ii_write_unlock(inode);
11632 +       fput(h_file);
11633 +
11634 +out:
11635 +       si_read_unlock(sb);
11636 +       mutex_unlock(&inode->i_mutex);
11637 +       return err;
11638 +}
11639 +
11640 +static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
11641 +                        const struct iovec *iov, unsigned long nv, loff_t pos)
11642 +{
11643 +       ssize_t err;
11644 +       struct file *file;
11645 +       ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
11646 +                       loff_t);
11647 +
11648 +       err = security_file_permission(h_file, rw);
11649 +       if (unlikely(err))
11650 +               goto out;
11651 +
11652 +       err = -ENOSYS;
11653 +       func = NULL;
11654 +       if (rw == MAY_READ)
11655 +               func = h_file->f_op->aio_read;
11656 +       else if (rw == MAY_WRITE)
11657 +               func = h_file->f_op->aio_write;
11658 +       if (func) {
11659 +               file = kio->ki_filp;
11660 +               kio->ki_filp = h_file;
11661 +               lockdep_off();
11662 +               err = func(kio, iov, nv, pos);
11663 +               lockdep_on();
11664 +               kio->ki_filp = file;
11665 +       } else
11666 +               /* currently there is no such fs */
11667 +               WARN_ON_ONCE(1);
11668 +
11669 +out:
11670 +       return err;
11671 +}
11672 +
11673 +static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
11674 +                            unsigned long nv, loff_t pos)
11675 +{
11676 +       ssize_t err;
11677 +       struct file *file, *h_file;
11678 +       struct dentry *dentry;
11679 +       struct super_block *sb;
11680 +
11681 +       file = kio->ki_filp;
11682 +       dentry = file->f_dentry;
11683 +       sb = dentry->d_sb;
11684 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11685 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11686 +       if (unlikely(err))
11687 +               goto out;
11688 +
11689 +       h_file = au_hf_top(file);
11690 +       get_file(h_file);
11691 +       di_read_unlock(dentry, AuLock_IR);
11692 +       fi_read_unlock(file);
11693 +
11694 +       err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
11695 +       /* todo: necessary? */
11696 +       /* file->f_ra = h_file->f_ra; */
11697 +       /* update without lock, I don't think it a problem */
11698 +       fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
11699 +       fput(h_file);
11700 +
11701 +out:
11702 +       si_read_unlock(sb);
11703 +       return err;
11704 +}
11705 +
11706 +static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
11707 +                             unsigned long nv, loff_t pos)
11708 +{
11709 +       ssize_t err;
11710 +       struct au_pin pin;
11711 +       struct dentry *dentry;
11712 +       struct inode *inode;
11713 +       struct file *file, *h_file;
11714 +       struct super_block *sb;
11715 +
11716 +       file = kio->ki_filp;
11717 +       dentry = file->f_dentry;
11718 +       sb = dentry->d_sb;
11719 +       inode = dentry->d_inode;
11720 +       au_mtx_and_read_lock(inode);
11721 +
11722 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11723 +       if (unlikely(err))
11724 +               goto out;
11725 +
11726 +       err = au_ready_to_write(file, -1, &pin);
11727 +       di_downgrade_lock(dentry, AuLock_IR);
11728 +       if (unlikely(err)) {
11729 +               di_read_unlock(dentry, AuLock_IR);
11730 +               fi_write_unlock(file);
11731 +               goto out;
11732 +       }
11733 +
11734 +       h_file = au_hf_top(file);
11735 +       get_file(h_file);
11736 +       au_unpin(&pin);
11737 +       di_read_unlock(dentry, AuLock_IR);
11738 +       fi_write_unlock(file);
11739 +
11740 +       err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
11741 +       ii_write_lock_child(inode);
11742 +       au_cpup_attr_timesizes(inode);
11743 +       inode->i_mode = file_inode(h_file)->i_mode;
11744 +       ii_write_unlock(inode);
11745 +       fput(h_file);
11746 +
11747 +out:
11748 +       si_read_unlock(sb);
11749 +       mutex_unlock(&inode->i_mutex);
11750 +       return err;
11751 +}
11752 +
11753 +static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
11754 +                               struct pipe_inode_info *pipe, size_t len,
11755 +                               unsigned int flags)
11756 +{
11757 +       ssize_t err;
11758 +       struct file *h_file;
11759 +       struct dentry *dentry;
11760 +       struct super_block *sb;
11761 +
11762 +       dentry = file->f_dentry;
11763 +       sb = dentry->d_sb;
11764 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
11765 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11766 +       if (unlikely(err))
11767 +               goto out;
11768 +
11769 +       err = -EINVAL;
11770 +       h_file = au_hf_top(file);
11771 +       get_file(h_file);
11772 +       if (au_test_loopback_kthread()) {
11773 +               au_warn_loopback(h_file->f_dentry->d_sb);
11774 +               if (file->f_mapping != h_file->f_mapping) {
11775 +                       file->f_mapping = h_file->f_mapping;
11776 +                       smp_mb(); /* unnecessary? */
11777 +               }
11778 +       }
11779 +       di_read_unlock(dentry, AuLock_IR);
11780 +       fi_read_unlock(file);
11781 +
11782 +       err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
11783 +       /* todo: necessasry? */
11784 +       /* file->f_ra = h_file->f_ra; */
11785 +       /* update without lock, I don't think it a problem */
11786 +       fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
11787 +       fput(h_file);
11788 +
11789 +out:
11790 +       si_read_unlock(sb);
11791 +       return err;
11792 +}
11793 +
11794 +static ssize_t
11795 +aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
11796 +                 size_t len, unsigned int flags)
11797 +{
11798 +       ssize_t err;
11799 +       struct au_pin pin;
11800 +       struct dentry *dentry;
11801 +       struct inode *inode;
11802 +       struct file *h_file;
11803 +       struct super_block *sb;
11804 +
11805 +       dentry = file->f_dentry;
11806 +       sb = dentry->d_sb;
11807 +       inode = dentry->d_inode;
11808 +       au_mtx_and_read_lock(inode);
11809 +
11810 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11811 +       if (unlikely(err))
11812 +               goto out;
11813 +
11814 +       err = au_ready_to_write(file, -1, &pin);
11815 +       di_downgrade_lock(dentry, AuLock_IR);
11816 +       if (unlikely(err)) {
11817 +               di_read_unlock(dentry, AuLock_IR);
11818 +               fi_write_unlock(file);
11819 +               goto out;
11820 +       }
11821 +
11822 +       h_file = au_hf_top(file);
11823 +       get_file(h_file);
11824 +       au_unpin(&pin);
11825 +       di_read_unlock(dentry, AuLock_IR);
11826 +       fi_write_unlock(file);
11827 +
11828 +       err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
11829 +       ii_write_lock_child(inode);
11830 +       au_cpup_attr_timesizes(inode);
11831 +       inode->i_mode = file_inode(h_file)->i_mode;
11832 +       ii_write_unlock(inode);
11833 +       fput(h_file);
11834 +
11835 +out:
11836 +       si_read_unlock(sb);
11837 +       mutex_unlock(&inode->i_mutex);
11838 +       return err;
11839 +}
11840 +
11841 +/* ---------------------------------------------------------------------- */
11842 +
11843 +/*
11844 + * The locking order around current->mmap_sem.
11845 + * - in most and regular cases
11846 + *   file I/O syscall -- aufs_read() or something
11847 + *     -- si_rwsem for read -- mmap_sem
11848 + *     (Note that [fdi]i_rwsem are released before mmap_sem).
11849 + * - in mmap case
11850 + *   mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
11851 + * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
11852 + * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
11853 + * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
11854 + * It means that when aufs acquires si_rwsem for write, the process should never
11855 + * acquire mmap_sem.
11856 + *
11857 + * Actually aufs_readdir() holds [fdi]i_rwsem before mmap_sem, but this is not a
11858 + * problem either since any directory is not able to be mmap-ed.
11859 + * The similar scenario is applied to aufs_readlink() too.
11860 + */
11861 +
11862 +/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
11863 +#define AuConv_VM_PROT(f, b)   _calc_vm_trans(f, VM_##b, PROT_##b)
11864 +
11865 +static unsigned long au_arch_prot_conv(unsigned long flags)
11866 +{
11867 +       /* currently ppc64 only */
11868 +#ifdef CONFIG_PPC64
11869 +       /* cf. linux/arch/powerpc/include/asm/mman.h */
11870 +       AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
11871 +       return AuConv_VM_PROT(flags, SAO);
11872 +#else
11873 +       AuDebugOn(arch_calc_vm_prot_bits(-1));
11874 +       return 0;
11875 +#endif
11876 +}
11877 +
11878 +static unsigned long au_prot_conv(unsigned long flags)
11879 +{
11880 +       return AuConv_VM_PROT(flags, READ)
11881 +               | AuConv_VM_PROT(flags, WRITE)
11882 +               | AuConv_VM_PROT(flags, EXEC)
11883 +               | au_arch_prot_conv(flags);
11884 +}
11885 +
11886 +/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
11887 +#define AuConv_VM_MAP(f, b)    _calc_vm_trans(f, VM_##b, MAP_##b)
11888 +
11889 +static unsigned long au_flag_conv(unsigned long flags)
11890 +{
11891 +       return AuConv_VM_MAP(flags, GROWSDOWN)
11892 +               | AuConv_VM_MAP(flags, DENYWRITE)
11893 +               | AuConv_VM_MAP(flags, LOCKED);
11894 +}
11895 +
11896 +static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
11897 +{
11898 +       int err;
11899 +       aufs_bindex_t bstart;
11900 +       const unsigned char wlock
11901 +               = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
11902 +       struct dentry *dentry;
11903 +       struct super_block *sb;
11904 +       struct file *h_file;
11905 +       struct au_branch *br;
11906 +       struct au_pin pin;
11907 +
11908 +       AuDbgVmRegion(file, vma);
11909 +
11910 +       dentry = file->f_dentry;
11911 +       sb = dentry->d_sb;
11912 +       lockdep_off();
11913 +       si_read_lock(sb, AuLock_NOPLMW);
11914 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11915 +       if (unlikely(err))
11916 +               goto out;
11917 +
11918 +       if (wlock) {
11919 +               err = au_ready_to_write(file, -1, &pin);
11920 +               di_write_unlock(dentry);
11921 +               if (unlikely(err)) {
11922 +                       fi_write_unlock(file);
11923 +                       goto out;
11924 +               }
11925 +               au_unpin(&pin);
11926 +       } else
11927 +               di_write_unlock(dentry);
11928 +
11929 +       bstart = au_fbstart(file);
11930 +       br = au_sbr(sb, bstart);
11931 +       h_file = au_hf_top(file);
11932 +       get_file(h_file);
11933 +       au_set_mmapped(file);
11934 +       fi_write_unlock(file);
11935 +       lockdep_on();
11936 +
11937 +       au_vm_file_reset(vma, h_file);
11938 +       err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
11939 +                                au_flag_conv(vma->vm_flags));
11940 +       if (!err)
11941 +               err = h_file->f_op->mmap(h_file, vma);
11942 +       if (unlikely(err))
11943 +               goto out_reset;
11944 +
11945 +       au_vm_prfile_set(vma, file);
11946 +       /* update without lock, I don't think it a problem */
11947 +       fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
11948 +       goto out_fput; /* success */
11949 +
11950 +out_reset:
11951 +       au_unset_mmapped(file);
11952 +       au_vm_file_reset(vma, file);
11953 +out_fput:
11954 +       fput(h_file);
11955 +       lockdep_off();
11956 +out:
11957 +       si_read_unlock(sb);
11958 +       lockdep_on();
11959 +       AuTraceErr(err);
11960 +       return err;
11961 +}
11962 +
11963 +/* ---------------------------------------------------------------------- */
11964 +
11965 +static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
11966 +                            int datasync)
11967 +{
11968 +       int err;
11969 +       struct au_pin pin;
11970 +       struct dentry *dentry;
11971 +       struct inode *inode;
11972 +       struct file *h_file;
11973 +       struct super_block *sb;
11974 +
11975 +       dentry = file->f_dentry;
11976 +       inode = dentry->d_inode;
11977 +       sb = dentry->d_sb;
11978 +       mutex_lock(&inode->i_mutex);
11979 +       err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11980 +       if (unlikely(err))
11981 +               goto out;
11982 +
11983 +       err = 0; /* -EBADF; */ /* posix? */
11984 +       if (unlikely(!(file->f_mode & FMODE_WRITE)))
11985 +               goto out_si;
11986 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11987 +       if (unlikely(err))
11988 +               goto out_si;
11989 +
11990 +       err = au_ready_to_write(file, -1, &pin);
11991 +       di_downgrade_lock(dentry, AuLock_IR);
11992 +       if (unlikely(err))
11993 +               goto out_unlock;
11994 +       au_unpin(&pin);
11995 +
11996 +       err = -EINVAL;
11997 +       h_file = au_hf_top(file);
11998 +       err = vfsub_fsync(h_file, &h_file->f_path, datasync);
11999 +       au_cpup_attr_timesizes(inode);
12000 +
12001 +out_unlock:
12002 +       di_read_unlock(dentry, AuLock_IR);
12003 +       fi_write_unlock(file);
12004 +out_si:
12005 +       si_read_unlock(sb);
12006 +out:
12007 +       mutex_unlock(&inode->i_mutex);
12008 +       return err;
12009 +}
12010 +
12011 +/* no one supports this operation, currently */
12012 +#if 0
12013 +static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
12014 +{
12015 +       int err;
12016 +       struct au_pin pin;
12017 +       struct dentry *dentry;
12018 +       struct inode *inode;
12019 +       struct file *file, *h_file;
12020 +
12021 +       file = kio->ki_filp;
12022 +       dentry = file->f_dentry;
12023 +       inode = dentry->d_inode;
12024 +       au_mtx_and_read_lock(inode);
12025 +
12026 +       err = 0; /* -EBADF; */ /* posix? */
12027 +       if (unlikely(!(file->f_mode & FMODE_WRITE)))
12028 +               goto out;
12029 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12030 +       if (unlikely(err))
12031 +               goto out;
12032 +
12033 +       err = au_ready_to_write(file, -1, &pin);
12034 +       di_downgrade_lock(dentry, AuLock_IR);
12035 +       if (unlikely(err))
12036 +               goto out_unlock;
12037 +       au_unpin(&pin);
12038 +
12039 +       err = -ENOSYS;
12040 +       h_file = au_hf_top(file);
12041 +       if (h_file->f_op && h_file->f_op->aio_fsync) {
12042 +               struct mutex *h_mtx;
12043 +
12044 +               h_mtx = &file_inode(h_file)->i_mutex;
12045 +               if (!is_sync_kiocb(kio)) {
12046 +                       get_file(h_file);
12047 +                       fput(file);
12048 +               }
12049 +               kio->ki_filp = h_file;
12050 +               err = h_file->f_op->aio_fsync(kio, datasync);
12051 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
12052 +               if (!err)
12053 +                       vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
12054 +               /*ignore*/
12055 +               au_cpup_attr_timesizes(inode);
12056 +               mutex_unlock(h_mtx);
12057 +       }
12058 +
12059 +out_unlock:
12060 +       di_read_unlock(dentry, AuLock_IR);
12061 +       fi_write_unlock(file);
12062 +out:
12063 +       si_read_unlock(inode->sb);
12064 +       mutex_unlock(&inode->i_mutex);
12065 +       return err;
12066 +}
12067 +#endif
12068 +
12069 +static int aufs_fasync(int fd, struct file *file, int flag)
12070 +{
12071 +       int err;
12072 +       struct file *h_file;
12073 +       struct dentry *dentry;
12074 +       struct super_block *sb;
12075 +
12076 +       dentry = file->f_dentry;
12077 +       sb = dentry->d_sb;
12078 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
12079 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
12080 +       if (unlikely(err))
12081 +               goto out;
12082 +
12083 +       h_file = au_hf_top(file);
12084 +       if (h_file->f_op && h_file->f_op->fasync)
12085 +               err = h_file->f_op->fasync(fd, h_file, flag);
12086 +
12087 +       di_read_unlock(dentry, AuLock_IR);
12088 +       fi_read_unlock(file);
12089 +
12090 +out:
12091 +       si_read_unlock(sb);
12092 +       return err;
12093 +}
12094 +
12095 +/* ---------------------------------------------------------------------- */
12096 +
12097 +/* no one supports this operation, currently */
12098 +#if 0
12099 +static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
12100 +                            size_t len, loff_t *pos , int more)
12101 +{
12102 +}
12103 +#endif
12104 +
12105 +/* ---------------------------------------------------------------------- */
12106 +
12107 +const struct file_operations aufs_file_fop = {
12108 +       .owner          = THIS_MODULE,
12109 +
12110 +       .llseek         = default_llseek,
12111 +
12112 +       .read           = aufs_read,
12113 +       .write          = aufs_write,
12114 +       .aio_read       = aufs_aio_read,
12115 +       .aio_write      = aufs_aio_write,
12116 +#ifdef CONFIG_AUFS_POLL
12117 +       .poll           = aufs_poll,
12118 +#endif
12119 +       .unlocked_ioctl = aufs_ioctl_nondir,
12120 +#ifdef CONFIG_COMPAT
12121 +       .compat_ioctl   = aufs_ioctl_nondir, /* same */
12122 +#endif
12123 +       .mmap           = aufs_mmap,
12124 +       .open           = aufs_open_nondir,
12125 +       .flush          = aufs_flush_nondir,
12126 +       .release        = aufs_release_nondir,
12127 +       .fsync          = aufs_fsync_nondir,
12128 +       /* .aio_fsync   = aufs_aio_fsync_nondir, */
12129 +       .fasync         = aufs_fasync,
12130 +       /* .sendpage    = aufs_sendpage, */
12131 +       .splice_write   = aufs_splice_write,
12132 +       .splice_read    = aufs_splice_read,
12133 +#if 0
12134 +       .aio_splice_write = aufs_aio_splice_write,
12135 +       .aio_splice_read  = aufs_aio_splice_read
12136 +#endif
12137 +};
12138 diff -urN /usr/share/empty/fs/aufs/f_op_sp.c linux/fs/aufs/f_op_sp.c
12139 --- /usr/share/empty/fs/aufs/f_op_sp.c  1970-01-01 01:00:00.000000000 +0100
12140 +++ linux/fs/aufs/f_op_sp.c     2013-07-06 13:20:47.750198454 +0200
12141 @@ -0,0 +1,376 @@
12142 +/*
12143 + * Copyright (C) 2005-2013 Junjiro R. Okajima
12144 + *
12145 + * This program, aufs is free software; you can redistribute it and/or modify
12146 + * it under the terms of the GNU General Public License as published by
12147 + * the Free Software Foundation; either version 2 of the License, or
12148 + * (at your option) any later version.
12149 + *
12150 + * This program is distributed in the hope that it will be useful,
12151 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12152 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12153 + * GNU General Public License for more details.
12154 + *
12155 + * You should have received a copy of the GNU General Public License
12156 + * along with this program; if not, write to the Free Software
12157 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
12158 + */
12159 +
12160 +/*
12161 + * file operations for special files.
12162 + * while they exist in aufs virtually,
12163 + * their file I/O is handled out of aufs.
12164 + */
12165 +
12166 +#include <linux/aio.h>
12167 +#include "aufs.h"
12168 +
12169 +/*
12170 + * I don't think the size of this list grows much.
12171 + * so here is a very simple list implemented in order to find finfo matching a
12172 + * given file.
12173 + */
12174 +static struct au_sphlhead au_finfo_sp = {
12175 +       .spin   = __SPIN_LOCK_INITIALIZER(au_finfo_sp.spin),
12176 +       .head   = HLIST_HEAD_INIT
12177 +};
12178 +
12179 +struct au_finfo_sp {
12180 +       struct hlist_node       hlist;
12181 +       struct file             *file;
12182 +       struct au_finfo         *finfo;
12183 +};
12184 +
12185 +struct au_finfo *au_fi_sp(struct file *file)
12186 +{
12187 +       struct au_finfo *finfo;
12188 +       struct au_finfo_sp *sp;
12189 +
12190 +       finfo = NULL;
12191 +       spin_lock(&au_finfo_sp.spin);
12192 +       hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12193 +               if (sp->file != file)
12194 +                       continue;
12195 +               finfo = sp->finfo;
12196 +               break;
12197 +       }
12198 +       spin_unlock(&au_finfo_sp.spin);
12199 +
12200 +       return finfo;
12201 +}
12202 +
12203 +static int au_fi_sp_add(struct file *file)
12204 +{
12205 +       int err;
12206 +       struct au_finfo_sp *sp;
12207 +
12208 +       err = -ENOMEM;
12209 +       sp = kmalloc(sizeof(*sp), GFP_NOFS);
12210 +       if (sp) {
12211 +               err = 0;
12212 +               sp->file = file;
12213 +               sp->finfo = file->private_data;
12214 +               spin_lock(&au_finfo_sp.spin);
12215 +               hlist_add_head(&sp->hlist, &au_finfo_sp.head);
12216 +               spin_unlock(&au_finfo_sp.spin);
12217 +       }
12218 +       return err;
12219 +}
12220 +
12221 +static void au_fi_sp_del(struct file *file)
12222 +{
12223 +       struct au_finfo_sp *sp, *do_free;
12224 +
12225 +       do_free = NULL;
12226 +       spin_lock(&au_finfo_sp.spin);
12227 +       hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12228 +               if (sp->file != file)
12229 +                       continue;
12230 +               hlist_del(&sp->hlist);
12231 +               do_free = sp;
12232 +               break;
12233 +       }
12234 +       spin_unlock(&au_finfo_sp.spin);
12235 +       kfree(do_free);
12236 +}
12237 +
12238 +/* ---------------------------------------------------------------------- */
12239 +
12240 +static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
12241 +                               unsigned long nv, loff_t pos)
12242 +{
12243 +       ssize_t err;
12244 +       aufs_bindex_t bstart;
12245 +       unsigned char wbr;
12246 +       struct file *file, *h_file;
12247 +       struct super_block *sb;
12248 +
12249 +       file = kio->ki_filp;
12250 +       sb = file->f_dentry->d_sb;
12251 +       si_read_lock(sb, AuLock_FLUSH);
12252 +       fi_read_lock(file);
12253 +       bstart = au_fbstart(file);
12254 +       h_file = au_hf_top(file);
12255 +       fi_read_unlock(file);
12256 +       wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12257 +       si_read_unlock(sb);
12258 +
12259 +       /* do not change the file in kio */
12260 +       AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
12261 +       err = h_file->f_op->aio_read(kio, iov, nv, pos);
12262 +       if (err > 0 && wbr)
12263 +               file_accessed(h_file);
12264 +
12265 +       return err;
12266 +}
12267 +
12268 +static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
12269 +                                unsigned long nv, loff_t pos)
12270 +{
12271 +       ssize_t err;
12272 +       aufs_bindex_t bstart;
12273 +       unsigned char wbr;
12274 +       struct super_block *sb;
12275 +       struct file *file, *h_file;
12276 +
12277 +       file = kio->ki_filp;
12278 +       sb = file->f_dentry->d_sb;
12279 +       si_read_lock(sb, AuLock_FLUSH);
12280 +       fi_read_lock(file);
12281 +       bstart = au_fbstart(file);
12282 +       h_file = au_hf_top(file);
12283 +       fi_read_unlock(file);
12284 +       wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12285 +       si_read_unlock(sb);
12286 +
12287 +       /* do not change the file in kio */
12288 +       AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
12289 +       err = h_file->f_op->aio_write(kio, iov, nv, pos);
12290 +       return err;
12291 +}
12292 +
12293 +/* ---------------------------------------------------------------------- */
12294 +
12295 +static int aufs_release_sp(struct inode *inode, struct file *file)
12296 +{
12297 +       int err;
12298 +       struct file *h_file;
12299 +
12300 +       fi_read_lock(file);
12301 +       h_file = au_hf_top(file);
12302 +       fi_read_unlock(file);
12303 +       /* close this fifo in aufs */
12304 +       err = h_file->f_op->release(inode, file); /* ignore */
12305 +       aufs_release_nondir(inode, file); /* ignore */
12306 +       au_fi_sp_del(file);
12307 +       return err;
12308 +}
12309 +
12310 +/* ---------------------------------------------------------------------- */
12311 +
12312 +/* currently, support only FIFO */
12313 +enum {
12314 +       AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
12315 +       /* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
12316 +       AuSp_Last
12317 +};
12318 +static int aufs_open_sp(struct inode *inode, struct file *file);
12319 +static struct au_sp_fop {
12320 +       int                     done;
12321 +       struct file_operations  fop;    /* not 'const' */
12322 +       spinlock_t              spin;
12323 +} au_sp_fop[AuSp_Last] = {
12324 +       [AuSp_FIFO] = {
12325 +               .fop    = {
12326 +                       .owner  = THIS_MODULE,
12327 +                       .open   = aufs_open_sp
12328 +               }
12329 +       }
12330 +};
12331 +
12332 +static void au_init_fop_sp(struct file *file)
12333 +{
12334 +       struct au_sp_fop *p;
12335 +       int i;
12336 +       struct file *h_file;
12337 +
12338 +       p = au_sp_fop;
12339 +       if (unlikely(!p->done)) {
12340 +               /* initialize first time only */
12341 +               static DEFINE_SPINLOCK(spin);
12342 +
12343 +               spin_lock(&spin);
12344 +               if (!p->done) {
12345 +                       BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
12346 +                                    != AuSp_Last);
12347 +                       for (i = 0; i < AuSp_Last; i++)
12348 +                               spin_lock_init(&p[i].spin);
12349 +                       p->done = 1;
12350 +               }
12351 +               spin_unlock(&spin);
12352 +       }
12353 +
12354 +       switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
12355 +       case FMODE_READ:
12356 +               i = AuSp_FIFO_R;
12357 +               break;
12358 +       case FMODE_WRITE:
12359 +               i = AuSp_FIFO_W;
12360 +               break;
12361 +       case FMODE_READ | FMODE_WRITE:
12362 +               i = AuSp_FIFO_RW;
12363 +               break;
12364 +       default:
12365 +               BUG();
12366 +       }
12367 +
12368 +       p += i;
12369 +       if (unlikely(!p->done)) {
12370 +               /* initialize first time only */
12371 +               h_file = au_hf_top(file);
12372 +               spin_lock(&p->spin);
12373 +               if (!p->done) {
12374 +                       p->fop = *h_file->f_op;
12375 +                       p->fop.owner = THIS_MODULE;
12376 +                       if (p->fop.aio_read)
12377 +                               p->fop.aio_read = aufs_aio_read_sp;
12378 +                       if (p->fop.aio_write)
12379 +                               p->fop.aio_write = aufs_aio_write_sp;
12380 +                       p->fop.release = aufs_release_sp;
12381 +                       p->done = 1;
12382 +               }
12383 +               spin_unlock(&p->spin);
12384 +       }
12385 +       file->f_op = &p->fop;
12386 +}
12387 +
12388 +static int au_cpup_sp(struct dentry *dentry)
12389 +{
12390 +       int err;
12391 +       aufs_bindex_t bcpup;
12392 +       struct au_pin pin;
12393 +       struct au_wr_dir_args wr_dir_args = {
12394 +               .force_btgt     = -1,
12395 +               .flags          = 0
12396 +       };
12397 +
12398 +       AuDbg("%.*s\n", AuDLNPair(dentry));
12399 +
12400 +       di_read_unlock(dentry, AuLock_IR);
12401 +       di_write_lock_child(dentry);
12402 +       err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
12403 +       if (unlikely(err < 0))
12404 +               goto out;
12405 +       bcpup = err;
12406 +       err = 0;
12407 +       if (bcpup == au_dbstart(dentry))
12408 +               goto out; /* success */
12409 +
12410 +       err = au_pin(&pin, dentry, bcpup, au_opt_udba(dentry->d_sb),
12411 +                    AuPin_MNT_WRITE);
12412 +       if (!err) {
12413 +               err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME, &pin);
12414 +               au_unpin(&pin);
12415 +       }
12416 +
12417 +out:
12418 +       di_downgrade_lock(dentry, AuLock_IR);
12419 +       return err;
12420 +}
12421 +
12422 +static int au_do_open_sp(struct file *file, int flags)
12423 +{
12424 +       int err;
12425 +       struct dentry *dentry;
12426 +       struct super_block *sb;
12427 +       struct file *h_file;
12428 +       struct inode *h_inode;
12429 +
12430 +       err = au_fi_sp_add(file);
12431 +       if (unlikely(err))
12432 +               goto out;
12433 +
12434 +       dentry = file->f_dentry;
12435 +       AuDbg("%.*s\n", AuDLNPair(dentry));
12436 +
12437 +       /*
12438 +        * try copying-up.
12439 +        * operate on the ro branch is not an error.
12440 +        */
12441 +       au_cpup_sp(dentry); /* ignore */
12442 +
12443 +       /* prepare h_file */
12444 +       err = au_do_open_nondir(file, vfsub_file_flags(file));
12445 +       if (unlikely(err))
12446 +               goto out_del;
12447 +
12448 +       sb = dentry->d_sb;
12449 +       h_file = au_hf_top(file);
12450 +       h_inode = file_inode(h_file);
12451 +       di_read_unlock(dentry, AuLock_IR);
12452 +       fi_write_unlock(file);
12453 +       si_read_unlock(sb);
12454 +       /* open this fifo in aufs */
12455 +       err = h_inode->i_fop->open(file_inode(file), file);
12456 +       si_noflush_read_lock(sb);
12457 +       fi_write_lock(file);
12458 +       di_read_lock_child(dentry, AuLock_IR);
12459 +       if (!err) {
12460 +               au_init_fop_sp(file);
12461 +               goto out; /* success */
12462 +       }
12463 +
12464 +out_del:
12465 +       au_fi_sp_del(file);
12466 +out:
12467 +       return err;
12468 +}
12469 +
12470 +static int aufs_open_sp(struct inode *inode, struct file *file)
12471 +{
12472 +       int err;
12473 +       struct super_block *sb;
12474 +
12475 +       sb = file->f_dentry->d_sb;
12476 +       si_read_lock(sb, AuLock_FLUSH);
12477 +       err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
12478 +       si_read_unlock(sb);
12479 +       return err;
12480 +}
12481 +
12482 +/* ---------------------------------------------------------------------- */
12483 +
12484 +void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
12485 +{
12486 +       init_special_inode(inode, mode, rdev);
12487 +
12488 +       switch (mode & S_IFMT) {
12489 +       case S_IFIFO:
12490 +               inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
12491 +               /*FALLTHROUGH*/
12492 +       case S_IFCHR:
12493 +       case S_IFBLK:
12494 +       case S_IFSOCK:
12495 +               break;
12496 +       default:
12497 +               AuDebugOn(1);
12498 +       }
12499 +}
12500 +
12501 +int au_special_file(umode_t mode)
12502 +{
12503 +       int ret;
12504 +
12505 +       ret = 0;
12506 +       switch (mode & S_IFMT) {
12507 +       case S_IFIFO:
12508 +#if 0
12509 +       case S_IFCHR:
12510 +       case S_IFBLK:
12511 +       case S_IFSOCK:
12512 +#endif
12513 +               ret = 1;
12514 +       }
12515 +
12516 +       return ret;
12517 +}
12518 diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
12519 --- /usr/share/empty/fs/aufs/fstype.h   1970-01-01 01:00:00.000000000 +0100
12520 +++ linux/fs/aufs/fstype.h      2013-07-06 13:20:47.750198454 +0200
12521 @@ -0,0 +1,480 @@
12522 +/*
12523 + * Copyright (C) 2005-2013 Junjiro R. Okajima
12524 + *
12525 + * This program, aufs is free software; you can redistribute it and/or modify
12526 + * it under the terms of the GNU General Public License as published by
12527 + * the Free Software Foundation; either version 2 of the License, or
12528 + * (at your option) any later version.
12529 + *
12530 + * This program is distributed in the hope that it will be useful,
12531 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12532 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12533 + * GNU General Public License for more details.
12534 + *
12535 + * You should have received a copy of the GNU General Public License
12536 + * along with this program; if not, write to the Free Software
12537 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
12538 + */
12539 +
12540 +/*
12541 + * judging filesystem type
12542 + */
12543 +
12544 +#ifndef __AUFS_FSTYPE_H__
12545 +#define __AUFS_FSTYPE_H__
12546 +
12547 +#ifdef __KERNEL__
12548 +
12549 +#include <linux/fs.h>
12550 +#include <linux/magic.h>
12551 +#include <linux/romfs_fs.h>
12552 +
12553 +static inline int au_test_aufs(struct super_block *sb)
12554 +{
12555 +       return sb->s_magic == AUFS_SUPER_MAGIC;
12556 +}
12557 +
12558 +static inline const char *au_sbtype(struct super_block *sb)
12559 +{
12560 +       return sb->s_type->name;
12561 +}
12562 +
12563 +static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
12564 +{
12565 +#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
12566 +       return sb->s_magic == ROMFS_MAGIC;
12567 +#else
12568 +       return 0;
12569 +#endif
12570 +}
12571 +
12572 +static inline int au_test_romfs(struct super_block *sb __maybe_unused)
12573 +{
12574 +#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
12575 +       return sb->s_magic == ISOFS_SUPER_MAGIC;
12576 +#else
12577 +       return 0;
12578 +#endif
12579 +}
12580 +
12581 +static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
12582 +{
12583 +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
12584 +       return sb->s_magic == CRAMFS_MAGIC;
12585 +#endif
12586 +       return 0;
12587 +}
12588 +
12589 +static inline int au_test_nfs(struct super_block *sb __maybe_unused)
12590 +{
12591 +#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
12592 +       return sb->s_magic == NFS_SUPER_MAGIC;
12593 +#else
12594 +       return 0;
12595 +#endif
12596 +}
12597 +
12598 +static inline int au_test_fuse(struct super_block *sb __maybe_unused)
12599 +{
12600 +#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
12601 +       return sb->s_magic == FUSE_SUPER_MAGIC;
12602 +#else
12603 +       return 0;
12604 +#endif
12605 +}
12606 +
12607 +static inline int au_test_xfs(struct super_block *sb __maybe_unused)
12608 +{
12609 +#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
12610 +       return sb->s_magic == XFS_SB_MAGIC;
12611 +#else
12612 +       return 0;
12613 +#endif
12614 +}
12615 +
12616 +static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
12617 +{
12618 +#ifdef CONFIG_TMPFS
12619 +       return sb->s_magic == TMPFS_MAGIC;
12620 +#else
12621 +       return 0;
12622 +#endif
12623 +}
12624 +
12625 +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
12626 +{
12627 +#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
12628 +       return !strcmp(au_sbtype(sb), "ecryptfs");
12629 +#else
12630 +       return 0;
12631 +#endif
12632 +}
12633 +
12634 +static inline int au_test_smbfs(struct super_block *sb __maybe_unused)
12635 +{
12636 +#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE)
12637 +       return sb->s_magic == SMB_SUPER_MAGIC;
12638 +#else
12639 +       return 0;
12640 +#endif
12641 +}
12642 +
12643 +static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
12644 +{
12645 +#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
12646 +       return sb->s_magic == OCFS2_SUPER_MAGIC;
12647 +#else
12648 +       return 0;
12649 +#endif
12650 +}
12651 +
12652 +static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
12653 +{
12654 +#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
12655 +       return sb->s_magic == DLMFS_MAGIC;
12656 +#else
12657 +       return 0;
12658 +#endif
12659 +}
12660 +
12661 +static inline int au_test_coda(struct super_block *sb __maybe_unused)
12662 +{
12663 +#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
12664 +       return sb->s_magic == CODA_SUPER_MAGIC;
12665 +#else
12666 +       return 0;
12667 +#endif
12668 +}
12669 +
12670 +static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
12671 +{
12672 +#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
12673 +       return sb->s_magic == V9FS_MAGIC;
12674 +#else
12675 +       return 0;
12676 +#endif
12677 +}
12678 +
12679 +static inline int au_test_ext4(struct super_block *sb __maybe_unused)
12680 +{
12681 +#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE)
12682 +       return sb->s_magic == EXT4_SUPER_MAGIC;
12683 +#else
12684 +       return 0;
12685 +#endif
12686 +}
12687 +
12688 +static inline int au_test_sysv(struct super_block *sb __maybe_unused)
12689 +{
12690 +#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
12691 +       return !strcmp(au_sbtype(sb), "sysv");
12692 +#else
12693 +       return 0;
12694 +#endif
12695 +}
12696 +
12697 +static inline int au_test_ramfs(struct super_block *sb)
12698 +{
12699 +       return sb->s_magic == RAMFS_MAGIC;
12700 +}
12701 +
12702 +static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
12703 +{
12704 +#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
12705 +       return sb->s_magic == UBIFS_SUPER_MAGIC;
12706 +#else
12707 +       return 0;
12708 +#endif
12709 +}
12710 +
12711 +static inline int au_test_procfs(struct super_block *sb __maybe_unused)
12712 +{
12713 +#ifdef CONFIG_PROC_FS
12714 +       return sb->s_magic == PROC_SUPER_MAGIC;
12715 +#else
12716 +       return 0;
12717 +#endif
12718 +}
12719 +
12720 +static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
12721 +{
12722 +#ifdef CONFIG_SYSFS
12723 +       return sb->s_magic == SYSFS_MAGIC;
12724 +#else
12725 +       return 0;
12726 +#endif
12727 +}
12728 +
12729 +static inline int au_test_configfs(struct super_block *sb __maybe_unused)
12730 +{
12731 +#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
12732 +       return sb->s_magic == CONFIGFS_MAGIC;
12733 +#else
12734 +       return 0;
12735 +#endif
12736 +}
12737 +
12738 +static inline int au_test_minix(struct super_block *sb __maybe_unused)
12739 +{
12740 +#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
12741 +       return sb->s_magic == MINIX3_SUPER_MAGIC
12742 +               || sb->s_magic == MINIX2_SUPER_MAGIC
12743 +               || sb->s_magic == MINIX2_SUPER_MAGIC2
12744 +               || sb->s_magic == MINIX_SUPER_MAGIC
12745 +               || sb->s_magic == MINIX_SUPER_MAGIC2;
12746 +#else
12747 +       return 0;
12748 +#endif
12749 +}
12750 +
12751 +static inline int au_test_cifs(struct super_block *sb __maybe_unused)
12752 +{
12753 +#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
12754 +       return sb->s_magic == CIFS_MAGIC_NUMBER;
12755 +#else
12756 +       return 0;
12757 +#endif
12758 +}
12759 +
12760 +static inline int au_test_fat(struct super_block *sb __maybe_unused)
12761 +{
12762 +#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
12763 +       return sb->s_magic == MSDOS_SUPER_MAGIC;
12764 +#else
12765 +       return 0;
12766 +#endif
12767 +}
12768 +
12769 +static inline int au_test_msdos(struct super_block *sb)
12770 +{
12771 +       return au_test_fat(sb);
12772 +}
12773 +
12774 +static inline int au_test_vfat(struct super_block *sb)
12775 +{
12776 +       return au_test_fat(sb);
12777 +}
12778 +
12779 +static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
12780 +{
12781 +#ifdef CONFIG_SECURITYFS
12782 +       return sb->s_magic == SECURITYFS_MAGIC;
12783 +#else
12784 +       return 0;
12785 +#endif
12786 +}
12787 +
12788 +static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
12789 +{
12790 +#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
12791 +       return sb->s_magic == SQUASHFS_MAGIC;
12792 +#else
12793 +       return 0;
12794 +#endif
12795 +}
12796 +
12797 +static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
12798 +{
12799 +#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
12800 +       return sb->s_magic == BTRFS_SUPER_MAGIC;
12801 +#else
12802 +       return 0;
12803 +#endif
12804 +}
12805 +
12806 +static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
12807 +{
12808 +#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
12809 +       return sb->s_magic == XENFS_SUPER_MAGIC;
12810 +#else
12811 +       return 0;
12812 +#endif
12813 +}
12814 +
12815 +static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
12816 +{
12817 +#ifdef CONFIG_DEBUG_FS
12818 +       return sb->s_magic == DEBUGFS_MAGIC;
12819 +#else
12820 +       return 0;
12821 +#endif
12822 +}
12823 +
12824 +static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
12825 +{
12826 +#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
12827 +       return sb->s_magic == NILFS_SUPER_MAGIC;
12828 +#else
12829 +       return 0;
12830 +#endif
12831 +}
12832 +
12833 +static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
12834 +{
12835 +#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
12836 +       return sb->s_magic == HFSPLUS_SUPER_MAGIC;
12837 +#else
12838 +       return 0;
12839 +#endif
12840 +}
12841 +
12842 +/* ---------------------------------------------------------------------- */
12843 +/*
12844 + * they can't be an aufs branch.
12845 + */
12846 +static inline int au_test_fs_unsuppoted(struct super_block *sb)
12847 +{
12848 +       return
12849 +#ifndef CONFIG_AUFS_BR_RAMFS
12850 +               au_test_ramfs(sb) ||
12851 +#endif
12852 +               au_test_procfs(sb)
12853 +               || au_test_sysfs(sb)
12854 +               || au_test_configfs(sb)
12855 +               || au_test_debugfs(sb)
12856 +               || au_test_securityfs(sb)
12857 +               || au_test_xenfs(sb)
12858 +               || au_test_ecryptfs(sb)
12859 +               /* || !strcmp(au_sbtype(sb), "unionfs") */
12860 +               || au_test_aufs(sb); /* will be supported in next version */
12861 +}
12862 +
12863 +static inline int au_test_fs_remote(struct super_block *sb)
12864 +{
12865 +       return !au_test_tmpfs(sb)
12866 +#ifdef CONFIG_AUFS_BR_RAMFS
12867 +               && !au_test_ramfs(sb)
12868 +#endif
12869 +               && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
12870 +}
12871 +
12872 +/* ---------------------------------------------------------------------- */
12873 +
12874 +/*
12875 + * Note: these functions (below) are created after reading ->getattr() in all
12876 + * filesystems under linux/fs. it means we have to do so in every update...
12877 + */
12878 +
12879 +/*
12880 + * some filesystems require getattr to refresh the inode attributes before
12881 + * referencing.
12882 + * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
12883 + * and leave the work for d_revalidate()
12884 + */
12885 +static inline int au_test_fs_refresh_iattr(struct super_block *sb)
12886 +{
12887 +       return au_test_nfs(sb)
12888 +               || au_test_fuse(sb)
12889 +               /* || au_test_smbfs(sb) */      /* untested */
12890 +               /* || au_test_ocfs2(sb) */      /* untested */
12891 +               /* || au_test_btrfs(sb) */      /* untested */
12892 +               /* || au_test_coda(sb) */       /* untested */
12893 +               /* || au_test_v9fs(sb) */       /* untested */
12894 +               ;
12895 +}
12896 +
12897 +/*
12898 + * filesystems which don't maintain i_size or i_blocks.
12899 + */
12900 +static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
12901 +{
12902 +       return au_test_xfs(sb)
12903 +               || au_test_btrfs(sb)
12904 +               || au_test_ubifs(sb)
12905 +               || au_test_hfsplus(sb)  /* maintained, but incorrect */
12906 +               /* || au_test_ext4(sb) */       /* untested */
12907 +               /* || au_test_ocfs2(sb) */      /* untested */
12908 +               /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
12909 +               /* || au_test_sysv(sb) */       /* untested */
12910 +               /* || au_test_minix(sb) */      /* untested */
12911 +               ;
12912 +}
12913 +
12914 +/*
12915 + * filesystems which don't store the correct value in some of their inode
12916 + * attributes.
12917 + */
12918 +static inline int au_test_fs_bad_iattr(struct super_block *sb)
12919 +{
12920 +       return au_test_fs_bad_iattr_size(sb)
12921 +               /* || au_test_cifs(sb) */       /* untested */
12922 +               || au_test_fat(sb)
12923 +               || au_test_msdos(sb)
12924 +               || au_test_vfat(sb);
12925 +}
12926 +
12927 +/* they don't check i_nlink in link(2) */
12928 +static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
12929 +{
12930 +       return au_test_tmpfs(sb)
12931 +#ifdef CONFIG_AUFS_BR_RAMFS
12932 +               || au_test_ramfs(sb)
12933 +#endif
12934 +               || au_test_ubifs(sb)
12935 +               || au_test_hfsplus(sb);
12936 +}
12937 +
12938 +/*
12939 + * filesystems which sets S_NOATIME and S_NOCMTIME.
12940 + */
12941 +static inline int au_test_fs_notime(struct super_block *sb)
12942 +{
12943 +       return au_test_nfs(sb)
12944 +               || au_test_fuse(sb)
12945 +               || au_test_ubifs(sb)
12946 +               /* || au_test_cifs(sb) */       /* untested */
12947 +               ;
12948 +}
12949 +
12950 +/*
12951 + * filesystems which requires replacing i_mapping.
12952 + */
12953 +static inline int au_test_fs_bad_mapping(struct super_block *sb)
12954 +{
12955 +       return au_test_fuse(sb)
12956 +               || au_test_ubifs(sb);
12957 +}
12958 +
12959 +/* temporary support for i#1 in cramfs */
12960 +static inline int au_test_fs_unique_ino(struct inode *inode)
12961 +{
12962 +       if (au_test_cramfs(inode->i_sb))
12963 +               return inode->i_ino != 1;
12964 +       return 1;
12965 +}
12966 +
12967 +/* ---------------------------------------------------------------------- */
12968 +
12969 +/*
12970 + * the filesystem where the xino files placed must support i/o after unlink and
12971 + * maintain i_size and i_blocks.
12972 + */
12973 +static inline int au_test_fs_bad_xino(struct super_block *sb)
12974 +{
12975 +       return au_test_fs_remote(sb)
12976 +               || au_test_fs_bad_iattr_size(sb)
12977 +               /* don't want unnecessary work for xino */
12978 +               || au_test_aufs(sb)
12979 +               || au_test_ecryptfs(sb)
12980 +               || au_test_nilfs(sb);
12981 +}
12982 +
12983 +static inline int au_test_fs_trunc_xino(struct super_block *sb)
12984 +{
12985 +       return au_test_tmpfs(sb)
12986 +               || au_test_ramfs(sb);
12987 +}
12988 +
12989 +/*
12990 + * test if the @sb is real-readonly.
12991 + */
12992 +static inline int au_test_fs_rr(struct super_block *sb)
12993 +{
12994 +       return au_test_squashfs(sb)
12995 +               || au_test_iso9660(sb)
12996 +               || au_test_cramfs(sb)
12997 +               || au_test_romfs(sb);
12998 +}
12999 +
13000 +#endif /* __KERNEL__ */
13001 +#endif /* __AUFS_FSTYPE_H__ */
13002 diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
13003 --- /usr/share/empty/fs/aufs/hfsnotify.c        1970-01-01 01:00:00.000000000 +0100
13004 +++ linux/fs/aufs/hfsnotify.c   2013-07-06 13:20:47.750198454 +0200
13005 @@ -0,0 +1,296 @@
13006 +/*
13007 + * Copyright (C) 2005-2013 Junjiro R. Okajima
13008 + *
13009 + * This program, aufs is free software; you can redistribute it and/or modify
13010 + * it under the terms of the GNU General Public License as published by
13011 + * the Free Software Foundation; either version 2 of the License, or
13012 + * (at your option) any later version.
13013 + *
13014 + * This program is distributed in the hope that it will be useful,
13015 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13016 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13017 + * GNU General Public License for more details.
13018 + *
13019 + * You should have received a copy of the GNU General Public License
13020 + * along with this program; if not, write to the Free Software
13021 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
13022 + */
13023 +
13024 +/*
13025 + * fsnotify for the lower directories
13026 + */
13027 +
13028 +#include "aufs.h"
13029 +
13030 +/* FS_IN_IGNORED is unnecessary */
13031 +static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
13032 +                                | FS_CREATE | FS_EVENT_ON_CHILD);
13033 +static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
13034 +static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
13035 +
13036 +static void au_hfsn_free_mark(struct fsnotify_mark *mark)
13037 +{
13038 +       struct au_hnotify *hn = container_of(mark, struct au_hnotify,
13039 +                                            hn_mark);
13040 +       AuDbg("here\n");
13041 +       au_cache_free_hnotify(hn);
13042 +       smp_mb__before_atomic_dec();
13043 +       if (atomic64_dec_and_test(&au_hfsn_ifree))
13044 +               wake_up(&au_hfsn_wq);
13045 +}
13046 +
13047 +static int au_hfsn_alloc(struct au_hinode *hinode)
13048 +{
13049 +       int err;
13050 +       struct au_hnotify *hn;
13051 +       struct super_block *sb;
13052 +       struct au_branch *br;
13053 +       struct fsnotify_mark *mark;
13054 +       aufs_bindex_t bindex;
13055 +
13056 +       hn = hinode->hi_notify;
13057 +       sb = hn->hn_aufs_inode->i_sb;
13058 +       bindex = au_br_index(sb, hinode->hi_id);
13059 +       br = au_sbr(sb, bindex);
13060 +       AuDebugOn(!br->br_hfsn);
13061 +
13062 +       mark = &hn->hn_mark;
13063 +       fsnotify_init_mark(mark, au_hfsn_free_mark);
13064 +       mark->mask = AuHfsnMask;
13065 +       /*
13066 +        * by udba rename or rmdir, aufs assign a new inode to the known
13067 +        * h_inode, so specify 1 to allow dups.
13068 +        */
13069 +       err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
13070 +                                /*mnt*/NULL, /*allow_dups*/1);
13071 +       /* even if err */
13072 +       fsnotify_put_mark(mark);
13073 +
13074 +       return err;
13075 +}
13076 +
13077 +static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
13078 +{
13079 +       struct fsnotify_mark *mark;
13080 +       unsigned long long ull;
13081 +       struct fsnotify_group *group;
13082 +
13083 +       ull = atomic64_inc_return(&au_hfsn_ifree);
13084 +       BUG_ON(!ull);
13085 +
13086 +       mark = &hn->hn_mark;
13087 +       spin_lock(&mark->lock);
13088 +       group = mark->group;
13089 +       fsnotify_get_group(group);
13090 +       spin_unlock(&mark->lock);
13091 +       fsnotify_destroy_mark(mark, group);
13092 +       fsnotify_put_group(group);
13093 +
13094 +       /* free hn by myself */
13095 +       return 0;
13096 +}
13097 +
13098 +/* ---------------------------------------------------------------------- */
13099 +
13100 +static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
13101 +{
13102 +       struct fsnotify_mark *mark;
13103 +
13104 +       mark = &hinode->hi_notify->hn_mark;
13105 +       spin_lock(&mark->lock);
13106 +       if (do_set) {
13107 +               AuDebugOn(mark->mask & AuHfsnMask);
13108 +               mark->mask |= AuHfsnMask;
13109 +       } else {
13110 +               AuDebugOn(!(mark->mask & AuHfsnMask));
13111 +               mark->mask &= ~AuHfsnMask;
13112 +       }
13113 +       spin_unlock(&mark->lock);
13114 +       /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
13115 +}
13116 +
13117 +/* ---------------------------------------------------------------------- */
13118 +
13119 +/* #define AuDbgHnotify */
13120 +#ifdef AuDbgHnotify
13121 +static char *au_hfsn_name(u32 mask)
13122 +{
13123 +#ifdef CONFIG_AUFS_DEBUG
13124 +#define test_ret(flag)                         \
13125 +       do {                                    \
13126 +               if (mask & flag)                \
13127 +                       return #flag;           \
13128 +       } while (0)
13129 +       test_ret(FS_ACCESS);
13130 +       test_ret(FS_MODIFY);
13131 +       test_ret(FS_ATTRIB);
13132 +       test_ret(FS_CLOSE_WRITE);
13133 +       test_ret(FS_CLOSE_NOWRITE);
13134 +       test_ret(FS_OPEN);
13135 +       test_ret(FS_MOVED_FROM);
13136 +       test_ret(FS_MOVED_TO);
13137 +       test_ret(FS_CREATE);
13138 +       test_ret(FS_DELETE);
13139 +       test_ret(FS_DELETE_SELF);
13140 +       test_ret(FS_MOVE_SELF);
13141 +       test_ret(FS_UNMOUNT);
13142 +       test_ret(FS_Q_OVERFLOW);
13143 +       test_ret(FS_IN_IGNORED);
13144 +       test_ret(FS_IN_ISDIR);
13145 +       test_ret(FS_IN_ONESHOT);
13146 +       test_ret(FS_EVENT_ON_CHILD);
13147 +       return "";
13148 +#undef test_ret
13149 +#else
13150 +       return "??";
13151 +#endif
13152 +}
13153 +#endif
13154 +
13155 +/* ---------------------------------------------------------------------- */
13156 +
13157 +static void au_hfsn_free_group(struct fsnotify_group *group)
13158 +{
13159 +       struct au_br_hfsnotify *hfsn = group->private;
13160 +
13161 +       AuDbg("here\n");
13162 +       kfree(hfsn);
13163 +}
13164 +
13165 +static int au_hfsn_handle_event(struct fsnotify_group *group,
13166 +                               struct fsnotify_mark *inode_mark,
13167 +                               struct fsnotify_mark *vfsmount_mark,
13168 +                               struct fsnotify_event *event)
13169 +{
13170 +       int err;
13171 +       struct au_hnotify *hnotify;
13172 +       struct inode *h_dir, *h_inode;
13173 +       __u32 mask;
13174 +       struct qstr h_child_qstr = QSTR_INIT(event->file_name, event->name_len);
13175 +
13176 +       AuDebugOn(event->data_type != FSNOTIFY_EVENT_INODE);
13177 +
13178 +       err = 0;
13179 +       /* if FS_UNMOUNT happens, there must be another bug */
13180 +       mask = event->mask;
13181 +       AuDebugOn(mask & FS_UNMOUNT);
13182 +       if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
13183 +               goto out;
13184 +
13185 +       h_dir = event->to_tell;
13186 +       h_inode = event->inode;
13187 +#ifdef AuDbgHnotify
13188 +       au_debug(1);
13189 +       if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
13190 +           || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
13191 +               AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
13192 +                     h_dir->i_ino, mask, au_hfsn_name(mask),
13193 +                     AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
13194 +               /* WARN_ON(1); */
13195 +       }
13196 +       au_debug(0);
13197 +#endif
13198 +
13199 +       AuDebugOn(!inode_mark);
13200 +       hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
13201 +       err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
13202 +
13203 +out:
13204 +       return err;
13205 +}
13206 +
13207 +/* isn't it waste to ask every registered 'group'? */
13208 +/* copied from linux/fs/notify/inotify/inotify_fsnotiry.c */
13209 +/* it should be exported to modules */
13210 +static bool au_hfsn_should_send_event(struct fsnotify_group *group,
13211 +                                     struct inode *h_inode,
13212 +                                     struct fsnotify_mark *inode_mark,
13213 +                                     struct fsnotify_mark *vfsmount_mark,
13214 +                                     __u32 mask, void *data, int data_type)
13215 +{
13216 +       mask = (mask & ~FS_EVENT_ON_CHILD);
13217 +       return inode_mark->mask & mask;
13218 +}
13219 +
13220 +static struct fsnotify_ops au_hfsn_ops = {
13221 +       .should_send_event      = au_hfsn_should_send_event,
13222 +       .handle_event           = au_hfsn_handle_event,
13223 +       .free_group_priv        = au_hfsn_free_group
13224 +};
13225 +
13226 +/* ---------------------------------------------------------------------- */
13227 +
13228 +static void au_hfsn_fin_br(struct au_branch *br)
13229 +{
13230 +       struct au_br_hfsnotify *hfsn;
13231 +
13232 +       hfsn = br->br_hfsn;
13233 +       if (hfsn)
13234 +               fsnotify_put_group(hfsn->hfsn_group);
13235 +}
13236 +
13237 +static int au_hfsn_init_br(struct au_branch *br, int perm)
13238 +{
13239 +       int err;
13240 +       struct fsnotify_group *group;
13241 +       struct au_br_hfsnotify *hfsn;
13242 +
13243 +       err = 0;
13244 +       br->br_hfsn = NULL;
13245 +       if (!au_br_hnotifyable(perm))
13246 +               goto out;
13247 +
13248 +       err = -ENOMEM;
13249 +       hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
13250 +       if (unlikely(!hfsn))
13251 +               goto out;
13252 +
13253 +       err = 0;
13254 +       group = fsnotify_alloc_group(&au_hfsn_ops);
13255 +       if (IS_ERR(group)) {
13256 +               err = PTR_ERR(group);
13257 +               pr_err("fsnotify_alloc_group() failed, %d\n", err);
13258 +               goto out_hfsn;
13259 +       }
13260 +
13261 +       group->private = hfsn;
13262 +       hfsn->hfsn_group = group;
13263 +       br->br_hfsn = hfsn;
13264 +       goto out; /* success */
13265 +
13266 +out_hfsn:
13267 +       kfree(hfsn);
13268 +out:
13269 +       return err;
13270 +}
13271 +
13272 +static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
13273 +{
13274 +       int err;
13275 +
13276 +       err = 0;
13277 +       if (!br->br_hfsn)
13278 +               err = au_hfsn_init_br(br, perm);
13279 +
13280 +       return err;
13281 +}
13282 +
13283 +/* ---------------------------------------------------------------------- */
13284 +
13285 +static void au_hfsn_fin(void)
13286 +{
13287 +       AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
13288 +       wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
13289 +}
13290 +
13291 +const struct au_hnotify_op au_hnotify_op = {
13292 +       .ctl            = au_hfsn_ctl,
13293 +       .alloc          = au_hfsn_alloc,
13294 +       .free           = au_hfsn_free,
13295 +
13296 +       .fin            = au_hfsn_fin,
13297 +
13298 +       .reset_br       = au_hfsn_reset_br,
13299 +       .fin_br         = au_hfsn_fin_br,
13300 +       .init_br        = au_hfsn_init_br
13301 +};
13302 diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
13303 --- /usr/share/empty/fs/aufs/hfsplus.c  1970-01-01 01:00:00.000000000 +0100
13304 +++ linux/fs/aufs/hfsplus.c     2013-07-06 13:20:47.750198454 +0200
13305 @@ -0,0 +1,56 @@
13306 +/*
13307 + * Copyright (C) 2010-2013 Junjiro R. Okajima
13308 + *
13309 + * This program, aufs is free software; you can redistribute it and/or modify
13310 + * it under the terms of the GNU General Public License as published by
13311 + * the Free Software Foundation; either version 2 of the License, or
13312 + * (at your option) any later version.
13313 + *
13314 + * This program is distributed in the hope that it will be useful,
13315 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13316 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13317 + * GNU General Public License for more details.
13318 + *
13319 + * You should have received a copy of the GNU General Public License
13320 + * along with this program; if not, write to the Free Software
13321 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
13322 + */
13323 +
13324 +/*
13325 + * special support for filesystems which aqucires an inode mutex
13326 + * at final closing a file, eg, hfsplus.
13327 + *
13328 + * This trick is very simple and stupid, just to open the file before really
13329 + * neceeary open to tell hfsplus that this is not the final closing.
13330 + * The caller should call au_h_open_pre() after acquiring the inode mutex,
13331 + * and au_h_open_post() after releasing it.
13332 + */
13333 +
13334 +#include "aufs.h"
13335 +
13336 +struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex)
13337 +{
13338 +       struct file *h_file;
13339 +       struct dentry *h_dentry;
13340 +
13341 +       h_dentry = au_h_dptr(dentry, bindex);
13342 +       AuDebugOn(!h_dentry);
13343 +       AuDebugOn(!h_dentry->d_inode);
13344 +
13345 +       h_file = NULL;
13346 +       if (au_test_hfsplus(h_dentry->d_sb)
13347 +           && S_ISREG(h_dentry->d_inode->i_mode))
13348 +               h_file = au_h_open(dentry, bindex,
13349 +                                  O_RDONLY | O_NOATIME | O_LARGEFILE,
13350 +                                  /*file*/NULL);
13351 +       return h_file;
13352 +}
13353 +
13354 +void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
13355 +                   struct file *h_file)
13356 +{
13357 +       if (h_file) {
13358 +               fput(h_file);
13359 +               au_sbr_put(dentry->d_sb, bindex);
13360 +       }
13361 +}
13362 diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
13363 --- /usr/share/empty/fs/aufs/hnotify.c  1970-01-01 01:00:00.000000000 +0100
13364 +++ linux/fs/aufs/hnotify.c     2013-07-30 22:42:55.842946719 +0200
13365 @@ -0,0 +1,712 @@
13366 +/*
13367 + * Copyright (C) 2005-2013 Junjiro R. Okajima
13368 + *
13369 + * This program, aufs is free software; you can redistribute it and/or modify
13370 + * it under the terms of the GNU General Public License as published by
13371 + * the Free Software Foundation; either version 2 of the License, or
13372 + * (at your option) any later version.
13373 + *
13374 + * This program is distributed in the hope that it will be useful,
13375 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13376 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13377 + * GNU General Public License for more details.
13378 + *
13379 + * You should have received a copy of the GNU General Public License
13380 + * along with this program; if not, write to the Free Software
13381 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
13382 + */
13383 +
13384 +/*
13385 + * abstraction to notify the direct changes on lower directories
13386 + */
13387 +
13388 +#include "aufs.h"
13389 +
13390 +int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
13391 +{
13392 +       int err;
13393 +       struct au_hnotify *hn;
13394 +
13395 +       err = -ENOMEM;
13396 +       hn = au_cache_alloc_hnotify();
13397 +       if (hn) {
13398 +               hn->hn_aufs_inode = inode;
13399 +               hinode->hi_notify = hn;
13400 +               err = au_hnotify_op.alloc(hinode);
13401 +               AuTraceErr(err);
13402 +               if (unlikely(err)) {
13403 +                       hinode->hi_notify = NULL;
13404 +                       au_cache_free_hnotify(hn);
13405 +                       /*
13406 +                        * The upper dir was removed by udba, but the same named
13407 +                        * dir left. In this case, aufs assignes a new inode
13408 +                        * number and set the monitor again.
13409 +                        * For the lower dir, the old monitnor is still left.
13410 +                        */
13411 +                       if (err == -EEXIST)
13412 +                               err = 0;
13413 +               }
13414 +       }
13415 +
13416 +       AuTraceErr(err);
13417 +       return err;
13418 +}
13419 +
13420 +void au_hn_free(struct au_hinode *hinode)
13421 +{
13422 +       struct au_hnotify *hn;
13423 +
13424 +       hn = hinode->hi_notify;
13425 +       if (hn) {
13426 +               hinode->hi_notify = NULL;
13427 +               if (au_hnotify_op.free(hinode, hn))
13428 +                       au_cache_free_hnotify(hn);
13429 +       }
13430 +}
13431 +
13432 +/* ---------------------------------------------------------------------- */
13433 +
13434 +void au_hn_ctl(struct au_hinode *hinode, int do_set)
13435 +{
13436 +       if (hinode->hi_notify)
13437 +               au_hnotify_op.ctl(hinode, do_set);
13438 +}
13439 +
13440 +void au_hn_reset(struct inode *inode, unsigned int flags)
13441 +{
13442 +       aufs_bindex_t bindex, bend;
13443 +       struct inode *hi;
13444 +       struct dentry *iwhdentry;
13445 +
13446 +       bend = au_ibend(inode);
13447 +       for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
13448 +               hi = au_h_iptr(inode, bindex);
13449 +               if (!hi)
13450 +                       continue;
13451 +
13452 +               /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
13453 +               iwhdentry = au_hi_wh(inode, bindex);
13454 +               if (iwhdentry)
13455 +                       dget(iwhdentry);
13456 +               au_igrab(hi);
13457 +               au_set_h_iptr(inode, bindex, NULL, 0);
13458 +               au_set_h_iptr(inode, bindex, au_igrab(hi),
13459 +                             flags & ~AuHi_XINO);
13460 +               iput(hi);
13461 +               dput(iwhdentry);
13462 +               /* mutex_unlock(&hi->i_mutex); */
13463 +       }
13464 +}
13465 +
13466 +/* ---------------------------------------------------------------------- */
13467 +
13468 +static int hn_xino(struct inode *inode, struct inode *h_inode)
13469 +{
13470 +       int err;
13471 +       aufs_bindex_t bindex, bend, bfound, bstart;
13472 +       struct inode *h_i;
13473 +
13474 +       err = 0;
13475 +       if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
13476 +               pr_warn("branch root dir was changed\n");
13477 +               goto out;
13478 +       }
13479 +
13480 +       bfound = -1;
13481 +       bend = au_ibend(inode);
13482 +       bstart = au_ibstart(inode);
13483 +#if 0 /* reserved for future use */
13484 +       if (bindex == bend) {
13485 +               /* keep this ino in rename case */
13486 +               goto out;
13487 +       }
13488 +#endif
13489 +       for (bindex = bstart; bindex <= bend; bindex++)
13490 +               if (au_h_iptr(inode, bindex) == h_inode) {
13491 +                       bfound = bindex;
13492 +                       break;
13493 +               }
13494 +       if (bfound < 0)
13495 +               goto out;
13496 +
13497 +       for (bindex = bstart; bindex <= bend; bindex++) {
13498 +               h_i = au_h_iptr(inode, bindex);
13499 +               if (!h_i)
13500 +                       continue;
13501 +
13502 +               err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
13503 +               /* ignore this error */
13504 +               /* bad action? */
13505 +       }
13506 +
13507 +       /* children inode number will be broken */
13508 +
13509 +out:
13510 +       AuTraceErr(err);
13511 +       return err;
13512 +}
13513 +
13514 +static int hn_gen_tree(struct dentry *dentry)
13515 +{
13516 +       int err, i, j, ndentry;
13517 +       struct au_dcsub_pages dpages;
13518 +       struct au_dpage *dpage;
13519 +       struct dentry **dentries;
13520 +
13521 +       err = au_dpages_init(&dpages, GFP_NOFS);
13522 +       if (unlikely(err))
13523 +               goto out;
13524 +       err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
13525 +       if (unlikely(err))
13526 +               goto out_dpages;
13527 +
13528 +       for (i = 0; i < dpages.ndpage; i++) {
13529 +               dpage = dpages.dpages + i;
13530 +               dentries = dpage->dentries;
13531 +               ndentry = dpage->ndentry;
13532 +               for (j = 0; j < ndentry; j++) {
13533 +                       struct dentry *d;
13534 +
13535 +                       d = dentries[j];
13536 +                       if (IS_ROOT(d))
13537 +                               continue;
13538 +
13539 +                       au_digen_dec(d);
13540 +                       if (d->d_inode)
13541 +                               /* todo: reset children xino?
13542 +                                  cached children only? */
13543 +                               au_iigen_dec(d->d_inode);
13544 +               }
13545 +       }
13546 +
13547 +out_dpages:
13548 +       au_dpages_free(&dpages);
13549 +
13550 +#if 0
13551 +       /* discard children */
13552 +       dentry_unhash(dentry);
13553 +       dput(dentry);
13554 +#endif
13555 +out:
13556 +       return err;
13557 +}
13558 +
13559 +/*
13560 + * return 0 if processed.
13561 + */
13562 +static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
13563 +                          const unsigned int isdir)
13564 +{
13565 +       int err;
13566 +       struct dentry *d;
13567 +       struct qstr *dname;
13568 +
13569 +       err = 1;
13570 +       if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
13571 +               pr_warn("branch root dir was changed\n");
13572 +               err = 0;
13573 +               goto out;
13574 +       }
13575 +
13576 +       if (!isdir) {
13577 +               AuDebugOn(!name);
13578 +               au_iigen_dec(inode);
13579 +               spin_lock(&inode->i_lock);
13580 +               hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
13581 +                       spin_lock(&d->d_lock);
13582 +                       dname = &d->d_name;
13583 +                       if (dname->len != nlen
13584 +                           && memcmp(dname->name, name, nlen)) {
13585 +                               spin_unlock(&d->d_lock);
13586 +                               continue;
13587 +                       }
13588 +                       err = 0;
13589 +                       au_digen_dec(d);
13590 +                       spin_unlock(&d->d_lock);
13591 +                       break;
13592 +               }
13593 +               spin_unlock(&inode->i_lock);
13594 +       } else {
13595 +               au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
13596 +               d = d_find_alias(inode);
13597 +               if (!d) {
13598 +                       au_iigen_dec(inode);
13599 +                       goto out;
13600 +               }
13601 +
13602 +               spin_lock(&d->d_lock);
13603 +               dname = &d->d_name;
13604 +               if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
13605 +                       spin_unlock(&d->d_lock);
13606 +                       err = hn_gen_tree(d);
13607 +                       spin_lock(&d->d_lock);
13608 +               }
13609 +               spin_unlock(&d->d_lock);
13610 +               dput(d);
13611 +       }
13612 +
13613 +out:
13614 +       AuTraceErr(err);
13615 +       return err;
13616 +}
13617 +
13618 +static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
13619 +{
13620 +       int err;
13621 +       struct inode *inode;
13622 +
13623 +       inode = dentry->d_inode;
13624 +       if (IS_ROOT(dentry)
13625 +           /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
13626 +               ) {
13627 +               pr_warn("branch root dir was changed\n");
13628 +               return 0;
13629 +       }
13630 +
13631 +       err = 0;
13632 +       if (!isdir) {
13633 +               au_digen_dec(dentry);
13634 +               if (inode)
13635 +                       au_iigen_dec(inode);
13636 +       } else {
13637 +               au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
13638 +               if (inode)
13639 +                       err = hn_gen_tree(dentry);
13640 +       }
13641 +
13642 +       AuTraceErr(err);
13643 +       return err;
13644 +}
13645 +
13646 +/* ---------------------------------------------------------------------- */
13647 +
13648 +/* hnotify job flags */
13649 +#define AuHnJob_XINO0          1
13650 +#define AuHnJob_GEN            (1 << 1)
13651 +#define AuHnJob_DIRENT         (1 << 2)
13652 +#define AuHnJob_ISDIR          (1 << 3)
13653 +#define AuHnJob_TRYXINO0       (1 << 4)
13654 +#define AuHnJob_MNTPNT         (1 << 5)
13655 +#define au_ftest_hnjob(flags, name)    ((flags) & AuHnJob_##name)
13656 +#define au_fset_hnjob(flags, name) \
13657 +       do { (flags) |= AuHnJob_##name; } while (0)
13658 +#define au_fclr_hnjob(flags, name) \
13659 +       do { (flags) &= ~AuHnJob_##name; } while (0)
13660 +
13661 +enum {
13662 +       AuHn_CHILD,
13663 +       AuHn_PARENT,
13664 +       AuHnLast
13665 +};
13666 +
13667 +struct au_hnotify_args {
13668 +       struct inode *h_dir, *dir, *h_child_inode;
13669 +       u32 mask;
13670 +       unsigned int flags[AuHnLast];
13671 +       unsigned int h_child_nlen;
13672 +       char h_child_name[];
13673 +};
13674 +
13675 +struct hn_job_args {
13676 +       unsigned int flags;
13677 +       struct inode *inode, *h_inode, *dir, *h_dir;
13678 +       struct dentry *dentry;
13679 +       char *h_name;
13680 +       int h_nlen;
13681 +};
13682 +
13683 +static int hn_job(struct hn_job_args *a)
13684 +{
13685 +       const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
13686 +
13687 +       /* reset xino */
13688 +       if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
13689 +               hn_xino(a->inode, a->h_inode); /* ignore this error */
13690 +
13691 +       if (au_ftest_hnjob(a->flags, TRYXINO0)
13692 +           && a->inode
13693 +           && a->h_inode) {
13694 +               mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
13695 +               if (!a->h_inode->i_nlink)
13696 +                       hn_xino(a->inode, a->h_inode); /* ignore this error */
13697 +               mutex_unlock(&a->h_inode->i_mutex);
13698 +       }
13699 +
13700 +       /* make the generation obsolete */
13701 +       if (au_ftest_hnjob(a->flags, GEN)) {
13702 +               int err = -1;
13703 +               if (a->inode)
13704 +                       err = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
13705 +                                             isdir);
13706 +               if (err && a->dentry)
13707 +                       hn_gen_by_name(a->dentry, isdir);
13708 +               /* ignore this error */
13709 +       }
13710 +
13711 +       /* make dir entries obsolete */
13712 +       if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
13713 +               struct au_vdir *vdir;
13714 +
13715 +               vdir = au_ivdir(a->inode);
13716 +               if (vdir)
13717 +                       vdir->vd_jiffy = 0;
13718 +               /* IMustLock(a->inode); */
13719 +               /* a->inode->i_version++; */
13720 +       }
13721 +
13722 +       /* can do nothing but warn */
13723 +       if (au_ftest_hnjob(a->flags, MNTPNT)
13724 +           && a->dentry
13725 +           && d_mountpoint(a->dentry))
13726 +               pr_warn("mount-point %.*s is removed or renamed\n",
13727 +                       AuDLNPair(a->dentry));
13728 +
13729 +       return 0;
13730 +}
13731 +
13732 +/* ---------------------------------------------------------------------- */
13733 +
13734 +static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
13735 +                                          struct inode *dir)
13736 +{
13737 +       struct dentry *dentry, *d, *parent;
13738 +       struct qstr *dname;
13739 +
13740 +       parent = d_find_alias(dir);
13741 +       if (!parent)
13742 +               return NULL;
13743 +
13744 +       dentry = NULL;
13745 +       spin_lock(&parent->d_lock);
13746 +       list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
13747 +               /* AuDbg("%.*s\n", AuDLNPair(d)); */
13748 +               spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
13749 +               dname = &d->d_name;
13750 +               if (dname->len != nlen || memcmp(dname->name, name, nlen))
13751 +                       goto cont_unlock;
13752 +               if (au_di(d))
13753 +                       au_digen_dec(d);
13754 +               else
13755 +                       goto cont_unlock;
13756 +               if (d->d_count) {
13757 +                       dentry = dget_dlock(d);
13758 +                       spin_unlock(&d->d_lock);
13759 +                       break;
13760 +               }
13761 +
13762 +       cont_unlock:
13763 +               spin_unlock(&d->d_lock);
13764 +       }
13765 +       spin_unlock(&parent->d_lock);
13766 +       dput(parent);
13767 +
13768 +       if (dentry)
13769 +               di_write_lock_child(dentry);
13770 +
13771 +       return dentry;
13772 +}
13773 +
13774 +static struct inode *lookup_wlock_by_ino(struct super_block *sb,
13775 +                                        aufs_bindex_t bindex, ino_t h_ino)
13776 +{
13777 +       struct inode *inode;
13778 +       ino_t ino;
13779 +       int err;
13780 +
13781 +       inode = NULL;
13782 +       err = au_xino_read(sb, bindex, h_ino, &ino);
13783 +       if (!err && ino)
13784 +               inode = ilookup(sb, ino);
13785 +       if (!inode)
13786 +               goto out;
13787 +
13788 +       if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
13789 +               pr_warn("wrong root branch\n");
13790 +               iput(inode);
13791 +               inode = NULL;
13792 +               goto out;
13793 +       }
13794 +
13795 +       ii_write_lock_child(inode);
13796 +
13797 +out:
13798 +       return inode;
13799 +}
13800 +
13801 +static void au_hn_bh(void *_args)
13802 +{
13803 +       struct au_hnotify_args *a = _args;
13804 +       struct super_block *sb;
13805 +       aufs_bindex_t bindex, bend, bfound;
13806 +       unsigned char xino, try_iput;
13807 +       int err;
13808 +       struct inode *inode;
13809 +       ino_t h_ino;
13810 +       struct hn_job_args args;
13811 +       struct dentry *dentry;
13812 +       struct au_sbinfo *sbinfo;
13813 +
13814 +       AuDebugOn(!_args);
13815 +       AuDebugOn(!a->h_dir);
13816 +       AuDebugOn(!a->dir);
13817 +       AuDebugOn(!a->mask);
13818 +       AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
13819 +             a->mask, a->dir->i_ino, a->h_dir->i_ino,
13820 +             a->h_child_inode ? a->h_child_inode->i_ino : 0);
13821 +
13822 +       inode = NULL;
13823 +       dentry = NULL;
13824 +       /*
13825 +        * do not lock a->dir->i_mutex here
13826 +        * because of d_revalidate() may cause a deadlock.
13827 +        */
13828 +       sb = a->dir->i_sb;
13829 +       AuDebugOn(!sb);
13830 +       sbinfo = au_sbi(sb);
13831 +       AuDebugOn(!sbinfo);
13832 +       si_write_lock(sb, AuLock_NOPLMW);
13833 +
13834 +       ii_read_lock_parent(a->dir);
13835 +       bfound = -1;
13836 +       bend = au_ibend(a->dir);
13837 +       for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
13838 +               if (au_h_iptr(a->dir, bindex) == a->h_dir) {
13839 +                       bfound = bindex;
13840 +                       break;
13841 +               }
13842 +       ii_read_unlock(a->dir);
13843 +       if (unlikely(bfound < 0))
13844 +               goto out;
13845 +
13846 +       xino = !!au_opt_test(au_mntflags(sb), XINO);
13847 +       h_ino = 0;
13848 +       if (a->h_child_inode)
13849 +               h_ino = a->h_child_inode->i_ino;
13850 +
13851 +       if (a->h_child_nlen
13852 +           && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
13853 +               || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
13854 +               dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
13855 +                                             a->dir);
13856 +       try_iput = 0;
13857 +       if (dentry)
13858 +               inode = dentry->d_inode;
13859 +       if (xino && !inode && h_ino
13860 +           && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
13861 +               || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
13862 +               || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
13863 +               inode = lookup_wlock_by_ino(sb, bfound, h_ino);
13864 +               try_iput = 1;
13865 +           }
13866 +
13867 +       args.flags = a->flags[AuHn_CHILD];
13868 +       args.dentry = dentry;
13869 +       args.inode = inode;
13870 +       args.h_inode = a->h_child_inode;
13871 +       args.dir = a->dir;
13872 +       args.h_dir = a->h_dir;
13873 +       args.h_name = a->h_child_name;
13874 +       args.h_nlen = a->h_child_nlen;
13875 +       err = hn_job(&args);
13876 +       if (dentry) {
13877 +               if (au_di(dentry))
13878 +                       di_write_unlock(dentry);
13879 +               dput(dentry);
13880 +       }
13881 +       if (inode && try_iput) {
13882 +               ii_write_unlock(inode);
13883 +               iput(inode);
13884 +       }
13885 +
13886 +       ii_write_lock_parent(a->dir);
13887 +       args.flags = a->flags[AuHn_PARENT];
13888 +       args.dentry = NULL;
13889 +       args.inode = a->dir;
13890 +       args.h_inode = a->h_dir;
13891 +       args.dir = NULL;
13892 +       args.h_dir = NULL;
13893 +       args.h_name = NULL;
13894 +       args.h_nlen = 0;
13895 +       err = hn_job(&args);
13896 +       ii_write_unlock(a->dir);
13897 +
13898 +out:
13899 +       iput(a->h_child_inode);
13900 +       iput(a->h_dir);
13901 +       iput(a->dir);
13902 +       si_write_unlock(sb);
13903 +       au_nwt_done(&sbinfo->si_nowait);
13904 +       kfree(a);
13905 +}
13906 +
13907 +/* ---------------------------------------------------------------------- */
13908 +
13909 +int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
13910 +              struct qstr *h_child_qstr, struct inode *h_child_inode)
13911 +{
13912 +       int err, len;
13913 +       unsigned int flags[AuHnLast], f;
13914 +       unsigned char isdir, isroot, wh;
13915 +       struct inode *dir;
13916 +       struct au_hnotify_args *args;
13917 +       char *p, *h_child_name;
13918 +
13919 +       err = 0;
13920 +       AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
13921 +       dir = igrab(hnotify->hn_aufs_inode);
13922 +       if (!dir)
13923 +               goto out;
13924 +
13925 +       isroot = (dir->i_ino == AUFS_ROOT_INO);
13926 +       wh = 0;
13927 +       h_child_name = (void *)h_child_qstr->name;
13928 +       len = h_child_qstr->len;
13929 +       if (h_child_name) {
13930 +               if (len > AUFS_WH_PFX_LEN
13931 +                   && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
13932 +                       h_child_name += AUFS_WH_PFX_LEN;
13933 +                       len -= AUFS_WH_PFX_LEN;
13934 +                       wh = 1;
13935 +               }
13936 +       }
13937 +
13938 +       isdir = 0;
13939 +       if (h_child_inode)
13940 +               isdir = !!S_ISDIR(h_child_inode->i_mode);
13941 +       flags[AuHn_PARENT] = AuHnJob_ISDIR;
13942 +       flags[AuHn_CHILD] = 0;
13943 +       if (isdir)
13944 +               flags[AuHn_CHILD] = AuHnJob_ISDIR;
13945 +       au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
13946 +       au_fset_hnjob(flags[AuHn_CHILD], GEN);
13947 +       switch (mask & FS_EVENTS_POSS_ON_CHILD) {
13948 +       case FS_MOVED_FROM:
13949 +       case FS_MOVED_TO:
13950 +               au_fset_hnjob(flags[AuHn_CHILD], XINO0);
13951 +               au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
13952 +               /*FALLTHROUGH*/
13953 +       case FS_CREATE:
13954 +               AuDebugOn(!h_child_name || !h_child_inode);
13955 +               break;
13956 +
13957 +       case FS_DELETE:
13958 +               /*
13959 +                * aufs never be able to get this child inode.
13960 +                * revalidation should be in d_revalidate()
13961 +                * by checking i_nlink, i_generation or d_unhashed().
13962 +                */
13963 +               AuDebugOn(!h_child_name);
13964 +               au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
13965 +               au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
13966 +               break;
13967 +
13968 +       default:
13969 +               AuDebugOn(1);
13970 +       }
13971 +
13972 +       if (wh)
13973 +               h_child_inode = NULL;
13974 +
13975 +       err = -ENOMEM;
13976 +       /* iput() and kfree() will be called in au_hnotify() */
13977 +       args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
13978 +       if (unlikely(!args)) {
13979 +               AuErr1("no memory\n");
13980 +               iput(dir);
13981 +               goto out;
13982 +       }
13983 +       args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
13984 +       args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
13985 +       args->mask = mask;
13986 +       args->dir = dir;
13987 +       args->h_dir = igrab(h_dir);
13988 +       if (h_child_inode)
13989 +               h_child_inode = igrab(h_child_inode); /* can be NULL */
13990 +       args->h_child_inode = h_child_inode;
13991 +       args->h_child_nlen = len;
13992 +       if (len) {
13993 +               p = (void *)args;
13994 +               p += sizeof(*args);
13995 +               memcpy(p, h_child_name, len);
13996 +               p[len] = 0;
13997 +       }
13998 +
13999 +       f = 0;
14000 +       if (!dir->i_nlink)
14001 +               f = AuWkq_NEST;
14002 +       err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
14003 +       if (unlikely(err)) {
14004 +               pr_err("wkq %d\n", err);
14005 +               iput(args->h_child_inode);
14006 +               iput(args->h_dir);
14007 +               iput(args->dir);
14008 +               kfree(args);
14009 +       }
14010 +
14011 +out:
14012 +       return err;
14013 +}
14014 +
14015 +/* ---------------------------------------------------------------------- */
14016 +
14017 +int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
14018 +{
14019 +       int err;
14020 +
14021 +       AuDebugOn(!(udba & AuOptMask_UDBA));
14022 +
14023 +       err = 0;
14024 +       if (au_hnotify_op.reset_br)
14025 +               err = au_hnotify_op.reset_br(udba, br, perm);
14026 +
14027 +       return err;
14028 +}
14029 +
14030 +int au_hnotify_init_br(struct au_branch *br, int perm)
14031 +{
14032 +       int err;
14033 +
14034 +       err = 0;
14035 +       if (au_hnotify_op.init_br)
14036 +               err = au_hnotify_op.init_br(br, perm);
14037 +
14038 +       return err;
14039 +}
14040 +
14041 +void au_hnotify_fin_br(struct au_branch *br)
14042 +{
14043 +       if (au_hnotify_op.fin_br)
14044 +               au_hnotify_op.fin_br(br);
14045 +}
14046 +
14047 +static void au_hn_destroy_cache(void)
14048 +{
14049 +       kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
14050 +       au_cachep[AuCache_HNOTIFY] = NULL;
14051 +}
14052 +
14053 +int __init au_hnotify_init(void)
14054 +{
14055 +       int err;
14056 +
14057 +       err = -ENOMEM;
14058 +       au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
14059 +       if (au_cachep[AuCache_HNOTIFY]) {
14060 +               err = 0;
14061 +               if (au_hnotify_op.init)
14062 +                       err = au_hnotify_op.init();
14063 +               if (unlikely(err))
14064 +                       au_hn_destroy_cache();
14065 +       }
14066 +       AuTraceErr(err);
14067 +       return err;
14068 +}
14069 +
14070 +void au_hnotify_fin(void)
14071 +{
14072 +       if (au_hnotify_op.fin)
14073 +               au_hnotify_op.fin();
14074 +       /* cf. au_cache_fin() */
14075 +       if (au_cachep[AuCache_HNOTIFY])
14076 +               au_hn_destroy_cache();
14077 +}
14078 diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
14079 --- /usr/share/empty/fs/aufs/iinfo.c    1970-01-01 01:00:00.000000000 +0100
14080 +++ linux/fs/aufs/iinfo.c       2013-07-06 13:20:47.750198454 +0200
14081 @@ -0,0 +1,276 @@
14082 +/*
14083 + * Copyright (C) 2005-2013 Junjiro R. Okajima
14084 + *
14085 + * This program, aufs is free software; you can redistribute it and/or modify
14086 + * it under the terms of the GNU General Public License as published by
14087 + * the Free Software Foundation; either version 2 of the License, or
14088 + * (at your option) any later version.
14089 + *
14090 + * This program is distributed in the hope that it will be useful,
14091 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14092 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14093 + * GNU General Public License for more details.
14094 + *
14095 + * You should have received a copy of the GNU General Public License
14096 + * along with this program; if not, write to the Free Software
14097 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
14098 + */
14099 +
14100 +/*
14101 + * inode private data
14102 + */
14103 +
14104 +#include "aufs.h"
14105 +
14106 +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
14107 +{
14108 +       struct inode *h_inode;
14109 +
14110 +       IiMustAnyLock(inode);
14111 +
14112 +       h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
14113 +       AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14114 +       return h_inode;
14115 +}
14116 +
14117 +/* todo: hard/soft set? */
14118 +void au_hiput(struct au_hinode *hinode)
14119 +{
14120 +       au_hn_free(hinode);
14121 +       dput(hinode->hi_whdentry);
14122 +       iput(hinode->hi_inode);
14123 +}
14124 +
14125 +unsigned int au_hi_flags(struct inode *inode, int isdir)
14126 +{
14127 +       unsigned int flags;
14128 +       const unsigned int mnt_flags = au_mntflags(inode->i_sb);
14129 +
14130 +       flags = 0;
14131 +       if (au_opt_test(mnt_flags, XINO))
14132 +               au_fset_hi(flags, XINO);
14133 +       if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
14134 +               au_fset_hi(flags, HNOTIFY);
14135 +       return flags;
14136 +}
14137 +
14138 +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
14139 +                  struct inode *h_inode, unsigned int flags)
14140 +{
14141 +       struct au_hinode *hinode;
14142 +       struct inode *hi;
14143 +       struct au_iinfo *iinfo = au_ii(inode);
14144 +
14145 +       IiMustWriteLock(inode);
14146 +
14147 +       hinode = iinfo->ii_hinode + bindex;
14148 +       hi = hinode->hi_inode;
14149 +       AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14150 +
14151 +       if (hi)
14152 +               au_hiput(hinode);
14153 +       hinode->hi_inode = h_inode;
14154 +       if (h_inode) {
14155 +               int err;
14156 +               struct super_block *sb = inode->i_sb;
14157 +               struct au_branch *br;
14158 +
14159 +               AuDebugOn(inode->i_mode
14160 +                         && (h_inode->i_mode & S_IFMT)
14161 +                         != (inode->i_mode & S_IFMT));
14162 +               if (bindex == iinfo->ii_bstart)
14163 +                       au_cpup_igen(inode, h_inode);
14164 +               br = au_sbr(sb, bindex);
14165 +               hinode->hi_id = br->br_id;
14166 +               if (au_ftest_hi(flags, XINO)) {
14167 +                       err = au_xino_write(sb, bindex, h_inode->i_ino,
14168 +                                           inode->i_ino);
14169 +                       if (unlikely(err))
14170 +                               AuIOErr1("failed au_xino_write() %d\n", err);
14171 +               }
14172 +
14173 +               if (au_ftest_hi(flags, HNOTIFY)
14174 +                   && au_br_hnotifyable(br->br_perm)) {
14175 +                       err = au_hn_alloc(hinode, inode);
14176 +                       if (unlikely(err))
14177 +                               AuIOErr1("au_hn_alloc() %d\n", err);
14178 +               }
14179 +       }
14180 +}
14181 +
14182 +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
14183 +                 struct dentry *h_wh)
14184 +{
14185 +       struct au_hinode *hinode;
14186 +
14187 +       IiMustWriteLock(inode);
14188 +
14189 +       hinode = au_ii(inode)->ii_hinode + bindex;
14190 +       AuDebugOn(hinode->hi_whdentry);
14191 +       hinode->hi_whdentry = h_wh;
14192 +}
14193 +
14194 +void au_update_iigen(struct inode *inode, int half)
14195 +{
14196 +       struct au_iinfo *iinfo;
14197 +       struct au_iigen *iigen;
14198 +       unsigned int sigen;
14199 +
14200 +       sigen = au_sigen(inode->i_sb);
14201 +       iinfo = au_ii(inode);
14202 +       iigen = &iinfo->ii_generation;
14203 +       spin_lock(&iinfo->ii_genspin);
14204 +       iigen->ig_generation = sigen;
14205 +       if (half)
14206 +               au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
14207 +       else
14208 +               au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
14209 +       spin_unlock(&iinfo->ii_genspin);
14210 +}
14211 +
14212 +/* it may be called at remount time, too */
14213 +void au_update_ibrange(struct inode *inode, int do_put_zero)
14214 +{
14215 +       struct au_iinfo *iinfo;
14216 +       aufs_bindex_t bindex, bend;
14217 +
14218 +       iinfo = au_ii(inode);
14219 +       if (!iinfo)
14220 +               return;
14221 +
14222 +       IiMustWriteLock(inode);
14223 +
14224 +       if (do_put_zero && iinfo->ii_bstart >= 0) {
14225 +               for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14226 +                    bindex++) {
14227 +                       struct inode *h_i;
14228 +
14229 +                       h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
14230 +                       if (h_i && !h_i->i_nlink)
14231 +                               au_set_h_iptr(inode, bindex, NULL, 0);
14232 +               }
14233 +       }
14234 +
14235 +       iinfo->ii_bstart = -1;
14236 +       iinfo->ii_bend = -1;
14237 +       bend = au_sbend(inode->i_sb);
14238 +       for (bindex = 0; bindex <= bend; bindex++)
14239 +               if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14240 +                       iinfo->ii_bstart = bindex;
14241 +                       break;
14242 +               }
14243 +       if (iinfo->ii_bstart >= 0)
14244 +               for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
14245 +                       if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14246 +                               iinfo->ii_bend = bindex;
14247 +                               break;
14248 +                       }
14249 +       AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
14250 +}
14251 +
14252 +/* ---------------------------------------------------------------------- */
14253 +
14254 +void au_icntnr_init_once(void *_c)
14255 +{
14256 +       struct au_icntnr *c = _c;
14257 +       struct au_iinfo *iinfo = &c->iinfo;
14258 +       static struct lock_class_key aufs_ii;
14259 +
14260 +       spin_lock_init(&iinfo->ii_genspin);
14261 +       au_rw_init(&iinfo->ii_rwsem);
14262 +       au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
14263 +       inode_init_once(&c->vfs_inode);
14264 +}
14265 +
14266 +int au_iinfo_init(struct inode *inode)
14267 +{
14268 +       struct au_iinfo *iinfo;
14269 +       struct super_block *sb;
14270 +       int nbr, i;
14271 +
14272 +       sb = inode->i_sb;
14273 +       iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
14274 +       nbr = au_sbend(sb) + 1;
14275 +       if (unlikely(nbr <= 0))
14276 +               nbr = 1;
14277 +       iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
14278 +       if (iinfo->ii_hinode) {
14279 +               au_ninodes_inc(sb);
14280 +               for (i = 0; i < nbr; i++)
14281 +                       iinfo->ii_hinode[i].hi_id = -1;
14282 +
14283 +               iinfo->ii_generation.ig_generation = au_sigen(sb);
14284 +               iinfo->ii_bstart = -1;
14285 +               iinfo->ii_bend = -1;
14286 +               iinfo->ii_vdir = NULL;
14287 +               return 0;
14288 +       }
14289 +       return -ENOMEM;
14290 +}
14291 +
14292 +int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
14293 +{
14294 +       int err, sz;
14295 +       struct au_hinode *hip;
14296 +
14297 +       AuRwMustWriteLock(&iinfo->ii_rwsem);
14298 +
14299 +       err = -ENOMEM;
14300 +       sz = sizeof(*hip) * (iinfo->ii_bend + 1);
14301 +       if (!sz)
14302 +               sz = sizeof(*hip);
14303 +       hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
14304 +       if (hip) {
14305 +               iinfo->ii_hinode = hip;
14306 +               err = 0;
14307 +       }
14308 +
14309 +       return err;
14310 +}
14311 +
14312 +void au_iinfo_fin(struct inode *inode)
14313 +{
14314 +       struct au_iinfo *iinfo;
14315 +       struct au_hinode *hi;
14316 +       struct super_block *sb;
14317 +       aufs_bindex_t bindex, bend;
14318 +       const unsigned char unlinked = !inode->i_nlink;
14319 +
14320 +       iinfo = au_ii(inode);
14321 +       /* bad_inode case */
14322 +       if (!iinfo)
14323 +               return;
14324 +
14325 +       sb = inode->i_sb;
14326 +       au_ninodes_dec(sb);
14327 +       if (si_pid_test(sb))
14328 +               au_xino_delete_inode(inode, unlinked);
14329 +       else {
14330 +               /*
14331 +                * it is safe to hide the dependency between sbinfo and
14332 +                * sb->s_umount.
14333 +                */
14334 +               lockdep_off();
14335 +               si_noflush_read_lock(sb);
14336 +               au_xino_delete_inode(inode, unlinked);
14337 +               si_read_unlock(sb);
14338 +               lockdep_on();
14339 +       }
14340 +
14341 +       if (iinfo->ii_vdir)
14342 +               au_vdir_free(iinfo->ii_vdir);
14343 +
14344 +       bindex = iinfo->ii_bstart;
14345 +       if (bindex >= 0) {
14346 +               hi = iinfo->ii_hinode + bindex;
14347 +               bend = iinfo->ii_bend;
14348 +               while (bindex++ <= bend) {
14349 +                       if (hi->hi_inode)
14350 +                               au_hiput(hi);
14351 +                       hi++;
14352 +               }
14353 +       }
14354 +       kfree(iinfo->ii_hinode);
14355 +       iinfo->ii_hinode = NULL;
14356 +       AuRwDestroy(&iinfo->ii_rwsem);
14357 +}
14358 diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
14359 --- /usr/share/empty/fs/aufs/inode.c    1970-01-01 01:00:00.000000000 +0100
14360 +++ linux/fs/aufs/inode.c       2013-07-06 13:20:47.750198454 +0200
14361 @@ -0,0 +1,492 @@
14362 +/*
14363 + * Copyright (C) 2005-2013 Junjiro R. Okajima
14364 + *
14365 + * This program, aufs is free software; you can redistribute it and/or modify
14366 + * it under the terms of the GNU General Public License as published by
14367 + * the Free Software Foundation; either version 2 of the License, or
14368 + * (at your option) any later version.
14369 + *
14370 + * This program is distributed in the hope that it will be useful,
14371 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14372 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14373 + * GNU General Public License for more details.
14374 + *
14375 + * You should have received a copy of the GNU General Public License
14376 + * along with this program; if not, write to the Free Software
14377 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
14378 + */
14379 +
14380 +/*
14381 + * inode functions
14382 + */
14383 +
14384 +#include "aufs.h"
14385 +
14386 +struct inode *au_igrab(struct inode *inode)
14387 +{
14388 +       if (inode) {
14389 +               AuDebugOn(!atomic_read(&inode->i_count));
14390 +               ihold(inode);
14391 +       }
14392 +       return inode;
14393 +}
14394 +
14395 +static void au_refresh_hinode_attr(struct inode *inode, int do_version)
14396 +{
14397 +       au_cpup_attr_all(inode, /*force*/0);
14398 +       au_update_iigen(inode, /*half*/1);
14399 +       if (do_version)
14400 +               inode->i_version++;
14401 +}
14402 +
14403 +static int au_ii_refresh(struct inode *inode, int *update)
14404 +{
14405 +       int err, e;
14406 +       umode_t type;
14407 +       aufs_bindex_t bindex, new_bindex;
14408 +       struct super_block *sb;
14409 +       struct au_iinfo *iinfo;
14410 +       struct au_hinode *p, *q, tmp;
14411 +
14412 +       IiMustWriteLock(inode);
14413 +
14414 +       *update = 0;
14415 +       sb = inode->i_sb;
14416 +       type = inode->i_mode & S_IFMT;
14417 +       iinfo = au_ii(inode);
14418 +       err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
14419 +       if (unlikely(err))
14420 +               goto out;
14421 +
14422 +       AuDebugOn(iinfo->ii_bstart < 0);
14423 +       p = iinfo->ii_hinode + iinfo->ii_bstart;
14424 +       for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14425 +            bindex++, p++) {
14426 +               if (!p->hi_inode)
14427 +                       continue;
14428 +
14429 +               AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
14430 +               new_bindex = au_br_index(sb, p->hi_id);
14431 +               if (new_bindex == bindex)
14432 +                       continue;
14433 +
14434 +               if (new_bindex < 0) {
14435 +                       *update = 1;
14436 +                       au_hiput(p);
14437 +                       p->hi_inode = NULL;
14438 +                       continue;
14439 +               }
14440 +
14441 +               if (new_bindex < iinfo->ii_bstart)
14442 +                       iinfo->ii_bstart = new_bindex;
14443 +               if (iinfo->ii_bend < new_bindex)
14444 +                       iinfo->ii_bend = new_bindex;
14445 +               /* swap two lower inode, and loop again */
14446 +               q = iinfo->ii_hinode + new_bindex;
14447 +               tmp = *q;
14448 +               *q = *p;
14449 +               *p = tmp;
14450 +               if (tmp.hi_inode) {
14451 +                       bindex--;
14452 +                       p--;
14453 +               }
14454 +       }
14455 +       au_update_ibrange(inode, /*do_put_zero*/0);
14456 +       e = au_dy_irefresh(inode);
14457 +       if (unlikely(e && !err))
14458 +               err = e;
14459 +
14460 +out:
14461 +       AuTraceErr(err);
14462 +       return err;
14463 +}
14464 +
14465 +int au_refresh_hinode_self(struct inode *inode)
14466 +{
14467 +       int err, update;
14468 +
14469 +       err = au_ii_refresh(inode, &update);
14470 +       if (!err)
14471 +               au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
14472 +
14473 +       AuTraceErr(err);
14474 +       return err;
14475 +}
14476 +
14477 +int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
14478 +{
14479 +       int err, e, update;
14480 +       unsigned int flags;
14481 +       umode_t mode;
14482 +       aufs_bindex_t bindex, bend;
14483 +       unsigned char isdir;
14484 +       struct au_hinode *p;
14485 +       struct au_iinfo *iinfo;
14486 +
14487 +       err = au_ii_refresh(inode, &update);
14488 +       if (unlikely(err))
14489 +               goto out;
14490 +
14491 +       update = 0;
14492 +       iinfo = au_ii(inode);
14493 +       p = iinfo->ii_hinode + iinfo->ii_bstart;
14494 +       mode = (inode->i_mode & S_IFMT);
14495 +       isdir = S_ISDIR(mode);
14496 +       flags = au_hi_flags(inode, isdir);
14497 +       bend = au_dbend(dentry);
14498 +       for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
14499 +               struct inode *h_i;
14500 +               struct dentry *h_d;
14501 +
14502 +               h_d = au_h_dptr(dentry, bindex);
14503 +               if (!h_d || !h_d->d_inode)
14504 +                       continue;
14505 +
14506 +               AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
14507 +               if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
14508 +                       h_i = au_h_iptr(inode, bindex);
14509 +                       if (h_i) {
14510 +                               if (h_i == h_d->d_inode)
14511 +                                       continue;
14512 +                               err = -EIO;
14513 +                               break;
14514 +                       }
14515 +               }
14516 +               if (bindex < iinfo->ii_bstart)
14517 +                       iinfo->ii_bstart = bindex;
14518 +               if (iinfo->ii_bend < bindex)
14519 +                       iinfo->ii_bend = bindex;
14520 +               au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
14521 +               update = 1;
14522 +       }
14523 +       au_update_ibrange(inode, /*do_put_zero*/0);
14524 +       e = au_dy_irefresh(inode);
14525 +       if (unlikely(e && !err))
14526 +               err = e;
14527 +       if (!err)
14528 +               au_refresh_hinode_attr(inode, update && isdir);
14529 +
14530 +out:
14531 +       AuTraceErr(err);
14532 +       return err;
14533 +}
14534 +
14535 +static int set_inode(struct inode *inode, struct dentry *dentry)
14536 +{
14537 +       int err;
14538 +       unsigned int flags;
14539 +       umode_t mode;
14540 +       aufs_bindex_t bindex, bstart, btail;
14541 +       unsigned char isdir;
14542 +       struct dentry *h_dentry;
14543 +       struct inode *h_inode;
14544 +       struct au_iinfo *iinfo;
14545 +
14546 +       IiMustWriteLock(inode);
14547 +
14548 +       err = 0;
14549 +       isdir = 0;
14550 +       bstart = au_dbstart(dentry);
14551 +       h_inode = au_h_dptr(dentry, bstart)->d_inode;
14552 +       mode = h_inode->i_mode;
14553 +       switch (mode & S_IFMT) {
14554 +       case S_IFREG:
14555 +               btail = au_dbtail(dentry);
14556 +               inode->i_op = &aufs_iop;
14557 +               inode->i_fop = &aufs_file_fop;
14558 +               err = au_dy_iaop(inode, bstart, h_inode);
14559 +               if (unlikely(err))
14560 +                       goto out;
14561 +               break;
14562 +       case S_IFDIR:
14563 +               isdir = 1;
14564 +               btail = au_dbtaildir(dentry);
14565 +               inode->i_op = &aufs_dir_iop;
14566 +               inode->i_fop = &aufs_dir_fop;
14567 +               break;
14568 +       case S_IFLNK:
14569 +               btail = au_dbtail(dentry);
14570 +               inode->i_op = &aufs_symlink_iop;
14571 +               break;
14572 +       case S_IFBLK:
14573 +       case S_IFCHR:
14574 +       case S_IFIFO:
14575 +       case S_IFSOCK:
14576 +               btail = au_dbtail(dentry);
14577 +               inode->i_op = &aufs_iop;
14578 +               au_init_special_fop(inode, mode, h_inode->i_rdev);
14579 +               break;
14580 +       default:
14581 +               AuIOErr("Unknown file type 0%o\n", mode);
14582 +               err = -EIO;
14583 +               goto out;
14584 +       }
14585 +
14586 +       /* do not set hnotify for whiteouted dirs (SHWH mode) */
14587 +       flags = au_hi_flags(inode, isdir);
14588 +       if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
14589 +           && au_ftest_hi(flags, HNOTIFY)
14590 +           && dentry->d_name.len > AUFS_WH_PFX_LEN
14591 +           && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
14592 +               au_fclr_hi(flags, HNOTIFY);
14593 +       iinfo = au_ii(inode);
14594 +       iinfo->ii_bstart = bstart;
14595 +       iinfo->ii_bend = btail;
14596 +       for (bindex = bstart; bindex <= btail; bindex++) {
14597 +               h_dentry = au_h_dptr(dentry, bindex);
14598 +               if (h_dentry)
14599 +                       au_set_h_iptr(inode, bindex,
14600 +                                     au_igrab(h_dentry->d_inode), flags);
14601 +       }
14602 +       au_cpup_attr_all(inode, /*force*/1);
14603 +
14604 +out:
14605 +       return err;
14606 +}
14607 +
14608 +/*
14609 + * successful returns with iinfo write_locked
14610 + * minus: errno
14611 + * zero: success, matched
14612 + * plus: no error, but unmatched
14613 + */
14614 +static int reval_inode(struct inode *inode, struct dentry *dentry)
14615 +{
14616 +       int err;
14617 +       unsigned int gen;
14618 +       struct au_iigen iigen;
14619 +       aufs_bindex_t bindex, bend;
14620 +       struct inode *h_inode, *h_dinode;
14621 +
14622 +       /*
14623 +        * before this function, if aufs got any iinfo lock, it must be only
14624 +        * one, the parent dir.
14625 +        * it can happen by UDBA and the obsoleted inode number.
14626 +        */
14627 +       err = -EIO;
14628 +       if (unlikely(inode->i_ino == parent_ino(dentry)))
14629 +               goto out;
14630 +
14631 +       err = 1;
14632 +       ii_write_lock_new_child(inode);
14633 +       h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
14634 +       bend = au_ibend(inode);
14635 +       for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14636 +               h_inode = au_h_iptr(inode, bindex);
14637 +               if (!h_inode || h_inode != h_dinode)
14638 +                       continue;
14639 +
14640 +               err = 0;
14641 +               gen = au_iigen(inode, &iigen);
14642 +               if (gen == au_digen(dentry)
14643 +                   && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
14644 +                       break;
14645 +
14646 +               /* fully refresh inode using dentry */
14647 +               err = au_refresh_hinode(inode, dentry);
14648 +               if (!err)
14649 +                       au_update_iigen(inode, /*half*/0);
14650 +               break;
14651 +       }
14652 +
14653 +       if (unlikely(err))
14654 +               ii_write_unlock(inode);
14655 +out:
14656 +       return err;
14657 +}
14658 +
14659 +int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14660 +          unsigned int d_type, ino_t *ino)
14661 +{
14662 +       int err;
14663 +       struct mutex *mtx;
14664 +
14665 +       /* prevent hardlinked inode number from race condition */
14666 +       mtx = NULL;
14667 +       if (d_type != DT_DIR) {
14668 +               mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
14669 +               mutex_lock(mtx);
14670 +       }
14671 +       err = au_xino_read(sb, bindex, h_ino, ino);
14672 +       if (unlikely(err))
14673 +               goto out;
14674 +
14675 +       if (!*ino) {
14676 +               err = -EIO;
14677 +               *ino = au_xino_new_ino(sb);
14678 +               if (unlikely(!*ino))
14679 +                       goto out;
14680 +               err = au_xino_write(sb, bindex, h_ino, *ino);
14681 +               if (unlikely(err))
14682 +                       goto out;
14683 +       }
14684 +
14685 +out:
14686 +       if (mtx)
14687 +               mutex_unlock(mtx);
14688 +       return err;
14689 +}
14690 +
14691 +/* successful returns with iinfo write_locked */
14692 +/* todo: return with unlocked? */
14693 +struct inode *au_new_inode(struct dentry *dentry, int must_new)
14694 +{
14695 +       struct inode *inode, *h_inode;
14696 +       struct dentry *h_dentry;
14697 +       struct super_block *sb;
14698 +       struct mutex *mtx;
14699 +       ino_t h_ino, ino;
14700 +       int err;
14701 +       aufs_bindex_t bstart;
14702 +
14703 +       sb = dentry->d_sb;
14704 +       bstart = au_dbstart(dentry);
14705 +       h_dentry = au_h_dptr(dentry, bstart);
14706 +       h_inode = h_dentry->d_inode;
14707 +       h_ino = h_inode->i_ino;
14708 +
14709 +       /*
14710 +        * stop 'race'-ing between hardlinks under different
14711 +        * parents.
14712 +        */
14713 +       mtx = NULL;
14714 +       if (!S_ISDIR(h_inode->i_mode))
14715 +               mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
14716 +
14717 +new_ino:
14718 +       if (mtx)
14719 +               mutex_lock(mtx);
14720 +       err = au_xino_read(sb, bstart, h_ino, &ino);
14721 +       inode = ERR_PTR(err);
14722 +       if (unlikely(err))
14723 +               goto out;
14724 +
14725 +       if (!ino) {
14726 +               ino = au_xino_new_ino(sb);
14727 +               if (unlikely(!ino)) {
14728 +                       inode = ERR_PTR(-EIO);
14729 +                       goto out;
14730 +               }
14731 +       }
14732 +
14733 +       AuDbg("i%lu\n", (unsigned long)ino);
14734 +       inode = au_iget_locked(sb, ino);
14735 +       err = PTR_ERR(inode);
14736 +       if (IS_ERR(inode))
14737 +               goto out;
14738 +
14739 +       AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
14740 +       if (inode->i_state & I_NEW) {
14741 +               /* verbose coding for lock class name */
14742 +               if (unlikely(S_ISLNK(h_inode->i_mode)))
14743 +                       au_rw_class(&au_ii(inode)->ii_rwsem,
14744 +                                   au_lc_key + AuLcSymlink_IIINFO);
14745 +               else if (unlikely(S_ISDIR(h_inode->i_mode)))
14746 +                       au_rw_class(&au_ii(inode)->ii_rwsem,
14747 +                                   au_lc_key + AuLcDir_IIINFO);
14748 +               else /* likely */
14749 +                       au_rw_class(&au_ii(inode)->ii_rwsem,
14750 +                                   au_lc_key + AuLcNonDir_IIINFO);
14751 +
14752 +               ii_write_lock_new_child(inode);
14753 +               err = set_inode(inode, dentry);
14754 +               if (!err) {
14755 +                       unlock_new_inode(inode);
14756 +                       goto out; /* success */
14757 +               }
14758 +
14759 +               /*
14760 +                * iget_failed() calls iput(), but we need to call
14761 +                * ii_write_unlock() after iget_failed(). so dirty hack for
14762 +                * i_count.
14763 +                */
14764 +               atomic_inc(&inode->i_count);
14765 +               iget_failed(inode);
14766 +               ii_write_unlock(inode);
14767 +               au_xino_write(sb, bstart, h_ino, /*ino*/0);
14768 +               /* ignore this error */
14769 +               goto out_iput;
14770 +       } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
14771 +               /*
14772 +                * horrible race condition between lookup, readdir and copyup
14773 +                * (or something).
14774 +                */
14775 +               if (mtx)
14776 +                       mutex_unlock(mtx);
14777 +               err = reval_inode(inode, dentry);
14778 +               if (unlikely(err < 0)) {
14779 +                       mtx = NULL;
14780 +                       goto out_iput;
14781 +               }
14782 +
14783 +               if (!err) {
14784 +                       mtx = NULL;
14785 +                       goto out; /* success */
14786 +               } else if (mtx)
14787 +                       mutex_lock(mtx);
14788 +       }
14789 +
14790 +       if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
14791 +               AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
14792 +                       " b%d, %s, %.*s, hi%lu, i%lu.\n",
14793 +                       bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
14794 +                       (unsigned long)h_ino, (unsigned long)ino);
14795 +       ino = 0;
14796 +       err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
14797 +       if (!err) {
14798 +               iput(inode);
14799 +               if (mtx)
14800 +                       mutex_unlock(mtx);
14801 +               goto new_ino;
14802 +       }
14803 +
14804 +out_iput:
14805 +       iput(inode);
14806 +       inode = ERR_PTR(err);
14807 +out:
14808 +       if (mtx)
14809 +               mutex_unlock(mtx);
14810 +       return inode;
14811 +}
14812 +
14813 +/* ---------------------------------------------------------------------- */
14814 +
14815 +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14816 +              struct inode *inode)
14817 +{
14818 +       int err;
14819 +
14820 +       err = au_br_rdonly(au_sbr(sb, bindex));
14821 +
14822 +       /* pseudo-link after flushed may happen out of bounds */
14823 +       if (!err
14824 +           && inode
14825 +           && au_ibstart(inode) <= bindex
14826 +           && bindex <= au_ibend(inode)) {
14827 +               /*
14828 +                * permission check is unnecessary since vfsub routine
14829 +                * will be called later
14830 +                */
14831 +               struct inode *hi = au_h_iptr(inode, bindex);
14832 +               if (hi)
14833 +                       err = IS_IMMUTABLE(hi) ? -EROFS : 0;
14834 +       }
14835 +
14836 +       return err;
14837 +}
14838 +
14839 +int au_test_h_perm(struct inode *h_inode, int mask)
14840 +{
14841 +       if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
14842 +               return 0;
14843 +       return inode_permission(h_inode, mask);
14844 +}
14845 +
14846 +int au_test_h_perm_sio(struct inode *h_inode, int mask)
14847 +{
14848 +       if (au_test_nfs(h_inode->i_sb)
14849 +           && (mask & MAY_WRITE)
14850 +           && S_ISDIR(h_inode->i_mode))
14851 +               mask |= MAY_READ; /* force permission check */
14852 +       return au_test_h_perm(h_inode, mask);
14853 +}
14854 diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
14855 --- /usr/share/empty/fs/aufs/inode.h    1970-01-01 01:00:00.000000000 +0100
14856 +++ linux/fs/aufs/inode.h       2013-07-06 13:20:47.750198454 +0200
14857 @@ -0,0 +1,600 @@
14858 +/*
14859 + * Copyright (C) 2005-2013 Junjiro R. Okajima
14860 + *
14861 + * This program, aufs is free software; you can redistribute it and/or modify
14862 + * it under the terms of the GNU General Public License as published by
14863 + * the Free Software Foundation; either version 2 of the License, or
14864 + * (at your option) any later version.
14865 + *
14866 + * This program is distributed in the hope that it will be useful,
14867 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14868 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14869 + * GNU General Public License for more details.
14870 + *
14871 + * You should have received a copy of the GNU General Public License
14872 + * along with this program; if not, write to the Free Software
14873 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
14874 + */
14875 +
14876 +/*
14877 + * inode operations
14878 + */
14879 +
14880 +#ifndef __AUFS_INODE_H__
14881 +#define __AUFS_INODE_H__
14882 +
14883 +#ifdef __KERNEL__
14884 +
14885 +#include <linux/fsnotify.h>
14886 +#include "rwsem.h"
14887 +
14888 +struct vfsmount;
14889 +
14890 +struct au_hnotify {
14891 +#ifdef CONFIG_AUFS_HNOTIFY
14892 +#ifdef CONFIG_AUFS_HFSNOTIFY
14893 +       /* never use fsnotify_add_vfsmount_mark() */
14894 +       struct fsnotify_mark            hn_mark;
14895 +#endif
14896 +       struct inode                    *hn_aufs_inode; /* no get/put */
14897 +#endif
14898 +} ____cacheline_aligned_in_smp;
14899 +
14900 +struct au_hinode {
14901 +       struct inode            *hi_inode;
14902 +       aufs_bindex_t           hi_id;
14903 +#ifdef CONFIG_AUFS_HNOTIFY
14904 +       struct au_hnotify       *hi_notify;
14905 +#endif
14906 +
14907 +       /* reference to the copied-up whiteout with get/put */
14908 +       struct dentry           *hi_whdentry;
14909 +};
14910 +
14911 +/* ig_flags */
14912 +#define AuIG_HALF_REFRESHED            1
14913 +#define au_ig_ftest(flags, name)       ((flags) & AuIG_##name)
14914 +#define au_ig_fset(flags, name) \
14915 +       do { (flags) |= AuIG_##name; } while (0)
14916 +#define au_ig_fclr(flags, name) \
14917 +       do { (flags) &= ~AuIG_##name; } while (0)
14918 +
14919 +struct au_iigen {
14920 +       __u32           ig_generation, ig_flags;
14921 +};
14922 +
14923 +struct au_vdir;
14924 +struct au_iinfo {
14925 +       spinlock_t              ii_genspin;
14926 +       struct au_iigen         ii_generation;
14927 +       struct super_block      *ii_hsb1;       /* no get/put */
14928 +
14929 +       struct au_rwsem         ii_rwsem;
14930 +       aufs_bindex_t           ii_bstart, ii_bend;
14931 +       __u32                   ii_higen;
14932 +       struct au_hinode        *ii_hinode;
14933 +       struct au_vdir          *ii_vdir;
14934 +};
14935 +
14936 +struct au_icntnr {
14937 +       struct au_iinfo iinfo;
14938 +       struct inode vfs_inode;
14939 +} ____cacheline_aligned_in_smp;
14940 +
14941 +/* au_pin flags */
14942 +#define AuPin_DI_LOCKED                1
14943 +#define AuPin_MNT_WRITE                (1 << 1)
14944 +#define au_ftest_pin(flags, name)      ((flags) & AuPin_##name)
14945 +#define au_fset_pin(flags, name) \
14946 +       do { (flags) |= AuPin_##name; } while (0)
14947 +#define au_fclr_pin(flags, name) \
14948 +       do { (flags) &= ~AuPin_##name; } while (0)
14949 +
14950 +struct au_pin {
14951 +       /* input */
14952 +       struct dentry *dentry;
14953 +       unsigned int udba;
14954 +       unsigned char lsc_di, lsc_hi, flags;
14955 +       aufs_bindex_t bindex;
14956 +
14957 +       /* output */
14958 +       struct dentry *parent;
14959 +       struct au_hinode *hdir;
14960 +       struct vfsmount *h_mnt;
14961 +
14962 +       /* temporary unlock/relock for copyup */
14963 +       struct dentry *h_dentry, *h_parent;
14964 +       struct au_branch *br;
14965 +       struct task_struct *task;
14966 +};
14967 +
14968 +void au_pin_hdir_unlock(struct au_pin *p);
14969 +int au_pin_hdir_relock(struct au_pin *p);
14970 +void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
14971 +void au_pin_hdir_acquire_nest(struct au_pin *p);
14972 +void au_pin_hdir_release(struct au_pin *p);
14973 +
14974 +/* ---------------------------------------------------------------------- */
14975 +
14976 +static inline struct au_iinfo *au_ii(struct inode *inode)
14977 +{
14978 +       struct au_iinfo *iinfo;
14979 +
14980 +       iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
14981 +       if (iinfo->ii_hinode)
14982 +               return iinfo;
14983 +       return NULL; /* debugging bad_inode case */
14984 +}
14985 +
14986 +/* ---------------------------------------------------------------------- */
14987 +
14988 +/* inode.c */
14989 +struct inode *au_igrab(struct inode *inode);
14990 +int au_refresh_hinode_self(struct inode *inode);
14991 +int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
14992 +int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14993 +          unsigned int d_type, ino_t *ino);
14994 +struct inode *au_new_inode(struct dentry *dentry, int must_new);
14995 +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14996 +              struct inode *inode);
14997 +int au_test_h_perm(struct inode *h_inode, int mask);
14998 +int au_test_h_perm_sio(struct inode *h_inode, int mask);
14999 +
15000 +static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
15001 +                           ino_t h_ino, unsigned int d_type, ino_t *ino)
15002 +{
15003 +#ifdef CONFIG_AUFS_SHWH
15004 +       return au_ino(sb, bindex, h_ino, d_type, ino);
15005 +#else
15006 +       return 0;
15007 +#endif
15008 +}
15009 +
15010 +/* i_op.c */
15011 +extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
15012 +
15013 +/* au_wr_dir flags */
15014 +#define AuWrDir_ADD_ENTRY      1
15015 +#define AuWrDir_TMP_WHENTRY    (1 << 1)
15016 +#define AuWrDir_ISDIR          (1 << 2)
15017 +#define au_ftest_wrdir(flags, name)    ((flags) & AuWrDir_##name)
15018 +#define au_fset_wrdir(flags, name) \
15019 +       do { (flags) |= AuWrDir_##name; } while (0)
15020 +#define au_fclr_wrdir(flags, name) \
15021 +       do { (flags) &= ~AuWrDir_##name; } while (0)
15022 +
15023 +struct au_wr_dir_args {
15024 +       aufs_bindex_t force_btgt;
15025 +       unsigned char flags;
15026 +};
15027 +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
15028 +             struct au_wr_dir_args *args);
15029 +
15030 +struct dentry *au_pinned_h_parent(struct au_pin *pin);
15031 +void au_pin_init(struct au_pin *pin, struct dentry *dentry,
15032 +                aufs_bindex_t bindex, int lsc_di, int lsc_hi,
15033 +                unsigned int udba, unsigned char flags);
15034 +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
15035 +          unsigned int udba, unsigned char flags) __must_check;
15036 +int au_do_pin(struct au_pin *pin) __must_check;
15037 +void au_unpin(struct au_pin *pin);
15038 +
15039 +/* i_op_add.c */
15040 +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15041 +              struct dentry *h_parent, int isdir);
15042 +int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15043 +              dev_t dev);
15044 +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
15045 +int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
15046 +               bool want_excl);
15047 +int aufs_link(struct dentry *src_dentry, struct inode *dir,
15048 +             struct dentry *dentry);
15049 +int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
15050 +
15051 +/* i_op_del.c */
15052 +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
15053 +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
15054 +              struct dentry *h_parent, int isdir);
15055 +int aufs_unlink(struct inode *dir, struct dentry *dentry);
15056 +int aufs_rmdir(struct inode *dir, struct dentry *dentry);
15057 +
15058 +/* i_op_ren.c */
15059 +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
15060 +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
15061 +               struct inode *dir, struct dentry *dentry);
15062 +
15063 +/* iinfo.c */
15064 +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
15065 +void au_hiput(struct au_hinode *hinode);
15066 +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15067 +                 struct dentry *h_wh);
15068 +unsigned int au_hi_flags(struct inode *inode, int isdir);
15069 +
15070 +/* hinode flags */
15071 +#define AuHi_XINO      1
15072 +#define AuHi_HNOTIFY   (1 << 1)
15073 +#define au_ftest_hi(flags, name)       ((flags) & AuHi_##name)
15074 +#define au_fset_hi(flags, name) \
15075 +       do { (flags) |= AuHi_##name; } while (0)
15076 +#define au_fclr_hi(flags, name) \
15077 +       do { (flags) &= ~AuHi_##name; } while (0)
15078 +
15079 +#ifndef CONFIG_AUFS_HNOTIFY
15080 +#undef AuHi_HNOTIFY
15081 +#define AuHi_HNOTIFY   0
15082 +#endif
15083 +
15084 +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15085 +                  struct inode *h_inode, unsigned int flags);
15086 +
15087 +void au_update_iigen(struct inode *inode, int half);
15088 +void au_update_ibrange(struct inode *inode, int do_put_zero);
15089 +
15090 +void au_icntnr_init_once(void *_c);
15091 +int au_iinfo_init(struct inode *inode);
15092 +void au_iinfo_fin(struct inode *inode);
15093 +int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
15094 +
15095 +#ifdef CONFIG_PROC_FS
15096 +/* plink.c */
15097 +int au_plink_maint(struct super_block *sb, int flags);
15098 +void au_plink_maint_leave(struct au_sbinfo *sbinfo);
15099 +int au_plink_maint_enter(struct super_block *sb);
15100 +#ifdef CONFIG_AUFS_DEBUG
15101 +void au_plink_list(struct super_block *sb);
15102 +#else
15103 +AuStubVoid(au_plink_list, struct super_block *sb)
15104 +#endif
15105 +int au_plink_test(struct inode *inode);
15106 +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
15107 +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
15108 +                    struct dentry *h_dentry);
15109 +void au_plink_put(struct super_block *sb, int verbose);
15110 +void au_plink_clean(struct super_block *sb, int verbose);
15111 +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
15112 +#else
15113 +AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
15114 +AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
15115 +AuStubInt0(au_plink_maint_enter, struct super_block *sb);
15116 +AuStubVoid(au_plink_list, struct super_block *sb);
15117 +AuStubInt0(au_plink_test, struct inode *inode);
15118 +AuStub(struct dentry *, au_plink_lkup, return NULL,
15119 +       struct inode *inode, aufs_bindex_t bindex);
15120 +AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
15121 +          struct dentry *h_dentry);
15122 +AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
15123 +AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
15124 +AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
15125 +#endif /* CONFIG_PROC_FS */
15126 +
15127 +/* ---------------------------------------------------------------------- */
15128 +
15129 +/* lock subclass for iinfo */
15130 +enum {
15131 +       AuLsc_II_CHILD,         /* child first */
15132 +       AuLsc_II_CHILD2,        /* rename(2), link(2), and cpup at hnotify */
15133 +       AuLsc_II_CHILD3,        /* copyup dirs */
15134 +       AuLsc_II_PARENT,        /* see AuLsc_I_PARENT in vfsub.h */
15135 +       AuLsc_II_PARENT2,
15136 +       AuLsc_II_PARENT3,       /* copyup dirs */
15137 +       AuLsc_II_NEW_CHILD
15138 +};
15139 +
15140 +/*
15141 + * ii_read_lock_child, ii_write_lock_child,
15142 + * ii_read_lock_child2, ii_write_lock_child2,
15143 + * ii_read_lock_child3, ii_write_lock_child3,
15144 + * ii_read_lock_parent, ii_write_lock_parent,
15145 + * ii_read_lock_parent2, ii_write_lock_parent2,
15146 + * ii_read_lock_parent3, ii_write_lock_parent3,
15147 + * ii_read_lock_new_child, ii_write_lock_new_child,
15148 + */
15149 +#define AuReadLockFunc(name, lsc) \
15150 +static inline void ii_read_lock_##name(struct inode *i) \
15151 +{ \
15152 +       au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15153 +}
15154 +
15155 +#define AuWriteLockFunc(name, lsc) \
15156 +static inline void ii_write_lock_##name(struct inode *i) \
15157 +{ \
15158 +       au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15159 +}
15160 +
15161 +#define AuRWLockFuncs(name, lsc) \
15162 +       AuReadLockFunc(name, lsc) \
15163 +       AuWriteLockFunc(name, lsc)
15164 +
15165 +AuRWLockFuncs(child, CHILD);
15166 +AuRWLockFuncs(child2, CHILD2);
15167 +AuRWLockFuncs(child3, CHILD3);
15168 +AuRWLockFuncs(parent, PARENT);
15169 +AuRWLockFuncs(parent2, PARENT2);
15170 +AuRWLockFuncs(parent3, PARENT3);
15171 +AuRWLockFuncs(new_child, NEW_CHILD);
15172 +
15173 +#undef AuReadLockFunc
15174 +#undef AuWriteLockFunc
15175 +#undef AuRWLockFuncs
15176 +
15177 +/*
15178 + * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
15179 + */
15180 +AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
15181 +
15182 +#define IiMustNoWaiters(i)     AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
15183 +#define IiMustAnyLock(i)       AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
15184 +#define IiMustWriteLock(i)     AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
15185 +
15186 +/* ---------------------------------------------------------------------- */
15187 +
15188 +static inline void au_icntnr_init(struct au_icntnr *c)
15189 +{
15190 +#ifdef CONFIG_AUFS_DEBUG
15191 +       c->vfs_inode.i_mode = 0;
15192 +#endif
15193 +}
15194 +
15195 +static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
15196 +{
15197 +       unsigned int gen;
15198 +       struct au_iinfo *iinfo;
15199 +
15200 +       iinfo = au_ii(inode);
15201 +       spin_lock(&iinfo->ii_genspin);
15202 +       if (iigen)
15203 +               *iigen = iinfo->ii_generation;
15204 +       gen = iinfo->ii_generation.ig_generation;
15205 +       spin_unlock(&iinfo->ii_genspin);
15206 +
15207 +       return gen;
15208 +}
15209 +
15210 +/* tiny test for inode number */
15211 +/* tmpfs generation is too rough */
15212 +static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
15213 +{
15214 +       struct au_iinfo *iinfo;
15215 +
15216 +       iinfo = au_ii(inode);
15217 +       AuRwMustAnyLock(&iinfo->ii_rwsem);
15218 +       return !(iinfo->ii_hsb1 == h_inode->i_sb
15219 +                && iinfo->ii_higen == h_inode->i_generation);
15220 +}
15221 +
15222 +static inline void au_iigen_dec(struct inode *inode)
15223 +{
15224 +       struct au_iinfo *iinfo;
15225 +
15226 +       iinfo = au_ii(inode);
15227 +       spin_lock(&iinfo->ii_genspin);
15228 +       iinfo->ii_generation.ig_generation--;
15229 +       spin_unlock(&iinfo->ii_genspin);
15230 +}
15231 +
15232 +static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
15233 +{
15234 +       int err;
15235 +
15236 +       err = 0;
15237 +       if (unlikely(inode && au_iigen(inode, NULL) != sigen))
15238 +               err = -EIO;
15239 +
15240 +       return err;
15241 +}
15242 +
15243 +/* ---------------------------------------------------------------------- */
15244 +
15245 +static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
15246 +                                       aufs_bindex_t bindex)
15247 +{
15248 +       IiMustAnyLock(inode);
15249 +       return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
15250 +}
15251 +
15252 +static inline aufs_bindex_t au_ibstart(struct inode *inode)
15253 +{
15254 +       IiMustAnyLock(inode);
15255 +       return au_ii(inode)->ii_bstart;
15256 +}
15257 +
15258 +static inline aufs_bindex_t au_ibend(struct inode *inode)
15259 +{
15260 +       IiMustAnyLock(inode);
15261 +       return au_ii(inode)->ii_bend;
15262 +}
15263 +
15264 +static inline struct au_vdir *au_ivdir(struct inode *inode)
15265 +{
15266 +       IiMustAnyLock(inode);
15267 +       return au_ii(inode)->ii_vdir;
15268 +}
15269 +
15270 +static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
15271 +{
15272 +       IiMustAnyLock(inode);
15273 +       return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
15274 +}
15275 +
15276 +static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
15277 +{
15278 +       IiMustWriteLock(inode);
15279 +       au_ii(inode)->ii_bstart = bindex;
15280 +}
15281 +
15282 +static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
15283 +{
15284 +       IiMustWriteLock(inode);
15285 +       au_ii(inode)->ii_bend = bindex;
15286 +}
15287 +
15288 +static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
15289 +{
15290 +       IiMustWriteLock(inode);
15291 +       au_ii(inode)->ii_vdir = vdir;
15292 +}
15293 +
15294 +static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
15295 +{
15296 +       IiMustAnyLock(inode);
15297 +       return au_ii(inode)->ii_hinode + bindex;
15298 +}
15299 +
15300 +/* ---------------------------------------------------------------------- */
15301 +
15302 +static inline struct dentry *au_pinned_parent(struct au_pin *pin)
15303 +{
15304 +       if (pin)
15305 +               return pin->parent;
15306 +       return NULL;
15307 +}
15308 +
15309 +static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
15310 +{
15311 +       if (pin && pin->hdir)
15312 +               return pin->hdir->hi_inode;
15313 +       return NULL;
15314 +}
15315 +
15316 +static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
15317 +{
15318 +       if (pin)
15319 +               return pin->hdir;
15320 +       return NULL;
15321 +}
15322 +
15323 +static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
15324 +{
15325 +       if (pin)
15326 +               pin->dentry = dentry;
15327 +}
15328 +
15329 +static inline void au_pin_set_parent_lflag(struct au_pin *pin,
15330 +                                          unsigned char lflag)
15331 +{
15332 +       if (pin) {
15333 +               if (lflag)
15334 +                       au_fset_pin(pin->flags, DI_LOCKED);
15335 +               else
15336 +                       au_fclr_pin(pin->flags, DI_LOCKED);
15337 +       }
15338 +}
15339 +
15340 +static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
15341 +{
15342 +       if (pin) {
15343 +               dput(pin->parent);
15344 +               pin->parent = dget(parent);
15345 +       }
15346 +}
15347 +
15348 +/* ---------------------------------------------------------------------- */
15349 +
15350 +struct au_branch;
15351 +#ifdef CONFIG_AUFS_HNOTIFY
15352 +struct au_hnotify_op {
15353 +       void (*ctl)(struct au_hinode *hinode, int do_set);
15354 +       int (*alloc)(struct au_hinode *hinode);
15355 +
15356 +       /*
15357 +        * if it returns true, the the caller should free hinode->hi_notify,
15358 +        * otherwise ->free() frees it.
15359 +        */
15360 +       int (*free)(struct au_hinode *hinode,
15361 +                   struct au_hnotify *hn) __must_check;
15362 +
15363 +       void (*fin)(void);
15364 +       int (*init)(void);
15365 +
15366 +       int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
15367 +       void (*fin_br)(struct au_branch *br);
15368 +       int (*init_br)(struct au_branch *br, int perm);
15369 +};
15370 +
15371 +/* hnotify.c */
15372 +int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
15373 +void au_hn_free(struct au_hinode *hinode);
15374 +void au_hn_ctl(struct au_hinode *hinode, int do_set);
15375 +void au_hn_reset(struct inode *inode, unsigned int flags);
15376 +int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15377 +              struct qstr *h_child_qstr, struct inode *h_child_inode);
15378 +int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
15379 +int au_hnotify_init_br(struct au_branch *br, int perm);
15380 +void au_hnotify_fin_br(struct au_branch *br);
15381 +int __init au_hnotify_init(void);
15382 +void au_hnotify_fin(void);
15383 +
15384 +/* hfsnotify.c */
15385 +extern const struct au_hnotify_op au_hnotify_op;
15386 +
15387 +static inline
15388 +void au_hn_init(struct au_hinode *hinode)
15389 +{
15390 +       hinode->hi_notify = NULL;
15391 +}
15392 +
15393 +static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15394 +{
15395 +       return hinode->hi_notify;
15396 +}
15397 +
15398 +#else
15399 +static inline
15400 +int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
15401 +               struct inode *inode __maybe_unused)
15402 +{
15403 +       return -EOPNOTSUPP;
15404 +}
15405 +
15406 +static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15407 +{
15408 +       return NULL;
15409 +}
15410 +
15411 +AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
15412 +AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
15413 +          int do_set __maybe_unused)
15414 +AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
15415 +          unsigned int flags __maybe_unused)
15416 +AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
15417 +          struct au_branch *br __maybe_unused,
15418 +          int perm __maybe_unused)
15419 +AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
15420 +          int perm __maybe_unused)
15421 +AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
15422 +AuStubInt0(__init au_hnotify_init, void)
15423 +AuStubVoid(au_hnotify_fin, void)
15424 +AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
15425 +#endif /* CONFIG_AUFS_HNOTIFY */
15426 +
15427 +static inline void au_hn_suspend(struct au_hinode *hdir)
15428 +{
15429 +       au_hn_ctl(hdir, /*do_set*/0);
15430 +}
15431 +
15432 +static inline void au_hn_resume(struct au_hinode *hdir)
15433 +{
15434 +       au_hn_ctl(hdir, /*do_set*/1);
15435 +}
15436 +
15437 +static inline void au_hn_imtx_lock(struct au_hinode *hdir)
15438 +{
15439 +       mutex_lock(&hdir->hi_inode->i_mutex);
15440 +       au_hn_suspend(hdir);
15441 +}
15442 +
15443 +static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
15444 +                                         unsigned int sc __maybe_unused)
15445 +{
15446 +       mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
15447 +       au_hn_suspend(hdir);
15448 +}
15449 +
15450 +static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
15451 +{
15452 +       au_hn_resume(hdir);
15453 +       mutex_unlock(&hdir->hi_inode->i_mutex);
15454 +}
15455 +
15456 +#endif /* __KERNEL__ */
15457 +#endif /* __AUFS_INODE_H__ */
15458 diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
15459 --- /usr/share/empty/fs/aufs/ioctl.c    1970-01-01 01:00:00.000000000 +0100
15460 +++ linux/fs/aufs/ioctl.c       2013-07-06 13:20:47.750198454 +0200
15461 @@ -0,0 +1,196 @@
15462 +/*
15463 + * Copyright (C) 2005-2013 Junjiro R. Okajima
15464 + *
15465 + * This program, aufs is free software; you can redistribute it and/or modify
15466 + * it under the terms of the GNU General Public License as published by
15467 + * the Free Software Foundation; either version 2 of the License, or
15468 + * (at your option) any later version.
15469 + *
15470 + * This program is distributed in the hope that it will be useful,
15471 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15472 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15473 + * GNU General Public License for more details.
15474 + *
15475 + * You should have received a copy of the GNU General Public License
15476 + * along with this program; if not, write to the Free Software
15477 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15478 + */
15479 +
15480 +/*
15481 + * ioctl
15482 + * plink-management and readdir in userspace.
15483 + * assist the pathconf(3) wrapper library.
15484 + */
15485 +
15486 +#include "aufs.h"
15487 +
15488 +static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
15489 +{
15490 +       int err, fd;
15491 +       aufs_bindex_t wbi, bindex, bend;
15492 +       struct file *h_file;
15493 +       struct super_block *sb;
15494 +       struct dentry *root;
15495 +       struct au_branch *br;
15496 +       struct aufs_wbr_fd wbrfd = {
15497 +               .oflags = au_dir_roflags,
15498 +               .brid   = -1
15499 +       };
15500 +       const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
15501 +               | O_NOATIME | O_CLOEXEC;
15502 +
15503 +       AuDebugOn(wbrfd.oflags & ~valid);
15504 +
15505 +       if (arg) {
15506 +               err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
15507 +               if (unlikely(err)) {
15508 +                       err = -EFAULT;
15509 +                       goto out;
15510 +               }
15511 +
15512 +               err = -EINVAL;
15513 +               AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
15514 +               wbrfd.oflags |= au_dir_roflags;
15515 +               AuDbg("0%o\n", wbrfd.oflags);
15516 +               if (unlikely(wbrfd.oflags & ~valid))
15517 +                       goto out;
15518 +       }
15519 +
15520 +       fd = get_unused_fd();
15521 +       err = fd;
15522 +       if (unlikely(fd < 0))
15523 +               goto out;
15524 +
15525 +       h_file = ERR_PTR(-EINVAL);
15526 +       wbi = 0;
15527 +       br = NULL;
15528 +       sb = path->dentry->d_sb;
15529 +       root = sb->s_root;
15530 +       aufs_read_lock(root, AuLock_IR);
15531 +       bend = au_sbend(sb);
15532 +       if (wbrfd.brid >= 0) {
15533 +               wbi = au_br_index(sb, wbrfd.brid);
15534 +               if (unlikely(wbi < 0 || wbi > bend))
15535 +                       goto out_unlock;
15536 +       }
15537 +
15538 +       h_file = ERR_PTR(-ENOENT);
15539 +       br = au_sbr(sb, wbi);
15540 +       if (!au_br_writable(br->br_perm)) {
15541 +               if (arg)
15542 +                       goto out_unlock;
15543 +
15544 +               bindex = wbi + 1;
15545 +               wbi = -1;
15546 +               for (; bindex <= bend; bindex++) {
15547 +                       br = au_sbr(sb, bindex);
15548 +                       if (au_br_writable(br->br_perm)) {
15549 +                               wbi = bindex;
15550 +                               br = au_sbr(sb, wbi);
15551 +                               break;
15552 +                       }
15553 +               }
15554 +       }
15555 +       AuDbg("wbi %d\n", wbi);
15556 +       if (wbi >= 0)
15557 +               h_file = au_h_open(root, wbi, wbrfd.oflags, NULL);
15558 +
15559 +out_unlock:
15560 +       aufs_read_unlock(root, AuLock_IR);
15561 +       err = PTR_ERR(h_file);
15562 +       if (IS_ERR(h_file))
15563 +               goto out_fd;
15564 +
15565 +       atomic_dec(&br->br_count); /* cf. au_h_open() */
15566 +       fd_install(fd, h_file);
15567 +       err = fd;
15568 +       goto out; /* success */
15569 +
15570 +out_fd:
15571 +       put_unused_fd(fd);
15572 +out:
15573 +       AuTraceErr(err);
15574 +       return err;
15575 +}
15576 +
15577 +/* ---------------------------------------------------------------------- */
15578 +
15579 +long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
15580 +{
15581 +       long err;
15582 +
15583 +       switch (cmd) {
15584 +       case AUFS_CTL_RDU:
15585 +       case AUFS_CTL_RDU_INO:
15586 +               err = au_rdu_ioctl(file, cmd, arg);
15587 +               break;
15588 +
15589 +       case AUFS_CTL_WBR_FD:
15590 +               err = au_wbr_fd(&file->f_path, (void __user *)arg);
15591 +               break;
15592 +
15593 +       case AUFS_CTL_IBUSY:
15594 +               err = au_ibusy_ioctl(file, arg);
15595 +               break;
15596 +
15597 +       default:
15598 +               /* do not call the lower */
15599 +               AuDbg("0x%x\n", cmd);
15600 +               err = -ENOTTY;
15601 +       }
15602 +
15603 +       AuTraceErr(err);
15604 +       return err;
15605 +}
15606 +
15607 +long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
15608 +{
15609 +       long err;
15610 +
15611 +       switch (cmd) {
15612 +       case AUFS_CTL_WBR_FD:
15613 +               err = au_wbr_fd(&file->f_path, (void __user *)arg);
15614 +               break;
15615 +
15616 +       default:
15617 +               /* do not call the lower */
15618 +               AuDbg("0x%x\n", cmd);
15619 +               err = -ENOTTY;
15620 +       }
15621 +
15622 +       AuTraceErr(err);
15623 +       return err;
15624 +}
15625 +
15626 +#ifdef CONFIG_COMPAT
15627 +long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15628 +                          unsigned long arg)
15629 +{
15630 +       long err;
15631 +
15632 +       switch (cmd) {
15633 +       case AUFS_CTL_RDU:
15634 +       case AUFS_CTL_RDU_INO:
15635 +               err = au_rdu_compat_ioctl(file, cmd, arg);
15636 +               break;
15637 +
15638 +       case AUFS_CTL_IBUSY:
15639 +               err = au_ibusy_compat_ioctl(file, arg);
15640 +               break;
15641 +
15642 +       default:
15643 +               err = aufs_ioctl_dir(file, cmd, arg);
15644 +       }
15645 +
15646 +       AuTraceErr(err);
15647 +       return err;
15648 +}
15649 +
15650 +#if 0 /* unused yet */
15651 +long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15652 +                             unsigned long arg)
15653 +{
15654 +       return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
15655 +}
15656 +#endif
15657 +#endif
15658 diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
15659 --- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
15660 +++ linux/fs/aufs/i_op_add.c    2013-07-30 22:42:46.235946055 +0200
15661 @@ -0,0 +1,716 @@
15662 +/*
15663 + * Copyright (C) 2005-2013 Junjiro R. Okajima
15664 + *
15665 + * This program, aufs is free software; you can redistribute it and/or modify
15666 + * it under the terms of the GNU General Public License as published by
15667 + * the Free Software Foundation; either version 2 of the License, or
15668 + * (at your option) any later version.
15669 + *
15670 + * This program is distributed in the hope that it will be useful,
15671 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15672 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15673 + * GNU General Public License for more details.
15674 + *
15675 + * You should have received a copy of the GNU General Public License
15676 + * along with this program; if not, write to the Free Software
15677 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15678 + */
15679 +
15680 +/*
15681 + * inode operations (add entry)
15682 + */
15683 +
15684 +#include "aufs.h"
15685 +
15686 +/*
15687 + * final procedure of adding a new entry, except link(2).
15688 + * remove whiteout, instantiate, copyup the parent dir's times and size
15689 + * and update version.
15690 + * if it failed, re-create the removed whiteout.
15691 + */
15692 +static int epilog(struct inode *dir, aufs_bindex_t bindex,
15693 +                 struct dentry *wh_dentry, struct dentry *dentry)
15694 +{
15695 +       int err, rerr;
15696 +       aufs_bindex_t bwh;
15697 +       struct path h_path;
15698 +       struct inode *inode, *h_dir;
15699 +       struct dentry *wh;
15700 +
15701 +       bwh = -1;
15702 +       if (wh_dentry) {
15703 +               h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
15704 +               IMustLock(h_dir);
15705 +               AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
15706 +               bwh = au_dbwh(dentry);
15707 +               h_path.dentry = wh_dentry;
15708 +               h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
15709 +               err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
15710 +                                         dentry);
15711 +               if (unlikely(err))
15712 +                       goto out;
15713 +       }
15714 +
15715 +       inode = au_new_inode(dentry, /*must_new*/1);
15716 +       if (!IS_ERR(inode)) {
15717 +               d_instantiate(dentry, inode);
15718 +               dir = dentry->d_parent->d_inode; /* dir inode is locked */
15719 +               IMustLock(dir);
15720 +               if (au_ibstart(dir) == au_dbstart(dentry))
15721 +                       au_cpup_attr_timesizes(dir);
15722 +               dir->i_version++;
15723 +               return 0; /* success */
15724 +       }
15725 +
15726 +       err = PTR_ERR(inode);
15727 +       if (!wh_dentry)
15728 +               goto out;
15729 +
15730 +       /* revert */
15731 +       /* dir inode is locked */
15732 +       wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
15733 +       rerr = PTR_ERR(wh);
15734 +       if (IS_ERR(wh)) {
15735 +               AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
15736 +                       AuDLNPair(dentry), err, rerr);
15737 +               err = -EIO;
15738 +       } else
15739 +               dput(wh);
15740 +
15741 +out:
15742 +       return err;
15743 +}
15744 +
15745 +static int au_d_may_add(struct dentry *dentry)
15746 +{
15747 +       int err;
15748 +
15749 +       err = 0;
15750 +       if (unlikely(d_unhashed(dentry)))
15751 +               err = -ENOENT;
15752 +       if (unlikely(dentry->d_inode))
15753 +               err = -EEXIST;
15754 +       return err;
15755 +}
15756 +
15757 +/*
15758 + * simple tests for the adding inode operations.
15759 + * following the checks in vfs, plus the parent-child relationship.
15760 + */
15761 +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15762 +              struct dentry *h_parent, int isdir)
15763 +{
15764 +       int err;
15765 +       umode_t h_mode;
15766 +       struct dentry *h_dentry;
15767 +       struct inode *h_inode;
15768 +
15769 +       err = -ENAMETOOLONG;
15770 +       if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15771 +               goto out;
15772 +
15773 +       h_dentry = au_h_dptr(dentry, bindex);
15774 +       h_inode = h_dentry->d_inode;
15775 +       if (!dentry->d_inode) {
15776 +               err = -EEXIST;
15777 +               if (unlikely(h_inode))
15778 +                       goto out;
15779 +       } else {
15780 +               /* rename(2) case */
15781 +               err = -EIO;
15782 +               if (unlikely(!h_inode || !h_inode->i_nlink))
15783 +                       goto out;
15784 +
15785 +               h_mode = h_inode->i_mode;
15786 +               if (!isdir) {
15787 +                       err = -EISDIR;
15788 +                       if (unlikely(S_ISDIR(h_mode)))
15789 +                               goto out;
15790 +               } else if (unlikely(!S_ISDIR(h_mode))) {
15791 +                       err = -ENOTDIR;
15792 +                       goto out;
15793 +               }
15794 +       }
15795 +
15796 +       err = 0;
15797 +       /* expected parent dir is locked */
15798 +       if (unlikely(h_parent != h_dentry->d_parent))
15799 +               err = -EIO;
15800 +
15801 +out:
15802 +       AuTraceErr(err);
15803 +       return err;
15804 +}
15805 +
15806 +/*
15807 + * initial procedure of adding a new entry.
15808 + * prepare writable branch and the parent dir, lock it,
15809 + * and lookup whiteout for the new entry.
15810 + */
15811 +static struct dentry*
15812 +lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
15813 +                 struct dentry *src_dentry, struct au_pin *pin,
15814 +                 struct au_wr_dir_args *wr_dir_args)
15815 +{
15816 +       struct dentry *wh_dentry, *h_parent;
15817 +       struct super_block *sb;
15818 +       struct au_branch *br;
15819 +       int err;
15820 +       unsigned int udba;
15821 +       aufs_bindex_t bcpup;
15822 +
15823 +       AuDbg("%.*s\n", AuDLNPair(dentry));
15824 +
15825 +       err = au_wr_dir(dentry, src_dentry, wr_dir_args);
15826 +       bcpup = err;
15827 +       wh_dentry = ERR_PTR(err);
15828 +       if (unlikely(err < 0))
15829 +               goto out;
15830 +
15831 +       sb = dentry->d_sb;
15832 +       udba = au_opt_udba(sb);
15833 +       err = au_pin(pin, dentry, bcpup, udba,
15834 +                    AuPin_DI_LOCKED | AuPin_MNT_WRITE);
15835 +       wh_dentry = ERR_PTR(err);
15836 +       if (unlikely(err))
15837 +               goto out;
15838 +
15839 +       h_parent = au_pinned_h_parent(pin);
15840 +       if (udba != AuOpt_UDBA_NONE
15841 +           && au_dbstart(dentry) == bcpup)
15842 +               err = au_may_add(dentry, bcpup, h_parent,
15843 +                                au_ftest_wrdir(wr_dir_args->flags, ISDIR));
15844 +       else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
15845 +               err = -ENAMETOOLONG;
15846 +       wh_dentry = ERR_PTR(err);
15847 +       if (unlikely(err))
15848 +               goto out_unpin;
15849 +
15850 +       br = au_sbr(sb, bcpup);
15851 +       if (dt) {
15852 +               struct path tmp = {
15853 +                       .dentry = h_parent,
15854 +                       .mnt    = au_br_mnt(br)
15855 +               };
15856 +               au_dtime_store(dt, au_pinned_parent(pin), &tmp);
15857 +       }
15858 +
15859 +       wh_dentry = NULL;
15860 +       if (bcpup != au_dbwh(dentry))
15861 +               goto out; /* success */
15862 +
15863 +       wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
15864 +
15865 +out_unpin:
15866 +       if (IS_ERR(wh_dentry))
15867 +               au_unpin(pin);
15868 +out:
15869 +       return wh_dentry;
15870 +}
15871 +
15872 +/* ---------------------------------------------------------------------- */
15873 +
15874 +enum { Mknod, Symlink, Creat };
15875 +struct simple_arg {
15876 +       int type;
15877 +       union {
15878 +               struct {
15879 +                       umode_t mode;
15880 +                       bool want_excl;
15881 +               } c;
15882 +               struct {
15883 +                       const char *symname;
15884 +               } s;
15885 +               struct {
15886 +                       umode_t mode;
15887 +                       dev_t dev;
15888 +               } m;
15889 +       } u;
15890 +};
15891 +
15892 +static int add_simple(struct inode *dir, struct dentry *dentry,
15893 +                     struct simple_arg *arg)
15894 +{
15895 +       int err;
15896 +       aufs_bindex_t bstart;
15897 +       unsigned char created;
15898 +       struct au_dtime dt;
15899 +       struct au_pin pin;
15900 +       struct path h_path;
15901 +       struct dentry *wh_dentry, *parent;
15902 +       struct inode *h_dir;
15903 +       struct au_wr_dir_args wr_dir_args = {
15904 +               .force_btgt     = -1,
15905 +               .flags          = AuWrDir_ADD_ENTRY
15906 +       };
15907 +
15908 +       AuDbg("%.*s\n", AuDLNPair(dentry));
15909 +       IMustLock(dir);
15910 +
15911 +       parent = dentry->d_parent; /* dir inode is locked */
15912 +       err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
15913 +       if (unlikely(err))
15914 +               goto out;
15915 +       err = au_d_may_add(dentry);
15916 +       if (unlikely(err))
15917 +               goto out_unlock;
15918 +       di_write_lock_parent(parent);
15919 +       wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin,
15920 +                                     &wr_dir_args);
15921 +       err = PTR_ERR(wh_dentry);
15922 +       if (IS_ERR(wh_dentry))
15923 +               goto out_parent;
15924 +
15925 +       bstart = au_dbstart(dentry);
15926 +       h_path.dentry = au_h_dptr(dentry, bstart);
15927 +       h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
15928 +       h_dir = au_pinned_h_dir(&pin);
15929 +       switch (arg->type) {
15930 +       case Creat:
15931 +               err = vfsub_create(h_dir, &h_path, arg->u.c.mode,
15932 +                                  arg->u.c.want_excl);
15933 +               break;
15934 +       case Symlink:
15935 +               err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname);
15936 +               break;
15937 +       case Mknod:
15938 +               err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev);
15939 +               break;
15940 +       default:
15941 +               BUG();
15942 +       }
15943 +       created = !err;
15944 +       if (!err)
15945 +               err = epilog(dir, bstart, wh_dentry, dentry);
15946 +
15947 +       /* revert */
15948 +       if (unlikely(created && err && h_path.dentry->d_inode)) {
15949 +               int rerr;
15950 +               rerr = vfsub_unlink(h_dir, &h_path, /*force*/0);
15951 +               if (rerr) {
15952 +                       AuIOErr("%.*s revert failure(%d, %d)\n",
15953 +                               AuDLNPair(dentry), err, rerr);
15954 +                       err = -EIO;
15955 +               }
15956 +               au_dtime_revert(&dt);
15957 +       }
15958 +
15959 +       au_unpin(&pin);
15960 +       dput(wh_dentry);
15961 +
15962 +out_parent:
15963 +       di_write_unlock(parent);
15964 +out_unlock:
15965 +       if (unlikely(err)) {
15966 +               au_update_dbstart(dentry);
15967 +               d_drop(dentry);
15968 +       }
15969 +       aufs_read_unlock(dentry, AuLock_DW);
15970 +out:
15971 +       return err;
15972 +}
15973 +
15974 +int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15975 +              dev_t dev)
15976 +{
15977 +       struct simple_arg arg = {
15978 +               .type = Mknod,
15979 +               .u.m = {
15980 +                       .mode   = mode,
15981 +                       .dev    = dev
15982 +               }
15983 +       };
15984 +       return add_simple(dir, dentry, &arg);
15985 +}
15986 +
15987 +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
15988 +{
15989 +       struct simple_arg arg = {
15990 +               .type = Symlink,
15991 +               .u.s.symname = symname
15992 +       };
15993 +       return add_simple(dir, dentry, &arg);
15994 +}
15995 +
15996 +int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
15997 +               bool want_excl)
15998 +{
15999 +       struct simple_arg arg = {
16000 +               .type = Creat,
16001 +               .u.c = {
16002 +                       .mode           = mode,
16003 +                       .want_excl      = want_excl
16004 +               }
16005 +       };
16006 +       return add_simple(dir, dentry, &arg);
16007 +}
16008 +
16009 +/* ---------------------------------------------------------------------- */
16010 +
16011 +struct au_link_args {
16012 +       aufs_bindex_t bdst, bsrc;
16013 +       struct au_pin pin;
16014 +       struct path h_path;
16015 +       struct dentry *src_parent, *parent;
16016 +};
16017 +
16018 +static int au_cpup_before_link(struct dentry *src_dentry,
16019 +                              struct au_link_args *a)
16020 +{
16021 +       int err;
16022 +       struct dentry *h_src_dentry;
16023 +
16024 +       di_read_lock_parent(a->src_parent, AuLock_IR);
16025 +       err = au_test_and_cpup_dirs(src_dentry, a->bdst);
16026 +       if (unlikely(err))
16027 +               goto out;
16028 +
16029 +       h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
16030 +       err = au_pin(&a->pin, src_dentry, a->bdst,
16031 +                    au_opt_udba(src_dentry->d_sb),
16032 +                    AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16033 +       if (unlikely(err))
16034 +               goto out;
16035 +
16036 +       err = au_sio_cpup_simple_h_open(src_dentry, a->bdst, -1,
16037 +                                       AuCpup_DTIME /* | AuCpup_KEEPLINO */,
16038 +                                       &a->pin, a->bsrc);
16039 +       au_unpin(&a->pin);
16040 +
16041 +out:
16042 +       di_read_unlock(a->src_parent, AuLock_IR);
16043 +       return err;
16044 +}
16045 +
16046 +static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
16047 +                          struct au_link_args *a)
16048 +{
16049 +       int err;
16050 +       unsigned char plink;
16051 +       aufs_bindex_t bend;
16052 +       struct dentry *h_src_dentry;
16053 +       struct inode *h_inode, *inode;
16054 +       struct super_block *sb;
16055 +       struct file *h_file;
16056 +
16057 +       plink = 0;
16058 +       h_inode = NULL;
16059 +       sb = src_dentry->d_sb;
16060 +       inode = src_dentry->d_inode;
16061 +       if (au_ibstart(inode) <= a->bdst)
16062 +               h_inode = au_h_iptr(inode, a->bdst);
16063 +       if (!h_inode || !h_inode->i_nlink) {
16064 +               /* copyup src_dentry as the name of dentry. */
16065 +               bend = au_dbend(dentry);
16066 +               if (bend < a->bsrc)
16067 +                       au_set_dbend(dentry, a->bsrc);
16068 +               au_set_h_dptr(dentry, a->bsrc,
16069 +                             dget(au_h_dptr(src_dentry, a->bsrc)));
16070 +               dget(a->h_path.dentry);
16071 +               au_set_h_dptr(dentry, a->bdst, NULL);
16072 +               dentry->d_inode = src_dentry->d_inode; /* tmp */
16073 +               h_file = au_h_open_pre(dentry, a->bsrc);
16074 +               if (IS_ERR(h_file))
16075 +                       err = PTR_ERR(h_file);
16076 +               else {
16077 +                       err = au_sio_cpup_simple(dentry, a->bdst, -1,
16078 +                                                AuCpup_KEEPLINO, &a->pin);
16079 +                       au_h_open_post(dentry, a->bsrc, h_file);
16080 +                       if (!err) {
16081 +                               dput(a->h_path.dentry);
16082 +                               a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16083 +                       } else
16084 +                               au_set_h_dptr(dentry, a->bdst,
16085 +                                             a->h_path.dentry);
16086 +               }
16087 +               dentry->d_inode = NULL; /* restore */
16088 +               au_set_h_dptr(dentry, a->bsrc, NULL);
16089 +               au_set_dbend(dentry, bend);
16090 +       } else {
16091 +               /* the inode of src_dentry already exists on a.bdst branch */
16092 +               h_src_dentry = d_find_alias(h_inode);
16093 +               if (!h_src_dentry && au_plink_test(inode)) {
16094 +                       plink = 1;
16095 +                       h_src_dentry = au_plink_lkup(inode, a->bdst);
16096 +                       err = PTR_ERR(h_src_dentry);
16097 +                       if (IS_ERR(h_src_dentry))
16098 +                               goto out;
16099 +
16100 +                       if (unlikely(!h_src_dentry->d_inode)) {
16101 +                               dput(h_src_dentry);
16102 +                               h_src_dentry = NULL;
16103 +                       }
16104 +
16105 +               }
16106 +               if (h_src_dentry) {
16107 +                       err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
16108 +                                        &a->h_path);
16109 +                       dput(h_src_dentry);
16110 +               } else {
16111 +                       AuIOErr("no dentry found for hi%lu on b%d\n",
16112 +                               h_inode->i_ino, a->bdst);
16113 +                       err = -EIO;
16114 +               }
16115 +       }
16116 +
16117 +       if (!err && !plink)
16118 +               au_plink_append(inode, a->bdst, a->h_path.dentry);
16119 +
16120 +out:
16121 +       AuTraceErr(err);
16122 +       return err;
16123 +}
16124 +
16125 +int aufs_link(struct dentry *src_dentry, struct inode *dir,
16126 +             struct dentry *dentry)
16127 +{
16128 +       int err, rerr;
16129 +       struct au_dtime dt;
16130 +       struct au_link_args *a;
16131 +       struct dentry *wh_dentry, *h_src_dentry;
16132 +       struct inode *inode;
16133 +       struct super_block *sb;
16134 +       struct au_wr_dir_args wr_dir_args = {
16135 +               /* .force_btgt  = -1, */
16136 +               .flags          = AuWrDir_ADD_ENTRY
16137 +       };
16138 +
16139 +       IMustLock(dir);
16140 +       inode = src_dentry->d_inode;
16141 +       IMustLock(inode);
16142 +
16143 +       err = -ENOMEM;
16144 +       a = kzalloc(sizeof(*a), GFP_NOFS);
16145 +       if (unlikely(!a))
16146 +               goto out;
16147 +
16148 +       a->parent = dentry->d_parent; /* dir inode is locked */
16149 +       err = aufs_read_and_write_lock2(dentry, src_dentry,
16150 +                                       AuLock_NOPLM | AuLock_GEN);
16151 +       if (unlikely(err))
16152 +               goto out_kfree;
16153 +       err = au_d_hashed_positive(src_dentry);
16154 +       if (unlikely(err))
16155 +               goto out_unlock;
16156 +       err = au_d_may_add(dentry);
16157 +       if (unlikely(err))
16158 +               goto out_unlock;
16159 +
16160 +       a->src_parent = dget_parent(src_dentry);
16161 +       wr_dir_args.force_btgt = au_ibstart(inode);
16162 +
16163 +       di_write_lock_parent(a->parent);
16164 +       wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
16165 +       wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
16166 +                                     &wr_dir_args);
16167 +       err = PTR_ERR(wh_dentry);
16168 +       if (IS_ERR(wh_dentry))
16169 +               goto out_parent;
16170 +
16171 +       err = 0;
16172 +       sb = dentry->d_sb;
16173 +       a->bdst = au_dbstart(dentry);
16174 +       a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16175 +       a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
16176 +       a->bsrc = au_ibstart(inode);
16177 +       h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16178 +       if (!h_src_dentry) {
16179 +               a->bsrc = au_dbstart(src_dentry);
16180 +               h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16181 +               AuDebugOn(!h_src_dentry);
16182 +       } else if (IS_ERR(h_src_dentry))
16183 +               goto out_parent;
16184 +
16185 +       if (au_opt_test(au_mntflags(sb), PLINK)) {
16186 +               if (a->bdst < a->bsrc
16187 +                   /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
16188 +                       err = au_cpup_or_link(src_dentry, dentry, a);
16189 +               else
16190 +                       err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
16191 +                                        &a->h_path);
16192 +               dput(h_src_dentry);
16193 +       } else {
16194 +               /*
16195 +                * copyup src_dentry to the branch we process,
16196 +                * and then link(2) to it.
16197 +                */
16198 +               dput(h_src_dentry);
16199 +               if (a->bdst < a->bsrc
16200 +                   /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
16201 +                       au_unpin(&a->pin);
16202 +                       di_write_unlock(a->parent);
16203 +                       err = au_cpup_before_link(src_dentry, a);
16204 +                       di_write_lock_parent(a->parent);
16205 +                       if (!err)
16206 +                               err = au_pin(&a->pin, dentry, a->bdst,
16207 +                                            au_opt_udba(sb),
16208 +                                            AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16209 +                       if (unlikely(err))
16210 +                               goto out_wh;
16211 +               }
16212 +               if (!err) {
16213 +                       h_src_dentry = au_h_dptr(src_dentry, a->bdst);
16214 +                       err = -ENOENT;
16215 +                       if (h_src_dentry && h_src_dentry->d_inode)
16216 +                               err = vfsub_link(h_src_dentry,
16217 +                                                au_pinned_h_dir(&a->pin),
16218 +                                                &a->h_path);
16219 +               }
16220 +       }
16221 +       if (unlikely(err))
16222 +               goto out_unpin;
16223 +
16224 +       if (wh_dentry) {
16225 +               a->h_path.dentry = wh_dentry;
16226 +               err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
16227 +                                         dentry);
16228 +               if (unlikely(err))
16229 +                       goto out_revert;
16230 +       }
16231 +
16232 +       dir->i_version++;
16233 +       if (au_ibstart(dir) == au_dbstart(dentry))
16234 +               au_cpup_attr_timesizes(dir);
16235 +       inc_nlink(inode);
16236 +       inode->i_ctime = dir->i_ctime;
16237 +       d_instantiate(dentry, au_igrab(inode));
16238 +       if (d_unhashed(a->h_path.dentry))
16239 +               /* some filesystem calls d_drop() */
16240 +               d_drop(dentry);
16241 +       goto out_unpin; /* success */
16242 +
16243 +out_revert:
16244 +       rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
16245 +       if (unlikely(rerr)) {
16246 +               AuIOErr("%.*s reverting failed(%d, %d)\n",
16247 +                       AuDLNPair(dentry), err, rerr);
16248 +               err = -EIO;
16249 +       }
16250 +       au_dtime_revert(&dt);
16251 +out_unpin:
16252 +       au_unpin(&a->pin);
16253 +out_wh:
16254 +       dput(wh_dentry);
16255 +out_parent:
16256 +       di_write_unlock(a->parent);
16257 +       dput(a->src_parent);
16258 +out_unlock:
16259 +       if (unlikely(err)) {
16260 +               au_update_dbstart(dentry);
16261 +               d_drop(dentry);
16262 +       }
16263 +       aufs_read_and_write_unlock2(dentry, src_dentry);
16264 +out_kfree:
16265 +       kfree(a);
16266 +out:
16267 +       AuTraceErr(err);
16268 +       return err;
16269 +}
16270 +
16271 +int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
16272 +{
16273 +       int err, rerr;
16274 +       aufs_bindex_t bindex;
16275 +       unsigned char diropq;
16276 +       struct path h_path;
16277 +       struct dentry *wh_dentry, *parent, *opq_dentry;
16278 +       struct mutex *h_mtx;
16279 +       struct super_block *sb;
16280 +       struct {
16281 +               struct au_pin pin;
16282 +               struct au_dtime dt;
16283 +       } *a; /* reduce the stack usage */
16284 +       struct au_wr_dir_args wr_dir_args = {
16285 +               .force_btgt     = -1,
16286 +               .flags          = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
16287 +       };
16288 +
16289 +       IMustLock(dir);
16290 +
16291 +       err = -ENOMEM;
16292 +       a = kmalloc(sizeof(*a), GFP_NOFS);
16293 +       if (unlikely(!a))
16294 +               goto out;
16295 +
16296 +       err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
16297 +       if (unlikely(err))
16298 +               goto out_free;
16299 +       err = au_d_may_add(dentry);
16300 +       if (unlikely(err))
16301 +               goto out_unlock;
16302 +
16303 +       parent = dentry->d_parent; /* dir inode is locked */
16304 +       di_write_lock_parent(parent);
16305 +       wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
16306 +                                     &a->pin, &wr_dir_args);
16307 +       err = PTR_ERR(wh_dentry);
16308 +       if (IS_ERR(wh_dentry))
16309 +               goto out_parent;
16310 +
16311 +       sb = dentry->d_sb;
16312 +       bindex = au_dbstart(dentry);
16313 +       h_path.dentry = au_h_dptr(dentry, bindex);
16314 +       h_path.mnt = au_sbr_mnt(sb, bindex);
16315 +       err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
16316 +       if (unlikely(err))
16317 +               goto out_unpin;
16318 +
16319 +       /* make the dir opaque */
16320 +       diropq = 0;
16321 +       h_mtx = &h_path.dentry->d_inode->i_mutex;
16322 +       if (wh_dentry
16323 +           || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
16324 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16325 +               opq_dentry = au_diropq_create(dentry, bindex);
16326 +               mutex_unlock(h_mtx);
16327 +               err = PTR_ERR(opq_dentry);
16328 +               if (IS_ERR(opq_dentry))
16329 +                       goto out_dir;
16330 +               dput(opq_dentry);
16331 +               diropq = 1;
16332 +       }
16333 +
16334 +       err = epilog(dir, bindex, wh_dentry, dentry);
16335 +       if (!err) {
16336 +               inc_nlink(dir);
16337 +               goto out_unpin; /* success */
16338 +       }
16339 +
16340 +       /* revert */
16341 +       if (diropq) {
16342 +               AuLabel(revert opq);
16343 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16344 +               rerr = au_diropq_remove(dentry, bindex);
16345 +               mutex_unlock(h_mtx);
16346 +               if (rerr) {
16347 +                       AuIOErr("%.*s reverting diropq failed(%d, %d)\n",
16348 +                               AuDLNPair(dentry), err, rerr);
16349 +                       err = -EIO;
16350 +               }
16351 +       }
16352 +
16353 +out_dir:
16354 +       AuLabel(revert dir);
16355 +       rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
16356 +       if (rerr) {
16357 +               AuIOErr("%.*s reverting dir failed(%d, %d)\n",
16358 +                       AuDLNPair(dentry), err, rerr);
16359 +               err = -EIO;
16360 +       }
16361 +       au_dtime_revert(&a->dt);
16362 +out_unpin:
16363 +       au_unpin(&a->pin);
16364 +       dput(wh_dentry);
16365 +out_parent:
16366 +       di_write_unlock(parent);
16367 +out_unlock:
16368 +       if (unlikely(err)) {
16369 +               au_update_dbstart(dentry);
16370 +               d_drop(dentry);
16371 +       }
16372 +       aufs_read_unlock(dentry, AuLock_DW);
16373 +out_free:
16374 +       kfree(a);
16375 +out:
16376 +       return err;
16377 +}
16378 diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
16379 --- /usr/share/empty/fs/aufs/i_op.c     1970-01-01 01:00:00.000000000 +0100
16380 +++ linux/fs/aufs/i_op.c        2013-07-30 22:42:46.235946055 +0200
16381 @@ -0,0 +1,1100 @@
16382 +/*
16383 + * Copyright (C) 2005-2013 Junjiro R. Okajima
16384 + *
16385 + * This program, aufs is free software; you can redistribute it and/or modify
16386 + * it under the terms of the GNU General Public License as published by
16387 + * the Free Software Foundation; either version 2 of the License, or
16388 + * (at your option) any later version.
16389 + *
16390 + * This program is distributed in the hope that it will be useful,
16391 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16392 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16393 + * GNU General Public License for more details.
16394 + *
16395 + * You should have received a copy of the GNU General Public License
16396 + * along with this program; if not, write to the Free Software
16397 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16398 + */
16399 +
16400 +/*
16401 + * inode operations (except add/del/rename)
16402 + */
16403 +
16404 +#include <linux/device_cgroup.h>
16405 +#include <linux/fs_stack.h>
16406 +#include <linux/mm.h>
16407 +#include <linux/namei.h>
16408 +#include <linux/security.h>
16409 +#include "aufs.h"
16410 +
16411 +static int h_permission(struct inode *h_inode, int mask,
16412 +                       struct vfsmount *h_mnt, int brperm)
16413 +{
16414 +       int err;
16415 +       const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
16416 +
16417 +       err = -EACCES;
16418 +       if ((write_mask && IS_IMMUTABLE(h_inode))
16419 +           || ((mask & MAY_EXEC)
16420 +               && S_ISREG(h_inode->i_mode)
16421 +               && ((h_mnt->mnt_flags & MNT_NOEXEC)
16422 +                   || !(h_inode->i_mode & S_IXUGO))))
16423 +               goto out;
16424 +
16425 +       /*
16426 +        * - skip the lower fs test in the case of write to ro branch.
16427 +        * - nfs dir permission write check is optimized, but a policy for
16428 +        *   link/rename requires a real check.
16429 +        */
16430 +       if ((write_mask && !au_br_writable(brperm))
16431 +           || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
16432 +               && write_mask && !(mask & MAY_READ))
16433 +           || !h_inode->i_op->permission) {
16434 +               /* AuLabel(generic_permission); */
16435 +               err = generic_permission(h_inode, mask);
16436 +       } else {
16437 +               /* AuLabel(h_inode->permission); */
16438 +               err = h_inode->i_op->permission(h_inode, mask);
16439 +               AuTraceErr(err);
16440 +       }
16441 +
16442 +       if (!err)
16443 +               err = devcgroup_inode_permission(h_inode, mask);
16444 +       if (!err)
16445 +               err = security_inode_permission(h_inode, mask);
16446 +
16447 +#if 0
16448 +       if (!err) {
16449 +               /* todo: do we need to call ima_path_check()? */
16450 +               struct path h_path = {
16451 +                       .dentry =
16452 +                       .mnt    = h_mnt
16453 +               };
16454 +               err = ima_path_check(&h_path,
16455 +                                    mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
16456 +                                    IMA_COUNT_LEAVE);
16457 +       }
16458 +#endif
16459 +
16460 +out:
16461 +       return err;
16462 +}
16463 +
16464 +static int aufs_permission(struct inode *inode, int mask)
16465 +{
16466 +       int err;
16467 +       aufs_bindex_t bindex, bend;
16468 +       const unsigned char isdir = !!S_ISDIR(inode->i_mode),
16469 +               write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
16470 +       struct inode *h_inode;
16471 +       struct super_block *sb;
16472 +       struct au_branch *br;
16473 +
16474 +       /* todo: support rcu-walk? */
16475 +       if (mask & MAY_NOT_BLOCK)
16476 +               return -ECHILD;
16477 +
16478 +       sb = inode->i_sb;
16479 +       si_read_lock(sb, AuLock_FLUSH);
16480 +       ii_read_lock_child(inode);
16481 +#if 0
16482 +       err = au_iigen_test(inode, au_sigen(sb));
16483 +       if (unlikely(err))
16484 +               goto out;
16485 +#endif
16486 +
16487 +       if (!isdir || write_mask) {
16488 +               err = au_busy_or_stale();
16489 +               h_inode = au_h_iptr(inode, au_ibstart(inode));
16490 +               if (unlikely(!h_inode
16491 +                            || (h_inode->i_mode & S_IFMT)
16492 +                            != (inode->i_mode & S_IFMT)))
16493 +                       goto out;
16494 +
16495 +               err = 0;
16496 +               bindex = au_ibstart(inode);
16497 +               br = au_sbr(sb, bindex);
16498 +               err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
16499 +               if (write_mask
16500 +                   && !err
16501 +                   && !special_file(h_inode->i_mode)) {
16502 +                       /* test whether the upper writable branch exists */
16503 +                       err = -EROFS;
16504 +                       for (; bindex >= 0; bindex--)
16505 +                               if (!au_br_rdonly(au_sbr(sb, bindex))) {
16506 +                                       err = 0;
16507 +                                       break;
16508 +                               }
16509 +               }
16510 +               goto out;
16511 +       }
16512 +
16513 +       /* non-write to dir */
16514 +       err = 0;
16515 +       bend = au_ibend(inode);
16516 +       for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
16517 +               h_inode = au_h_iptr(inode, bindex);
16518 +               if (h_inode) {
16519 +                       err = au_busy_or_stale();
16520 +                       if (unlikely(!S_ISDIR(h_inode->i_mode)))
16521 +                               break;
16522 +
16523 +                       br = au_sbr(sb, bindex);
16524 +                       err = h_permission(h_inode, mask, au_br_mnt(br),
16525 +                                          br->br_perm);
16526 +               }
16527 +       }
16528 +
16529 +out:
16530 +       ii_read_unlock(inode);
16531 +       si_read_unlock(sb);
16532 +       return err;
16533 +}
16534 +
16535 +/* ---------------------------------------------------------------------- */
16536 +
16537 +static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
16538 +                                 unsigned int flags)
16539 +{
16540 +       struct dentry *ret, *parent;
16541 +       struct inode *inode;
16542 +       struct super_block *sb;
16543 +       int err, npositive;
16544 +
16545 +       IMustLock(dir);
16546 +
16547 +       /* todo: support rcu-walk? */
16548 +       ret = ERR_PTR(-ECHILD);
16549 +       if (flags & LOOKUP_RCU)
16550 +               goto out;
16551 +
16552 +       ret = ERR_PTR(-ENAMETOOLONG);
16553 +       if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
16554 +               goto out;
16555 +
16556 +       sb = dir->i_sb;
16557 +       err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16558 +       ret = ERR_PTR(err);
16559 +       if (unlikely(err))
16560 +               goto out;
16561 +
16562 +       err = au_di_init(dentry);
16563 +       ret = ERR_PTR(err);
16564 +       if (unlikely(err))
16565 +               goto out_si;
16566 +
16567 +       inode = NULL;
16568 +       npositive = 0; /* suppress a warning */
16569 +       parent = dentry->d_parent; /* dir inode is locked */
16570 +       di_read_lock_parent(parent, AuLock_IR);
16571 +       err = au_alive_dir(parent);
16572 +       if (!err)
16573 +               err = au_digen_test(parent, au_sigen(sb));
16574 +       if (!err) {
16575 +               npositive = au_lkup_dentry(dentry, au_dbstart(parent),
16576 +                                          /*type*/0);
16577 +               err = npositive;
16578 +       }
16579 +       di_read_unlock(parent, AuLock_IR);
16580 +       ret = ERR_PTR(err);
16581 +       if (unlikely(err < 0))
16582 +               goto out_unlock;
16583 +
16584 +       if (npositive) {
16585 +               inode = au_new_inode(dentry, /*must_new*/0);
16586 +               ret = (void *)inode;
16587 +       }
16588 +       if (IS_ERR(inode)) {
16589 +               inode = NULL;
16590 +               goto out_unlock;
16591 +       }
16592 +
16593 +       ret = d_splice_alias(inode, dentry);
16594 +#if 0
16595 +       if (unlikely(d_need_lookup(dentry))) {
16596 +               spin_lock(&dentry->d_lock);
16597 +               dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
16598 +               spin_unlock(&dentry->d_lock);
16599 +       } else
16600 +#endif
16601 +       if (unlikely(IS_ERR(ret) && inode)) {
16602 +               ii_write_unlock(inode);
16603 +               iput(inode);
16604 +               inode = NULL;
16605 +       }
16606 +
16607 +out_unlock:
16608 +       di_write_unlock(dentry);
16609 +       if (inode) {
16610 +               /* verbose coding for lock class name */
16611 +               if (unlikely(S_ISLNK(inode->i_mode)))
16612 +                       au_rw_class(&au_di(dentry)->di_rwsem,
16613 +                                   au_lc_key + AuLcSymlink_DIINFO);
16614 +               else if (unlikely(S_ISDIR(inode->i_mode)))
16615 +                       au_rw_class(&au_di(dentry)->di_rwsem,
16616 +                                   au_lc_key + AuLcDir_DIINFO);
16617 +               else /* likely */
16618 +                       au_rw_class(&au_di(dentry)->di_rwsem,
16619 +                                   au_lc_key + AuLcNonDir_DIINFO);
16620 +       }
16621 +out_si:
16622 +       si_read_unlock(sb);
16623 +out:
16624 +       return ret;
16625 +}
16626 +
16627 +/* ---------------------------------------------------------------------- */
16628 +
16629 +static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
16630 +                         const unsigned char add_entry, aufs_bindex_t bcpup,
16631 +                         aufs_bindex_t bstart)
16632 +{
16633 +       int err;
16634 +       struct dentry *h_parent;
16635 +       struct inode *h_dir;
16636 +
16637 +       if (add_entry)
16638 +               IMustLock(parent->d_inode);
16639 +       else
16640 +               di_write_lock_parent(parent);
16641 +
16642 +       err = 0;
16643 +       if (!au_h_dptr(parent, bcpup)) {
16644 +               if (bstart < bcpup)
16645 +                       err = au_cpdown_dirs(dentry, bcpup);
16646 +               else
16647 +                       err = au_cpup_dirs(dentry, bcpup);
16648 +       }
16649 +       if (!err && add_entry) {
16650 +               h_parent = au_h_dptr(parent, bcpup);
16651 +               h_dir = h_parent->d_inode;
16652 +               mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
16653 +               err = au_lkup_neg(dentry, bcpup,
16654 +                                 au_ftest_wrdir(add_entry, TMP_WHENTRY));
16655 +               /* todo: no unlock here */
16656 +               mutex_unlock(&h_dir->i_mutex);
16657 +
16658 +               AuDbg("bcpup %d\n", bcpup);
16659 +               if (!err) {
16660 +                       if (!dentry->d_inode)
16661 +                               au_set_h_dptr(dentry, bstart, NULL);
16662 +                       au_update_dbrange(dentry, /*do_put_zero*/0);
16663 +               }
16664 +       }
16665 +
16666 +       if (!add_entry)
16667 +               di_write_unlock(parent);
16668 +       if (!err)
16669 +               err = bcpup; /* success */
16670 +
16671 +       AuTraceErr(err);
16672 +       return err;
16673 +}
16674 +
16675 +/*
16676 + * decide the branch and the parent dir where we will create a new entry.
16677 + * returns new bindex or an error.
16678 + * copyup the parent dir if needed.
16679 + */
16680 +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16681 +             struct au_wr_dir_args *args)
16682 +{
16683 +       int err;
16684 +       aufs_bindex_t bcpup, bstart, src_bstart;
16685 +       const unsigned char add_entry
16686 +               = au_ftest_wrdir(args->flags, ADD_ENTRY)
16687 +               | au_ftest_wrdir(args->flags, TMP_WHENTRY);
16688 +       struct super_block *sb;
16689 +       struct dentry *parent;
16690 +       struct au_sbinfo *sbinfo;
16691 +
16692 +       sb = dentry->d_sb;
16693 +       sbinfo = au_sbi(sb);
16694 +       parent = dget_parent(dentry);
16695 +       bstart = au_dbstart(dentry);
16696 +       bcpup = bstart;
16697 +       if (args->force_btgt < 0) {
16698 +               if (src_dentry) {
16699 +                       src_bstart = au_dbstart(src_dentry);
16700 +                       if (src_bstart < bstart)
16701 +                               bcpup = src_bstart;
16702 +               } else if (add_entry) {
16703 +                       err = AuWbrCreate(sbinfo, dentry,
16704 +                                         au_ftest_wrdir(args->flags, ISDIR));
16705 +                       bcpup = err;
16706 +               }
16707 +
16708 +               if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
16709 +                       if (add_entry)
16710 +                               err = AuWbrCopyup(sbinfo, dentry);
16711 +                       else {
16712 +                               if (!IS_ROOT(dentry)) {
16713 +                                       di_read_lock_parent(parent, !AuLock_IR);
16714 +                                       err = AuWbrCopyup(sbinfo, dentry);
16715 +                                       di_read_unlock(parent, !AuLock_IR);
16716 +                               } else
16717 +                                       err = AuWbrCopyup(sbinfo, dentry);
16718 +                       }
16719 +                       bcpup = err;
16720 +                       if (unlikely(err < 0))
16721 +                               goto out;
16722 +               }
16723 +       } else {
16724 +               bcpup = args->force_btgt;
16725 +               AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
16726 +       }
16727 +
16728 +       AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
16729 +       err = bcpup;
16730 +       if (bcpup == bstart)
16731 +               goto out; /* success */
16732 +
16733 +       /* copyup the new parent into the branch we process */
16734 +       err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
16735 +       if (err >= 0) {
16736 +               if (!dentry->d_inode) {
16737 +                       au_set_h_dptr(dentry, bstart, NULL);
16738 +                       au_set_dbstart(dentry, bcpup);
16739 +                       au_set_dbend(dentry, bcpup);
16740 +               }
16741 +               AuDebugOn(add_entry && !au_h_dptr(dentry, bcpup));
16742 +       }
16743 +
16744 +out:
16745 +       dput(parent);
16746 +       return err;
16747 +}
16748 +
16749 +/* ---------------------------------------------------------------------- */
16750 +
16751 +void au_pin_hdir_unlock(struct au_pin *p)
16752 +{
16753 +       if (p->hdir)
16754 +               au_hn_imtx_unlock(p->hdir);
16755 +}
16756 +
16757 +static int au_pin_hdir_lock(struct au_pin *p)
16758 +{
16759 +       int err;
16760 +
16761 +       err = 0;
16762 +       if (!p->hdir)
16763 +               goto out;
16764 +
16765 +       /* even if an error happens later, keep this lock */
16766 +       au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
16767 +
16768 +       err = -EBUSY;
16769 +       if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
16770 +               goto out;
16771 +
16772 +       err = 0;
16773 +       if (p->h_dentry)
16774 +               err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
16775 +                                 p->h_parent, p->br);
16776 +
16777 +out:
16778 +       return err;
16779 +}
16780 +
16781 +int au_pin_hdir_relock(struct au_pin *p)
16782 +{
16783 +       int err, i;
16784 +       struct inode *h_i;
16785 +       struct dentry *h_d[] = {
16786 +               p->h_dentry,
16787 +               p->h_parent
16788 +       };
16789 +
16790 +       err = au_pin_hdir_lock(p);
16791 +       if (unlikely(err))
16792 +               goto out;
16793 +
16794 +       for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
16795 +               if (!h_d[i])
16796 +                       continue;
16797 +               h_i = h_d[i]->d_inode;
16798 +               if (h_i)
16799 +                       err = !h_i->i_nlink;
16800 +       }
16801 +
16802 +out:
16803 +       return err;
16804 +}
16805 +
16806 +void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
16807 +{
16808 +#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
16809 +       p->hdir->hi_inode->i_mutex.owner = task;
16810 +#endif
16811 +}
16812 +
16813 +void au_pin_hdir_acquire_nest(struct au_pin *p)
16814 +{
16815 +       if (p->hdir) {
16816 +               mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
16817 +                                  p->lsc_hi, 0, NULL, _RET_IP_);
16818 +               au_pin_hdir_set_owner(p, current);
16819 +       }
16820 +}
16821 +
16822 +void au_pin_hdir_release(struct au_pin *p)
16823 +{
16824 +       if (p->hdir) {
16825 +               au_pin_hdir_set_owner(p, p->task);
16826 +               mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
16827 +       }
16828 +}
16829 +
16830 +struct dentry *au_pinned_h_parent(struct au_pin *pin)
16831 +{
16832 +       if (pin && pin->parent)
16833 +               return au_h_dptr(pin->parent, pin->bindex);
16834 +       return NULL;
16835 +}
16836 +
16837 +void au_unpin(struct au_pin *p)
16838 +{
16839 +       if (p->hdir)
16840 +               au_pin_hdir_unlock(p);
16841 +       if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
16842 +               vfsub_mnt_drop_write(p->h_mnt);
16843 +       if (!p->hdir)
16844 +               return;
16845 +
16846 +       if (!au_ftest_pin(p->flags, DI_LOCKED))
16847 +               di_read_unlock(p->parent, AuLock_IR);
16848 +       iput(p->hdir->hi_inode);
16849 +       dput(p->parent);
16850 +       p->parent = NULL;
16851 +       p->hdir = NULL;
16852 +       p->h_mnt = NULL;
16853 +       /* do not clear p->task */
16854 +}
16855 +
16856 +int au_do_pin(struct au_pin *p)
16857 +{
16858 +       int err;
16859 +       struct super_block *sb;
16860 +       struct inode *h_dir;
16861 +
16862 +       err = 0;
16863 +       sb = p->dentry->d_sb;
16864 +       p->br = au_sbr(sb, p->bindex);
16865 +       if (IS_ROOT(p->dentry)) {
16866 +               if (au_ftest_pin(p->flags, MNT_WRITE)) {
16867 +                       p->h_mnt = au_br_mnt(p->br);
16868 +                       err = vfsub_mnt_want_write(p->h_mnt);
16869 +                       if (unlikely(err)) {
16870 +                               au_fclr_pin(p->flags, MNT_WRITE);
16871 +                               goto out_err;
16872 +                       }
16873 +               }
16874 +               goto out;
16875 +       }
16876 +
16877 +       p->h_dentry = NULL;
16878 +       if (p->bindex <= au_dbend(p->dentry))
16879 +               p->h_dentry = au_h_dptr(p->dentry, p->bindex);
16880 +
16881 +       p->parent = dget_parent(p->dentry);
16882 +       if (!au_ftest_pin(p->flags, DI_LOCKED))
16883 +               di_read_lock(p->parent, AuLock_IR, p->lsc_di);
16884 +
16885 +       h_dir = NULL;
16886 +       p->h_parent = au_h_dptr(p->parent, p->bindex);
16887 +       p->hdir = au_hi(p->parent->d_inode, p->bindex);
16888 +       if (p->hdir)
16889 +               h_dir = p->hdir->hi_inode;
16890 +
16891 +       /*
16892 +        * udba case, or
16893 +        * if DI_LOCKED is not set, then p->parent may be different
16894 +        * and h_parent can be NULL.
16895 +        */
16896 +       if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
16897 +               err = -EBUSY;
16898 +               if (!au_ftest_pin(p->flags, DI_LOCKED))
16899 +                       di_read_unlock(p->parent, AuLock_IR);
16900 +               dput(p->parent);
16901 +               p->parent = NULL;
16902 +               goto out_err;
16903 +       }
16904 +
16905 +       if (au_ftest_pin(p->flags, MNT_WRITE)) {
16906 +               p->h_mnt = au_br_mnt(p->br);
16907 +               err = vfsub_mnt_want_write(p->h_mnt);
16908 +               if (unlikely(err)) {
16909 +                       au_fclr_pin(p->flags, MNT_WRITE);
16910 +                       if (!au_ftest_pin(p->flags, DI_LOCKED))
16911 +                               di_read_unlock(p->parent, AuLock_IR);
16912 +                       dput(p->parent);
16913 +                       p->parent = NULL;
16914 +                       goto out_err;
16915 +               }
16916 +       }
16917 +
16918 +       au_igrab(h_dir);
16919 +       err = au_pin_hdir_lock(p);
16920 +       if (!err)
16921 +               goto out; /* success */
16922 +
16923 +out_err:
16924 +       pr_err("err %d\n", err);
16925 +       err = au_busy_or_stale();
16926 +out:
16927 +       return err;
16928 +}
16929 +
16930 +void au_pin_init(struct au_pin *p, struct dentry *dentry,
16931 +                aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16932 +                unsigned int udba, unsigned char flags)
16933 +{
16934 +       p->dentry = dentry;
16935 +       p->udba = udba;
16936 +       p->lsc_di = lsc_di;
16937 +       p->lsc_hi = lsc_hi;
16938 +       p->flags = flags;
16939 +       p->bindex = bindex;
16940 +
16941 +       p->parent = NULL;
16942 +       p->hdir = NULL;
16943 +       p->h_mnt = NULL;
16944 +
16945 +       p->h_dentry = NULL;
16946 +       p->h_parent = NULL;
16947 +       p->br = NULL;
16948 +       p->task = current;
16949 +}
16950 +
16951 +int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16952 +          unsigned int udba, unsigned char flags)
16953 +{
16954 +       au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
16955 +                   udba, flags);
16956 +       return au_do_pin(pin);
16957 +}
16958 +
16959 +/* ---------------------------------------------------------------------- */
16960 +
16961 +/*
16962 + * ->setattr() and ->getattr() are called in various cases.
16963 + * chmod, stat: dentry is revalidated.
16964 + * fchmod, fstat: file and dentry are not revalidated, additionally they may be
16965 + *               unhashed.
16966 + * for ->setattr(), ia->ia_file is passed from ftruncate only.
16967 + */
16968 +/* todo: consolidate with do_refresh() and simple_reval_dpath() */
16969 +static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
16970 +{
16971 +       int err;
16972 +       struct inode *inode;
16973 +       struct dentry *parent;
16974 +
16975 +       err = 0;
16976 +       inode = dentry->d_inode;
16977 +       if (au_digen_test(dentry, sigen)) {
16978 +               parent = dget_parent(dentry);
16979 +               di_read_lock_parent(parent, AuLock_IR);
16980 +               err = au_refresh_dentry(dentry, parent);
16981 +               di_read_unlock(parent, AuLock_IR);
16982 +               dput(parent);
16983 +       }
16984 +
16985 +       AuTraceErr(err);
16986 +       return err;
16987 +}
16988 +
16989 +#define AuIcpup_DID_CPUP       1
16990 +#define au_ftest_icpup(flags, name)    ((flags) & AuIcpup_##name)
16991 +#define au_fset_icpup(flags, name) \
16992 +       do { (flags) |= AuIcpup_##name; } while (0)
16993 +#define au_fclr_icpup(flags, name) \
16994 +       do { (flags) &= ~AuIcpup_##name; } while (0)
16995 +
16996 +struct au_icpup_args {
16997 +       unsigned char flags;
16998 +       unsigned char pin_flags;
16999 +       aufs_bindex_t btgt;
17000 +       unsigned int udba;
17001 +       struct au_pin pin;
17002 +       struct path h_path;
17003 +       struct inode *h_inode;
17004 +};
17005 +
17006 +static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
17007 +                           struct au_icpup_args *a)
17008 +{
17009 +       int err;
17010 +       loff_t sz;
17011 +       aufs_bindex_t bstart, ibstart;
17012 +       struct dentry *hi_wh, *parent;
17013 +       struct inode *inode;
17014 +       struct au_wr_dir_args wr_dir_args = {
17015 +               .force_btgt     = -1,
17016 +               .flags          = 0
17017 +       };
17018 +
17019 +       bstart = au_dbstart(dentry);
17020 +       inode = dentry->d_inode;
17021 +       if (S_ISDIR(inode->i_mode))
17022 +               au_fset_wrdir(wr_dir_args.flags, ISDIR);
17023 +       /* plink or hi_wh() case */
17024 +       ibstart = au_ibstart(inode);
17025 +       if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
17026 +               wr_dir_args.force_btgt = ibstart;
17027 +       err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17028 +       if (unlikely(err < 0))
17029 +               goto out;
17030 +       a->btgt = err;
17031 +       if (err != bstart)
17032 +               au_fset_icpup(a->flags, DID_CPUP);
17033 +
17034 +       err = 0;
17035 +       a->pin_flags = AuPin_MNT_WRITE;
17036 +       parent = NULL;
17037 +       if (!IS_ROOT(dentry)) {
17038 +               au_fset_pin(a->pin_flags, DI_LOCKED);
17039 +               parent = dget_parent(dentry);
17040 +               di_write_lock_parent(parent);
17041 +       }
17042 +
17043 +       err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
17044 +       if (unlikely(err))
17045 +               goto out_parent;
17046 +
17047 +       a->h_path.dentry = au_h_dptr(dentry, bstart);
17048 +       a->h_inode = a->h_path.dentry->d_inode;
17049 +       mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17050 +       sz = -1;
17051 +       if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
17052 +               sz = ia->ia_size;
17053 +       mutex_unlock(&a->h_inode->i_mutex);
17054 +
17055 +       hi_wh = NULL;
17056 +       if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
17057 +               hi_wh = au_hi_wh(inode, a->btgt);
17058 +               if (!hi_wh) {
17059 +                       err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL,
17060 +                                            &a->pin);
17061 +                       if (unlikely(err))
17062 +                               goto out_unlock;
17063 +                       hi_wh = au_hi_wh(inode, a->btgt);
17064 +                       /* todo: revalidate hi_wh? */
17065 +               }
17066 +       }
17067 +
17068 +       if (parent) {
17069 +               au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
17070 +               di_downgrade_lock(parent, AuLock_IR);
17071 +               dput(parent);
17072 +               parent = NULL;
17073 +       }
17074 +       if (!au_ftest_icpup(a->flags, DID_CPUP))
17075 +               goto out; /* success */
17076 +
17077 +       if (!d_unhashed(dentry)) {
17078 +               err = au_sio_cpup_simple_h_open(dentry, a->btgt, sz,
17079 +                                               AuCpup_DTIME, &a->pin, bstart);
17080 +               if (!err)
17081 +                       a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17082 +       } else if (!hi_wh)
17083 +               a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17084 +       else
17085 +               a->h_path.dentry = hi_wh; /* do not dget here */
17086 +
17087 +out_unlock:
17088 +       a->h_inode = a->h_path.dentry->d_inode;
17089 +       if (!err)
17090 +               goto out; /* success */
17091 +       au_unpin(&a->pin);
17092 +out_parent:
17093 +       if (parent) {
17094 +               di_write_unlock(parent);
17095 +               dput(parent);
17096 +       }
17097 +out:
17098 +       if (!err)
17099 +               mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17100 +       return err;
17101 +}
17102 +
17103 +static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
17104 +{
17105 +       int err;
17106 +       struct inode *inode;
17107 +       struct super_block *sb;
17108 +       struct file *file;
17109 +       struct au_icpup_args *a;
17110 +
17111 +       inode = dentry->d_inode;
17112 +       IMustLock(inode);
17113 +
17114 +       err = -ENOMEM;
17115 +       a = kzalloc(sizeof(*a), GFP_NOFS);
17116 +       if (unlikely(!a))
17117 +               goto out;
17118 +
17119 +       if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
17120 +               ia->ia_valid &= ~ATTR_MODE;
17121 +
17122 +       file = NULL;
17123 +       sb = dentry->d_sb;
17124 +       err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17125 +       if (unlikely(err))
17126 +               goto out_kfree;
17127 +
17128 +       if (ia->ia_valid & ATTR_FILE) {
17129 +               /* currently ftruncate(2) only */
17130 +               AuDebugOn(!S_ISREG(inode->i_mode));
17131 +               file = ia->ia_file;
17132 +               err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
17133 +               if (unlikely(err))
17134 +                       goto out_si;
17135 +               ia->ia_file = au_hf_top(file);
17136 +               a->udba = AuOpt_UDBA_NONE;
17137 +       } else {
17138 +               /* fchmod() doesn't pass ia_file */
17139 +               a->udba = au_opt_udba(sb);
17140 +               di_write_lock_child(dentry);
17141 +               /* no d_unlinked(), to set UDBA_NONE for root */
17142 +               if (d_unhashed(dentry))
17143 +                       a->udba = AuOpt_UDBA_NONE;
17144 +               if (a->udba != AuOpt_UDBA_NONE) {
17145 +                       AuDebugOn(IS_ROOT(dentry));
17146 +                       err = au_reval_for_attr(dentry, au_sigen(sb));
17147 +                       if (unlikely(err))
17148 +                               goto out_dentry;
17149 +               }
17150 +       }
17151 +
17152 +       err = au_pin_and_icpup(dentry, ia, a);
17153 +       if (unlikely(err < 0))
17154 +               goto out_dentry;
17155 +       if (au_ftest_icpup(a->flags, DID_CPUP)) {
17156 +               ia->ia_file = NULL;
17157 +               ia->ia_valid &= ~ATTR_FILE;
17158 +       }
17159 +
17160 +       a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
17161 +       if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
17162 +           == (ATTR_MODE | ATTR_CTIME)) {
17163 +               err = security_path_chmod(&a->h_path, ia->ia_mode);
17164 +               if (unlikely(err))
17165 +                       goto out_unlock;
17166 +       } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
17167 +                  && (ia->ia_valid & ATTR_CTIME)) {
17168 +               err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
17169 +               if (unlikely(err))
17170 +                       goto out_unlock;
17171 +       }
17172 +
17173 +       if (ia->ia_valid & ATTR_SIZE) {
17174 +               struct file *f;
17175 +
17176 +               if (ia->ia_size < i_size_read(inode))
17177 +                       /* unmap only */
17178 +                       truncate_setsize(inode, ia->ia_size);
17179 +
17180 +               f = NULL;
17181 +               if (ia->ia_valid & ATTR_FILE)
17182 +                       f = ia->ia_file;
17183 +               mutex_unlock(&a->h_inode->i_mutex);
17184 +               err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
17185 +               mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17186 +       } else
17187 +               err = vfsub_notify_change(&a->h_path, ia);
17188 +       if (!err)
17189 +               au_cpup_attr_changeable(inode);
17190 +
17191 +out_unlock:
17192 +       mutex_unlock(&a->h_inode->i_mutex);
17193 +       au_unpin(&a->pin);
17194 +       if (unlikely(err))
17195 +               au_update_dbstart(dentry);
17196 +out_dentry:
17197 +       di_write_unlock(dentry);
17198 +       if (file) {
17199 +               fi_write_unlock(file);
17200 +               ia->ia_file = file;
17201 +               ia->ia_valid |= ATTR_FILE;
17202 +       }
17203 +out_si:
17204 +       si_read_unlock(sb);
17205 +out_kfree:
17206 +       kfree(a);
17207 +out:
17208 +       AuTraceErr(err);
17209 +       return err;
17210 +}
17211 +
17212 +static void au_refresh_iattr(struct inode *inode, struct kstat *st,
17213 +                            unsigned int nlink)
17214 +{
17215 +       unsigned int n;
17216 +
17217 +       inode->i_mode = st->mode;
17218 +       /* don't i_[ug]id_write() here */
17219 +       inode->i_uid = st->uid;
17220 +       inode->i_gid = st->gid;
17221 +       inode->i_atime = st->atime;
17222 +       inode->i_mtime = st->mtime;
17223 +       inode->i_ctime = st->ctime;
17224 +
17225 +       au_cpup_attr_nlink(inode, /*force*/0);
17226 +       if (S_ISDIR(inode->i_mode)) {
17227 +               n = inode->i_nlink;
17228 +               n -= nlink;
17229 +               n += st->nlink;
17230 +               smp_mb();
17231 +               /* 0 can happen */
17232 +               set_nlink(inode, n);
17233 +       }
17234 +
17235 +       spin_lock(&inode->i_lock);
17236 +       inode->i_blocks = st->blocks;
17237 +       i_size_write(inode, st->size);
17238 +       spin_unlock(&inode->i_lock);
17239 +}
17240 +
17241 +static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
17242 +                       struct dentry *dentry, struct kstat *st)
17243 +{
17244 +       int err;
17245 +       unsigned int mnt_flags;
17246 +       aufs_bindex_t bindex;
17247 +       unsigned char udba_none, positive;
17248 +       struct super_block *sb, *h_sb;
17249 +       struct inode *inode;
17250 +       struct path h_path;
17251 +
17252 +       sb = dentry->d_sb;
17253 +       inode = dentry->d_inode;
17254 +       err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17255 +       if (unlikely(err))
17256 +               goto out;
17257 +       mnt_flags = au_mntflags(sb);
17258 +       udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
17259 +
17260 +       /* support fstat(2) */
17261 +       if (!d_unlinked(dentry) && !udba_none) {
17262 +               unsigned int sigen = au_sigen(sb);
17263 +               err = au_digen_test(dentry, sigen);
17264 +               if (!err) {
17265 +                       di_read_lock_child(dentry, AuLock_IR);
17266 +                       err = au_dbrange_test(dentry);
17267 +                       if (unlikely(err))
17268 +                               goto out_unlock;
17269 +               } else {
17270 +                       AuDebugOn(IS_ROOT(dentry));
17271 +                       di_write_lock_child(dentry);
17272 +                       err = au_dbrange_test(dentry);
17273 +                       if (!err)
17274 +                               err = au_reval_for_attr(dentry, sigen);
17275 +                       di_downgrade_lock(dentry, AuLock_IR);
17276 +                       if (unlikely(err))
17277 +                               goto out_unlock;
17278 +               }
17279 +       } else
17280 +               di_read_lock_child(dentry, AuLock_IR);
17281 +
17282 +       bindex = au_ibstart(inode);
17283 +       h_path.mnt = au_sbr_mnt(sb, bindex);
17284 +       h_sb = h_path.mnt->mnt_sb;
17285 +       if (!au_test_fs_bad_iattr(h_sb) && udba_none)
17286 +               goto out_fill; /* success */
17287 +
17288 +       h_path.dentry = NULL;
17289 +       if (au_dbstart(dentry) == bindex)
17290 +               h_path.dentry = dget(au_h_dptr(dentry, bindex));
17291 +       else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
17292 +               h_path.dentry = au_plink_lkup(inode, bindex);
17293 +               if (IS_ERR(h_path.dentry))
17294 +                       goto out_fill; /* pretending success */
17295 +       }
17296 +       /* illegally overlapped or something */
17297 +       if (unlikely(!h_path.dentry))
17298 +               goto out_fill; /* pretending success */
17299 +
17300 +       positive = !!h_path.dentry->d_inode;
17301 +       if (positive)
17302 +               err = vfs_getattr(&h_path, st);
17303 +       dput(h_path.dentry);
17304 +       if (!err) {
17305 +               if (positive)
17306 +                       au_refresh_iattr(inode, st,
17307 +                                        h_path.dentry->d_inode->i_nlink);
17308 +               goto out_fill; /* success */
17309 +       }
17310 +       AuTraceErr(err);
17311 +       goto out_unlock;
17312 +
17313 +out_fill:
17314 +       generic_fillattr(inode, st);
17315 +out_unlock:
17316 +       di_read_unlock(dentry, AuLock_IR);
17317 +       si_read_unlock(sb);
17318 +out:
17319 +       AuTraceErr(err);
17320 +       return err;
17321 +}
17322 +
17323 +/* ---------------------------------------------------------------------- */
17324 +
17325 +static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
17326 +                     int bufsiz)
17327 +{
17328 +       int err;
17329 +       struct super_block *sb;
17330 +       struct dentry *h_dentry;
17331 +
17332 +       err = -EINVAL;
17333 +       h_dentry = au_h_dptr(dentry, bindex);
17334 +       if (unlikely(!h_dentry->d_inode->i_op->readlink))
17335 +               goto out;
17336 +
17337 +       err = security_inode_readlink(h_dentry);
17338 +       if (unlikely(err))
17339 +               goto out;
17340 +
17341 +       sb = dentry->d_sb;
17342 +       if (!au_test_ro(sb, bindex, dentry->d_inode)) {
17343 +               vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
17344 +               fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
17345 +       }
17346 +       err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
17347 +
17348 +out:
17349 +       return err;
17350 +}
17351 +
17352 +static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
17353 +{
17354 +       int err;
17355 +
17356 +       err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17357 +       if (unlikely(err))
17358 +               goto out;
17359 +       err = au_d_hashed_positive(dentry);
17360 +       if (!err)
17361 +               err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
17362 +       aufs_read_unlock(dentry, AuLock_IR);
17363 +
17364 +out:
17365 +       return err;
17366 +}
17367 +
17368 +static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
17369 +{
17370 +       int err;
17371 +       mm_segment_t old_fs;
17372 +       union {
17373 +               char *k;
17374 +               char __user *u;
17375 +       } buf;
17376 +
17377 +       err = -ENOMEM;
17378 +       buf.k = (void *)__get_free_page(GFP_NOFS);
17379 +       if (unlikely(!buf.k))
17380 +               goto out;
17381 +
17382 +       err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17383 +       if (unlikely(err))
17384 +               goto out_name;
17385 +
17386 +       err = au_d_hashed_positive(dentry);
17387 +       if (!err) {
17388 +               old_fs = get_fs();
17389 +               set_fs(KERNEL_DS);
17390 +               err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
17391 +               set_fs(old_fs);
17392 +       }
17393 +       aufs_read_unlock(dentry, AuLock_IR);
17394 +
17395 +       if (err >= 0) {
17396 +               buf.k[err] = 0;
17397 +               /* will be freed by put_link */
17398 +               nd_set_link(nd, buf.k);
17399 +               return NULL; /* success */
17400 +       }
17401 +
17402 +out_name:
17403 +       free_page((unsigned long)buf.k);
17404 +out:
17405 +       AuTraceErr(err);
17406 +       return ERR_PTR(err);
17407 +}
17408 +
17409 +static void aufs_put_link(struct dentry *dentry __maybe_unused,
17410 +                         struct nameidata *nd, void *cookie __maybe_unused)
17411 +{
17412 +       char *p;
17413 +
17414 +       p = nd_get_link(nd);
17415 +       if (!IS_ERR_OR_NULL(p))
17416 +               free_page((unsigned long)p);
17417 +}
17418 +
17419 +/* ---------------------------------------------------------------------- */
17420 +
17421 +static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
17422 +{
17423 +       int err;
17424 +       struct super_block *sb;
17425 +       struct inode *h_inode;
17426 +
17427 +       sb = inode->i_sb;
17428 +       /* mmap_sem might be acquired already, cf. aufs_mmap() */
17429 +       lockdep_off();
17430 +       si_read_lock(sb, AuLock_FLUSH);
17431 +       ii_write_lock_child(inode);
17432 +       lockdep_on();
17433 +       h_inode = au_h_iptr(inode, au_ibstart(inode));
17434 +       err = vfsub_update_time(h_inode, ts, flags);
17435 +       lockdep_off();
17436 +       ii_write_unlock(inode);
17437 +       si_read_unlock(sb);
17438 +       lockdep_on();
17439 +       return err;
17440 +}
17441 +
17442 +/* ---------------------------------------------------------------------- */
17443 +
17444 +struct inode_operations aufs_symlink_iop = {
17445 +       .permission     = aufs_permission,
17446 +       .setattr        = aufs_setattr,
17447 +       .getattr        = aufs_getattr,
17448 +
17449 +       .readlink       = aufs_readlink,
17450 +       .follow_link    = aufs_follow_link,
17451 +       .put_link       = aufs_put_link,
17452 +
17453 +       /* .update_time = aufs_update_time */
17454 +};
17455 +
17456 +struct inode_operations aufs_dir_iop = {
17457 +       .create         = aufs_create,
17458 +       .lookup         = aufs_lookup,
17459 +       .link           = aufs_link,
17460 +       .unlink         = aufs_unlink,
17461 +       .symlink        = aufs_symlink,
17462 +       .mkdir          = aufs_mkdir,
17463 +       .rmdir          = aufs_rmdir,
17464 +       .mknod          = aufs_mknod,
17465 +       .rename         = aufs_rename,
17466 +
17467 +       .permission     = aufs_permission,
17468 +       .setattr        = aufs_setattr,
17469 +       .getattr        = aufs_getattr,
17470 +
17471 +       .update_time    = aufs_update_time
17472 +       /* no support for atomic_open() */
17473 +};
17474 +
17475 +struct inode_operations aufs_iop = {
17476 +       .permission     = aufs_permission,
17477 +       .setattr        = aufs_setattr,
17478 +       .getattr        = aufs_getattr,
17479 +
17480 +       .update_time    = aufs_update_time
17481 +};
17482 diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
17483 --- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
17484 +++ linux/fs/aufs/i_op_del.c    2013-07-06 13:20:47.750198454 +0200
17485 @@ -0,0 +1,477 @@
17486 +/*
17487 + * Copyright (C) 2005-2013 Junjiro R. Okajima
17488 + *
17489 + * This program, aufs is free software; you can redistribute it and/or modify
17490 + * it under the terms of the GNU General Public License as published by
17491 + * the Free Software Foundation; either version 2 of the License, or
17492 + * (at your option) any later version.
17493 + *
17494 + * This program is distributed in the hope that it will be useful,
17495 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17496 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17497 + * GNU General Public License for more details.
17498 + *
17499 + * You should have received a copy of the GNU General Public License
17500 + * along with this program; if not, write to the Free Software
17501 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17502 + */
17503 +
17504 +/*
17505 + * inode operations (del entry)
17506 + */
17507 +
17508 +#include "aufs.h"
17509 +
17510 +/*
17511 + * decide if a new whiteout for @dentry is necessary or not.
17512 + * when it is necessary, prepare the parent dir for the upper branch whose
17513 + * branch index is @bcpup for creation. the actual creation of the whiteout will
17514 + * be done by caller.
17515 + * return value:
17516 + * 0: wh is unnecessary
17517 + * plus: wh is necessary
17518 + * minus: error
17519 + */
17520 +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
17521 +{
17522 +       int need_wh, err;
17523 +       aufs_bindex_t bstart;
17524 +       struct super_block *sb;
17525 +
17526 +       sb = dentry->d_sb;
17527 +       bstart = au_dbstart(dentry);
17528 +       if (*bcpup < 0) {
17529 +               *bcpup = bstart;
17530 +               if (au_test_ro(sb, bstart, dentry->d_inode)) {
17531 +                       err = AuWbrCopyup(au_sbi(sb), dentry);
17532 +                       *bcpup = err;
17533 +                       if (unlikely(err < 0))
17534 +                               goto out;
17535 +               }
17536 +       } else
17537 +               AuDebugOn(bstart < *bcpup
17538 +                         || au_test_ro(sb, *bcpup, dentry->d_inode));
17539 +       AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
17540 +
17541 +       if (*bcpup != bstart) {
17542 +               err = au_cpup_dirs(dentry, *bcpup);
17543 +               if (unlikely(err))
17544 +                       goto out;
17545 +               need_wh = 1;
17546 +       } else {
17547 +               struct au_dinfo *dinfo, *tmp;
17548 +
17549 +               need_wh = -ENOMEM;
17550 +               dinfo = au_di(dentry);
17551 +               tmp = au_di_alloc(sb, AuLsc_DI_TMP);
17552 +               if (tmp) {
17553 +                       au_di_cp(tmp, dinfo);
17554 +                       au_di_swap(tmp, dinfo);
17555 +                       /* returns the number of positive dentries */
17556 +                       need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
17557 +                       au_di_swap(tmp, dinfo);
17558 +                       au_rw_write_unlock(&tmp->di_rwsem);
17559 +                       au_di_free(tmp);
17560 +               }
17561 +       }
17562 +       AuDbg("need_wh %d\n", need_wh);
17563 +       err = need_wh;
17564 +
17565 +out:
17566 +       return err;
17567 +}
17568 +
17569 +/*
17570 + * simple tests for the del-entry operations.
17571 + * following the checks in vfs, plus the parent-child relationship.
17572 + */
17573 +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
17574 +              struct dentry *h_parent, int isdir)
17575 +{
17576 +       int err;
17577 +       umode_t h_mode;
17578 +       struct dentry *h_dentry, *h_latest;
17579 +       struct inode *h_inode;
17580 +
17581 +       h_dentry = au_h_dptr(dentry, bindex);
17582 +       h_inode = h_dentry->d_inode;
17583 +       if (dentry->d_inode) {
17584 +               err = -ENOENT;
17585 +               if (unlikely(!h_inode || !h_inode->i_nlink))
17586 +                       goto out;
17587 +
17588 +               h_mode = h_inode->i_mode;
17589 +               if (!isdir) {
17590 +                       err = -EISDIR;
17591 +                       if (unlikely(S_ISDIR(h_mode)))
17592 +                               goto out;
17593 +               } else if (unlikely(!S_ISDIR(h_mode))) {
17594 +                       err = -ENOTDIR;
17595 +                       goto out;
17596 +               }
17597 +       } else {
17598 +               /* rename(2) case */
17599 +               err = -EIO;
17600 +               if (unlikely(h_inode))
17601 +                       goto out;
17602 +       }
17603 +
17604 +       err = -ENOENT;
17605 +       /* expected parent dir is locked */
17606 +       if (unlikely(h_parent != h_dentry->d_parent))
17607 +               goto out;
17608 +       err = 0;
17609 +
17610 +       /*
17611 +        * rmdir a dir may break the consistency on some filesystem.
17612 +        * let's try heavy test.
17613 +        */
17614 +       err = -EACCES;
17615 +       if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
17616 +               goto out;
17617 +
17618 +       h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
17619 +                                  au_sbr(dentry->d_sb, bindex));
17620 +       err = -EIO;
17621 +       if (IS_ERR(h_latest))
17622 +               goto out;
17623 +       if (h_latest == h_dentry)
17624 +               err = 0;
17625 +       dput(h_latest);
17626 +
17627 +out:
17628 +       return err;
17629 +}
17630 +
17631 +/*
17632 + * decide the branch where we operate for @dentry. the branch index will be set
17633 + * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
17634 + * dir for reverting.
17635 + * when a new whiteout is necessary, create it.
17636 + */
17637 +static struct dentry*
17638 +lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
17639 +                   struct au_dtime *dt, struct au_pin *pin)
17640 +{
17641 +       struct dentry *wh_dentry;
17642 +       struct super_block *sb;
17643 +       struct path h_path;
17644 +       int err, need_wh;
17645 +       unsigned int udba;
17646 +       aufs_bindex_t bcpup;
17647 +
17648 +       need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
17649 +       wh_dentry = ERR_PTR(need_wh);
17650 +       if (unlikely(need_wh < 0))
17651 +               goto out;
17652 +
17653 +       sb = dentry->d_sb;
17654 +       udba = au_opt_udba(sb);
17655 +       bcpup = *rbcpup;
17656 +       err = au_pin(pin, dentry, bcpup, udba,
17657 +                    AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17658 +       wh_dentry = ERR_PTR(err);
17659 +       if (unlikely(err))
17660 +               goto out;
17661 +
17662 +       h_path.dentry = au_pinned_h_parent(pin);
17663 +       if (udba != AuOpt_UDBA_NONE
17664 +           && au_dbstart(dentry) == bcpup) {
17665 +               err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
17666 +               wh_dentry = ERR_PTR(err);
17667 +               if (unlikely(err))
17668 +                       goto out_unpin;
17669 +       }
17670 +
17671 +       h_path.mnt = au_sbr_mnt(sb, bcpup);
17672 +       au_dtime_store(dt, au_pinned_parent(pin), &h_path);
17673 +       wh_dentry = NULL;
17674 +       if (!need_wh)
17675 +               goto out; /* success, no need to create whiteout */
17676 +
17677 +       wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
17678 +       if (IS_ERR(wh_dentry))
17679 +               goto out_unpin;
17680 +
17681 +       /* returns with the parent is locked and wh_dentry is dget-ed */
17682 +       goto out; /* success */
17683 +
17684 +out_unpin:
17685 +       au_unpin(pin);
17686 +out:
17687 +       return wh_dentry;
17688 +}
17689 +
17690 +/*
17691 + * when removing a dir, rename it to a unique temporary whiteout-ed name first
17692 + * in order to be revertible and save time for removing many child whiteouts
17693 + * under the dir.
17694 + * returns 1 when there are too many child whiteout and caller should remove
17695 + * them asynchronously. returns 0 when the number of children is enough small to
17696 + * remove now or the branch fs is a remote fs.
17697 + * otherwise return an error.
17698 + */
17699 +static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
17700 +                          struct au_nhash *whlist, struct inode *dir)
17701 +{
17702 +       int rmdir_later, err, dirwh;
17703 +       struct dentry *h_dentry;
17704 +       struct super_block *sb;
17705 +
17706 +       sb = dentry->d_sb;
17707 +       SiMustAnyLock(sb);
17708 +       h_dentry = au_h_dptr(dentry, bindex);
17709 +       err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
17710 +       if (unlikely(err))
17711 +               goto out;
17712 +
17713 +       /* stop monitoring */
17714 +       au_hn_free(au_hi(dentry->d_inode, bindex));
17715 +
17716 +       if (!au_test_fs_remote(h_dentry->d_sb)) {
17717 +               dirwh = au_sbi(sb)->si_dirwh;
17718 +               rmdir_later = (dirwh <= 1);
17719 +               if (!rmdir_later)
17720 +                       rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
17721 +                                                             dirwh);
17722 +               if (rmdir_later)
17723 +                       return rmdir_later;
17724 +       }
17725 +
17726 +       err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
17727 +       if (unlikely(err)) {
17728 +               AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
17729 +                       AuDLNPair(h_dentry), bindex, err);
17730 +               err = 0;
17731 +       }
17732 +
17733 +out:
17734 +       AuTraceErr(err);
17735 +       return err;
17736 +}
17737 +
17738 +/*
17739 + * final procedure for deleting a entry.
17740 + * maintain dentry and iattr.
17741 + */
17742 +static void epilog(struct inode *dir, struct dentry *dentry,
17743 +                  aufs_bindex_t bindex)
17744 +{
17745 +       struct inode *inode;
17746 +
17747 +       inode = dentry->d_inode;
17748 +       d_drop(dentry);
17749 +       inode->i_ctime = dir->i_ctime;
17750 +
17751 +       if (au_ibstart(dir) == bindex)
17752 +               au_cpup_attr_timesizes(dir);
17753 +       dir->i_version++;
17754 +}
17755 +
17756 +/*
17757 + * when an error happened, remove the created whiteout and revert everything.
17758 + */
17759 +static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
17760 +                    aufs_bindex_t bwh, struct dentry *wh_dentry,
17761 +                    struct dentry *dentry, struct au_dtime *dt)
17762 +{
17763 +       int rerr;
17764 +       struct path h_path = {
17765 +               .dentry = wh_dentry,
17766 +               .mnt    = au_sbr_mnt(dir->i_sb, bindex)
17767 +       };
17768 +
17769 +       rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
17770 +       if (!rerr) {
17771 +               au_set_dbwh(dentry, bwh);
17772 +               au_dtime_revert(dt);
17773 +               return 0;
17774 +       }
17775 +
17776 +       AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
17777 +               AuDLNPair(dentry), err, rerr);
17778 +       return -EIO;
17779 +}
17780 +
17781 +/* ---------------------------------------------------------------------- */
17782 +
17783 +int aufs_unlink(struct inode *dir, struct dentry *dentry)
17784 +{
17785 +       int err;
17786 +       aufs_bindex_t bwh, bindex, bstart;
17787 +       struct au_dtime dt;
17788 +       struct au_pin pin;
17789 +       struct path h_path;
17790 +       struct inode *inode, *h_dir;
17791 +       struct dentry *parent, *wh_dentry;
17792 +
17793 +       IMustLock(dir);
17794 +
17795 +       err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17796 +       if (unlikely(err))
17797 +               goto out;
17798 +       err = au_d_hashed_positive(dentry);
17799 +       if (unlikely(err))
17800 +               goto out_unlock;
17801 +       inode = dentry->d_inode;
17802 +       IMustLock(inode);
17803 +       err = -EISDIR;
17804 +       if (unlikely(S_ISDIR(inode->i_mode)))
17805 +               goto out_unlock; /* possible? */
17806 +
17807 +       bstart = au_dbstart(dentry);
17808 +       bwh = au_dbwh(dentry);
17809 +       bindex = -1;
17810 +       parent = dentry->d_parent; /* dir inode is locked */
17811 +       di_write_lock_parent(parent);
17812 +       wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
17813 +       err = PTR_ERR(wh_dentry);
17814 +       if (IS_ERR(wh_dentry))
17815 +               goto out_parent;
17816 +
17817 +       h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
17818 +       h_path.dentry = au_h_dptr(dentry, bstart);
17819 +       dget(h_path.dentry);
17820 +       if (bindex == bstart) {
17821 +               h_dir = au_pinned_h_dir(&pin);
17822 +               err = vfsub_unlink(h_dir, &h_path, /*force*/0);
17823 +       } else {
17824 +               /* dir inode is locked */
17825 +               h_dir = wh_dentry->d_parent->d_inode;
17826 +               IMustLock(h_dir);
17827 +               err = 0;
17828 +       }
17829 +
17830 +       if (!err) {
17831 +               vfsub_drop_nlink(inode);
17832 +               epilog(dir, dentry, bindex);
17833 +
17834 +               /* update target timestamps */
17835 +               if (bindex == bstart) {
17836 +                       vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
17837 +                       inode->i_ctime = h_path.dentry->d_inode->i_ctime;
17838 +               } else
17839 +                       /* todo: this timestamp may be reverted later */
17840 +                       inode->i_ctime = h_dir->i_ctime;
17841 +               goto out_unpin; /* success */
17842 +       }
17843 +
17844 +       /* revert */
17845 +       if (wh_dentry) {
17846 +               int rerr;
17847 +
17848 +               rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
17849 +               if (rerr)
17850 +                       err = rerr;
17851 +       }
17852 +
17853 +out_unpin:
17854 +       au_unpin(&pin);
17855 +       dput(wh_dentry);
17856 +       dput(h_path.dentry);
17857 +out_parent:
17858 +       di_write_unlock(parent);
17859 +out_unlock:
17860 +       aufs_read_unlock(dentry, AuLock_DW);
17861 +out:
17862 +       return err;
17863 +}
17864 +
17865 +int aufs_rmdir(struct inode *dir, struct dentry *dentry)
17866 +{
17867 +       int err, rmdir_later;
17868 +       aufs_bindex_t bwh, bindex, bstart;
17869 +       struct au_dtime dt;
17870 +       struct au_pin pin;
17871 +       struct inode *inode;
17872 +       struct dentry *parent, *wh_dentry, *h_dentry;
17873 +       struct au_whtmp_rmdir *args;
17874 +
17875 +       IMustLock(dir);
17876 +
17877 +       err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
17878 +       if (unlikely(err))
17879 +               goto out;
17880 +       err = au_alive_dir(dentry);
17881 +       if (unlikely(err))
17882 +               goto out_unlock;
17883 +       inode = dentry->d_inode;
17884 +       IMustLock(inode);
17885 +       err = -ENOTDIR;
17886 +       if (unlikely(!S_ISDIR(inode->i_mode)))
17887 +               goto out_unlock; /* possible? */
17888 +
17889 +       err = -ENOMEM;
17890 +       args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
17891 +       if (unlikely(!args))
17892 +               goto out_unlock;
17893 +
17894 +       parent = dentry->d_parent; /* dir inode is locked */
17895 +       di_write_lock_parent(parent);
17896 +       err = au_test_empty(dentry, &args->whlist);
17897 +       if (unlikely(err))
17898 +               goto out_parent;
17899 +
17900 +       bstart = au_dbstart(dentry);
17901 +       bwh = au_dbwh(dentry);
17902 +       bindex = -1;
17903 +       wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
17904 +       err = PTR_ERR(wh_dentry);
17905 +       if (IS_ERR(wh_dentry))
17906 +               goto out_parent;
17907 +
17908 +       h_dentry = au_h_dptr(dentry, bstart);
17909 +       dget(h_dentry);
17910 +       rmdir_later = 0;
17911 +       if (bindex == bstart) {
17912 +               err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
17913 +               if (err > 0) {
17914 +                       rmdir_later = err;
17915 +                       err = 0;
17916 +               }
17917 +       } else {
17918 +               /* stop monitoring */
17919 +               au_hn_free(au_hi(inode, bstart));
17920 +
17921 +               /* dir inode is locked */
17922 +               IMustLock(wh_dentry->d_parent->d_inode);
17923 +               err = 0;
17924 +       }
17925 +
17926 +       if (!err) {
17927 +               vfsub_dead_dir(inode);
17928 +               au_set_dbdiropq(dentry, -1);
17929 +               epilog(dir, dentry, bindex);
17930 +
17931 +               if (rmdir_later) {
17932 +                       au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
17933 +                       args = NULL;
17934 +               }
17935 +
17936 +               goto out_unpin; /* success */
17937 +       }
17938 +
17939 +       /* revert */
17940 +       AuLabel(revert);
17941 +       if (wh_dentry) {
17942 +               int rerr;
17943 +
17944 +               rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
17945 +               if (rerr)
17946 +                       err = rerr;
17947 +       }
17948 +
17949 +out_unpin:
17950 +       au_unpin(&pin);
17951 +       dput(wh_dentry);
17952 +       dput(h_dentry);
17953 +out_parent:
17954 +       di_write_unlock(parent);
17955 +       if (args)
17956 +               au_whtmp_rmdir_free(args);
17957 +out_unlock:
17958 +       aufs_read_unlock(dentry, AuLock_DW);
17959 +out:
17960 +       AuTraceErr(err);
17961 +       return err;
17962 +}
17963 diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
17964 --- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
17965 +++ linux/fs/aufs/i_op_ren.c    2013-07-30 22:42:46.235946055 +0200
17966 @@ -0,0 +1,1045 @@
17967 +/*
17968 + * Copyright (C) 2005-2013 Junjiro R. Okajima
17969 + *
17970 + * This program, aufs is free software; you can redistribute it and/or modify
17971 + * it under the terms of the GNU General Public License as published by
17972 + * the Free Software Foundation; either version 2 of the License, or
17973 + * (at your option) any later version.
17974 + *
17975 + * This program is distributed in the hope that it will be useful,
17976 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17977 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17978 + * GNU General Public License for more details.
17979 + *
17980 + * You should have received a copy of the GNU General Public License
17981 + * along with this program; if not, write to the Free Software
17982 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17983 + */
17984 +
17985 +/*
17986 + * inode operation (rename entry)
17987 + * todo: this is crazy monster
17988 + */
17989 +
17990 +#include "aufs.h"
17991 +
17992 +enum { AuSRC, AuDST, AuSrcDst };
17993 +enum { AuPARENT, AuCHILD, AuParentChild };
17994 +
17995 +#define AuRen_ISDIR    1
17996 +#define AuRen_ISSAMEDIR        (1 << 1)
17997 +#define AuRen_WHSRC    (1 << 2)
17998 +#define AuRen_WHDST    (1 << 3)
17999 +#define AuRen_MNT_WRITE        (1 << 4)
18000 +#define AuRen_DT_DSTDIR        (1 << 5)
18001 +#define AuRen_DIROPQ   (1 << 6)
18002 +#define AuRen_CPUP     (1 << 7)
18003 +#define au_ftest_ren(flags, name)      ((flags) & AuRen_##name)
18004 +#define au_fset_ren(flags, name) \
18005 +       do { (flags) |= AuRen_##name; } while (0)
18006 +#define au_fclr_ren(flags, name) \
18007 +       do { (flags) &= ~AuRen_##name; } while (0)
18008 +
18009 +struct au_ren_args {
18010 +       struct {
18011 +               struct dentry *dentry, *h_dentry, *parent, *h_parent,
18012 +                       *wh_dentry;
18013 +               struct inode *dir, *inode;
18014 +               struct au_hinode *hdir;
18015 +               struct au_dtime dt[AuParentChild];
18016 +               aufs_bindex_t bstart;
18017 +       } sd[AuSrcDst];
18018 +
18019 +#define src_dentry     sd[AuSRC].dentry
18020 +#define src_dir                sd[AuSRC].dir
18021 +#define src_inode      sd[AuSRC].inode
18022 +#define src_h_dentry   sd[AuSRC].h_dentry
18023 +#define src_parent     sd[AuSRC].parent
18024 +#define src_h_parent   sd[AuSRC].h_parent
18025 +#define src_wh_dentry  sd[AuSRC].wh_dentry
18026 +#define src_hdir       sd[AuSRC].hdir
18027 +#define src_h_dir      sd[AuSRC].hdir->hi_inode
18028 +#define src_dt         sd[AuSRC].dt
18029 +#define src_bstart     sd[AuSRC].bstart
18030 +
18031 +#define dst_dentry     sd[AuDST].dentry
18032 +#define dst_dir                sd[AuDST].dir
18033 +#define dst_inode      sd[AuDST].inode
18034 +#define dst_h_dentry   sd[AuDST].h_dentry
18035 +#define dst_parent     sd[AuDST].parent
18036 +#define dst_h_parent   sd[AuDST].h_parent
18037 +#define dst_wh_dentry  sd[AuDST].wh_dentry
18038 +#define dst_hdir       sd[AuDST].hdir
18039 +#define dst_h_dir      sd[AuDST].hdir->hi_inode
18040 +#define dst_dt         sd[AuDST].dt
18041 +#define dst_bstart     sd[AuDST].bstart
18042 +
18043 +       struct dentry *h_trap;
18044 +       struct au_branch *br;
18045 +       struct au_hinode *src_hinode;
18046 +       struct path h_path;
18047 +       struct au_nhash whlist;
18048 +       aufs_bindex_t btgt, src_bwh, src_bdiropq;
18049 +
18050 +       unsigned int flags;
18051 +
18052 +       struct au_whtmp_rmdir *thargs;
18053 +       struct dentry *h_dst;
18054 +};
18055 +
18056 +/* ---------------------------------------------------------------------- */
18057 +
18058 +/*
18059 + * functions for reverting.
18060 + * when an error happened in a single rename systemcall, we should revert
18061 + * everything as if nothing happend.
18062 + * we don't need to revert the copied-up/down the parent dir since they are
18063 + * harmless.
18064 + */
18065 +
18066 +#define RevertFailure(fmt, ...) do { \
18067 +       AuIOErr("revert failure: " fmt " (%d, %d)\n", \
18068 +               ##__VA_ARGS__, err, rerr); \
18069 +       err = -EIO; \
18070 +} while (0)
18071 +
18072 +static void au_ren_rev_diropq(int err, struct au_ren_args *a)
18073 +{
18074 +       int rerr;
18075 +
18076 +       au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18077 +       rerr = au_diropq_remove(a->src_dentry, a->btgt);
18078 +       au_hn_imtx_unlock(a->src_hinode);
18079 +       au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
18080 +       if (rerr)
18081 +               RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
18082 +}
18083 +
18084 +static void au_ren_rev_rename(int err, struct au_ren_args *a)
18085 +{
18086 +       int rerr;
18087 +
18088 +       a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
18089 +                                         a->src_h_parent);
18090 +       rerr = PTR_ERR(a->h_path.dentry);
18091 +       if (IS_ERR(a->h_path.dentry)) {
18092 +               RevertFailure("lkup one %.*s", AuDLNPair(a->src_dentry));
18093 +               return;
18094 +       }
18095 +
18096 +       rerr = vfsub_rename(a->dst_h_dir,
18097 +                           au_h_dptr(a->src_dentry, a->btgt),
18098 +                           a->src_h_dir, &a->h_path);
18099 +       d_drop(a->h_path.dentry);
18100 +       dput(a->h_path.dentry);
18101 +       /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
18102 +       if (rerr)
18103 +               RevertFailure("rename %.*s", AuDLNPair(a->src_dentry));
18104 +}
18105 +
18106 +static void au_ren_rev_cpup(int err, struct au_ren_args *a)
18107 +{
18108 +       int rerr;
18109 +
18110 +       a->h_path.dentry = a->dst_h_dentry;
18111 +       rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0);
18112 +       au_set_h_dptr(a->src_dentry, a->btgt, NULL);
18113 +       au_set_dbstart(a->src_dentry, a->src_bstart);
18114 +       if (rerr)
18115 +               RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry));
18116 +}
18117 +
18118 +static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
18119 +{
18120 +       int rerr;
18121 +
18122 +       a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
18123 +                                         a->dst_h_parent);
18124 +       rerr = PTR_ERR(a->h_path.dentry);
18125 +       if (IS_ERR(a->h_path.dentry)) {
18126 +               RevertFailure("lkup one %.*s", AuDLNPair(a->dst_dentry));
18127 +               return;
18128 +       }
18129 +       if (a->h_path.dentry->d_inode) {
18130 +               d_drop(a->h_path.dentry);
18131 +               dput(a->h_path.dentry);
18132 +               return;
18133 +       }
18134 +
18135 +       rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path);
18136 +       d_drop(a->h_path.dentry);
18137 +       dput(a->h_path.dentry);
18138 +       if (!rerr)
18139 +               au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
18140 +       else
18141 +               RevertFailure("rename %.*s", AuDLNPair(a->h_dst));
18142 +}
18143 +
18144 +static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
18145 +{
18146 +       int rerr;
18147 +
18148 +       a->h_path.dentry = a->src_wh_dentry;
18149 +       rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
18150 +       au_set_dbwh(a->src_dentry, a->src_bwh);
18151 +       if (rerr)
18152 +               RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
18153 +}
18154 +#undef RevertFailure
18155 +
18156 +/* ---------------------------------------------------------------------- */
18157 +
18158 +/*
18159 + * when we have to copyup the renaming entry, do it with the rename-target name
18160 + * in order to minimize the cost (the later actual rename is unnecessary).
18161 + * otherwise rename it on the target branch.
18162 + */
18163 +static int au_ren_or_cpup(struct au_ren_args *a)
18164 +{
18165 +       int err;
18166 +       struct dentry *d;
18167 +
18168 +       d = a->src_dentry;
18169 +       if (au_dbstart(d) == a->btgt) {
18170 +               a->h_path.dentry = a->dst_h_dentry;
18171 +               if (au_ftest_ren(a->flags, DIROPQ)
18172 +                   && au_dbdiropq(d) == a->btgt)
18173 +                       au_fclr_ren(a->flags, DIROPQ);
18174 +               AuDebugOn(au_dbstart(d) != a->btgt);
18175 +               err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
18176 +                                  a->dst_h_dir, &a->h_path);
18177 +       } else {
18178 +#if 1
18179 +               BUG();
18180 +#else
18181 +               struct file *h_file;
18182 +
18183 +               au_fset_ren(a->flags, CPUP);
18184 +               au_set_dbstart(d, a->btgt);
18185 +               au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry));
18186 +               h_file = au_h_open_pre(d, a->src_bstart);
18187 +               if (IS_ERR(h_file))
18188 +                       err = PTR_ERR(h_file);
18189 +               else {
18190 +                       err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1,
18191 +                                                !AuCpup_DTIME, a->dst_parent);
18192 +                       au_h_open_post(d, a->src_bstart, h_file);
18193 +               }
18194 +               if (!err) {
18195 +                       d = a->dst_dentry;
18196 +                       au_set_h_dptr(d, a->btgt, NULL);
18197 +                       au_update_dbstart(d);
18198 +               } else {
18199 +                       au_set_h_dptr(d, a->btgt, NULL);
18200 +                       au_set_dbstart(d, a->src_bstart);
18201 +               }
18202 +#endif
18203 +       }
18204 +       if (!err && a->h_dst)
18205 +               /* it will be set to dinfo later */
18206 +               dget(a->h_dst);
18207 +
18208 +       return err;
18209 +}
18210 +
18211 +/* cf. aufs_rmdir() */
18212 +static int au_ren_del_whtmp(struct au_ren_args *a)
18213 +{
18214 +       int err;
18215 +       struct inode *dir;
18216 +
18217 +       dir = a->dst_dir;
18218 +       SiMustAnyLock(dir->i_sb);
18219 +       if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
18220 +                                    au_sbi(dir->i_sb)->si_dirwh)
18221 +           || au_test_fs_remote(a->h_dst->d_sb)) {
18222 +               err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
18223 +               if (unlikely(err))
18224 +                       pr_warn("failed removing whtmp dir %.*s (%d), "
18225 +                               "ignored.\n", AuDLNPair(a->h_dst), err);
18226 +       } else {
18227 +               au_nhash_wh_free(&a->thargs->whlist);
18228 +               a->thargs->whlist = a->whlist;
18229 +               a->whlist.nh_num = 0;
18230 +               au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
18231 +               dput(a->h_dst);
18232 +               a->thargs = NULL;
18233 +       }
18234 +
18235 +       return 0;
18236 +}
18237 +
18238 +/* make it 'opaque' dir. */
18239 +static int au_ren_diropq(struct au_ren_args *a)
18240 +{
18241 +       int err;
18242 +       struct dentry *diropq;
18243 +
18244 +       err = 0;
18245 +       a->src_bdiropq = au_dbdiropq(a->src_dentry);
18246 +       a->src_hinode = au_hi(a->src_inode, a->btgt);
18247 +       au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18248 +       diropq = au_diropq_create(a->src_dentry, a->btgt);
18249 +       au_hn_imtx_unlock(a->src_hinode);
18250 +       if (IS_ERR(diropq))
18251 +               err = PTR_ERR(diropq);
18252 +       dput(diropq);
18253 +
18254 +       return err;
18255 +}
18256 +
18257 +static int do_rename(struct au_ren_args *a)
18258 +{
18259 +       int err;
18260 +       struct dentry *d, *h_d;
18261 +
18262 +       /* prepare workqueue args for asynchronous rmdir */
18263 +       h_d = a->dst_h_dentry;
18264 +       if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
18265 +               err = -ENOMEM;
18266 +               a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
18267 +               if (unlikely(!a->thargs))
18268 +                       goto out;
18269 +               a->h_dst = dget(h_d);
18270 +       }
18271 +
18272 +       /* create whiteout for src_dentry */
18273 +       if (au_ftest_ren(a->flags, WHSRC)) {
18274 +               a->src_bwh = au_dbwh(a->src_dentry);
18275 +               AuDebugOn(a->src_bwh >= 0);
18276 +               a->src_wh_dentry
18277 +                       = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
18278 +               err = PTR_ERR(a->src_wh_dentry);
18279 +               if (IS_ERR(a->src_wh_dentry))
18280 +                       goto out_thargs;
18281 +       }
18282 +
18283 +       /* lookup whiteout for dentry */
18284 +       if (au_ftest_ren(a->flags, WHDST)) {
18285 +               h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
18286 +                                a->br);
18287 +               err = PTR_ERR(h_d);
18288 +               if (IS_ERR(h_d))
18289 +                       goto out_whsrc;
18290 +               if (!h_d->d_inode)
18291 +                       dput(h_d);
18292 +               else
18293 +                       a->dst_wh_dentry = h_d;
18294 +       }
18295 +
18296 +       /* rename dentry to tmpwh */
18297 +       if (a->thargs) {
18298 +               err = au_whtmp_ren(a->dst_h_dentry, a->br);
18299 +               if (unlikely(err))
18300 +                       goto out_whdst;
18301 +
18302 +               d = a->dst_dentry;
18303 +               au_set_h_dptr(d, a->btgt, NULL);
18304 +               err = au_lkup_neg(d, a->btgt, /*wh*/0);
18305 +               if (unlikely(err))
18306 +                       goto out_whtmp;
18307 +               a->dst_h_dentry = au_h_dptr(d, a->btgt);
18308 +       }
18309 +
18310 +       /* cpup src */
18311 +       if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) {
18312 +#if 1
18313 +               BUG();
18314 +#else
18315 +               struct file *h_file;
18316 +
18317 +               h_file = au_h_open_pre(a->src_dentry, a->src_bstart);
18318 +               if (IS_ERR(h_file))
18319 +                       err = PTR_ERR(h_file);
18320 +               else {
18321 +                       err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1,
18322 +                                                !AuCpup_DTIME);
18323 +                       au_h_open_post(a->src_dentry, a->src_bstart, h_file);
18324 +               }
18325 +               if (unlikely(err))
18326 +                       goto out_whtmp;
18327 +#endif
18328 +       }
18329 +
18330 +       /* rename by vfs_rename or cpup */
18331 +       d = a->dst_dentry;
18332 +       if (au_ftest_ren(a->flags, ISDIR)
18333 +           && (a->dst_wh_dentry
18334 +               || au_dbdiropq(d) == a->btgt
18335 +               /* hide the lower to keep xino */
18336 +               || a->btgt < au_dbend(d)
18337 +               || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
18338 +               au_fset_ren(a->flags, DIROPQ);
18339 +       err = au_ren_or_cpup(a);
18340 +       if (unlikely(err))
18341 +               /* leave the copied-up one */
18342 +               goto out_whtmp;
18343 +
18344 +       /* make dir opaque */
18345 +       if (au_ftest_ren(a->flags, DIROPQ)) {
18346 +               err = au_ren_diropq(a);
18347 +               if (unlikely(err))
18348 +                       goto out_rename;
18349 +       }
18350 +
18351 +       /* update target timestamps */
18352 +       AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
18353 +       a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
18354 +       vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
18355 +       a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
18356 +
18357 +       /* remove whiteout for dentry */
18358 +       if (a->dst_wh_dentry) {
18359 +               a->h_path.dentry = a->dst_wh_dentry;
18360 +               err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
18361 +                                         a->dst_dentry);
18362 +               if (unlikely(err))
18363 +                       goto out_diropq;
18364 +       }
18365 +
18366 +       /* remove whtmp */
18367 +       if (a->thargs)
18368 +               au_ren_del_whtmp(a); /* ignore this error */
18369 +
18370 +       err = 0;
18371 +       goto out_success;
18372 +
18373 +out_diropq:
18374 +       if (au_ftest_ren(a->flags, DIROPQ))
18375 +               au_ren_rev_diropq(err, a);
18376 +out_rename:
18377 +       if (!au_ftest_ren(a->flags, CPUP))
18378 +               au_ren_rev_rename(err, a);
18379 +       else
18380 +               au_ren_rev_cpup(err, a);
18381 +       dput(a->h_dst);
18382 +out_whtmp:
18383 +       if (a->thargs)
18384 +               au_ren_rev_whtmp(err, a);
18385 +out_whdst:
18386 +       dput(a->dst_wh_dentry);
18387 +       a->dst_wh_dentry = NULL;
18388 +out_whsrc:
18389 +       if (a->src_wh_dentry)
18390 +               au_ren_rev_whsrc(err, a);
18391 +out_success:
18392 +       dput(a->src_wh_dentry);
18393 +       dput(a->dst_wh_dentry);
18394 +out_thargs:
18395 +       if (a->thargs) {
18396 +               dput(a->h_dst);
18397 +               au_whtmp_rmdir_free(a->thargs);
18398 +               a->thargs = NULL;
18399 +       }
18400 +out:
18401 +       return err;
18402 +}
18403 +
18404 +/* ---------------------------------------------------------------------- */
18405 +
18406 +/*
18407 + * test if @dentry dir can be rename destination or not.
18408 + * success means, it is a logically empty dir.
18409 + */
18410 +static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
18411 +{
18412 +       return au_test_empty(dentry, whlist);
18413 +}
18414 +
18415 +/*
18416 + * test if @dentry dir can be rename source or not.
18417 + * if it can, return 0 and @children is filled.
18418 + * success means,
18419 + * - it is a logically empty dir.
18420 + * - or, it exists on writable branch and has no children including whiteouts
18421 + *       on the lower branch.
18422 + */
18423 +static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
18424 +{
18425 +       int err;
18426 +       unsigned int rdhash;
18427 +       aufs_bindex_t bstart;
18428 +
18429 +       bstart = au_dbstart(dentry);
18430 +       if (bstart != btgt) {
18431 +               struct au_nhash whlist;
18432 +
18433 +               SiMustAnyLock(dentry->d_sb);
18434 +               rdhash = au_sbi(dentry->d_sb)->si_rdhash;
18435 +               if (!rdhash)
18436 +                       rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
18437 +                                                          dentry));
18438 +               err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
18439 +               if (unlikely(err))
18440 +                       goto out;
18441 +               err = au_test_empty(dentry, &whlist);
18442 +               au_nhash_wh_free(&whlist);
18443 +               goto out;
18444 +       }
18445 +
18446 +       if (bstart == au_dbtaildir(dentry))
18447 +               return 0; /* success */
18448 +
18449 +       err = au_test_empty_lower(dentry);
18450 +
18451 +out:
18452 +       if (err == -ENOTEMPTY) {
18453 +               AuWarn1("renaming dir who has child(ren) on multiple branches,"
18454 +                       " is not supported\n");
18455 +               err = -EXDEV;
18456 +       }
18457 +       return err;
18458 +}
18459 +
18460 +/* side effect: sets whlist and h_dentry */
18461 +static int au_ren_may_dir(struct au_ren_args *a)
18462 +{
18463 +       int err;
18464 +       unsigned int rdhash;
18465 +       struct dentry *d;
18466 +
18467 +       d = a->dst_dentry;
18468 +       SiMustAnyLock(d->d_sb);
18469 +
18470 +       err = 0;
18471 +       if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
18472 +               rdhash = au_sbi(d->d_sb)->si_rdhash;
18473 +               if (!rdhash)
18474 +                       rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
18475 +               err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
18476 +               if (unlikely(err))
18477 +                       goto out;
18478 +
18479 +               au_set_dbstart(d, a->dst_bstart);
18480 +               err = may_rename_dstdir(d, &a->whlist);
18481 +               au_set_dbstart(d, a->btgt);
18482 +       }
18483 +       a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
18484 +       if (unlikely(err))
18485 +               goto out;
18486 +
18487 +       d = a->src_dentry;
18488 +       a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
18489 +       if (au_ftest_ren(a->flags, ISDIR)) {
18490 +               err = may_rename_srcdir(d, a->btgt);
18491 +               if (unlikely(err)) {
18492 +                       au_nhash_wh_free(&a->whlist);
18493 +                       a->whlist.nh_num = 0;
18494 +               }
18495 +       }
18496 +out:
18497 +       return err;
18498 +}
18499 +
18500 +/* ---------------------------------------------------------------------- */
18501 +
18502 +/*
18503 + * simple tests for rename.
18504 + * following the checks in vfs, plus the parent-child relationship.
18505 + */
18506 +static int au_may_ren(struct au_ren_args *a)
18507 +{
18508 +       int err, isdir;
18509 +       struct inode *h_inode;
18510 +
18511 +       if (a->src_bstart == a->btgt) {
18512 +               err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
18513 +                                au_ftest_ren(a->flags, ISDIR));
18514 +               if (unlikely(err))
18515 +                       goto out;
18516 +               err = -EINVAL;
18517 +               if (unlikely(a->src_h_dentry == a->h_trap))
18518 +                       goto out;
18519 +       }
18520 +
18521 +       err = 0;
18522 +       if (a->dst_bstart != a->btgt)
18523 +               goto out;
18524 +
18525 +       err = -ENOTEMPTY;
18526 +       if (unlikely(a->dst_h_dentry == a->h_trap))
18527 +               goto out;
18528 +
18529 +       err = -EIO;
18530 +       h_inode = a->dst_h_dentry->d_inode;
18531 +       isdir = !!au_ftest_ren(a->flags, ISDIR);
18532 +       if (!a->dst_dentry->d_inode) {
18533 +               if (unlikely(h_inode))
18534 +                       goto out;
18535 +               err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
18536 +                                isdir);
18537 +       } else {
18538 +               if (unlikely(!h_inode || !h_inode->i_nlink))
18539 +                       goto out;
18540 +               err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
18541 +                                isdir);
18542 +               if (unlikely(err))
18543 +                       goto out;
18544 +       }
18545 +
18546 +out:
18547 +       if (unlikely(err == -ENOENT || err == -EEXIST))
18548 +               err = -EIO;
18549 +       AuTraceErr(err);
18550 +       return err;
18551 +}
18552 +
18553 +/* ---------------------------------------------------------------------- */
18554 +
18555 +/*
18556 + * locking order
18557 + * (VFS)
18558 + * - src_dir and dir by lock_rename()
18559 + * - inode if exitsts
18560 + * (aufs)
18561 + * - lock all
18562 + *   + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
18563 + *     + si_read_lock
18564 + *     + di_write_lock2_child()
18565 + *       + di_write_lock_child()
18566 + *        + ii_write_lock_child()
18567 + *       + di_write_lock_child2()
18568 + *        + ii_write_lock_child2()
18569 + *     + src_parent and parent
18570 + *       + di_write_lock_parent()
18571 + *        + ii_write_lock_parent()
18572 + *       + di_write_lock_parent2()
18573 + *        + ii_write_lock_parent2()
18574 + *   + lower src_dir and dir by vfsub_lock_rename()
18575 + *   + verify the every relationships between child and parent. if any
18576 + *     of them failed, unlock all and return -EBUSY.
18577 + */
18578 +static void au_ren_unlock(struct au_ren_args *a)
18579 +{
18580 +       vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
18581 +                           a->dst_h_parent, a->dst_hdir);
18582 +       if (au_ftest_ren(a->flags, MNT_WRITE))
18583 +               vfsub_mnt_drop_write(au_br_mnt(a->br));
18584 +}
18585 +
18586 +static int au_ren_lock(struct au_ren_args *a)
18587 +{
18588 +       int err;
18589 +       unsigned int udba;
18590 +
18591 +       err = 0;
18592 +       a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
18593 +       a->src_hdir = au_hi(a->src_dir, a->btgt);
18594 +       a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
18595 +       a->dst_hdir = au_hi(a->dst_dir, a->btgt);
18596 +
18597 +       err = vfsub_mnt_want_write(au_br_mnt(a->br));
18598 +       if (unlikely(err))
18599 +               goto out;
18600 +       au_fset_ren(a->flags, MNT_WRITE);
18601 +       a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
18602 +                                     a->dst_h_parent, a->dst_hdir);
18603 +       udba = au_opt_udba(a->src_dentry->d_sb);
18604 +       if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
18605 +                    || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
18606 +               err = au_busy_or_stale();
18607 +       if (!err && au_dbstart(a->src_dentry) == a->btgt)
18608 +               err = au_h_verify(a->src_h_dentry, udba,
18609 +                                 a->src_h_parent->d_inode, a->src_h_parent,
18610 +                                 a->br);
18611 +       if (!err && au_dbstart(a->dst_dentry) == a->btgt)
18612 +               err = au_h_verify(a->dst_h_dentry, udba,
18613 +                                 a->dst_h_parent->d_inode, a->dst_h_parent,
18614 +                                 a->br);
18615 +       if (!err)
18616 +               goto out; /* success */
18617 +
18618 +       err = au_busy_or_stale();
18619 +       au_ren_unlock(a);
18620 +
18621 +out:
18622 +       return err;
18623 +}
18624 +
18625 +/* ---------------------------------------------------------------------- */
18626 +
18627 +static void au_ren_refresh_dir(struct au_ren_args *a)
18628 +{
18629 +       struct inode *dir;
18630 +
18631 +       dir = a->dst_dir;
18632 +       dir->i_version++;
18633 +       if (au_ftest_ren(a->flags, ISDIR)) {
18634 +               /* is this updating defined in POSIX? */
18635 +               au_cpup_attr_timesizes(a->src_inode);
18636 +               au_cpup_attr_nlink(dir, /*force*/1);
18637 +       }
18638 +
18639 +       if (au_ibstart(dir) == a->btgt)
18640 +               au_cpup_attr_timesizes(dir);
18641 +
18642 +       if (au_ftest_ren(a->flags, ISSAMEDIR))
18643 +               return;
18644 +
18645 +       dir = a->src_dir;
18646 +       dir->i_version++;
18647 +       if (au_ftest_ren(a->flags, ISDIR))
18648 +               au_cpup_attr_nlink(dir, /*force*/1);
18649 +       if (au_ibstart(dir) == a->btgt)
18650 +               au_cpup_attr_timesizes(dir);
18651 +}
18652 +
18653 +static void au_ren_refresh(struct au_ren_args *a)
18654 +{
18655 +       aufs_bindex_t bend, bindex;
18656 +       struct dentry *d, *h_d;
18657 +       struct inode *i, *h_i;
18658 +       struct super_block *sb;
18659 +
18660 +       d = a->dst_dentry;
18661 +       d_drop(d);
18662 +       if (a->h_dst)
18663 +               /* already dget-ed by au_ren_or_cpup() */
18664 +               au_set_h_dptr(d, a->btgt, a->h_dst);
18665 +
18666 +       i = a->dst_inode;
18667 +       if (i) {
18668 +               if (!au_ftest_ren(a->flags, ISDIR))
18669 +                       vfsub_drop_nlink(i);
18670 +               else {
18671 +                       vfsub_dead_dir(i);
18672 +                       au_cpup_attr_timesizes(i);
18673 +               }
18674 +               au_update_dbrange(d, /*do_put_zero*/1);
18675 +       } else {
18676 +               bend = a->btgt;
18677 +               for (bindex = au_dbstart(d); bindex < bend; bindex++)
18678 +                       au_set_h_dptr(d, bindex, NULL);
18679 +               bend = au_dbend(d);
18680 +               for (bindex = a->btgt + 1; bindex <= bend; bindex++)
18681 +                       au_set_h_dptr(d, bindex, NULL);
18682 +               au_update_dbrange(d, /*do_put_zero*/0);
18683 +       }
18684 +
18685 +       d = a->src_dentry;
18686 +       au_set_dbwh(d, -1);
18687 +       bend = au_dbend(d);
18688 +       for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18689 +               h_d = au_h_dptr(d, bindex);
18690 +               if (h_d)
18691 +                       au_set_h_dptr(d, bindex, NULL);
18692 +       }
18693 +       au_set_dbend(d, a->btgt);
18694 +
18695 +       sb = d->d_sb;
18696 +       i = a->src_inode;
18697 +       if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
18698 +               return; /* success */
18699 +
18700 +       bend = au_ibend(i);
18701 +       for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
18702 +               h_i = au_h_iptr(i, bindex);
18703 +               if (h_i) {
18704 +                       au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
18705 +                       /* ignore this error */
18706 +                       au_set_h_iptr(i, bindex, NULL, 0);
18707 +               }
18708 +       }
18709 +       au_set_ibend(i, a->btgt);
18710 +}
18711 +
18712 +/* ---------------------------------------------------------------------- */
18713 +
18714 +/* mainly for link(2) and rename(2) */
18715 +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
18716 +{
18717 +       aufs_bindex_t bdiropq, bwh;
18718 +       struct dentry *parent;
18719 +       struct au_branch *br;
18720 +
18721 +       parent = dentry->d_parent;
18722 +       IMustLock(parent->d_inode); /* dir is locked */
18723 +
18724 +       bdiropq = au_dbdiropq(parent);
18725 +       bwh = au_dbwh(dentry);
18726 +       br = au_sbr(dentry->d_sb, btgt);
18727 +       if (au_br_rdonly(br)
18728 +           || (0 <= bdiropq && bdiropq < btgt)
18729 +           || (0 <= bwh && bwh < btgt))
18730 +               btgt = -1;
18731 +
18732 +       AuDbg("btgt %d\n", btgt);
18733 +       return btgt;
18734 +}
18735 +
18736 +/* sets src_bstart, dst_bstart and btgt */
18737 +static int au_ren_wbr(struct au_ren_args *a)
18738 +{
18739 +       int err;
18740 +       struct au_wr_dir_args wr_dir_args = {
18741 +               /* .force_btgt  = -1, */
18742 +               .flags          = AuWrDir_ADD_ENTRY
18743 +       };
18744 +
18745 +       a->src_bstart = au_dbstart(a->src_dentry);
18746 +       a->dst_bstart = au_dbstart(a->dst_dentry);
18747 +       if (au_ftest_ren(a->flags, ISDIR))
18748 +               au_fset_wrdir(wr_dir_args.flags, ISDIR);
18749 +       wr_dir_args.force_btgt = a->src_bstart;
18750 +       if (a->dst_inode && a->dst_bstart < a->src_bstart)
18751 +               wr_dir_args.force_btgt = a->dst_bstart;
18752 +       wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
18753 +       err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
18754 +       a->btgt = err;
18755 +
18756 +       return err;
18757 +}
18758 +
18759 +static void au_ren_dt(struct au_ren_args *a)
18760 +{
18761 +       a->h_path.dentry = a->src_h_parent;
18762 +       au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
18763 +       if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
18764 +               a->h_path.dentry = a->dst_h_parent;
18765 +               au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
18766 +       }
18767 +
18768 +       au_fclr_ren(a->flags, DT_DSTDIR);
18769 +       if (!au_ftest_ren(a->flags, ISDIR))
18770 +               return;
18771 +
18772 +       a->h_path.dentry = a->src_h_dentry;
18773 +       au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
18774 +       if (a->dst_h_dentry->d_inode) {
18775 +               au_fset_ren(a->flags, DT_DSTDIR);
18776 +               a->h_path.dentry = a->dst_h_dentry;
18777 +               au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
18778 +       }
18779 +}
18780 +
18781 +static void au_ren_rev_dt(int err, struct au_ren_args *a)
18782 +{
18783 +       struct dentry *h_d;
18784 +       struct mutex *h_mtx;
18785 +
18786 +       au_dtime_revert(a->src_dt + AuPARENT);
18787 +       if (!au_ftest_ren(a->flags, ISSAMEDIR))
18788 +               au_dtime_revert(a->dst_dt + AuPARENT);
18789 +
18790 +       if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
18791 +               h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
18792 +               h_mtx = &h_d->d_inode->i_mutex;
18793 +               mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18794 +               au_dtime_revert(a->src_dt + AuCHILD);
18795 +               mutex_unlock(h_mtx);
18796 +
18797 +               if (au_ftest_ren(a->flags, DT_DSTDIR)) {
18798 +                       h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
18799 +                       h_mtx = &h_d->d_inode->i_mutex;
18800 +                       mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18801 +                       au_dtime_revert(a->dst_dt + AuCHILD);
18802 +                       mutex_unlock(h_mtx);
18803 +               }
18804 +       }
18805 +}
18806 +
18807 +/* ---------------------------------------------------------------------- */
18808 +
18809 +int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
18810 +               struct inode *_dst_dir, struct dentry *_dst_dentry)
18811 +{
18812 +       int err, flags;
18813 +       /* reduce stack space */
18814 +       struct au_ren_args *a;
18815 +
18816 +       AuDbg("%.*s, %.*s\n", AuDLNPair(_src_dentry), AuDLNPair(_dst_dentry));
18817 +       IMustLock(_src_dir);
18818 +       IMustLock(_dst_dir);
18819 +
18820 +       err = -ENOMEM;
18821 +       BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
18822 +       a = kzalloc(sizeof(*a), GFP_NOFS);
18823 +       if (unlikely(!a))
18824 +               goto out;
18825 +
18826 +       a->src_dir = _src_dir;
18827 +       a->src_dentry = _src_dentry;
18828 +       a->src_inode = a->src_dentry->d_inode;
18829 +       a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
18830 +       a->dst_dir = _dst_dir;
18831 +       a->dst_dentry = _dst_dentry;
18832 +       a->dst_inode = a->dst_dentry->d_inode;
18833 +       a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
18834 +       if (a->dst_inode) {
18835 +               IMustLock(a->dst_inode);
18836 +               au_igrab(a->dst_inode);
18837 +       }
18838 +
18839 +       err = -ENOTDIR;
18840 +       flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
18841 +       if (S_ISDIR(a->src_inode->i_mode)) {
18842 +               au_fset_ren(a->flags, ISDIR);
18843 +               if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
18844 +                       goto out_free;
18845 +               err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18846 +                                               AuLock_DIR | flags);
18847 +       } else
18848 +               err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18849 +                                               flags);
18850 +       if (unlikely(err))
18851 +               goto out_free;
18852 +
18853 +       err = au_d_hashed_positive(a->src_dentry);
18854 +       if (unlikely(err))
18855 +               goto out_unlock;
18856 +       err = -ENOENT;
18857 +       if (a->dst_inode) {
18858 +               /*
18859 +                * If it is a dir, VFS unhash dst_dentry before this
18860 +                * function. It means we cannot rely upon d_unhashed().
18861 +                */
18862 +               if (unlikely(!a->dst_inode->i_nlink))
18863 +                       goto out_unlock;
18864 +               if (!S_ISDIR(a->dst_inode->i_mode)) {
18865 +                       err = au_d_hashed_positive(a->dst_dentry);
18866 +                       if (unlikely(err))
18867 +                               goto out_unlock;
18868 +               } else if (unlikely(IS_DEADDIR(a->dst_inode)))
18869 +                       goto out_unlock;
18870 +       } else if (unlikely(d_unhashed(a->dst_dentry)))
18871 +               goto out_unlock;
18872 +
18873 +       /*
18874 +        * is it possible?
18875 +        * yes, it happend (in linux-3.3-rcN) but I don't know why.
18876 +        * there may exist a problem somewhere else.
18877 +        */
18878 +       err = -EINVAL;
18879 +       if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
18880 +               goto out_unlock;
18881 +
18882 +       au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
18883 +       di_write_lock_parent(a->dst_parent);
18884 +
18885 +       /* which branch we process */
18886 +       err = au_ren_wbr(a);
18887 +       if (unlikely(err < 0))
18888 +               goto out_parent;
18889 +       a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
18890 +       a->h_path.mnt = au_br_mnt(a->br);
18891 +
18892 +       /* are they available to be renamed */
18893 +       err = au_ren_may_dir(a);
18894 +       if (unlikely(err))
18895 +               goto out_children;
18896 +
18897 +       /* prepare the writable parent dir on the same branch */
18898 +       if (a->dst_bstart == a->btgt) {
18899 +               au_fset_ren(a->flags, WHDST);
18900 +       } else {
18901 +               err = au_cpup_dirs(a->dst_dentry, a->btgt);
18902 +               if (unlikely(err))
18903 +                       goto out_children;
18904 +       }
18905 +
18906 +       if (a->src_dir != a->dst_dir) {
18907 +               /*
18908 +                * this temporary unlock is safe,
18909 +                * because both dir->i_mutex are locked.
18910 +                */
18911 +               di_write_unlock(a->dst_parent);
18912 +               di_write_lock_parent(a->src_parent);
18913 +               err = au_wr_dir_need_wh(a->src_dentry,
18914 +                                       au_ftest_ren(a->flags, ISDIR),
18915 +                                       &a->btgt);
18916 +               di_write_unlock(a->src_parent);
18917 +               di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
18918 +               au_fclr_ren(a->flags, ISSAMEDIR);
18919 +       } else
18920 +               err = au_wr_dir_need_wh(a->src_dentry,
18921 +                                       au_ftest_ren(a->flags, ISDIR),
18922 +                                       &a->btgt);
18923 +       if (unlikely(err < 0))
18924 +               goto out_children;
18925 +       if (err)
18926 +               au_fset_ren(a->flags, WHSRC);
18927 +
18928 +       /* cpup src */
18929 +       if (a->src_bstart != a->btgt) {
18930 +               struct au_pin pin;
18931 +
18932 +               err = au_pin(&pin, a->src_dentry, a->btgt,
18933 +                            au_opt_udba(a->src_dentry->d_sb),
18934 +                            AuPin_DI_LOCKED | AuPin_MNT_WRITE);
18935 +               if (!err) {
18936 +                       AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
18937 +                       err = au_sio_cpup_simple_h_open(a->src_dentry, a->btgt,
18938 +                                                       -1, AuCpup_DTIME, &pin,
18939 +                                                       a->src_bstart);
18940 +                       au_unpin(&pin);
18941 +               }
18942 +               if (unlikely(err))
18943 +                       goto out_children;
18944 +               a->src_bstart = a->btgt;
18945 +               a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
18946 +               au_fset_ren(a->flags, WHSRC);
18947 +       }
18948 +
18949 +       /* lock them all */
18950 +       err = au_ren_lock(a);
18951 +       if (unlikely(err))
18952 +               /* leave the copied-up one */
18953 +               goto out_children;
18954 +
18955 +       if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
18956 +               err = au_may_ren(a);
18957 +       else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
18958 +               err = -ENAMETOOLONG;
18959 +       if (unlikely(err))
18960 +               goto out_hdir;
18961 +
18962 +       /* store timestamps to be revertible */
18963 +       au_ren_dt(a);
18964 +
18965 +       /* here we go */
18966 +       err = do_rename(a);
18967 +       if (unlikely(err))
18968 +               goto out_dt;
18969 +
18970 +       /* update dir attributes */
18971 +       au_ren_refresh_dir(a);
18972 +
18973 +       /* dput/iput all lower dentries */
18974 +       au_ren_refresh(a);
18975 +
18976 +       goto out_hdir; /* success */
18977 +
18978 +out_dt:
18979 +       au_ren_rev_dt(err, a);
18980 +out_hdir:
18981 +       au_ren_unlock(a);
18982 +out_children:
18983 +       au_nhash_wh_free(&a->whlist);
18984 +       if (err && a->dst_inode && a->dst_bstart != a->btgt) {
18985 +               AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
18986 +               au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
18987 +               au_set_dbstart(a->dst_dentry, a->dst_bstart);
18988 +       }
18989 +out_parent:
18990 +       if (!err)
18991 +               d_move(a->src_dentry, a->dst_dentry);
18992 +       else {
18993 +               au_update_dbstart(a->dst_dentry);
18994 +               if (!a->dst_inode)
18995 +                       d_drop(a->dst_dentry);
18996 +       }
18997 +       if (au_ftest_ren(a->flags, ISSAMEDIR))
18998 +               di_write_unlock(a->dst_parent);
18999 +       else
19000 +               di_write_unlock2(a->src_parent, a->dst_parent);
19001 +out_unlock:
19002 +       aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
19003 +out_free:
19004 +       iput(a->dst_inode);
19005 +       if (a->thargs)
19006 +               au_whtmp_rmdir_free(a->thargs);
19007 +       kfree(a);
19008 +out:
19009 +       AuTraceErr(err);
19010 +       return err;
19011 +}
19012 diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
19013 --- /usr/share/empty/fs/aufs/Kconfig    1970-01-01 01:00:00.000000000 +0100
19014 +++ linux/fs/aufs/Kconfig       2013-07-06 13:20:47.736864659 +0200
19015 @@ -0,0 +1,202 @@
19016 +config AUFS_FS
19017 +       tristate "Aufs (Advanced multi layered unification filesystem) support"
19018 +       help
19019 +       Aufs is a stackable unification filesystem such as Unionfs,
19020 +       which unifies several directories and provides a merged single
19021 +       directory.
19022 +       In the early days, aufs was entirely re-designed and
19023 +       re-implemented Unionfs Version 1.x series. Introducing many
19024 +       original ideas, approaches and improvements, it becomes totally
19025 +       different from Unionfs while keeping the basic features.
19026 +
19027 +if AUFS_FS
19028 +choice
19029 +       prompt "Maximum number of branches"
19030 +       default AUFS_BRANCH_MAX_127
19031 +       help
19032 +       Specifies the maximum number of branches (or member directories)
19033 +       in a single aufs. The larger value consumes more system
19034 +       resources and has a minor impact to performance.
19035 +config AUFS_BRANCH_MAX_127
19036 +       bool "127"
19037 +       help
19038 +       Specifies the maximum number of branches (or member directories)
19039 +       in a single aufs. The larger value consumes more system
19040 +       resources and has a minor impact to performance.
19041 +config AUFS_BRANCH_MAX_511
19042 +       bool "511"
19043 +       help
19044 +       Specifies the maximum number of branches (or member directories)
19045 +       in a single aufs. The larger value consumes more system
19046 +       resources and has a minor impact to performance.
19047 +config AUFS_BRANCH_MAX_1023
19048 +       bool "1023"
19049 +       help
19050 +       Specifies the maximum number of branches (or member directories)
19051 +       in a single aufs. The larger value consumes more system
19052 +       resources and has a minor impact to performance.
19053 +config AUFS_BRANCH_MAX_32767
19054 +       bool "32767"
19055 +       help
19056 +       Specifies the maximum number of branches (or member directories)
19057 +       in a single aufs. The larger value consumes more system
19058 +       resources and has a minor impact to performance.
19059 +endchoice
19060 +
19061 +config AUFS_SBILIST
19062 +       bool
19063 +       depends on AUFS_MAGIC_SYSRQ || PROC_FS
19064 +       default y
19065 +       help
19066 +       Automatic configuration for internal use.
19067 +       When aufs supports Magic SysRq or /proc, enabled automatically.
19068 +
19069 +config AUFS_HNOTIFY
19070 +       bool "Detect direct branch access (bypassing aufs)"
19071 +       help
19072 +       If you want to modify files on branches directly, eg. bypassing aufs,
19073 +       and want aufs to detect the changes of them fully, then enable this
19074 +       option and use 'udba=notify' mount option.
19075 +       Currently there is only one available configuration, "fsnotify".
19076 +       It will have a negative impact to the performance.
19077 +       See detail in aufs.5.
19078 +
19079 +choice
19080 +       prompt "method" if AUFS_HNOTIFY
19081 +       default AUFS_HFSNOTIFY
19082 +config AUFS_HFSNOTIFY
19083 +       bool "fsnotify"
19084 +       select FSNOTIFY
19085 +endchoice
19086 +
19087 +config AUFS_EXPORT
19088 +       bool "NFS-exportable aufs"
19089 +       depends on EXPORTFS
19090 +       help
19091 +       If you want to export your mounted aufs via NFS, then enable this
19092 +       option. There are several requirements for this configuration.
19093 +       See detail in aufs.5.
19094 +
19095 +config AUFS_INO_T_64
19096 +       bool
19097 +       depends on AUFS_EXPORT
19098 +       depends on 64BIT && !(ALPHA || S390)
19099 +       default y
19100 +       help
19101 +       Automatic configuration for internal use.
19102 +       /* typedef unsigned long/int __kernel_ino_t */
19103 +       /* alpha and s390x are int */
19104 +
19105 +config AUFS_RDU
19106 +       bool "Readdir in userspace"
19107 +       help
19108 +       Aufs has two methods to provide a merged view for a directory,
19109 +       by a user-space library and by kernel-space natively. The latter
19110 +       is always enabled but sometimes large and slow.
19111 +       If you enable this option, install the library in aufs2-util
19112 +       package, and set some environment variables for your readdir(3),
19113 +       then the work will be handled in user-space which generally
19114 +       shows better performance in most cases.
19115 +       See detail in aufs.5.
19116 +
19117 +config AUFS_PROC_MAP
19118 +       bool "support for /proc/maps and lsof(1)"
19119 +       depends on PROC_FS
19120 +       help
19121 +       When you issue mmap(2) in aufs, it is actually a direct mmap(2)
19122 +       call to the file on the branch fs since the file in aufs is
19123 +       purely virtual. And the file path printed in /proc/maps (and
19124 +       others) will be the path on the branch fs. In most cases, it
19125 +       does no harm. But some utilities like lsof(1) may confuse since
19126 +       the utility or user may expect the file path in aufs to be
19127 +       printed.
19128 +       To address this issue, aufs provides a patch which introduces a
19129 +       new member called vm_prfile into struct vm_are_struct. The patch
19130 +       is meaningless without enabling this configuration since nobody
19131 +       sets the new vm_prfile member.
19132 +       If you don't apply the patch, then enabling this configuration
19133 +       will cause a compile error.
19134 +       This approach is fragile since if someone else make some changes
19135 +       around vm_file, then vm_prfile may not work anymore. As a
19136 +       workaround such case, aufs provides this configuration. If you
19137 +       disable it, then lsof(1) may produce incorrect result but the
19138 +       problem will be gone even if the aufs patch is applied (I hope).
19139 +
19140 +config AUFS_SP_IATTR
19141 +       bool "Respect the attributes (mtime/ctime mainly) of special files"
19142 +       help
19143 +       When you write something to a special file, some attributes of it
19144 +       (mtime/ctime mainly) may be updated. Generally such updates are
19145 +       less important (actually some device drivers and NFS ignore
19146 +       it). But some applications (such like test program) requires
19147 +       such updates. If you need these updates, then enable this
19148 +       configuration which introduces some overhead.
19149 +       Currently this configuration handles FIFO only.
19150 +
19151 +config AUFS_SHWH
19152 +       bool "Show whiteouts"
19153 +       help
19154 +       If you want to make the whiteouts in aufs visible, then enable
19155 +       this option and specify 'shwh' mount option. Although it may
19156 +       sounds like philosophy or something, but in technically it
19157 +       simply shows the name of whiteout with keeping its behaviour.
19158 +
19159 +config AUFS_BR_RAMFS
19160 +       bool "Ramfs (initramfs/rootfs) as an aufs branch"
19161 +       help
19162 +       If you want to use ramfs as an aufs branch fs, then enable this
19163 +       option. Generally tmpfs is recommended.
19164 +       Aufs prohibited them to be a branch fs by default, because
19165 +       initramfs becomes unusable after switch_root or something
19166 +       generally. If you sets initramfs as an aufs branch and boot your
19167 +       system by switch_root, you will meet a problem easily since the
19168 +       files in initramfs may be inaccessible.
19169 +       Unless you are going to use ramfs as an aufs branch fs without
19170 +       switch_root or something, leave it N.
19171 +
19172 +config AUFS_BR_FUSE
19173 +       bool "Fuse fs as an aufs branch"
19174 +       depends on FUSE_FS
19175 +       select AUFS_POLL
19176 +       help
19177 +       If you want to use fuse-based userspace filesystem as an aufs
19178 +       branch fs, then enable this option.
19179 +       It implements the internal poll(2) operation which is
19180 +       implemented by fuse only (curretnly).
19181 +
19182 +config AUFS_POLL
19183 +       bool
19184 +       help
19185 +       Automatic configuration for internal use.
19186 +
19187 +config AUFS_BR_HFSPLUS
19188 +       bool "Hfsplus as an aufs branch"
19189 +       depends on HFSPLUS_FS
19190 +       default y
19191 +       help
19192 +       If you want to use hfsplus fs as an aufs branch fs, then enable
19193 +       this option. This option introduces a small overhead at
19194 +       copying-up a file on hfsplus.
19195 +
19196 +config AUFS_BDEV_LOOP
19197 +       bool
19198 +       depends on BLK_DEV_LOOP
19199 +       default y
19200 +       help
19201 +       Automatic configuration for internal use.
19202 +       Convert =[ym] into =y.
19203 +
19204 +config AUFS_DEBUG
19205 +       bool "Debug aufs"
19206 +       help
19207 +       Enable this to compile aufs internal debug code.
19208 +       It will have a negative impact to the performance.
19209 +
19210 +config AUFS_MAGIC_SYSRQ
19211 +       bool
19212 +       depends on AUFS_DEBUG && MAGIC_SYSRQ
19213 +       default y
19214 +       help
19215 +       Automatic configuration for internal use.
19216 +       When aufs supports Magic SysRq, enabled automatically.
19217 +endif
19218 diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
19219 --- /usr/share/empty/fs/aufs/loop.c     1970-01-01 01:00:00.000000000 +0100
19220 +++ linux/fs/aufs/loop.c        2013-07-30 22:42:55.842946719 +0200
19221 @@ -0,0 +1,135 @@
19222 +/*
19223 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19224 + *
19225 + * This program, aufs is free software; you can redistribute it and/or modify
19226 + * it under the terms of the GNU General Public License as published by
19227 + * the Free Software Foundation; either version 2 of the License, or
19228 + * (at your option) any later version.
19229 + *
19230 + * This program is distributed in the hope that it will be useful,
19231 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19232 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19233 + * GNU General Public License for more details.
19234 + *
19235 + * You should have received a copy of the GNU General Public License
19236 + * along with this program; if not, write to the Free Software
19237 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19238 + */
19239 +
19240 +/*
19241 + * support for loopback block device as a branch
19242 + */
19243 +
19244 +#include <linux/loop.h>
19245 +#include "aufs.h"
19246 +
19247 +/*
19248 + * test if two lower dentries have overlapping branches.
19249 + */
19250 +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
19251 +{
19252 +       struct super_block *h_sb;
19253 +       struct loop_device *l;
19254 +
19255 +       h_sb = h_adding->d_sb;
19256 +       if (MAJOR(h_sb->s_dev) != LOOP_MAJOR)
19257 +               return 0;
19258 +
19259 +       l = h_sb->s_bdev->bd_disk->private_data;
19260 +       h_adding = l->lo_backing_file->f_dentry;
19261 +       /*
19262 +        * h_adding can be local NFS.
19263 +        * in this case aufs cannot detect the loop.
19264 +        */
19265 +       if (unlikely(h_adding->d_sb == sb))
19266 +               return 1;
19267 +       return !!au_test_subdir(h_adding, sb->s_root);
19268 +}
19269 +
19270 +/* true if a kernel thread named 'loop[0-9].*' accesses a file */
19271 +int au_test_loopback_kthread(void)
19272 +{
19273 +       int ret;
19274 +       struct task_struct *tsk = current;
19275 +       char c, comm[sizeof(tsk->comm)];
19276 +
19277 +       ret = 0;
19278 +       if (tsk->flags & PF_KTHREAD) {
19279 +               get_task_comm(comm, tsk);
19280 +               c = comm[4];
19281 +               ret = ('0' <= c && c <= '9'
19282 +                      && !strncmp(comm, "loop", 4));
19283 +       }
19284 +
19285 +       return ret;
19286 +}
19287 +
19288 +/* ---------------------------------------------------------------------- */
19289 +
19290 +#define au_warn_loopback_step  16
19291 +static int au_warn_loopback_nelem = au_warn_loopback_step;
19292 +static unsigned long *au_warn_loopback_array;
19293 +
19294 +void au_warn_loopback(struct super_block *h_sb)
19295 +{
19296 +       int i, new_nelem;
19297 +       unsigned long *a, magic;
19298 +       static DEFINE_SPINLOCK(spin);
19299 +
19300 +       magic = h_sb->s_magic;
19301 +       spin_lock(&spin);
19302 +       a = au_warn_loopback_array;
19303 +       for (i = 0; i < au_warn_loopback_nelem && *a; i++)
19304 +               if (a[i] == magic) {
19305 +                       spin_unlock(&spin);
19306 +                       return;
19307 +               }
19308 +
19309 +       /* h_sb is new to us, print it */
19310 +       if (i < au_warn_loopback_nelem) {
19311 +               a[i] = magic;
19312 +               goto pr;
19313 +       }
19314 +
19315 +       /* expand the array */
19316 +       new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
19317 +       a = au_kzrealloc(au_warn_loopback_array,
19318 +                        au_warn_loopback_nelem * sizeof(unsigned long),
19319 +                        new_nelem * sizeof(unsigned long), GFP_ATOMIC);
19320 +       if (a) {
19321 +               au_warn_loopback_nelem = new_nelem;
19322 +               au_warn_loopback_array = a;
19323 +               a[i] = magic;
19324 +               goto pr;
19325 +       }
19326 +
19327 +       spin_unlock(&spin);
19328 +       AuWarn1("realloc failed, ignored\n");
19329 +       return;
19330 +
19331 +pr:
19332 +       spin_unlock(&spin);
19333 +       pr_warn("you may want to try another patch for loopback file "
19334 +               "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
19335 +}
19336 +
19337 +int au_loopback_init(void)
19338 +{
19339 +       int err;
19340 +       struct super_block *sb __maybe_unused;
19341 +
19342 +       AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
19343 +
19344 +       err = 0;
19345 +       au_warn_loopback_array = kcalloc(au_warn_loopback_step,
19346 +                                        sizeof(unsigned long), GFP_NOFS);
19347 +       if (unlikely(!au_warn_loopback_array))
19348 +               err = -ENOMEM;
19349 +
19350 +       return err;
19351 +}
19352 +
19353 +void au_loopback_fin(void)
19354 +{
19355 +       kfree(au_warn_loopback_array);
19356 +}
19357 diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
19358 --- /usr/share/empty/fs/aufs/loop.h     1970-01-01 01:00:00.000000000 +0100
19359 +++ linux/fs/aufs/loop.h        2013-07-30 22:42:55.842946719 +0200
19360 @@ -0,0 +1,50 @@
19361 +/*
19362 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19363 + *
19364 + * This program, aufs is free software; you can redistribute it and/or modify
19365 + * it under the terms of the GNU General Public License as published by
19366 + * the Free Software Foundation; either version 2 of the License, or
19367 + * (at your option) any later version.
19368 + *
19369 + * This program is distributed in the hope that it will be useful,
19370 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19371 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19372 + * GNU General Public License for more details.
19373 + *
19374 + * You should have received a copy of the GNU General Public License
19375 + * along with this program; if not, write to the Free Software
19376 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19377 + */
19378 +
19379 +/*
19380 + * support for loopback mount as a branch
19381 + */
19382 +
19383 +#ifndef __AUFS_LOOP_H__
19384 +#define __AUFS_LOOP_H__
19385 +
19386 +#ifdef __KERNEL__
19387 +
19388 +struct dentry;
19389 +struct super_block;
19390 +
19391 +#ifdef CONFIG_AUFS_BDEV_LOOP
19392 +/* loop.c */
19393 +int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
19394 +int au_test_loopback_kthread(void);
19395 +void au_warn_loopback(struct super_block *h_sb);
19396 +
19397 +int au_loopback_init(void);
19398 +void au_loopback_fin(void);
19399 +#else
19400 +AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
19401 +          struct dentry *h_adding)
19402 +AuStubInt0(au_test_loopback_kthread, void)
19403 +AuStubVoid(au_warn_loopback, struct super_block *h_sb)
19404 +
19405 +AuStubInt0(au_loopback_init, void)
19406 +AuStubVoid(au_loopback_fin, void)
19407 +#endif /* BLK_DEV_LOOP */
19408 +
19409 +#endif /* __KERNEL__ */
19410 +#endif /* __AUFS_LOOP_H__ */
19411 diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
19412 --- /usr/share/empty/fs/aufs/magic.mk   1970-01-01 01:00:00.000000000 +0100
19413 +++ linux/fs/aufs/magic.mk      2013-07-06 13:20:47.750198454 +0200
19414 @@ -0,0 +1,54 @@
19415 +
19416 +# defined in ${srctree}/fs/fuse/inode.c
19417 +# tristate
19418 +ifdef CONFIG_FUSE_FS
19419 +ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
19420 +endif
19421 +
19422 +# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
19423 +# tristate
19424 +ifdef CONFIG_OCFS2_FS
19425 +ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
19426 +endif
19427 +
19428 +# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
19429 +# tristate
19430 +ifdef CONFIG_OCFS2_FS_O2CB
19431 +ccflags-y += -DDLMFS_MAGIC=0x76a9f425
19432 +endif
19433 +
19434 +# defined in ${srctree}/fs/cifs/cifsfs.c
19435 +# tristate
19436 +ifdef CONFIG_CIFS_FS
19437 +ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
19438 +endif
19439 +
19440 +# defined in ${srctree}/fs/xfs/xfs_sb.h
19441 +# tristate
19442 +ifdef CONFIG_XFS_FS
19443 +ccflags-y += -DXFS_SB_MAGIC=0x58465342
19444 +endif
19445 +
19446 +# defined in ${srctree}/fs/configfs/mount.c
19447 +# tristate
19448 +ifdef CONFIG_CONFIGFS_FS
19449 +ccflags-y += -DCONFIGFS_MAGIC=0x62656570
19450 +endif
19451 +
19452 +# defined in ${srctree}/fs/9p/v9fs.h
19453 +# tristate
19454 +ifdef CONFIG_9P_FS
19455 +ccflags-y += -DV9FS_MAGIC=0x01021997
19456 +endif
19457 +
19458 +# defined in ${srctree}/fs/ubifs/ubifs.h
19459 +# tristate
19460 +ifdef CONFIG_UBIFS_FS
19461 +ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
19462 +endif
19463 +
19464 +# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
19465 +# tristate
19466 +ifdef CONFIG_HFSPLUS_FS
19467 +ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
19468 +endif
19469 diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
19470 --- /usr/share/empty/fs/aufs/Makefile   1970-01-01 01:00:00.000000000 +0100
19471 +++ linux/fs/aufs/Makefile      2013-07-06 13:20:47.736864659 +0200
19472 @@ -0,0 +1,42 @@
19473 +
19474 +include ${src}/magic.mk
19475 +ifeq (${CONFIG_AUFS_FS},m)
19476 +include ${src}/conf.mk
19477 +endif
19478 +-include ${src}/priv_def.mk
19479 +
19480 +# cf. include/linux/kernel.h
19481 +# enable pr_debug
19482 +ccflags-y += -DDEBUG
19483 +# sparse requires the full pathname
19484 +ifdef M
19485 +ccflags-y += -include ${M}/../../include/linux/aufs_type.h
19486 +else
19487 +ccflags-y += -include ${srctree}/include/linux/aufs_type.h
19488 +endif
19489 +
19490 +obj-$(CONFIG_AUFS_FS) += aufs.o
19491 +aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
19492 +       wkq.o vfsub.o dcsub.o \
19493 +       cpup.o whout.o wbr_policy.o \
19494 +       dinfo.o dentry.o \
19495 +       dynop.o \
19496 +       finfo.o file.o f_op.o \
19497 +       dir.o vdir.o \
19498 +       iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
19499 +       ioctl.o
19500 +
19501 +# all are boolean
19502 +aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
19503 +aufs-$(CONFIG_SYSFS) += sysfs.o
19504 +aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
19505 +aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
19506 +aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
19507 +aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
19508 +aufs-$(CONFIG_AUFS_EXPORT) += export.o
19509 +aufs-$(CONFIG_AUFS_POLL) += poll.o
19510 +aufs-$(CONFIG_AUFS_RDU) += rdu.o
19511 +aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
19512 +aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
19513 +aufs-$(CONFIG_AUFS_DEBUG) += debug.o
19514 +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
19515 diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
19516 --- /usr/share/empty/fs/aufs/module.c   1970-01-01 01:00:00.000000000 +0100
19517 +++ linux/fs/aufs/module.c      2013-07-06 13:20:47.750198454 +0200
19518 @@ -0,0 +1,203 @@
19519 +/*
19520 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19521 + *
19522 + * This program, aufs is free software; you can redistribute it and/or modify
19523 + * it under the terms of the GNU General Public License as published by
19524 + * the Free Software Foundation; either version 2 of the License, or
19525 + * (at your option) any later version.
19526 + *
19527 + * This program is distributed in the hope that it will be useful,
19528 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19529 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19530 + * GNU General Public License for more details.
19531 + *
19532 + * You should have received a copy of the GNU General Public License
19533 + * along with this program; if not, write to the Free Software
19534 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19535 + */
19536 +
19537 +/*
19538 + * module global variables and operations
19539 + */
19540 +
19541 +#include <linux/module.h>
19542 +#include <linux/seq_file.h>
19543 +#include "aufs.h"
19544 +
19545 +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
19546 +{
19547 +       if (new_sz <= nused)
19548 +               return p;
19549 +
19550 +       p = krealloc(p, new_sz, gfp);
19551 +       if (p)
19552 +               memset(p + nused, 0, new_sz - nused);
19553 +       return p;
19554 +}
19555 +
19556 +/* ---------------------------------------------------------------------- */
19557 +
19558 +/*
19559 + * aufs caches
19560 + */
19561 +struct kmem_cache *au_cachep[AuCache_Last];
19562 +static int __init au_cache_init(void)
19563 +{
19564 +       au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
19565 +       if (au_cachep[AuCache_DINFO])
19566 +               /* SLAB_DESTROY_BY_RCU */
19567 +               au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
19568 +                                                       au_icntnr_init_once);
19569 +       if (au_cachep[AuCache_ICNTNR])
19570 +               au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
19571 +                                                      au_fi_init_once);
19572 +       if (au_cachep[AuCache_FINFO])
19573 +               au_cachep[AuCache_VDIR] = AuCache(au_vdir);
19574 +       if (au_cachep[AuCache_VDIR])
19575 +               au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
19576 +       if (au_cachep[AuCache_DEHSTR])
19577 +               return 0;
19578 +
19579 +       return -ENOMEM;
19580 +}
19581 +
19582 +static void au_cache_fin(void)
19583 +{
19584 +       int i;
19585 +
19586 +       /*
19587 +        * Make sure all delayed rcu free inodes are flushed before we
19588 +        * destroy cache.
19589 +        */
19590 +       rcu_barrier();
19591 +
19592 +       /* excluding AuCache_HNOTIFY */
19593 +       BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
19594 +       for (i = 0; i < AuCache_HNOTIFY; i++)
19595 +               if (au_cachep[i]) {
19596 +                       kmem_cache_destroy(au_cachep[i]);
19597 +                       au_cachep[i] = NULL;
19598 +               }
19599 +}
19600 +
19601 +/* ---------------------------------------------------------------------- */
19602 +
19603 +int au_dir_roflags;
19604 +
19605 +#ifdef CONFIG_AUFS_SBILIST
19606 +/*
19607 + * iterate_supers_type() doesn't protect us from
19608 + * remounting (branch management)
19609 + */
19610 +struct au_splhead au_sbilist;
19611 +#endif
19612 +
19613 +struct lock_class_key au_lc_key[AuLcKey_Last];
19614 +
19615 +/*
19616 + * functions for module interface.
19617 + */
19618 +MODULE_LICENSE("GPL");
19619 +/* MODULE_LICENSE("GPL v2"); */
19620 +MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
19621 +MODULE_DESCRIPTION(AUFS_NAME
19622 +       " -- Advanced multi layered unification filesystem");
19623 +MODULE_VERSION(AUFS_VERSION);
19624 +MODULE_ALIAS_FS(AUFS_NAME);
19625 +
19626 +/* this module parameter has no meaning when SYSFS is disabled */
19627 +int sysaufs_brs = 1;
19628 +MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
19629 +module_param_named(brs, sysaufs_brs, int, S_IRUGO);
19630 +
19631 +/* ---------------------------------------------------------------------- */
19632 +
19633 +static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
19634 +
19635 +int au_seq_path(struct seq_file *seq, struct path *path)
19636 +{
19637 +       return seq_path(seq, path, au_esc_chars);
19638 +}
19639 +
19640 +/* ---------------------------------------------------------------------- */
19641 +
19642 +static int __init aufs_init(void)
19643 +{
19644 +       int err, i;
19645 +       char *p;
19646 +
19647 +       p = au_esc_chars;
19648 +       for (i = 1; i <= ' '; i++)
19649 +               *p++ = i;
19650 +       *p++ = '\\';
19651 +       *p++ = '\x7f';
19652 +       *p = 0;
19653 +
19654 +       au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
19655 +
19656 +       au_sbilist_init();
19657 +       sysaufs_brs_init();
19658 +       au_debug_init();
19659 +       au_dy_init();
19660 +       err = sysaufs_init();
19661 +       if (unlikely(err))
19662 +               goto out;
19663 +       err = au_procfs_init();
19664 +       if (unlikely(err))
19665 +               goto out_sysaufs;
19666 +       err = au_wkq_init();
19667 +       if (unlikely(err))
19668 +               goto out_procfs;
19669 +       err = au_loopback_init();
19670 +       if (unlikely(err))
19671 +               goto out_wkq;
19672 +       err = au_hnotify_init();
19673 +       if (unlikely(err))
19674 +               goto out_loopback;
19675 +       err = au_sysrq_init();
19676 +       if (unlikely(err))
19677 +               goto out_hin;
19678 +       err = au_cache_init();
19679 +       if (unlikely(err))
19680 +               goto out_sysrq;
19681 +       err = register_filesystem(&aufs_fs_type);
19682 +       if (unlikely(err))
19683 +               goto out_cache;
19684 +       /* since we define pr_fmt, call printk directly */
19685 +       printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
19686 +       goto out; /* success */
19687 +
19688 +out_cache:
19689 +       au_cache_fin();
19690 +out_sysrq:
19691 +       au_sysrq_fin();
19692 +out_hin:
19693 +       au_hnotify_fin();
19694 +out_loopback:
19695 +       au_loopback_fin();
19696 +out_wkq:
19697 +       au_wkq_fin();
19698 +out_procfs:
19699 +       au_procfs_fin();
19700 +out_sysaufs:
19701 +       sysaufs_fin();
19702 +       au_dy_fin();
19703 +out:
19704 +       return err;
19705 +}
19706 +
19707 +static void __exit aufs_exit(void)
19708 +{
19709 +       unregister_filesystem(&aufs_fs_type);
19710 +       au_cache_fin();
19711 +       au_sysrq_fin();
19712 +       au_hnotify_fin();
19713 +       au_loopback_fin();
19714 +       au_wkq_fin();
19715 +       au_procfs_fin();
19716 +       sysaufs_fin();
19717 +       au_dy_fin();
19718 +}
19719 +
19720 +module_init(aufs_init);
19721 +module_exit(aufs_exit);
19722 diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
19723 --- /usr/share/empty/fs/aufs/module.h   1970-01-01 01:00:00.000000000 +0100
19724 +++ linux/fs/aufs/module.h      2013-07-06 13:20:47.750198454 +0200
19725 @@ -0,0 +1,105 @@
19726 +/*
19727 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19728 + *
19729 + * This program, aufs is free software; you can redistribute it and/or modify
19730 + * it under the terms of the GNU General Public License as published by
19731 + * the Free Software Foundation; either version 2 of the License, or
19732 + * (at your option) any later version.
19733 + *
19734 + * This program is distributed in the hope that it will be useful,
19735 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19736 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19737 + * GNU General Public License for more details.
19738 + *
19739 + * You should have received a copy of the GNU General Public License
19740 + * along with this program; if not, write to the Free Software
19741 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19742 + */
19743 +
19744 +/*
19745 + * module initialization and module-global
19746 + */
19747 +
19748 +#ifndef __AUFS_MODULE_H__
19749 +#define __AUFS_MODULE_H__
19750 +
19751 +#ifdef __KERNEL__
19752 +
19753 +#include <linux/slab.h>
19754 +
19755 +struct path;
19756 +struct seq_file;
19757 +
19758 +/* module parameters */
19759 +extern int sysaufs_brs;
19760 +
19761 +/* ---------------------------------------------------------------------- */
19762 +
19763 +extern int au_dir_roflags;
19764 +
19765 +enum {
19766 +       AuLcNonDir_FIINFO,
19767 +       AuLcNonDir_DIINFO,
19768 +       AuLcNonDir_IIINFO,
19769 +
19770 +       AuLcDir_FIINFO,
19771 +       AuLcDir_DIINFO,
19772 +       AuLcDir_IIINFO,
19773 +
19774 +       AuLcSymlink_DIINFO,
19775 +       AuLcSymlink_IIINFO,
19776 +
19777 +       AuLcKey_Last
19778 +};
19779 +extern struct lock_class_key au_lc_key[AuLcKey_Last];
19780 +
19781 +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
19782 +int au_seq_path(struct seq_file *seq, struct path *path);
19783 +
19784 +#ifdef CONFIG_PROC_FS
19785 +/* procfs.c */
19786 +int __init au_procfs_init(void);
19787 +void au_procfs_fin(void);
19788 +#else
19789 +AuStubInt0(au_procfs_init, void);
19790 +AuStubVoid(au_procfs_fin, void);
19791 +#endif
19792 +
19793 +/* ---------------------------------------------------------------------- */
19794 +
19795 +/* kmem cache */
19796 +enum {
19797 +       AuCache_DINFO,
19798 +       AuCache_ICNTNR,
19799 +       AuCache_FINFO,
19800 +       AuCache_VDIR,
19801 +       AuCache_DEHSTR,
19802 +       AuCache_HNOTIFY, /* must be last */
19803 +       AuCache_Last
19804 +};
19805 +
19806 +#define AuCacheFlags           (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
19807 +#define AuCache(type)          KMEM_CACHE(type, AuCacheFlags)
19808 +#define AuCacheCtor(type, ctor)        \
19809 +       kmem_cache_create(#type, sizeof(struct type), \
19810 +                         __alignof__(struct type), AuCacheFlags, ctor)
19811 +
19812 +extern struct kmem_cache *au_cachep[];
19813 +
19814 +#define AuCacheFuncs(name, index) \
19815 +static inline struct au_##name *au_cache_alloc_##name(void) \
19816 +{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
19817 +static inline void au_cache_free_##name(struct au_##name *p) \
19818 +{ kmem_cache_free(au_cachep[AuCache_##index], p); }
19819 +
19820 +AuCacheFuncs(dinfo, DINFO);
19821 +AuCacheFuncs(icntnr, ICNTNR);
19822 +AuCacheFuncs(finfo, FINFO);
19823 +AuCacheFuncs(vdir, VDIR);
19824 +AuCacheFuncs(vdir_dehstr, DEHSTR);
19825 +#ifdef CONFIG_AUFS_HNOTIFY
19826 +AuCacheFuncs(hnotify, HNOTIFY);
19827 +#endif
19828 +
19829 +#endif /* __KERNEL__ */
19830 +#endif /* __AUFS_MODULE_H__ */
19831 diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
19832 --- /usr/share/empty/fs/aufs/opts.c     1970-01-01 01:00:00.000000000 +0100
19833 +++ linux/fs/aufs/opts.c        2013-07-06 13:20:47.753531903 +0200
19834 @@ -0,0 +1,1697 @@
19835 +/*
19836 + * Copyright (C) 2005-2013 Junjiro R. Okajima
19837 + *
19838 + * This program, aufs is free software; you can redistribute it and/or modify
19839 + * it under the terms of the GNU General Public License as published by
19840 + * the Free Software Foundation; either version 2 of the License, or
19841 + * (at your option) any later version.
19842 + *
19843 + * This program is distributed in the hope that it will be useful,
19844 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19845 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19846 + * GNU General Public License for more details.
19847 + *
19848 + * You should have received a copy of the GNU General Public License
19849 + * along with this program; if not, write to the Free Software
19850 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19851 + */
19852 +
19853 +/*
19854 + * mount options/flags
19855 + */
19856 +
19857 +#include <linux/namei.h>
19858 +#include <linux/types.h> /* a distribution requires */
19859 +#include <linux/parser.h>
19860 +#include "aufs.h"
19861 +
19862 +/* ---------------------------------------------------------------------- */
19863 +
19864 +enum {
19865 +       Opt_br,
19866 +       Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
19867 +       Opt_idel, Opt_imod, Opt_ireorder,
19868 +       Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
19869 +       Opt_rdblk_def, Opt_rdhash_def,
19870 +       Opt_xino, Opt_zxino, Opt_noxino,
19871 +       Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
19872 +       Opt_trunc_xino_path, Opt_itrunc_xino,
19873 +       Opt_trunc_xib, Opt_notrunc_xib,
19874 +       Opt_shwh, Opt_noshwh,
19875 +       Opt_plink, Opt_noplink, Opt_list_plink,
19876 +       Opt_udba,
19877 +       Opt_dio, Opt_nodio,
19878 +       /* Opt_lock, Opt_unlock, */
19879 +       Opt_cmd, Opt_cmd_args,
19880 +       Opt_diropq_a, Opt_diropq_w,
19881 +       Opt_warn_perm, Opt_nowarn_perm,
19882 +       Opt_wbr_copyup, Opt_wbr_create,
19883 +       Opt_refrof, Opt_norefrof,
19884 +       Opt_verbose, Opt_noverbose,
19885 +       Opt_sum, Opt_nosum, Opt_wsum,
19886 +       Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
19887 +};
19888 +
19889 +static match_table_t options = {
19890 +       {Opt_br, "br=%s"},
19891 +       {Opt_br, "br:%s"},
19892 +
19893 +       {Opt_add, "add=%d:%s"},
19894 +       {Opt_add, "add:%d:%s"},
19895 +       {Opt_add, "ins=%d:%s"},
19896 +       {Opt_add, "ins:%d:%s"},
19897 +       {Opt_append, "append=%s"},
19898 +       {Opt_append, "append:%s"},
19899 +       {Opt_prepend, "prepend=%s"},
19900 +       {Opt_prepend, "prepend:%s"},
19901 +
19902 +       {Opt_del, "del=%s"},
19903 +       {Opt_del, "del:%s"},
19904 +       /* {Opt_idel, "idel:%d"}, */
19905 +       {Opt_mod, "mod=%s"},
19906 +       {Opt_mod, "mod:%s"},
19907 +       /* {Opt_imod, "imod:%d:%s"}, */
19908 +
19909 +       {Opt_dirwh, "dirwh=%d"},
19910 +
19911 +       {Opt_xino, "xino=%s"},
19912 +       {Opt_noxino, "noxino"},
19913 +       {Opt_trunc_xino, "trunc_xino"},
19914 +       {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
19915 +       {Opt_notrunc_xino, "notrunc_xino"},
19916 +       {Opt_trunc_xino_path, "trunc_xino=%s"},
19917 +       {Opt_itrunc_xino, "itrunc_xino=%d"},
19918 +       /* {Opt_zxino, "zxino=%s"}, */
19919 +       {Opt_trunc_xib, "trunc_xib"},
19920 +       {Opt_notrunc_xib, "notrunc_xib"},
19921 +
19922 +#ifdef CONFIG_PROC_FS
19923 +       {Opt_plink, "plink"},
19924 +#else
19925 +       {Opt_ignore_silent, "plink"},
19926 +#endif
19927 +
19928 +       {Opt_noplink, "noplink"},
19929 +
19930 +#ifdef CONFIG_AUFS_DEBUG
19931 +       {Opt_list_plink, "list_plink"},
19932 +#endif
19933 +
19934 +       {Opt_udba, "udba=%s"},
19935 +
19936 +       {Opt_dio, "dio"},
19937 +       {Opt_nodio, "nodio"},
19938 +
19939 +       {Opt_diropq_a, "diropq=always"},
19940 +       {Opt_diropq_a, "diropq=a"},
19941 +       {Opt_diropq_w, "diropq=whiteouted"},
19942 +       {Opt_diropq_w, "diropq=w"},
19943 +
19944 +       {Opt_warn_perm, "warn_perm"},
19945 +       {Opt_nowarn_perm, "nowarn_perm"},
19946 +
19947 +       /* keep them temporary */
19948 +       {Opt_ignore_silent, "coo=%s"},
19949 +       {Opt_ignore_silent, "nodlgt"},
19950 +       {Opt_ignore_silent, "nodirperm1"},
19951 +       {Opt_ignore_silent, "clean_plink"},
19952 +
19953 +#ifdef CONFIG_AUFS_SHWH
19954 +       {Opt_shwh, "shwh"},
19955 +#endif
19956 +       {Opt_noshwh, "noshwh"},
19957 +
19958 +       {Opt_rendir, "rendir=%d"},
19959 +
19960 +       {Opt_refrof, "refrof"},
19961 +       {Opt_norefrof, "norefrof"},
19962 +
19963 +       {Opt_verbose, "verbose"},
19964 +       {Opt_verbose, "v"},
19965 +       {Opt_noverbose, "noverbose"},
19966 +       {Opt_noverbose, "quiet"},
19967 +       {Opt_noverbose, "q"},
19968 +       {Opt_noverbose, "silent"},
19969 +
19970 +       {Opt_sum, "sum"},
19971 +       {Opt_nosum, "nosum"},
19972 +       {Opt_wsum, "wsum"},
19973 +
19974 +       {Opt_rdcache, "rdcache=%d"},
19975 +       {Opt_rdblk, "rdblk=%d"},
19976 +       {Opt_rdblk_def, "rdblk=def"},
19977 +       {Opt_rdhash, "rdhash=%d"},
19978 +       {Opt_rdhash_def, "rdhash=def"},
19979 +
19980 +       {Opt_wbr_create, "create=%s"},
19981 +       {Opt_wbr_create, "create_policy=%s"},
19982 +       {Opt_wbr_copyup, "cpup=%s"},
19983 +       {Opt_wbr_copyup, "copyup=%s"},
19984 +       {Opt_wbr_copyup, "copyup_policy=%s"},
19985 +
19986 +       /* internal use for the scripts */
19987 +       {Opt_ignore_silent, "si=%s"},
19988 +
19989 +       {Opt_br, "dirs=%s"},
19990 +       {Opt_ignore, "debug=%d"},
19991 +       {Opt_ignore, "delete=whiteout"},
19992 +       {Opt_ignore, "delete=all"},
19993 +       {Opt_ignore, "imap=%s"},
19994 +
19995 +       /* temporary workaround, due to old mount(8)? */
19996 +       {Opt_ignore_silent, "relatime"},
19997 +
19998 +       {Opt_err, NULL}
19999 +};
20000 +
20001 +/* ---------------------------------------------------------------------- */
20002 +
20003 +static const char *au_parser_pattern(int val, struct match_token *token)
20004 +{
20005 +       while (token->pattern) {
20006 +               if (token->token == val)
20007 +                       return token->pattern;
20008 +               token++;
20009 +       }
20010 +       BUG();
20011 +       return "??";
20012 +}
20013 +
20014 +/* ---------------------------------------------------------------------- */
20015 +
20016 +static match_table_t brperm = {
20017 +       {AuBrPerm_RO, AUFS_BRPERM_RO},
20018 +       {AuBrPerm_RR, AUFS_BRPERM_RR},
20019 +       {AuBrPerm_RW, AUFS_BRPERM_RW},
20020 +       {0, NULL}
20021 +};
20022 +
20023 +static match_table_t brattr = {
20024 +       {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
20025 +       {AuBrRAttr_WH, AUFS_BRRATTR_WH},
20026 +       {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
20027 +       {0, NULL}
20028 +};
20029 +
20030 +#define AuBrStr_LONGEST        AUFS_BRPERM_RW \
20031 +       "+" AUFS_BRATTR_UNPIN \
20032 +       "+" AUFS_BRWATTR_NLWH
20033 +
20034 +static int br_attr_val(char *str, match_table_t table, substring_t args[])
20035 +{
20036 +       int attr, v;
20037 +       char *p;
20038 +
20039 +       attr = 0;
20040 +       do {
20041 +               p = strchr(str, '+');
20042 +               if (p)
20043 +                       *p = 0;
20044 +               v = match_token(str, table, args);
20045 +               if (v)
20046 +                       attr |= v;
20047 +               else {
20048 +                       if (p)
20049 +                               *p = '+';
20050 +                       pr_warn("ignored branch attribute %s\n", str);
20051 +                       break;
20052 +               }
20053 +               if (p)
20054 +                       str = p + 1;
20055 +       } while (p);
20056 +
20057 +       return attr;
20058 +}
20059 +
20060 +static int noinline_for_stack br_perm_val(char *perm)
20061 +{
20062 +       int val;
20063 +       char *p, *q;
20064 +       substring_t args[MAX_OPT_ARGS];
20065 +
20066 +       p = strchr(perm, '+');
20067 +       if (p)
20068 +               *p = 0;
20069 +       val = match_token(perm, brperm, args);
20070 +       if (!val) {
20071 +               if (p)
20072 +                       *p = '+';
20073 +               pr_warn("ignored branch permission %s\n", perm);
20074 +               val = AuBrPerm_RO;
20075 +               goto out;
20076 +       }
20077 +       if (!p)
20078 +               goto out;
20079 +
20080 +       p++;
20081 +       while (1) {
20082 +               q = strchr(p, '+');
20083 +               if (q)
20084 +                       *q = 0;
20085 +               val |= br_attr_val(p, brattr, args);
20086 +               if (q) {
20087 +                       *q = '+';
20088 +                       p = q + 1;
20089 +               } else
20090 +                       break;
20091 +       }
20092 +       switch (val & AuBrPerm_Mask) {
20093 +       case AuBrPerm_RO:
20094 +       case AuBrPerm_RR:
20095 +               if (unlikely(val & AuBrWAttr_NoLinkWH)) {
20096 +                       pr_warn("ignored branch attribute %s\n",
20097 +                               AUFS_BRWATTR_NLWH);
20098 +                       val &= ~AuBrWAttr_NoLinkWH;
20099 +               }
20100 +               break;
20101 +       case AuBrPerm_RW:
20102 +               if (unlikely(val & AuBrRAttr_WH)) {
20103 +                       pr_warn("ignored branch attribute %s\n",
20104 +                               AUFS_BRRATTR_WH);
20105 +                       val &= ~AuBrRAttr_WH;
20106 +               }
20107 +               break;
20108 +       }
20109 +
20110 +out:
20111 +       return val;
20112 +}
20113 +
20114 +/* Caller should free the return value */
20115 +char *au_optstr_br_perm(int brperm)
20116 +{
20117 +       char *p, a[sizeof(AuBrStr_LONGEST)];
20118 +       int sz;
20119 +
20120 +#define SetPerm(str) do {                      \
20121 +               sz = sizeof(str);               \
20122 +               memcpy(a, str, sz);             \
20123 +               p = a + sz - 1;                 \
20124 +       } while (0)
20125 +
20126 +#define AppendAttr(flag, str) do {                     \
20127 +               if (brperm & flag) {            \
20128 +                       sz = sizeof(str);       \
20129 +                       *p++ = '+';             \
20130 +                       memcpy(p, str, sz);     \
20131 +                       p += sz - 1;            \
20132 +               }                               \
20133 +       } while (0)
20134 +
20135 +       switch (brperm & AuBrPerm_Mask) {
20136 +       case AuBrPerm_RO:
20137 +               SetPerm(AUFS_BRPERM_RO);
20138 +               break;
20139 +       case AuBrPerm_RR:
20140 +               SetPerm(AUFS_BRPERM_RR);
20141 +               break;
20142 +       case AuBrPerm_RW:
20143 +               SetPerm(AUFS_BRPERM_RW);
20144 +               break;
20145 +       default:
20146 +               AuDebugOn(1);
20147 +       }
20148 +
20149 +       AppendAttr(AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN);
20150 +       AppendAttr(AuBrRAttr_WH, AUFS_BRRATTR_WH);
20151 +       AppendAttr(AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH);
20152 +
20153 +       AuDebugOn(strlen(a) >= sizeof(a));
20154 +       return kstrdup(a, GFP_NOFS);
20155 +#undef SetPerm
20156 +#undef AppendAttr
20157 +}
20158 +
20159 +/* ---------------------------------------------------------------------- */
20160 +
20161 +static match_table_t udbalevel = {
20162 +       {AuOpt_UDBA_REVAL, "reval"},
20163 +       {AuOpt_UDBA_NONE, "none"},
20164 +#ifdef CONFIG_AUFS_HNOTIFY
20165 +       {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
20166 +#ifdef CONFIG_AUFS_HFSNOTIFY
20167 +       {AuOpt_UDBA_HNOTIFY, "fsnotify"},
20168 +#endif
20169 +#endif
20170 +       {-1, NULL}
20171 +};
20172 +
20173 +static int noinline_for_stack udba_val(char *str)
20174 +{
20175 +       substring_t args[MAX_OPT_ARGS];
20176 +
20177 +       return match_token(str, udbalevel, args);
20178 +}
20179 +
20180 +const char *au_optstr_udba(int udba)
20181 +{
20182 +       return au_parser_pattern(udba, (void *)udbalevel);
20183 +}
20184 +
20185 +/* ---------------------------------------------------------------------- */
20186 +
20187 +static match_table_t au_wbr_create_policy = {
20188 +       {AuWbrCreate_TDP, "tdp"},
20189 +       {AuWbrCreate_TDP, "top-down-parent"},
20190 +       {AuWbrCreate_RR, "rr"},
20191 +       {AuWbrCreate_RR, "round-robin"},
20192 +       {AuWbrCreate_MFS, "mfs"},
20193 +       {AuWbrCreate_MFS, "most-free-space"},
20194 +       {AuWbrCreate_MFSV, "mfs:%d"},
20195 +       {AuWbrCreate_MFSV, "most-free-space:%d"},
20196 +
20197 +       {AuWbrCreate_MFSRR, "mfsrr:%d"},
20198 +       {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
20199 +       {AuWbrCreate_PMFS, "pmfs"},
20200 +       {AuWbrCreate_PMFSV, "pmfs:%d"},
20201 +
20202 +       {-1, NULL}
20203 +};
20204 +
20205 +/*
20206 + * cf. linux/lib/parser.c and cmdline.c
20207 + * gave up calling memparse() since it uses simple_strtoull() instead of
20208 + * kstrto...().
20209 + */
20210 +static int noinline_for_stack
20211 +au_match_ull(substring_t *s, unsigned long long *result)
20212 +{
20213 +       int err;
20214 +       unsigned int len;
20215 +       char a[32];
20216 +
20217 +       err = -ERANGE;
20218 +       len = s->to - s->from;
20219 +       if (len + 1 <= sizeof(a)) {
20220 +               memcpy(a, s->from, len);
20221 +               a[len] = '\0';
20222 +               err = kstrtoull(a, 0, result);
20223 +       }
20224 +       return err;
20225 +}
20226 +
20227 +static int au_wbr_mfs_wmark(substring_t *arg, char *str,
20228 +                           struct au_opt_wbr_create *create)
20229 +{
20230 +       int err;
20231 +       unsigned long long ull;
20232 +
20233 +       err = 0;
20234 +       if (!au_match_ull(arg, &ull))
20235 +               create->mfsrr_watermark = ull;
20236 +       else {
20237 +               pr_err("bad integer in %s\n", str);
20238 +               err = -EINVAL;
20239 +       }
20240 +
20241 +       return err;
20242 +}
20243 +
20244 +static int au_wbr_mfs_sec(substring_t *arg, char *str,
20245 +                         struct au_opt_wbr_create *create)
20246 +{
20247 +       int n, err;
20248 +
20249 +       err = 0;
20250 +       if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
20251 +               create->mfs_second = n;
20252 +       else {
20253 +               pr_err("bad integer in %s\n", str);
20254 +               err = -EINVAL;
20255 +       }
20256 +
20257 +       return err;
20258 +}
20259 +
20260 +static int noinline_for_stack
20261 +au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
20262 +{
20263 +       int err, e;
20264 +       substring_t args[MAX_OPT_ARGS];
20265 +
20266 +       err = match_token(str, au_wbr_create_policy, args);
20267 +       create->wbr_create = err;
20268 +       switch (err) {
20269 +       case AuWbrCreate_MFSRRV:
20270 +               e = au_wbr_mfs_wmark(&args[0], str, create);
20271 +               if (!e)
20272 +                       e = au_wbr_mfs_sec(&args[1], str, create);
20273 +               if (unlikely(e))
20274 +                       err = e;
20275 +               break;
20276 +       case AuWbrCreate_MFSRR:
20277 +               e = au_wbr_mfs_wmark(&args[0], str, create);
20278 +               if (unlikely(e)) {
20279 +                       err = e;
20280 +                       break;
20281 +               }
20282 +               /*FALLTHROUGH*/
20283 +       case AuWbrCreate_MFS:
20284 +       case AuWbrCreate_PMFS:
20285 +               create->mfs_second = AUFS_MFS_DEF_SEC;
20286 +               break;
20287 +       case AuWbrCreate_MFSV:
20288 +       case AuWbrCreate_PMFSV:
20289 +               e = au_wbr_mfs_sec(&args[0], str, create);
20290 +               if (unlikely(e))
20291 +                       err = e;
20292 +               break;
20293 +       }
20294 +
20295 +       return err;
20296 +}
20297 +
20298 +const char *au_optstr_wbr_create(int wbr_create)
20299 +{
20300 +       return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
20301 +}
20302 +
20303 +static match_table_t au_wbr_copyup_policy = {
20304 +       {AuWbrCopyup_TDP, "tdp"},
20305 +       {AuWbrCopyup_TDP, "top-down-parent"},
20306 +       {AuWbrCopyup_BUP, "bup"},
20307 +       {AuWbrCopyup_BUP, "bottom-up-parent"},
20308 +       {AuWbrCopyup_BU, "bu"},
20309 +       {AuWbrCopyup_BU, "bottom-up"},
20310 +       {-1, NULL}
20311 +};
20312 +
20313 +static int noinline_for_stack au_wbr_copyup_val(char *str)
20314 +{
20315 +       substring_t args[MAX_OPT_ARGS];
20316 +
20317 +       return match_token(str, au_wbr_copyup_policy, args);
20318 +}
20319 +
20320 +const char *au_optstr_wbr_copyup(int wbr_copyup)
20321 +{
20322 +       return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
20323 +}
20324 +
20325 +/* ---------------------------------------------------------------------- */
20326 +
20327 +static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
20328 +
20329 +static void dump_opts(struct au_opts *opts)
20330 +{
20331 +#ifdef CONFIG_AUFS_DEBUG
20332 +       /* reduce stack space */
20333 +       union {
20334 +               struct au_opt_add *add;
20335 +               struct au_opt_del *del;
20336 +               struct au_opt_mod *mod;
20337 +               struct au_opt_xino *xino;
20338 +               struct au_opt_xino_itrunc *xino_itrunc;
20339 +               struct au_opt_wbr_create *create;
20340 +       } u;
20341 +       struct au_opt *opt;
20342 +
20343 +       opt = opts->opt;
20344 +       while (opt->type != Opt_tail) {
20345 +               switch (opt->type) {
20346 +               case Opt_add:
20347 +                       u.add = &opt->add;
20348 +                       AuDbg("add {b%d, %s, 0x%x, %p}\n",
20349 +                                 u.add->bindex, u.add->pathname, u.add->perm,
20350 +                                 u.add->path.dentry);
20351 +                       break;
20352 +               case Opt_del:
20353 +               case Opt_idel:
20354 +                       u.del = &opt->del;
20355 +                       AuDbg("del {%s, %p}\n",
20356 +                             u.del->pathname, u.del->h_path.dentry);
20357 +                       break;
20358 +               case Opt_mod:
20359 +               case Opt_imod:
20360 +                       u.mod = &opt->mod;
20361 +                       AuDbg("mod {%s, 0x%x, %p}\n",
20362 +                                 u.mod->path, u.mod->perm, u.mod->h_root);
20363 +                       break;
20364 +               case Opt_append:
20365 +                       u.add = &opt->add;
20366 +                       AuDbg("append {b%d, %s, 0x%x, %p}\n",
20367 +                                 u.add->bindex, u.add->pathname, u.add->perm,
20368 +                                 u.add->path.dentry);
20369 +                       break;
20370 +               case Opt_prepend:
20371 +                       u.add = &opt->add;
20372 +                       AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
20373 +                                 u.add->bindex, u.add->pathname, u.add->perm,
20374 +                                 u.add->path.dentry);
20375 +                       break;
20376 +               case Opt_dirwh:
20377 +                       AuDbg("dirwh %d\n", opt->dirwh);
20378 +                       break;
20379 +               case Opt_rdcache:
20380 +                       AuDbg("rdcache %d\n", opt->rdcache);
20381 +                       break;
20382 +               case Opt_rdblk:
20383 +                       AuDbg("rdblk %u\n", opt->rdblk);
20384 +                       break;
20385 +               case Opt_rdblk_def:
20386 +                       AuDbg("rdblk_def\n");
20387 +                       break;
20388 +               case Opt_rdhash:
20389 +                       AuDbg("rdhash %u\n", opt->rdhash);
20390 +                       break;
20391 +               case Opt_rdhash_def:
20392 +                       AuDbg("rdhash_def\n");
20393 +                       break;
20394 +               case Opt_xino:
20395 +                       u.xino = &opt->xino;
20396 +                       AuDbg("xino {%s %.*s}\n",
20397 +                                 u.xino->path,
20398 +                                 AuDLNPair(u.xino->file->f_dentry));
20399 +                       break;
20400 +               case Opt_trunc_xino:
20401 +                       AuLabel(trunc_xino);
20402 +                       break;
20403 +               case Opt_notrunc_xino:
20404 +                       AuLabel(notrunc_xino);
20405 +                       break;
20406 +               case Opt_trunc_xino_path:
20407 +               case Opt_itrunc_xino:
20408 +                       u.xino_itrunc = &opt->xino_itrunc;
20409 +                       AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
20410 +                       break;
20411 +
20412 +               case Opt_noxino:
20413 +                       AuLabel(noxino);
20414 +                       break;
20415 +               case Opt_trunc_xib:
20416 +                       AuLabel(trunc_xib);
20417 +                       break;
20418 +               case Opt_notrunc_xib:
20419 +                       AuLabel(notrunc_xib);
20420 +                       break;
20421 +               case Opt_shwh:
20422 +                       AuLabel(shwh);
20423 +                       break;
20424 +               case Opt_noshwh:
20425 +                       AuLabel(noshwh);
20426 +                       break;
20427 +               case Opt_plink:
20428 +                       AuLabel(plink);
20429 +                       break;
20430 +               case Opt_noplink:
20431 +                       AuLabel(noplink);
20432 +                       break;
20433 +               case Opt_list_plink:
20434 +                       AuLabel(list_plink);
20435 +                       break;
20436 +               case Opt_udba:
20437 +                       AuDbg("udba %d, %s\n",
20438 +                                 opt->udba, au_optstr_udba(opt->udba));
20439 +                       break;
20440 +               case Opt_dio:
20441 +                       AuLabel(dio);
20442 +                       break;
20443 +               case Opt_nodio:
20444 +                       AuLabel(nodio);
20445 +                       break;
20446 +               case Opt_diropq_a:
20447 +                       AuLabel(diropq_a);
20448 +                       break;
20449 +               case Opt_diropq_w:
20450 +                       AuLabel(diropq_w);
20451 +                       break;
20452 +               case Opt_warn_perm:
20453 +                       AuLabel(warn_perm);
20454 +                       break;
20455 +               case Opt_nowarn_perm:
20456 +                       AuLabel(nowarn_perm);
20457 +                       break;
20458 +               case Opt_refrof:
20459 +                       AuLabel(refrof);
20460 +                       break;
20461 +               case Opt_norefrof:
20462 +                       AuLabel(norefrof);
20463 +                       break;
20464 +               case Opt_verbose:
20465 +                       AuLabel(verbose);
20466 +                       break;
20467 +               case Opt_noverbose:
20468 +                       AuLabel(noverbose);
20469 +                       break;
20470 +               case Opt_sum:
20471 +                       AuLabel(sum);
20472 +                       break;
20473 +               case Opt_nosum:
20474 +                       AuLabel(nosum);
20475 +                       break;
20476 +               case Opt_wsum:
20477 +                       AuLabel(wsum);
20478 +                       break;
20479 +               case Opt_wbr_create:
20480 +                       u.create = &opt->wbr_create;
20481 +                       AuDbg("create %d, %s\n", u.create->wbr_create,
20482 +                                 au_optstr_wbr_create(u.create->wbr_create));
20483 +                       switch (u.create->wbr_create) {
20484 +                       case AuWbrCreate_MFSV:
20485 +                       case AuWbrCreate_PMFSV:
20486 +                               AuDbg("%d sec\n", u.create->mfs_second);
20487 +                               break;
20488 +                       case AuWbrCreate_MFSRR:
20489 +                               AuDbg("%llu watermark\n",
20490 +                                         u.create->mfsrr_watermark);
20491 +                               break;
20492 +                       case AuWbrCreate_MFSRRV:
20493 +                               AuDbg("%llu watermark, %d sec\n",
20494 +                                         u.create->mfsrr_watermark,
20495 +                                         u.create->mfs_second);
20496 +                               break;
20497 +                       }
20498 +                       break;
20499 +               case Opt_wbr_copyup:
20500 +                       AuDbg("copyup %d, %s\n", opt->wbr_copyup,
20501 +                                 au_optstr_wbr_copyup(opt->wbr_copyup));
20502 +                       break;
20503 +               default:
20504 +                       BUG();
20505 +               }
20506 +               opt++;
20507 +       }
20508 +#endif
20509 +}
20510 +
20511 +void au_opts_free(struct au_opts *opts)
20512 +{
20513 +       struct au_opt *opt;
20514 +
20515 +       opt = opts->opt;
20516 +       while (opt->type != Opt_tail) {
20517 +               switch (opt->type) {
20518 +               case Opt_add:
20519 +               case Opt_append:
20520 +               case Opt_prepend:
20521 +                       path_put(&opt->add.path);
20522 +                       break;
20523 +               case Opt_del:
20524 +               case Opt_idel:
20525 +                       path_put(&opt->del.h_path);
20526 +                       break;
20527 +               case Opt_mod:
20528 +               case Opt_imod:
20529 +                       dput(opt->mod.h_root);
20530 +                       break;
20531 +               case Opt_xino:
20532 +                       fput(opt->xino.file);
20533 +                       break;
20534 +               }
20535 +               opt++;
20536 +       }
20537 +}
20538 +
20539 +static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
20540 +                  aufs_bindex_t bindex)
20541 +{
20542 +       int err;
20543 +       struct au_opt_add *add = &opt->add;
20544 +       char *p;
20545 +
20546 +       add->bindex = bindex;
20547 +       add->perm = AuBrPerm_RO;
20548 +       add->pathname = opt_str;
20549 +       p = strchr(opt_str, '=');
20550 +       if (p) {
20551 +               *p++ = 0;
20552 +               if (*p)
20553 +                       add->perm = br_perm_val(p);
20554 +       }
20555 +
20556 +       err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
20557 +       if (!err) {
20558 +               if (!p) {
20559 +                       add->perm = AuBrPerm_RO;
20560 +                       if (au_test_fs_rr(add->path.dentry->d_sb))
20561 +                               add->perm = AuBrPerm_RR;
20562 +                       else if (!bindex && !(sb_flags & MS_RDONLY))
20563 +                               add->perm = AuBrPerm_RW;
20564 +               }
20565 +               opt->type = Opt_add;
20566 +               goto out;
20567 +       }
20568 +       pr_err("lookup failed %s (%d)\n", add->pathname, err);
20569 +       err = -EINVAL;
20570 +
20571 +out:
20572 +       return err;
20573 +}
20574 +
20575 +static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
20576 +{
20577 +       int err;
20578 +
20579 +       del->pathname = args[0].from;
20580 +       AuDbg("del path %s\n", del->pathname);
20581 +
20582 +       err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
20583 +       if (unlikely(err))
20584 +               pr_err("lookup failed %s (%d)\n", del->pathname, err);
20585 +
20586 +       return err;
20587 +}
20588 +
20589 +#if 0 /* reserved for future use */
20590 +static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
20591 +                             struct au_opt_del *del, substring_t args[])
20592 +{
20593 +       int err;
20594 +       struct dentry *root;
20595 +
20596 +       err = -EINVAL;
20597 +       root = sb->s_root;
20598 +       aufs_read_lock(root, AuLock_FLUSH);
20599 +       if (bindex < 0 || au_sbend(sb) < bindex) {
20600 +               pr_err("out of bounds, %d\n", bindex);
20601 +               goto out;
20602 +       }
20603 +
20604 +       err = 0;
20605 +       del->h_path.dentry = dget(au_h_dptr(root, bindex));
20606 +       del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
20607 +
20608 +out:
20609 +       aufs_read_unlock(root, !AuLock_IR);
20610 +       return err;
20611 +}
20612 +#endif
20613 +
20614 +static int noinline_for_stack
20615 +au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
20616 +{
20617 +       int err;
20618 +       struct path path;
20619 +       char *p;
20620 +
20621 +       err = -EINVAL;
20622 +       mod->path = args[0].from;
20623 +       p = strchr(mod->path, '=');
20624 +       if (unlikely(!p)) {
20625 +               pr_err("no permssion %s\n", args[0].from);
20626 +               goto out;
20627 +       }
20628 +
20629 +       *p++ = 0;
20630 +       err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
20631 +       if (unlikely(err)) {
20632 +               pr_err("lookup failed %s (%d)\n", mod->path, err);
20633 +               goto out;
20634 +       }
20635 +
20636 +       mod->perm = br_perm_val(p);
20637 +       AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
20638 +       mod->h_root = dget(path.dentry);
20639 +       path_put(&path);
20640 +
20641 +out:
20642 +       return err;
20643 +}
20644 +
20645 +#if 0 /* reserved for future use */
20646 +static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
20647 +                             struct au_opt_mod *mod, substring_t args[])
20648 +{
20649 +       int err;
20650 +       struct dentry *root;
20651 +
20652 +       err = -EINVAL;
20653 +       root = sb->s_root;
20654 +       aufs_read_lock(root, AuLock_FLUSH);
20655 +       if (bindex < 0 || au_sbend(sb) < bindex) {
20656 +               pr_err("out of bounds, %d\n", bindex);
20657 +               goto out;
20658 +       }
20659 +
20660 +       err = 0;
20661 +       mod->perm = br_perm_val(args[1].from);
20662 +       AuDbg("mod path %s, perm 0x%x, %s\n",
20663 +             mod->path, mod->perm, args[1].from);
20664 +       mod->h_root = dget(au_h_dptr(root, bindex));
20665 +
20666 +out:
20667 +       aufs_read_unlock(root, !AuLock_IR);
20668 +       return err;
20669 +}
20670 +#endif
20671 +
20672 +static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
20673 +                             substring_t args[])
20674 +{
20675 +       int err;
20676 +       struct file *file;
20677 +
20678 +       file = au_xino_create(sb, args[0].from, /*silent*/0);
20679 +       err = PTR_ERR(file);
20680 +       if (IS_ERR(file))
20681 +               goto out;
20682 +
20683 +       err = -EINVAL;
20684 +       if (unlikely(file->f_dentry->d_sb == sb)) {
20685 +               fput(file);
20686 +               pr_err("%s must be outside\n", args[0].from);
20687 +               goto out;
20688 +       }
20689 +
20690 +       err = 0;
20691 +       xino->file = file;
20692 +       xino->path = args[0].from;
20693 +
20694 +out:
20695 +       return err;
20696 +}
20697 +
20698 +static int noinline_for_stack
20699 +au_opts_parse_xino_itrunc_path(struct super_block *sb,
20700 +                              struct au_opt_xino_itrunc *xino_itrunc,
20701 +                              substring_t args[])
20702 +{
20703 +       int err;
20704 +       aufs_bindex_t bend, bindex;
20705 +       struct path path;
20706 +       struct dentry *root;
20707 +
20708 +       err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
20709 +       if (unlikely(err)) {
20710 +               pr_err("lookup failed %s (%d)\n", args[0].from, err);
20711 +               goto out;
20712 +       }
20713 +
20714 +       xino_itrunc->bindex = -1;
20715 +       root = sb->s_root;
20716 +       aufs_read_lock(root, AuLock_FLUSH);
20717 +       bend = au_sbend(sb);
20718 +       for (bindex = 0; bindex <= bend; bindex++) {
20719 +               if (au_h_dptr(root, bindex) == path.dentry) {
20720 +                       xino_itrunc->bindex = bindex;
20721 +                       break;
20722 +               }
20723 +       }
20724 +       aufs_read_unlock(root, !AuLock_IR);
20725 +       path_put(&path);
20726 +
20727 +       if (unlikely(xino_itrunc->bindex < 0)) {
20728 +               pr_err("no such branch %s\n", args[0].from);
20729 +               err = -EINVAL;
20730 +       }
20731 +
20732 +out:
20733 +       return err;
20734 +}
20735 +
20736 +/* called without aufs lock */
20737 +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
20738 +{
20739 +       int err, n, token;
20740 +       aufs_bindex_t bindex;
20741 +       unsigned char skipped;
20742 +       struct dentry *root;
20743 +       struct au_opt *opt, *opt_tail;
20744 +       char *opt_str;
20745 +       /* reduce the stack space */
20746 +       union {
20747 +               struct au_opt_xino_itrunc *xino_itrunc;
20748 +               struct au_opt_wbr_create *create;
20749 +       } u;
20750 +       struct {
20751 +               substring_t args[MAX_OPT_ARGS];
20752 +       } *a;
20753 +
20754 +       err = -ENOMEM;
20755 +       a = kmalloc(sizeof(*a), GFP_NOFS);
20756 +       if (unlikely(!a))
20757 +               goto out;
20758 +
20759 +       root = sb->s_root;
20760 +       err = 0;
20761 +       bindex = 0;
20762 +       opt = opts->opt;
20763 +       opt_tail = opt + opts->max_opt - 1;
20764 +       opt->type = Opt_tail;
20765 +       while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
20766 +               err = -EINVAL;
20767 +               skipped = 0;
20768 +               token = match_token(opt_str, options, a->args);
20769 +               switch (token) {
20770 +               case Opt_br:
20771 +                       err = 0;
20772 +                       while (!err && (opt_str = strsep(&a->args[0].from, ":"))
20773 +                              && *opt_str) {
20774 +                               err = opt_add(opt, opt_str, opts->sb_flags,
20775 +                                             bindex++);
20776 +                               if (unlikely(!err && ++opt > opt_tail)) {
20777 +                                       err = -E2BIG;
20778 +                                       break;
20779 +                               }
20780 +                               opt->type = Opt_tail;
20781 +                               skipped = 1;
20782 +                       }
20783 +                       break;
20784 +               case Opt_add:
20785 +                       if (unlikely(match_int(&a->args[0], &n))) {
20786 +                               pr_err("bad integer in %s\n", opt_str);
20787 +                               break;
20788 +                       }
20789 +                       bindex = n;
20790 +                       err = opt_add(opt, a->args[1].from, opts->sb_flags,
20791 +                                     bindex);
20792 +                       if (!err)
20793 +                               opt->type = token;
20794 +                       break;
20795 +               case Opt_append:
20796 +                       err = opt_add(opt, a->args[0].from, opts->sb_flags,
20797 +                                     /*dummy bindex*/1);
20798 +                       if (!err)
20799 +                               opt->type = token;
20800 +                       break;
20801 +               case Opt_prepend:
20802 +                       err = opt_add(opt, a->args[0].from, opts->sb_flags,
20803 +                                     /*bindex*/0);
20804 +                       if (!err)
20805 +                               opt->type = token;
20806 +                       break;
20807 +               case Opt_del:
20808 +                       err = au_opts_parse_del(&opt->del, a->args);
20809 +                       if (!err)
20810 +                               opt->type = token;
20811 +                       break;
20812 +#if 0 /* reserved for future use */
20813 +               case Opt_idel:
20814 +                       del->pathname = "(indexed)";
20815 +                       if (unlikely(match_int(&args[0], &n))) {
20816 +                               pr_err("bad integer in %s\n", opt_str);
20817 +                               break;
20818 +                       }
20819 +                       err = au_opts_parse_idel(sb, n, &opt->del, a->args);
20820 +                       if (!err)
20821 +                               opt->type = token;
20822 +                       break;
20823 +#endif
20824 +               case Opt_mod:
20825 +                       err = au_opts_parse_mod(&opt->mod, a->args);
20826 +                       if (!err)
20827 +                               opt->type = token;
20828 +                       break;
20829 +#ifdef IMOD /* reserved for future use */
20830 +               case Opt_imod:
20831 +                       u.mod->path = "(indexed)";
20832 +                       if (unlikely(match_int(&a->args[0], &n))) {
20833 +                               pr_err("bad integer in %s\n", opt_str);
20834 +                               break;
20835 +                       }
20836 +                       err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
20837 +                       if (!err)
20838 +                               opt->type = token;
20839 +                       break;
20840 +#endif
20841 +               case Opt_xino:
20842 +                       err = au_opts_parse_xino(sb, &opt->xino, a->args);
20843 +                       if (!err)
20844 +                               opt->type = token;
20845 +                       break;
20846 +
20847 +               case Opt_trunc_xino_path:
20848 +                       err = au_opts_parse_xino_itrunc_path
20849 +                               (sb, &opt->xino_itrunc, a->args);
20850 +                       if (!err)
20851 +                               opt->type = token;
20852 +                       break;
20853 +
20854 +               case Opt_itrunc_xino:
20855 +                       u.xino_itrunc = &opt->xino_itrunc;
20856 +                       if (unlikely(match_int(&a->args[0], &n))) {
20857 +                               pr_err("bad integer in %s\n", opt_str);
20858 +                               break;
20859 +                       }
20860 +                       u.xino_itrunc->bindex = n;
20861 +                       aufs_read_lock(root, AuLock_FLUSH);
20862 +                       if (n < 0 || au_sbend(sb) < n) {
20863 +                               pr_err("out of bounds, %d\n", n);
20864 +                               aufs_read_unlock(root, !AuLock_IR);
20865 +                               break;
20866 +                       }
20867 +                       aufs_read_unlock(root, !AuLock_IR);
20868 +                       err = 0;
20869 +                       opt->type = token;
20870 +                       break;
20871 +
20872 +               case Opt_dirwh:
20873 +                       if (unlikely(match_int(&a->args[0], &opt->dirwh)))
20874 +                               break;
20875 +                       err = 0;
20876 +                       opt->type = token;
20877 +                       break;
20878 +
20879 +               case Opt_rdcache:
20880 +                       if (unlikely(match_int(&a->args[0], &n))) {
20881 +                               pr_err("bad integer in %s\n", opt_str);
20882 +                               break;
20883 +                       }
20884 +                       if (unlikely(n > AUFS_RDCACHE_MAX)) {
20885 +                               pr_err("rdcache must be smaller than %d\n",
20886 +                                      AUFS_RDCACHE_MAX);
20887 +                               break;
20888 +                       }
20889 +                       opt->rdcache = n;
20890 +                       err = 0;
20891 +                       opt->type = token;
20892 +                       break;
20893 +               case Opt_rdblk:
20894 +                       if (unlikely(match_int(&a->args[0], &n)
20895 +                                    || n < 0
20896 +                                    || n > KMALLOC_MAX_SIZE)) {
20897 +                               pr_err("bad integer in %s\n", opt_str);
20898 +                               break;
20899 +                       }
20900 +                       if (unlikely(n && n < NAME_MAX)) {
20901 +                               pr_err("rdblk must be larger than %d\n",
20902 +                                      NAME_MAX);
20903 +                               break;
20904 +                       }
20905 +                       opt->rdblk = n;
20906 +                       err = 0;
20907 +                       opt->type = token;
20908 +                       break;
20909 +               case Opt_rdhash:
20910 +                       if (unlikely(match_int(&a->args[0], &n)
20911 +                                    || n < 0
20912 +                                    || n * sizeof(struct hlist_head)
20913 +                                    > KMALLOC_MAX_SIZE)) {
20914 +                               pr_err("bad integer in %s\n", opt_str);
20915 +                               break;
20916 +                       }
20917 +                       opt->rdhash = n;
20918 +                       err = 0;
20919 +                       opt->type = token;
20920 +                       break;
20921 +
20922 +               case Opt_trunc_xino:
20923 +               case Opt_notrunc_xino:
20924 +               case Opt_noxino:
20925 +               case Opt_trunc_xib:
20926 +               case Opt_notrunc_xib:
20927 +               case Opt_shwh:
20928 +               case Opt_noshwh:
20929 +               case Opt_plink:
20930 +               case Opt_noplink:
20931 +               case Opt_list_plink:
20932 +               case Opt_dio:
20933 +               case Opt_nodio:
20934 +               case Opt_diropq_a:
20935 +               case Opt_diropq_w:
20936 +               case Opt_warn_perm:
20937 +               case Opt_nowarn_perm:
20938 +               case Opt_refrof:
20939 +               case Opt_norefrof:
20940 +               case Opt_verbose:
20941 +               case Opt_noverbose:
20942 +               case Opt_sum:
20943 +               case Opt_nosum:
20944 +               case Opt_wsum:
20945 +               case Opt_rdblk_def:
20946 +               case Opt_rdhash_def:
20947 +                       err = 0;
20948 +                       opt->type = token;
20949 +                       break;
20950 +
20951 +               case Opt_udba:
20952 +                       opt->udba = udba_val(a->args[0].from);
20953 +                       if (opt->udba >= 0) {
20954 +                               err = 0;
20955 +                               opt->type = token;
20956 +                       } else
20957 +                               pr_err("wrong value, %s\n", opt_str);
20958 +                       break;
20959 +
20960 +               case Opt_wbr_create:
20961 +                       u.create = &opt->wbr_create;
20962 +                       u.create->wbr_create
20963 +                               = au_wbr_create_val(a->args[0].from, u.create);
20964 +                       if (u.create->wbr_create >= 0) {
20965 +                               err = 0;
20966 +                               opt->type = token;
20967 +                       } else
20968 +                               pr_err("wrong value, %s\n", opt_str);
20969 +                       break;
20970 +               case Opt_wbr_copyup:
20971 +                       opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
20972 +                       if (opt->wbr_copyup >= 0) {
20973 +                               err = 0;
20974 +                               opt->type = token;
20975 +                       } else
20976 +                               pr_err("wrong value, %s\n", opt_str);
20977 +                       break;
20978 +
20979 +               case Opt_ignore:
20980 +                       pr_warn("ignored %s\n", opt_str);
20981 +                       /*FALLTHROUGH*/
20982 +               case Opt_ignore_silent:
20983 +                       skipped = 1;
20984 +                       err = 0;
20985 +                       break;
20986 +               case Opt_err:
20987 +                       pr_err("unknown option %s\n", opt_str);
20988 +                       break;
20989 +               }
20990 +
20991 +               if (!err && !skipped) {
20992 +                       if (unlikely(++opt > opt_tail)) {
20993 +                               err = -E2BIG;
20994 +                               opt--;
20995 +                               opt->type = Opt_tail;
20996 +                               break;
20997 +                       }
20998 +                       opt->type = Opt_tail;
20999 +               }
21000 +       }
21001 +
21002 +       kfree(a);
21003 +       dump_opts(opts);
21004 +       if (unlikely(err))
21005 +               au_opts_free(opts);
21006 +
21007 +out:
21008 +       return err;
21009 +}
21010 +
21011 +static int au_opt_wbr_create(struct super_block *sb,
21012 +                            struct au_opt_wbr_create *create)
21013 +{
21014 +       int err;
21015 +       struct au_sbinfo *sbinfo;
21016 +
21017 +       SiMustWriteLock(sb);
21018 +
21019 +       err = 1; /* handled */
21020 +       sbinfo = au_sbi(sb);
21021 +       if (sbinfo->si_wbr_create_ops->fin) {
21022 +               err = sbinfo->si_wbr_create_ops->fin(sb);
21023 +               if (!err)
21024 +                       err = 1;
21025 +       }
21026 +
21027 +       sbinfo->si_wbr_create = create->wbr_create;
21028 +       sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
21029 +       switch (create->wbr_create) {
21030 +       case AuWbrCreate_MFSRRV:
21031 +       case AuWbrCreate_MFSRR:
21032 +               sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
21033 +               /*FALLTHROUGH*/
21034 +       case AuWbrCreate_MFS:
21035 +       case AuWbrCreate_MFSV:
21036 +       case AuWbrCreate_PMFS:
21037 +       case AuWbrCreate_PMFSV:
21038 +               sbinfo->si_wbr_mfs.mfs_expire
21039 +                       = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
21040 +               break;
21041 +       }
21042 +
21043 +       if (sbinfo->si_wbr_create_ops->init)
21044 +               sbinfo->si_wbr_create_ops->init(sb); /* ignore */
21045 +
21046 +       return err;
21047 +}
21048 +
21049 +/*
21050 + * returns,
21051 + * plus: processed without an error
21052 + * zero: unprocessed
21053 + */
21054 +static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
21055 +                        struct au_opts *opts)
21056 +{
21057 +       int err;
21058 +       struct au_sbinfo *sbinfo;
21059 +
21060 +       SiMustWriteLock(sb);
21061 +
21062 +       err = 1; /* handled */
21063 +       sbinfo = au_sbi(sb);
21064 +       switch (opt->type) {
21065 +       case Opt_udba:
21066 +               sbinfo->si_mntflags &= ~AuOptMask_UDBA;
21067 +               sbinfo->si_mntflags |= opt->udba;
21068 +               opts->given_udba |= opt->udba;
21069 +               break;
21070 +
21071 +       case Opt_plink:
21072 +               au_opt_set(sbinfo->si_mntflags, PLINK);
21073 +               break;
21074 +       case Opt_noplink:
21075 +               if (au_opt_test(sbinfo->si_mntflags, PLINK))
21076 +                       au_plink_put(sb, /*verbose*/1);
21077 +               au_opt_clr(sbinfo->si_mntflags, PLINK);
21078 +               break;
21079 +       case Opt_list_plink:
21080 +               if (au_opt_test(sbinfo->si_mntflags, PLINK))
21081 +                       au_plink_list(sb);
21082 +               break;
21083 +
21084 +       case Opt_dio:
21085 +               au_opt_set(sbinfo->si_mntflags, DIO);
21086 +               au_fset_opts(opts->flags, REFRESH_DYAOP);
21087 +               break;
21088 +       case Opt_nodio:
21089 +               au_opt_clr(sbinfo->si_mntflags, DIO);
21090 +               au_fset_opts(opts->flags, REFRESH_DYAOP);
21091 +               break;
21092 +
21093 +       case Opt_diropq_a:
21094 +               au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
21095 +               break;
21096 +       case Opt_diropq_w:
21097 +               au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
21098 +               break;
21099 +
21100 +       case Opt_warn_perm:
21101 +               au_opt_set(sbinfo->si_mntflags, WARN_PERM);
21102 +               break;
21103 +       case Opt_nowarn_perm:
21104 +               au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
21105 +               break;
21106 +
21107 +       case Opt_refrof:
21108 +               au_opt_set(sbinfo->si_mntflags, REFROF);
21109 +               break;
21110 +       case Opt_norefrof:
21111 +               au_opt_clr(sbinfo->si_mntflags, REFROF);
21112 +               break;
21113 +
21114 +       case Opt_verbose:
21115 +               au_opt_set(sbinfo->si_mntflags, VERBOSE);
21116 +               break;
21117 +       case Opt_noverbose:
21118 +               au_opt_clr(sbinfo->si_mntflags, VERBOSE);
21119 +               break;
21120 +
21121 +       case Opt_sum:
21122 +               au_opt_set(sbinfo->si_mntflags, SUM);
21123 +               break;
21124 +       case Opt_wsum:
21125 +               au_opt_clr(sbinfo->si_mntflags, SUM);
21126 +               au_opt_set(sbinfo->si_mntflags, SUM_W);
21127 +       case Opt_nosum:
21128 +               au_opt_clr(sbinfo->si_mntflags, SUM);
21129 +               au_opt_clr(sbinfo->si_mntflags, SUM_W);
21130 +               break;
21131 +
21132 +       case Opt_wbr_create:
21133 +               err = au_opt_wbr_create(sb, &opt->wbr_create);
21134 +               break;
21135 +       case Opt_wbr_copyup:
21136 +               sbinfo->si_wbr_copyup = opt->wbr_copyup;
21137 +               sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
21138 +               break;
21139 +
21140 +       case Opt_dirwh:
21141 +               sbinfo->si_dirwh = opt->dirwh;
21142 +               break;
21143 +
21144 +       case Opt_rdcache:
21145 +               sbinfo->si_rdcache
21146 +                       = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
21147 +               break;
21148 +       case Opt_rdblk:
21149 +               sbinfo->si_rdblk = opt->rdblk;
21150 +               break;
21151 +       case Opt_rdblk_def:
21152 +               sbinfo->si_rdblk = AUFS_RDBLK_DEF;
21153 +               break;
21154 +       case Opt_rdhash:
21155 +               sbinfo->si_rdhash = opt->rdhash;
21156 +               break;
21157 +       case Opt_rdhash_def:
21158 +               sbinfo->si_rdhash = AUFS_RDHASH_DEF;
21159 +               break;
21160 +
21161 +       case Opt_shwh:
21162 +               au_opt_set(sbinfo->si_mntflags, SHWH);
21163 +               break;
21164 +       case Opt_noshwh:
21165 +               au_opt_clr(sbinfo->si_mntflags, SHWH);
21166 +               break;
21167 +
21168 +       case Opt_trunc_xino:
21169 +               au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
21170 +               break;
21171 +       case Opt_notrunc_xino:
21172 +               au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
21173 +               break;
21174 +
21175 +       case Opt_trunc_xino_path:
21176 +       case Opt_itrunc_xino:
21177 +               err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
21178 +               if (!err)
21179 +                       err = 1;
21180 +               break;
21181 +
21182 +       case Opt_trunc_xib:
21183 +               au_fset_opts(opts->flags, TRUNC_XIB);
21184 +               break;
21185 +       case Opt_notrunc_xib:
21186 +               au_fclr_opts(opts->flags, TRUNC_XIB);
21187 +               break;
21188 +
21189 +       default:
21190 +               err = 0;
21191 +               break;
21192 +       }
21193 +
21194 +       return err;
21195 +}
21196 +
21197 +/*
21198 + * returns tri-state.
21199 + * plus: processed without an error
21200 + * zero: unprocessed
21201 + * minus: error
21202 + */
21203 +static int au_opt_br(struct super_block *sb, struct au_opt *opt,
21204 +                    struct au_opts *opts)
21205 +{
21206 +       int err, do_refresh;
21207 +
21208 +       err = 0;
21209 +       switch (opt->type) {
21210 +       case Opt_append:
21211 +               opt->add.bindex = au_sbend(sb) + 1;
21212 +               if (opt->add.bindex < 0)
21213 +                       opt->add.bindex = 0;
21214 +               goto add;
21215 +       case Opt_prepend:
21216 +               opt->add.bindex = 0;
21217 +       add:
21218 +       case Opt_add:
21219 +               err = au_br_add(sb, &opt->add,
21220 +                               au_ftest_opts(opts->flags, REMOUNT));
21221 +               if (!err) {
21222 +                       err = 1;
21223 +                       au_fset_opts(opts->flags, REFRESH);
21224 +               }
21225 +               break;
21226 +
21227 +       case Opt_del:
21228 +       case Opt_idel:
21229 +               err = au_br_del(sb, &opt->del,
21230 +                               au_ftest_opts(opts->flags, REMOUNT));
21231 +               if (!err) {
21232 +                       err = 1;
21233 +                       au_fset_opts(opts->flags, TRUNC_XIB);
21234 +                       au_fset_opts(opts->flags, REFRESH);
21235 +               }
21236 +               break;
21237 +
21238 +       case Opt_mod:
21239 +       case Opt_imod:
21240 +               err = au_br_mod(sb, &opt->mod,
21241 +                               au_ftest_opts(opts->flags, REMOUNT),
21242 +                               &do_refresh);
21243 +               if (!err) {
21244 +                       err = 1;
21245 +                       if (do_refresh)
21246 +                               au_fset_opts(opts->flags, REFRESH);
21247 +               }
21248 +               break;
21249 +       }
21250 +
21251 +       return err;
21252 +}
21253 +
21254 +static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
21255 +                      struct au_opt_xino **opt_xino,
21256 +                      struct au_opts *opts)
21257 +{
21258 +       int err;
21259 +       aufs_bindex_t bend, bindex;
21260 +       struct dentry *root, *parent, *h_root;
21261 +
21262 +       err = 0;
21263 +       switch (opt->type) {
21264 +       case Opt_xino:
21265 +               err = au_xino_set(sb, &opt->xino,
21266 +                                 !!au_ftest_opts(opts->flags, REMOUNT));
21267 +               if (unlikely(err))
21268 +                       break;
21269 +
21270 +               *opt_xino = &opt->xino;
21271 +               au_xino_brid_set(sb, -1);
21272 +
21273 +               /* safe d_parent access */
21274 +               parent = opt->xino.file->f_dentry->d_parent;
21275 +               root = sb->s_root;
21276 +               bend = au_sbend(sb);
21277 +               for (bindex = 0; bindex <= bend; bindex++) {
21278 +                       h_root = au_h_dptr(root, bindex);
21279 +                       if (h_root == parent) {
21280 +                               au_xino_brid_set(sb, au_sbr_id(sb, bindex));
21281 +                               break;
21282 +                       }
21283 +               }
21284 +               break;
21285 +
21286 +       case Opt_noxino:
21287 +               au_xino_clr(sb);
21288 +               au_xino_brid_set(sb, -1);
21289 +               *opt_xino = (void *)-1;
21290 +               break;
21291 +       }
21292 +
21293 +       return err;
21294 +}
21295 +
21296 +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
21297 +                  unsigned int pending)
21298 +{
21299 +       int err;
21300 +       aufs_bindex_t bindex, bend;
21301 +       unsigned char do_plink, skip, do_free;
21302 +       struct au_branch *br;
21303 +       struct au_wbr *wbr;
21304 +       struct dentry *root;
21305 +       struct inode *dir, *h_dir;
21306 +       struct au_sbinfo *sbinfo;
21307 +       struct au_hinode *hdir;
21308 +
21309 +       SiMustAnyLock(sb);
21310 +
21311 +       sbinfo = au_sbi(sb);
21312 +       AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
21313 +
21314 +       if (!(sb_flags & MS_RDONLY)) {
21315 +               if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
21316 +                       pr_warn("first branch should be rw\n");
21317 +               if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
21318 +                       pr_warn("shwh should be used with ro\n");
21319 +       }
21320 +
21321 +       if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
21322 +           && !au_opt_test(sbinfo->si_mntflags, XINO))
21323 +               pr_warn("udba=*notify requires xino\n");
21324 +
21325 +       err = 0;
21326 +       root = sb->s_root;
21327 +       dir = root->d_inode;
21328 +       do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
21329 +       bend = au_sbend(sb);
21330 +       for (bindex = 0; !err && bindex <= bend; bindex++) {
21331 +               skip = 0;
21332 +               h_dir = au_h_iptr(dir, bindex);
21333 +               br = au_sbr(sb, bindex);
21334 +               do_free = 0;
21335 +
21336 +               wbr = br->br_wbr;
21337 +               if (wbr)
21338 +                       wbr_wh_read_lock(wbr);
21339 +
21340 +               if (!au_br_writable(br->br_perm)) {
21341 +                       do_free = !!wbr;
21342 +                       skip = (!wbr
21343 +                               || (!wbr->wbr_whbase
21344 +                                   && !wbr->wbr_plink
21345 +                                   && !wbr->wbr_orph));
21346 +               } else if (!au_br_wh_linkable(br->br_perm)) {
21347 +                       /* skip = (!br->br_whbase && !br->br_orph); */
21348 +                       skip = (!wbr || !wbr->wbr_whbase);
21349 +                       if (skip && wbr) {
21350 +                               if (do_plink)
21351 +                                       skip = !!wbr->wbr_plink;
21352 +                               else
21353 +                                       skip = !wbr->wbr_plink;
21354 +                       }
21355 +               } else {
21356 +                       /* skip = (br->br_whbase && br->br_ohph); */
21357 +                       skip = (wbr && wbr->wbr_whbase);
21358 +                       if (skip) {
21359 +                               if (do_plink)
21360 +                                       skip = !!wbr->wbr_plink;
21361 +                               else
21362 +                                       skip = !wbr->wbr_plink;
21363 +                       }
21364 +               }
21365 +               if (wbr)
21366 +                       wbr_wh_read_unlock(wbr);
21367 +
21368 +               if (skip)
21369 +                       continue;
21370 +
21371 +               hdir = au_hi(dir, bindex);
21372 +               au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
21373 +               if (wbr)
21374 +                       wbr_wh_write_lock(wbr);
21375 +               err = au_wh_init(br, sb);
21376 +               if (wbr)
21377 +                       wbr_wh_write_unlock(wbr);
21378 +               au_hn_imtx_unlock(hdir);
21379 +
21380 +               if (!err && do_free) {
21381 +                       kfree(wbr);
21382 +                       br->br_wbr = NULL;
21383 +               }
21384 +       }
21385 +
21386 +       return err;
21387 +}
21388 +
21389 +int au_opts_mount(struct super_block *sb, struct au_opts *opts)
21390 +{
21391 +       int err;
21392 +       unsigned int tmp;
21393 +       aufs_bindex_t bindex, bend;
21394 +       struct au_opt *opt;
21395 +       struct au_opt_xino *opt_xino, xino;
21396 +       struct au_sbinfo *sbinfo;
21397 +       struct au_branch *br;
21398 +
21399 +       SiMustWriteLock(sb);
21400 +
21401 +       err = 0;
21402 +       opt_xino = NULL;
21403 +       opt = opts->opt;
21404 +       while (err >= 0 && opt->type != Opt_tail)
21405 +               err = au_opt_simple(sb, opt++, opts);
21406 +       if (err > 0)
21407 +               err = 0;
21408 +       else if (unlikely(err < 0))
21409 +               goto out;
21410 +
21411 +       /* disable xino and udba temporary */
21412 +       sbinfo = au_sbi(sb);
21413 +       tmp = sbinfo->si_mntflags;
21414 +       au_opt_clr(sbinfo->si_mntflags, XINO);
21415 +       au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
21416 +
21417 +       opt = opts->opt;
21418 +       while (err >= 0 && opt->type != Opt_tail)
21419 +               err = au_opt_br(sb, opt++, opts);
21420 +       if (err > 0)
21421 +               err = 0;
21422 +       else if (unlikely(err < 0))
21423 +               goto out;
21424 +
21425 +       bend = au_sbend(sb);
21426 +       if (unlikely(bend < 0)) {
21427 +               err = -EINVAL;
21428 +               pr_err("no branches\n");
21429 +               goto out;
21430 +       }
21431 +
21432 +       if (au_opt_test(tmp, XINO))
21433 +               au_opt_set(sbinfo->si_mntflags, XINO);
21434 +       opt = opts->opt;
21435 +       while (!err && opt->type != Opt_tail)
21436 +               err = au_opt_xino(sb, opt++, &opt_xino, opts);
21437 +       if (unlikely(err))
21438 +               goto out;
21439 +
21440 +       err = au_opts_verify(sb, sb->s_flags, tmp);
21441 +       if (unlikely(err))
21442 +               goto out;
21443 +
21444 +       /* restore xino */
21445 +       if (au_opt_test(tmp, XINO) && !opt_xino) {
21446 +               xino.file = au_xino_def(sb);
21447 +               err = PTR_ERR(xino.file);
21448 +               if (IS_ERR(xino.file))
21449 +                       goto out;
21450 +
21451 +               err = au_xino_set(sb, &xino, /*remount*/0);
21452 +               fput(xino.file);
21453 +               if (unlikely(err))
21454 +                       goto out;
21455 +       }
21456 +
21457 +       /* restore udba */
21458 +       tmp &= AuOptMask_UDBA;
21459 +       sbinfo->si_mntflags &= ~AuOptMask_UDBA;
21460 +       sbinfo->si_mntflags |= tmp;
21461 +       bend = au_sbend(sb);
21462 +       for (bindex = 0; bindex <= bend; bindex++) {
21463 +               br = au_sbr(sb, bindex);
21464 +               err = au_hnotify_reset_br(tmp, br, br->br_perm);
21465 +               if (unlikely(err))
21466 +                       AuIOErr("hnotify failed on br %d, %d, ignored\n",
21467 +                               bindex, err);
21468 +               /* go on even if err */
21469 +       }
21470 +       if (au_opt_test(tmp, UDBA_HNOTIFY)) {
21471 +               struct inode *dir = sb->s_root->d_inode;
21472 +               au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
21473 +       }
21474 +
21475 +out:
21476 +       return err;
21477 +}
21478 +
21479 +int au_opts_remount(struct super_block *sb, struct au_opts *opts)
21480 +{
21481 +       int err, rerr;
21482 +       struct inode *dir;
21483 +       struct au_opt_xino *opt_xino;
21484 +       struct au_opt *opt;
21485 +       struct au_sbinfo *sbinfo;
21486 +
21487 +       SiMustWriteLock(sb);
21488 +
21489 +       dir = sb->s_root->d_inode;
21490 +       sbinfo = au_sbi(sb);
21491 +       err = 0;
21492 +       opt_xino = NULL;
21493 +       opt = opts->opt;
21494 +       while (err >= 0 && opt->type != Opt_tail) {
21495 +               err = au_opt_simple(sb, opt, opts);
21496 +               if (!err)
21497 +                       err = au_opt_br(sb, opt, opts);
21498 +               if (!err)
21499 +                       err = au_opt_xino(sb, opt, &opt_xino, opts);
21500 +               opt++;
21501 +       }
21502 +       if (err > 0)
21503 +               err = 0;
21504 +       AuTraceErr(err);
21505 +       /* go on even err */
21506 +
21507 +       rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
21508 +       if (unlikely(rerr && !err))
21509 +               err = rerr;
21510 +
21511 +       if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
21512 +               rerr = au_xib_trunc(sb);
21513 +               if (unlikely(rerr && !err))
21514 +                       err = rerr;
21515 +       }
21516 +
21517 +       /* will be handled by the caller */
21518 +       if (!au_ftest_opts(opts->flags, REFRESH)
21519 +           && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
21520 +               au_fset_opts(opts->flags, REFRESH);
21521 +
21522 +       AuDbg("status 0x%x\n", opts->flags);
21523 +       return err;
21524 +}
21525 +
21526 +/* ---------------------------------------------------------------------- */
21527 +
21528 +unsigned int au_opt_udba(struct super_block *sb)
21529 +{
21530 +       return au_mntflags(sb) & AuOptMask_UDBA;
21531 +}
21532 diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
21533 --- /usr/share/empty/fs/aufs/opts.h     1970-01-01 01:00:00.000000000 +0100
21534 +++ linux/fs/aufs/opts.h        2013-07-06 13:20:47.753531903 +0200
21535 @@ -0,0 +1,209 @@
21536 +/*
21537 + * Copyright (C) 2005-2013 Junjiro R. Okajima
21538 + *
21539 + * This program, aufs is free software; you can redistribute it and/or modify
21540 + * it under the terms of the GNU General Public License as published by
21541 + * the Free Software Foundation; either version 2 of the License, or
21542 + * (at your option) any later version.
21543 + *
21544 + * This program is distributed in the hope that it will be useful,
21545 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21546 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21547 + * GNU General Public License for more details.
21548 + *
21549 + * You should have received a copy of the GNU General Public License
21550 + * along with this program; if not, write to the Free Software
21551 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21552 + */
21553 +
21554 +/*
21555 + * mount options/flags
21556 + */
21557 +
21558 +#ifndef __AUFS_OPTS_H__
21559 +#define __AUFS_OPTS_H__
21560 +
21561 +#ifdef __KERNEL__
21562 +
21563 +#include <linux/path.h>
21564 +
21565 +struct file;
21566 +struct super_block;
21567 +
21568 +/* ---------------------------------------------------------------------- */
21569 +
21570 +/* mount flags */
21571 +#define AuOpt_XINO             1               /* external inode number bitmap
21572 +                                                  and translation table */
21573 +#define AuOpt_TRUNC_XINO       (1 << 1)        /* truncate xino files */
21574 +#define AuOpt_UDBA_NONE                (1 << 2)        /* users direct branch access */
21575 +#define AuOpt_UDBA_REVAL       (1 << 3)
21576 +#define AuOpt_UDBA_HNOTIFY     (1 << 4)
21577 +#define AuOpt_SHWH             (1 << 5)        /* show whiteout */
21578 +#define AuOpt_PLINK            (1 << 6)        /* pseudo-link */
21579 +#define AuOpt_DIRPERM1         (1 << 7)        /* unimplemented */
21580 +#define AuOpt_REFROF           (1 << 8)        /* unimplemented */
21581 +#define AuOpt_ALWAYS_DIROPQ    (1 << 9)        /* policy to creating diropq */
21582 +#define AuOpt_SUM              (1 << 10)       /* summation for statfs(2) */
21583 +#define AuOpt_SUM_W            (1 << 11)       /* unimplemented */
21584 +#define AuOpt_WARN_PERM                (1 << 12)       /* warn when add-branch */
21585 +#define AuOpt_VERBOSE          (1 << 13)       /* busy inode when del-branch */
21586 +#define AuOpt_DIO              (1 << 14)       /* direct io */
21587 +
21588 +#ifndef CONFIG_AUFS_HNOTIFY
21589 +#undef AuOpt_UDBA_HNOTIFY
21590 +#define AuOpt_UDBA_HNOTIFY     0
21591 +#endif
21592 +#ifndef CONFIG_AUFS_SHWH
21593 +#undef AuOpt_SHWH
21594 +#define AuOpt_SHWH             0
21595 +#endif
21596 +
21597 +#define AuOpt_Def      (AuOpt_XINO \
21598 +                        | AuOpt_UDBA_REVAL \
21599 +                        | AuOpt_PLINK \
21600 +                        /* | AuOpt_DIRPERM1 */ \
21601 +                        | AuOpt_WARN_PERM)
21602 +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
21603 +                        | AuOpt_UDBA_REVAL \
21604 +                        | AuOpt_UDBA_HNOTIFY)
21605 +
21606 +#define au_opt_test(flags, name)       (flags & AuOpt_##name)
21607 +#define au_opt_set(flags, name) do { \
21608 +       BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
21609 +       ((flags) |= AuOpt_##name); \
21610 +} while (0)
21611 +#define au_opt_set_udba(flags, name) do { \
21612 +       (flags) &= ~AuOptMask_UDBA; \
21613 +       ((flags) |= AuOpt_##name); \
21614 +} while (0)
21615 +#define au_opt_clr(flags, name) do { \
21616 +       ((flags) &= ~AuOpt_##name); \
21617 +} while (0)
21618 +
21619 +static inline unsigned int au_opts_plink(unsigned int mntflags)
21620 +{
21621 +#ifdef CONFIG_PROC_FS
21622 +       return mntflags;
21623 +#else
21624 +       return mntflags & ~AuOpt_PLINK;
21625 +#endif
21626 +}
21627 +
21628 +/* ---------------------------------------------------------------------- */
21629 +
21630 +/* policies to select one among multiple writable branches */
21631 +enum {
21632 +       AuWbrCreate_TDP,        /* top down parent */
21633 +       AuWbrCreate_RR,         /* round robin */
21634 +       AuWbrCreate_MFS,        /* most free space */
21635 +       AuWbrCreate_MFSV,       /* mfs with seconds */
21636 +       AuWbrCreate_MFSRR,      /* mfs then rr */
21637 +       AuWbrCreate_MFSRRV,     /* mfs then rr with seconds */
21638 +       AuWbrCreate_PMFS,       /* parent and mfs */
21639 +       AuWbrCreate_PMFSV,      /* parent and mfs with seconds */
21640 +
21641 +       AuWbrCreate_Def = AuWbrCreate_TDP
21642 +};
21643 +
21644 +enum {
21645 +       AuWbrCopyup_TDP,        /* top down parent */
21646 +       AuWbrCopyup_BUP,        /* bottom up parent */
21647 +       AuWbrCopyup_BU,         /* bottom up */
21648 +
21649 +       AuWbrCopyup_Def = AuWbrCopyup_TDP
21650 +};
21651 +
21652 +/* ---------------------------------------------------------------------- */
21653 +
21654 +struct au_opt_add {
21655 +       aufs_bindex_t   bindex;
21656 +       char            *pathname;
21657 +       int             perm;
21658 +       struct path     path;
21659 +};
21660 +
21661 +struct au_opt_del {
21662 +       char            *pathname;
21663 +       struct path     h_path;
21664 +};
21665 +
21666 +struct au_opt_mod {
21667 +       char            *path;
21668 +       int             perm;
21669 +       struct dentry   *h_root;
21670 +};
21671 +
21672 +struct au_opt_xino {
21673 +       char            *path;
21674 +       struct file     *file;
21675 +};
21676 +
21677 +struct au_opt_xino_itrunc {
21678 +       aufs_bindex_t   bindex;
21679 +};
21680 +
21681 +struct au_opt_wbr_create {
21682 +       int                     wbr_create;
21683 +       int                     mfs_second;
21684 +       unsigned long long      mfsrr_watermark;
21685 +};
21686 +
21687 +struct au_opt {
21688 +       int type;
21689 +       union {
21690 +               struct au_opt_xino      xino;
21691 +               struct au_opt_xino_itrunc xino_itrunc;
21692 +               struct au_opt_add       add;
21693 +               struct au_opt_del       del;
21694 +               struct au_opt_mod       mod;
21695 +               int                     dirwh;
21696 +               int                     rdcache;
21697 +               unsigned int            rdblk;
21698 +               unsigned int            rdhash;
21699 +               int                     udba;
21700 +               struct au_opt_wbr_create wbr_create;
21701 +               int                     wbr_copyup;
21702 +       };
21703 +};
21704 +
21705 +/* opts flags */
21706 +#define AuOpts_REMOUNT         1
21707 +#define AuOpts_REFRESH         (1 << 1)
21708 +#define AuOpts_TRUNC_XIB       (1 << 2)
21709 +#define AuOpts_REFRESH_DYAOP   (1 << 3)
21710 +#define au_ftest_opts(flags, name)     ((flags) & AuOpts_##name)
21711 +#define au_fset_opts(flags, name) \
21712 +       do { (flags) |= AuOpts_##name; } while (0)
21713 +#define au_fclr_opts(flags, name) \
21714 +       do { (flags) &= ~AuOpts_##name; } while (0)
21715 +
21716 +struct au_opts {
21717 +       struct au_opt   *opt;
21718 +       int             max_opt;
21719 +
21720 +       unsigned int    given_udba;
21721 +       unsigned int    flags;
21722 +       unsigned long   sb_flags;
21723 +};
21724 +
21725 +/* ---------------------------------------------------------------------- */
21726 +
21727 +char *au_optstr_br_perm(int brperm);
21728 +const char *au_optstr_udba(int udba);
21729 +const char *au_optstr_wbr_copyup(int wbr_copyup);
21730 +const char *au_optstr_wbr_create(int wbr_create);
21731 +
21732 +void au_opts_free(struct au_opts *opts);
21733 +int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
21734 +int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
21735 +                  unsigned int pending);
21736 +int au_opts_mount(struct super_block *sb, struct au_opts *opts);
21737 +int au_opts_remount(struct super_block *sb, struct au_opts *opts);
21738 +
21739 +unsigned int au_opt_udba(struct super_block *sb);
21740 +
21741 +/* ---------------------------------------------------------------------- */
21742 +
21743 +#endif /* __KERNEL__ */
21744 +#endif /* __AUFS_OPTS_H__ */
21745 diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
21746 --- /usr/share/empty/fs/aufs/plink.c    1970-01-01 01:00:00.000000000 +0100
21747 +++ linux/fs/aufs/plink.c       2013-07-06 13:20:47.753531903 +0200
21748 @@ -0,0 +1,520 @@
21749 +/*
21750 + * Copyright (C) 2005-2013 Junjiro R. Okajima
21751 + *
21752 + * This program, aufs is free software; you can redistribute it and/or modify
21753 + * it under the terms of the GNU General Public License as published by
21754 + * the Free Software Foundation; either version 2 of the License, or
21755 + * (at your option) any later version.
21756 + *
21757 + * This program is distributed in the hope that it will be useful,
21758 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21759 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21760 + * GNU General Public License for more details.
21761 + *
21762 + * You should have received a copy of the GNU General Public License
21763 + * along with this program; if not, write to the Free Software
21764 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21765 + */
21766 +
21767 +/*
21768 + * pseudo-link
21769 + */
21770 +
21771 +#include "aufs.h"
21772 +
21773 +/*
21774 + * the pseudo-link maintenance mode.
21775 + * during a user process maintains the pseudo-links,
21776 + * prohibit adding a new plink and branch manipulation.
21777 + *
21778 + * Flags
21779 + * NOPLM:
21780 + *     For entry functions which will handle plink, and i_mutex is already held
21781 + *     in VFS.
21782 + *     They cannot wait and should return an error at once.
21783 + *     Callers has to check the error.
21784 + * NOPLMW:
21785 + *     For entry functions which will handle plink, but i_mutex is not held
21786 + *     in VFS.
21787 + *     They can wait the plink maintenance mode to finish.
21788 + *
21789 + * They behave like F_SETLK and F_SETLKW.
21790 + * If the caller never handle plink, then both flags are unnecessary.
21791 + */
21792 +
21793 +int au_plink_maint(struct super_block *sb, int flags)
21794 +{
21795 +       int err;
21796 +       pid_t pid, ppid;
21797 +       struct au_sbinfo *sbi;
21798 +
21799 +       SiMustAnyLock(sb);
21800 +
21801 +       err = 0;
21802 +       if (!au_opt_test(au_mntflags(sb), PLINK))
21803 +               goto out;
21804 +
21805 +       sbi = au_sbi(sb);
21806 +       pid = sbi->si_plink_maint_pid;
21807 +       if (!pid || pid == current->pid)
21808 +               goto out;
21809 +
21810 +       /* todo: it highly depends upon /sbin/mount.aufs */
21811 +       rcu_read_lock();
21812 +       ppid = task_pid_vnr(rcu_dereference(current->real_parent));
21813 +       rcu_read_unlock();
21814 +       if (pid == ppid)
21815 +               goto out;
21816 +
21817 +       if (au_ftest_lock(flags, NOPLMW)) {
21818 +               /* if there is no i_mutex lock in VFS, we don't need to wait */
21819 +               /* AuDebugOn(!lockdep_depth(current)); */
21820 +               while (sbi->si_plink_maint_pid) {
21821 +                       si_read_unlock(sb);
21822 +                       /* gave up wake_up_bit() */
21823 +                       wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
21824 +
21825 +                       if (au_ftest_lock(flags, FLUSH))
21826 +                               au_nwt_flush(&sbi->si_nowait);
21827 +                       si_noflush_read_lock(sb);
21828 +               }
21829 +       } else if (au_ftest_lock(flags, NOPLM)) {
21830 +               AuDbg("ppid %d, pid %d\n", ppid, pid);
21831 +               err = -EAGAIN;
21832 +       }
21833 +
21834 +out:
21835 +       return err;
21836 +}
21837 +
21838 +void au_plink_maint_leave(struct au_sbinfo *sbinfo)
21839 +{
21840 +       spin_lock(&sbinfo->si_plink_maint_lock);
21841 +       sbinfo->si_plink_maint_pid = 0;
21842 +       spin_unlock(&sbinfo->si_plink_maint_lock);
21843 +       wake_up_all(&sbinfo->si_plink_wq);
21844 +}
21845 +
21846 +int au_plink_maint_enter(struct super_block *sb)
21847 +{
21848 +       int err;
21849 +       struct au_sbinfo *sbinfo;
21850 +
21851 +       err = 0;
21852 +       sbinfo = au_sbi(sb);
21853 +       /* make sure i am the only one in this fs */
21854 +       si_write_lock(sb, AuLock_FLUSH);
21855 +       if (au_opt_test(au_mntflags(sb), PLINK)) {
21856 +               spin_lock(&sbinfo->si_plink_maint_lock);
21857 +               if (!sbinfo->si_plink_maint_pid)
21858 +                       sbinfo->si_plink_maint_pid = current->pid;
21859 +               else
21860 +                       err = -EBUSY;
21861 +               spin_unlock(&sbinfo->si_plink_maint_lock);
21862 +       }
21863 +       si_write_unlock(sb);
21864 +
21865 +       return err;
21866 +}
21867 +
21868 +/* ---------------------------------------------------------------------- */
21869 +
21870 +#ifdef CONFIG_AUFS_DEBUG
21871 +void au_plink_list(struct super_block *sb)
21872 +{
21873 +       int i;
21874 +       struct au_sbinfo *sbinfo;
21875 +       struct hlist_head *plink_hlist;
21876 +       struct pseudo_link *plink;
21877 +
21878 +       SiMustAnyLock(sb);
21879 +
21880 +       sbinfo = au_sbi(sb);
21881 +       AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
21882 +       AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
21883 +
21884 +       for (i = 0; i < AuPlink_NHASH; i++) {
21885 +               plink_hlist = &sbinfo->si_plink[i].head;
21886 +               rcu_read_lock();
21887 +               hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
21888 +                       AuDbg("%lu\n", plink->inode->i_ino);
21889 +               rcu_read_unlock();
21890 +       }
21891 +}
21892 +#endif
21893 +
21894 +/* is the inode pseudo-linked? */
21895 +int au_plink_test(struct inode *inode)
21896 +{
21897 +       int found, i;
21898 +       struct au_sbinfo *sbinfo;
21899 +       struct hlist_head *plink_hlist;
21900 +       struct pseudo_link *plink;
21901 +
21902 +       sbinfo = au_sbi(inode->i_sb);
21903 +       AuRwMustAnyLock(&sbinfo->si_rwsem);
21904 +       AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
21905 +       AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
21906 +
21907 +       found = 0;
21908 +       i = au_plink_hash(inode->i_ino);
21909 +       plink_hlist = &sbinfo->si_plink[i].head;
21910 +       rcu_read_lock();
21911 +       hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
21912 +               if (plink->inode == inode) {
21913 +                       found = 1;
21914 +                       break;
21915 +               }
21916 +       rcu_read_unlock();
21917 +       return found;
21918 +}
21919 +
21920 +/* ---------------------------------------------------------------------- */
21921 +
21922 +/*
21923 + * generate a name for plink.
21924 + * the file will be stored under AUFS_WH_PLINKDIR.
21925 + */
21926 +/* 20 is max digits length of ulong 64 */
21927 +#define PLINK_NAME_LEN ((20 + 1) * 2)
21928 +
21929 +static int plink_name(char *name, int len, struct inode *inode,
21930 +                     aufs_bindex_t bindex)
21931 +{
21932 +       int rlen;
21933 +       struct inode *h_inode;
21934 +
21935 +       h_inode = au_h_iptr(inode, bindex);
21936 +       rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
21937 +       return rlen;
21938 +}
21939 +
21940 +struct au_do_plink_lkup_args {
21941 +       struct dentry **errp;
21942 +       struct qstr *tgtname;
21943 +       struct dentry *h_parent;
21944 +       struct au_branch *br;
21945 +};
21946 +
21947 +static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
21948 +                                      struct dentry *h_parent,
21949 +                                      struct au_branch *br)
21950 +{
21951 +       struct dentry *h_dentry;
21952 +       struct mutex *h_mtx;
21953 +
21954 +       h_mtx = &h_parent->d_inode->i_mutex;
21955 +       mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
21956 +       h_dentry = vfsub_lkup_one(tgtname, h_parent);
21957 +       mutex_unlock(h_mtx);
21958 +       return h_dentry;
21959 +}
21960 +
21961 +static void au_call_do_plink_lkup(void *args)
21962 +{
21963 +       struct au_do_plink_lkup_args *a = args;
21964 +       *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
21965 +}
21966 +
21967 +/* lookup the plink-ed @inode under the branch at @bindex */
21968 +struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
21969 +{
21970 +       struct dentry *h_dentry, *h_parent;
21971 +       struct au_branch *br;
21972 +       struct inode *h_dir;
21973 +       int wkq_err;
21974 +       char a[PLINK_NAME_LEN];
21975 +       struct qstr tgtname = QSTR_INIT(a, 0);
21976 +
21977 +       AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
21978 +
21979 +       br = au_sbr(inode->i_sb, bindex);
21980 +       h_parent = br->br_wbr->wbr_plink;
21981 +       h_dir = h_parent->d_inode;
21982 +       tgtname.len = plink_name(a, sizeof(a), inode, bindex);
21983 +
21984 +       if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
21985 +               struct au_do_plink_lkup_args args = {
21986 +                       .errp           = &h_dentry,
21987 +                       .tgtname        = &tgtname,
21988 +                       .h_parent       = h_parent,
21989 +                       .br             = br
21990 +               };
21991 +
21992 +               wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
21993 +               if (unlikely(wkq_err))
21994 +                       h_dentry = ERR_PTR(wkq_err);
21995 +       } else
21996 +               h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
21997 +
21998 +       return h_dentry;
21999 +}
22000 +
22001 +/* create a pseudo-link */
22002 +static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
22003 +                     struct dentry *h_dentry, struct au_branch *br)
22004 +{
22005 +       int err;
22006 +       struct path h_path = {
22007 +               .mnt = au_br_mnt(br)
22008 +       };
22009 +       struct inode *h_dir;
22010 +
22011 +       h_dir = h_parent->d_inode;
22012 +       mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
22013 +again:
22014 +       h_path.dentry = vfsub_lkup_one(tgt, h_parent);
22015 +       err = PTR_ERR(h_path.dentry);
22016 +       if (IS_ERR(h_path.dentry))
22017 +               goto out;
22018 +
22019 +       err = 0;
22020 +       /* wh.plink dir is not monitored */
22021 +       /* todo: is it really safe? */
22022 +       if (h_path.dentry->d_inode
22023 +           && h_path.dentry->d_inode != h_dentry->d_inode) {
22024 +               err = vfsub_unlink(h_dir, &h_path, /*force*/0);
22025 +               dput(h_path.dentry);
22026 +               h_path.dentry = NULL;
22027 +               if (!err)
22028 +                       goto again;
22029 +       }
22030 +       if (!err && !h_path.dentry->d_inode)
22031 +               err = vfsub_link(h_dentry, h_dir, &h_path);
22032 +       dput(h_path.dentry);
22033 +
22034 +out:
22035 +       mutex_unlock(&h_dir->i_mutex);
22036 +       return err;
22037 +}
22038 +
22039 +struct do_whplink_args {
22040 +       int *errp;
22041 +       struct qstr *tgt;
22042 +       struct dentry *h_parent;
22043 +       struct dentry *h_dentry;
22044 +       struct au_branch *br;
22045 +};
22046 +
22047 +static void call_do_whplink(void *args)
22048 +{
22049 +       struct do_whplink_args *a = args;
22050 +       *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
22051 +}
22052 +
22053 +static int whplink(struct dentry *h_dentry, struct inode *inode,
22054 +                  aufs_bindex_t bindex, struct au_branch *br)
22055 +{
22056 +       int err, wkq_err;
22057 +       struct au_wbr *wbr;
22058 +       struct dentry *h_parent;
22059 +       struct inode *h_dir;
22060 +       char a[PLINK_NAME_LEN];
22061 +       struct qstr tgtname = QSTR_INIT(a, 0);
22062 +
22063 +       wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
22064 +       h_parent = wbr->wbr_plink;
22065 +       h_dir = h_parent->d_inode;
22066 +       tgtname.len = plink_name(a, sizeof(a), inode, bindex);
22067 +
22068 +       /* always superio. */
22069 +       if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
22070 +               struct do_whplink_args args = {
22071 +                       .errp           = &err,
22072 +                       .tgt            = &tgtname,
22073 +                       .h_parent       = h_parent,
22074 +                       .h_dentry       = h_dentry,
22075 +                       .br             = br
22076 +               };
22077 +               wkq_err = au_wkq_wait(call_do_whplink, &args);
22078 +               if (unlikely(wkq_err))
22079 +                       err = wkq_err;
22080 +       } else
22081 +               err = do_whplink(&tgtname, h_parent, h_dentry, br);
22082 +
22083 +       return err;
22084 +}
22085 +
22086 +/* free a single plink */
22087 +static void do_put_plink(struct pseudo_link *plink, int do_del)
22088 +{
22089 +       if (do_del)
22090 +               hlist_del(&plink->hlist);
22091 +       iput(plink->inode);
22092 +       kfree(plink);
22093 +}
22094 +
22095 +static void do_put_plink_rcu(struct rcu_head *rcu)
22096 +{
22097 +       struct pseudo_link *plink;
22098 +
22099 +       plink = container_of(rcu, struct pseudo_link, rcu);
22100 +       iput(plink->inode);
22101 +       kfree(plink);
22102 +}
22103 +
22104 +/*
22105 + * create a new pseudo-link for @h_dentry on @bindex.
22106 + * the linked inode is held in aufs @inode.
22107 + */
22108 +void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
22109 +                    struct dentry *h_dentry)
22110 +{
22111 +       struct super_block *sb;
22112 +       struct au_sbinfo *sbinfo;
22113 +       struct hlist_head *plink_hlist;
22114 +       struct pseudo_link *plink, *tmp;
22115 +       struct au_sphlhead *sphl;
22116 +       int found, err, cnt, i;
22117 +
22118 +       sb = inode->i_sb;
22119 +       sbinfo = au_sbi(sb);
22120 +       AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
22121 +       AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
22122 +
22123 +       found = au_plink_test(inode);
22124 +       if (found)
22125 +               return;
22126 +
22127 +       i = au_plink_hash(inode->i_ino);
22128 +       sphl = sbinfo->si_plink + i;
22129 +       plink_hlist = &sphl->head;
22130 +       tmp = kmalloc(sizeof(*plink), GFP_NOFS);
22131 +       if (tmp)
22132 +               tmp->inode = au_igrab(inode);
22133 +       else {
22134 +               err = -ENOMEM;
22135 +               goto out;
22136 +       }
22137 +
22138 +       spin_lock(&sphl->spin);
22139 +       hlist_for_each_entry(plink, plink_hlist, hlist) {
22140 +               if (plink->inode == inode) {
22141 +                       found = 1;
22142 +                       break;
22143 +               }
22144 +       }
22145 +       if (!found)
22146 +               hlist_add_head_rcu(&tmp->hlist, plink_hlist);
22147 +       spin_unlock(&sphl->spin);
22148 +       if (!found) {
22149 +               cnt = au_sphl_count(sphl);
22150 +#define msg "unexpectedly unblanced or too many pseudo-links"
22151 +               if (cnt > AUFS_PLINK_WARN)
22152 +                       AuWarn1(msg ", %d\n", cnt);
22153 +#undef msg
22154 +               err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
22155 +       } else {
22156 +               do_put_plink(tmp, 0);
22157 +               return;
22158 +       }
22159 +
22160 +out:
22161 +       if (unlikely(err)) {
22162 +               pr_warn("err %d, damaged pseudo link.\n", err);
22163 +               if (tmp) {
22164 +                       au_sphl_del_rcu(&tmp->hlist, sphl);
22165 +                       call_rcu(&tmp->rcu, do_put_plink_rcu);
22166 +               }
22167 +       }
22168 +}
22169 +
22170 +/* free all plinks */
22171 +void au_plink_put(struct super_block *sb, int verbose)
22172 +{
22173 +       int i, warned;
22174 +       struct au_sbinfo *sbinfo;
22175 +       struct hlist_head *plink_hlist;
22176 +       struct hlist_node *tmp;
22177 +       struct pseudo_link *plink;
22178 +
22179 +       SiMustWriteLock(sb);
22180 +
22181 +       sbinfo = au_sbi(sb);
22182 +       AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
22183 +       AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
22184 +
22185 +       /* no spin_lock since sbinfo is write-locked */
22186 +       warned = 0;
22187 +       for (i = 0; i < AuPlink_NHASH; i++) {
22188 +               plink_hlist = &sbinfo->si_plink[i].head;
22189 +               if (!warned && verbose && !hlist_empty(plink_hlist)) {
22190 +                       pr_warn("pseudo-link is not flushed");
22191 +                       warned = 1;
22192 +               }
22193 +               hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
22194 +                       do_put_plink(plink, 0);
22195 +               INIT_HLIST_HEAD(plink_hlist);
22196 +       }
22197 +}
22198 +
22199 +void au_plink_clean(struct super_block *sb, int verbose)
22200 +{
22201 +       struct dentry *root;
22202 +
22203 +       root = sb->s_root;
22204 +       aufs_write_lock(root);
22205 +       if (au_opt_test(au_mntflags(sb), PLINK))
22206 +               au_plink_put(sb, verbose);
22207 +       aufs_write_unlock(root);
22208 +}
22209 +
22210 +static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
22211 +{
22212 +       int do_put;
22213 +       aufs_bindex_t bstart, bend, bindex;
22214 +
22215 +       do_put = 0;
22216 +       bstart = au_ibstart(inode);
22217 +       bend = au_ibend(inode);
22218 +       if (bstart >= 0) {
22219 +               for (bindex = bstart; bindex <= bend; bindex++) {
22220 +                       if (!au_h_iptr(inode, bindex)
22221 +                           || au_ii_br_id(inode, bindex) != br_id)
22222 +                               continue;
22223 +                       au_set_h_iptr(inode, bindex, NULL, 0);
22224 +                       do_put = 1;
22225 +                       break;
22226 +               }
22227 +               if (do_put)
22228 +                       for (bindex = bstart; bindex <= bend; bindex++)
22229 +                               if (au_h_iptr(inode, bindex)) {
22230 +                                       do_put = 0;
22231 +                                       break;
22232 +                               }
22233 +       } else
22234 +               do_put = 1;
22235 +
22236 +       return do_put;
22237 +}
22238 +
22239 +/* free the plinks on a branch specified by @br_id */
22240 +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
22241 +{
22242 +       struct au_sbinfo *sbinfo;
22243 +       struct hlist_head *plink_hlist;
22244 +       struct hlist_node *tmp;
22245 +       struct pseudo_link *plink;
22246 +       struct inode *inode;
22247 +       int i, do_put;
22248 +
22249 +       SiMustWriteLock(sb);
22250 +
22251 +       sbinfo = au_sbi(sb);
22252 +       AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
22253 +       AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
22254 +
22255 +       /* no spin_lock since sbinfo is write-locked */
22256 +       for (i = 0; i < AuPlink_NHASH; i++) {
22257 +               plink_hlist = &sbinfo->si_plink[i].head;
22258 +               hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
22259 +                       inode = au_igrab(plink->inode);
22260 +                       ii_write_lock_child(inode);
22261 +                       do_put = au_plink_do_half_refresh(inode, br_id);
22262 +                       if (do_put)
22263 +                               do_put_plink(plink, 1);
22264 +                       ii_write_unlock(inode);
22265 +                       iput(inode);
22266 +               }
22267 +       }
22268 +}
22269 diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
22270 --- /usr/share/empty/fs/aufs/poll.c     1970-01-01 01:00:00.000000000 +0100
22271 +++ linux/fs/aufs/poll.c        2013-07-06 13:20:47.753531903 +0200
22272 @@ -0,0 +1,56 @@
22273 +/*
22274 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22275 + *
22276 + * This program, aufs is free software; you can redistribute it and/or modify
22277 + * it under the terms of the GNU General Public License as published by
22278 + * the Free Software Foundation; either version 2 of the License, or
22279 + * (at your option) any later version.
22280 + *
22281 + * This program is distributed in the hope that it will be useful,
22282 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22283 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22284 + * GNU General Public License for more details.
22285 + *
22286 + * You should have received a copy of the GNU General Public License
22287 + * along with this program; if not, write to the Free Software
22288 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22289 + */
22290 +
22291 +/*
22292 + * poll operation
22293 + * There is only one filesystem which implements ->poll operation, currently.
22294 + */
22295 +
22296 +#include "aufs.h"
22297 +
22298 +unsigned int aufs_poll(struct file *file, poll_table *wait)
22299 +{
22300 +       unsigned int mask;
22301 +       int err;
22302 +       struct file *h_file;
22303 +       struct dentry *dentry;
22304 +       struct super_block *sb;
22305 +
22306 +       /* We should pretend an error happened. */
22307 +       mask = POLLERR /* | POLLIN | POLLOUT */;
22308 +       dentry = file->f_dentry;
22309 +       sb = dentry->d_sb;
22310 +       si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
22311 +       err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
22312 +       if (unlikely(err))
22313 +               goto out;
22314 +
22315 +       /* it is not an error if h_file has no operation */
22316 +       mask = DEFAULT_POLLMASK;
22317 +       h_file = au_hf_top(file);
22318 +       if (h_file->f_op && h_file->f_op->poll)
22319 +               mask = h_file->f_op->poll(h_file, wait);
22320 +
22321 +       di_read_unlock(dentry, AuLock_IR);
22322 +       fi_read_unlock(file);
22323 +
22324 +out:
22325 +       si_read_unlock(sb);
22326 +       AuTraceErr((int)mask);
22327 +       return mask;
22328 +}
22329 diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
22330 --- /usr/share/empty/fs/aufs/procfs.c   1970-01-01 01:00:00.000000000 +0100
22331 +++ linux/fs/aufs/procfs.c      2013-07-06 13:20:47.753531903 +0200
22332 @@ -0,0 +1,170 @@
22333 +/*
22334 + * Copyright (C) 2010-2013 Junjiro R. Okajima
22335 + *
22336 + * This program, aufs is free software; you can redistribute it and/or modify
22337 + * it under the terms of the GNU General Public License as published by
22338 + * the Free Software Foundation; either version 2 of the License, or
22339 + * (at your option) any later version.
22340 + *
22341 + * This program is distributed in the hope that it will be useful,
22342 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22343 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22344 + * GNU General Public License for more details.
22345 + *
22346 + * You should have received a copy of the GNU General Public License
22347 + * along with this program; if not, write to the Free Software
22348 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22349 + */
22350 +
22351 +/*
22352 + * procfs interfaces
22353 + */
22354 +
22355 +#include <linux/proc_fs.h>
22356 +#include "aufs.h"
22357 +
22358 +static int au_procfs_plm_release(struct inode *inode, struct file *file)
22359 +{
22360 +       struct au_sbinfo *sbinfo;
22361 +
22362 +       sbinfo = file->private_data;
22363 +       if (sbinfo) {
22364 +               au_plink_maint_leave(sbinfo);
22365 +               kobject_put(&sbinfo->si_kobj);
22366 +       }
22367 +
22368 +       return 0;
22369 +}
22370 +
22371 +static void au_procfs_plm_write_clean(struct file *file)
22372 +{
22373 +       struct au_sbinfo *sbinfo;
22374 +
22375 +       sbinfo = file->private_data;
22376 +       if (sbinfo)
22377 +               au_plink_clean(sbinfo->si_sb, /*verbose*/0);
22378 +}
22379 +
22380 +static int au_procfs_plm_write_si(struct file *file, unsigned long id)
22381 +{
22382 +       int err;
22383 +       struct super_block *sb;
22384 +       struct au_sbinfo *sbinfo;
22385 +
22386 +       err = -EBUSY;
22387 +       if (unlikely(file->private_data))
22388 +               goto out;
22389 +
22390 +       sb = NULL;
22391 +       /* don't use au_sbilist_lock() here */
22392 +       spin_lock(&au_sbilist.spin);
22393 +       list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
22394 +               if (id == sysaufs_si_id(sbinfo)) {
22395 +                       kobject_get(&sbinfo->si_kobj);
22396 +                       sb = sbinfo->si_sb;
22397 +                       break;
22398 +               }
22399 +       spin_unlock(&au_sbilist.spin);
22400 +
22401 +       err = -EINVAL;
22402 +       if (unlikely(!sb))
22403 +               goto out;
22404 +
22405 +       err = au_plink_maint_enter(sb);
22406 +       if (!err)
22407 +               /* keep kobject_get() */
22408 +               file->private_data = sbinfo;
22409 +       else
22410 +               kobject_put(&sbinfo->si_kobj);
22411 +out:
22412 +       return err;
22413 +}
22414 +
22415 +/*
22416 + * Accept a valid "si=xxxx" only.
22417 + * Once it is accepted successfully, accept "clean" too.
22418 + */
22419 +static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
22420 +                                  size_t count, loff_t *ppos)
22421 +{
22422 +       ssize_t err;
22423 +       unsigned long id;
22424 +       /* last newline is allowed */
22425 +       char buf[3 + sizeof(unsigned long) * 2 + 1];
22426 +
22427 +       err = -EACCES;
22428 +       if (unlikely(!capable(CAP_SYS_ADMIN)))
22429 +               goto out;
22430 +
22431 +       err = -EINVAL;
22432 +       if (unlikely(count > sizeof(buf)))
22433 +               goto out;
22434 +
22435 +       err = copy_from_user(buf, ubuf, count);
22436 +       if (unlikely(err)) {
22437 +               err = -EFAULT;
22438 +               goto out;
22439 +       }
22440 +       buf[count] = 0;
22441 +
22442 +       err = -EINVAL;
22443 +       if (!strcmp("clean", buf)) {
22444 +               au_procfs_plm_write_clean(file);
22445 +               goto out_success;
22446 +       } else if (unlikely(strncmp("si=", buf, 3)))
22447 +               goto out;
22448 +
22449 +       err = kstrtoul(buf + 3, 16, &id);
22450 +       if (unlikely(err))
22451 +               goto out;
22452 +
22453 +       err = au_procfs_plm_write_si(file, id);
22454 +       if (unlikely(err))
22455 +               goto out;
22456 +
22457 +out_success:
22458 +       err = count; /* success */
22459 +out:
22460 +       return err;
22461 +}
22462 +
22463 +static const struct file_operations au_procfs_plm_fop = {
22464 +       .write          = au_procfs_plm_write,
22465 +       .release        = au_procfs_plm_release,
22466 +       .owner          = THIS_MODULE
22467 +};
22468 +
22469 +/* ---------------------------------------------------------------------- */
22470 +
22471 +static struct proc_dir_entry *au_procfs_dir;
22472 +
22473 +void au_procfs_fin(void)
22474 +{
22475 +       remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
22476 +       remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
22477 +}
22478 +
22479 +int __init au_procfs_init(void)
22480 +{
22481 +       int err;
22482 +       struct proc_dir_entry *entry;
22483 +
22484 +       err = -ENOMEM;
22485 +       au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
22486 +       if (unlikely(!au_procfs_dir))
22487 +               goto out;
22488 +
22489 +       entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
22490 +                           au_procfs_dir, &au_procfs_plm_fop);
22491 +       if (unlikely(!entry))
22492 +               goto out_dir;
22493 +
22494 +       err = 0;
22495 +       goto out; /* success */
22496 +
22497 +
22498 +out_dir:
22499 +       remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
22500 +out:
22501 +       return err;
22502 +}
22503 diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
22504 --- /usr/share/empty/fs/aufs/rdu.c      1970-01-01 01:00:00.000000000 +0100
22505 +++ linux/fs/aufs/rdu.c 2013-07-30 22:42:55.842946719 +0200
22506 @@ -0,0 +1,384 @@
22507 +/*
22508 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22509 + *
22510 + * This program, aufs is free software; you can redistribute it and/or modify
22511 + * it under the terms of the GNU General Public License as published by
22512 + * the Free Software Foundation; either version 2 of the License, or
22513 + * (at your option) any later version.
22514 + *
22515 + * This program is distributed in the hope that it will be useful,
22516 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22517 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22518 + * GNU General Public License for more details.
22519 + *
22520 + * You should have received a copy of the GNU General Public License
22521 + * along with this program; if not, write to the Free Software
22522 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22523 + */
22524 +
22525 +/*
22526 + * readdir in userspace.
22527 + */
22528 +
22529 +#include <linux/compat.h>
22530 +#include <linux/fs_stack.h>
22531 +#include <linux/security.h>
22532 +#include "aufs.h"
22533 +
22534 +/* bits for struct aufs_rdu.flags */
22535 +#define        AuRdu_CALLED    1
22536 +#define        AuRdu_CONT      (1 << 1)
22537 +#define        AuRdu_FULL      (1 << 2)
22538 +#define au_ftest_rdu(flags, name)      ((flags) & AuRdu_##name)
22539 +#define au_fset_rdu(flags, name) \
22540 +       do { (flags) |= AuRdu_##name; } while (0)
22541 +#define au_fclr_rdu(flags, name) \
22542 +       do { (flags) &= ~AuRdu_##name; } while (0)
22543 +
22544 +struct au_rdu_arg {
22545 +       struct aufs_rdu                 *rdu;
22546 +       union au_rdu_ent_ul             ent;
22547 +       unsigned long                   end;
22548 +
22549 +       struct super_block              *sb;
22550 +       int                             err;
22551 +};
22552 +
22553 +static int au_rdu_fill(void *__arg, const char *name, int nlen,
22554 +                      loff_t offset, u64 h_ino, unsigned int d_type)
22555 +{
22556 +       int err, len;
22557 +       struct au_rdu_arg *arg = __arg;
22558 +       struct aufs_rdu *rdu = arg->rdu;
22559 +       struct au_rdu_ent ent;
22560 +
22561 +       err = 0;
22562 +       arg->err = 0;
22563 +       au_fset_rdu(rdu->cookie.flags, CALLED);
22564 +       len = au_rdu_len(nlen);
22565 +       if (arg->ent.ul + len  < arg->end) {
22566 +               ent.ino = h_ino;
22567 +               ent.bindex = rdu->cookie.bindex;
22568 +               ent.type = d_type;
22569 +               ent.nlen = nlen;
22570 +               if (unlikely(nlen > AUFS_MAX_NAMELEN))
22571 +                       ent.type = DT_UNKNOWN;
22572 +
22573 +               /* unnecessary to support mmap_sem since this is a dir */
22574 +               err = -EFAULT;
22575 +               if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
22576 +                       goto out;
22577 +               if (copy_to_user(arg->ent.e->name, name, nlen))
22578 +                       goto out;
22579 +               /* the terminating NULL */
22580 +               if (__put_user(0, arg->ent.e->name + nlen))
22581 +                       goto out;
22582 +               err = 0;
22583 +               /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
22584 +               arg->ent.ul += len;
22585 +               rdu->rent++;
22586 +       } else {
22587 +               err = -EFAULT;
22588 +               au_fset_rdu(rdu->cookie.flags, FULL);
22589 +               rdu->full = 1;
22590 +               rdu->tail = arg->ent;
22591 +       }
22592 +
22593 +out:
22594 +       /* AuTraceErr(err); */
22595 +       return err;
22596 +}
22597 +
22598 +static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
22599 +{
22600 +       int err;
22601 +       loff_t offset;
22602 +       struct au_rdu_cookie *cookie = &arg->rdu->cookie;
22603 +
22604 +       /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
22605 +       offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
22606 +       err = offset;
22607 +       if (unlikely(offset != cookie->h_pos))
22608 +               goto out;
22609 +
22610 +       err = 0;
22611 +       do {
22612 +               arg->err = 0;
22613 +               au_fclr_rdu(cookie->flags, CALLED);
22614 +               /* smp_mb(); */
22615 +               err = vfsub_readdir(h_file, au_rdu_fill, arg);
22616 +               if (err >= 0)
22617 +                       err = arg->err;
22618 +       } while (!err
22619 +                && au_ftest_rdu(cookie->flags, CALLED)
22620 +                && !au_ftest_rdu(cookie->flags, FULL));
22621 +       cookie->h_pos = h_file->f_pos;
22622 +
22623 +out:
22624 +       AuTraceErr(err);
22625 +       return err;
22626 +}
22627 +
22628 +static int au_rdu(struct file *file, struct aufs_rdu *rdu)
22629 +{
22630 +       int err;
22631 +       aufs_bindex_t bend;
22632 +       struct au_rdu_arg arg;
22633 +       struct dentry *dentry;
22634 +       struct inode *inode;
22635 +       struct file *h_file;
22636 +       struct au_rdu_cookie *cookie = &rdu->cookie;
22637 +
22638 +       err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
22639 +       if (unlikely(err)) {
22640 +               err = -EFAULT;
22641 +               AuTraceErr(err);
22642 +               goto out;
22643 +       }
22644 +       rdu->rent = 0;
22645 +       rdu->tail = rdu->ent;
22646 +       rdu->full = 0;
22647 +       arg.rdu = rdu;
22648 +       arg.ent = rdu->ent;
22649 +       arg.end = arg.ent.ul;
22650 +       arg.end += rdu->sz;
22651 +
22652 +       err = -ENOTDIR;
22653 +       if (unlikely(!file->f_op || !file->f_op->readdir))
22654 +               goto out;
22655 +
22656 +       err = security_file_permission(file, MAY_READ);
22657 +       AuTraceErr(err);
22658 +       if (unlikely(err))
22659 +               goto out;
22660 +
22661 +       dentry = file->f_dentry;
22662 +       inode = dentry->d_inode;
22663 +#if 1
22664 +       mutex_lock(&inode->i_mutex);
22665 +#else
22666 +       err = mutex_lock_killable(&inode->i_mutex);
22667 +       AuTraceErr(err);
22668 +       if (unlikely(err))
22669 +               goto out;
22670 +#endif
22671 +
22672 +       arg.sb = inode->i_sb;
22673 +       err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
22674 +       if (unlikely(err))
22675 +               goto out_mtx;
22676 +       err = au_alive_dir(dentry);
22677 +       if (unlikely(err))
22678 +               goto out_si;
22679 +       /* todo: reval? */
22680 +       fi_read_lock(file);
22681 +
22682 +       err = -EAGAIN;
22683 +       if (unlikely(au_ftest_rdu(cookie->flags, CONT)
22684 +                    && cookie->generation != au_figen(file)))
22685 +               goto out_unlock;
22686 +
22687 +       err = 0;
22688 +       if (!rdu->blk) {
22689 +               rdu->blk = au_sbi(arg.sb)->si_rdblk;
22690 +               if (!rdu->blk)
22691 +                       rdu->blk = au_dir_size(file, /*dentry*/NULL);
22692 +       }
22693 +       bend = au_fbstart(file);
22694 +       if (cookie->bindex < bend)
22695 +               cookie->bindex = bend;
22696 +       bend = au_fbend_dir(file);
22697 +       /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
22698 +       for (; !err && cookie->bindex <= bend;
22699 +            cookie->bindex++, cookie->h_pos = 0) {
22700 +               h_file = au_hf_dir(file, cookie->bindex);
22701 +               if (!h_file)
22702 +                       continue;
22703 +
22704 +               au_fclr_rdu(cookie->flags, FULL);
22705 +               err = au_rdu_do(h_file, &arg);
22706 +               AuTraceErr(err);
22707 +               if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
22708 +                       break;
22709 +       }
22710 +       AuDbg("rent %llu\n", rdu->rent);
22711 +
22712 +       if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
22713 +               rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
22714 +               au_fset_rdu(cookie->flags, CONT);
22715 +               cookie->generation = au_figen(file);
22716 +       }
22717 +
22718 +       ii_read_lock_child(inode);
22719 +       fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
22720 +       ii_read_unlock(inode);
22721 +
22722 +out_unlock:
22723 +       fi_read_unlock(file);
22724 +out_si:
22725 +       si_read_unlock(arg.sb);
22726 +out_mtx:
22727 +       mutex_unlock(&inode->i_mutex);
22728 +out:
22729 +       AuTraceErr(err);
22730 +       return err;
22731 +}
22732 +
22733 +static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
22734 +{
22735 +       int err;
22736 +       ino_t ino;
22737 +       unsigned long long nent;
22738 +       union au_rdu_ent_ul *u;
22739 +       struct au_rdu_ent ent;
22740 +       struct super_block *sb;
22741 +
22742 +       err = 0;
22743 +       nent = rdu->nent;
22744 +       u = &rdu->ent;
22745 +       sb = file->f_dentry->d_sb;
22746 +       si_read_lock(sb, AuLock_FLUSH);
22747 +       while (nent-- > 0) {
22748 +               /* unnecessary to support mmap_sem since this is a dir */
22749 +               err = copy_from_user(&ent, u->e, sizeof(ent));
22750 +               if (!err)
22751 +                       err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
22752 +               if (unlikely(err)) {
22753 +                       err = -EFAULT;
22754 +                       AuTraceErr(err);
22755 +                       break;
22756 +               }
22757 +
22758 +               /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
22759 +               if (!ent.wh)
22760 +                       err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
22761 +               else
22762 +                       err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
22763 +                                       &ino);
22764 +               if (unlikely(err)) {
22765 +                       AuTraceErr(err);
22766 +                       break;
22767 +               }
22768 +
22769 +               err = __put_user(ino, &u->e->ino);
22770 +               if (unlikely(err)) {
22771 +                       err = -EFAULT;
22772 +                       AuTraceErr(err);
22773 +                       break;
22774 +               }
22775 +               u->ul += au_rdu_len(ent.nlen);
22776 +       }
22777 +       si_read_unlock(sb);
22778 +
22779 +       return err;
22780 +}
22781 +
22782 +/* ---------------------------------------------------------------------- */
22783 +
22784 +static int au_rdu_verify(struct aufs_rdu *rdu)
22785 +{
22786 +       AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
22787 +             "%llu, b%d, 0x%x, g%u}\n",
22788 +             rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
22789 +             rdu->blk,
22790 +             rdu->rent, rdu->shwh, rdu->full,
22791 +             rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
22792 +             rdu->cookie.generation);
22793 +
22794 +       if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
22795 +               return 0;
22796 +
22797 +       AuDbg("%u:%u\n",
22798 +             rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
22799 +       return -EINVAL;
22800 +}
22801 +
22802 +long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
22803 +{
22804 +       long err, e;
22805 +       struct aufs_rdu rdu;
22806 +       void __user *p = (void __user *)arg;
22807 +
22808 +       err = copy_from_user(&rdu, p, sizeof(rdu));
22809 +       if (unlikely(err)) {
22810 +               err = -EFAULT;
22811 +               AuTraceErr(err);
22812 +               goto out;
22813 +       }
22814 +       err = au_rdu_verify(&rdu);
22815 +       if (unlikely(err))
22816 +               goto out;
22817 +
22818 +       switch (cmd) {
22819 +       case AUFS_CTL_RDU:
22820 +               err = au_rdu(file, &rdu);
22821 +               if (unlikely(err))
22822 +                       break;
22823 +
22824 +               e = copy_to_user(p, &rdu, sizeof(rdu));
22825 +               if (unlikely(e)) {
22826 +                       err = -EFAULT;
22827 +                       AuTraceErr(err);
22828 +               }
22829 +               break;
22830 +       case AUFS_CTL_RDU_INO:
22831 +               err = au_rdu_ino(file, &rdu);
22832 +               break;
22833 +
22834 +       default:
22835 +               /* err = -ENOTTY; */
22836 +               err = -EINVAL;
22837 +       }
22838 +
22839 +out:
22840 +       AuTraceErr(err);
22841 +       return err;
22842 +}
22843 +
22844 +#ifdef CONFIG_COMPAT
22845 +long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
22846 +{
22847 +       long err, e;
22848 +       struct aufs_rdu rdu;
22849 +       void __user *p = compat_ptr(arg);
22850 +
22851 +       /* todo: get_user()? */
22852 +       err = copy_from_user(&rdu, p, sizeof(rdu));
22853 +       if (unlikely(err)) {
22854 +               err = -EFAULT;
22855 +               AuTraceErr(err);
22856 +               goto out;
22857 +       }
22858 +       rdu.ent.e = compat_ptr(rdu.ent.ul);
22859 +       err = au_rdu_verify(&rdu);
22860 +       if (unlikely(err))
22861 +               goto out;
22862 +
22863 +       switch (cmd) {
22864 +       case AUFS_CTL_RDU:
22865 +               err = au_rdu(file, &rdu);
22866 +               if (unlikely(err))
22867 +                       break;
22868 +
22869 +               rdu.ent.ul = ptr_to_compat(rdu.ent.e);
22870 +               rdu.tail.ul = ptr_to_compat(rdu.tail.e);
22871 +               e = copy_to_user(p, &rdu, sizeof(rdu));
22872 +               if (unlikely(e)) {
22873 +                       err = -EFAULT;
22874 +                       AuTraceErr(err);
22875 +               }
22876 +               break;
22877 +       case AUFS_CTL_RDU_INO:
22878 +               err = au_rdu_ino(file, &rdu);
22879 +               break;
22880 +
22881 +       default:
22882 +               /* err = -ENOTTY; */
22883 +               err = -EINVAL;
22884 +       }
22885 +
22886 +out:
22887 +       AuTraceErr(err);
22888 +       return err;
22889 +}
22890 +#endif
22891 diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
22892 --- /usr/share/empty/fs/aufs/rwsem.h    1970-01-01 01:00:00.000000000 +0100
22893 +++ linux/fs/aufs/rwsem.h       2013-07-06 13:20:47.753531903 +0200
22894 @@ -0,0 +1,188 @@
22895 +/*
22896 + * Copyright (C) 2005-2013 Junjiro R. Okajima
22897 + *
22898 + * This program, aufs is free software; you can redistribute it and/or modify
22899 + * it under the terms of the GNU General Public License as published by
22900 + * the Free Software Foundation; either version 2 of the License, or
22901 + * (at your option) any later version.
22902 + *
22903 + * This program is distributed in the hope that it will be useful,
22904 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22905 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22906 + * GNU General Public License for more details.
22907 + *
22908 + * You should have received a copy of the GNU General Public License
22909 + * along with this program; if not, write to the Free Software
22910 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22911 + */
22912 +
22913 +/*
22914 + * simple read-write semaphore wrappers
22915 + */
22916 +
22917 +#ifndef __AUFS_RWSEM_H__
22918 +#define __AUFS_RWSEM_H__
22919 +
22920 +#ifdef __KERNEL__
22921 +
22922 +#include "debug.h"
22923 +
22924 +struct au_rwsem {
22925 +       struct rw_semaphore     rwsem;
22926 +#ifdef CONFIG_AUFS_DEBUG
22927 +       /* just for debugging, not almighty counter */
22928 +       atomic_t                rcnt, wcnt;
22929 +#endif
22930 +};
22931 +
22932 +#ifdef CONFIG_AUFS_DEBUG
22933 +#define AuDbgCntInit(rw) do { \
22934 +       atomic_set(&(rw)->rcnt, 0); \
22935 +       atomic_set(&(rw)->wcnt, 0); \
22936 +       smp_mb(); /* atomic set */ \
22937 +} while (0)
22938 +
22939 +#define AuDbgRcntInc(rw)       atomic_inc(&(rw)->rcnt)
22940 +#define AuDbgRcntDec(rw)       WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
22941 +#define AuDbgWcntInc(rw)       atomic_inc(&(rw)->wcnt)
22942 +#define AuDbgWcntDec(rw)       WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
22943 +#else
22944 +#define AuDbgCntInit(rw)       do {} while (0)
22945 +#define AuDbgRcntInc(rw)       do {} while (0)
22946 +#define AuDbgRcntDec(rw)       do {} while (0)
22947 +#define AuDbgWcntInc(rw)       do {} while (0)
22948 +#define AuDbgWcntDec(rw)       do {} while (0)
22949 +#endif /* CONFIG_AUFS_DEBUG */
22950 +
22951 +/* to debug easier, do not make them inlined functions */
22952 +#define AuRwMustNoWaiters(rw)  AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
22953 +/* rwsem_is_locked() is unusable */
22954 +#define AuRwMustReadLock(rw)   AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
22955 +#define AuRwMustWriteLock(rw)  AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
22956 +#define AuRwMustAnyLock(rw)    AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
22957 +                                       && atomic_read(&(rw)->wcnt) <= 0)
22958 +#define AuRwDestroy(rw)                AuDebugOn(atomic_read(&(rw)->rcnt) \
22959 +                                       || atomic_read(&(rw)->wcnt))
22960 +
22961 +#define au_rw_class(rw, key)   lockdep_set_class(&(rw)->rwsem, key)
22962 +
22963 +static inline void au_rw_init(struct au_rwsem *rw)
22964 +{
22965 +       AuDbgCntInit(rw);
22966 +       init_rwsem(&rw->rwsem);
22967 +}
22968 +
22969 +static inline void au_rw_init_wlock(struct au_rwsem *rw)
22970 +{
22971 +       au_rw_init(rw);
22972 +       down_write(&rw->rwsem);
22973 +       AuDbgWcntInc(rw);
22974 +}
22975 +
22976 +static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
22977 +                                          unsigned int lsc)
22978 +{
22979 +       au_rw_init(rw);
22980 +       down_write_nested(&rw->rwsem, lsc);
22981 +       AuDbgWcntInc(rw);
22982 +}
22983 +
22984 +static inline void au_rw_read_lock(struct au_rwsem *rw)
22985 +{
22986 +       down_read(&rw->rwsem);
22987 +       AuDbgRcntInc(rw);
22988 +}
22989 +
22990 +static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
22991 +{
22992 +       down_read_nested(&rw->rwsem, lsc);
22993 +       AuDbgRcntInc(rw);
22994 +}
22995 +
22996 +static inline void au_rw_read_unlock(struct au_rwsem *rw)
22997 +{
22998 +       AuRwMustReadLock(rw);
22999 +       AuDbgRcntDec(rw);
23000 +       up_read(&rw->rwsem);
23001 +}
23002 +
23003 +static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
23004 +{
23005 +       AuRwMustWriteLock(rw);
23006 +       AuDbgRcntInc(rw);
23007 +       AuDbgWcntDec(rw);
23008 +       downgrade_write(&rw->rwsem);
23009 +}
23010 +
23011 +static inline void au_rw_write_lock(struct au_rwsem *rw)
23012 +{
23013 +       down_write(&rw->rwsem);
23014 +       AuDbgWcntInc(rw);
23015 +}
23016 +
23017 +static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
23018 +                                          unsigned int lsc)
23019 +{
23020 +       down_write_nested(&rw->rwsem, lsc);
23021 +       AuDbgWcntInc(rw);
23022 +}
23023 +
23024 +static inline void au_rw_write_unlock(struct au_rwsem *rw)
23025 +{
23026 +       AuRwMustWriteLock(rw);
23027 +       AuDbgWcntDec(rw);
23028 +       up_write(&rw->rwsem);
23029 +}
23030 +
23031 +/* why is not _nested version defined */
23032 +static inline int au_rw_read_trylock(struct au_rwsem *rw)
23033 +{
23034 +       int ret = down_read_trylock(&rw->rwsem);
23035 +       if (ret)
23036 +               AuDbgRcntInc(rw);
23037 +       return ret;
23038 +}
23039 +
23040 +static inline int au_rw_write_trylock(struct au_rwsem *rw)
23041 +{
23042 +       int ret = down_write_trylock(&rw->rwsem);
23043 +       if (ret)
23044 +               AuDbgWcntInc(rw);
23045 +       return ret;
23046 +}
23047 +
23048 +#undef AuDbgCntInit
23049 +#undef AuDbgRcntInc
23050 +#undef AuDbgRcntDec
23051 +#undef AuDbgWcntInc
23052 +#undef AuDbgWcntDec
23053 +
23054 +#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
23055 +static inline void prefix##_read_lock(param) \
23056 +{ au_rw_read_lock(rwsem); } \
23057 +static inline void prefix##_write_lock(param) \
23058 +{ au_rw_write_lock(rwsem); } \
23059 +static inline int prefix##_read_trylock(param) \
23060 +{ return au_rw_read_trylock(rwsem); } \
23061 +static inline int prefix##_write_trylock(param) \
23062 +{ return au_rw_write_trylock(rwsem); }
23063 +/* why is not _nested version defined */
23064 +/* static inline void prefix##_read_trylock_nested(param, lsc)
23065 +{ au_rw_read_trylock_nested(rwsem, lsc)); }
23066 +static inline void prefix##_write_trylock_nestd(param, lsc)
23067 +{ au_rw_write_trylock_nested(rwsem, lsc); } */
23068 +
23069 +#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
23070 +static inline void prefix##_read_unlock(param) \
23071 +{ au_rw_read_unlock(rwsem); } \
23072 +static inline void prefix##_write_unlock(param) \
23073 +{ au_rw_write_unlock(rwsem); } \
23074 +static inline void prefix##_downgrade_lock(param) \
23075 +{ au_rw_dgrade_lock(rwsem); }
23076 +
23077 +#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
23078 +       AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
23079 +       AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
23080 +
23081 +#endif /* __KERNEL__ */
23082 +#endif /* __AUFS_RWSEM_H__ */
23083 diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
23084 --- /usr/share/empty/fs/aufs/sbinfo.c   1970-01-01 01:00:00.000000000 +0100
23085 +++ linux/fs/aufs/sbinfo.c      2013-07-06 13:20:47.753531903 +0200
23086 @@ -0,0 +1,346 @@
23087 +/*
23088 + * Copyright (C) 2005-2013 Junjiro R. Okajima
23089 + *
23090 + * This program, aufs is free software; you can redistribute it and/or modify
23091 + * it under the terms of the GNU General Public License as published by
23092 + * the Free Software Foundation; either version 2 of the License, or
23093 + * (at your option) any later version.
23094 + *
23095 + * This program is distributed in the hope that it will be useful,
23096 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23097 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23098 + * GNU General Public License for more details.
23099 + *
23100 + * You should have received a copy of the GNU General Public License
23101 + * along with this program; if not, write to the Free Software
23102 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23103 + */
23104 +
23105 +/*
23106 + * superblock private data
23107 + */
23108 +
23109 +#include "aufs.h"
23110 +
23111 +/*
23112 + * they are necessary regardless sysfs is disabled.
23113 + */
23114 +void au_si_free(struct kobject *kobj)
23115 +{
23116 +       int i;
23117 +       struct au_sbinfo *sbinfo;
23118 +       char *locked __maybe_unused; /* debug only */
23119 +
23120 +       sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
23121 +       for (i = 0; i < AuPlink_NHASH; i++)
23122 +               AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
23123 +       AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
23124 +
23125 +       au_rw_write_lock(&sbinfo->si_rwsem);
23126 +       au_br_free(sbinfo);
23127 +       au_rw_write_unlock(&sbinfo->si_rwsem);
23128 +
23129 +       AuDebugOn(radix_tree_gang_lookup
23130 +                 (&sbinfo->au_si_pid.tree, (void **)&locked,
23131 +                  /*first_index*/PID_MAX_DEFAULT - 1,
23132 +                  /*max_items*/sizeof(locked)/sizeof(*locked)));
23133 +
23134 +       kfree(sbinfo->si_branch);
23135 +       kfree(sbinfo->au_si_pid.bitmap);
23136 +       mutex_destroy(&sbinfo->si_xib_mtx);
23137 +       AuRwDestroy(&sbinfo->si_rwsem);
23138 +
23139 +       kfree(sbinfo);
23140 +}
23141 +
23142 +int au_si_alloc(struct super_block *sb)
23143 +{
23144 +       int err, i;
23145 +       struct au_sbinfo *sbinfo;
23146 +       static struct lock_class_key aufs_si;
23147 +
23148 +       err = -ENOMEM;
23149 +       sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
23150 +       if (unlikely(!sbinfo))
23151 +               goto out;
23152 +
23153 +       BUILD_BUG_ON(sizeof(unsigned long) !=
23154 +                    sizeof(*sbinfo->au_si_pid.bitmap));
23155 +       sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
23156 +                                       sizeof(*sbinfo->au_si_pid.bitmap),
23157 +                                       GFP_NOFS);
23158 +       if (unlikely(!sbinfo->au_si_pid.bitmap))
23159 +               goto out_sbinfo;
23160 +
23161 +       /* will be reallocated separately */
23162 +       sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
23163 +       if (unlikely(!sbinfo->si_branch))
23164 +               goto out_pidmap;
23165 +
23166 +       err = sysaufs_si_init(sbinfo);
23167 +       if (unlikely(err))
23168 +               goto out_br;
23169 +
23170 +       au_nwt_init(&sbinfo->si_nowait);
23171 +       au_rw_init_wlock(&sbinfo->si_rwsem);
23172 +       au_rw_class(&sbinfo->si_rwsem, &aufs_si);
23173 +       spin_lock_init(&sbinfo->au_si_pid.tree_lock);
23174 +       INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
23175 +
23176 +       atomic_long_set(&sbinfo->si_ninodes, 0);
23177 +       atomic_long_set(&sbinfo->si_nfiles, 0);
23178 +
23179 +       sbinfo->si_bend = -1;
23180 +
23181 +       sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
23182 +       sbinfo->si_wbr_create = AuWbrCreate_Def;
23183 +       sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
23184 +       sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
23185 +
23186 +       sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
23187 +
23188 +       mutex_init(&sbinfo->si_xib_mtx);
23189 +       sbinfo->si_xino_brid = -1;
23190 +       /* leave si_xib_last_pindex and si_xib_next_bit */
23191 +
23192 +       sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
23193 +       sbinfo->si_rdblk = AUFS_RDBLK_DEF;
23194 +       sbinfo->si_rdhash = AUFS_RDHASH_DEF;
23195 +       sbinfo->si_dirwh = AUFS_DIRWH_DEF;
23196 +
23197 +       for (i = 0; i < AuPlink_NHASH; i++)
23198 +               au_sphl_init(sbinfo->si_plink + i);
23199 +       init_waitqueue_head(&sbinfo->si_plink_wq);
23200 +       spin_lock_init(&sbinfo->si_plink_maint_lock);
23201 +
23202 +       /* leave other members for sysaufs and si_mnt. */
23203 +       sbinfo->si_sb = sb;
23204 +       sb->s_fs_info = sbinfo;
23205 +       si_pid_set(sb);
23206 +       au_debug_sbinfo_init(sbinfo);
23207 +       return 0; /* success */
23208 +
23209 +out_br:
23210 +       kfree(sbinfo->si_branch);
23211 +out_pidmap:
23212 +       kfree(sbinfo->au_si_pid.bitmap);
23213 +out_sbinfo:
23214 +       kfree(sbinfo);
23215 +out:
23216 +       return err;
23217 +}
23218 +
23219 +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
23220 +{
23221 +       int err, sz;
23222 +       struct au_branch **brp;
23223 +
23224 +       AuRwMustWriteLock(&sbinfo->si_rwsem);
23225 +
23226 +       err = -ENOMEM;
23227 +       sz = sizeof(*brp) * (sbinfo->si_bend + 1);
23228 +       if (unlikely(!sz))
23229 +               sz = sizeof(*brp);
23230 +       brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
23231 +       if (brp) {
23232 +               sbinfo->si_branch = brp;
23233 +               err = 0;
23234 +       }
23235 +
23236 +       return err;
23237 +}
23238 +
23239 +/* ---------------------------------------------------------------------- */
23240 +
23241 +unsigned int au_sigen_inc(struct super_block *sb)
23242 +{
23243 +       unsigned int gen;
23244 +
23245 +       SiMustWriteLock(sb);
23246 +
23247 +       gen = ++au_sbi(sb)->si_generation;
23248 +       au_update_digen(sb->s_root);
23249 +       au_update_iigen(sb->s_root->d_inode, /*half*/0);
23250 +       sb->s_root->d_inode->i_version++;
23251 +       return gen;
23252 +}
23253 +
23254 +aufs_bindex_t au_new_br_id(struct super_block *sb)
23255 +{
23256 +       aufs_bindex_t br_id;
23257 +       int i;
23258 +       struct au_sbinfo *sbinfo;
23259 +
23260 +       SiMustWriteLock(sb);
23261 +
23262 +       sbinfo = au_sbi(sb);
23263 +       for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
23264 +               br_id = ++sbinfo->si_last_br_id;
23265 +               AuDebugOn(br_id < 0);
23266 +               if (br_id && au_br_index(sb, br_id) < 0)
23267 +                       return br_id;
23268 +       }
23269 +
23270 +       return -1;
23271 +}
23272 +
23273 +/* ---------------------------------------------------------------------- */
23274 +
23275 +/* it is ok that new 'nwt' tasks are appended while we are sleeping */
23276 +int si_read_lock(struct super_block *sb, int flags)
23277 +{
23278 +       int err;
23279 +
23280 +       err = 0;
23281 +       if (au_ftest_lock(flags, FLUSH))
23282 +               au_nwt_flush(&au_sbi(sb)->si_nowait);
23283 +
23284 +       si_noflush_read_lock(sb);
23285 +       err = au_plink_maint(sb, flags);
23286 +       if (unlikely(err))
23287 +               si_read_unlock(sb);
23288 +
23289 +       return err;
23290 +}
23291 +
23292 +int si_write_lock(struct super_block *sb, int flags)
23293 +{
23294 +       int err;
23295 +
23296 +       if (au_ftest_lock(flags, FLUSH))
23297 +               au_nwt_flush(&au_sbi(sb)->si_nowait);
23298 +
23299 +       si_noflush_write_lock(sb);
23300 +       err = au_plink_maint(sb, flags);
23301 +       if (unlikely(err))
23302 +               si_write_unlock(sb);
23303 +
23304 +       return err;
23305 +}
23306 +
23307 +/* dentry and super_block lock. call at entry point */
23308 +int aufs_read_lock(struct dentry *dentry, int flags)
23309 +{
23310 +       int err;
23311 +       struct super_block *sb;
23312 +
23313 +       sb = dentry->d_sb;
23314 +       err = si_read_lock(sb, flags);
23315 +       if (unlikely(err))
23316 +               goto out;
23317 +
23318 +       if (au_ftest_lock(flags, DW))
23319 +               di_write_lock_child(dentry);
23320 +       else
23321 +               di_read_lock_child(dentry, flags);
23322 +
23323 +       if (au_ftest_lock(flags, GEN)) {
23324 +               err = au_digen_test(dentry, au_sigen(sb));
23325 +               AuDebugOn(!err && au_dbrange_test(dentry));
23326 +               if (unlikely(err))
23327 +                       aufs_read_unlock(dentry, flags);
23328 +       }
23329 +
23330 +out:
23331 +       return err;
23332 +}
23333 +
23334 +void aufs_read_unlock(struct dentry *dentry, int flags)
23335 +{
23336 +       if (au_ftest_lock(flags, DW))
23337 +               di_write_unlock(dentry);
23338 +       else
23339 +               di_read_unlock(dentry, flags);
23340 +       si_read_unlock(dentry->d_sb);
23341 +}
23342 +
23343 +void aufs_write_lock(struct dentry *dentry)
23344 +{
23345 +       si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
23346 +       di_write_lock_child(dentry);
23347 +}
23348 +
23349 +void aufs_write_unlock(struct dentry *dentry)
23350 +{
23351 +       di_write_unlock(dentry);
23352 +       si_write_unlock(dentry->d_sb);
23353 +}
23354 +
23355 +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
23356 +{
23357 +       int err;
23358 +       unsigned int sigen;
23359 +       struct super_block *sb;
23360 +
23361 +       sb = d1->d_sb;
23362 +       err = si_read_lock(sb, flags);
23363 +       if (unlikely(err))
23364 +               goto out;
23365 +
23366 +       di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
23367 +
23368 +       if (au_ftest_lock(flags, GEN)) {
23369 +               sigen = au_sigen(sb);
23370 +               err = au_digen_test(d1, sigen);
23371 +               AuDebugOn(!err && au_dbrange_test(d1));
23372 +               if (!err) {
23373 +                       err = au_digen_test(d2, sigen);
23374 +                       AuDebugOn(!err && au_dbrange_test(d2));
23375 +               }
23376 +               if (unlikely(err))
23377 +                       aufs_read_and_write_unlock2(d1, d2);
23378 +       }
23379 +
23380 +out:
23381 +       return err;
23382 +}
23383 +
23384 +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
23385 +{
23386 +       di_write_unlock2(d1, d2);
23387 +       si_read_unlock(d1->d_sb);
23388 +}
23389 +
23390 +/* ---------------------------------------------------------------------- */
23391 +
23392 +int si_pid_test_slow(struct super_block *sb)
23393 +{
23394 +       void *p;
23395 +
23396 +       rcu_read_lock();
23397 +       p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
23398 +       rcu_read_unlock();
23399 +
23400 +       return (long)!!p;
23401 +}
23402 +
23403 +void si_pid_set_slow(struct super_block *sb)
23404 +{
23405 +       int err;
23406 +       struct au_sbinfo *sbinfo;
23407 +
23408 +       AuDebugOn(si_pid_test_slow(sb));
23409 +
23410 +       sbinfo = au_sbi(sb);
23411 +       err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
23412 +       AuDebugOn(err);
23413 +       spin_lock(&sbinfo->au_si_pid.tree_lock);
23414 +       err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
23415 +                               /*any valid ptr*/sb);
23416 +       spin_unlock(&sbinfo->au_si_pid.tree_lock);
23417 +       AuDebugOn(err);
23418 +       radix_tree_preload_end();
23419 +}
23420 +
23421 +void si_pid_clr_slow(struct super_block *sb)
23422 +{
23423 +       void *p;
23424 +       struct au_sbinfo *sbinfo;
23425 +
23426 +       AuDebugOn(!si_pid_test_slow(sb));
23427 +
23428 +       sbinfo = au_sbi(sb);
23429 +       spin_lock(&sbinfo->au_si_pid.tree_lock);
23430 +       p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
23431 +       spin_unlock(&sbinfo->au_si_pid.tree_lock);
23432 +}
23433 diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
23434 --- /usr/share/empty/fs/aufs/spl.h      1970-01-01 01:00:00.000000000 +0100
23435 +++ linux/fs/aufs/spl.h 2013-07-06 13:20:47.753531903 +0200
23436 @@ -0,0 +1,112 @@
23437 +/*
23438 + * Copyright (C) 2005-2013 Junjiro R. Okajima
23439 + *
23440 + * This program, aufs is free software; you can redistribute it and/or modify
23441 + * it under the terms of the GNU General Public License as published by
23442 + * the Free Software Foundation; either version 2 of the License, or
23443 + * (at your option) any later version.
23444 + *
23445 + * This program is distributed in the hope that it will be useful,
23446 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23447 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23448 + * GNU General Public License for more details.
23449 + *
23450 + * You should have received a copy of the GNU General Public License
23451 + * along with this program; if not, write to the Free Software
23452 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23453 + */
23454 +
23455 +/*
23456 + * simple list protected by a spinlock
23457 + */
23458 +
23459 +#ifndef __AUFS_SPL_H__
23460 +#define __AUFS_SPL_H__
23461 +
23462 +#ifdef __KERNEL__
23463 +
23464 +struct au_splhead {
23465 +       spinlock_t              spin;
23466 +       struct list_head        head;
23467 +};
23468 +
23469 +static inline void au_spl_init(struct au_splhead *spl)
23470 +{
23471 +       spin_lock_init(&spl->spin);
23472 +       INIT_LIST_HEAD(&spl->head);
23473 +}
23474 +
23475 +static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
23476 +{
23477 +       spin_lock(&spl->spin);
23478 +       list_add(list, &spl->head);
23479 +       spin_unlock(&spl->spin);
23480 +}
23481 +
23482 +static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
23483 +{
23484 +       spin_lock(&spl->spin);
23485 +       list_del(list);
23486 +       spin_unlock(&spl->spin);
23487 +}
23488 +
23489 +static inline void au_spl_del_rcu(struct list_head *list,
23490 +                                 struct au_splhead *spl)
23491 +{
23492 +       spin_lock(&spl->spin);
23493 +       list_del_rcu(list);
23494 +       spin_unlock(&spl->spin);
23495 +}
23496 +
23497 +/* ---------------------------------------------------------------------- */
23498 +
23499 +struct au_sphlhead {
23500 +       spinlock_t              spin;
23501 +       struct hlist_head       head;
23502 +};
23503 +
23504 +static inline void au_sphl_init(struct au_sphlhead *sphl)
23505 +{
23506 +       spin_lock_init(&sphl->spin);
23507 +       INIT_HLIST_HEAD(&sphl->head);
23508 +}
23509 +
23510 +static inline void au_sphl_add(struct hlist_node *hlist,
23511 +                              struct au_sphlhead *sphl)
23512 +{
23513 +       spin_lock(&sphl->spin);
23514 +       hlist_add_head(hlist, &sphl->head);
23515 +       spin_unlock(&sphl->spin);
23516 +}
23517 +
23518 +static inline void au_sphl_del(struct hlist_node *hlist,
23519 +                              struct au_sphlhead *sphl)
23520 +{
23521 +       spin_lock(&sphl->spin);
23522 +       hlist_del(hlist);
23523 +       spin_unlock(&sphl->spin);
23524 +}
23525 +
23526 +static inline void au_sphl_del_rcu(struct hlist_node *hlist,
23527 +                                  struct au_sphlhead *sphl)
23528 +{
23529 +       spin_lock(&sphl->spin);
23530 +       hlist_del_rcu(hlist);
23531 +       spin_unlock(&sphl->spin);
23532 +}
23533 +
23534 +static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
23535 +{
23536 +       unsigned long cnt;
23537 +       struct hlist_node *pos;
23538 +
23539 +       cnt = 0;
23540 +       spin_lock(&sphl->spin);
23541 +       hlist_for_each(pos, &sphl->head)
23542 +               cnt++;
23543 +       spin_unlock(&sphl->spin);
23544 +       return cnt;
23545 +}
23546 +
23547 +#endif /* __KERNEL__ */
23548 +#endif /* __AUFS_SPL_H__ */
23549 diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
23550 --- /usr/share/empty/fs/aufs/super.c    1970-01-01 01:00:00.000000000 +0100
23551 +++ linux/fs/aufs/super.c       2013-07-06 13:20:47.753531903 +0200
23552 @@ -0,0 +1,992 @@
23553 +/*
23554 + * Copyright (C) 2005-2013 Junjiro R. Okajima
23555 + *
23556 + * This program, aufs is free software; you can redistribute it and/or modify
23557 + * it under the terms of the GNU General Public License as published by
23558 + * the Free Software Foundation; either version 2 of the License, or
23559 + * (at your option) any later version.
23560 + *
23561 + * This program is distributed in the hope that it will be useful,
23562 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23563 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23564 + * GNU General Public License for more details.
23565 + *
23566 + * You should have received a copy of the GNU General Public License
23567 + * along with this program; if not, write to the Free Software
23568 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23569 + */
23570 +
23571 +/*
23572 + * mount and super_block operations
23573 + */
23574 +
23575 +#include <linux/mm.h>
23576 +#include <linux/module.h>
23577 +#include <linux/seq_file.h>
23578 +#include <linux/statfs.h>
23579 +#include <linux/vmalloc.h>
23580 +#include <linux/writeback.h>
23581 +#include "aufs.h"
23582 +
23583 +/*
23584 + * super_operations
23585 + */
23586 +static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
23587 +{
23588 +       struct au_icntnr *c;
23589 +
23590 +       c = au_cache_alloc_icntnr();
23591 +       if (c) {
23592 +               au_icntnr_init(c);
23593 +               c->vfs_inode.i_version = 1; /* sigen(sb); */
23594 +               c->iinfo.ii_hinode = NULL;
23595 +               return &c->vfs_inode;
23596 +       }
23597 +       return NULL;
23598 +}
23599 +
23600 +static void aufs_destroy_inode_cb(struct rcu_head *head)
23601 +{
23602 +       struct inode *inode = container_of(head, struct inode, i_rcu);
23603 +
23604 +       INIT_HLIST_HEAD(&inode->i_dentry);
23605 +       au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
23606 +}
23607 +
23608 +static void aufs_destroy_inode(struct inode *inode)
23609 +{
23610 +       au_iinfo_fin(inode);
23611 +       call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
23612 +}
23613 +
23614 +struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
23615 +{
23616 +       struct inode *inode;
23617 +       int err;
23618 +
23619 +       inode = iget_locked(sb, ino);
23620 +       if (unlikely(!inode)) {
23621 +               inode = ERR_PTR(-ENOMEM);
23622 +               goto out;
23623 +       }
23624 +       if (!(inode->i_state & I_NEW))
23625 +               goto out;
23626 +
23627 +       err = au_xigen_new(inode);
23628 +       if (!err)
23629 +               err = au_iinfo_init(inode);
23630 +       if (!err)
23631 +               inode->i_version++;
23632 +       else {
23633 +               iget_failed(inode);
23634 +               inode = ERR_PTR(err);
23635 +       }
23636 +
23637 +out:
23638 +       /* never return NULL */
23639 +       AuDebugOn(!inode);
23640 +       AuTraceErrPtr(inode);
23641 +       return inode;
23642 +}
23643 +
23644 +/* lock free root dinfo */
23645 +static int au_show_brs(struct seq_file *seq, struct super_block *sb)
23646 +{
23647 +       int err;
23648 +       aufs_bindex_t bindex, bend;
23649 +       struct path path;
23650 +       struct au_hdentry *hdp;
23651 +       struct au_branch *br;
23652 +       char *perm;
23653 +
23654 +       err = 0;
23655 +       bend = au_sbend(sb);
23656 +       hdp = au_di(sb->s_root)->di_hdentry;
23657 +       for (bindex = 0; !err && bindex <= bend; bindex++) {
23658 +               br = au_sbr(sb, bindex);
23659 +               path.mnt = au_br_mnt(br);
23660 +               path.dentry = hdp[bindex].hd_dentry;
23661 +               err = au_seq_path(seq, &path);
23662 +               if (err > 0) {
23663 +                       perm = au_optstr_br_perm(br->br_perm);
23664 +                       if (perm) {
23665 +                               err = seq_printf(seq, "=%s", perm);
23666 +                               kfree(perm);
23667 +                               if (err == -1)
23668 +                                       err = -E2BIG;
23669 +                       } else
23670 +                               err = -ENOMEM;
23671 +               }
23672 +               if (!err && bindex != bend)
23673 +                       err = seq_putc(seq, ':');
23674 +       }
23675 +
23676 +       return err;
23677 +}
23678 +
23679 +static void au_show_wbr_create(struct seq_file *m, int v,
23680 +                              struct au_sbinfo *sbinfo)
23681 +{
23682 +       const char *pat;
23683 +
23684 +       AuRwMustAnyLock(&sbinfo->si_rwsem);
23685 +
23686 +       seq_printf(m, ",create=");
23687 +       pat = au_optstr_wbr_create(v);
23688 +       switch (v) {
23689 +       case AuWbrCreate_TDP:
23690 +       case AuWbrCreate_RR:
23691 +       case AuWbrCreate_MFS:
23692 +       case AuWbrCreate_PMFS:
23693 +               seq_printf(m, pat);
23694 +               break;
23695 +       case AuWbrCreate_MFSV:
23696 +               seq_printf(m, /*pat*/"mfs:%lu",
23697 +                          jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23698 +                          / MSEC_PER_SEC);
23699 +               break;
23700 +       case AuWbrCreate_PMFSV:
23701 +               seq_printf(m, /*pat*/"pmfs:%lu",
23702 +                          jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23703 +                          / MSEC_PER_SEC);
23704 +               break;
23705 +       case AuWbrCreate_MFSRR:
23706 +               seq_printf(m, /*pat*/"mfsrr:%llu",
23707 +                          sbinfo->si_wbr_mfs.mfsrr_watermark);
23708 +               break;
23709 +       case AuWbrCreate_MFSRRV:
23710 +               seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
23711 +                          sbinfo->si_wbr_mfs.mfsrr_watermark,
23712 +                          jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23713 +                          / MSEC_PER_SEC);
23714 +               break;
23715 +       }
23716 +}
23717 +
23718 +static int au_show_xino(struct seq_file *seq, struct super_block *sb)
23719 +{
23720 +#ifdef CONFIG_SYSFS
23721 +       return 0;
23722 +#else
23723 +       int err;
23724 +       const int len = sizeof(AUFS_XINO_FNAME) - 1;
23725 +       aufs_bindex_t bindex, brid;
23726 +       struct qstr *name;
23727 +       struct file *f;
23728 +       struct dentry *d, *h_root;
23729 +       struct au_hdentry *hdp;
23730 +
23731 +       AuRwMustAnyLock(&sbinfo->si_rwsem);
23732 +
23733 +       err = 0;
23734 +       f = au_sbi(sb)->si_xib;
23735 +       if (!f)
23736 +               goto out;
23737 +
23738 +       /* stop printing the default xino path on the first writable branch */
23739 +       h_root = NULL;
23740 +       brid = au_xino_brid(sb);
23741 +       if (brid >= 0) {
23742 +               bindex = au_br_index(sb, brid);
23743 +               hdp = au_di(sb->s_root)->di_hdentry;
23744 +               h_root = hdp[0 + bindex].hd_dentry;
23745 +       }
23746 +       d = f->f_dentry;
23747 +       name = &d->d_name;
23748 +       /* safe ->d_parent because the file is unlinked */
23749 +       if (d->d_parent == h_root
23750 +           && name->len == len
23751 +           && !memcmp(name->name, AUFS_XINO_FNAME, len))
23752 +               goto out;
23753 +
23754 +       seq_puts(seq, ",xino=");
23755 +       err = au_xino_path(seq, f);
23756 +
23757 +out:
23758 +       return err;
23759 +#endif
23760 +}
23761 +
23762 +/* seq_file will re-call me in case of too long string */
23763 +static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
23764 +{
23765 +       int err;
23766 +       unsigned int mnt_flags, v;
23767 +       struct super_block *sb;
23768 +       struct au_sbinfo *sbinfo;
23769 +
23770 +#define AuBool(name, str) do { \
23771 +       v = au_opt_test(mnt_flags, name); \
23772 +       if (v != au_opt_test(AuOpt_Def, name)) \
23773 +               seq_printf(m, ",%s" #str, v ? "" : "no"); \
23774 +} while (0)
23775 +
23776 +#define AuStr(name, str) do { \
23777 +       v = mnt_flags & AuOptMask_##name; \
23778 +       if (v != (AuOpt_Def & AuOptMask_##name)) \
23779 +               seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
23780 +} while (0)
23781 +
23782 +#define AuUInt(name, str, val) do { \
23783 +       if (val != AUFS_##name##_DEF) \
23784 +               seq_printf(m, "," #str "=%u", val); \
23785 +} while (0)
23786 +
23787 +       /* lock free root dinfo */
23788 +       sb = dentry->d_sb;
23789 +       si_noflush_read_lock(sb);
23790 +       sbinfo = au_sbi(sb);
23791 +       seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
23792 +
23793 +       mnt_flags = au_mntflags(sb);
23794 +       if (au_opt_test(mnt_flags, XINO)) {
23795 +               err = au_show_xino(m, sb);
23796 +               if (unlikely(err))
23797 +                       goto out;
23798 +       } else
23799 +               seq_puts(m, ",noxino");
23800 +
23801 +       AuBool(TRUNC_XINO, trunc_xino);
23802 +       AuStr(UDBA, udba);
23803 +       AuBool(SHWH, shwh);
23804 +       AuBool(PLINK, plink);
23805 +       AuBool(DIO, dio);
23806 +       /* AuBool(DIRPERM1, dirperm1); */
23807 +       /* AuBool(REFROF, refrof); */
23808 +
23809 +       v = sbinfo->si_wbr_create;
23810 +       if (v != AuWbrCreate_Def)
23811 +               au_show_wbr_create(m, v, sbinfo);
23812 +
23813 +       v = sbinfo->si_wbr_copyup;
23814 +       if (v != AuWbrCopyup_Def)
23815 +               seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
23816 +
23817 +       v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
23818 +       if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
23819 +               seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
23820 +
23821 +       AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
23822 +
23823 +       v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
23824 +       AuUInt(RDCACHE, rdcache, v);
23825 +
23826 +       AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
23827 +       AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
23828 +
23829 +       AuBool(SUM, sum);
23830 +       /* AuBool(SUM_W, wsum); */
23831 +       AuBool(WARN_PERM, warn_perm);
23832 +       AuBool(VERBOSE, verbose);
23833 +
23834 +out:
23835 +       /* be sure to print "br:" last */
23836 +       if (!sysaufs_brs) {
23837 +               seq_puts(m, ",br:");
23838 +               au_show_brs(m, sb);
23839 +       }
23840 +       si_read_unlock(sb);
23841 +       return 0;
23842 +
23843 +#undef AuBool
23844 +#undef AuStr
23845 +#undef AuUInt
23846 +}
23847 +
23848 +/* ---------------------------------------------------------------------- */
23849 +
23850 +/* sum mode which returns the summation for statfs(2) */
23851 +
23852 +static u64 au_add_till_max(u64 a, u64 b)
23853 +{
23854 +       u64 old;
23855 +
23856 +       old = a;
23857 +       a += b;
23858 +       if (old <= a)
23859 +               return a;
23860 +       return ULLONG_MAX;
23861 +}
23862 +
23863 +static u64 au_mul_till_max(u64 a, long mul)
23864 +{
23865 +       u64 old;
23866 +
23867 +       old = a;
23868 +       a *= mul;
23869 +       if (old <= a)
23870 +               return a;
23871 +       return ULLONG_MAX;
23872 +}
23873 +
23874 +static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
23875 +{
23876 +       int err;
23877 +       long bsize, factor;
23878 +       u64 blocks, bfree, bavail, files, ffree;
23879 +       aufs_bindex_t bend, bindex, i;
23880 +       unsigned char shared;
23881 +       struct path h_path;
23882 +       struct super_block *h_sb;
23883 +
23884 +       err = 0;
23885 +       bsize = LONG_MAX;
23886 +       files = 0;
23887 +       ffree = 0;
23888 +       blocks = 0;
23889 +       bfree = 0;
23890 +       bavail = 0;
23891 +       bend = au_sbend(sb);
23892 +       for (bindex = 0; bindex <= bend; bindex++) {
23893 +               h_path.mnt = au_sbr_mnt(sb, bindex);
23894 +               h_sb = h_path.mnt->mnt_sb;
23895 +               shared = 0;
23896 +               for (i = 0; !shared && i < bindex; i++)
23897 +                       shared = (au_sbr_sb(sb, i) == h_sb);
23898 +               if (shared)
23899 +                       continue;
23900 +
23901 +               /* sb->s_root for NFS is unreliable */
23902 +               h_path.dentry = h_path.mnt->mnt_root;
23903 +               err = vfs_statfs(&h_path, buf);
23904 +               if (unlikely(err))
23905 +                       goto out;
23906 +
23907 +               if (bsize > buf->f_bsize) {
23908 +                       /*
23909 +                        * we will reduce bsize, so we have to expand blocks
23910 +                        * etc. to match them again
23911 +                        */
23912 +                       factor = (bsize / buf->f_bsize);
23913 +                       blocks = au_mul_till_max(blocks, factor);
23914 +                       bfree = au_mul_till_max(bfree, factor);
23915 +                       bavail = au_mul_till_max(bavail, factor);
23916 +                       bsize = buf->f_bsize;
23917 +               }
23918 +
23919 +               factor = (buf->f_bsize / bsize);
23920 +               blocks = au_add_till_max(blocks,
23921 +                               au_mul_till_max(buf->f_blocks, factor));
23922 +               bfree = au_add_till_max(bfree,
23923 +                               au_mul_till_max(buf->f_bfree, factor));
23924 +               bavail = au_add_till_max(bavail,
23925 +                               au_mul_till_max(buf->f_bavail, factor));
23926 +               files = au_add_till_max(files, buf->f_files);
23927 +               ffree = au_add_till_max(ffree, buf->f_ffree);
23928 +       }
23929 +
23930 +       buf->f_bsize = bsize;
23931 +       buf->f_blocks = blocks;
23932 +       buf->f_bfree = bfree;
23933 +       buf->f_bavail = bavail;
23934 +       buf->f_files = files;
23935 +       buf->f_ffree = ffree;
23936 +       buf->f_frsize = 0;
23937 +
23938 +out:
23939 +       return err;
23940 +}
23941 +
23942 +static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
23943 +{
23944 +       int err;
23945 +       struct path h_path;
23946 +       struct super_block *sb;
23947 +
23948 +       /* lock free root dinfo */
23949 +       sb = dentry->d_sb;
23950 +       si_noflush_read_lock(sb);
23951 +       if (!au_opt_test(au_mntflags(sb), SUM)) {
23952 +               /* sb->s_root for NFS is unreliable */
23953 +               h_path.mnt = au_sbr_mnt(sb, 0);
23954 +               h_path.dentry = h_path.mnt->mnt_root;
23955 +               err = vfs_statfs(&h_path, buf);
23956 +       } else
23957 +               err = au_statfs_sum(sb, buf);
23958 +       si_read_unlock(sb);
23959 +
23960 +       if (!err) {
23961 +               buf->f_type = AUFS_SUPER_MAGIC;
23962 +               buf->f_namelen = AUFS_MAX_NAMELEN;
23963 +               memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
23964 +       }
23965 +       /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
23966 +
23967 +       return err;
23968 +}
23969 +
23970 +/* ---------------------------------------------------------------------- */
23971 +
23972 +static int aufs_sync_fs(struct super_block *sb, int wait)
23973 +{
23974 +       int err, e;
23975 +       aufs_bindex_t bend, bindex;
23976 +       struct au_branch *br;
23977 +       struct super_block *h_sb;
23978 +
23979 +       err = 0;
23980 +       si_noflush_read_lock(sb);
23981 +       bend = au_sbend(sb);
23982 +       for (bindex = 0; bindex <= bend; bindex++) {
23983 +               br = au_sbr(sb, bindex);
23984 +               if (!au_br_writable(br->br_perm))
23985 +                       continue;
23986 +
23987 +               h_sb = au_sbr_sb(sb, bindex);
23988 +               if (h_sb->s_op->sync_fs) {
23989 +                       e = h_sb->s_op->sync_fs(h_sb, wait);
23990 +                       if (unlikely(e && !err))
23991 +                               err = e;
23992 +                       /* go on even if an error happens */
23993 +               }
23994 +       }
23995 +       si_read_unlock(sb);
23996 +
23997 +       return err;
23998 +}
23999 +
24000 +/* ---------------------------------------------------------------------- */
24001 +
24002 +/* final actions when unmounting a file system */
24003 +static void aufs_put_super(struct super_block *sb)
24004 +{
24005 +       struct au_sbinfo *sbinfo;
24006 +
24007 +       sbinfo = au_sbi(sb);
24008 +       if (!sbinfo)
24009 +               return;
24010 +
24011 +       dbgaufs_si_fin(sbinfo);
24012 +       kobject_put(&sbinfo->si_kobj);
24013 +}
24014 +
24015 +/* ---------------------------------------------------------------------- */
24016 +
24017 +void au_array_free(void *array)
24018 +{
24019 +       if (array) {
24020 +               if (!is_vmalloc_addr(array))
24021 +                       kfree(array);
24022 +               else
24023 +                       vfree(array);
24024 +       }
24025 +}
24026 +
24027 +void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
24028 +{
24029 +       void *array;
24030 +       unsigned long long n;
24031 +
24032 +       array = NULL;
24033 +       n = 0;
24034 +       if (!*hint)
24035 +               goto out;
24036 +
24037 +       if (*hint > ULLONG_MAX / sizeof(array)) {
24038 +               array = ERR_PTR(-EMFILE);
24039 +               pr_err("hint %llu\n", *hint);
24040 +               goto out;
24041 +       }
24042 +
24043 +       array = kmalloc(sizeof(array) * *hint, GFP_NOFS);
24044 +       if (unlikely(!array))
24045 +               array = vmalloc(sizeof(array) * *hint);
24046 +       if (unlikely(!array)) {
24047 +               array = ERR_PTR(-ENOMEM);
24048 +               goto out;
24049 +       }
24050 +
24051 +       n = cb(array, *hint, arg);
24052 +       AuDebugOn(n > *hint);
24053 +
24054 +out:
24055 +       *hint = n;
24056 +       return array;
24057 +}
24058 +
24059 +static unsigned long long au_iarray_cb(void *a,
24060 +                                      unsigned long long max __maybe_unused,
24061 +                                      void *arg)
24062 +{
24063 +       unsigned long long n;
24064 +       struct inode **p, *inode;
24065 +       struct list_head *head;
24066 +
24067 +       n = 0;
24068 +       p = a;
24069 +       head = arg;
24070 +       spin_lock(&inode_sb_list_lock);
24071 +       list_for_each_entry(inode, head, i_sb_list) {
24072 +               if (!is_bad_inode(inode)
24073 +                   && au_ii(inode)->ii_bstart >= 0) {
24074 +                       spin_lock(&inode->i_lock);
24075 +                       if (atomic_read(&inode->i_count)) {
24076 +                               au_igrab(inode);
24077 +                               *p++ = inode;
24078 +                               n++;
24079 +                               AuDebugOn(n > max);
24080 +                       }
24081 +                       spin_unlock(&inode->i_lock);
24082 +               }
24083 +       }
24084 +       spin_unlock(&inode_sb_list_lock);
24085 +
24086 +       return n;
24087 +}
24088 +
24089 +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
24090 +{
24091 +       *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
24092 +       return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
24093 +}
24094 +
24095 +void au_iarray_free(struct inode **a, unsigned long long max)
24096 +{
24097 +       unsigned long long ull;
24098 +
24099 +       for (ull = 0; ull < max; ull++)
24100 +               iput(a[ull]);
24101 +       au_array_free(a);
24102 +}
24103 +
24104 +/* ---------------------------------------------------------------------- */
24105 +
24106 +/*
24107 + * refresh dentry and inode at remount time.
24108 + */
24109 +/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
24110 +static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
24111 +                     struct dentry *parent)
24112 +{
24113 +       int err;
24114 +
24115 +       di_write_lock_child(dentry);
24116 +       di_read_lock_parent(parent, AuLock_IR);
24117 +       err = au_refresh_dentry(dentry, parent);
24118 +       if (!err && dir_flags)
24119 +               au_hn_reset(dentry->d_inode, dir_flags);
24120 +       di_read_unlock(parent, AuLock_IR);
24121 +       di_write_unlock(dentry);
24122 +
24123 +       return err;
24124 +}
24125 +
24126 +static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
24127 +                          struct au_sbinfo *sbinfo,
24128 +                          const unsigned int dir_flags)
24129 +{
24130 +       int err;
24131 +       struct dentry *parent;
24132 +       struct inode *inode;
24133 +
24134 +       err = 0;
24135 +       parent = dget_parent(dentry);
24136 +       if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
24137 +               inode = dentry->d_inode;
24138 +               if (inode) {
24139 +                       if (!S_ISDIR(inode->i_mode))
24140 +                               err = au_do_refresh(dentry, /*dir_flags*/0,
24141 +                                                parent);
24142 +                       else {
24143 +                               err = au_do_refresh(dentry, dir_flags, parent);
24144 +                               if (unlikely(err))
24145 +                                       au_fset_si(sbinfo, FAILED_REFRESH_DIR);
24146 +                       }
24147 +               } else
24148 +                       err = au_do_refresh(dentry, /*dir_flags*/0, parent);
24149 +               AuDbgDentry(dentry);
24150 +       }
24151 +       dput(parent);
24152 +
24153 +       AuTraceErr(err);
24154 +       return err;
24155 +}
24156 +
24157 +static int au_refresh_d(struct super_block *sb)
24158 +{
24159 +       int err, i, j, ndentry, e;
24160 +       unsigned int sigen;
24161 +       struct au_dcsub_pages dpages;
24162 +       struct au_dpage *dpage;
24163 +       struct dentry **dentries, *d;
24164 +       struct au_sbinfo *sbinfo;
24165 +       struct dentry *root = sb->s_root;
24166 +       const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
24167 +
24168 +       err = au_dpages_init(&dpages, GFP_NOFS);
24169 +       if (unlikely(err))
24170 +               goto out;
24171 +       err = au_dcsub_pages(&dpages, root, NULL, NULL);
24172 +       if (unlikely(err))
24173 +               goto out_dpages;
24174 +
24175 +       sigen = au_sigen(sb);
24176 +       sbinfo = au_sbi(sb);
24177 +       for (i = 0; i < dpages.ndpage; i++) {
24178 +               dpage = dpages.dpages + i;
24179 +               dentries = dpage->dentries;
24180 +               ndentry = dpage->ndentry;
24181 +               for (j = 0; j < ndentry; j++) {
24182 +                       d = dentries[j];
24183 +                       e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
24184 +                       if (unlikely(e && !err))
24185 +                               err = e;
24186 +                       /* go on even err */
24187 +               }
24188 +       }
24189 +
24190 +out_dpages:
24191 +       au_dpages_free(&dpages);
24192 +out:
24193 +       return err;
24194 +}
24195 +
24196 +static int au_refresh_i(struct super_block *sb)
24197 +{
24198 +       int err, e;
24199 +       unsigned int sigen;
24200 +       unsigned long long max, ull;
24201 +       struct inode *inode, **array;
24202 +
24203 +       array = au_iarray_alloc(sb, &max);
24204 +       err = PTR_ERR(array);
24205 +       if (IS_ERR(array))
24206 +               goto out;
24207 +
24208 +       err = 0;
24209 +       sigen = au_sigen(sb);
24210 +       for (ull = 0; ull < max; ull++) {
24211 +               inode = array[ull];
24212 +               if (au_iigen(inode, NULL) != sigen) {
24213 +                       ii_write_lock_child(inode);
24214 +                       e = au_refresh_hinode_self(inode);
24215 +                       ii_write_unlock(inode);
24216 +                       if (unlikely(e)) {
24217 +                               pr_err("error %d, i%lu\n", e, inode->i_ino);
24218 +                               if (!err)
24219 +                                       err = e;
24220 +                               /* go on even if err */
24221 +                       }
24222 +               }
24223 +       }
24224 +
24225 +       au_iarray_free(array, max);
24226 +
24227 +out:
24228 +       return err;
24229 +}
24230 +
24231 +static void au_remount_refresh(struct super_block *sb)
24232 +{
24233 +       int err, e;
24234 +       unsigned int udba;
24235 +       aufs_bindex_t bindex, bend;
24236 +       struct dentry *root;
24237 +       struct inode *inode;
24238 +       struct au_branch *br;
24239 +
24240 +       au_sigen_inc(sb);
24241 +       au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
24242 +
24243 +       root = sb->s_root;
24244 +       DiMustNoWaiters(root);
24245 +       inode = root->d_inode;
24246 +       IiMustNoWaiters(inode);
24247 +
24248 +       udba = au_opt_udba(sb);
24249 +       bend = au_sbend(sb);
24250 +       for (bindex = 0; bindex <= bend; bindex++) {
24251 +               br = au_sbr(sb, bindex);
24252 +               err = au_hnotify_reset_br(udba, br, br->br_perm);
24253 +               if (unlikely(err))
24254 +                       AuIOErr("hnotify failed on br %d, %d, ignored\n",
24255 +                               bindex, err);
24256 +               /* go on even if err */
24257 +       }
24258 +       au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
24259 +
24260 +       di_write_unlock(root);
24261 +       err = au_refresh_d(sb);
24262 +       e = au_refresh_i(sb);
24263 +       if (unlikely(e && !err))
24264 +               err = e;
24265 +       /* aufs_write_lock() calls ..._child() */
24266 +       di_write_lock_child(root);
24267 +
24268 +       au_cpup_attr_all(inode, /*force*/1);
24269 +
24270 +       if (unlikely(err))
24271 +               AuIOErr("refresh failed, ignored, %d\n", err);
24272 +}
24273 +
24274 +/* stop extra interpretation of errno in mount(8), and strange error messages */
24275 +static int cvt_err(int err)
24276 +{
24277 +       AuTraceErr(err);
24278 +
24279 +       switch (err) {
24280 +       case -ENOENT:
24281 +       case -ENOTDIR:
24282 +       case -EEXIST:
24283 +       case -EIO:
24284 +               err = -EINVAL;
24285 +       }
24286 +       return err;
24287 +}
24288 +
24289 +static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
24290 +{
24291 +       int err, do_dx;
24292 +       unsigned int mntflags;
24293 +       struct au_opts opts;
24294 +       struct dentry *root;
24295 +       struct inode *inode;
24296 +       struct au_sbinfo *sbinfo;
24297 +
24298 +       err = 0;
24299 +       root = sb->s_root;
24300 +       if (!data || !*data) {
24301 +               err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
24302 +               if (!err) {
24303 +                       di_write_lock_child(root);
24304 +                       err = au_opts_verify(sb, *flags, /*pending*/0);
24305 +                       aufs_write_unlock(root);
24306 +               }
24307 +               goto out;
24308 +       }
24309 +
24310 +       err = -ENOMEM;
24311 +       memset(&opts, 0, sizeof(opts));
24312 +       opts.opt = (void *)__get_free_page(GFP_NOFS);
24313 +       if (unlikely(!opts.opt))
24314 +               goto out;
24315 +       opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
24316 +       opts.flags = AuOpts_REMOUNT;
24317 +       opts.sb_flags = *flags;
24318 +
24319 +       /* parse it before aufs lock */
24320 +       err = au_opts_parse(sb, data, &opts);
24321 +       if (unlikely(err))
24322 +               goto out_opts;
24323 +
24324 +       sbinfo = au_sbi(sb);
24325 +       inode = root->d_inode;
24326 +       mutex_lock(&inode->i_mutex);
24327 +       err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
24328 +       if (unlikely(err))
24329 +               goto out_mtx;
24330 +       di_write_lock_child(root);
24331 +
24332 +       /* au_opts_remount() may return an error */
24333 +       err = au_opts_remount(sb, &opts);
24334 +       au_opts_free(&opts);
24335 +
24336 +       if (au_ftest_opts(opts.flags, REFRESH))
24337 +               au_remount_refresh(sb);
24338 +
24339 +       if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
24340 +               mntflags = au_mntflags(sb);
24341 +               do_dx = !!au_opt_test(mntflags, DIO);
24342 +               au_dy_arefresh(do_dx);
24343 +       }
24344 +
24345 +       aufs_write_unlock(root);
24346 +
24347 +out_mtx:
24348 +       mutex_unlock(&inode->i_mutex);
24349 +out_opts:
24350 +       free_page((unsigned long)opts.opt);
24351 +out:
24352 +       err = cvt_err(err);
24353 +       AuTraceErr(err);
24354 +       return err;
24355 +}
24356 +
24357 +static const struct super_operations aufs_sop = {
24358 +       .alloc_inode    = aufs_alloc_inode,
24359 +       .destroy_inode  = aufs_destroy_inode,
24360 +       /* always deleting, no clearing */
24361 +       .drop_inode     = generic_delete_inode,
24362 +       .show_options   = aufs_show_options,
24363 +       .statfs         = aufs_statfs,
24364 +       .put_super      = aufs_put_super,
24365 +       .sync_fs        = aufs_sync_fs,
24366 +       .remount_fs     = aufs_remount_fs
24367 +};
24368 +
24369 +/* ---------------------------------------------------------------------- */
24370 +
24371 +static int alloc_root(struct super_block *sb)
24372 +{
24373 +       int err;
24374 +       struct inode *inode;
24375 +       struct dentry *root;
24376 +
24377 +       err = -ENOMEM;
24378 +       inode = au_iget_locked(sb, AUFS_ROOT_INO);
24379 +       err = PTR_ERR(inode);
24380 +       if (IS_ERR(inode))
24381 +               goto out;
24382 +
24383 +       inode->i_op = &aufs_dir_iop;
24384 +       inode->i_fop = &aufs_dir_fop;
24385 +       inode->i_mode = S_IFDIR;
24386 +       set_nlink(inode, 2);
24387 +       unlock_new_inode(inode);
24388 +
24389 +       root = d_make_root(inode);
24390 +       if (unlikely(!root))
24391 +               goto out;
24392 +       err = PTR_ERR(root);
24393 +       if (IS_ERR(root))
24394 +               goto out;
24395 +
24396 +       err = au_di_init(root);
24397 +       if (!err) {
24398 +               sb->s_root = root;
24399 +               return 0; /* success */
24400 +       }
24401 +       dput(root);
24402 +
24403 +out:
24404 +       return err;
24405 +}
24406 +
24407 +static int aufs_fill_super(struct super_block *sb, void *raw_data,
24408 +                          int silent __maybe_unused)
24409 +{
24410 +       int err;
24411 +       struct au_opts opts;
24412 +       struct dentry *root;
24413 +       struct inode *inode;
24414 +       char *arg = raw_data;
24415 +
24416 +       if (unlikely(!arg || !*arg)) {
24417 +               err = -EINVAL;
24418 +               pr_err("no arg\n");
24419 +               goto out;
24420 +       }
24421 +
24422 +       err = -ENOMEM;
24423 +       memset(&opts, 0, sizeof(opts));
24424 +       opts.opt = (void *)__get_free_page(GFP_NOFS);
24425 +       if (unlikely(!opts.opt))
24426 +               goto out;
24427 +       opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
24428 +       opts.sb_flags = sb->s_flags;
24429 +
24430 +       err = au_si_alloc(sb);
24431 +       if (unlikely(err))
24432 +               goto out_opts;
24433 +
24434 +       /* all timestamps always follow the ones on the branch */
24435 +       sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
24436 +       sb->s_op = &aufs_sop;
24437 +       sb->s_d_op = &aufs_dop;
24438 +       sb->s_magic = AUFS_SUPER_MAGIC;
24439 +       sb->s_maxbytes = 0;
24440 +       au_export_init(sb);
24441 +
24442 +       err = alloc_root(sb);
24443 +       if (unlikely(err)) {
24444 +               si_write_unlock(sb);
24445 +               goto out_info;
24446 +       }
24447 +       root = sb->s_root;
24448 +       inode = root->d_inode;
24449 +
24450 +       /*
24451 +        * actually we can parse options regardless aufs lock here.
24452 +        * but at remount time, parsing must be done before aufs lock.
24453 +        * so we follow the same rule.
24454 +        */
24455 +       ii_write_lock_parent(inode);
24456 +       aufs_write_unlock(root);
24457 +       err = au_opts_parse(sb, arg, &opts);
24458 +       if (unlikely(err))
24459 +               goto out_root;
24460 +
24461 +       /* lock vfs_inode first, then aufs. */
24462 +       mutex_lock(&inode->i_mutex);
24463 +       aufs_write_lock(root);
24464 +       err = au_opts_mount(sb, &opts);
24465 +       au_opts_free(&opts);
24466 +       aufs_write_unlock(root);
24467 +       mutex_unlock(&inode->i_mutex);
24468 +       if (!err)
24469 +               goto out_opts; /* success */
24470 +
24471 +out_root:
24472 +       dput(root);
24473 +       sb->s_root = NULL;
24474 +out_info:
24475 +       dbgaufs_si_fin(au_sbi(sb));
24476 +       kobject_put(&au_sbi(sb)->si_kobj);
24477 +       sb->s_fs_info = NULL;
24478 +out_opts:
24479 +       free_page((unsigned long)opts.opt);
24480 +out:
24481 +       AuTraceErr(err);
24482 +       err = cvt_err(err);
24483 +       AuTraceErr(err);
24484 +       return err;
24485 +}
24486 +
24487 +/* ---------------------------------------------------------------------- */
24488 +
24489 +static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
24490 +                                const char *dev_name __maybe_unused,
24491 +                                void *raw_data)
24492 +{
24493 +       struct dentry *root;
24494 +       struct super_block *sb;
24495 +
24496 +       /* all timestamps always follow the ones on the branch */
24497 +       /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
24498 +       root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
24499 +       if (IS_ERR(root))
24500 +               goto out;
24501 +
24502 +       sb = root->d_sb;
24503 +       si_write_lock(sb, !AuLock_FLUSH);
24504 +       sysaufs_brs_add(sb, 0);
24505 +       si_write_unlock(sb);
24506 +       au_sbilist_add(sb);
24507 +
24508 +out:
24509 +       return root;
24510 +}
24511 +
24512 +static void aufs_kill_sb(struct super_block *sb)
24513 +{
24514 +       struct au_sbinfo *sbinfo;
24515 +
24516 +       sbinfo = au_sbi(sb);
24517 +       if (sbinfo) {
24518 +               au_sbilist_del(sb);
24519 +               aufs_write_lock(sb->s_root);
24520 +               if (sbinfo->si_wbr_create_ops->fin)
24521 +                       sbinfo->si_wbr_create_ops->fin(sb);
24522 +               if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
24523 +                       au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
24524 +                       au_remount_refresh(sb);
24525 +               }
24526 +               if (au_opt_test(sbinfo->si_mntflags, PLINK))
24527 +                       au_plink_put(sb, /*verbose*/1);
24528 +               au_xino_clr(sb);
24529 +               sbinfo->si_sb = NULL;
24530 +               aufs_write_unlock(sb->s_root);
24531 +               au_nwt_flush(&sbinfo->si_nowait);
24532 +       }
24533 +       generic_shutdown_super(sb);
24534 +}
24535 +
24536 +struct file_system_type aufs_fs_type = {
24537 +       .name           = AUFS_FSTYPE,
24538 +       /* a race between rename and others */
24539 +       .fs_flags       = FS_RENAME_DOES_D_MOVE,
24540 +       .mount          = aufs_mount,
24541 +       .kill_sb        = aufs_kill_sb,
24542 +       /* no need to __module_get() and module_put(). */
24543 +       .owner          = THIS_MODULE,
24544 +};
24545 diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
24546 --- /usr/share/empty/fs/aufs/super.h    1970-01-01 01:00:00.000000000 +0100
24547 +++ linux/fs/aufs/super.h       2013-07-06 13:20:47.753531903 +0200
24548 @@ -0,0 +1,555 @@
24549 +/*
24550 + * Copyright (C) 2005-2013 Junjiro R. Okajima
24551 + *
24552 + * This program, aufs is free software; you can redistribute it and/or modify
24553 + * it under the terms of the GNU General Public License as published by
24554 + * the Free Software Foundation; either version 2 of the License, or
24555 + * (at your option) any later version.
24556 + *
24557 + * This program is distributed in the hope that it will be useful,
24558 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24559 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24560 + * GNU General Public License for more details.
24561 + *
24562 + * You should have received a copy of the GNU General Public License
24563 + * along with this program; if not, write to the Free Software
24564 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24565 + */
24566 +
24567 +/*
24568 + * super_block operations
24569 + */
24570 +
24571 +#ifndef __AUFS_SUPER_H__
24572 +#define __AUFS_SUPER_H__
24573 +
24574 +#ifdef __KERNEL__
24575 +
24576 +#include <linux/fs.h>
24577 +#include "rwsem.h"
24578 +#include "spl.h"
24579 +#include "wkq.h"
24580 +
24581 +typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
24582 +typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
24583 +                              loff_t *);
24584 +
24585 +/* policies to select one among multiple writable branches */
24586 +struct au_wbr_copyup_operations {
24587 +       int (*copyup)(struct dentry *dentry);
24588 +};
24589 +
24590 +struct au_wbr_create_operations {
24591 +       int (*create)(struct dentry *dentry, int isdir);
24592 +       int (*init)(struct super_block *sb);
24593 +       int (*fin)(struct super_block *sb);
24594 +};
24595 +
24596 +struct au_wbr_mfs {
24597 +       struct mutex    mfs_lock; /* protect this structure */
24598 +       unsigned long   mfs_jiffy;
24599 +       unsigned long   mfs_expire;
24600 +       aufs_bindex_t   mfs_bindex;
24601 +
24602 +       unsigned long long      mfsrr_bytes;
24603 +       unsigned long long      mfsrr_watermark;
24604 +};
24605 +
24606 +struct pseudo_link {
24607 +       union {
24608 +               struct hlist_node hlist;
24609 +               struct rcu_head rcu;
24610 +       };
24611 +       struct inode *inode;
24612 +};
24613 +
24614 +#define AuPlink_NHASH 100
24615 +static inline int au_plink_hash(ino_t ino)
24616 +{
24617 +       return ino % AuPlink_NHASH;
24618 +}
24619 +
24620 +struct au_branch;
24621 +struct au_sbinfo {
24622 +       /* nowait tasks in the system-wide workqueue */
24623 +       struct au_nowait_tasks  si_nowait;
24624 +
24625 +       /*
24626 +        * tried sb->s_umount, but failed due to the dependecy between i_mutex.
24627 +        * rwsem for au_sbinfo is necessary.
24628 +        */
24629 +       struct au_rwsem         si_rwsem;
24630 +
24631 +       /* prevent recursive locking in deleting inode */
24632 +       struct {
24633 +               unsigned long           *bitmap;
24634 +               spinlock_t              tree_lock;
24635 +               struct radix_tree_root  tree;
24636 +       } au_si_pid;
24637 +
24638 +       /*
24639 +        * dirty approach to protect sb->sb_inodes and ->s_files from remount.
24640 +        */
24641 +       atomic_long_t           si_ninodes, si_nfiles;
24642 +
24643 +       /* branch management */
24644 +       unsigned int            si_generation;
24645 +
24646 +       /* see above flags */
24647 +       unsigned char           au_si_status;
24648 +
24649 +       aufs_bindex_t           si_bend;
24650 +
24651 +       /* dirty trick to keep br_id plus */
24652 +       unsigned int            si_last_br_id :
24653 +                               sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
24654 +       struct au_branch        **si_branch;
24655 +
24656 +       /* policy to select a writable branch */
24657 +       unsigned char           si_wbr_copyup;
24658 +       unsigned char           si_wbr_create;
24659 +       struct au_wbr_copyup_operations *si_wbr_copyup_ops;
24660 +       struct au_wbr_create_operations *si_wbr_create_ops;
24661 +
24662 +       /* round robin */
24663 +       atomic_t                si_wbr_rr_next;
24664 +
24665 +       /* most free space */
24666 +       struct au_wbr_mfs       si_wbr_mfs;
24667 +
24668 +       /* mount flags */
24669 +       /* include/asm-ia64/siginfo.h defines a macro named si_flags */
24670 +       unsigned int            si_mntflags;
24671 +
24672 +       /* external inode number (bitmap and translation table) */
24673 +       au_readf_t              si_xread;
24674 +       au_writef_t             si_xwrite;
24675 +       struct file             *si_xib;
24676 +       struct mutex            si_xib_mtx; /* protect xib members */
24677 +       unsigned long           *si_xib_buf;
24678 +       unsigned long           si_xib_last_pindex;
24679 +       int                     si_xib_next_bit;
24680 +       aufs_bindex_t           si_xino_brid;
24681 +       /* reserved for future use */
24682 +       /* unsigned long long   si_xib_limit; */        /* Max xib file size */
24683 +
24684 +#ifdef CONFIG_AUFS_EXPORT
24685 +       /* i_generation */
24686 +       struct file             *si_xigen;
24687 +       atomic_t                si_xigen_next;
24688 +#endif
24689 +
24690 +       /* vdir parameters */
24691 +       unsigned long           si_rdcache;     /* max cache time in jiffies */
24692 +       unsigned int            si_rdblk;       /* deblk size */
24693 +       unsigned int            si_rdhash;      /* hash size */
24694 +
24695 +       /*
24696 +        * If the number of whiteouts are larger than si_dirwh, leave all of
24697 +        * them after au_whtmp_ren to reduce the cost of rmdir(2).
24698 +        * future fsck.aufs or kernel thread will remove them later.
24699 +        * Otherwise, remove all whiteouts and the dir in rmdir(2).
24700 +        */
24701 +       unsigned int            si_dirwh;
24702 +
24703 +       /*
24704 +        * rename(2) a directory with all children.
24705 +        */
24706 +       /* reserved for future use */
24707 +       /* int                  si_rendir; */
24708 +
24709 +       /* pseudo_link list */
24710 +       struct au_sphlhead      si_plink[AuPlink_NHASH];
24711 +       wait_queue_head_t       si_plink_wq;
24712 +       spinlock_t              si_plink_maint_lock;
24713 +       pid_t                   si_plink_maint_pid;
24714 +
24715 +       /*
24716 +        * sysfs and lifetime management.
24717 +        * this is not a small structure and it may be a waste of memory in case
24718 +        * of sysfs is disabled, particulary when many aufs-es are mounted.
24719 +        * but using sysfs is majority.
24720 +        */
24721 +       struct kobject          si_kobj;
24722 +#ifdef CONFIG_DEBUG_FS
24723 +       struct dentry            *si_dbgaufs;
24724 +       struct dentry            *si_dbgaufs_plink;
24725 +       struct dentry            *si_dbgaufs_xib;
24726 +#ifdef CONFIG_AUFS_EXPORT
24727 +       struct dentry            *si_dbgaufs_xigen;
24728 +#endif
24729 +#endif
24730 +
24731 +#ifdef CONFIG_AUFS_SBILIST
24732 +       struct list_head        si_list;
24733 +#endif
24734 +
24735 +       /* dirty, necessary for unmounting, sysfs and sysrq */
24736 +       struct super_block      *si_sb;
24737 +};
24738 +
24739 +/* sbinfo status flags */
24740 +/*
24741 + * set true when refresh_dirs() failed at remount time.
24742 + * then try refreshing dirs at access time again.
24743 + * if it is false, refreshing dirs at access time is unnecesary
24744 + */
24745 +#define AuSi_FAILED_REFRESH_DIR        1
24746 +static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
24747 +                                          unsigned int flag)
24748 +{
24749 +       AuRwMustAnyLock(&sbi->si_rwsem);
24750 +       return sbi->au_si_status & flag;
24751 +}
24752 +#define au_ftest_si(sbinfo, name)      au_do_ftest_si(sbinfo, AuSi_##name)
24753 +#define au_fset_si(sbinfo, name) do { \
24754 +       AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
24755 +       (sbinfo)->au_si_status |= AuSi_##name; \
24756 +} while (0)
24757 +#define au_fclr_si(sbinfo, name) do { \
24758 +       AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
24759 +       (sbinfo)->au_si_status &= ~AuSi_##name; \
24760 +} while (0)
24761 +
24762 +/* ---------------------------------------------------------------------- */
24763 +
24764 +/* policy to select one among writable branches */
24765 +#define AuWbrCopyup(sbinfo, ...) \
24766 +       ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
24767 +#define AuWbrCreate(sbinfo, ...) \
24768 +       ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
24769 +
24770 +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
24771 +#define AuLock_DW              1               /* write-lock dentry */
24772 +#define AuLock_IR              (1 << 1)        /* read-lock inode */
24773 +#define AuLock_IW              (1 << 2)        /* write-lock inode */
24774 +#define AuLock_FLUSH           (1 << 3)        /* wait for 'nowait' tasks */
24775 +#define AuLock_DIR             (1 << 4)        /* target is a dir */
24776 +#define AuLock_NOPLM           (1 << 5)        /* return err in plm mode */
24777 +#define AuLock_NOPLMW          (1 << 6)        /* wait for plm mode ends */
24778 +#define AuLock_GEN             (1 << 7)        /* test digen/iigen */
24779 +#define au_ftest_lock(flags, name)     ((flags) & AuLock_##name)
24780 +#define au_fset_lock(flags, name) \
24781 +       do { (flags) |= AuLock_##name; } while (0)
24782 +#define au_fclr_lock(flags, name) \
24783 +       do { (flags) &= ~AuLock_##name; } while (0)
24784 +
24785 +/* ---------------------------------------------------------------------- */
24786 +
24787 +/* super.c */
24788 +extern struct file_system_type aufs_fs_type;
24789 +struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
24790 +typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
24791 +                                          void *arg);
24792 +void au_array_free(void *array);
24793 +void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
24794 +struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
24795 +void au_iarray_free(struct inode **a, unsigned long long max);
24796 +
24797 +/* sbinfo.c */
24798 +void au_si_free(struct kobject *kobj);
24799 +int au_si_alloc(struct super_block *sb);
24800 +int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
24801 +
24802 +unsigned int au_sigen_inc(struct super_block *sb);
24803 +aufs_bindex_t au_new_br_id(struct super_block *sb);
24804 +
24805 +int si_read_lock(struct super_block *sb, int flags);
24806 +int si_write_lock(struct super_block *sb, int flags);
24807 +int aufs_read_lock(struct dentry *dentry, int flags);
24808 +void aufs_read_unlock(struct dentry *dentry, int flags);
24809 +void aufs_write_lock(struct dentry *dentry);
24810 +void aufs_write_unlock(struct dentry *dentry);
24811 +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
24812 +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
24813 +
24814 +int si_pid_test_slow(struct super_block *sb);
24815 +void si_pid_set_slow(struct super_block *sb);
24816 +void si_pid_clr_slow(struct super_block *sb);
24817 +
24818 +/* wbr_policy.c */
24819 +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
24820 +extern struct au_wbr_create_operations au_wbr_create_ops[];
24821 +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
24822 +
24823 +/* ---------------------------------------------------------------------- */
24824 +
24825 +static inline struct au_sbinfo *au_sbi(struct super_block *sb)
24826 +{
24827 +       return sb->s_fs_info;
24828 +}
24829 +
24830 +/* ---------------------------------------------------------------------- */
24831 +
24832 +#ifdef CONFIG_AUFS_EXPORT
24833 +int au_test_nfsd(void);
24834 +void au_export_init(struct super_block *sb);
24835 +void au_xigen_inc(struct inode *inode);
24836 +int au_xigen_new(struct inode *inode);
24837 +int au_xigen_set(struct super_block *sb, struct file *base);
24838 +void au_xigen_clr(struct super_block *sb);
24839 +
24840 +static inline int au_busy_or_stale(void)
24841 +{
24842 +       if (!au_test_nfsd())
24843 +               return -EBUSY;
24844 +       return -ESTALE;
24845 +}
24846 +#else
24847 +AuStubInt0(au_test_nfsd, void)
24848 +AuStubVoid(au_export_init, struct super_block *sb)
24849 +AuStubVoid(au_xigen_inc, struct inode *inode)
24850 +AuStubInt0(au_xigen_new, struct inode *inode)
24851 +AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
24852 +AuStubVoid(au_xigen_clr, struct super_block *sb)
24853 +static inline int au_busy_or_stale(void)
24854 +{
24855 +       return -EBUSY;
24856 +}
24857 +#endif /* CONFIG_AUFS_EXPORT */
24858 +
24859 +/* ---------------------------------------------------------------------- */
24860 +
24861 +#ifdef CONFIG_AUFS_SBILIST
24862 +/* module.c */
24863 +extern struct au_splhead au_sbilist;
24864 +
24865 +static inline void au_sbilist_init(void)
24866 +{
24867 +       au_spl_init(&au_sbilist);
24868 +}
24869 +
24870 +static inline void au_sbilist_add(struct super_block *sb)
24871 +{
24872 +       au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
24873 +}
24874 +
24875 +static inline void au_sbilist_del(struct super_block *sb)
24876 +{
24877 +       au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
24878 +}
24879 +
24880 +#ifdef CONFIG_AUFS_MAGIC_SYSRQ
24881 +static inline void au_sbilist_lock(void)
24882 +{
24883 +       spin_lock(&au_sbilist.spin);
24884 +}
24885 +
24886 +static inline void au_sbilist_unlock(void)
24887 +{
24888 +       spin_unlock(&au_sbilist.spin);
24889 +}
24890 +#define AuGFP_SBILIST  GFP_ATOMIC
24891 +#else
24892 +AuStubVoid(au_sbilist_lock, void)
24893 +AuStubVoid(au_sbilist_unlock, void)
24894 +#define AuGFP_SBILIST  GFP_NOFS
24895 +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
24896 +#else
24897 +AuStubVoid(au_sbilist_init, void)
24898 +AuStubVoid(au_sbilist_add, struct super_block*)
24899 +AuStubVoid(au_sbilist_del, struct super_block*)
24900 +AuStubVoid(au_sbilist_lock, void)
24901 +AuStubVoid(au_sbilist_unlock, void)
24902 +#define AuGFP_SBILIST  GFP_NOFS
24903 +#endif
24904 +
24905 +/* ---------------------------------------------------------------------- */
24906 +
24907 +static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
24908 +{
24909 +       /*
24910 +        * This function is a dynamic '__init' fucntion actually,
24911 +        * so the tiny check for si_rwsem is unnecessary.
24912 +        */
24913 +       /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
24914 +#ifdef CONFIG_DEBUG_FS
24915 +       sbinfo->si_dbgaufs = NULL;
24916 +       sbinfo->si_dbgaufs_plink = NULL;
24917 +       sbinfo->si_dbgaufs_xib = NULL;
24918 +#ifdef CONFIG_AUFS_EXPORT
24919 +       sbinfo->si_dbgaufs_xigen = NULL;
24920 +#endif
24921 +#endif
24922 +}
24923 +
24924 +/* ---------------------------------------------------------------------- */
24925 +
24926 +static inline pid_t si_pid_bit(void)
24927 +{
24928 +       /* the origin of pid is 1, but the bitmap's is 0 */
24929 +       return current->pid - 1;
24930 +}
24931 +
24932 +static inline int si_pid_test(struct super_block *sb)
24933 +{
24934 +       pid_t bit = si_pid_bit();
24935 +       if (bit < PID_MAX_DEFAULT)
24936 +               return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24937 +       else
24938 +               return si_pid_test_slow(sb);
24939 +}
24940 +
24941 +static inline void si_pid_set(struct super_block *sb)
24942 +{
24943 +       pid_t bit = si_pid_bit();
24944 +       if (bit < PID_MAX_DEFAULT) {
24945 +               AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
24946 +               set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24947 +               /* smp_mb(); */
24948 +       } else
24949 +               si_pid_set_slow(sb);
24950 +}
24951 +
24952 +static inline void si_pid_clr(struct super_block *sb)
24953 +{
24954 +       pid_t bit = si_pid_bit();
24955 +       if (bit < PID_MAX_DEFAULT) {
24956 +               AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
24957 +               clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
24958 +               /* smp_mb(); */
24959 +       } else
24960 +               si_pid_clr_slow(sb);
24961 +}
24962 +
24963 +/* ---------------------------------------------------------------------- */
24964 +
24965 +/* lock superblock. mainly for entry point functions */
24966 +/*
24967 + * __si_read_lock, __si_write_lock,
24968 + * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
24969 + */
24970 +AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
24971 +
24972 +#define SiMustNoWaiters(sb)    AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
24973 +#define SiMustAnyLock(sb)      AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
24974 +#define SiMustWriteLock(sb)    AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
24975 +
24976 +static inline void si_noflush_read_lock(struct super_block *sb)
24977 +{
24978 +       __si_read_lock(sb);
24979 +       si_pid_set(sb);
24980 +}
24981 +
24982 +static inline int si_noflush_read_trylock(struct super_block *sb)
24983 +{
24984 +       int locked = __si_read_trylock(sb);
24985 +       if (locked)
24986 +               si_pid_set(sb);
24987 +       return locked;
24988 +}
24989 +
24990 +static inline void si_noflush_write_lock(struct super_block *sb)
24991 +{
24992 +       __si_write_lock(sb);
24993 +       si_pid_set(sb);
24994 +}
24995 +
24996 +static inline int si_noflush_write_trylock(struct super_block *sb)
24997 +{
24998 +       int locked = __si_write_trylock(sb);
24999 +       if (locked)
25000 +               si_pid_set(sb);
25001 +       return locked;
25002 +}
25003 +
25004 +#if 0 /* unused */
25005 +static inline int si_read_trylock(struct super_block *sb, int flags)
25006 +{
25007 +       if (au_ftest_lock(flags, FLUSH))
25008 +               au_nwt_flush(&au_sbi(sb)->si_nowait);
25009 +       return si_noflush_read_trylock(sb);
25010 +}
25011 +#endif
25012 +
25013 +static inline void si_read_unlock(struct super_block *sb)
25014 +{
25015 +       si_pid_clr(sb);
25016 +       __si_read_unlock(sb);
25017 +}
25018 +
25019 +#if 0 /* unused */
25020 +static inline int si_write_trylock(struct super_block *sb, int flags)
25021 +{
25022 +       if (au_ftest_lock(flags, FLUSH))
25023 +               au_nwt_flush(&au_sbi(sb)->si_nowait);
25024 +       return si_noflush_write_trylock(sb);
25025 +}
25026 +#endif
25027 +
25028 +static inline void si_write_unlock(struct super_block *sb)
25029 +{
25030 +       si_pid_clr(sb);
25031 +       __si_write_unlock(sb);
25032 +}
25033 +
25034 +#if 0 /* unused */
25035 +static inline void si_downgrade_lock(struct super_block *sb)
25036 +{
25037 +       __si_downgrade_lock(sb);
25038 +}
25039 +#endif
25040 +
25041 +/* ---------------------------------------------------------------------- */
25042 +
25043 +static inline aufs_bindex_t au_sbend(struct super_block *sb)
25044 +{
25045 +       SiMustAnyLock(sb);
25046 +       return au_sbi(sb)->si_bend;
25047 +}
25048 +
25049 +static inline unsigned int au_mntflags(struct super_block *sb)
25050 +{
25051 +       SiMustAnyLock(sb);
25052 +       return au_sbi(sb)->si_mntflags;
25053 +}
25054 +
25055 +static inline unsigned int au_sigen(struct super_block *sb)
25056 +{
25057 +       SiMustAnyLock(sb);
25058 +       return au_sbi(sb)->si_generation;
25059 +}
25060 +
25061 +static inline void au_ninodes_inc(struct super_block *sb)
25062 +{
25063 +       atomic_long_inc(&au_sbi(sb)->si_ninodes);
25064 +}
25065 +
25066 +static inline void au_ninodes_dec(struct super_block *sb)
25067 +{
25068 +       AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
25069 +       atomic_long_dec(&au_sbi(sb)->si_ninodes);
25070 +}
25071 +
25072 +static inline void au_nfiles_inc(struct super_block *sb)
25073 +{
25074 +       atomic_long_inc(&au_sbi(sb)->si_nfiles);
25075 +}
25076 +
25077 +static inline void au_nfiles_dec(struct super_block *sb)
25078 +{
25079 +       AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
25080 +       atomic_long_dec(&au_sbi(sb)->si_nfiles);
25081 +}
25082 +
25083 +static inline struct au_branch *au_sbr(struct super_block *sb,
25084 +                                      aufs_bindex_t bindex)
25085 +{
25086 +       SiMustAnyLock(sb);
25087 +       return au_sbi(sb)->si_branch[0 + bindex];
25088 +}
25089 +
25090 +static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
25091 +{
25092 +       SiMustWriteLock(sb);
25093 +       au_sbi(sb)->si_xino_brid = brid;
25094 +}
25095 +
25096 +static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
25097 +{
25098 +       SiMustAnyLock(sb);
25099 +       return au_sbi(sb)->si_xino_brid;
25100 +}
25101 +
25102 +#endif /* __KERNEL__ */
25103 +#endif /* __AUFS_SUPER_H__ */
25104 diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
25105 --- /usr/share/empty/fs/aufs/sysaufs.c  1970-01-01 01:00:00.000000000 +0100
25106 +++ linux/fs/aufs/sysaufs.c     2013-07-06 13:20:47.753531903 +0200
25107 @@ -0,0 +1,105 @@
25108 +/*
25109 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25110 + *
25111 + * This program, aufs is free software; you can redistribute it and/or modify
25112 + * it under the terms of the GNU General Public License as published by
25113 + * the Free Software Foundation; either version 2 of the License, or
25114 + * (at your option) any later version.
25115 + *
25116 + * This program is distributed in the hope that it will be useful,
25117 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25118 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25119 + * GNU General Public License for more details.
25120 + *
25121 + * You should have received a copy of the GNU General Public License
25122 + * along with this program; if not, write to the Free Software
25123 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25124 + */
25125 +
25126 +/*
25127 + * sysfs interface and lifetime management
25128 + * they are necessary regardless sysfs is disabled.
25129 + */
25130 +
25131 +#include <linux/random.h>
25132 +#include "aufs.h"
25133 +
25134 +unsigned long sysaufs_si_mask;
25135 +struct kset *sysaufs_kset;
25136 +
25137 +#define AuSiAttr(_name) { \
25138 +       .attr   = { .name = __stringify(_name), .mode = 0444 }, \
25139 +       .show   = sysaufs_si_##_name,                           \
25140 +}
25141 +
25142 +static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
25143 +struct attribute *sysaufs_si_attrs[] = {
25144 +       &sysaufs_si_attr_xi_path.attr,
25145 +       NULL,
25146 +};
25147 +
25148 +static const struct sysfs_ops au_sbi_ops = {
25149 +       .show   = sysaufs_si_show
25150 +};
25151 +
25152 +static struct kobj_type au_sbi_ktype = {
25153 +       .release        = au_si_free,
25154 +       .sysfs_ops      = &au_sbi_ops,
25155 +       .default_attrs  = sysaufs_si_attrs
25156 +};
25157 +
25158 +/* ---------------------------------------------------------------------- */
25159 +
25160 +int sysaufs_si_init(struct au_sbinfo *sbinfo)
25161 +{
25162 +       int err;
25163 +
25164 +       sbinfo->si_kobj.kset = sysaufs_kset;
25165 +       /* cf. sysaufs_name() */
25166 +       err = kobject_init_and_add
25167 +               (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
25168 +                SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
25169 +
25170 +       dbgaufs_si_null(sbinfo);
25171 +       if (!err) {
25172 +               err = dbgaufs_si_init(sbinfo);
25173 +               if (unlikely(err))
25174 +                       kobject_put(&sbinfo->si_kobj);
25175 +       }
25176 +       return err;
25177 +}
25178 +
25179 +void sysaufs_fin(void)
25180 +{
25181 +       dbgaufs_fin();
25182 +       sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
25183 +       kset_unregister(sysaufs_kset);
25184 +}
25185 +
25186 +int __init sysaufs_init(void)
25187 +{
25188 +       int err;
25189 +
25190 +       do {
25191 +               get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
25192 +       } while (!sysaufs_si_mask);
25193 +
25194 +       err = -EINVAL;
25195 +       sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
25196 +       if (unlikely(!sysaufs_kset))
25197 +               goto out;
25198 +       err = PTR_ERR(sysaufs_kset);
25199 +       if (IS_ERR(sysaufs_kset))
25200 +               goto out;
25201 +       err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
25202 +       if (unlikely(err)) {
25203 +               kset_unregister(sysaufs_kset);
25204 +               goto out;
25205 +       }
25206 +
25207 +       err = dbgaufs_init();
25208 +       if (unlikely(err))
25209 +               sysaufs_fin();
25210 +out:
25211 +       return err;
25212 +}
25213 diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
25214 --- /usr/share/empty/fs/aufs/sysaufs.h  1970-01-01 01:00:00.000000000 +0100
25215 +++ linux/fs/aufs/sysaufs.h     2013-07-06 13:20:47.753531903 +0200
25216 @@ -0,0 +1,104 @@
25217 +/*
25218 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25219 + *
25220 + * This program, aufs is free software; you can redistribute it and/or modify
25221 + * it under the terms of the GNU General Public License as published by
25222 + * the Free Software Foundation; either version 2 of the License, or
25223 + * (at your option) any later version.
25224 + *
25225 + * This program is distributed in the hope that it will be useful,
25226 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25227 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25228 + * GNU General Public License for more details.
25229 + *
25230 + * You should have received a copy of the GNU General Public License
25231 + * along with this program; if not, write to the Free Software
25232 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25233 + */
25234 +
25235 +/*
25236 + * sysfs interface and mount lifetime management
25237 + */
25238 +
25239 +#ifndef __SYSAUFS_H__
25240 +#define __SYSAUFS_H__
25241 +
25242 +#ifdef __KERNEL__
25243 +
25244 +#include <linux/sysfs.h>
25245 +#include "module.h"
25246 +
25247 +struct super_block;
25248 +struct au_sbinfo;
25249 +
25250 +struct sysaufs_si_attr {
25251 +       struct attribute attr;
25252 +       int (*show)(struct seq_file *seq, struct super_block *sb);
25253 +};
25254 +
25255 +/* ---------------------------------------------------------------------- */
25256 +
25257 +/* sysaufs.c */
25258 +extern unsigned long sysaufs_si_mask;
25259 +extern struct kset *sysaufs_kset;
25260 +extern struct attribute *sysaufs_si_attrs[];
25261 +int sysaufs_si_init(struct au_sbinfo *sbinfo);
25262 +int __init sysaufs_init(void);
25263 +void sysaufs_fin(void);
25264 +
25265 +/* ---------------------------------------------------------------------- */
25266 +
25267 +/* some people doesn't like to show a pointer in kernel */
25268 +static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
25269 +{
25270 +       return sysaufs_si_mask ^ (unsigned long)sbinfo;
25271 +}
25272 +
25273 +#define SysaufsSiNamePrefix    "si_"
25274 +#define SysaufsSiNameLen       (sizeof(SysaufsSiNamePrefix) + 16)
25275 +static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
25276 +{
25277 +       snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
25278 +                sysaufs_si_id(sbinfo));
25279 +}
25280 +
25281 +struct au_branch;
25282 +#ifdef CONFIG_SYSFS
25283 +/* sysfs.c */
25284 +extern struct attribute_group *sysaufs_attr_group;
25285 +
25286 +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
25287 +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
25288 +                        char *buf);
25289 +
25290 +void sysaufs_br_init(struct au_branch *br);
25291 +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
25292 +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
25293 +
25294 +#define sysaufs_brs_init()     do {} while (0)
25295 +
25296 +#else
25297 +#define sysaufs_attr_group     NULL
25298 +
25299 +AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
25300 +
25301 +static inline
25302 +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
25303 +                        char *buf)
25304 +{
25305 +       return 0;
25306 +}
25307 +
25308 +AuStubVoid(sysaufs_br_init, struct au_branch *br)
25309 +AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
25310 +AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
25311 +
25312 +static inline void sysaufs_brs_init(void)
25313 +{
25314 +       sysaufs_brs = 0;
25315 +}
25316 +
25317 +#endif /* CONFIG_SYSFS */
25318 +
25319 +#endif /* __KERNEL__ */
25320 +#endif /* __SYSAUFS_H__ */
25321 diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
25322 --- /usr/share/empty/fs/aufs/sysfs.c    1970-01-01 01:00:00.000000000 +0100
25323 +++ linux/fs/aufs/sysfs.c       2013-07-06 13:20:47.753531903 +0200
25324 @@ -0,0 +1,257 @@
25325 +/*
25326 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25327 + *
25328 + * This program, aufs is free software; you can redistribute it and/or modify
25329 + * it under the terms of the GNU General Public License as published by
25330 + * the Free Software Foundation; either version 2 of the License, or
25331 + * (at your option) any later version.
25332 + *
25333 + * This program is distributed in the hope that it will be useful,
25334 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25335 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25336 + * GNU General Public License for more details.
25337 + *
25338 + * You should have received a copy of the GNU General Public License
25339 + * along with this program; if not, write to the Free Software
25340 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25341 + */
25342 +
25343 +/*
25344 + * sysfs interface
25345 + */
25346 +
25347 +#include <linux/seq_file.h>
25348 +#include "aufs.h"
25349 +
25350 +#ifdef CONFIG_AUFS_FS_MODULE
25351 +/* this entry violates the "one line per file" policy of sysfs */
25352 +static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
25353 +                          char *buf)
25354 +{
25355 +       ssize_t err;
25356 +       static char *conf =
25357 +/* this file is generated at compiling */
25358 +#include "conf.str"
25359 +               ;
25360 +
25361 +       err = snprintf(buf, PAGE_SIZE, conf);
25362 +       if (unlikely(err >= PAGE_SIZE))
25363 +               err = -EFBIG;
25364 +       return err;
25365 +}
25366 +
25367 +static struct kobj_attribute au_config_attr = __ATTR_RO(config);
25368 +#endif
25369 +
25370 +static struct attribute *au_attr[] = {
25371 +#ifdef CONFIG_AUFS_FS_MODULE
25372 +       &au_config_attr.attr,
25373 +#endif
25374 +       NULL,   /* need to NULL terminate the list of attributes */
25375 +};
25376 +
25377 +static struct attribute_group sysaufs_attr_group_body = {
25378 +       .attrs = au_attr
25379 +};
25380 +
25381 +struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
25382 +
25383 +/* ---------------------------------------------------------------------- */
25384 +
25385 +int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
25386 +{
25387 +       int err;
25388 +
25389 +       SiMustAnyLock(sb);
25390 +
25391 +       err = 0;
25392 +       if (au_opt_test(au_mntflags(sb), XINO)) {
25393 +               err = au_xino_path(seq, au_sbi(sb)->si_xib);
25394 +               seq_putc(seq, '\n');
25395 +       }
25396 +       return err;
25397 +}
25398 +
25399 +/*
25400 + * the lifetime of branch is independent from the entry under sysfs.
25401 + * sysfs handles the lifetime of the entry, and never call ->show() after it is
25402 + * unlinked.
25403 + */
25404 +static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
25405 +                        aufs_bindex_t bindex)
25406 +{
25407 +       int err;
25408 +       struct path path;
25409 +       struct dentry *root;
25410 +       struct au_branch *br;
25411 +       char *perm;
25412 +
25413 +       AuDbg("b%d\n", bindex);
25414 +
25415 +       err = 0;
25416 +       root = sb->s_root;
25417 +       di_read_lock_parent(root, !AuLock_IR);
25418 +       br = au_sbr(sb, bindex);
25419 +       path.mnt = au_br_mnt(br);
25420 +       path.dentry = au_h_dptr(root, bindex);
25421 +       au_seq_path(seq, &path);
25422 +       di_read_unlock(root, !AuLock_IR);
25423 +       perm = au_optstr_br_perm(br->br_perm);
25424 +       if (perm) {
25425 +               err = seq_printf(seq, "=%s\n", perm);
25426 +               kfree(perm);
25427 +               if (err == -1)
25428 +                       err = -E2BIG;
25429 +       } else
25430 +               err = -ENOMEM;
25431 +       return err;
25432 +}
25433 +
25434 +/* ---------------------------------------------------------------------- */
25435 +
25436 +static struct seq_file *au_seq(char *p, ssize_t len)
25437 +{
25438 +       struct seq_file *seq;
25439 +
25440 +       seq = kzalloc(sizeof(*seq), GFP_NOFS);
25441 +       if (seq) {
25442 +               /* mutex_init(&seq.lock); */
25443 +               seq->buf = p;
25444 +               seq->size = len;
25445 +               return seq; /* success */
25446 +       }
25447 +
25448 +       seq = ERR_PTR(-ENOMEM);
25449 +       return seq;
25450 +}
25451 +
25452 +#define SysaufsBr_PREFIX "br"
25453 +
25454 +/* todo: file size may exceed PAGE_SIZE */
25455 +ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
25456 +                       char *buf)
25457 +{
25458 +       ssize_t err;
25459 +       long l;
25460 +       aufs_bindex_t bend;
25461 +       struct au_sbinfo *sbinfo;
25462 +       struct super_block *sb;
25463 +       struct seq_file *seq;
25464 +       char *name;
25465 +       struct attribute **cattr;
25466 +
25467 +       sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
25468 +       sb = sbinfo->si_sb;
25469 +
25470 +       /*
25471 +        * prevent a race condition between sysfs and aufs.
25472 +        * for instance, sysfs_file_read() calls sysfs_get_active_two() which
25473 +        * prohibits maintaining the sysfs entries.
25474 +        * hew we acquire read lock after sysfs_get_active_two().
25475 +        * on the other hand, the remount process may maintain the sysfs/aufs
25476 +        * entries after acquiring write lock.
25477 +        * it can cause a deadlock.
25478 +        * simply we gave up processing read here.
25479 +        */
25480 +       err = -EBUSY;
25481 +       if (unlikely(!si_noflush_read_trylock(sb)))
25482 +               goto out;
25483 +
25484 +       seq = au_seq(buf, PAGE_SIZE);
25485 +       err = PTR_ERR(seq);
25486 +       if (IS_ERR(seq))
25487 +               goto out_unlock;
25488 +
25489 +       name = (void *)attr->name;
25490 +       cattr = sysaufs_si_attrs;
25491 +       while (*cattr) {
25492 +               if (!strcmp(name, (*cattr)->name)) {
25493 +                       err = container_of(*cattr, struct sysaufs_si_attr, attr)
25494 +                               ->show(seq, sb);
25495 +                       goto out_seq;
25496 +               }
25497 +               cattr++;
25498 +       }
25499 +
25500 +       bend = au_sbend(sb);
25501 +       if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) {
25502 +               name += sizeof(SysaufsBr_PREFIX) - 1;
25503 +               err = kstrtol(name, 10, &l);
25504 +               if (!err) {
25505 +                       if (l <= bend)
25506 +                               err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l);
25507 +                       else
25508 +                               err = -ENOENT;
25509 +               }
25510 +               goto out_seq;
25511 +       }
25512 +       BUG();
25513 +
25514 +out_seq:
25515 +       if (!err) {
25516 +               err = seq->count;
25517 +               /* sysfs limit */
25518 +               if (unlikely(err == PAGE_SIZE))
25519 +                       err = -EFBIG;
25520 +       }
25521 +       kfree(seq);
25522 +out_unlock:
25523 +       si_read_unlock(sb);
25524 +out:
25525 +       return err;
25526 +}
25527 +
25528 +/* ---------------------------------------------------------------------- */
25529 +
25530 +void sysaufs_br_init(struct au_branch *br)
25531 +{
25532 +       struct attribute *attr = &br->br_attr;
25533 +
25534 +       sysfs_attr_init(attr);
25535 +       attr->name = br->br_name;
25536 +       attr->mode = S_IRUGO;
25537 +}
25538 +
25539 +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
25540 +{
25541 +       struct au_branch *br;
25542 +       struct kobject *kobj;
25543 +       aufs_bindex_t bend;
25544 +
25545 +       dbgaufs_brs_del(sb, bindex);
25546 +
25547 +       if (!sysaufs_brs)
25548 +               return;
25549 +
25550 +       kobj = &au_sbi(sb)->si_kobj;
25551 +       bend = au_sbend(sb);
25552 +       for (; bindex <= bend; bindex++) {
25553 +               br = au_sbr(sb, bindex);
25554 +               sysfs_remove_file(kobj, &br->br_attr);
25555 +       }
25556 +}
25557 +
25558 +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
25559 +{
25560 +       int err;
25561 +       aufs_bindex_t bend;
25562 +       struct kobject *kobj;
25563 +       struct au_branch *br;
25564 +
25565 +       dbgaufs_brs_add(sb, bindex);
25566 +
25567 +       if (!sysaufs_brs)
25568 +               return;
25569 +
25570 +       kobj = &au_sbi(sb)->si_kobj;
25571 +       bend = au_sbend(sb);
25572 +       for (; bindex <= bend; bindex++) {
25573 +               br = au_sbr(sb, bindex);
25574 +               snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX
25575 +                        "%d", bindex);
25576 +               err = sysfs_create_file(kobj, &br->br_attr);
25577 +               if (unlikely(err))
25578 +                       pr_warn("failed %s under sysfs(%d)\n",
25579 +                               br->br_name, err);
25580 +       }
25581 +}
25582 diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
25583 --- /usr/share/empty/fs/aufs/sysrq.c    1970-01-01 01:00:00.000000000 +0100
25584 +++ linux/fs/aufs/sysrq.c       2013-07-06 13:20:47.753531903 +0200
25585 @@ -0,0 +1,151 @@
25586 +/*
25587 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25588 + *
25589 + * This program, aufs is free software; you can redistribute it and/or modify
25590 + * it under the terms of the GNU General Public License as published by
25591 + * the Free Software Foundation; either version 2 of the License, or
25592 + * (at your option) any later version.
25593 + *
25594 + * This program is distributed in the hope that it will be useful,
25595 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25596 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25597 + * GNU General Public License for more details.
25598 + *
25599 + * You should have received a copy of the GNU General Public License
25600 + * along with this program; if not, write to the Free Software
25601 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25602 + */
25603 +
25604 +/*
25605 + * magic sysrq hanlder
25606 + */
25607 +
25608 +/* #include <linux/sysrq.h> */
25609 +#include <linux/writeback.h>
25610 +#include "aufs.h"
25611 +
25612 +/* ---------------------------------------------------------------------- */
25613 +
25614 +static void sysrq_sb(struct super_block *sb)
25615 +{
25616 +       char *plevel;
25617 +       struct au_sbinfo *sbinfo;
25618 +       struct file *file;
25619 +
25620 +       plevel = au_plevel;
25621 +       au_plevel = KERN_WARNING;
25622 +
25623 +       /* since we define pr_fmt, call printk directly */
25624 +#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
25625 +
25626 +       sbinfo = au_sbi(sb);
25627 +       printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
25628 +       pr("superblock\n");
25629 +       au_dpri_sb(sb);
25630 +
25631 +#if 0
25632 +       pr("root dentry\n");
25633 +       au_dpri_dentry(sb->s_root);
25634 +       pr("root inode\n");
25635 +       au_dpri_inode(sb->s_root->d_inode);
25636 +#endif
25637 +
25638 +#if 0
25639 +       do {
25640 +               int err, i, j, ndentry;
25641 +               struct au_dcsub_pages dpages;
25642 +               struct au_dpage *dpage;
25643 +
25644 +               err = au_dpages_init(&dpages, GFP_ATOMIC);
25645 +               if (unlikely(err))
25646 +                       break;
25647 +               err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
25648 +               if (!err)
25649 +                       for (i = 0; i < dpages.ndpage; i++) {
25650 +                               dpage = dpages.dpages + i;
25651 +                               ndentry = dpage->ndentry;
25652 +                               for (j = 0; j < ndentry; j++)
25653 +                                       au_dpri_dentry(dpage->dentries[j]);
25654 +                       }
25655 +               au_dpages_free(&dpages);
25656 +       } while (0);
25657 +#endif
25658 +
25659 +#if 1
25660 +       {
25661 +               struct inode *i;
25662 +               pr("isolated inode\n");
25663 +               spin_lock(&inode_sb_list_lock);
25664 +               list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
25665 +                       spin_lock(&i->i_lock);
25666 +                       if (1 || hlist_empty(&i->i_dentry))
25667 +                               au_dpri_inode(i);
25668 +                       spin_unlock(&i->i_lock);
25669 +               }
25670 +               spin_unlock(&inode_sb_list_lock);
25671 +       }
25672 +#endif
25673 +       pr("files\n");
25674 +       lg_global_lock(&files_lglock);
25675 +       do_file_list_for_each_entry(sb, file) {
25676 +               umode_t mode;
25677 +               mode = file_inode(file)->i_mode;
25678 +               if (!special_file(mode) || au_special_file(mode))
25679 +                       au_dpri_file(file);
25680 +       } while_file_list_for_each_entry;
25681 +       lg_global_unlock(&files_lglock);
25682 +       pr("done\n");
25683 +
25684 +#undef pr
25685 +       au_plevel = plevel;
25686 +}
25687 +
25688 +/* ---------------------------------------------------------------------- */
25689 +
25690 +/* module parameter */
25691 +static char *aufs_sysrq_key = "a";
25692 +module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
25693 +MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
25694 +
25695 +static void au_sysrq(int key __maybe_unused)
25696 +{
25697 +       struct au_sbinfo *sbinfo;
25698 +
25699 +       lockdep_off();
25700 +       au_sbilist_lock();
25701 +       list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
25702 +               sysrq_sb(sbinfo->si_sb);
25703 +       au_sbilist_unlock();
25704 +       lockdep_on();
25705 +}
25706 +
25707 +static struct sysrq_key_op au_sysrq_op = {
25708 +       .handler        = au_sysrq,
25709 +       .help_msg       = "Aufs",
25710 +       .action_msg     = "Aufs",
25711 +       .enable_mask    = SYSRQ_ENABLE_DUMP
25712 +};
25713 +
25714 +/* ---------------------------------------------------------------------- */
25715 +
25716 +int __init au_sysrq_init(void)
25717 +{
25718 +       int err;
25719 +       char key;
25720 +
25721 +       err = -1;
25722 +       key = *aufs_sysrq_key;
25723 +       if ('a' <= key && key <= 'z')
25724 +               err = register_sysrq_key(key, &au_sysrq_op);
25725 +       if (unlikely(err))
25726 +               pr_err("err %d, sysrq=%c\n", err, key);
25727 +       return err;
25728 +}
25729 +
25730 +void au_sysrq_fin(void)
25731 +{
25732 +       int err;
25733 +       err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
25734 +       if (unlikely(err))
25735 +               pr_err("err %d (ignored)\n", err);
25736 +}
25737 diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
25738 --- /usr/share/empty/fs/aufs/vdir.c     1970-01-01 01:00:00.000000000 +0100
25739 +++ linux/fs/aufs/vdir.c        2013-07-30 22:42:55.842946719 +0200
25740 @@ -0,0 +1,878 @@
25741 +/*
25742 + * Copyright (C) 2005-2013 Junjiro R. Okajima
25743 + *
25744 + * This program, aufs is free software; you can redistribute it and/or modify
25745 + * it under the terms of the GNU General Public License as published by
25746 + * the Free Software Foundation; either version 2 of the License, or
25747 + * (at your option) any later version.
25748 + *
25749 + * This program is distributed in the hope that it will be useful,
25750 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25751 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25752 + * GNU General Public License for more details.
25753 + *
25754 + * You should have received a copy of the GNU General Public License
25755 + * along with this program; if not, write to the Free Software
25756 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25757 + */
25758 +
25759 +/*
25760 + * virtual or vertical directory
25761 + */
25762 +
25763 +#include "aufs.h"
25764 +
25765 +static unsigned int calc_size(int nlen)
25766 +{
25767 +       return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
25768 +}
25769 +
25770 +static int set_deblk_end(union au_vdir_deblk_p *p,
25771 +                        union au_vdir_deblk_p *deblk_end)
25772 +{
25773 +       if (calc_size(0) <= deblk_end->deblk - p->deblk) {
25774 +               p->de->de_str.len = 0;
25775 +               /* smp_mb(); */
25776 +               return 0;
25777 +       }
25778 +       return -1; /* error */
25779 +}
25780 +
25781 +/* returns true or false */
25782 +static int is_deblk_end(union au_vdir_deblk_p *p,
25783 +                       union au_vdir_deblk_p *deblk_end)
25784 +{
25785 +       if (calc_size(0) <= deblk_end->deblk - p->deblk)
25786 +               return !p->de->de_str.len;
25787 +       return 1;
25788 +}
25789 +
25790 +static unsigned char *last_deblk(struct au_vdir *vdir)
25791 +{
25792 +       return vdir->vd_deblk[vdir->vd_nblk - 1];
25793 +}
25794 +
25795 +/* ---------------------------------------------------------------------- */
25796 +
25797 +/* estimate the apropriate size for name hash table */
25798 +unsigned int au_rdhash_est(loff_t sz)
25799 +{
25800 +       unsigned int n;
25801 +
25802 +       n = UINT_MAX;
25803 +       sz >>= 10;
25804 +       if (sz < n)
25805 +               n = sz;
25806 +       if (sz < AUFS_RDHASH_DEF)
25807 +               n = AUFS_RDHASH_DEF;
25808 +       /* pr_info("n %u\n", n); */
25809 +       return n;
25810 +}
25811 +
25812 +/*
25813 + * the allocated memory has to be freed by
25814 + * au_nhash_wh_free() or au_nhash_de_free().
25815 + */
25816 +int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
25817 +{
25818 +       struct hlist_head *head;
25819 +       unsigned int u;
25820 +
25821 +       head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
25822 +       if (head) {
25823 +               nhash->nh_num = num_hash;
25824 +               nhash->nh_head = head;
25825 +               for (u = 0; u < num_hash; u++)
25826 +                       INIT_HLIST_HEAD(head++);
25827 +               return 0; /* success */
25828 +       }
25829 +
25830 +       return -ENOMEM;
25831 +}
25832 +
25833 +static void nhash_count(struct hlist_head *head)
25834 +{
25835 +#if 0
25836 +       unsigned long n;
25837 +       struct hlist_node *pos;
25838 +
25839 +       n = 0;
25840 +       hlist_for_each(pos, head)
25841 +               n++;
25842 +       pr_info("%lu\n", n);
25843 +#endif
25844 +}
25845 +
25846 +static void au_nhash_wh_do_free(struct hlist_head *head)
25847 +{
25848 +       struct au_vdir_wh *pos;
25849 +       struct hlist_node *node;
25850 +
25851 +       hlist_for_each_entry_safe(pos, node, head, wh_hash)
25852 +               kfree(pos);
25853 +}
25854 +
25855 +static void au_nhash_de_do_free(struct hlist_head *head)
25856 +{
25857 +       struct au_vdir_dehstr *pos;
25858 +       struct hlist_node *node;
25859 +
25860 +       hlist_for_each_entry_safe(pos, node, head, hash)
25861 +               au_cache_free_vdir_dehstr(pos);
25862 +}
25863 +
25864 +static void au_nhash_do_free(struct au_nhash *nhash,
25865 +                            void (*free)(struct hlist_head *head))
25866 +{
25867 +       unsigned int n;
25868 +       struct hlist_head *head;
25869 +
25870 +       n = nhash->nh_num;
25871 +       if (!n)
25872 +               return;
25873 +
25874 +       head = nhash->nh_head;
25875 +       while (n-- > 0) {
25876 +               nhash_count(head);
25877 +               free(head++);
25878 +       }
25879 +       kfree(nhash->nh_head);
25880 +}
25881 +
25882 +void au_nhash_wh_free(struct au_nhash *whlist)
25883 +{
25884 +       au_nhash_do_free(whlist, au_nhash_wh_do_free);
25885 +}
25886 +
25887 +static void au_nhash_de_free(struct au_nhash *delist)
25888 +{
25889 +       au_nhash_do_free(delist, au_nhash_de_do_free);
25890 +}
25891 +
25892 +/* ---------------------------------------------------------------------- */
25893 +
25894 +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
25895 +                           int limit)
25896 +{
25897 +       int num;
25898 +       unsigned int u, n;
25899 +       struct hlist_head *head;
25900 +       struct au_vdir_wh *pos;
25901 +
25902 +       num = 0;
25903 +       n = whlist->nh_num;
25904 +       head = whlist->nh_head;
25905 +       for (u = 0; u < n; u++, head++)
25906 +               hlist_for_each_entry(pos, head, wh_hash)
25907 +                       if (pos->wh_bindex == btgt && ++num > limit)
25908 +                               return 1;
25909 +       return 0;
25910 +}
25911 +
25912 +static struct hlist_head *au_name_hash(struct au_nhash *nhash,
25913 +                                      unsigned char *name,
25914 +                                      unsigned int len)
25915 +{
25916 +       unsigned int v;
25917 +       /* const unsigned int magic_bit = 12; */
25918 +
25919 +       AuDebugOn(!nhash->nh_num || !nhash->nh_head);
25920 +
25921 +       v = 0;
25922 +       while (len--)
25923 +               v += *name++;
25924 +       /* v = hash_long(v, magic_bit); */
25925 +       v %= nhash->nh_num;
25926 +       return nhash->nh_head + v;
25927 +}
25928 +
25929 +static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
25930 +                             int nlen)
25931 +{
25932 +       return str->len == nlen && !memcmp(str->name, name, nlen);
25933 +}
25934 +
25935 +/* returns found or not */
25936 +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
25937 +{
25938 +       struct hlist_head *head;
25939 +       struct au_vdir_wh *pos;
25940 +       struct au_vdir_destr *str;
25941 +
25942 +       head = au_name_hash(whlist, name, nlen);
25943 +       hlist_for_each_entry(pos, head, wh_hash) {
25944 +               str = &pos->wh_str;
25945 +               AuDbg("%.*s\n", str->len, str->name);
25946 +               if (au_nhash_test_name(str, name, nlen))
25947 +                       return 1;
25948 +       }
25949 +       return 0;
25950 +}
25951 +
25952 +/* returns found(true) or not */
25953 +static int test_known(struct au_nhash *delist, char *name, int nlen)
25954 +{
25955 +       struct hlist_head *head;
25956 +       struct au_vdir_dehstr *pos;
25957 +       struct au_vdir_destr *str;
25958 +
25959 +       head = au_name_hash(delist, name, nlen);
25960 +       hlist_for_each_entry(pos, head, hash) {
25961 +               str = pos->str;
25962 +               AuDbg("%.*s\n", str->len, str->name);
25963 +               if (au_nhash_test_name(str, name, nlen))
25964 +                       return 1;
25965 +       }
25966 +       return 0;
25967 +}
25968 +
25969 +static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
25970 +                           unsigned char d_type)
25971 +{
25972 +#ifdef CONFIG_AUFS_SHWH
25973 +       wh->wh_ino = ino;
25974 +       wh->wh_type = d_type;
25975 +#endif
25976 +}
25977 +
25978 +/* ---------------------------------------------------------------------- */
25979 +
25980 +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
25981 +                      unsigned int d_type, aufs_bindex_t bindex,
25982 +                      unsigned char shwh)
25983 +{
25984 +       int err;
25985 +       struct au_vdir_destr *str;
25986 +       struct au_vdir_wh *wh;
25987 +
25988 +       AuDbg("%.*s\n", nlen, name);
25989 +       AuDebugOn(!whlist->nh_num || !whlist->nh_head);
25990 +
25991 +       err = -ENOMEM;
25992 +       wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
25993 +       if (unlikely(!wh))
25994 +               goto out;
25995 +
25996 +       err = 0;
25997 +       wh->wh_bindex = bindex;
25998 +       if (shwh)
25999 +               au_shwh_init_wh(wh, ino, d_type);
26000 +       str = &wh->wh_str;
26001 +       str->len = nlen;
26002 +       memcpy(str->name, name, nlen);
26003 +       hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
26004 +       /* smp_mb(); */
26005 +
26006 +out:
26007 +       return err;
26008 +}
26009 +
26010 +static int append_deblk(struct au_vdir *vdir)
26011 +{
26012 +       int err;
26013 +       unsigned long ul;
26014 +       const unsigned int deblk_sz = vdir->vd_deblk_sz;
26015 +       union au_vdir_deblk_p p, deblk_end;
26016 +       unsigned char **o;
26017 +
26018 +       err = -ENOMEM;
26019 +       o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
26020 +                    GFP_NOFS);
26021 +       if (unlikely(!o))
26022 +               goto out;
26023 +
26024 +       vdir->vd_deblk = o;
26025 +       p.deblk = kmalloc(deblk_sz, GFP_NOFS);
26026 +       if (p.deblk) {
26027 +               ul = vdir->vd_nblk++;
26028 +               vdir->vd_deblk[ul] = p.deblk;
26029 +               vdir->vd_last.ul = ul;
26030 +               vdir->vd_last.p.deblk = p.deblk;
26031 +               deblk_end.deblk = p.deblk + deblk_sz;
26032 +               err = set_deblk_end(&p, &deblk_end);
26033 +       }
26034 +
26035 +out:
26036 +       return err;
26037 +}
26038 +
26039 +static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
26040 +                    unsigned int d_type, struct au_nhash *delist)
26041 +{
26042 +       int err;
26043 +       unsigned int sz;
26044 +       const unsigned int deblk_sz = vdir->vd_deblk_sz;
26045 +       union au_vdir_deblk_p p, *room, deblk_end;
26046 +       struct au_vdir_dehstr *dehstr;
26047 +
26048 +       p.deblk = last_deblk(vdir);
26049 +       deblk_end.deblk = p.deblk + deblk_sz;
26050 +       room = &vdir->vd_last.p;
26051 +       AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
26052 +                 || !is_deblk_end(room, &deblk_end));
26053 +
26054 +       sz = calc_size(nlen);
26055 +       if (unlikely(sz > deblk_end.deblk - room->deblk)) {
26056 +               err = append_deblk(vdir);
26057 +               if (unlikely(err))
26058 +                       goto out;
26059 +
26060 +               p.deblk = last_deblk(vdir);
26061 +               deblk_end.deblk = p.deblk + deblk_sz;
26062 +               /* smp_mb(); */
26063 +               AuDebugOn(room->deblk != p.deblk);
26064 +       }
26065 +
26066 +       err = -ENOMEM;
26067 +       dehstr = au_cache_alloc_vdir_dehstr();
26068 +       if (unlikely(!dehstr))
26069 +               goto out;
26070 +
26071 +       dehstr->str = &room->de->de_str;
26072 +       hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
26073 +       room->de->de_ino = ino;
26074 +       room->de->de_type = d_type;
26075 +       room->de->de_str.len = nlen;
26076 +       memcpy(room->de->de_str.name, name, nlen);
26077 +
26078 +       err = 0;
26079 +       room->deblk += sz;
26080 +       if (unlikely(set_deblk_end(room, &deblk_end)))
26081 +               err = append_deblk(vdir);
26082 +       /* smp_mb(); */
26083 +
26084 +out:
26085 +       return err;
26086 +}
26087 +
26088 +/* ---------------------------------------------------------------------- */
26089 +
26090 +void au_vdir_free(struct au_vdir *vdir)
26091 +{
26092 +       unsigned char **deblk;
26093 +
26094 +       deblk = vdir->vd_deblk;
26095 +       while (vdir->vd_nblk--)
26096 +               kfree(*deblk++);
26097 +       kfree(vdir->vd_deblk);
26098 +       au_cache_free_vdir(vdir);
26099 +}
26100 +
26101 +static struct au_vdir *alloc_vdir(struct file *file)
26102 +{
26103 +       struct au_vdir *vdir;
26104 +       struct super_block *sb;
26105 +       int err;
26106 +
26107 +       sb = file->f_dentry->d_sb;
26108 +       SiMustAnyLock(sb);
26109 +
26110 +       err = -ENOMEM;
26111 +       vdir = au_cache_alloc_vdir();
26112 +       if (unlikely(!vdir))
26113 +               goto out;
26114 +
26115 +       vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
26116 +       if (unlikely(!vdir->vd_deblk))
26117 +               goto out_free;
26118 +
26119 +       vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
26120 +       if (!vdir->vd_deblk_sz) {
26121 +               /* estimate the apropriate size for deblk */
26122 +               vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
26123 +               /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
26124 +       }
26125 +       vdir->vd_nblk = 0;
26126 +       vdir->vd_version = 0;
26127 +       vdir->vd_jiffy = 0;
26128 +       err = append_deblk(vdir);
26129 +       if (!err)
26130 +               return vdir; /* success */
26131 +
26132 +       kfree(vdir->vd_deblk);
26133 +
26134 +out_free:
26135 +       au_cache_free_vdir(vdir);
26136 +out:
26137 +       vdir = ERR_PTR(err);
26138 +       return vdir;
26139 +}
26140 +
26141 +static int reinit_vdir(struct au_vdir *vdir)
26142 +{
26143 +       int err;
26144 +       union au_vdir_deblk_p p, deblk_end;
26145 +
26146 +       while (vdir->vd_nblk > 1) {
26147 +               kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
26148 +               /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
26149 +               vdir->vd_nblk--;
26150 +       }
26151 +       p.deblk = vdir->vd_deblk[0];
26152 +       deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
26153 +       err = set_deblk_end(&p, &deblk_end);
26154 +       /* keep vd_dblk_sz */
26155 +       vdir->vd_last.ul = 0;
26156 +       vdir->vd_last.p.deblk = vdir->vd_deblk[0];
26157 +       vdir->vd_version = 0;
26158 +       vdir->vd_jiffy = 0;
26159 +       /* smp_mb(); */
26160 +       return err;
26161 +}
26162 +
26163 +/* ---------------------------------------------------------------------- */
26164 +
26165 +#define AuFillVdir_CALLED      1
26166 +#define AuFillVdir_WHABLE      (1 << 1)
26167 +#define AuFillVdir_SHWH                (1 << 2)
26168 +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
26169 +#define au_fset_fillvdir(flags, name) \
26170 +       do { (flags) |= AuFillVdir_##name; } while (0)
26171 +#define au_fclr_fillvdir(flags, name) \
26172 +       do { (flags) &= ~AuFillVdir_##name; } while (0)
26173 +
26174 +#ifndef CONFIG_AUFS_SHWH
26175 +#undef AuFillVdir_SHWH
26176 +#define AuFillVdir_SHWH                0
26177 +#endif
26178 +
26179 +struct fillvdir_arg {
26180 +       struct file             *file;
26181 +       struct au_vdir          *vdir;
26182 +       struct au_nhash         delist;
26183 +       struct au_nhash         whlist;
26184 +       aufs_bindex_t           bindex;
26185 +       unsigned int            flags;
26186 +       int                     err;
26187 +};
26188 +
26189 +static int fillvdir(void *__arg, const char *__name, int nlen,
26190 +                   loff_t offset __maybe_unused, u64 h_ino,
26191 +                   unsigned int d_type)
26192 +{
26193 +       struct fillvdir_arg *arg = __arg;
26194 +       char *name = (void *)__name;
26195 +       struct super_block *sb;
26196 +       ino_t ino;
26197 +       const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
26198 +
26199 +       arg->err = 0;
26200 +       sb = arg->file->f_dentry->d_sb;
26201 +       au_fset_fillvdir(arg->flags, CALLED);
26202 +       /* smp_mb(); */
26203 +       if (nlen <= AUFS_WH_PFX_LEN
26204 +           || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
26205 +               if (test_known(&arg->delist, name, nlen)
26206 +                   || au_nhash_test_known_wh(&arg->whlist, name, nlen))
26207 +                       goto out; /* already exists or whiteouted */
26208 +
26209 +               sb = arg->file->f_dentry->d_sb;
26210 +               arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
26211 +               if (!arg->err) {
26212 +                       if (unlikely(nlen > AUFS_MAX_NAMELEN))
26213 +                               d_type = DT_UNKNOWN;
26214 +                       arg->err = append_de(arg->vdir, name, nlen, ino,
26215 +                                            d_type, &arg->delist);
26216 +               }
26217 +       } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
26218 +               name += AUFS_WH_PFX_LEN;
26219 +               nlen -= AUFS_WH_PFX_LEN;
26220 +               if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
26221 +                       goto out; /* already whiteouted */
26222 +
26223 +               if (shwh)
26224 +                       arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
26225 +                                            &ino);
26226 +               if (!arg->err) {
26227 +                       if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
26228 +                               d_type = DT_UNKNOWN;
26229 +                       arg->err = au_nhash_append_wh
26230 +                               (&arg->whlist, name, nlen, ino, d_type,
26231 +                                arg->bindex, shwh);
26232 +               }
26233 +       }
26234 +
26235 +out:
26236 +       if (!arg->err)
26237 +               arg->vdir->vd_jiffy = jiffies;
26238 +       /* smp_mb(); */
26239 +       AuTraceErr(arg->err);
26240 +       return arg->err;
26241 +}
26242 +
26243 +static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
26244 +                         struct au_nhash *whlist, struct au_nhash *delist)
26245 +{
26246 +#ifdef CONFIG_AUFS_SHWH
26247 +       int err;
26248 +       unsigned int nh, u;
26249 +       struct hlist_head *head;
26250 +       struct au_vdir_wh *pos;
26251 +       struct hlist_node *n;
26252 +       char *p, *o;
26253 +       struct au_vdir_destr *destr;
26254 +
26255 +       AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
26256 +
26257 +       err = -ENOMEM;
26258 +       o = p = (void *)__get_free_page(GFP_NOFS);
26259 +       if (unlikely(!p))
26260 +               goto out;
26261 +
26262 +       err = 0;
26263 +       nh = whlist->nh_num;
26264 +       memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
26265 +       p += AUFS_WH_PFX_LEN;
26266 +       for (u = 0; u < nh; u++) {
26267 +               head = whlist->nh_head + u;
26268 +               hlist_for_each_entry_safe(pos, n, head, wh_hash) {
26269 +                       destr = &pos->wh_str;
26270 +                       memcpy(p, destr->name, destr->len);
26271 +                       err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
26272 +                                       pos->wh_ino, pos->wh_type, delist);
26273 +                       if (unlikely(err))
26274 +                               break;
26275 +               }
26276 +       }
26277 +
26278 +       free_page((unsigned long)o);
26279 +
26280 +out:
26281 +       AuTraceErr(err);
26282 +       return err;
26283 +#else
26284 +       return 0;
26285 +#endif
26286 +}
26287 +
26288 +static int au_do_read_vdir(struct fillvdir_arg *arg)
26289 +{
26290 +       int err;
26291 +       unsigned int rdhash;
26292 +       loff_t offset;
26293 +       aufs_bindex_t bend, bindex, bstart;
26294 +       unsigned char shwh;
26295 +       struct file *hf, *file;
26296 +       struct super_block *sb;
26297 +
26298 +       file = arg->file;
26299 +       sb = file->f_dentry->d_sb;
26300 +       SiMustAnyLock(sb);
26301 +
26302 +       rdhash = au_sbi(sb)->si_rdhash;
26303 +       if (!rdhash)
26304 +               rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
26305 +       err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
26306 +       if (unlikely(err))
26307 +               goto out;
26308 +       err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
26309 +       if (unlikely(err))
26310 +               goto out_delist;
26311 +
26312 +       err = 0;
26313 +       arg->flags = 0;
26314 +       shwh = 0;
26315 +       if (au_opt_test(au_mntflags(sb), SHWH)) {
26316 +               shwh = 1;
26317 +               au_fset_fillvdir(arg->flags, SHWH);
26318 +       }
26319 +       bstart = au_fbstart(file);
26320 +       bend = au_fbend_dir(file);
26321 +       for (bindex = bstart; !err && bindex <= bend; bindex++) {
26322 +               hf = au_hf_dir(file, bindex);
26323 +               if (!hf)
26324 +                       continue;
26325 +
26326 +               offset = vfsub_llseek(hf, 0, SEEK_SET);
26327 +               err = offset;
26328 +               if (unlikely(offset))
26329 +                       break;
26330 +
26331 +               arg->bindex = bindex;
26332 +               au_fclr_fillvdir(arg->flags, WHABLE);
26333 +               if (shwh
26334 +                   || (bindex != bend
26335 +                       && au_br_whable(au_sbr_perm(sb, bindex))))
26336 +                       au_fset_fillvdir(arg->flags, WHABLE);
26337 +               do {
26338 +                       arg->err = 0;
26339 +                       au_fclr_fillvdir(arg->flags, CALLED);
26340 +                       /* smp_mb(); */
26341 +                       err = vfsub_readdir(hf, fillvdir, arg);
26342 +                       if (err >= 0)
26343 +                               err = arg->err;
26344 +               } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
26345 +       }
26346 +
26347 +       if (!err && shwh)
26348 +               err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
26349 +
26350 +       au_nhash_wh_free(&arg->whlist);
26351 +
26352 +out_delist:
26353 +       au_nhash_de_free(&arg->delist);
26354 +out:
26355 +       return err;
26356 +}
26357 +
26358 +static int read_vdir(struct file *file, int may_read)
26359 +{
26360 +       int err;
26361 +       unsigned long expire;
26362 +       unsigned char do_read;
26363 +       struct fillvdir_arg arg;
26364 +       struct inode *inode;
26365 +       struct au_vdir *vdir, *allocated;
26366 +
26367 +       err = 0;
26368 +       inode = file_inode(file);
26369 +       IMustLock(inode);
26370 +       SiMustAnyLock(inode->i_sb);
26371 +
26372 +       allocated = NULL;
26373 +       do_read = 0;
26374 +       expire = au_sbi(inode->i_sb)->si_rdcache;
26375 +       vdir = au_ivdir(inode);
26376 +       if (!vdir) {
26377 +               do_read = 1;
26378 +               vdir = alloc_vdir(file);
26379 +               err = PTR_ERR(vdir);
26380 +               if (IS_ERR(vdir))
26381 +                       goto out;
26382 +               err = 0;
26383 +               allocated = vdir;
26384 +       } else if (may_read
26385 +                  && (inode->i_version != vdir->vd_version
26386 +                      || time_after(jiffies, vdir->vd_jiffy + expire))) {
26387 +               do_read = 1;
26388 +               err = reinit_vdir(vdir);
26389 +               if (unlikely(err))
26390 +                       goto out;
26391 +       }
26392 +
26393 +       if (!do_read)
26394 +               return 0; /* success */
26395 +
26396 +       arg.file = file;
26397 +       arg.vdir = vdir;
26398 +       err = au_do_read_vdir(&arg);
26399 +       if (!err) {
26400 +               /* file->f_pos = 0; */
26401 +               vdir->vd_version = inode->i_version;
26402 +               vdir->vd_last.ul = 0;
26403 +               vdir->vd_last.p.deblk = vdir->vd_deblk[0];
26404 +               if (allocated)
26405 +                       au_set_ivdir(inode, allocated);
26406 +       } else if (allocated)
26407 +               au_vdir_free(allocated);
26408 +
26409 +out:
26410 +       return err;
26411 +}
26412 +
26413 +static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
26414 +{
26415 +       int err, rerr;
26416 +       unsigned long ul, n;
26417 +       const unsigned int deblk_sz = src->vd_deblk_sz;
26418 +
26419 +       AuDebugOn(tgt->vd_nblk != 1);
26420 +
26421 +       err = -ENOMEM;
26422 +       if (tgt->vd_nblk < src->vd_nblk) {
26423 +               unsigned char **p;
26424 +
26425 +               p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
26426 +                            GFP_NOFS);
26427 +               if (unlikely(!p))
26428 +                       goto out;
26429 +               tgt->vd_deblk = p;
26430 +       }
26431 +
26432 +       if (tgt->vd_deblk_sz != deblk_sz) {
26433 +               unsigned char *p;
26434 +
26435 +               tgt->vd_deblk_sz = deblk_sz;
26436 +               p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
26437 +               if (unlikely(!p))
26438 +                       goto out;
26439 +               tgt->vd_deblk[0] = p;
26440 +       }
26441 +       memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
26442 +       tgt->vd_version = src->vd_version;
26443 +       tgt->vd_jiffy = src->vd_jiffy;
26444 +
26445 +       n = src->vd_nblk;
26446 +       for (ul = 1; ul < n; ul++) {
26447 +               tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
26448 +                                           GFP_NOFS);
26449 +               if (unlikely(!tgt->vd_deblk[ul]))
26450 +                       goto out;
26451 +               tgt->vd_nblk++;
26452 +       }
26453 +       tgt->vd_nblk = n;
26454 +       tgt->vd_last.ul = tgt->vd_last.ul;
26455 +       tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
26456 +       tgt->vd_last.p.deblk += src->vd_last.p.deblk
26457 +               - src->vd_deblk[src->vd_last.ul];
26458 +       /* smp_mb(); */
26459 +       return 0; /* success */
26460 +
26461 +out:
26462 +       rerr = reinit_vdir(tgt);
26463 +       BUG_ON(rerr);
26464 +       return err;
26465 +}
26466 +
26467 +int au_vdir_init(struct file *file)
26468 +{
26469 +       int err;
26470 +       struct inode *inode;
26471 +       struct au_vdir *vdir_cache, *allocated;
26472 +
26473 +       err = read_vdir(file, !file->f_pos);
26474 +       if (unlikely(err))
26475 +               goto out;
26476 +
26477 +       allocated = NULL;
26478 +       vdir_cache = au_fvdir_cache(file);
26479 +       if (!vdir_cache) {
26480 +               vdir_cache = alloc_vdir(file);
26481 +               err = PTR_ERR(vdir_cache);
26482 +               if (IS_ERR(vdir_cache))
26483 +                       goto out;
26484 +               allocated = vdir_cache;
26485 +       } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
26486 +               err = reinit_vdir(vdir_cache);
26487 +               if (unlikely(err))
26488 +                       goto out;
26489 +       } else
26490 +               return 0; /* success */
26491 +
26492 +       inode = file_inode(file);
26493 +       err = copy_vdir(vdir_cache, au_ivdir(inode));
26494 +       if (!err) {
26495 +               file->f_version = inode->i_version;
26496 +               if (allocated)
26497 +                       au_set_fvdir_cache(file, allocated);
26498 +       } else if (allocated)
26499 +               au_vdir_free(allocated);
26500 +
26501 +out:
26502 +       return err;
26503 +}
26504 +
26505 +static loff_t calc_offset(struct au_vdir *vdir)
26506 +{
26507 +       loff_t offset;
26508 +       union au_vdir_deblk_p p;
26509 +
26510 +       p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
26511 +       offset = vdir->vd_last.p.deblk - p.deblk;
26512 +       offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
26513 +       return offset;
26514 +}
26515 +
26516 +/* returns true or false */
26517 +static int seek_vdir(struct file *file)
26518 +{
26519 +       int valid;
26520 +       unsigned int deblk_sz;
26521 +       unsigned long ul, n;
26522 +       loff_t offset;
26523 +       union au_vdir_deblk_p p, deblk_end;
26524 +       struct au_vdir *vdir_cache;
26525 +
26526 +       valid = 1;
26527 +       vdir_cache = au_fvdir_cache(file);
26528 +       offset = calc_offset(vdir_cache);
26529 +       AuDbg("offset %lld\n", offset);
26530 +       if (file->f_pos == offset)
26531 +               goto out;
26532 +
26533 +       vdir_cache->vd_last.ul = 0;
26534 +       vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
26535 +       if (!file->f_pos)
26536 +               goto out;
26537 +
26538 +       valid = 0;
26539 +       deblk_sz = vdir_cache->vd_deblk_sz;
26540 +       ul = div64_u64(file->f_pos, deblk_sz);
26541 +       AuDbg("ul %lu\n", ul);
26542 +       if (ul >= vdir_cache->vd_nblk)
26543 +               goto out;
26544 +
26545 +       n = vdir_cache->vd_nblk;
26546 +       for (; ul < n; ul++) {
26547 +               p.deblk = vdir_cache->vd_deblk[ul];
26548 +               deblk_end.deblk = p.deblk + deblk_sz;
26549 +               offset = ul;
26550 +               offset *= deblk_sz;
26551 +               while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) {
26552 +                       unsigned int l;
26553 +
26554 +                       l = calc_size(p.de->de_str.len);
26555 +                       offset += l;
26556 +                       p.deblk += l;
26557 +               }
26558 +               if (!is_deblk_end(&p, &deblk_end)) {
26559 +                       valid = 1;
26560 +                       vdir_cache->vd_last.ul = ul;
26561 +                       vdir_cache->vd_last.p = p;
26562 +                       break;
26563 +               }
26564 +       }
26565 +
26566 +out:
26567 +       /* smp_mb(); */
26568 +       AuTraceErr(!valid);
26569 +       return valid;
26570 +}
26571 +
26572 +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir)
26573 +{
26574 +       int err;
26575 +       unsigned int l, deblk_sz;
26576 +       union au_vdir_deblk_p deblk_end;
26577 +       struct au_vdir *vdir_cache;
26578 +       struct au_vdir_de *de;
26579 +
26580 +       vdir_cache = au_fvdir_cache(file);
26581 +       if (!seek_vdir(file))
26582 +               return 0;
26583 +
26584 +       deblk_sz = vdir_cache->vd_deblk_sz;
26585 +       while (1) {
26586 +               deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
26587 +               deblk_end.deblk += deblk_sz;
26588 +               while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
26589 +                       de = vdir_cache->vd_last.p.de;
26590 +                       AuDbg("%.*s, off%lld, i%lu, dt%d\n",
26591 +                             de->de_str.len, de->de_str.name, file->f_pos,
26592 +                             (unsigned long)de->de_ino, de->de_type);
26593 +                       err = filldir(dirent, de->de_str.name, de->de_str.len,
26594 +                                     file->f_pos, de->de_ino, de->de_type);
26595 +                       if (unlikely(err)) {
26596 +                               AuTraceErr(err);
26597 +                               /* todo: ignore the error caused by udba? */
26598 +                               /* return err; */
26599 +                               return 0;
26600 +                       }
26601 +
26602 +                       l = calc_size(de->de_str.len);
26603 +                       vdir_cache->vd_last.p.deblk += l;
26604 +                       file->f_pos += l;
26605 +               }
26606 +               if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
26607 +                       vdir_cache->vd_last.ul++;
26608 +                       vdir_cache->vd_last.p.deblk
26609 +                               = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
26610 +                       file->f_pos = deblk_sz * vdir_cache->vd_last.ul;
26611 +                       continue;
26612 +               }
26613 +               break;
26614 +       }
26615 +
26616 +       /* smp_mb(); */
26617 +       return 0;
26618 +}
26619 diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
26620 --- /usr/share/empty/fs/aufs/vfsub.c    1970-01-01 01:00:00.000000000 +0100
26621 +++ linux/fs/aufs/vfsub.c       2013-07-30 22:42:55.842946719 +0200
26622 @@ -0,0 +1,769 @@
26623 +/*
26624 + * Copyright (C) 2005-2013 Junjiro R. Okajima
26625 + *
26626 + * This program, aufs is free software; you can redistribute it and/or modify
26627 + * it under the terms of the GNU General Public License as published by
26628 + * the Free Software Foundation; either version 2 of the License, or
26629 + * (at your option) any later version.
26630 + *
26631 + * This program is distributed in the hope that it will be useful,
26632 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
26633 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26634 + * GNU General Public License for more details.
26635 + *
26636 + * You should have received a copy of the GNU General Public License
26637 + * along with this program; if not, write to the Free Software
26638 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
26639 + */
26640 +
26641 +/*
26642 + * sub-routines for VFS
26643 + */
26644 +
26645 +#include <linux/ima.h>
26646 +#include <linux/namei.h>
26647 +#include <linux/security.h>
26648 +#include <linux/splice.h>
26649 +#include "aufs.h"
26650 +
26651 +int vfsub_update_h_iattr(struct path *h_path, int *did)
26652 +{
26653 +       int err;
26654 +       struct kstat st;
26655 +       struct super_block *h_sb;
26656 +
26657 +       /* for remote fs, leave work for its getattr or d_revalidate */
26658 +       /* for bad i_attr fs, handle them in aufs_getattr() */
26659 +       /* still some fs may acquire i_mutex. we need to skip them */
26660 +       err = 0;
26661 +       if (!did)
26662 +               did = &err;
26663 +       h_sb = h_path->dentry->d_sb;
26664 +       *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
26665 +       if (*did)
26666 +               err = vfs_getattr(h_path, &st);
26667 +
26668 +       return err;
26669 +}
26670 +
26671 +/* ---------------------------------------------------------------------- */
26672 +
26673 +struct file *vfsub_dentry_open(struct path *path, int flags)
26674 +{
26675 +       struct file *file;
26676 +
26677 +       file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
26678 +                          current_cred());
26679 +       if (!IS_ERR_OR_NULL(file)
26680 +           && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
26681 +               i_readcount_inc(path->dentry->d_inode);
26682 +
26683 +       return file;
26684 +}
26685 +
26686 +struct file *vfsub_filp_open(const char *path, int oflags, int mode)
26687 +{
26688 +       struct file *file;
26689 +
26690 +       lockdep_off();
26691 +       file = filp_open(path,
26692 +                        oflags /* | __FMODE_NONOTIFY */,
26693 +                        mode);
26694 +       lockdep_on();
26695 +       if (IS_ERR(file))
26696 +               goto out;
26697 +       vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26698 +
26699 +out:
26700 +       return file;
26701 +}
26702 +
26703 +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
26704 +{
26705 +       int err;
26706 +
26707 +       err = kern_path(name, flags, path);
26708 +       if (!err && path->dentry->d_inode)
26709 +               vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
26710 +       return err;
26711 +}
26712 +
26713 +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
26714 +                                   int len)
26715 +{
26716 +       struct path path = {
26717 +               .mnt = NULL
26718 +       };
26719 +
26720 +       /* VFS checks it too, but by WARN_ON_ONCE() */
26721 +       IMustLock(parent->d_inode);
26722 +
26723 +       path.dentry = lookup_one_len(name, parent, len);
26724 +       if (IS_ERR(path.dentry))
26725 +               goto out;
26726 +       if (path.dentry->d_inode)
26727 +               vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
26728 +
26729 +out:
26730 +       AuTraceErrPtr(path.dentry);
26731 +       return path.dentry;
26732 +}
26733 +
26734 +void vfsub_call_lkup_one(void *args)
26735 +{
26736 +       struct vfsub_lkup_one_args *a = args;
26737 +       *a->errp = vfsub_lkup_one(a->name, a->parent);
26738 +}
26739 +
26740 +/* ---------------------------------------------------------------------- */
26741 +
26742 +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
26743 +                                struct dentry *d2, struct au_hinode *hdir2)
26744 +{
26745 +       struct dentry *d;
26746 +
26747 +       lockdep_off();
26748 +       d = lock_rename(d1, d2);
26749 +       lockdep_on();
26750 +       au_hn_suspend(hdir1);
26751 +       if (hdir1 != hdir2)
26752 +               au_hn_suspend(hdir2);
26753 +
26754 +       return d;
26755 +}
26756 +
26757 +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
26758 +                        struct dentry *d2, struct au_hinode *hdir2)
26759 +{
26760 +       au_hn_resume(hdir1);
26761 +       if (hdir1 != hdir2)
26762 +               au_hn_resume(hdir2);
26763 +       lockdep_off();
26764 +       unlock_rename(d1, d2);
26765 +       lockdep_on();
26766 +}
26767 +
26768 +/* ---------------------------------------------------------------------- */
26769 +
26770 +int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
26771 +{
26772 +       int err;
26773 +       struct dentry *d;
26774 +
26775 +       IMustLock(dir);
26776 +
26777 +       d = path->dentry;
26778 +       path->dentry = d->d_parent;
26779 +       err = security_path_mknod(path, d, mode, 0);
26780 +       path->dentry = d;
26781 +       if (unlikely(err))
26782 +               goto out;
26783 +
26784 +       err = vfs_create(dir, path->dentry, mode, want_excl);
26785 +       if (!err) {
26786 +               struct path tmp = *path;
26787 +               int did;
26788 +
26789 +               vfsub_update_h_iattr(&tmp, &did);
26790 +               if (did) {
26791 +                       tmp.dentry = path->dentry->d_parent;
26792 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26793 +               }
26794 +               /*ignore*/
26795 +       }
26796 +
26797 +out:
26798 +       return err;
26799 +}
26800 +
26801 +int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
26802 +{
26803 +       int err;
26804 +       struct dentry *d;
26805 +
26806 +       IMustLock(dir);
26807 +
26808 +       d = path->dentry;
26809 +       path->dentry = d->d_parent;
26810 +       err = security_path_symlink(path, d, symname);
26811 +       path->dentry = d;
26812 +       if (unlikely(err))
26813 +               goto out;
26814 +
26815 +       err = vfs_symlink(dir, path->dentry, symname);
26816 +       if (!err) {
26817 +               struct path tmp = *path;
26818 +               int did;
26819 +
26820 +               vfsub_update_h_iattr(&tmp, &did);
26821 +               if (did) {
26822 +                       tmp.dentry = path->dentry->d_parent;
26823 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26824 +               }
26825 +               /*ignore*/
26826 +       }
26827 +
26828 +out:
26829 +       return err;
26830 +}
26831 +
26832 +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
26833 +{
26834 +       int err;
26835 +       struct dentry *d;
26836 +
26837 +       IMustLock(dir);
26838 +
26839 +       d = path->dentry;
26840 +       path->dentry = d->d_parent;
26841 +       err = security_path_mknod(path, d, mode, new_encode_dev(dev));
26842 +       path->dentry = d;
26843 +       if (unlikely(err))
26844 +               goto out;
26845 +
26846 +       err = vfs_mknod(dir, path->dentry, mode, dev);
26847 +       if (!err) {
26848 +               struct path tmp = *path;
26849 +               int did;
26850 +
26851 +               vfsub_update_h_iattr(&tmp, &did);
26852 +               if (did) {
26853 +                       tmp.dentry = path->dentry->d_parent;
26854 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26855 +               }
26856 +               /*ignore*/
26857 +       }
26858 +
26859 +out:
26860 +       return err;
26861 +}
26862 +
26863 +static int au_test_nlink(struct inode *inode)
26864 +{
26865 +       const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
26866 +
26867 +       if (!au_test_fs_no_limit_nlink(inode->i_sb)
26868 +           || inode->i_nlink < link_max)
26869 +               return 0;
26870 +       return -EMLINK;
26871 +}
26872 +
26873 +int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
26874 +{
26875 +       int err;
26876 +       struct dentry *d;
26877 +
26878 +       IMustLock(dir);
26879 +
26880 +       err = au_test_nlink(src_dentry->d_inode);
26881 +       if (unlikely(err))
26882 +               return err;
26883 +
26884 +       /* we don't call may_linkat() */
26885 +       d = path->dentry;
26886 +       path->dentry = d->d_parent;
26887 +       err = security_path_link(src_dentry, path, d);
26888 +       path->dentry = d;
26889 +       if (unlikely(err))
26890 +               goto out;
26891 +
26892 +       lockdep_off();
26893 +       err = vfs_link(src_dentry, dir, path->dentry);
26894 +       lockdep_on();
26895 +       if (!err) {
26896 +               struct path tmp = *path;
26897 +               int did;
26898 +
26899 +               /* fuse has different memory inode for the same inumber */
26900 +               vfsub_update_h_iattr(&tmp, &did);
26901 +               if (did) {
26902 +                       tmp.dentry = path->dentry->d_parent;
26903 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26904 +                       tmp.dentry = src_dentry;
26905 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26906 +               }
26907 +               /*ignore*/
26908 +       }
26909 +
26910 +out:
26911 +       return err;
26912 +}
26913 +
26914 +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
26915 +                struct inode *dir, struct path *path)
26916 +{
26917 +       int err;
26918 +       struct path tmp = {
26919 +               .mnt    = path->mnt
26920 +       };
26921 +       struct dentry *d;
26922 +
26923 +       IMustLock(dir);
26924 +       IMustLock(src_dir);
26925 +
26926 +       d = path->dentry;
26927 +       path->dentry = d->d_parent;
26928 +       tmp.dentry = src_dentry->d_parent;
26929 +       err = security_path_rename(&tmp, src_dentry, path, d);
26930 +       path->dentry = d;
26931 +       if (unlikely(err))
26932 +               goto out;
26933 +
26934 +       lockdep_off();
26935 +       err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
26936 +       lockdep_on();
26937 +       if (!err) {
26938 +               int did;
26939 +
26940 +               tmp.dentry = d->d_parent;
26941 +               vfsub_update_h_iattr(&tmp, &did);
26942 +               if (did) {
26943 +                       tmp.dentry = src_dentry;
26944 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26945 +                       tmp.dentry = src_dentry->d_parent;
26946 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26947 +               }
26948 +               /*ignore*/
26949 +       }
26950 +
26951 +out:
26952 +       return err;
26953 +}
26954 +
26955 +int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
26956 +{
26957 +       int err;
26958 +       struct dentry *d;
26959 +
26960 +       IMustLock(dir);
26961 +
26962 +       d = path->dentry;
26963 +       path->dentry = d->d_parent;
26964 +       err = security_path_mkdir(path, d, mode);
26965 +       path->dentry = d;
26966 +       if (unlikely(err))
26967 +               goto out;
26968 +
26969 +       err = vfs_mkdir(dir, path->dentry, mode);
26970 +       if (!err) {
26971 +               struct path tmp = *path;
26972 +               int did;
26973 +
26974 +               vfsub_update_h_iattr(&tmp, &did);
26975 +               if (did) {
26976 +                       tmp.dentry = path->dentry->d_parent;
26977 +                       vfsub_update_h_iattr(&tmp, /*did*/NULL);
26978 +               }
26979 +               /*ignore*/
26980 +       }
26981 +
26982 +out:
26983 +       return err;
26984 +}
26985 +
26986 +int vfsub_rmdir(struct inode *dir, struct path *path)
26987 +{
26988 +       int err;
26989 +       struct dentry *d;
26990 +
26991 +       IMustLock(dir);
26992 +
26993 +       d = path->dentry;
26994 +       path->dentry = d->d_parent;
26995 +       err = security_path_rmdir(path, d);
26996 +       path->dentry = d;
26997 +       if (unlikely(err))
26998 +               goto out;
26999 +
27000 +       lockdep_off();
27001 +       err = vfs_rmdir(dir, path->dentry);
27002 +       lockdep_on();
27003 +       if (!err) {
27004 +               struct path tmp = {
27005 +                       .dentry = path->dentry->d_parent,
27006 +                       .mnt    = path->mnt
27007 +               };
27008 +
27009 +               vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
27010 +       }
27011 +
27012 +out:
27013 +       return err;
27014 +}
27015 +
27016 +/* ---------------------------------------------------------------------- */
27017 +
27018 +/* todo: support mmap_sem? */
27019 +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
27020 +                    loff_t *ppos)
27021 +{
27022 +       ssize_t err;
27023 +
27024 +       lockdep_off();
27025 +       err = vfs_read(file, ubuf, count, ppos);
27026 +       lockdep_on();
27027 +       if (err >= 0)
27028 +               vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27029 +       return err;
27030 +}
27031 +
27032 +/* todo: kernel_read()? */
27033 +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
27034 +                    loff_t *ppos)
27035 +{
27036 +       ssize_t err;
27037 +       mm_segment_t oldfs;
27038 +       union {
27039 +               void *k;
27040 +               char __user *u;
27041 +       } buf;
27042 +
27043 +       buf.k = kbuf;
27044 +       oldfs = get_fs();
27045 +       set_fs(KERNEL_DS);
27046 +       err = vfsub_read_u(file, buf.u, count, ppos);
27047 +       set_fs(oldfs);
27048 +       return err;
27049 +}
27050 +
27051 +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
27052 +                     loff_t *ppos)
27053 +{
27054 +       ssize_t err;
27055 +
27056 +       lockdep_off();
27057 +       err = vfs_write(file, ubuf, count, ppos);
27058 +       lockdep_on();
27059 +       if (err >= 0)
27060 +               vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27061 +       return err;
27062 +}
27063 +
27064 +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
27065 +{
27066 +       ssize_t err;
27067 +       mm_segment_t oldfs;
27068 +       union {
27069 +               void *k;
27070 +               const char __user *u;
27071 +       } buf;
27072 +
27073 +       buf.k = kbuf;
27074 +       oldfs = get_fs();
27075 +       set_fs(KERNEL_DS);
27076 +       err = vfsub_write_u(file, buf.u, count, ppos);
27077 +       set_fs(oldfs);
27078 +       return err;
27079 +}
27080 +
27081 +int vfsub_flush(struct file *file, fl_owner_t id)
27082 +{
27083 +       int err;
27084 +
27085 +       err = 0;
27086 +       if (file->f_op && file->f_op->flush) {
27087 +               if (!au_test_nfs(file->f_dentry->d_sb))
27088 +                       err = file->f_op->flush(file, id);
27089 +               else {
27090 +                       lockdep_off();
27091 +                       err = file->f_op->flush(file, id);
27092 +                       lockdep_on();
27093 +               }
27094 +               if (!err)
27095 +                       vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
27096 +               /*ignore*/
27097 +       }
27098 +       return err;
27099 +}
27100 +
27101 +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
27102 +{
27103 +       int err;
27104 +
27105 +       lockdep_off();
27106 +       err = vfs_readdir(file, filldir, arg);
27107 +       lockdep_on();
27108 +       if (err >= 0)
27109 +               vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
27110 +       return err;
27111 +}
27112 +
27113 +long vfsub_splice_to(struct file *in, loff_t *ppos,
27114 +                    struct pipe_inode_info *pipe, size_t len,
27115 +                    unsigned int flags)
27116 +{
27117 +       long err;
27118 +
27119 +       lockdep_off();
27120 +       err = do_splice_to(in, ppos, pipe, len, flags);
27121 +       lockdep_on();
27122 +       file_accessed(in);
27123 +       if (err >= 0)
27124 +               vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
27125 +       return err;
27126 +}
27127 +
27128 +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
27129 +                      loff_t *ppos, size_t len, unsigned int flags)
27130 +{
27131 +       long err;
27132 +
27133 +       lockdep_off();
27134 +       err = do_splice_from(pipe, out, ppos, len, flags);
27135 +       lockdep_on();
27136 +       if (err >= 0)
27137 +               vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
27138 +       return err;
27139 +}
27140 +
27141 +int vfsub_fsync(struct file *file, struct path *path, int datasync)
27142 +{
27143 +       int err;
27144 +
27145 +       /* file can be NULL */
27146 +       lockdep_off();
27147 +       err = vfs_fsync(file, datasync);
27148 +       lockdep_on();
27149 +       if (!err) {
27150 +               if (!path) {
27151 +                       AuDebugOn(!file);
27152 +                       path = &file->f_path;
27153 +               }
27154 +               vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
27155 +       }
27156 +       return err;
27157 +}
27158 +
27159 +/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
27160 +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
27161 +               struct file *h_file)
27162 +{
27163 +       int err;
27164 +       struct inode *h_inode;
27165 +       struct super_block *h_sb;
27166 +
27167 +       if (!h_file) {
27168 +               err = vfsub_truncate(h_path, length);
27169 +               goto out;
27170 +       }
27171 +
27172 +       h_inode = h_path->dentry->d_inode;
27173 +       h_sb = h_inode->i_sb;
27174 +       lockdep_off();
27175 +       sb_start_write(h_sb);
27176 +       lockdep_on();
27177 +       err = locks_verify_truncate(h_inode, h_file, length);
27178 +       if (!err)
27179 +               err = security_path_truncate(h_path);
27180 +       if (!err) {
27181 +               lockdep_off();
27182 +               err = do_truncate(h_path->dentry, length, attr, h_file);
27183 +               lockdep_on();
27184 +       }
27185 +       lockdep_off();
27186 +       sb_end_write(h_sb);
27187 +       lockdep_on();
27188 +
27189 +out:
27190 +       return err;
27191 +}
27192 +
27193 +/* ---------------------------------------------------------------------- */
27194 +
27195 +struct au_vfsub_mkdir_args {
27196 +       int *errp;
27197 +       struct inode *dir;
27198 +       struct path *path;
27199 +       int mode;
27200 +};
27201 +
27202 +static void au_call_vfsub_mkdir(void *args)
27203 +{
27204 +       struct au_vfsub_mkdir_args *a = args;
27205 +       *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
27206 +}
27207 +
27208 +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
27209 +{
27210 +       int err, do_sio, wkq_err;
27211 +
27212 +       do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
27213 +       if (!do_sio)
27214 +               err = vfsub_mkdir(dir, path, mode);
27215 +       else {
27216 +               struct au_vfsub_mkdir_args args = {
27217 +                       .errp   = &err,
27218 +                       .dir    = dir,
27219 +                       .path   = path,
27220 +                       .mode   = mode
27221 +               };
27222 +               wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
27223 +               if (unlikely(wkq_err))
27224 +                       err = wkq_err;
27225 +       }
27226 +
27227 +       return err;
27228 +}
27229 +
27230 +struct au_vfsub_rmdir_args {
27231 +       int *errp;
27232 +       struct inode *dir;
27233 +       struct path *path;
27234 +};
27235 +
27236 +static void au_call_vfsub_rmdir(void *args)
27237 +{
27238 +       struct au_vfsub_rmdir_args *a = args;
27239 +       *a->errp = vfsub_rmdir(a->dir, a->path);
27240 +}
27241 +
27242 +int vfsub_sio_rmdir(struct inode *dir, struct path *path)
27243 +{
27244 +       int err, do_sio, wkq_err;
27245 +
27246 +       do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
27247 +       if (!do_sio)
27248 +               err = vfsub_rmdir(dir, path);
27249 +       else {
27250 +               struct au_vfsub_rmdir_args args = {
27251 +                       .errp   = &err,
27252 +                       .dir    = dir,
27253 +                       .path   = path
27254 +               };
27255 +               wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
27256 +               if (unlikely(wkq_err))
27257 +                       err = wkq_err;
27258 +       }
27259 +
27260 +       return err;
27261 +}
27262 +
27263 +/* ---------------------------------------------------------------------- */
27264 +
27265 +struct notify_change_args {
27266 +       int *errp;
27267 +       struct path *path;
27268 +       struct iattr *ia;
27269 +};
27270 +
27271 +static void call_notify_change(void *args)
27272 +{
27273 +       struct notify_change_args *a = args;
27274 +       struct inode *h_inode;
27275 +
27276 +       h_inode = a->path->dentry->d_inode;
27277 +       IMustLock(h_inode);
27278 +
27279 +       *a->errp = -EPERM;
27280 +       if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
27281 +               *a->errp = notify_change(a->path->dentry, a->ia);
27282 +               if (!*a->errp)
27283 +                       vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
27284 +       }
27285 +       AuTraceErr(*a->errp);
27286 +}
27287 +
27288 +int vfsub_notify_change(struct path *path, struct iattr *ia)
27289 +{
27290 +       int err;
27291 +       struct notify_change_args args = {
27292 +               .errp   = &err,
27293 +               .path   = path,
27294 +               .ia     = ia
27295 +       };
27296 +
27297 +       call_notify_change(&args);
27298 +
27299 +       return err;
27300 +}
27301 +
27302 +int vfsub_sio_notify_change(struct path *path, struct iattr *ia)
27303 +{
27304 +       int err, wkq_err;
27305 +       struct notify_change_args args = {
27306 +               .errp   = &err,
27307 +               .path   = path,
27308 +               .ia     = ia
27309 +       };
27310 +
27311 +       wkq_err = au_wkq_wait(call_notify_change, &args);
27312 +       if (unlikely(wkq_err))
27313 +               err = wkq_err;
27314 +
27315 +       return err;
27316 +}
27317 +
27318 +/* ---------------------------------------------------------------------- */
27319 +
27320 +struct unlink_args {
27321 +       int *errp;
27322 +       struct inode *dir;
27323 +       struct path *path;
27324 +};
27325 +
27326 +static void call_unlink(void *args)
27327 +{
27328 +       struct unlink_args *a = args;
27329 +       struct dentry *d = a->path->dentry;
27330 +       struct inode *h_inode;
27331 +       const int stop_sillyrename = (au_test_nfs(d->d_sb)
27332 +                                     && d->d_count == 1);
27333 +
27334 +       IMustLock(a->dir);
27335 +
27336 +       a->path->dentry = d->d_parent;
27337 +       *a->errp = security_path_unlink(a->path, d);
27338 +       a->path->dentry = d;
27339 +       if (unlikely(*a->errp))
27340 +               return;
27341 +
27342 +       if (!stop_sillyrename)
27343 +               dget(d);
27344 +       h_inode = d->d_inode;
27345 +       if (h_inode)
27346 +               ihold(h_inode);
27347 +
27348 +       lockdep_off();
27349 +       *a->errp = vfs_unlink(a->dir, d);
27350 +       lockdep_on();
27351 +       if (!*a->errp) {
27352 +               struct path tmp = {
27353 +                       .dentry = d->d_parent,
27354 +                       .mnt    = a->path->mnt
27355 +               };
27356 +               vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
27357 +       }
27358 +
27359 +       if (!stop_sillyrename)
27360 +               dput(d);
27361 +       if (h_inode)
27362 +               iput(h_inode);
27363 +
27364 +       AuTraceErr(*a->errp);
27365 +}
27366 +
27367 +/*
27368 + * @dir: must be locked.
27369 + * @dentry: target dentry.
27370 + */
27371 +int vfsub_unlink(struct inode *dir, struct path *path, int force)
27372 +{
27373 +       int err;
27374 +       struct unlink_args args = {
27375 +               .errp   = &err,
27376 +               .dir    = dir,
27377 +               .path   = path
27378 +       };
27379 +
27380 +       if (!force)
27381 +               call_unlink(&args);
27382 +       else {
27383 +               int wkq_err;
27384 +
27385 +               wkq_err = au_wkq_wait(call_unlink, &args);
27386 +               if (unlikely(wkq_err))
27387 +                       err = wkq_err;
27388 +       }
27389 +
27390 +       return err;
27391 +}
27392 diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
27393 --- /usr/share/empty/fs/aufs/vfsub.h    1970-01-01 01:00:00.000000000 +0100
27394 +++ linux/fs/aufs/vfsub.h       2013-07-30 22:42:55.842946719 +0200
27395 @@ -0,0 +1,294 @@
27396 +/*
27397 + * Copyright (C) 2005-2013 Junjiro R. Okajima
27398 + *
27399 + * This program, aufs is free software; you can redistribute it and/or modify
27400 + * it under the terms of the GNU General Public License as published by
27401 + * the Free Software Foundation; either version 2 of the License, or
27402 + * (at your option) any later version.
27403 + *
27404 + * This program is distributed in the hope that it will be useful,
27405 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27406 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27407 + * GNU General Public License for more details.
27408 + *
27409 + * You should have received a copy of the GNU General Public License
27410 + * along with this program; if not, write to the Free Software
27411 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27412 + */
27413 +
27414 +/*
27415 + * sub-routines for VFS
27416 + */
27417 +
27418 +#ifndef __AUFS_VFSUB_H__
27419 +#define __AUFS_VFSUB_H__
27420 +
27421 +#ifdef __KERNEL__
27422 +
27423 +#include <linux/fs.h>
27424 +#include <linux/lglock.h>
27425 +#include <linux/mount.h>
27426 +#include "debug.h"
27427 +
27428 +/* copied from linux/fs/internal.h */
27429 +/* todo: BAD approach!! */
27430 +extern struct lglock vfsmount_lock;
27431 +extern void __mnt_drop_write(struct vfsmount *);
27432 +extern spinlock_t inode_sb_list_lock;
27433 +
27434 +/* copied from linux/fs/file_table.c */
27435 +extern struct lglock files_lglock;
27436 +#ifdef CONFIG_SMP
27437 +/*
27438 + * These macros iterate all files on all CPUs for a given superblock.
27439 + * files_lglock must be held globally.
27440 + */
27441 +#define do_file_list_for_each_entry(__sb, __file)              \
27442 +{                                                              \
27443 +       int i;                                                  \
27444 +       for_each_possible_cpu(i) {                              \
27445 +               struct list_head *list;                         \
27446 +               list = per_cpu_ptr((__sb)->s_files, i);         \
27447 +               list_for_each_entry((__file), list, f_u.fu_list)
27448 +
27449 +#define while_file_list_for_each_entry                         \
27450 +       }                                                       \
27451 +}
27452 +
27453 +#else
27454 +
27455 +#define do_file_list_for_each_entry(__sb, __file)              \
27456 +{                                                              \
27457 +       struct list_head *list;                                 \
27458 +       list = &(sb)->s_files;                                  \
27459 +       list_for_each_entry((__file), list, f_u.fu_list)
27460 +
27461 +#define while_file_list_for_each_entry                         \
27462 +}
27463 +#endif
27464 +
27465 +/* ---------------------------------------------------------------------- */
27466 +
27467 +/* lock subclass for lower inode */
27468 +/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
27469 +/* reduce? gave up. */
27470 +enum {
27471 +       AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */
27472 +       AuLsc_I_PARENT,         /* lower inode, parent first */
27473 +       AuLsc_I_PARENT2,        /* copyup dirs */
27474 +       AuLsc_I_PARENT3,        /* copyup wh */
27475 +       AuLsc_I_CHILD,
27476 +       AuLsc_I_CHILD2,
27477 +       AuLsc_I_End
27478 +};
27479 +
27480 +/* to debug easier, do not make them inlined functions */
27481 +#define MtxMustLock(mtx)       AuDebugOn(!mutex_is_locked(mtx))
27482 +#define IMustLock(i)           MtxMustLock(&(i)->i_mutex)
27483 +
27484 +/* ---------------------------------------------------------------------- */
27485 +
27486 +static inline void vfsub_drop_nlink(struct inode *inode)
27487 +{
27488 +       AuDebugOn(!inode->i_nlink);
27489 +       drop_nlink(inode);
27490 +}
27491 +
27492 +static inline void vfsub_dead_dir(struct inode *inode)
27493 +{
27494 +       AuDebugOn(!S_ISDIR(inode->i_mode));
27495 +       inode->i_flags |= S_DEAD;
27496 +       clear_nlink(inode);
27497 +}
27498 +
27499 +/* ---------------------------------------------------------------------- */
27500 +
27501 +int vfsub_update_h_iattr(struct path *h_path, int *did);
27502 +struct file *vfsub_dentry_open(struct path *path, int flags);
27503 +struct file *vfsub_filp_open(const char *path, int oflags, int mode);
27504 +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
27505 +
27506 +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
27507 +                                   int len);
27508 +
27509 +struct vfsub_lkup_one_args {
27510 +       struct dentry **errp;
27511 +       struct qstr *name;
27512 +       struct dentry *parent;
27513 +};
27514 +
27515 +static inline struct dentry *vfsub_lkup_one(struct qstr *name,
27516 +                                           struct dentry *parent)
27517 +{
27518 +       return vfsub_lookup_one_len(name->name, parent, name->len);
27519 +}
27520 +
27521 +void vfsub_call_lkup_one(void *args);
27522 +
27523 +/* ---------------------------------------------------------------------- */
27524 +
27525 +static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
27526 +{
27527 +       int err;
27528 +       lockdep_off();
27529 +       err = mnt_want_write(mnt);
27530 +       lockdep_on();
27531 +       return err;
27532 +}
27533 +
27534 +static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
27535 +{
27536 +       lockdep_off();
27537 +       mnt_drop_write(mnt);
27538 +       lockdep_on();
27539 +}
27540 +
27541 +static inline void vfsub_mnt_drop_write_file(struct file *file)
27542 +{
27543 +       lockdep_off();
27544 +       mnt_drop_write_file(file);
27545 +       lockdep_on();
27546 +}
27547 +
27548 +/* ---------------------------------------------------------------------- */
27549 +
27550 +struct au_hinode;
27551 +struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
27552 +                                struct dentry *d2, struct au_hinode *hdir2);
27553 +void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
27554 +                        struct dentry *d2, struct au_hinode *hdir2);
27555 +
27556 +int vfsub_create(struct inode *dir, struct path *path, int mode,
27557 +                bool want_excl);
27558 +int vfsub_symlink(struct inode *dir, struct path *path,
27559 +                 const char *symname);
27560 +int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
27561 +int vfsub_link(struct dentry *src_dentry, struct inode *dir,
27562 +              struct path *path);
27563 +int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
27564 +                struct inode *hdir, struct path *path);
27565 +int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
27566 +int vfsub_rmdir(struct inode *dir, struct path *path);
27567 +
27568 +/* ---------------------------------------------------------------------- */
27569 +
27570 +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
27571 +                    loff_t *ppos);
27572 +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
27573 +                       loff_t *ppos);
27574 +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
27575 +                     loff_t *ppos);
27576 +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
27577 +                     loff_t *ppos);
27578 +int vfsub_flush(struct file *file, fl_owner_t id);
27579 +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
27580 +
27581 +static inline loff_t vfsub_f_size_read(struct file *file)
27582 +{
27583 +       return i_size_read(file_inode(file));
27584 +}
27585 +
27586 +static inline unsigned int vfsub_file_flags(struct file *file)
27587 +{
27588 +       unsigned int flags;
27589 +
27590 +       spin_lock(&file->f_lock);
27591 +       flags = file->f_flags;
27592 +       spin_unlock(&file->f_lock);
27593 +
27594 +       return flags;
27595 +}
27596 +
27597 +static inline void vfsub_file_accessed(struct file *h_file)
27598 +{
27599 +       file_accessed(h_file);
27600 +       vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
27601 +}
27602 +
27603 +static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
27604 +                                    struct dentry *h_dentry)
27605 +{
27606 +       struct path h_path = {
27607 +               .dentry = h_dentry,
27608 +               .mnt    = h_mnt
27609 +       };
27610 +       touch_atime(&h_path);
27611 +       vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
27612 +}
27613 +
27614 +static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
27615 +                                   int flags)
27616 +{
27617 +       return update_time(h_inode, ts, flags);
27618 +       /* no vfsub_update_h_iattr() since we don't have struct path */
27619 +}
27620 +
27621 +long vfsub_splice_to(struct file *in, loff_t *ppos,
27622 +                    struct pipe_inode_info *pipe, size_t len,
27623 +                    unsigned int flags);
27624 +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
27625 +                      loff_t *ppos, size_t len, unsigned int flags);
27626 +
27627 +static inline long vfsub_truncate(struct path *path, loff_t length)
27628 +{
27629 +       long err;
27630 +       lockdep_off();
27631 +       err = vfs_truncate(path, length);
27632 +       lockdep_on();
27633 +       return err;
27634 +}
27635 +
27636 +int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
27637 +               struct file *h_file);
27638 +int vfsub_fsync(struct file *file, struct path *path, int datasync);
27639 +
27640 +/* ---------------------------------------------------------------------- */
27641 +
27642 +static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
27643 +{
27644 +       loff_t err;
27645 +
27646 +       lockdep_off();
27647 +       err = vfs_llseek(file, offset, origin);
27648 +       lockdep_on();
27649 +       return err;
27650 +}
27651 +
27652 +/* ---------------------------------------------------------------------- */
27653 +
27654 +/* dirty workaround for strict type of fmode_t */
27655 +union vfsub_fmu {
27656 +       fmode_t fm;
27657 +       unsigned int ui;
27658 +};
27659 +
27660 +static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
27661 +{
27662 +       union vfsub_fmu u = {
27663 +               .fm = fm
27664 +       };
27665 +
27666 +       BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
27667 +
27668 +       return u.ui;
27669 +}
27670 +
27671 +static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
27672 +{
27673 +       union vfsub_fmu u = {
27674 +               .ui = ui
27675 +       };
27676 +
27677 +       return u.fm;
27678 +}
27679 +
27680 +/* ---------------------------------------------------------------------- */
27681 +
27682 +int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
27683 +int vfsub_sio_rmdir(struct inode *dir, struct path *path);
27684 +int vfsub_sio_notify_change(struct path *path, struct iattr *ia);
27685 +int vfsub_notify_change(struct path *path, struct iattr *ia);
27686 +int vfsub_unlink(struct inode *dir, struct path *path, int force);
27687 +
27688 +#endif /* __KERNEL__ */
27689 +#endif /* __AUFS_VFSUB_H__ */
27690 diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
27691 --- /usr/share/empty/fs/aufs/wbr_policy.c       1970-01-01 01:00:00.000000000 +0100
27692 +++ linux/fs/aufs/wbr_policy.c  2013-07-06 13:20:47.753531903 +0200
27693 @@ -0,0 +1,701 @@
27694 +/*
27695 + * Copyright (C) 2005-2013 Junjiro R. Okajima
27696 + *
27697 + * This program, aufs is free software; you can redistribute it and/or modify
27698 + * it under the terms of the GNU General Public License as published by
27699 + * the Free Software Foundation; either version 2 of the License, or
27700 + * (at your option) any later version.
27701 + *
27702 + * This program is distributed in the hope that it will be useful,
27703 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27704 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27705 + * GNU General Public License for more details.
27706 + *
27707 + * You should have received a copy of the GNU General Public License
27708 + * along with this program; if not, write to the Free Software
27709 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27710 + */
27711 +
27712 +/*
27713 + * policies for selecting one among multiple writable branches
27714 + */
27715 +
27716 +#include <linux/statfs.h>
27717 +#include "aufs.h"
27718 +
27719 +/* subset of cpup_attr() */
27720 +static noinline_for_stack
27721 +int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
27722 +{
27723 +       int err, sbits;
27724 +       struct iattr ia;
27725 +       struct inode *h_isrc;
27726 +
27727 +       h_isrc = h_src->d_inode;
27728 +       ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
27729 +       ia.ia_mode = h_isrc->i_mode;
27730 +       ia.ia_uid = h_isrc->i_uid;
27731 +       ia.ia_gid = h_isrc->i_gid;
27732 +       sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
27733 +       au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
27734 +       err = vfsub_sio_notify_change(h_path, &ia);
27735 +
27736 +       /* is this nfs only? */
27737 +       if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
27738 +               ia.ia_valid = ATTR_FORCE | ATTR_MODE;
27739 +               ia.ia_mode = h_isrc->i_mode;
27740 +               err = vfsub_sio_notify_change(h_path, &ia);
27741 +       }
27742 +
27743 +       return err;
27744 +}
27745 +
27746 +#define AuCpdown_PARENT_OPQ    1
27747 +#define AuCpdown_WHED          (1 << 1)
27748 +#define AuCpdown_MADE_DIR      (1 << 2)
27749 +#define AuCpdown_DIROPQ                (1 << 3)
27750 +#define au_ftest_cpdown(flags, name)   ((flags) & AuCpdown_##name)
27751 +#define au_fset_cpdown(flags, name) \
27752 +       do { (flags) |= AuCpdown_##name; } while (0)
27753 +#define au_fclr_cpdown(flags, name) \
27754 +       do { (flags) &= ~AuCpdown_##name; } while (0)
27755 +
27756 +struct au_cpdown_dir_args {
27757 +       struct dentry *parent;
27758 +       unsigned int flags;
27759 +};
27760 +
27761 +static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
27762 +                            struct au_cpdown_dir_args *a)
27763 +{
27764 +       int err;
27765 +       struct dentry *opq_dentry;
27766 +
27767 +       opq_dentry = au_diropq_create(dentry, bdst);
27768 +       err = PTR_ERR(opq_dentry);
27769 +       if (IS_ERR(opq_dentry))
27770 +               goto out;
27771 +       dput(opq_dentry);
27772 +       au_fset_cpdown(a->flags, DIROPQ);
27773 +
27774 +out:
27775 +       return err;
27776 +}
27777 +
27778 +static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
27779 +                           struct inode *dir, aufs_bindex_t bdst)
27780 +{
27781 +       int err;
27782 +       struct path h_path;
27783 +       struct au_branch *br;
27784 +
27785 +       br = au_sbr(dentry->d_sb, bdst);
27786 +       h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
27787 +       err = PTR_ERR(h_path.dentry);
27788 +       if (IS_ERR(h_path.dentry))
27789 +               goto out;
27790 +
27791 +       err = 0;
27792 +       if (h_path.dentry->d_inode) {
27793 +               h_path.mnt = au_br_mnt(br);
27794 +               err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
27795 +                                         dentry);
27796 +       }
27797 +       dput(h_path.dentry);
27798 +
27799 +out:
27800 +       return err;
27801 +}
27802 +
27803 +static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
27804 +                        struct au_pin *pin,
27805 +                        struct dentry *h_parent, void *arg)
27806 +{
27807 +       int err, rerr;
27808 +       aufs_bindex_t bopq, bstart;
27809 +       struct path h_path;
27810 +       struct dentry *parent;
27811 +       struct inode *h_dir, *h_inode, *inode, *dir;
27812 +       struct au_cpdown_dir_args *args = arg;
27813 +
27814 +       bstart = au_dbstart(dentry);
27815 +       /* dentry is di-locked */
27816 +       parent = dget_parent(dentry);
27817 +       dir = parent->d_inode;
27818 +       h_dir = h_parent->d_inode;
27819 +       AuDebugOn(h_dir != au_h_iptr(dir, bdst));
27820 +       IMustLock(h_dir);
27821 +
27822 +       err = au_lkup_neg(dentry, bdst, /*wh*/0);
27823 +       if (unlikely(err < 0))
27824 +               goto out;
27825 +       h_path.dentry = au_h_dptr(dentry, bdst);
27826 +       h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
27827 +       err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
27828 +                             S_IRWXU | S_IRUGO | S_IXUGO);
27829 +       if (unlikely(err))
27830 +               goto out_put;
27831 +       au_fset_cpdown(args->flags, MADE_DIR);
27832 +
27833 +       bopq = au_dbdiropq(dentry);
27834 +       au_fclr_cpdown(args->flags, WHED);
27835 +       au_fclr_cpdown(args->flags, DIROPQ);
27836 +       if (au_dbwh(dentry) == bdst)
27837 +               au_fset_cpdown(args->flags, WHED);
27838 +       if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst)
27839 +               au_fset_cpdown(args->flags, PARENT_OPQ);
27840 +       h_inode = h_path.dentry->d_inode;
27841 +       mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
27842 +       if (au_ftest_cpdown(args->flags, WHED)) {
27843 +               err = au_cpdown_dir_opq(dentry, bdst, args);
27844 +               if (unlikely(err)) {
27845 +                       mutex_unlock(&h_inode->i_mutex);
27846 +                       goto out_dir;
27847 +               }
27848 +       }
27849 +
27850 +       err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
27851 +       mutex_unlock(&h_inode->i_mutex);
27852 +       if (unlikely(err))
27853 +               goto out_opq;
27854 +
27855 +       if (au_ftest_cpdown(args->flags, WHED)) {
27856 +               err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
27857 +               if (unlikely(err))
27858 +                       goto out_opq;
27859 +       }
27860 +
27861 +       inode = dentry->d_inode;
27862 +       if (au_ibend(inode) < bdst)
27863 +               au_set_ibend(inode, bdst);
27864 +       au_set_h_iptr(inode, bdst, au_igrab(h_inode),
27865 +                     au_hi_flags(inode, /*isdir*/1));
27866 +       goto out; /* success */
27867 +
27868 +       /* revert */
27869 +out_opq:
27870 +       if (au_ftest_cpdown(args->flags, DIROPQ)) {
27871 +               mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
27872 +               rerr = au_diropq_remove(dentry, bdst);
27873 +               mutex_unlock(&h_inode->i_mutex);
27874 +               if (unlikely(rerr)) {
27875 +                       AuIOErr("failed removing diropq for %.*s b%d (%d)\n",
27876 +                               AuDLNPair(dentry), bdst, rerr);
27877 +                       err = -EIO;
27878 +                       goto out;
27879 +               }
27880 +       }
27881 +out_dir:
27882 +       if (au_ftest_cpdown(args->flags, MADE_DIR)) {
27883 +               rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
27884 +               if (unlikely(rerr)) {
27885 +                       AuIOErr("failed removing %.*s b%d (%d)\n",
27886 +                               AuDLNPair(dentry), bdst, rerr);
27887 +                       err = -EIO;
27888 +               }
27889 +       }
27890 +out_put:
27891 +       au_set_h_dptr(dentry, bdst, NULL);
27892 +       if (au_dbend(dentry) == bdst)
27893 +               au_update_dbend(dentry);
27894 +out:
27895 +       dput(parent);
27896 +       return err;
27897 +}
27898 +
27899 +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
27900 +{
27901 +       int err;
27902 +       struct au_cpdown_dir_args args = {
27903 +               .parent = dget_parent(dentry),
27904 +               .flags  = 0
27905 +       };
27906 +
27907 +       err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args);
27908 +       dput(args.parent);
27909 +
27910 +       return err;
27911 +}
27912 +
27913 +/* ---------------------------------------------------------------------- */
27914 +
27915 +/* policies for create */
27916 +
27917 +static int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
27918 +{
27919 +       int err, i, j, ndentry;
27920 +       aufs_bindex_t bopq;
27921 +       struct au_dcsub_pages dpages;
27922 +       struct au_dpage *dpage;
27923 +       struct dentry **dentries, *parent, *d;
27924 +
27925 +       err = au_dpages_init(&dpages, GFP_NOFS);
27926 +       if (unlikely(err))
27927 +               goto out;
27928 +       parent = dget_parent(dentry);
27929 +       err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
27930 +       if (unlikely(err))
27931 +               goto out_free;
27932 +
27933 +       err = bindex;
27934 +       for (i = 0; i < dpages.ndpage; i++) {
27935 +               dpage = dpages.dpages + i;
27936 +               dentries = dpage->dentries;
27937 +               ndentry = dpage->ndentry;
27938 +               for (j = 0; j < ndentry; j++) {
27939 +                       d = dentries[j];
27940 +                       di_read_lock_parent2(d, !AuLock_IR);
27941 +                       bopq = au_dbdiropq(d);
27942 +                       di_read_unlock(d, !AuLock_IR);
27943 +                       if (bopq >= 0 && bopq < err)
27944 +                               err = bopq;
27945 +               }
27946 +       }
27947 +
27948 +out_free:
27949 +       dput(parent);
27950 +       au_dpages_free(&dpages);
27951 +out:
27952 +       return err;
27953 +}
27954 +
27955 +static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
27956 +{
27957 +       for (; bindex >= 0; bindex--)
27958 +               if (!au_br_rdonly(au_sbr(sb, bindex)))
27959 +                       return bindex;
27960 +       return -EROFS;
27961 +}
27962 +
27963 +/* top down parent */
27964 +static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused)
27965 +{
27966 +       int err;
27967 +       aufs_bindex_t bstart, bindex;
27968 +       struct super_block *sb;
27969 +       struct dentry *parent, *h_parent;
27970 +
27971 +       sb = dentry->d_sb;
27972 +       bstart = au_dbstart(dentry);
27973 +       err = bstart;
27974 +       if (!au_br_rdonly(au_sbr(sb, bstart)))
27975 +               goto out;
27976 +
27977 +       err = -EROFS;
27978 +       parent = dget_parent(dentry);
27979 +       for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
27980 +               h_parent = au_h_dptr(parent, bindex);
27981 +               if (!h_parent || !h_parent->d_inode)
27982 +                       continue;
27983 +
27984 +               if (!au_br_rdonly(au_sbr(sb, bindex))) {
27985 +                       err = bindex;
27986 +                       break;
27987 +               }
27988 +       }
27989 +       dput(parent);
27990 +
27991 +       /* bottom up here */
27992 +       if (unlikely(err < 0)) {
27993 +               err = au_wbr_bu(sb, bstart - 1);
27994 +               if (err >= 0)
27995 +                       err = au_wbr_nonopq(dentry, err);
27996 +       }
27997 +
27998 +out:
27999 +       AuDbg("b%d\n", err);
28000 +       return err;
28001 +}
28002 +
28003 +/* ---------------------------------------------------------------------- */
28004 +
28005 +/* an exception for the policy other than tdp */
28006 +static int au_wbr_create_exp(struct dentry *dentry)
28007 +{
28008 +       int err;
28009 +       aufs_bindex_t bwh, bdiropq;
28010 +       struct dentry *parent;
28011 +
28012 +       err = -1;
28013 +       bwh = au_dbwh(dentry);
28014 +       parent = dget_parent(dentry);
28015 +       bdiropq = au_dbdiropq(parent);
28016 +       if (bwh >= 0) {
28017 +               if (bdiropq >= 0)
28018 +                       err = min(bdiropq, bwh);
28019 +               else
28020 +                       err = bwh;
28021 +               AuDbg("%d\n", err);
28022 +       } else if (bdiropq >= 0) {
28023 +               err = bdiropq;
28024 +               AuDbg("%d\n", err);
28025 +       }
28026 +       dput(parent);
28027 +
28028 +       if (err >= 0)
28029 +               err = au_wbr_nonopq(dentry, err);
28030 +
28031 +       if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
28032 +               err = -1;
28033 +
28034 +       AuDbg("%d\n", err);
28035 +       return err;
28036 +}
28037 +
28038 +/* ---------------------------------------------------------------------- */
28039 +
28040 +/* round robin */
28041 +static int au_wbr_create_init_rr(struct super_block *sb)
28042 +{
28043 +       int err;
28044 +
28045 +       err = au_wbr_bu(sb, au_sbend(sb));
28046 +       atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
28047 +       /* smp_mb(); */
28048 +
28049 +       AuDbg("b%d\n", err);
28050 +       return err;
28051 +}
28052 +
28053 +static int au_wbr_create_rr(struct dentry *dentry, int isdir)
28054 +{
28055 +       int err, nbr;
28056 +       unsigned int u;
28057 +       aufs_bindex_t bindex, bend;
28058 +       struct super_block *sb;
28059 +       atomic_t *next;
28060 +
28061 +       err = au_wbr_create_exp(dentry);
28062 +       if (err >= 0)
28063 +               goto out;
28064 +
28065 +       sb = dentry->d_sb;
28066 +       next = &au_sbi(sb)->si_wbr_rr_next;
28067 +       bend = au_sbend(sb);
28068 +       nbr = bend + 1;
28069 +       for (bindex = 0; bindex <= bend; bindex++) {
28070 +               if (!isdir) {
28071 +                       err = atomic_dec_return(next) + 1;
28072 +                       /* modulo for 0 is meaningless */
28073 +                       if (unlikely(!err))
28074 +                               err = atomic_dec_return(next) + 1;
28075 +               } else
28076 +                       err = atomic_read(next);
28077 +               AuDbg("%d\n", err);
28078 +               u = err;
28079 +               err = u % nbr;
28080 +               AuDbg("%d\n", err);
28081 +               if (!au_br_rdonly(au_sbr(sb, err)))
28082 +                       break;
28083 +               err = -EROFS;
28084 +       }
28085 +
28086 +       if (err >= 0)
28087 +               err = au_wbr_nonopq(dentry, err);
28088 +
28089 +out:
28090 +       AuDbg("%d\n", err);
28091 +       return err;
28092 +}
28093 +
28094 +/* ---------------------------------------------------------------------- */
28095 +
28096 +/* most free space */
28097 +static void au_mfs(struct dentry *dentry)
28098 +{
28099 +       struct super_block *sb;
28100 +       struct au_branch *br;
28101 +       struct au_wbr_mfs *mfs;
28102 +       aufs_bindex_t bindex, bend;
28103 +       int err;
28104 +       unsigned long long b, bavail;
28105 +       struct path h_path;
28106 +       /* reduce the stack usage */
28107 +       struct kstatfs *st;
28108 +
28109 +       st = kmalloc(sizeof(*st), GFP_NOFS);
28110 +       if (unlikely(!st)) {
28111 +               AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
28112 +               return;
28113 +       }
28114 +
28115 +       bavail = 0;
28116 +       sb = dentry->d_sb;
28117 +       mfs = &au_sbi(sb)->si_wbr_mfs;
28118 +       MtxMustLock(&mfs->mfs_lock);
28119 +       mfs->mfs_bindex = -EROFS;
28120 +       mfs->mfsrr_bytes = 0;
28121 +       bend = au_sbend(sb);
28122 +       for (bindex = 0; bindex <= bend; bindex++) {
28123 +               br = au_sbr(sb, bindex);
28124 +               if (au_br_rdonly(br))
28125 +                       continue;
28126 +
28127 +               /* sb->s_root for NFS is unreliable */
28128 +               h_path.mnt = au_br_mnt(br);
28129 +               h_path.dentry = h_path.mnt->mnt_root;
28130 +               err = vfs_statfs(&h_path, st);
28131 +               if (unlikely(err)) {
28132 +                       AuWarn1("failed statfs, b%d, %d\n", bindex, err);
28133 +                       continue;
28134 +               }
28135 +
28136 +               /* when the available size is equal, select the lower one */
28137 +               BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
28138 +                            || sizeof(b) < sizeof(st->f_bsize));
28139 +               b = st->f_bavail * st->f_bsize;
28140 +               br->br_wbr->wbr_bytes = b;
28141 +               if (b >= bavail) {
28142 +                       bavail = b;
28143 +                       mfs->mfs_bindex = bindex;
28144 +                       mfs->mfs_jiffy = jiffies;
28145 +               }
28146 +       }
28147 +
28148 +       mfs->mfsrr_bytes = bavail;
28149 +       AuDbg("b%d\n", mfs->mfs_bindex);
28150 +       kfree(st);
28151 +}
28152 +
28153 +static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused)
28154 +{
28155 +       int err;
28156 +       struct super_block *sb;
28157 +       struct au_wbr_mfs *mfs;
28158 +
28159 +       err = au_wbr_create_exp(dentry);
28160 +       if (err >= 0)
28161 +               goto out;
28162 +
28163 +       sb = dentry->d_sb;
28164 +       mfs = &au_sbi(sb)->si_wbr_mfs;
28165 +       mutex_lock(&mfs->mfs_lock);
28166 +       if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
28167 +           || mfs->mfs_bindex < 0
28168 +           || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
28169 +               au_mfs(dentry);
28170 +       mutex_unlock(&mfs->mfs_lock);
28171 +       err = mfs->mfs_bindex;
28172 +
28173 +       if (err >= 0)
28174 +               err = au_wbr_nonopq(dentry, err);
28175 +
28176 +out:
28177 +       AuDbg("b%d\n", err);
28178 +       return err;
28179 +}
28180 +
28181 +static int au_wbr_create_init_mfs(struct super_block *sb)
28182 +{
28183 +       struct au_wbr_mfs *mfs;
28184 +
28185 +       mfs = &au_sbi(sb)->si_wbr_mfs;
28186 +       mutex_init(&mfs->mfs_lock);
28187 +       mfs->mfs_jiffy = 0;
28188 +       mfs->mfs_bindex = -EROFS;
28189 +
28190 +       return 0;
28191 +}
28192 +
28193 +static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
28194 +{
28195 +       mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
28196 +       return 0;
28197 +}
28198 +
28199 +/* ---------------------------------------------------------------------- */
28200 +
28201 +/* most free space and then round robin */
28202 +static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir)
28203 +{
28204 +       int err;
28205 +       struct au_wbr_mfs *mfs;
28206 +
28207 +       err = au_wbr_create_mfs(dentry, isdir);
28208 +       if (err >= 0) {
28209 +               mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
28210 +               mutex_lock(&mfs->mfs_lock);
28211 +               if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
28212 +                       err = au_wbr_create_rr(dentry, isdir);
28213 +               mutex_unlock(&mfs->mfs_lock);
28214 +       }
28215 +
28216 +       AuDbg("b%d\n", err);
28217 +       return err;
28218 +}
28219 +
28220 +static int au_wbr_create_init_mfsrr(struct super_block *sb)
28221 +{
28222 +       int err;
28223 +
28224 +       au_wbr_create_init_mfs(sb); /* ignore */
28225 +       err = au_wbr_create_init_rr(sb);
28226 +
28227 +       return err;
28228 +}
28229 +
28230 +/* ---------------------------------------------------------------------- */
28231 +
28232 +/* top down parent and most free space */
28233 +static int au_wbr_create_pmfs(struct dentry *dentry, int isdir)
28234 +{
28235 +       int err, e2;
28236 +       unsigned long long b;
28237 +       aufs_bindex_t bindex, bstart, bend;
28238 +       struct super_block *sb;
28239 +       struct dentry *parent, *h_parent;
28240 +       struct au_branch *br;
28241 +
28242 +       err = au_wbr_create_tdp(dentry, isdir);
28243 +       if (unlikely(err < 0))
28244 +               goto out;
28245 +       parent = dget_parent(dentry);
28246 +       bstart = au_dbstart(parent);
28247 +       bend = au_dbtaildir(parent);
28248 +       if (bstart == bend)
28249 +               goto out_parent; /* success */
28250 +
28251 +       e2 = au_wbr_create_mfs(dentry, isdir);
28252 +       if (e2 < 0)
28253 +               goto out_parent; /* success */
28254 +
28255 +       /* when the available size is equal, select upper one */
28256 +       sb = dentry->d_sb;
28257 +       br = au_sbr(sb, err);
28258 +       b = br->br_wbr->wbr_bytes;
28259 +       AuDbg("b%d, %llu\n", err, b);
28260 +
28261 +       for (bindex = bstart; bindex <= bend; bindex++) {
28262 +               h_parent = au_h_dptr(parent, bindex);
28263 +               if (!h_parent || !h_parent->d_inode)
28264 +                       continue;
28265 +
28266 +               br = au_sbr(sb, bindex);
28267 +               if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
28268 +                       b = br->br_wbr->wbr_bytes;
28269 +                       err = bindex;
28270 +                       AuDbg("b%d, %llu\n", err, b);
28271 +               }
28272 +       }
28273 +
28274 +       if (err >= 0)
28275 +               err = au_wbr_nonopq(dentry, err);
28276 +
28277 +out_parent:
28278 +       dput(parent);
28279 +out:
28280 +       AuDbg("b%d\n", err);
28281 +       return err;
28282 +}
28283 +
28284 +/* ---------------------------------------------------------------------- */
28285 +
28286 +/* policies for copyup */
28287 +
28288 +/* top down parent */
28289 +static int au_wbr_copyup_tdp(struct dentry *dentry)
28290 +{
28291 +       return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0);
28292 +}
28293 +
28294 +/* bottom up parent */
28295 +static int au_wbr_copyup_bup(struct dentry *dentry)
28296 +{
28297 +       int err;
28298 +       aufs_bindex_t bindex, bstart;
28299 +       struct dentry *parent, *h_parent;
28300 +       struct super_block *sb;
28301 +
28302 +       err = -EROFS;
28303 +       sb = dentry->d_sb;
28304 +       parent = dget_parent(dentry);
28305 +       bstart = au_dbstart(parent);
28306 +       for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
28307 +               h_parent = au_h_dptr(parent, bindex);
28308 +               if (!h_parent || !h_parent->d_inode)
28309 +                       continue;
28310 +
28311 +               if (!au_br_rdonly(au_sbr(sb, bindex))) {
28312 +                       err = bindex;
28313 +                       break;
28314 +               }
28315 +       }
28316 +       dput(parent);
28317 +
28318 +       /* bottom up here */
28319 +       if (unlikely(err < 0))
28320 +               err = au_wbr_bu(sb, bstart - 1);
28321 +
28322 +       AuDbg("b%d\n", err);
28323 +       return err;
28324 +}
28325 +
28326 +/* bottom up */
28327 +static int au_wbr_copyup_bu(struct dentry *dentry)
28328 +{
28329 +       int err;
28330 +       aufs_bindex_t bstart;
28331 +
28332 +       bstart = au_dbstart(dentry);
28333 +       err = au_wbr_bu(dentry->d_sb, bstart);
28334 +       AuDbg("b%d\n", err);
28335 +       if (err > bstart)
28336 +               err = au_wbr_nonopq(dentry, err);
28337 +
28338 +       AuDbg("b%d\n", err);
28339 +       return err;
28340 +}
28341 +
28342 +/* ---------------------------------------------------------------------- */
28343 +
28344 +struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
28345 +       [AuWbrCopyup_TDP] = {
28346 +               .copyup = au_wbr_copyup_tdp
28347 +       },
28348 +       [AuWbrCopyup_BUP] = {
28349 +               .copyup = au_wbr_copyup_bup
28350 +       },
28351 +       [AuWbrCopyup_BU] = {
28352 +               .copyup = au_wbr_copyup_bu
28353 +       }
28354 +};
28355 +
28356 +struct au_wbr_create_operations au_wbr_create_ops[] = {
28357 +       [AuWbrCreate_TDP] = {
28358 +               .create = au_wbr_create_tdp
28359 +       },
28360 +       [AuWbrCreate_RR] = {
28361 +               .create = au_wbr_create_rr,
28362 +               .init   = au_wbr_create_init_rr
28363 +       },
28364 +       [AuWbrCreate_MFS] = {
28365 +               .create = au_wbr_create_mfs,
28366 +               .init   = au_wbr_create_init_mfs,
28367 +               .fin    = au_wbr_create_fin_mfs
28368 +       },
28369 +       [AuWbrCreate_MFSV] = {
28370 +               .create = au_wbr_create_mfs,
28371 +               .init   = au_wbr_create_init_mfs,
28372 +               .fin    = au_wbr_create_fin_mfs
28373 +       },
28374 +       [AuWbrCreate_MFSRR] = {
28375 +               .create = au_wbr_create_mfsrr,
28376 +               .init   = au_wbr_create_init_mfsrr,
28377 +               .fin    = au_wbr_create_fin_mfs
28378 +       },
28379 +       [AuWbrCreate_MFSRRV] = {
28380 +               .create = au_wbr_create_mfsrr,
28381 +               .init   = au_wbr_create_init_mfsrr,
28382 +               .fin    = au_wbr_create_fin_mfs
28383 +       },
28384 +       [AuWbrCreate_PMFS] = {
28385 +               .create = au_wbr_create_pmfs,
28386 +               .init   = au_wbr_create_init_mfs,
28387 +               .fin    = au_wbr_create_fin_mfs
28388 +       },
28389 +       [AuWbrCreate_PMFSV] = {
28390 +               .create = au_wbr_create_pmfs,
28391 +               .init   = au_wbr_create_init_mfs,
28392 +               .fin    = au_wbr_create_fin_mfs
28393 +       }
28394 +};
28395 diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
28396 --- /usr/share/empty/fs/aufs/whout.c    1970-01-01 01:00:00.000000000 +0100
28397 +++ linux/fs/aufs/whout.c       2013-07-06 13:20:47.760198800 +0200
28398 @@ -0,0 +1,1022 @@
28399 +/*
28400 + * Copyright (C) 2005-2013 Junjiro R. Okajima
28401 + *
28402 + * This program, aufs is free software; you can redistribute it and/or modify
28403 + * it under the terms of the GNU General Public License as published by
28404 + * the Free Software Foundation; either version 2 of the License, or
28405 + * (at your option) any later version.
28406 + *
28407 + * This program is distributed in the hope that it will be useful,
28408 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28409 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28410 + * GNU General Public License for more details.
28411 + *
28412 + * You should have received a copy of the GNU General Public License
28413 + * along with this program; if not, write to the Free Software
28414 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28415 + */
28416 +
28417 +/*
28418 + * whiteout for logical deletion and opaque directory
28419 + */
28420 +
28421 +#include "aufs.h"
28422 +
28423 +#define WH_MASK                        S_IRUGO
28424 +
28425 +/*
28426 + * If a directory contains this file, then it is opaque.  We start with the
28427 + * .wh. flag so that it is blocked by lookup.
28428 + */
28429 +static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
28430 +                                          sizeof(AUFS_WH_DIROPQ) - 1);
28431 +
28432 +/*
28433 + * generate whiteout name, which is NOT terminated by NULL.
28434 + * @name: original d_name.name
28435 + * @len: original d_name.len
28436 + * @wh: whiteout qstr
28437 + * returns zero when succeeds, otherwise error.
28438 + * succeeded value as wh->name should be freed by kfree().
28439 + */
28440 +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
28441 +{
28442 +       char *p;
28443 +
28444 +       if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
28445 +               return -ENAMETOOLONG;
28446 +
28447 +       wh->len = name->len + AUFS_WH_PFX_LEN;
28448 +       p = kmalloc(wh->len, GFP_NOFS);
28449 +       wh->name = p;
28450 +       if (p) {
28451 +               memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
28452 +               memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
28453 +               /* smp_mb(); */
28454 +               return 0;
28455 +       }
28456 +       return -ENOMEM;
28457 +}
28458 +
28459 +/* ---------------------------------------------------------------------- */
28460 +
28461 +/*
28462 + * test if the @wh_name exists under @h_parent.
28463 + * @try_sio specifies the necessary of super-io.
28464 + */
28465 +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
28466 +              struct au_branch *br, int try_sio)
28467 +{
28468 +       int err;
28469 +       struct dentry *wh_dentry;
28470 +
28471 +       if (!try_sio)
28472 +               wh_dentry = vfsub_lkup_one(wh_name, h_parent);
28473 +       else
28474 +               wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
28475 +       err = PTR_ERR(wh_dentry);
28476 +       if (IS_ERR(wh_dentry))
28477 +               goto out;
28478 +
28479 +       err = 0;
28480 +       if (!wh_dentry->d_inode)
28481 +               goto out_wh; /* success */
28482 +
28483 +       err = 1;
28484 +       if (S_ISREG(wh_dentry->d_inode->i_mode))
28485 +               goto out_wh; /* success */
28486 +
28487 +       err = -EIO;
28488 +       AuIOErr("%.*s Invalid whiteout entry type 0%o.\n",
28489 +               AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode);
28490 +
28491 +out_wh:
28492 +       dput(wh_dentry);
28493 +out:
28494 +       return err;
28495 +}
28496 +
28497 +/*
28498 + * test if the @h_dentry sets opaque or not.
28499 + */
28500 +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
28501 +{
28502 +       int err;
28503 +       struct inode *h_dir;
28504 +
28505 +       h_dir = h_dentry->d_inode;
28506 +       err = au_wh_test(h_dentry, &diropq_name, br,
28507 +                        au_test_h_perm_sio(h_dir, MAY_EXEC));
28508 +       return err;
28509 +}
28510 +
28511 +/*
28512 + * returns a negative dentry whose name is unique and temporary.
28513 + */
28514 +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
28515 +                            struct qstr *prefix)
28516 +{
28517 +       struct dentry *dentry;
28518 +       int i;
28519 +       char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
28520 +               *name, *p;
28521 +       /* strict atomic_t is unnecessary here */
28522 +       static unsigned short cnt;
28523 +       struct qstr qs;
28524 +
28525 +       BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
28526 +
28527 +       name = defname;
28528 +       qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
28529 +       if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
28530 +               dentry = ERR_PTR(-ENAMETOOLONG);
28531 +               if (unlikely(qs.len > NAME_MAX))
28532 +                       goto out;
28533 +               dentry = ERR_PTR(-ENOMEM);
28534 +               name = kmalloc(qs.len + 1, GFP_NOFS);
28535 +               if (unlikely(!name))
28536 +                       goto out;
28537 +       }
28538 +
28539 +       /* doubly whiteout-ed */
28540 +       memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
28541 +       p = name + AUFS_WH_PFX_LEN * 2;
28542 +       memcpy(p, prefix->name, prefix->len);
28543 +       p += prefix->len;
28544 +       *p++ = '.';
28545 +       AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
28546 +
28547 +       qs.name = name;
28548 +       for (i = 0; i < 3; i++) {
28549 +               sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
28550 +               dentry = au_sio_lkup_one(&qs, h_parent, br);
28551 +               if (IS_ERR(dentry) || !dentry->d_inode)
28552 +                       goto out_name;
28553 +               dput(dentry);
28554 +       }
28555 +       /* pr_warn("could not get random name\n"); */
28556 +       dentry = ERR_PTR(-EEXIST);
28557 +       AuDbg("%.*s\n", AuLNPair(&qs));
28558 +       BUG();
28559 +
28560 +out_name:
28561 +       if (name != defname)
28562 +               kfree(name);
28563 +out:
28564 +       AuTraceErrPtr(dentry);
28565 +       return dentry;
28566 +}
28567 +
28568 +/*
28569 + * rename the @h_dentry on @br to the whiteouted temporary name.
28570 + */
28571 +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
28572 +{
28573 +       int err;
28574 +       struct path h_path = {
28575 +               .mnt = au_br_mnt(br)
28576 +       };
28577 +       struct inode *h_dir;
28578 +       struct dentry *h_parent;
28579 +
28580 +       h_parent = h_dentry->d_parent; /* dir inode is locked */
28581 +       h_dir = h_parent->d_inode;
28582 +       IMustLock(h_dir);
28583 +
28584 +       h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
28585 +       err = PTR_ERR(h_path.dentry);
28586 +       if (IS_ERR(h_path.dentry))
28587 +               goto out;
28588 +
28589 +       /* under the same dir, no need to lock_rename() */
28590 +       err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path);
28591 +       AuTraceErr(err);
28592 +       dput(h_path.dentry);
28593 +
28594 +out:
28595 +       AuTraceErr(err);
28596 +       return err;
28597 +}
28598 +
28599 +/* ---------------------------------------------------------------------- */
28600 +/*
28601 + * functions for removing a whiteout
28602 + */
28603 +
28604 +static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
28605 +{
28606 +       int force;
28607 +
28608 +       /*
28609 +        * forces superio when the dir has a sticky bit.
28610 +        * this may be a violation of unix fs semantics.
28611 +        */
28612 +       force = (h_dir->i_mode & S_ISVTX)
28613 +               && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
28614 +       return vfsub_unlink(h_dir, h_path, force);
28615 +}
28616 +
28617 +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
28618 +                       struct dentry *dentry)
28619 +{
28620 +       int err;
28621 +
28622 +       err = do_unlink_wh(h_dir, h_path);
28623 +       if (!err && dentry)
28624 +               au_set_dbwh(dentry, -1);
28625 +
28626 +       return err;
28627 +}
28628 +
28629 +static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
28630 +                         struct au_branch *br)
28631 +{
28632 +       int err;
28633 +       struct path h_path = {
28634 +               .mnt = au_br_mnt(br)
28635 +       };
28636 +
28637 +       err = 0;
28638 +       h_path.dentry = vfsub_lkup_one(wh, h_parent);
28639 +       if (IS_ERR(h_path.dentry))
28640 +               err = PTR_ERR(h_path.dentry);
28641 +       else {
28642 +               if (h_path.dentry->d_inode
28643 +                   && S_ISREG(h_path.dentry->d_inode->i_mode))
28644 +                       err = do_unlink_wh(h_parent->d_inode, &h_path);
28645 +               dput(h_path.dentry);
28646 +       }
28647 +
28648 +       return err;
28649 +}
28650 +
28651 +/* ---------------------------------------------------------------------- */
28652 +/*
28653 + * initialize/clean whiteout for a branch
28654 + */
28655 +
28656 +static void au_wh_clean(struct inode *h_dir, struct path *whpath,
28657 +                       const int isdir)
28658 +{
28659 +       int err;
28660 +
28661 +       if (!whpath->dentry->d_inode)
28662 +               return;
28663 +
28664 +       if (isdir)
28665 +               err = vfsub_rmdir(h_dir, whpath);
28666 +       else
28667 +               err = vfsub_unlink(h_dir, whpath, /*force*/0);
28668 +       if (unlikely(err))
28669 +               pr_warn("failed removing %.*s (%d), ignored.\n",
28670 +                       AuDLNPair(whpath->dentry), err);
28671 +}
28672 +
28673 +static int test_linkable(struct dentry *h_root)
28674 +{
28675 +       struct inode *h_dir = h_root->d_inode;
28676 +
28677 +       if (h_dir->i_op->link)
28678 +               return 0;
28679 +
28680 +       pr_err("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n",
28681 +              AuDLNPair(h_root), au_sbtype(h_root->d_sb));
28682 +       return -ENOSYS;
28683 +}
28684 +
28685 +/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
28686 +static int au_whdir(struct inode *h_dir, struct path *path)
28687 +{
28688 +       int err;
28689 +
28690 +       err = -EEXIST;
28691 +       if (!path->dentry->d_inode) {
28692 +               int mode = S_IRWXU;
28693 +
28694 +               if (au_test_nfs(path->dentry->d_sb))
28695 +                       mode |= S_IXUGO;
28696 +               err = vfsub_mkdir(h_dir, path, mode);
28697 +       } else if (S_ISDIR(path->dentry->d_inode->i_mode))
28698 +               err = 0;
28699 +       else
28700 +               pr_err("unknown %.*s exists\n", AuDLNPair(path->dentry));
28701 +
28702 +       return err;
28703 +}
28704 +
28705 +struct au_wh_base {
28706 +       const struct qstr *name;
28707 +       struct dentry *dentry;
28708 +};
28709 +
28710 +static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
28711 +                         struct path *h_path)
28712 +{
28713 +       h_path->dentry = base[AuBrWh_BASE].dentry;
28714 +       au_wh_clean(h_dir, h_path, /*isdir*/0);
28715 +       h_path->dentry = base[AuBrWh_PLINK].dentry;
28716 +       au_wh_clean(h_dir, h_path, /*isdir*/1);
28717 +       h_path->dentry = base[AuBrWh_ORPH].dentry;
28718 +       au_wh_clean(h_dir, h_path, /*isdir*/1);
28719 +}
28720 +
28721 +/*
28722 + * returns tri-state,
28723 + * minus: error, caller should print the mesage
28724 + * zero: succuess
28725 + * plus: error, caller should NOT print the mesage
28726 + */
28727 +static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
28728 +                               int do_plink, struct au_wh_base base[],
28729 +                               struct path *h_path)
28730 +{
28731 +       int err;
28732 +       struct inode *h_dir;
28733 +
28734 +       h_dir = h_root->d_inode;
28735 +       h_path->dentry = base[AuBrWh_BASE].dentry;
28736 +       au_wh_clean(h_dir, h_path, /*isdir*/0);
28737 +       h_path->dentry = base[AuBrWh_PLINK].dentry;
28738 +       if (do_plink) {
28739 +               err = test_linkable(h_root);
28740 +               if (unlikely(err)) {
28741 +                       err = 1;
28742 +                       goto out;
28743 +               }
28744 +
28745 +               err = au_whdir(h_dir, h_path);
28746 +               if (unlikely(err))
28747 +                       goto out;
28748 +               wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
28749 +       } else
28750 +               au_wh_clean(h_dir, h_path, /*isdir*/1);
28751 +       h_path->dentry = base[AuBrWh_ORPH].dentry;
28752 +       err = au_whdir(h_dir, h_path);
28753 +       if (unlikely(err))
28754 +               goto out;
28755 +       wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
28756 +
28757 +out:
28758 +       return err;
28759 +}
28760 +
28761 +/*
28762 + * for the moment, aufs supports the branch filesystem which does not support
28763 + * link(2). testing on FAT which does not support i_op->setattr() fully either,
28764 + * copyup failed. finally, such filesystem will not be used as the writable
28765 + * branch.
28766 + *
28767 + * returns tri-state, see above.
28768 + */
28769 +static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
28770 +                        int do_plink, struct au_wh_base base[],
28771 +                        struct path *h_path)
28772 +{
28773 +       int err;
28774 +       struct inode *h_dir;
28775 +
28776 +       WbrWhMustWriteLock(wbr);
28777 +
28778 +       err = test_linkable(h_root);
28779 +       if (unlikely(err)) {
28780 +               err = 1;
28781 +               goto out;
28782 +       }
28783 +
28784 +       /*
28785 +        * todo: should this create be done in /sbin/mount.aufs helper?
28786 +        */
28787 +       err = -EEXIST;
28788 +       h_dir = h_root->d_inode;
28789 +       if (!base[AuBrWh_BASE].dentry->d_inode) {
28790 +               h_path->dentry = base[AuBrWh_BASE].dentry;
28791 +               err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
28792 +       } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
28793 +               err = 0;
28794 +       else
28795 +               pr_err("unknown %.*s/%.*s exists\n",
28796 +                      AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
28797 +       if (unlikely(err))
28798 +               goto out;
28799 +
28800 +       h_path->dentry = base[AuBrWh_PLINK].dentry;
28801 +       if (do_plink) {
28802 +               err = au_whdir(h_dir, h_path);
28803 +               if (unlikely(err))
28804 +                       goto out;
28805 +               wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
28806 +       } else
28807 +               au_wh_clean(h_dir, h_path, /*isdir*/1);
28808 +       wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
28809 +
28810 +       h_path->dentry = base[AuBrWh_ORPH].dentry;
28811 +       err = au_whdir(h_dir, h_path);
28812 +       if (unlikely(err))
28813 +               goto out;
28814 +       wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
28815 +
28816 +out:
28817 +       return err;
28818 +}
28819 +
28820 +/*
28821 + * initialize the whiteout base file/dir for @br.
28822 + */
28823 +int au_wh_init(struct au_branch *br, struct super_block *sb)
28824 +{
28825 +       int err, i;
28826 +       const unsigned char do_plink
28827 +               = !!au_opt_test(au_mntflags(sb), PLINK);
28828 +       struct inode *h_dir;
28829 +       struct path path = br->br_path;
28830 +       struct dentry *h_root = path.dentry;
28831 +       struct au_wbr *wbr = br->br_wbr;
28832 +       static const struct qstr base_name[] = {
28833 +               [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
28834 +                                         sizeof(AUFS_BASE_NAME) - 1),
28835 +               [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
28836 +                                          sizeof(AUFS_PLINKDIR_NAME) - 1),
28837 +               [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
28838 +                                         sizeof(AUFS_ORPHDIR_NAME) - 1)
28839 +       };
28840 +       struct au_wh_base base[] = {
28841 +               [AuBrWh_BASE] = {
28842 +                       .name   = base_name + AuBrWh_BASE,
28843 +                       .dentry = NULL
28844 +               },
28845 +               [AuBrWh_PLINK] = {
28846 +                       .name   = base_name + AuBrWh_PLINK,
28847 +                       .dentry = NULL
28848 +               },
28849 +               [AuBrWh_ORPH] = {
28850 +                       .name   = base_name + AuBrWh_ORPH,
28851 +                       .dentry = NULL
28852 +               }
28853 +       };
28854 +
28855 +       if (wbr)
28856 +               WbrWhMustWriteLock(wbr);
28857 +
28858 +       for (i = 0; i < AuBrWh_Last; i++) {
28859 +               /* doubly whiteouted */
28860 +               struct dentry *d;
28861 +
28862 +               d = au_wh_lkup(h_root, (void *)base[i].name, br);
28863 +               err = PTR_ERR(d);
28864 +               if (IS_ERR(d))
28865 +                       goto out;
28866 +
28867 +               base[i].dentry = d;
28868 +               AuDebugOn(wbr
28869 +                         && wbr->wbr_wh[i]
28870 +                         && wbr->wbr_wh[i] != base[i].dentry);
28871 +       }
28872 +
28873 +       if (wbr)
28874 +               for (i = 0; i < AuBrWh_Last; i++) {
28875 +                       dput(wbr->wbr_wh[i]);
28876 +                       wbr->wbr_wh[i] = NULL;
28877 +               }
28878 +
28879 +       err = 0;
28880 +       if (!au_br_writable(br->br_perm)) {
28881 +               h_dir = h_root->d_inode;
28882 +               au_wh_init_ro(h_dir, base, &path);
28883 +       } else if (!au_br_wh_linkable(br->br_perm)) {
28884 +               err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
28885 +               if (err > 0)
28886 +                       goto out;
28887 +               else if (err)
28888 +                       goto out_err;
28889 +       } else {
28890 +               err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
28891 +               if (err > 0)
28892 +                       goto out;
28893 +               else if (err)
28894 +                       goto out_err;
28895 +       }
28896 +       goto out; /* success */
28897 +
28898 +out_err:
28899 +       pr_err("an error(%d) on the writable branch %.*s(%s)\n",
28900 +              err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
28901 +out:
28902 +       for (i = 0; i < AuBrWh_Last; i++)
28903 +               dput(base[i].dentry);
28904 +       return err;
28905 +}
28906 +
28907 +/* ---------------------------------------------------------------------- */
28908 +/*
28909 + * whiteouts are all hard-linked usually.
28910 + * when its link count reaches a ceiling, we create a new whiteout base
28911 + * asynchronously.
28912 + */
28913 +
28914 +struct reinit_br_wh {
28915 +       struct super_block *sb;
28916 +       struct au_branch *br;
28917 +};
28918 +
28919 +static void reinit_br_wh(void *arg)
28920 +{
28921 +       int err;
28922 +       aufs_bindex_t bindex;
28923 +       struct path h_path;
28924 +       struct reinit_br_wh *a = arg;
28925 +       struct au_wbr *wbr;
28926 +       struct inode *dir;
28927 +       struct dentry *h_root;
28928 +       struct au_hinode *hdir;
28929 +
28930 +       err = 0;
28931 +       wbr = a->br->br_wbr;
28932 +       /* big aufs lock */
28933 +       si_noflush_write_lock(a->sb);
28934 +       if (!au_br_writable(a->br->br_perm))
28935 +               goto out;
28936 +       bindex = au_br_index(a->sb, a->br->br_id);
28937 +       if (unlikely(bindex < 0))
28938 +               goto out;
28939 +
28940 +       di_read_lock_parent(a->sb->s_root, AuLock_IR);
28941 +       dir = a->sb->s_root->d_inode;
28942 +       hdir = au_hi(dir, bindex);
28943 +       h_root = au_h_dptr(a->sb->s_root, bindex);
28944 +       AuDebugOn(h_root != au_br_dentry(a->br));
28945 +
28946 +       au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
28947 +       wbr_wh_write_lock(wbr);
28948 +       err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
28949 +                         h_root, a->br);
28950 +       if (!err) {
28951 +               h_path.dentry = wbr->wbr_whbase;
28952 +               h_path.mnt = au_br_mnt(a->br);
28953 +               err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0);
28954 +       } else {
28955 +               pr_warn("%.*s is moved, ignored\n",
28956 +                       AuDLNPair(wbr->wbr_whbase));
28957 +               err = 0;
28958 +       }
28959 +       dput(wbr->wbr_whbase);
28960 +       wbr->wbr_whbase = NULL;
28961 +       if (!err)
28962 +               err = au_wh_init(a->br, a->sb);
28963 +       wbr_wh_write_unlock(wbr);
28964 +       au_hn_imtx_unlock(hdir);
28965 +       di_read_unlock(a->sb->s_root, AuLock_IR);
28966 +
28967 +out:
28968 +       if (wbr)
28969 +               atomic_dec(&wbr->wbr_wh_running);
28970 +       atomic_dec(&a->br->br_count);
28971 +       si_write_unlock(a->sb);
28972 +       au_nwt_done(&au_sbi(a->sb)->si_nowait);
28973 +       kfree(arg);
28974 +       if (unlikely(err))
28975 +               AuIOErr("err %d\n", err);
28976 +}
28977 +
28978 +static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
28979 +{
28980 +       int do_dec, wkq_err;
28981 +       struct reinit_br_wh *arg;
28982 +
28983 +       do_dec = 1;
28984 +       if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
28985 +               goto out;
28986 +
28987 +       /* ignore ENOMEM */
28988 +       arg = kmalloc(sizeof(*arg), GFP_NOFS);
28989 +       if (arg) {
28990 +               /*
28991 +                * dec(wh_running), kfree(arg) and dec(br_count)
28992 +                * in reinit function
28993 +                */
28994 +               arg->sb = sb;
28995 +               arg->br = br;
28996 +               atomic_inc(&br->br_count);
28997 +               wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
28998 +               if (unlikely(wkq_err)) {
28999 +                       atomic_dec(&br->br_wbr->wbr_wh_running);
29000 +                       atomic_dec(&br->br_count);
29001 +                       kfree(arg);
29002 +               }
29003 +               do_dec = 0;
29004 +       }
29005 +
29006 +out:
29007 +       if (do_dec)
29008 +               atomic_dec(&br->br_wbr->wbr_wh_running);
29009 +}
29010 +
29011 +/* ---------------------------------------------------------------------- */
29012 +
29013 +/*
29014 + * create the whiteout @wh.
29015 + */
29016 +static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
29017 +                            struct dentry *wh)
29018 +{
29019 +       int err;
29020 +       struct path h_path = {
29021 +               .dentry = wh
29022 +       };
29023 +       struct au_branch *br;
29024 +       struct au_wbr *wbr;
29025 +       struct dentry *h_parent;
29026 +       struct inode *h_dir;
29027 +
29028 +       h_parent = wh->d_parent; /* dir inode is locked */
29029 +       h_dir = h_parent->d_inode;
29030 +       IMustLock(h_dir);
29031 +
29032 +       br = au_sbr(sb, bindex);
29033 +       h_path.mnt = au_br_mnt(br);
29034 +       wbr = br->br_wbr;
29035 +       wbr_wh_read_lock(wbr);
29036 +       if (wbr->wbr_whbase) {
29037 +               err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path);
29038 +               if (!err || err != -EMLINK)
29039 +                       goto out;
29040 +
29041 +               /* link count full. re-initialize br_whbase. */
29042 +               kick_reinit_br_wh(sb, br);
29043 +       }
29044 +
29045 +       /* return this error in this context */
29046 +       err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
29047 +
29048 +out:
29049 +       wbr_wh_read_unlock(wbr);
29050 +       return err;
29051 +}
29052 +
29053 +/* ---------------------------------------------------------------------- */
29054 +
29055 +/*
29056 + * create or remove the diropq.
29057 + */
29058 +static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
29059 +                               unsigned int flags)
29060 +{
29061 +       struct dentry *opq_dentry, *h_dentry;
29062 +       struct super_block *sb;
29063 +       struct au_branch *br;
29064 +       int err;
29065 +
29066 +       sb = dentry->d_sb;
29067 +       br = au_sbr(sb, bindex);
29068 +       h_dentry = au_h_dptr(dentry, bindex);
29069 +       opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
29070 +       if (IS_ERR(opq_dentry))
29071 +               goto out;
29072 +
29073 +       if (au_ftest_diropq(flags, CREATE)) {
29074 +               err = link_or_create_wh(sb, bindex, opq_dentry);
29075 +               if (!err) {
29076 +                       au_set_dbdiropq(dentry, bindex);
29077 +                       goto out; /* success */
29078 +               }
29079 +       } else {
29080 +               struct path tmp = {
29081 +                       .dentry = opq_dentry,
29082 +                       .mnt    = au_br_mnt(br)
29083 +               };
29084 +               err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
29085 +               if (!err)
29086 +                       au_set_dbdiropq(dentry, -1);
29087 +       }
29088 +       dput(opq_dentry);
29089 +       opq_dentry = ERR_PTR(err);
29090 +
29091 +out:
29092 +       return opq_dentry;
29093 +}
29094 +
29095 +struct do_diropq_args {
29096 +       struct dentry **errp;
29097 +       struct dentry *dentry;
29098 +       aufs_bindex_t bindex;
29099 +       unsigned int flags;
29100 +};
29101 +
29102 +static void call_do_diropq(void *args)
29103 +{
29104 +       struct do_diropq_args *a = args;
29105 +       *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
29106 +}
29107 +
29108 +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
29109 +                            unsigned int flags)
29110 +{
29111 +       struct dentry *diropq, *h_dentry;
29112 +
29113 +       h_dentry = au_h_dptr(dentry, bindex);
29114 +       if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
29115 +               diropq = do_diropq(dentry, bindex, flags);
29116 +       else {
29117 +               int wkq_err;
29118 +               struct do_diropq_args args = {
29119 +                       .errp           = &diropq,
29120 +                       .dentry         = dentry,
29121 +                       .bindex         = bindex,
29122 +                       .flags          = flags
29123 +               };
29124 +
29125 +               wkq_err = au_wkq_wait(call_do_diropq, &args);
29126 +               if (unlikely(wkq_err))
29127 +                       diropq = ERR_PTR(wkq_err);
29128 +       }
29129 +
29130 +       return diropq;
29131 +}
29132 +
29133 +/* ---------------------------------------------------------------------- */
29134 +
29135 +/*
29136 + * lookup whiteout dentry.
29137 + * @h_parent: lower parent dentry which must exist and be locked
29138 + * @base_name: name of dentry which will be whiteouted
29139 + * returns dentry for whiteout.
29140 + */
29141 +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
29142 +                         struct au_branch *br)
29143 +{
29144 +       int err;
29145 +       struct qstr wh_name;
29146 +       struct dentry *wh_dentry;
29147 +
29148 +       err = au_wh_name_alloc(&wh_name, base_name);
29149 +       wh_dentry = ERR_PTR(err);
29150 +       if (!err) {
29151 +               wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
29152 +               kfree(wh_name.name);
29153 +       }
29154 +       return wh_dentry;
29155 +}
29156 +
29157 +/*
29158 + * link/create a whiteout for @dentry on @bindex.
29159 + */
29160 +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
29161 +                           struct dentry *h_parent)
29162 +{
29163 +       struct dentry *wh_dentry;
29164 +       struct super_block *sb;
29165 +       int err;
29166 +
29167 +       sb = dentry->d_sb;
29168 +       wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
29169 +       if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
29170 +               err = link_or_create_wh(sb, bindex, wh_dentry);
29171 +               if (!err)
29172 +                       au_set_dbwh(dentry, bindex);
29173 +               else {
29174 +                       dput(wh_dentry);
29175 +                       wh_dentry = ERR_PTR(err);
29176 +               }
29177 +       }
29178 +
29179 +       return wh_dentry;
29180 +}
29181 +
29182 +/* ---------------------------------------------------------------------- */
29183 +
29184 +/* Delete all whiteouts in this directory on branch bindex. */
29185 +static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
29186 +                          aufs_bindex_t bindex, struct au_branch *br)
29187 +{
29188 +       int err;
29189 +       unsigned long ul, n;
29190 +       struct qstr wh_name;
29191 +       char *p;
29192 +       struct hlist_head *head;
29193 +       struct au_vdir_wh *pos;
29194 +       struct au_vdir_destr *str;
29195 +
29196 +       err = -ENOMEM;
29197 +       p = (void *)__get_free_page(GFP_NOFS);
29198 +       wh_name.name = p;
29199 +       if (unlikely(!wh_name.name))
29200 +               goto out;
29201 +
29202 +       err = 0;
29203 +       memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
29204 +       p += AUFS_WH_PFX_LEN;
29205 +       n = whlist->nh_num;
29206 +       head = whlist->nh_head;
29207 +       for (ul = 0; !err && ul < n; ul++, head++) {
29208 +               hlist_for_each_entry(pos, head, wh_hash) {
29209 +                       if (pos->wh_bindex != bindex)
29210 +                               continue;
29211 +
29212 +                       str = &pos->wh_str;
29213 +                       if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
29214 +                               memcpy(p, str->name, str->len);
29215 +                               wh_name.len = AUFS_WH_PFX_LEN + str->len;
29216 +                               err = unlink_wh_name(h_dentry, &wh_name, br);
29217 +                               if (!err)
29218 +                                       continue;
29219 +                               break;
29220 +                       }
29221 +                       AuIOErr("whiteout name too long %.*s\n",
29222 +                               str->len, str->name);
29223 +                       err = -EIO;
29224 +                       break;
29225 +               }
29226 +       }
29227 +       free_page((unsigned long)wh_name.name);
29228 +
29229 +out:
29230 +       return err;
29231 +}
29232 +
29233 +struct del_wh_children_args {
29234 +       int *errp;
29235 +       struct dentry *h_dentry;
29236 +       struct au_nhash *whlist;
29237 +       aufs_bindex_t bindex;
29238 +       struct au_branch *br;
29239 +};
29240 +
29241 +static void call_del_wh_children(void *args)
29242 +{
29243 +       struct del_wh_children_args *a = args;
29244 +       *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
29245 +}
29246 +
29247 +/* ---------------------------------------------------------------------- */
29248 +
29249 +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
29250 +{
29251 +       struct au_whtmp_rmdir *whtmp;
29252 +       int err;
29253 +       unsigned int rdhash;
29254 +
29255 +       SiMustAnyLock(sb);
29256 +
29257 +       whtmp = kmalloc(sizeof(*whtmp), gfp);
29258 +       if (unlikely(!whtmp)) {
29259 +               whtmp = ERR_PTR(-ENOMEM);
29260 +               goto out;
29261 +       }
29262 +
29263 +       whtmp->dir = NULL;
29264 +       whtmp->br = NULL;
29265 +       whtmp->wh_dentry = NULL;
29266 +       /* no estimation for dir size */
29267 +       rdhash = au_sbi(sb)->si_rdhash;
29268 +       if (!rdhash)
29269 +               rdhash = AUFS_RDHASH_DEF;
29270 +       err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
29271 +       if (unlikely(err)) {
29272 +               kfree(whtmp);
29273 +               whtmp = ERR_PTR(err);
29274 +       }
29275 +
29276 +out:
29277 +       return whtmp;
29278 +}
29279 +
29280 +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
29281 +{
29282 +       if (whtmp->br)
29283 +               atomic_dec(&whtmp->br->br_count);
29284 +       dput(whtmp->wh_dentry);
29285 +       iput(whtmp->dir);
29286 +       au_nhash_wh_free(&whtmp->whlist);
29287 +       kfree(whtmp);
29288 +}
29289 +
29290 +/*
29291 + * rmdir the whiteouted temporary named dir @h_dentry.
29292 + * @whlist: whiteouted children.
29293 + */
29294 +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
29295 +                  struct dentry *wh_dentry, struct au_nhash *whlist)
29296 +{
29297 +       int err;
29298 +       struct path h_tmp;
29299 +       struct inode *wh_inode, *h_dir;
29300 +       struct au_branch *br;
29301 +
29302 +       h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
29303 +       IMustLock(h_dir);
29304 +
29305 +       br = au_sbr(dir->i_sb, bindex);
29306 +       wh_inode = wh_dentry->d_inode;
29307 +       mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
29308 +
29309 +       /*
29310 +        * someone else might change some whiteouts while we were sleeping.
29311 +        * it means this whlist may have an obsoleted entry.
29312 +        */
29313 +       if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
29314 +               err = del_wh_children(wh_dentry, whlist, bindex, br);
29315 +       else {
29316 +               int wkq_err;
29317 +               struct del_wh_children_args args = {
29318 +                       .errp           = &err,
29319 +                       .h_dentry       = wh_dentry,
29320 +                       .whlist         = whlist,
29321 +                       .bindex         = bindex,
29322 +                       .br             = br
29323 +               };
29324 +
29325 +               wkq_err = au_wkq_wait(call_del_wh_children, &args);
29326 +               if (unlikely(wkq_err))
29327 +                       err = wkq_err;
29328 +       }
29329 +       mutex_unlock(&wh_inode->i_mutex);
29330 +
29331 +       if (!err) {
29332 +               h_tmp.dentry = wh_dentry;
29333 +               h_tmp.mnt = au_br_mnt(br);
29334 +               err = vfsub_rmdir(h_dir, &h_tmp);
29335 +       }
29336 +
29337 +       if (!err) {
29338 +               if (au_ibstart(dir) == bindex) {
29339 +                       /* todo: dir->i_mutex is necessary */
29340 +                       au_cpup_attr_timesizes(dir);
29341 +                       vfsub_drop_nlink(dir);
29342 +               }
29343 +               return 0; /* success */
29344 +       }
29345 +
29346 +       pr_warn("failed removing %.*s(%d), ignored\n",
29347 +               AuDLNPair(wh_dentry), err);
29348 +       return err;
29349 +}
29350 +
29351 +static void call_rmdir_whtmp(void *args)
29352 +{
29353 +       int err;
29354 +       aufs_bindex_t bindex;
29355 +       struct au_whtmp_rmdir *a = args;
29356 +       struct super_block *sb;
29357 +       struct dentry *h_parent;
29358 +       struct inode *h_dir;
29359 +       struct au_hinode *hdir;
29360 +
29361 +       /* rmdir by nfsd may cause deadlock with this i_mutex */
29362 +       /* mutex_lock(&a->dir->i_mutex); */
29363 +       err = -EROFS;
29364 +       sb = a->dir->i_sb;
29365 +       si_read_lock(sb, !AuLock_FLUSH);
29366 +       if (!au_br_writable(a->br->br_perm))
29367 +               goto out;
29368 +       bindex = au_br_index(sb, a->br->br_id);
29369 +       if (unlikely(bindex < 0))
29370 +               goto out;
29371 +
29372 +       err = -EIO;
29373 +       ii_write_lock_parent(a->dir);
29374 +       h_parent = dget_parent(a->wh_dentry);
29375 +       h_dir = h_parent->d_inode;
29376 +       hdir = au_hi(a->dir, bindex);
29377 +       err = vfsub_mnt_want_write(au_br_mnt(a->br));
29378 +       if (unlikely(err))
29379 +               goto out_mnt;
29380 +       au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
29381 +       err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
29382 +                         a->br);
29383 +       if (!err)
29384 +               err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
29385 +       au_hn_imtx_unlock(hdir);
29386 +       vfsub_mnt_drop_write(au_br_mnt(a->br));
29387 +
29388 +out_mnt:
29389 +       dput(h_parent);
29390 +       ii_write_unlock(a->dir);
29391 +out:
29392 +       /* mutex_unlock(&a->dir->i_mutex); */
29393 +       au_whtmp_rmdir_free(a);
29394 +       si_read_unlock(sb);
29395 +       au_nwt_done(&au_sbi(sb)->si_nowait);
29396 +       if (unlikely(err))
29397 +               AuIOErr("err %d\n", err);
29398 +}
29399 +
29400 +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
29401 +                        struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
29402 +{
29403 +       int wkq_err;
29404 +       struct super_block *sb;
29405 +
29406 +       IMustLock(dir);
29407 +
29408 +       /* all post-process will be done in do_rmdir_whtmp(). */
29409 +       sb = dir->i_sb;
29410 +       args->dir = au_igrab(dir);
29411 +       args->br = au_sbr(sb, bindex);
29412 +       atomic_inc(&args->br->br_count);
29413 +       args->wh_dentry = dget(wh_dentry);
29414 +       wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
29415 +       if (unlikely(wkq_err)) {
29416 +               pr_warn("rmdir error %.*s (%d), ignored\n",
29417 +                       AuDLNPair(wh_dentry), wkq_err);
29418 +               au_whtmp_rmdir_free(args);
29419 +       }
29420 +}
29421 diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
29422 --- /usr/share/empty/fs/aufs/whout.h    1970-01-01 01:00:00.000000000 +0100
29423 +++ linux/fs/aufs/whout.h       2013-07-06 13:20:47.760198800 +0200
29424 @@ -0,0 +1,87 @@
29425 +/*
29426 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29427 + *
29428 + * This program, aufs is free software; you can redistribute it and/or modify
29429 + * it under the terms of the GNU General Public License as published by
29430 + * the Free Software Foundation; either version 2 of the License, or
29431 + * (at your option) any later version.
29432 + *
29433 + * This program is distributed in the hope that it will be useful,
29434 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29435 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29436 + * GNU General Public License for more details.
29437 + *
29438 + * You should have received a copy of the GNU General Public License
29439 + * along with this program; if not, write to the Free Software
29440 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
29441 + */
29442 +
29443 +/*
29444 + * whiteout for logical deletion and opaque directory
29445 + */
29446 +
29447 +#ifndef __AUFS_WHOUT_H__
29448 +#define __AUFS_WHOUT_H__
29449 +
29450 +#ifdef __KERNEL__
29451 +
29452 +#include "dir.h"
29453 +
29454 +/* whout.c */
29455 +int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
29456 +struct au_branch;
29457 +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
29458 +              struct au_branch *br, int try_sio);
29459 +int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
29460 +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
29461 +                            struct qstr *prefix);
29462 +int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
29463 +int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
29464 +                       struct dentry *dentry);
29465 +int au_wh_init(struct au_branch *br, struct super_block *sb);
29466 +
29467 +/* diropq flags */
29468 +#define AuDiropq_CREATE        1
29469 +#define au_ftest_diropq(flags, name)   ((flags) & AuDiropq_##name)
29470 +#define au_fset_diropq(flags, name) \
29471 +       do { (flags) |= AuDiropq_##name; } while (0)
29472 +#define au_fclr_diropq(flags, name) \
29473 +       do { (flags) &= ~AuDiropq_##name; } while (0)
29474 +
29475 +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
29476 +                            unsigned int flags);
29477 +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
29478 +                         struct au_branch *br);
29479 +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
29480 +                           struct dentry *h_parent);
29481 +
29482 +/* real rmdir for the whiteout-ed dir */
29483 +struct au_whtmp_rmdir {
29484 +       struct inode *dir;
29485 +       struct au_branch *br;
29486 +       struct dentry *wh_dentry;
29487 +       struct au_nhash whlist;
29488 +};
29489 +
29490 +struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
29491 +void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
29492 +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
29493 +                  struct dentry *wh_dentry, struct au_nhash *whlist);
29494 +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
29495 +                        struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
29496 +
29497 +/* ---------------------------------------------------------------------- */
29498 +
29499 +static inline struct dentry *au_diropq_create(struct dentry *dentry,
29500 +                                             aufs_bindex_t bindex)
29501 +{
29502 +       return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
29503 +}
29504 +
29505 +static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
29506 +{
29507 +       return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
29508 +}
29509 +
29510 +#endif /* __KERNEL__ */
29511 +#endif /* __AUFS_WHOUT_H__ */
29512 diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
29513 --- /usr/share/empty/fs/aufs/wkq.c      1970-01-01 01:00:00.000000000 +0100
29514 +++ linux/fs/aufs/wkq.c 2013-07-06 13:20:47.760198800 +0200
29515 @@ -0,0 +1,213 @@
29516 +/*
29517 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29518 + *
29519 + * This program, aufs is free software; you can redistribute it and/or modify
29520 + * it under the terms of the GNU General Public License as published by
29521 + * the Free Software Foundation; either version 2 of the License, or
29522 + * (at your option) any later version.
29523 + *
29524 + * This program is distributed in the hope that it will be useful,
29525 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29526 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29527 + * GNU General Public License for more details.
29528 + *
29529 + * You should have received a copy of the GNU General Public License
29530 + * along with this program; if not, write to the Free Software
29531 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
29532 + */
29533 +
29534 +/*
29535 + * workqueue for asynchronous/super-io operations
29536 + * todo: try new dredential scheme
29537 + */
29538 +
29539 +#include <linux/module.h>
29540 +#include "aufs.h"
29541 +
29542 +/* internal workqueue named AUFS_WKQ_NAME */
29543 +
29544 +static struct workqueue_struct *au_wkq;
29545 +
29546 +struct au_wkinfo {
29547 +       struct work_struct wk;
29548 +       struct kobject *kobj;
29549 +
29550 +       unsigned int flags; /* see wkq.h */
29551 +
29552 +       au_wkq_func_t func;
29553 +       void *args;
29554 +
29555 +       struct completion *comp;
29556 +};
29557 +
29558 +/* ---------------------------------------------------------------------- */
29559 +
29560 +static void wkq_func(struct work_struct *wk)
29561 +{
29562 +       struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
29563 +
29564 +       AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
29565 +       AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
29566 +
29567 +       wkinfo->func(wkinfo->args);
29568 +       if (au_ftest_wkq(wkinfo->flags, WAIT))
29569 +               complete(wkinfo->comp);
29570 +       else {
29571 +               kobject_put(wkinfo->kobj);
29572 +               module_put(THIS_MODULE); /* todo: ?? */
29573 +               kfree(wkinfo);
29574 +       }
29575 +}
29576 +
29577 +/*
29578 + * Since struct completion is large, try allocating it dynamically.
29579 + */
29580 +#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS)
29581 +#define AuWkqCompDeclare(name) struct completion *comp = NULL
29582 +
29583 +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
29584 +{
29585 +       *comp = kmalloc(sizeof(**comp), GFP_NOFS);
29586 +       if (*comp) {
29587 +               init_completion(*comp);
29588 +               wkinfo->comp = *comp;
29589 +               return 0;
29590 +       }
29591 +       return -ENOMEM;
29592 +}
29593 +
29594 +static void au_wkq_comp_free(struct completion *comp)
29595 +{
29596 +       kfree(comp);
29597 +}
29598 +
29599 +#else
29600 +
29601 +/* no braces */
29602 +#define AuWkqCompDeclare(name) \
29603 +       DECLARE_COMPLETION_ONSTACK(_ ## name); \
29604 +       struct completion *comp = &_ ## name
29605 +
29606 +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
29607 +{
29608 +       wkinfo->comp = *comp;
29609 +       return 0;
29610 +}
29611 +
29612 +static void au_wkq_comp_free(struct completion *comp __maybe_unused)
29613 +{
29614 +       /* empty */
29615 +}
29616 +#endif /* 4KSTACKS */
29617 +
29618 +static void au_wkq_run(struct au_wkinfo *wkinfo)
29619 +{
29620 +       if (au_ftest_wkq(wkinfo->flags, NEST)) {
29621 +               if (au_wkq_test()) {
29622 +                       AuWarn1("wkq from wkq, due to a dead dir by UDBA?\n");
29623 +                       AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
29624 +               }
29625 +       } else
29626 +               au_dbg_verify_kthread();
29627 +
29628 +       if (au_ftest_wkq(wkinfo->flags, WAIT)) {
29629 +               INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
29630 +               queue_work(au_wkq, &wkinfo->wk);
29631 +       } else {
29632 +               INIT_WORK(&wkinfo->wk, wkq_func);
29633 +               schedule_work(&wkinfo->wk);
29634 +       }
29635 +}
29636 +
29637 +/*
29638 + * Be careful. It is easy to make deadlock happen.
29639 + * processA: lock, wkq and wait
29640 + * processB: wkq and wait, lock in wkq
29641 + * --> deadlock
29642 + */
29643 +int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
29644 +{
29645 +       int err;
29646 +       AuWkqCompDeclare(comp);
29647 +       struct au_wkinfo wkinfo = {
29648 +               .flags  = flags,
29649 +               .func   = func,
29650 +               .args   = args
29651 +       };
29652 +
29653 +       err = au_wkq_comp_alloc(&wkinfo, &comp);
29654 +       if (!err) {
29655 +               au_wkq_run(&wkinfo);
29656 +               /* no timeout, no interrupt */
29657 +               wait_for_completion(wkinfo.comp);
29658 +               au_wkq_comp_free(comp);
29659 +               destroy_work_on_stack(&wkinfo.wk);
29660 +       }
29661 +
29662 +       return err;
29663 +
29664 +}
29665 +
29666 +/*
29667 + * Note: dget/dput() in func for aufs dentries are not supported. It will be a
29668 + * problem in a concurrent umounting.
29669 + */
29670 +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
29671 +                 unsigned int flags)
29672 +{
29673 +       int err;
29674 +       struct au_wkinfo *wkinfo;
29675 +
29676 +       atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
29677 +
29678 +       /*
29679 +        * wkq_func() must free this wkinfo.
29680 +        * it highly depends upon the implementation of workqueue.
29681 +        */
29682 +       err = 0;
29683 +       wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
29684 +       if (wkinfo) {
29685 +               wkinfo->kobj = &au_sbi(sb)->si_kobj;
29686 +               wkinfo->flags = flags & ~AuWkq_WAIT;
29687 +               wkinfo->func = func;
29688 +               wkinfo->args = args;
29689 +               wkinfo->comp = NULL;
29690 +               kobject_get(wkinfo->kobj);
29691 +               __module_get(THIS_MODULE); /* todo: ?? */
29692 +
29693 +               au_wkq_run(wkinfo);
29694 +       } else {
29695 +               err = -ENOMEM;
29696 +               au_nwt_done(&au_sbi(sb)->si_nowait);
29697 +       }
29698 +
29699 +       return err;
29700 +}
29701 +
29702 +/* ---------------------------------------------------------------------- */
29703 +
29704 +void au_nwt_init(struct au_nowait_tasks *nwt)
29705 +{
29706 +       atomic_set(&nwt->nw_len, 0);
29707 +       /* smp_mb(); */ /* atomic_set */
29708 +       init_waitqueue_head(&nwt->nw_wq);
29709 +}
29710 +
29711 +void au_wkq_fin(void)
29712 +{
29713 +       destroy_workqueue(au_wkq);
29714 +}
29715 +
29716 +int __init au_wkq_init(void)
29717 +{
29718 +       int err;
29719 +
29720 +       err = 0;
29721 +       au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
29722 +       if (IS_ERR(au_wkq))
29723 +               err = PTR_ERR(au_wkq);
29724 +       else if (!au_wkq)
29725 +               err = -ENOMEM;
29726 +
29727 +       return err;
29728 +}
29729 diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
29730 --- /usr/share/empty/fs/aufs/wkq.h      1970-01-01 01:00:00.000000000 +0100
29731 +++ linux/fs/aufs/wkq.h 2013-07-06 13:20:47.760198800 +0200
29732 @@ -0,0 +1,92 @@
29733 +/*
29734 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29735 + *
29736 + * This program, aufs is free software; you can redistribute it and/or modify
29737 + * it under the terms of the GNU General Public License as published by
29738 + * the Free Software Foundation; either version 2 of the License, or
29739 + * (at your option) any later version.
29740 + *
29741 + * This program is distributed in the hope that it will be useful,
29742 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29743 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29744 + * GNU General Public License for more details.
29745 + *
29746 + * You should have received a copy of the GNU General Public License
29747 + * along with this program; if not, write to the Free Software
29748 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
29749 + */
29750 +
29751 +/*
29752 + * workqueue for asynchronous/super-io operations
29753 + * todo: try new credentials management scheme
29754 + */
29755 +
29756 +#ifndef __AUFS_WKQ_H__
29757 +#define __AUFS_WKQ_H__
29758 +
29759 +#ifdef __KERNEL__
29760 +
29761 +struct super_block;
29762 +
29763 +/* ---------------------------------------------------------------------- */
29764 +
29765 +/*
29766 + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
29767 + */
29768 +struct au_nowait_tasks {
29769 +       atomic_t                nw_len;
29770 +       wait_queue_head_t       nw_wq;
29771 +};
29772 +
29773 +/* ---------------------------------------------------------------------- */
29774 +
29775 +typedef void (*au_wkq_func_t)(void *args);
29776 +
29777 +/* wkq flags */
29778 +#define AuWkq_WAIT     1
29779 +#define AuWkq_NEST     (1 << 1)
29780 +#define au_ftest_wkq(flags, name)      ((flags) & AuWkq_##name)
29781 +#define au_fset_wkq(flags, name) \
29782 +       do { (flags) |= AuWkq_##name; } while (0)
29783 +#define au_fclr_wkq(flags, name) \
29784 +       do { (flags) &= ~AuWkq_##name; } while (0)
29785 +
29786 +#ifndef CONFIG_AUFS_HNOTIFY
29787 +#undef AuWkq_NEST
29788 +#define AuWkq_NEST     0
29789 +#endif
29790 +
29791 +/* wkq.c */
29792 +int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
29793 +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
29794 +                 unsigned int flags);
29795 +void au_nwt_init(struct au_nowait_tasks *nwt);
29796 +int __init au_wkq_init(void);
29797 +void au_wkq_fin(void);
29798 +
29799 +/* ---------------------------------------------------------------------- */
29800 +
29801 +static inline int au_wkq_test(void)
29802 +{
29803 +       return current->flags & PF_WQ_WORKER;
29804 +}
29805 +
29806 +static inline int au_wkq_wait(au_wkq_func_t func, void *args)
29807 +{
29808 +       return au_wkq_do_wait(AuWkq_WAIT, func, args);
29809 +}
29810 +
29811 +static inline void au_nwt_done(struct au_nowait_tasks *nwt)
29812 +{
29813 +       if (atomic_dec_and_test(&nwt->nw_len))
29814 +               wake_up_all(&nwt->nw_wq);
29815 +}
29816 +
29817 +static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
29818 +{
29819 +       wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
29820 +       return 0;
29821 +}
29822 +
29823 +#endif /* __KERNEL__ */
29824 +#endif /* __AUFS_WKQ_H__ */
29825 diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
29826 --- /usr/share/empty/fs/aufs/xino.c     1970-01-01 01:00:00.000000000 +0100
29827 +++ linux/fs/aufs/xino.c        2013-07-06 13:20:47.760198800 +0200
29828 @@ -0,0 +1,1264 @@
29829 +/*
29830 + * Copyright (C) 2005-2013 Junjiro R. Okajima
29831 + *
29832 + * This program, aufs is free software; you can redistribute it and/or modify
29833 + * it under the terms of the GNU General Public License as published by
29834 + * the Free Software Foundation; either version 2 of the License, or
29835 + * (at your option) any later version.
29836 + *
29837 + * This program is distributed in the hope that it will be useful,
29838 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29839 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29840 + * GNU General Public License for more details.
29841 + *
29842 + * You should have received a copy of the GNU General Public License
29843 + * along with this program; if not, write to the Free Software
29844 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
29845 + */
29846 +
29847 +/*
29848 + * external inode number translation table and bitmap
29849 + */
29850 +
29851 +#include <linux/seq_file.h>
29852 +#include "aufs.h"
29853 +
29854 +/* todo: unnecessary to support mmap_sem since kernel-space? */
29855 +ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
29856 +                  loff_t *pos)
29857 +{
29858 +       ssize_t err;
29859 +       mm_segment_t oldfs;
29860 +       union {
29861 +               void *k;
29862 +               char __user *u;
29863 +       } buf;
29864 +
29865 +       buf.k = kbuf;
29866 +       oldfs = get_fs();
29867 +       set_fs(KERNEL_DS);
29868 +       do {
29869 +               /* todo: signal_pending? */
29870 +               err = func(file, buf.u, size, pos);
29871 +       } while (err == -EAGAIN || err == -EINTR);
29872 +       set_fs(oldfs);
29873 +
29874 +#if 0 /* reserved for future use */
29875 +       if (err > 0)
29876 +               fsnotify_access(file->f_dentry);
29877 +#endif
29878 +
29879 +       return err;
29880 +}
29881 +
29882 +/* ---------------------------------------------------------------------- */
29883 +
29884 +static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
29885 +                             size_t size, loff_t *pos)
29886 +{
29887 +       ssize_t err;
29888 +       mm_segment_t oldfs;
29889 +       union {
29890 +               void *k;
29891 +               const char __user *u;
29892 +       } buf;
29893 +
29894 +       buf.k = kbuf;
29895 +       oldfs = get_fs();
29896 +       set_fs(KERNEL_DS);
29897 +       do {
29898 +               /* todo: signal_pending? */
29899 +               err = func(file, buf.u, size, pos);
29900 +       } while (err == -EAGAIN || err == -EINTR);
29901 +       set_fs(oldfs);
29902 +
29903 +#if 0 /* reserved for future use */
29904 +       if (err > 0)
29905 +               fsnotify_modify(file->f_dentry);
29906 +#endif
29907 +
29908 +       return err;
29909 +}
29910 +
29911 +struct do_xino_fwrite_args {
29912 +       ssize_t *errp;
29913 +       au_writef_t func;
29914 +       struct file *file;
29915 +       void *buf;
29916 +       size_t size;
29917 +       loff_t *pos;
29918 +};
29919 +
29920 +static void call_do_xino_fwrite(void *args)
29921 +{
29922 +       struct do_xino_fwrite_args *a = args;
29923 +       *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
29924 +}
29925 +
29926 +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
29927 +                   loff_t *pos)
29928 +{
29929 +       ssize_t err;
29930 +
29931 +       /* todo: signal block and no wkq? */
29932 +       if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
29933 +               lockdep_off();
29934 +               err = do_xino_fwrite(func, file, buf, size, pos);
29935 +               lockdep_on();
29936 +       } else {
29937 +               /*
29938 +                * it breaks RLIMIT_FSIZE and normal user's limit,
29939 +                * users should care about quota and real 'filesystem full.'
29940 +                */
29941 +               int wkq_err;
29942 +               struct do_xino_fwrite_args args = {
29943 +                       .errp   = &err,
29944 +                       .func   = func,
29945 +                       .file   = file,
29946 +                       .buf    = buf,
29947 +                       .size   = size,
29948 +                       .pos    = pos
29949 +               };
29950 +
29951 +               wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
29952 +               if (unlikely(wkq_err))
29953 +                       err = wkq_err;
29954 +       }
29955 +
29956 +       return err;
29957 +}
29958 +
29959 +/* ---------------------------------------------------------------------- */
29960 +
29961 +/*
29962 + * create a new xinofile at the same place/path as @base_file.
29963 + */
29964 +struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
29965 +{
29966 +       struct file *file;
29967 +       struct dentry *base, *parent;
29968 +       struct inode *dir;
29969 +       struct qstr *name;
29970 +       struct path path;
29971 +       int err;
29972 +
29973 +       base = base_file->f_dentry;
29974 +       parent = base->d_parent; /* dir inode is locked */
29975 +       dir = parent->d_inode;
29976 +       IMustLock(dir);
29977 +
29978 +       file = ERR_PTR(-EINVAL);
29979 +       name = &base->d_name;
29980 +       path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
29981 +       if (IS_ERR(path.dentry)) {
29982 +               file = (void *)path.dentry;
29983 +               pr_err("%.*s lookup err %ld\n",
29984 +                      AuLNPair(name), PTR_ERR(path.dentry));
29985 +               goto out;
29986 +       }
29987 +
29988 +       /* no need to mnt_want_write() since we call dentry_open() later */
29989 +       err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
29990 +       if (unlikely(err)) {
29991 +               file = ERR_PTR(err);
29992 +               pr_err("%.*s create err %d\n", AuLNPair(name), err);
29993 +               goto out_dput;
29994 +       }
29995 +
29996 +       path.mnt = base_file->f_path.mnt;
29997 +       file = vfsub_dentry_open(&path,
29998 +                                O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
29999 +                                /* | __FMODE_NONOTIFY */);
30000 +       if (IS_ERR(file)) {
30001 +               pr_err("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
30002 +               goto out_dput;
30003 +       }
30004 +
30005 +       err = vfsub_unlink(dir, &file->f_path, /*force*/0);
30006 +       if (unlikely(err)) {
30007 +               pr_err("%.*s unlink err %d\n", AuLNPair(name), err);
30008 +               goto out_fput;
30009 +       }
30010 +
30011 +       if (copy_src) {
30012 +               /* no one can touch copy_src xino */
30013 +               err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
30014 +               if (unlikely(err)) {
30015 +                       pr_err("%.*s copy err %d\n", AuLNPair(name), err);
30016 +                       goto out_fput;
30017 +               }
30018 +       }
30019 +       goto out_dput; /* success */
30020 +
30021 +out_fput:
30022 +       fput(file);
30023 +       file = ERR_PTR(err);
30024 +out_dput:
30025 +       dput(path.dentry);
30026 +out:
30027 +       return file;
30028 +}
30029 +
30030 +struct au_xino_lock_dir {
30031 +       struct au_hinode *hdir;
30032 +       struct dentry *parent;
30033 +       struct mutex *mtx;
30034 +};
30035 +
30036 +static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
30037 +                            struct au_xino_lock_dir *ldir)
30038 +{
30039 +       aufs_bindex_t brid, bindex;
30040 +
30041 +       ldir->hdir = NULL;
30042 +       bindex = -1;
30043 +       brid = au_xino_brid(sb);
30044 +       if (brid >= 0)
30045 +               bindex = au_br_index(sb, brid);
30046 +       if (bindex >= 0) {
30047 +               ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
30048 +               au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
30049 +       } else {
30050 +               ldir->parent = dget_parent(xino->f_dentry);
30051 +               ldir->mtx = &ldir->parent->d_inode->i_mutex;
30052 +               mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
30053 +       }
30054 +}
30055 +
30056 +static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
30057 +{
30058 +       if (ldir->hdir)
30059 +               au_hn_imtx_unlock(ldir->hdir);
30060 +       else {
30061 +               mutex_unlock(ldir->mtx);
30062 +               dput(ldir->parent);
30063 +       }
30064 +}
30065 +
30066 +/* ---------------------------------------------------------------------- */
30067 +
30068 +/* trucate xino files asynchronously */
30069 +
30070 +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
30071 +{
30072 +       int err;
30073 +       aufs_bindex_t bi, bend;
30074 +       struct au_branch *br;
30075 +       struct file *new_xino, *file;
30076 +       struct super_block *h_sb;
30077 +       struct au_xino_lock_dir ldir;
30078 +
30079 +       err = -EINVAL;
30080 +       bend = au_sbend(sb);
30081 +       if (unlikely(bindex < 0 || bend < bindex))
30082 +               goto out;
30083 +       br = au_sbr(sb, bindex);
30084 +       file = br->br_xino.xi_file;
30085 +       if (!file)
30086 +               goto out;
30087 +
30088 +       au_xino_lock_dir(sb, file, &ldir);
30089 +       /* mnt_want_write() is unnecessary here */
30090 +       new_xino = au_xino_create2(file, file);
30091 +       au_xino_unlock_dir(&ldir);
30092 +       err = PTR_ERR(new_xino);
30093 +       if (IS_ERR(new_xino))
30094 +               goto out;
30095 +       err = 0;
30096 +       fput(file);
30097 +       br->br_xino.xi_file = new_xino;
30098 +
30099 +       h_sb = au_br_sb(br);
30100 +       for (bi = 0; bi <= bend; bi++) {
30101 +               if (unlikely(bi == bindex))
30102 +                       continue;
30103 +               br = au_sbr(sb, bi);
30104 +               if (au_br_sb(br) != h_sb)
30105 +                       continue;
30106 +
30107 +               fput(br->br_xino.xi_file);
30108 +               br->br_xino.xi_file = new_xino;
30109 +               get_file(new_xino);
30110 +       }
30111 +
30112 +out:
30113 +       return err;
30114 +}
30115 +
30116 +struct xino_do_trunc_args {
30117 +       struct super_block *sb;
30118 +       struct au_branch *br;
30119 +};
30120 +
30121 +static void xino_do_trunc(void *_args)
30122 +{
30123 +       struct xino_do_trunc_args *args = _args;
30124 +       struct super_block *sb;
30125 +       struct au_branch *br;
30126 +       struct inode *dir;
30127 +       int err;
30128 +       aufs_bindex_t bindex;
30129 +
30130 +       err = 0;
30131 +       sb = args->sb;
30132 +       dir = sb->s_root->d_inode;
30133 +       br = args->br;
30134 +
30135 +       si_noflush_write_lock(sb);
30136 +       ii_read_lock_parent(dir);
30137 +       bindex = au_br_index(sb, br->br_id);
30138 +       err = au_xino_trunc(sb, bindex);
30139 +       if (!err
30140 +           && file_inode(br->br_xino.xi_file)->i_blocks
30141 +           >= br->br_xino_upper)
30142 +               br->br_xino_upper += AUFS_XINO_TRUNC_STEP;
30143 +
30144 +       ii_read_unlock(dir);
30145 +       if (unlikely(err))
30146 +               pr_warn("err b%d, upper %llu, (%d)\n",
30147 +                       bindex, (unsigned long long)br->br_xino_upper, err);
30148 +       atomic_dec(&br->br_xino_running);
30149 +       atomic_dec(&br->br_count);
30150 +       si_write_unlock(sb);
30151 +       au_nwt_done(&au_sbi(sb)->si_nowait);
30152 +       kfree(args);
30153 +}
30154 +
30155 +static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
30156 +{
30157 +       struct xino_do_trunc_args *args;
30158 +       int wkq_err;
30159 +
30160 +       if (file_inode(br->br_xino.xi_file)->i_blocks
30161 +           < br->br_xino_upper)
30162 +               return;
30163 +
30164 +       if (atomic_inc_return(&br->br_xino_running) > 1)
30165 +               goto out;
30166 +
30167 +       /* lock and kfree() will be called in trunc_xino() */
30168 +       args = kmalloc(sizeof(*args), GFP_NOFS);
30169 +       if (unlikely(!args)) {
30170 +               AuErr1("no memory\n");
30171 +               goto out_args;
30172 +       }
30173 +
30174 +       atomic_inc(&br->br_count);
30175 +       args->sb = sb;
30176 +       args->br = br;
30177 +       wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
30178 +       if (!wkq_err)
30179 +               return; /* success */
30180 +
30181 +       pr_err("wkq %d\n", wkq_err);
30182 +       atomic_dec(&br->br_count);
30183 +
30184 +out_args:
30185 +       kfree(args);
30186 +out:
30187 +       atomic_dec(&br->br_xino_running);
30188 +}
30189 +
30190 +/* ---------------------------------------------------------------------- */
30191 +
30192 +static int au_xino_do_write(au_writef_t write, struct file *file,
30193 +                           ino_t h_ino, ino_t ino)
30194 +{
30195 +       loff_t pos;
30196 +       ssize_t sz;
30197 +
30198 +       pos = h_ino;
30199 +       if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
30200 +               AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
30201 +               return -EFBIG;
30202 +       }
30203 +       pos *= sizeof(ino);
30204 +       sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
30205 +       if (sz == sizeof(ino))
30206 +               return 0; /* success */
30207 +
30208 +       AuIOErr("write failed (%zd)\n", sz);
30209 +       return -EIO;
30210 +}
30211 +
30212 +/*
30213 + * write @ino to the xinofile for the specified branch{@sb, @bindex}
30214 + * at the position of @h_ino.
30215 + * even if @ino is zero, it is written to the xinofile and means no entry.
30216 + * if the size of the xino file on a specific filesystem exceeds the watermark,
30217 + * try truncating it.
30218 + */
30219 +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
30220 +                 ino_t ino)
30221 +{
30222 +       int err;
30223 +       unsigned int mnt_flags;
30224 +       struct au_branch *br;
30225 +
30226 +       BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
30227 +                    || ((loff_t)-1) > 0);
30228 +       SiMustAnyLock(sb);
30229 +
30230 +       mnt_flags = au_mntflags(sb);
30231 +       if (!au_opt_test(mnt_flags, XINO))
30232 +               return 0;
30233 +
30234 +       br = au_sbr(sb, bindex);
30235 +       err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
30236 +                              h_ino, ino);
30237 +       if (!err) {
30238 +               if (au_opt_test(mnt_flags, TRUNC_XINO)
30239 +                   && au_test_fs_trunc_xino(au_br_sb(br)))
30240 +                       xino_try_trunc(sb, br);
30241 +               return 0; /* success */
30242 +       }
30243 +
30244 +       AuIOErr("write failed (%d)\n", err);
30245 +       return -EIO;
30246 +}
30247 +
30248 +/* ---------------------------------------------------------------------- */
30249 +
30250 +/* aufs inode number bitmap */
30251 +
30252 +static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
30253 +static ino_t xib_calc_ino(unsigned long pindex, int bit)
30254 +{
30255 +       ino_t ino;
30256 +
30257 +       AuDebugOn(bit < 0 || page_bits <= bit);
30258 +       ino = AUFS_FIRST_INO + pindex * page_bits + bit;
30259 +       return ino;
30260 +}
30261 +
30262 +static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
30263 +{
30264 +       AuDebugOn(ino < AUFS_FIRST_INO);
30265 +       ino -= AUFS_FIRST_INO;
30266 +       *pindex = ino / page_bits;
30267 +       *bit = ino % page_bits;
30268 +}
30269 +
30270 +static int xib_pindex(struct super_block *sb, unsigned long pindex)
30271 +{
30272 +       int err;
30273 +       loff_t pos;
30274 +       ssize_t sz;
30275 +       struct au_sbinfo *sbinfo;
30276 +       struct file *xib;
30277 +       unsigned long *p;
30278 +
30279 +       sbinfo = au_sbi(sb);
30280 +       MtxMustLock(&sbinfo->si_xib_mtx);
30281 +       AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
30282 +                 || !au_opt_test(sbinfo->si_mntflags, XINO));
30283 +
30284 +       if (pindex == sbinfo->si_xib_last_pindex)
30285 +               return 0;
30286 +
30287 +       xib = sbinfo->si_xib;
30288 +       p = sbinfo->si_xib_buf;
30289 +       pos = sbinfo->si_xib_last_pindex;
30290 +       pos *= PAGE_SIZE;
30291 +       sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
30292 +       if (unlikely(sz != PAGE_SIZE))
30293 +               goto out;
30294 +
30295 +       pos = pindex;
30296 +       pos *= PAGE_SIZE;
30297 +       if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
30298 +               sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
30299 +       else {
30300 +               memset(p, 0, PAGE_SIZE);
30301 +               sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
30302 +       }
30303 +       if (sz == PAGE_SIZE) {
30304 +               sbinfo->si_xib_last_pindex = pindex;
30305 +               return 0; /* success */
30306 +       }
30307 +
30308 +out:
30309 +       AuIOErr1("write failed (%zd)\n", sz);
30310 +       err = sz;
30311 +       if (sz >= 0)
30312 +               err = -EIO;
30313 +       return err;
30314 +}
30315 +
30316 +/* ---------------------------------------------------------------------- */
30317 +
30318 +static void au_xib_clear_bit(struct inode *inode)
30319 +{
30320 +       int err, bit;
30321 +       unsigned long pindex;
30322 +       struct super_block *sb;
30323 +       struct au_sbinfo *sbinfo;
30324 +
30325 +       AuDebugOn(inode->i_nlink);
30326 +
30327 +       sb = inode->i_sb;
30328 +       xib_calc_bit(inode->i_ino, &pindex, &bit);
30329 +       AuDebugOn(page_bits <= bit);
30330 +       sbinfo = au_sbi(sb);
30331 +       mutex_lock(&sbinfo->si_xib_mtx);
30332 +       err = xib_pindex(sb, pindex);
30333 +       if (!err) {
30334 +               clear_bit(bit, sbinfo->si_xib_buf);
30335 +               sbinfo->si_xib_next_bit = bit;
30336 +       }
30337 +       mutex_unlock(&sbinfo->si_xib_mtx);
30338 +}
30339 +
30340 +/* for s_op->delete_inode() */
30341 +void au_xino_delete_inode(struct inode *inode, const int unlinked)
30342 +{
30343 +       int err;
30344 +       unsigned int mnt_flags;
30345 +       aufs_bindex_t bindex, bend, bi;
30346 +       unsigned char try_trunc;
30347 +       struct au_iinfo *iinfo;
30348 +       struct super_block *sb;
30349 +       struct au_hinode *hi;
30350 +       struct inode *h_inode;
30351 +       struct au_branch *br;
30352 +       au_writef_t xwrite;
30353 +
30354 +       sb = inode->i_sb;
30355 +       mnt_flags = au_mntflags(sb);
30356 +       if (!au_opt_test(mnt_flags, XINO)
30357 +           || inode->i_ino == AUFS_ROOT_INO)
30358 +               return;
30359 +
30360 +       if (unlinked) {
30361 +               au_xigen_inc(inode);
30362 +               au_xib_clear_bit(inode);
30363 +       }
30364 +
30365 +       iinfo = au_ii(inode);
30366 +       if (!iinfo)
30367 +               return;
30368 +
30369 +       bindex = iinfo->ii_bstart;
30370 +       if (bindex < 0)
30371 +               return;
30372 +
30373 +       xwrite = au_sbi(sb)->si_xwrite;
30374 +       try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
30375 +       hi = iinfo->ii_hinode + bindex;
30376 +       bend = iinfo->ii_bend;
30377 +       for (; bindex <= bend; bindex++, hi++) {
30378 +               h_inode = hi->hi_inode;
30379 +               if (!h_inode
30380 +                   || (!unlinked && h_inode->i_nlink))
30381 +                       continue;
30382 +
30383 +               /* inode may not be revalidated */
30384 +               bi = au_br_index(sb, hi->hi_id);
30385 +               if (bi < 0)
30386 +                       continue;
30387 +
30388 +               br = au_sbr(sb, bi);
30389 +               err = au_xino_do_write(xwrite, br->br_xino.xi_file,
30390 +                                      h_inode->i_ino, /*ino*/0);
30391 +               if (!err && try_trunc
30392 +                   && au_test_fs_trunc_xino(au_br_sb(br)))
30393 +                       xino_try_trunc(sb, br);
30394 +       }
30395 +}
30396 +
30397 +/* get an unused inode number from bitmap */
30398 +ino_t au_xino_new_ino(struct super_block *sb)
30399 +{
30400 +       ino_t ino;
30401 +       unsigned long *p, pindex, ul, pend;
30402 +       struct au_sbinfo *sbinfo;
30403 +       struct file *file;
30404 +       int free_bit, err;
30405 +
30406 +       if (!au_opt_test(au_mntflags(sb), XINO))
30407 +               return iunique(sb, AUFS_FIRST_INO);
30408 +
30409 +       sbinfo = au_sbi(sb);
30410 +       mutex_lock(&sbinfo->si_xib_mtx);
30411 +       p = sbinfo->si_xib_buf;
30412 +       free_bit = sbinfo->si_xib_next_bit;
30413 +       if (free_bit < page_bits && !test_bit(free_bit, p))
30414 +               goto out; /* success */
30415 +       free_bit = find_first_zero_bit(p, page_bits);
30416 +       if (free_bit < page_bits)
30417 +               goto out; /* success */
30418 +
30419 +       pindex = sbinfo->si_xib_last_pindex;
30420 +       for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
30421 +               err = xib_pindex(sb, ul);
30422 +               if (unlikely(err))
30423 +                       goto out_err;
30424 +               free_bit = find_first_zero_bit(p, page_bits);
30425 +               if (free_bit < page_bits)
30426 +                       goto out; /* success */
30427 +       }
30428 +
30429 +       file = sbinfo->si_xib;
30430 +       pend = vfsub_f_size_read(file) / PAGE_SIZE;
30431 +       for (ul = pindex + 1; ul <= pend; ul++) {
30432 +               err = xib_pindex(sb, ul);
30433 +               if (unlikely(err))
30434 +                       goto out_err;
30435 +               free_bit = find_first_zero_bit(p, page_bits);
30436 +               if (free_bit < page_bits)
30437 +                       goto out; /* success */
30438 +       }
30439 +       BUG();
30440 +
30441 +out:
30442 +       set_bit(free_bit, p);
30443 +       sbinfo->si_xib_next_bit = free_bit + 1;
30444 +       pindex = sbinfo->si_xib_last_pindex;
30445 +       mutex_unlock(&sbinfo->si_xib_mtx);
30446 +       ino = xib_calc_ino(pindex, free_bit);
30447 +       AuDbg("i%lu\n", (unsigned long)ino);
30448 +       return ino;
30449 +out_err:
30450 +       mutex_unlock(&sbinfo->si_xib_mtx);
30451 +       AuDbg("i0\n");
30452 +       return 0;
30453 +}
30454 +
30455 +/*
30456 + * read @ino from xinofile for the specified branch{@sb, @bindex}
30457 + * at the position of @h_ino.
30458 + * if @ino does not exist and @do_new is true, get new one.
30459 + */
30460 +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
30461 +                ino_t *ino)
30462 +{
30463 +       int err;
30464 +       ssize_t sz;
30465 +       loff_t pos;
30466 +       struct file *file;
30467 +       struct au_sbinfo *sbinfo;
30468 +
30469 +       *ino = 0;
30470 +       if (!au_opt_test(au_mntflags(sb), XINO))
30471 +               return 0; /* no xino */
30472 +
30473 +       err = 0;
30474 +       sbinfo = au_sbi(sb);
30475 +       pos = h_ino;
30476 +       if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
30477 +               AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
30478 +               return -EFBIG;
30479 +       }
30480 +       pos *= sizeof(*ino);
30481 +
30482 +       file = au_sbr(sb, bindex)->br_xino.xi_file;
30483 +       if (vfsub_f_size_read(file) < pos + sizeof(*ino))
30484 +               return 0; /* no ino */
30485 +
30486 +       sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
30487 +       if (sz == sizeof(*ino))
30488 +               return 0; /* success */
30489 +
30490 +       err = sz;
30491 +       if (unlikely(sz >= 0)) {
30492 +               err = -EIO;
30493 +               AuIOErr("xino read error (%zd)\n", sz);
30494 +       }
30495 +
30496 +       return err;
30497 +}
30498 +
30499 +/* ---------------------------------------------------------------------- */
30500 +
30501 +/* create and set a new xino file */
30502 +
30503 +struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
30504 +{
30505 +       struct file *file;
30506 +       struct dentry *h_parent, *d;
30507 +       struct inode *h_dir;
30508 +       int err;
30509 +
30510 +       /*
30511 +        * at mount-time, and the xino file is the default path,
30512 +        * hnotify is disabled so we have no notify events to ignore.
30513 +        * when a user specified the xino, we cannot get au_hdir to be ignored.
30514 +        */
30515 +       file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
30516 +                              /* | __FMODE_NONOTIFY */,
30517 +                              S_IRUGO | S_IWUGO);
30518 +       if (IS_ERR(file)) {
30519 +               if (!silent)
30520 +                       pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
30521 +               return file;
30522 +       }
30523 +
30524 +       /* keep file count */
30525 +       h_parent = dget_parent(file->f_dentry);
30526 +       h_dir = h_parent->d_inode;
30527 +       mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
30528 +       /* mnt_want_write() is unnecessary here */
30529 +       err = vfsub_unlink(h_dir, &file->f_path, /*force*/0);
30530 +       mutex_unlock(&h_dir->i_mutex);
30531 +       dput(h_parent);
30532 +       if (unlikely(err)) {
30533 +               if (!silent)
30534 +                       pr_err("unlink %s(%d)\n", fname, err);
30535 +               goto out;
30536 +       }
30537 +
30538 +       err = -EINVAL;
30539 +       d = file->f_dentry;
30540 +       if (unlikely(sb == d->d_sb)) {
30541 +               if (!silent)
30542 +                       pr_err("%s must be outside\n", fname);
30543 +               goto out;
30544 +       }
30545 +       if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
30546 +               if (!silent)
30547 +                       pr_err("xino doesn't support %s(%s)\n",
30548 +                              fname, au_sbtype(d->d_sb));
30549 +               goto out;
30550 +       }
30551 +       return file; /* success */
30552 +
30553 +out:
30554 +       fput(file);
30555 +       file = ERR_PTR(err);
30556 +       return file;
30557 +}
30558 +
30559 +/*
30560 + * find another branch who is on the same filesystem of the specified
30561 + * branch{@btgt}. search until @bend.
30562 + */
30563 +static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
30564 +                       aufs_bindex_t bend)
30565 +{
30566 +       aufs_bindex_t bindex;
30567 +       struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
30568 +
30569 +       for (bindex = 0; bindex < btgt; bindex++)
30570 +               if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
30571 +                       return bindex;
30572 +       for (bindex++; bindex <= bend; bindex++)
30573 +               if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
30574 +                       return bindex;
30575 +       return -1;
30576 +}
30577 +
30578 +/* ---------------------------------------------------------------------- */
30579 +
30580 +/*
30581 + * initialize the xinofile for the specified branch @br
30582 + * at the place/path where @base_file indicates.
30583 + * test whether another branch is on the same filesystem or not,
30584 + * if @do_test is true.
30585 + */
30586 +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
30587 +              struct file *base_file, int do_test)
30588 +{
30589 +       int err;
30590 +       ino_t ino;
30591 +       aufs_bindex_t bend, bindex;
30592 +       struct au_branch *shared_br, *b;
30593 +       struct file *file;
30594 +       struct super_block *tgt_sb;
30595 +
30596 +       shared_br = NULL;
30597 +       bend = au_sbend(sb);
30598 +       if (do_test) {
30599 +               tgt_sb = au_br_sb(br);
30600 +               for (bindex = 0; bindex <= bend; bindex++) {
30601 +                       b = au_sbr(sb, bindex);
30602 +                       if (tgt_sb == au_br_sb(b)) {
30603 +                               shared_br = b;
30604 +                               break;
30605 +                       }
30606 +               }
30607 +       }
30608 +
30609 +       if (!shared_br || !shared_br->br_xino.xi_file) {
30610 +               struct au_xino_lock_dir ldir;
30611 +
30612 +               au_xino_lock_dir(sb, base_file, &ldir);
30613 +               /* mnt_want_write() is unnecessary here */
30614 +               file = au_xino_create2(base_file, NULL);
30615 +               au_xino_unlock_dir(&ldir);
30616 +               err = PTR_ERR(file);
30617 +               if (IS_ERR(file))
30618 +                       goto out;
30619 +               br->br_xino.xi_file = file;
30620 +       } else {
30621 +               br->br_xino.xi_file = shared_br->br_xino.xi_file;
30622 +               get_file(br->br_xino.xi_file);
30623 +       }
30624 +
30625 +       ino = AUFS_ROOT_INO;
30626 +       err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
30627 +                              h_ino, ino);
30628 +       if (unlikely(err)) {
30629 +               fput(br->br_xino.xi_file);
30630 +               br->br_xino.xi_file = NULL;
30631 +       }
30632 +
30633 +out:
30634 +       return err;
30635 +}
30636 +
30637 +/* ---------------------------------------------------------------------- */
30638 +
30639 +/* trucate a xino bitmap file */
30640 +
30641 +/* todo: slow */
30642 +static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
30643 +{
30644 +       int err, bit;
30645 +       ssize_t sz;
30646 +       unsigned long pindex;
30647 +       loff_t pos, pend;
30648 +       struct au_sbinfo *sbinfo;
30649 +       au_readf_t func;
30650 +       ino_t *ino;
30651 +       unsigned long *p;
30652 +
30653 +       err = 0;
30654 +       sbinfo = au_sbi(sb);
30655 +       MtxMustLock(&sbinfo->si_xib_mtx);
30656 +       p = sbinfo->si_xib_buf;
30657 +       func = sbinfo->si_xread;
30658 +       pend = vfsub_f_size_read(file);
30659 +       pos = 0;
30660 +       while (pos < pend) {
30661 +               sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
30662 +               err = sz;
30663 +               if (unlikely(sz <= 0))
30664 +                       goto out;
30665 +
30666 +               err = 0;
30667 +               for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
30668 +                       if (unlikely(*ino < AUFS_FIRST_INO))
30669 +                               continue;
30670 +
30671 +                       xib_calc_bit(*ino, &pindex, &bit);
30672 +                       AuDebugOn(page_bits <= bit);
30673 +                       err = xib_pindex(sb, pindex);
30674 +                       if (!err)
30675 +                               set_bit(bit, p);
30676 +                       else
30677 +                               goto out;
30678 +               }
30679 +       }
30680 +
30681 +out:
30682 +       return err;
30683 +}
30684 +
30685 +static int xib_restore(struct super_block *sb)
30686 +{
30687 +       int err;
30688 +       aufs_bindex_t bindex, bend;
30689 +       void *page;
30690 +
30691 +       err = -ENOMEM;
30692 +       page = (void *)__get_free_page(GFP_NOFS);
30693 +       if (unlikely(!page))
30694 +               goto out;
30695 +
30696 +       err = 0;
30697 +       bend = au_sbend(sb);
30698 +       for (bindex = 0; !err && bindex <= bend; bindex++)
30699 +               if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
30700 +                       err = do_xib_restore
30701 +                               (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
30702 +               else
30703 +                       AuDbg("b%d\n", bindex);
30704 +       free_page((unsigned long)page);
30705 +
30706 +out:
30707 +       return err;
30708 +}
30709 +
30710 +int au_xib_trunc(struct super_block *sb)
30711 +{
30712 +       int err;
30713 +       ssize_t sz;
30714 +       loff_t pos;
30715 +       struct au_xino_lock_dir ldir;
30716 +       struct au_sbinfo *sbinfo;
30717 +       unsigned long *p;
30718 +       struct file *file;
30719 +
30720 +       SiMustWriteLock(sb);
30721 +
30722 +       err = 0;
30723 +       sbinfo = au_sbi(sb);
30724 +       if (!au_opt_test(sbinfo->si_mntflags, XINO))
30725 +               goto out;
30726 +
30727 +       file = sbinfo->si_xib;
30728 +       if (vfsub_f_size_read(file) <= PAGE_SIZE)
30729 +               goto out;
30730 +
30731 +       au_xino_lock_dir(sb, file, &ldir);
30732 +       /* mnt_want_write() is unnecessary here */
30733 +       file = au_xino_create2(sbinfo->si_xib, NULL);
30734 +       au_xino_unlock_dir(&ldir);
30735 +       err = PTR_ERR(file);
30736 +       if (IS_ERR(file))
30737 +               goto out;
30738 +       fput(sbinfo->si_xib);
30739 +       sbinfo->si_xib = file;
30740 +
30741 +       p = sbinfo->si_xib_buf;
30742 +       memset(p, 0, PAGE_SIZE);
30743 +       pos = 0;
30744 +       sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
30745 +       if (unlikely(sz != PAGE_SIZE)) {
30746 +               err = sz;
30747 +               AuIOErr("err %d\n", err);
30748 +               if (sz >= 0)
30749 +                       err = -EIO;
30750 +               goto out;
30751 +       }
30752 +
30753 +       mutex_lock(&sbinfo->si_xib_mtx);
30754 +       /* mnt_want_write() is unnecessary here */
30755 +       err = xib_restore(sb);
30756 +       mutex_unlock(&sbinfo->si_xib_mtx);
30757 +
30758 +out:
30759 +       return err;
30760 +}
30761 +
30762 +/* ---------------------------------------------------------------------- */
30763 +
30764 +/*
30765 + * xino mount option handlers
30766 + */
30767 +static au_readf_t find_readf(struct file *h_file)
30768 +{
30769 +       const struct file_operations *fop = h_file->f_op;
30770 +
30771 +       if (fop) {
30772 +               if (fop->read)
30773 +                       return fop->read;
30774 +               if (fop->aio_read)
30775 +                       return do_sync_read;
30776 +       }
30777 +       return ERR_PTR(-ENOSYS);
30778 +}
30779 +
30780 +static au_writef_t find_writef(struct file *h_file)
30781 +{
30782 +       const struct file_operations *fop = h_file->f_op;
30783 +
30784 +       if (fop) {
30785 +               if (fop->write)
30786 +                       return fop->write;
30787 +               if (fop->aio_write)
30788 +                       return do_sync_write;
30789 +       }
30790 +       return ERR_PTR(-ENOSYS);
30791 +}
30792 +
30793 +/* xino bitmap */
30794 +static void xino_clear_xib(struct super_block *sb)
30795 +{
30796 +       struct au_sbinfo *sbinfo;
30797 +
30798 +       SiMustWriteLock(sb);
30799 +
30800 +       sbinfo = au_sbi(sb);
30801 +       sbinfo->si_xread = NULL;
30802 +       sbinfo->si_xwrite = NULL;
30803 +       if (sbinfo->si_xib)
30804 +               fput(sbinfo->si_xib);
30805 +       sbinfo->si_xib = NULL;
30806 +       free_page((unsigned long)sbinfo->si_xib_buf);
30807 +       sbinfo->si_xib_buf = NULL;
30808 +}
30809 +
30810 +static int au_xino_set_xib(struct super_block *sb, struct file *base)
30811 +{
30812 +       int err;
30813 +       loff_t pos;
30814 +       struct au_sbinfo *sbinfo;
30815 +       struct file *file;
30816 +
30817 +       SiMustWriteLock(sb);
30818 +
30819 +       sbinfo = au_sbi(sb);
30820 +       file = au_xino_create2(base, sbinfo->si_xib);
30821 +       err = PTR_ERR(file);
30822 +       if (IS_ERR(file))
30823 +               goto out;
30824 +       if (sbinfo->si_xib)
30825 +               fput(sbinfo->si_xib);
30826 +       sbinfo->si_xib = file;
30827 +       sbinfo->si_xread = find_readf(file);
30828 +       sbinfo->si_xwrite = find_writef(file);
30829 +
30830 +       err = -ENOMEM;
30831 +       if (!sbinfo->si_xib_buf)
30832 +               sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
30833 +       if (unlikely(!sbinfo->si_xib_buf))
30834 +               goto out_unset;
30835 +
30836 +       sbinfo->si_xib_last_pindex = 0;
30837 +       sbinfo->si_xib_next_bit = 0;
30838 +       if (vfsub_f_size_read(file) < PAGE_SIZE) {
30839 +               pos = 0;
30840 +               err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
30841 +                                 PAGE_SIZE, &pos);
30842 +               if (unlikely(err != PAGE_SIZE))
30843 +                       goto out_free;
30844 +       }
30845 +       err = 0;
30846 +       goto out; /* success */
30847 +
30848 +out_free:
30849 +       free_page((unsigned long)sbinfo->si_xib_buf);
30850 +       sbinfo->si_xib_buf = NULL;
30851 +       if (err >= 0)
30852 +               err = -EIO;
30853 +out_unset:
30854 +       fput(sbinfo->si_xib);
30855 +       sbinfo->si_xib = NULL;
30856 +       sbinfo->si_xread = NULL;
30857 +       sbinfo->si_xwrite = NULL;
30858 +out:
30859 +       return err;
30860 +}
30861 +
30862 +/* xino for each branch */
30863 +static void xino_clear_br(struct super_block *sb)
30864 +{
30865 +       aufs_bindex_t bindex, bend;
30866 +       struct au_branch *br;
30867 +
30868 +       bend = au_sbend(sb);
30869 +       for (bindex = 0; bindex <= bend; bindex++) {
30870 +               br = au_sbr(sb, bindex);
30871 +               if (!br || !br->br_xino.xi_file)
30872 +                       continue;
30873 +
30874 +               fput(br->br_xino.xi_file);
30875 +               br->br_xino.xi_file = NULL;
30876 +       }
30877 +}
30878 +
30879 +static int au_xino_set_br(struct super_block *sb, struct file *base)
30880 +{
30881 +       int err;
30882 +       ino_t ino;
30883 +       aufs_bindex_t bindex, bend, bshared;
30884 +       struct {
30885 +               struct file *old, *new;
30886 +       } *fpair, *p;
30887 +       struct au_branch *br;
30888 +       struct inode *inode;
30889 +       au_writef_t writef;
30890 +
30891 +       SiMustWriteLock(sb);
30892 +
30893 +       err = -ENOMEM;
30894 +       bend = au_sbend(sb);
30895 +       fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
30896 +       if (unlikely(!fpair))
30897 +               goto out;
30898 +
30899 +       inode = sb->s_root->d_inode;
30900 +       ino = AUFS_ROOT_INO;
30901 +       writef = au_sbi(sb)->si_xwrite;
30902 +       for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
30903 +               br = au_sbr(sb, bindex);
30904 +               bshared = is_sb_shared(sb, bindex, bindex - 1);
30905 +               if (bshared >= 0) {
30906 +                       /* shared xino */
30907 +                       *p = fpair[bshared];
30908 +                       get_file(p->new);
30909 +               }
30910 +
30911 +               if (!p->new) {
30912 +                       /* new xino */
30913 +                       p->old = br->br_xino.xi_file;
30914 +                       p->new = au_xino_create2(base, br->br_xino.xi_file);
30915 +                       err = PTR_ERR(p->new);
30916 +                       if (IS_ERR(p->new)) {
30917 +                               p->new = NULL;
30918 +                               goto out_pair;
30919 +                       }
30920 +               }
30921 +
30922 +               err = au_xino_do_write(writef, p->new,
30923 +                                      au_h_iptr(inode, bindex)->i_ino, ino);
30924 +               if (unlikely(err))
30925 +                       goto out_pair;
30926 +       }
30927 +
30928 +       for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
30929 +               br = au_sbr(sb, bindex);
30930 +               if (br->br_xino.xi_file)
30931 +                       fput(br->br_xino.xi_file);
30932 +               get_file(p->new);
30933 +               br->br_xino.xi_file = p->new;
30934 +       }
30935 +
30936 +out_pair:
30937 +       for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
30938 +               if (p->new)
30939 +                       fput(p->new);
30940 +               else
30941 +                       break;
30942 +       kfree(fpair);
30943 +out:
30944 +       return err;
30945 +}
30946 +
30947 +void au_xino_clr(struct super_block *sb)
30948 +{
30949 +       struct au_sbinfo *sbinfo;
30950 +
30951 +       au_xigen_clr(sb);
30952 +       xino_clear_xib(sb);
30953 +       xino_clear_br(sb);
30954 +       sbinfo = au_sbi(sb);
30955 +       /* lvalue, do not call au_mntflags() */
30956 +       au_opt_clr(sbinfo->si_mntflags, XINO);
30957 +}
30958 +
30959 +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
30960 +{
30961 +       int err, skip;
30962 +       struct dentry *parent, *cur_parent;
30963 +       struct qstr *dname, *cur_name;
30964 +       struct file *cur_xino;
30965 +       struct inode *dir;
30966 +       struct au_sbinfo *sbinfo;
30967 +
30968 +       SiMustWriteLock(sb);
30969 +
30970 +       err = 0;
30971 +       sbinfo = au_sbi(sb);
30972 +       parent = dget_parent(xino->file->f_dentry);
30973 +       if (remount) {
30974 +               skip = 0;
30975 +               dname = &xino->file->f_dentry->d_name;
30976 +               cur_xino = sbinfo->si_xib;
30977 +               if (cur_xino) {
30978 +                       cur_parent = dget_parent(cur_xino->f_dentry);
30979 +                       cur_name = &cur_xino->f_dentry->d_name;
30980 +                       skip = (cur_parent == parent
30981 +                               && dname->len == cur_name->len
30982 +                               && !memcmp(dname->name, cur_name->name,
30983 +                                          dname->len));
30984 +                       dput(cur_parent);
30985 +               }
30986 +               if (skip)
30987 +                       goto out;
30988 +       }
30989 +
30990 +       au_opt_set(sbinfo->si_mntflags, XINO);
30991 +       dir = parent->d_inode;
30992 +       mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
30993 +       /* mnt_want_write() is unnecessary here */
30994 +       err = au_xino_set_xib(sb, xino->file);
30995 +       if (!err)
30996 +               err = au_xigen_set(sb, xino->file);
30997 +       if (!err)
30998 +               err = au_xino_set_br(sb, xino->file);
30999 +       mutex_unlock(&dir->i_mutex);
31000 +       if (!err)
31001 +               goto out; /* success */
31002 +
31003 +       /* reset all */
31004 +       AuIOErr("failed creating xino(%d).\n", err);
31005 +
31006 +out:
31007 +       dput(parent);
31008 +       return err;
31009 +}
31010 +
31011 +/* ---------------------------------------------------------------------- */
31012 +
31013 +/*
31014 + * create a xinofile at the default place/path.
31015 + */
31016 +struct file *au_xino_def(struct super_block *sb)
31017 +{
31018 +       struct file *file;
31019 +       char *page, *p;
31020 +       struct au_branch *br;
31021 +       struct super_block *h_sb;
31022 +       struct path path;
31023 +       aufs_bindex_t bend, bindex, bwr;
31024 +
31025 +       br = NULL;
31026 +       bend = au_sbend(sb);
31027 +       bwr = -1;
31028 +       for (bindex = 0; bindex <= bend; bindex++) {
31029 +               br = au_sbr(sb, bindex);
31030 +               if (au_br_writable(br->br_perm)
31031 +                   && !au_test_fs_bad_xino(au_br_sb(br))) {
31032 +                       bwr = bindex;
31033 +                       break;
31034 +               }
31035 +       }
31036 +
31037 +       if (bwr >= 0) {
31038 +               file = ERR_PTR(-ENOMEM);
31039 +               page = (void *)__get_free_page(GFP_NOFS);
31040 +               if (unlikely(!page))
31041 +                       goto out;
31042 +               path.mnt = au_br_mnt(br);
31043 +               path.dentry = au_h_dptr(sb->s_root, bwr);
31044 +               p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
31045 +               file = (void *)p;
31046 +               if (!IS_ERR(p)) {
31047 +                       strcat(p, "/" AUFS_XINO_FNAME);
31048 +                       AuDbg("%s\n", p);
31049 +                       file = au_xino_create(sb, p, /*silent*/0);
31050 +                       if (!IS_ERR(file))
31051 +                               au_xino_brid_set(sb, br->br_id);
31052 +               }
31053 +               free_page((unsigned long)page);
31054 +       } else {
31055 +               file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
31056 +               if (IS_ERR(file))
31057 +                       goto out;
31058 +               h_sb = file->f_dentry->d_sb;
31059 +               if (unlikely(au_test_fs_bad_xino(h_sb))) {
31060 +                       pr_err("xino doesn't support %s(%s)\n",
31061 +                              AUFS_XINO_DEFPATH, au_sbtype(h_sb));
31062 +                       fput(file);
31063 +                       file = ERR_PTR(-EINVAL);
31064 +               }
31065 +               if (!IS_ERR(file))
31066 +                       au_xino_brid_set(sb, -1);
31067 +       }
31068 +
31069 +out:
31070 +       return file;
31071 +}
31072 +
31073 +/* ---------------------------------------------------------------------- */
31074 +
31075 +int au_xino_path(struct seq_file *seq, struct file *file)
31076 +{
31077 +       int err;
31078 +
31079 +       err = au_seq_path(seq, &file->f_path);
31080 +       if (unlikely(err < 0))
31081 +               goto out;
31082 +
31083 +       err = 0;
31084 +#define Deleted "\\040(deleted)"
31085 +       seq->count -= sizeof(Deleted) - 1;
31086 +       AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
31087 +                        sizeof(Deleted) - 1));
31088 +#undef Deleted
31089 +
31090 +out:
31091 +       return err;
31092 +}
31093 diff -urN /usr/share/empty/include/linux/aufs_type.h linux/include/linux/aufs_type.h
31094 --- /usr/share/empty/include/linux/aufs_type.h  1970-01-01 01:00:00.000000000 +0100
31095 +++ linux/include/linux/aufs_type.h     2013-07-06 13:20:47.760198800 +0200
31096 @@ -0,0 +1,19 @@
31097 +/*
31098 + * Copyright (C) 2012-2013 Junjiro R. Okajima
31099 + *
31100 + * This program, aufs is free software; you can redistribute it and/or modify
31101 + * it under the terms of the GNU General Public License as published by
31102 + * the Free Software Foundation; either version 2 of the License, or
31103 + * (at your option) any later version.
31104 + *
31105 + * This program is distributed in the hope that it will be useful,
31106 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31107 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31108 + * GNU General Public License for more details.
31109 + *
31110 + * You should have received a copy of the GNU General Public License
31111 + * along with this program; if not, write to the Free Software
31112 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
31113 + */
31114 +
31115 +#include <uapi/linux/aufs_type.h>
31116 diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
31117 --- /usr/share/empty/include/uapi/linux/aufs_type.h     1970-01-01 01:00:00.000000000 +0100
31118 +++ linux/include/uapi/linux/aufs_type.h        2013-07-30 22:42:55.842946719 +0200
31119 @@ -0,0 +1,235 @@
31120 +/*
31121 + * Copyright (C) 2005-2013 Junjiro R. Okajima
31122 + *
31123 + * This program, aufs is free software; you can redistribute it and/or modify
31124 + * it under the terms of the GNU General Public License as published by
31125 + * the Free Software Foundation; either version 2 of the License, or
31126 + * (at your option) any later version.
31127 + *
31128 + * This program is distributed in the hope that it will be useful,
31129 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31130 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31131 + * GNU General Public License for more details.
31132 + *
31133 + * You should have received a copy of the GNU General Public License
31134 + * along with this program; if not, write to the Free Software
31135 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
31136 + */
31137 +
31138 +#ifndef __AUFS_TYPE_H__
31139 +#define __AUFS_TYPE_H__
31140 +
31141 +#define AUFS_NAME      "aufs"
31142 +
31143 +#ifdef __KERNEL__
31144 +/*
31145 + * define it before including all other headers.
31146 + * sched.h may use pr_* macros before defining "current", so define the
31147 + * no-current version first, and re-define later.
31148 + */
31149 +#define pr_fmt(fmt)    AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
31150 +#include <linux/sched.h>
31151 +#undef pr_fmt
31152 +#define pr_fmt(fmt) \
31153 +               AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
31154 +               (int)sizeof(current->comm), current->comm, current->pid
31155 +#else
31156 +#include <stdint.h>
31157 +#include <sys/types.h>
31158 +#endif /* __KERNEL__ */
31159 +
31160 +#include <linux/limits.h>
31161 +
31162 +#define AUFS_VERSION   "3.10-20130722"
31163 +
31164 +/* todo? move this to linux-2.6.19/include/magic.h */
31165 +#define AUFS_SUPER_MAGIC       ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
31166 +
31167 +/* ---------------------------------------------------------------------- */
31168 +
31169 +#ifdef CONFIG_AUFS_BRANCH_MAX_127
31170 +typedef int8_t aufs_bindex_t;
31171 +#define AUFS_BRANCH_MAX 127
31172 +#else
31173 +typedef int16_t aufs_bindex_t;
31174 +#ifdef CONFIG_AUFS_BRANCH_MAX_511
31175 +#define AUFS_BRANCH_MAX 511
31176 +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
31177 +#define AUFS_BRANCH_MAX 1023
31178 +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
31179 +#define AUFS_BRANCH_MAX 32767
31180 +#endif
31181 +#endif
31182 +
31183 +#ifdef __KERNEL__
31184 +#ifndef AUFS_BRANCH_MAX
31185 +#error unknown CONFIG_AUFS_BRANCH_MAX value
31186 +#endif
31187 +#endif /* __KERNEL__ */
31188 +
31189 +/* ---------------------------------------------------------------------- */
31190 +
31191 +#define AUFS_FSTYPE            AUFS_NAME
31192 +
31193 +#define AUFS_ROOT_INO          2
31194 +#define AUFS_FIRST_INO         11
31195 +
31196 +#define AUFS_WH_PFX            ".wh."
31197 +#define AUFS_WH_PFX_LEN                ((int)sizeof(AUFS_WH_PFX) - 1)
31198 +#define AUFS_WH_TMP_LEN                4
31199 +/* a limit for rmdir/rename a dir and copyup */
31200 +#define AUFS_MAX_NAMELEN       (NAME_MAX \
31201 +                               - AUFS_WH_PFX_LEN * 2   /* doubly whiteouted */\
31202 +                               - 1                     /* dot */\
31203 +                               - AUFS_WH_TMP_LEN)      /* hex */
31204 +#define AUFS_XINO_FNAME                "." AUFS_NAME ".xino"
31205 +#define AUFS_XINO_DEFPATH      "/tmp/" AUFS_XINO_FNAME
31206 +#define AUFS_XINO_TRUNC_INIT   64 /* blocks */
31207 +#define AUFS_XINO_TRUNC_STEP   4  /* blocks */
31208 +#define AUFS_DIRWH_DEF         3
31209 +#define AUFS_RDCACHE_DEF       10 /* seconds */
31210 +#define AUFS_RDCACHE_MAX       3600 /* seconds */
31211 +#define AUFS_RDBLK_DEF         512 /* bytes */
31212 +#define AUFS_RDHASH_DEF                32
31213 +#define AUFS_WKQ_NAME          AUFS_NAME "d"
31214 +#define AUFS_MFS_DEF_SEC       30 /* seconds */
31215 +#define AUFS_MFS_MAX_SEC       3600 /* seconds */
31216 +#define AUFS_PLINK_WARN                50 /* number of plinks in a single bucket */
31217 +
31218 +/* pseudo-link maintenace under /proc */
31219 +#define AUFS_PLINK_MAINT_NAME  "plink_maint"
31220 +#define AUFS_PLINK_MAINT_DIR   "fs/" AUFS_NAME
31221 +#define AUFS_PLINK_MAINT_PATH  AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
31222 +
31223 +#define AUFS_DIROPQ_NAME       AUFS_WH_PFX ".opq" /* whiteouted doubly */
31224 +#define AUFS_WH_DIROPQ         AUFS_WH_PFX AUFS_DIROPQ_NAME
31225 +
31226 +#define AUFS_BASE_NAME         AUFS_WH_PFX AUFS_NAME
31227 +#define AUFS_PLINKDIR_NAME     AUFS_WH_PFX "plnk"
31228 +#define AUFS_ORPHDIR_NAME      AUFS_WH_PFX "orph"
31229 +
31230 +/* doubly whiteouted */
31231 +#define AUFS_WH_BASE           AUFS_WH_PFX AUFS_BASE_NAME
31232 +#define AUFS_WH_PLINKDIR       AUFS_WH_PFX AUFS_PLINKDIR_NAME
31233 +#define AUFS_WH_ORPHDIR                AUFS_WH_PFX AUFS_ORPHDIR_NAME
31234 +
31235 +/* branch permissions and attributes */
31236 +#define AUFS_BRPERM_RW         "rw"
31237 +#define AUFS_BRPERM_RO         "ro"
31238 +#define AUFS_BRPERM_RR         "rr"
31239 +#define AUFS_BRRATTR_WH                "wh"
31240 +#define AUFS_BRWATTR_NLWH      "nolwh"
31241 +#define AUFS_BRATTR_UNPIN      "unpin"
31242 +
31243 +/* ---------------------------------------------------------------------- */
31244 +
31245 +/* ioctl */
31246 +enum {
31247 +       /* readdir in userspace */
31248 +       AuCtl_RDU,
31249 +       AuCtl_RDU_INO,
31250 +
31251 +       /* pathconf wrapper */
31252 +       AuCtl_WBR_FD,
31253 +
31254 +       /* busy inode */
31255 +       AuCtl_IBUSY
31256 +};
31257 +
31258 +/* borrowed from linux/include/linux/kernel.h */
31259 +#ifndef ALIGN
31260 +#define ALIGN(x, a)            __ALIGN_MASK(x, (typeof(x))(a)-1)
31261 +#define __ALIGN_MASK(x, mask)  (((x)+(mask))&~(mask))
31262 +#endif
31263 +
31264 +/* borrowed from linux/include/linux/compiler-gcc3.h */
31265 +#ifndef __aligned
31266 +#define __aligned(x)                   __attribute__((aligned(x)))
31267 +#endif
31268 +
31269 +#ifdef __KERNEL__
31270 +#ifndef __packed
31271 +#define __packed                       __attribute__((packed))
31272 +#endif
31273 +#endif
31274 +
31275 +struct au_rdu_cookie {
31276 +       uint64_t        h_pos;
31277 +       int16_t         bindex;
31278 +       uint8_t         flags;
31279 +       uint8_t         pad;
31280 +       uint32_t        generation;
31281 +} __aligned(8);
31282 +
31283 +struct au_rdu_ent {
31284 +       uint64_t        ino;
31285 +       int16_t         bindex;
31286 +       uint8_t         type;
31287 +       uint8_t         nlen;
31288 +       uint8_t         wh;
31289 +       char            name[0];
31290 +} __aligned(8);
31291 +
31292 +static inline int au_rdu_len(int nlen)
31293 +{
31294 +       /* include the terminating NULL */
31295 +       return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
31296 +                    sizeof(uint64_t));
31297 +}
31298 +
31299 +union au_rdu_ent_ul {
31300 +       struct au_rdu_ent __user        *e;
31301 +       uint64_t                        ul;
31302 +};
31303 +
31304 +enum {
31305 +       AufsCtlRduV_SZ,
31306 +       AufsCtlRduV_End
31307 +};
31308 +
31309 +struct aufs_rdu {
31310 +       /* input */
31311 +       union {
31312 +               uint64_t        sz;     /* AuCtl_RDU */
31313 +               uint64_t        nent;   /* AuCtl_RDU_INO */
31314 +       };
31315 +       union au_rdu_ent_ul     ent;
31316 +       uint16_t                verify[AufsCtlRduV_End];
31317 +
31318 +       /* input/output */
31319 +       uint32_t                blk;
31320 +
31321 +       /* output */
31322 +       union au_rdu_ent_ul     tail;
31323 +       /* number of entries which were added in a single call */
31324 +       uint64_t                rent;
31325 +       uint8_t                 full;
31326 +       uint8_t                 shwh;
31327 +
31328 +       struct au_rdu_cookie    cookie;
31329 +} __aligned(8);
31330 +
31331 +/* ---------------------------------------------------------------------- */
31332 +
31333 +struct aufs_wbr_fd {
31334 +       uint32_t        oflags;
31335 +       int16_t         brid;
31336 +} __aligned(8);
31337 +
31338 +/* ---------------------------------------------------------------------- */
31339 +
31340 +struct aufs_ibusy {
31341 +       uint64_t        ino, h_ino;
31342 +       int16_t         bindex;
31343 +} __aligned(8);
31344 +
31345 +/* ---------------------------------------------------------------------- */
31346 +
31347 +#define AuCtlType              'A'
31348 +#define AUFS_CTL_RDU           _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
31349 +#define AUFS_CTL_RDU_INO       _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
31350 +#define AUFS_CTL_WBR_FD                _IOW(AuCtlType, AuCtl_WBR_FD, \
31351 +                                    struct aufs_wbr_fd)
31352 +#define AUFS_CTL_IBUSY         _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
31353 +
31354 +#endif /* __AUFS_TYPE_H__ */
31355
This page took 3.482595 seconds and 3 git commands to generate.