]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs3.patch
- http://vserver.13thfloor.at/Experimental/patch-3.10.9-vs2.3.6.6.diff
[packages/kernel.git] / kernel-aufs3.patch
CommitLineData
367653fa 1aufs3.10 kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
86dc4139 4index c229f82..397b473 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
86dc4139 7@@ -212,6 +212,7 @@ source "fs/ufs/Kconfig"
7f207e10 8 source "fs/exofs/Kconfig"
1716fcea 9 source "fs/f2fs/Kconfig"
c06a8ce3 10 source "fs/efivarfs/Kconfig"
7f207e10
AM
11+source "fs/aufs/Kconfig"
12
13 endif # MISC_FILESYSTEMS
14
15diff --git a/fs/Makefile b/fs/Makefile
86dc4139 16index 4fe6df3..4a57676 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
86dc4139 19@@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules
7f207e10 20 obj-$(CONFIG_CEPH_FS) += ceph/
bf0370f2 21 obj-$(CONFIG_PSTORE) += pstore/
c06a8ce3 22 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
86dc4139 23+obj-$(CONFIG_AUFS_FS) += aufs/
c06a8ce3 24diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
367653fa 25index bdc6e87..349600c 100644
c06a8ce3
AM
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
367653fa 36aufs3.10 base patch
7f207e10 37
537831f9 38diff --git a/fs/file_table.c b/fs/file_table.c
86dc4139 39index 485dc0e..8db8096 100644
537831f9
AM
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;
0c3ec466 51diff --git a/fs/inode.c b/fs/inode.c
86dc4139 52index 00d5fc3..f324521 100644
0c3ec466
AM
53--- a/fs/inode.c
54+++ b/fs/inode.c
c06a8ce3 55@@ -1498,7 +1498,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
0c3ec466
AM
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);
7f207e10 64diff --git a/fs/splice.c b/fs/splice.c
367653fa 65index d37431d..987346f 100644
7f207e10
AM
66--- a/fs/splice.c
67+++ b/fs/splice.c
c06a8ce3 68@@ -1093,8 +1093,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
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);
86dc4139 79@@ -1124,9 +1124,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
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);
0c3ec466 92diff --git a/include/linux/fs.h b/include/linux/fs.h
86dc4139 93index 65c2be2..0148214 100644
0c3ec466
AM
94--- a/include/linux/fs.h
95+++ b/include/linux/fs.h
86dc4139 96@@ -2574,6 +2574,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
0c3ec466
AM
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);
1e00d052 104diff --git a/include/linux/splice.h b/include/linux/splice.h
86dc4139 105index 74575cb..bfc6fb6 100644
1e00d052
AM
106--- a/include/linux/splice.h
107+++ b/include/linux/splice.h
86dc4139 108@@ -92,4 +92,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
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;
1e00d052
AM
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
367653fa 119aufs3.10 standalone patch
7f207e10
AM
120
121diff --git a/fs/file_table.c b/fs/file_table.c
86dc4139 122index 8db8096..e271e28 100644
7f207e10
AM
123--- a/fs/file_table.c
124+++ b/fs/file_table.c
b4510431 125@@ -37,6 +37,7 @@ struct files_stat_struct files_stat = {
0c3ec466
AM
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;
86dc4139 133@@ -405,6 +406,8 @@ void file_sb_list_del(struct file *file)
7f207e10
AM
134 }
135 }
136
137+EXPORT_SYMBOL(file_sb_list_del);
1facf9fc 138+
7f207e10
AM
139 #ifdef CONFIG_SMP
140
141 /*
1e00d052 142diff --git a/fs/inode.c b/fs/inode.c
86dc4139 143index f324521..bff7670 100644
1e00d052
AM
144--- a/fs/inode.c
145+++ b/fs/inode.c
92d182d2 146@@ -56,6 +56,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
4b3da204 147 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
2cbb1c4b
JR
148
149 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
2cbb1c4b 150+EXPORT_SYMBOL(inode_sb_list_lock);
7f207e10
AM
151
152 /*
4b3da204 153 * Empty aops. Can be used for the cases where the user does not
c06a8ce3 154@@ -1514,6 +1515,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
0c3ec466
AM
155 mark_inode_dirty_sync(inode);
156 return 0;
157 }
158+EXPORT_SYMBOL(update_time);
159
160 /**
161 * touch_atime - update the access time
7f207e10 162diff --git a/fs/namespace.c b/fs/namespace.c
86dc4139 163index 7b1ca9b..51db6ad 100644
7f207e10
AM
164--- a/fs/namespace.c
165+++ b/fs/namespace.c
86dc4139 166@@ -54,6 +54,7 @@ EXPORT_SYMBOL_GPL(fs_kobj);
0c3ec466
AM
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 {
86dc4139 174@@ -427,6 +428,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
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
86dc4139 182@@ -1456,6 +1458,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
183 }
184 return 0;
185 }
186+EXPORT_SYMBOL(iterate_mounts);
187
7eafdf33 188 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
189 {
190diff --git a/fs/notify/group.c b/fs/notify/group.c
1716fcea 191index bd2625b..2ff2a0f 100644
7f207e10
AM
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"
1716fcea
AM
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)
7f207e10 211 if (atomic_dec_and_test(&group->refcnt))
1716fcea 212 fsnotify_final_destroy_group(group);
7f207e10
AM
213 }
214+EXPORT_SYMBOL(fsnotify_put_group);
215
216 /*
217 * Create a new fsnotify_group and hold a reference for the group returned.
1716fcea 218@@ -102,6 +105,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
219
220 return group;
221 }
222+EXPORT_SYMBOL(fsnotify_alloc_group);
1716fcea
AM
223
224 int fsnotify_fasync(int fd, struct file *file, int on)
225 {
7f207e10 226diff --git a/fs/notify/mark.c b/fs/notify/mark.c
1716fcea 227index fc6b49b..a6bb87d 100644
7f207e10
AM
228--- a/fs/notify/mark.c
229+++ b/fs/notify/mark.c
1716fcea 230@@ -115,6 +115,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 231 mark->free_mark(mark);
1716fcea 232 }
7f207e10
AM
233 }
234+EXPORT_SYMBOL(fsnotify_put_mark);
235
236 /*
237 * Any time a mark is getting freed we end up here.
1716fcea
AM
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);
7f207e10
AM
241 }
242+EXPORT_SYMBOL(fsnotify_destroy_mark);
243
244 void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
245 {
1716fcea 246@@ -281,6 +283,7 @@ err:
7f207e10
AM
247
248 return ret;
249 }
250+EXPORT_SYMBOL(fsnotify_add_mark);
251
1716fcea
AM
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,
7f207e10
AM
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 {
262diff --git a/fs/open.c b/fs/open.c
86dc4139 263index 8c74100..be563cd 100644
7f207e10
AM
264--- a/fs/open.c
265+++ b/fs/open.c
c06a8ce3 266@@ -61,6 +61,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
7f207e10
AM
267 mutex_unlock(&dentry->d_inode->i_mutex);
268 return ret;
269 }
270+EXPORT_SYMBOL(do_truncate);
271
1716fcea 272 long vfs_truncate(struct path *path, loff_t length)
7f207e10
AM
273 {
274diff --git a/fs/splice.c b/fs/splice.c
367653fa 275index 987346f..8d6a045 100644
7f207e10
AM
276--- a/fs/splice.c
277+++ b/fs/splice.c
86dc4139
AM
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;
7f207e10
AM
281 }
282+EXPORT_SYMBOL(do_splice_from);
283
284 /*
285 * Attempt to initiate a splice from a file to a pipe.
86dc4139 286@@ -1146,6 +1147,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
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
294diff --git a/security/commoncap.c b/security/commoncap.c
c06a8ce3 295index c44b6fe..d78b003 100644
7f207e10
AM
296--- a/security/commoncap.c
297+++ b/security/commoncap.c
1716fcea 298@@ -988,9 +988,11 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 299 }
7f207e10
AM
300 return ret;
301 }
0c3ec466
AM
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);
7f207e10 310diff --git a/security/device_cgroup.c b/security/device_cgroup.c
86dc4139 311index dd0dc57..9760ecb6 100644
7f207e10
AM
312--- a/security/device_cgroup.c
313+++ b/security/device_cgroup.c
f6c5ef8b
AM
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>
86dc4139 322@@ -789,6 +790,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
323 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
324 access);
7f207e10 325 }
2cbb1c4b 326+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
327
328 int devcgroup_inode_mknod(int mode, dev_t dev)
329 {
330diff --git a/security/security.c b/security/security.c
86dc4139 331index a3dce87..06a6ea6 100644
7f207e10
AM
332--- a/security/security.c
333+++ b/security/security.c
537831f9 334@@ -396,6 +396,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10
AM
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 {
537831f9 342@@ -412,6 +413,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10
AM
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)
537831f9 350@@ -420,6 +422,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10
AM
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)
537831f9 358@@ -438,6 +441,7 @@ int security_path_truncate(struct path *path)
7f207e10
AM
359 return 0;
360 return security_ops->path_truncate(path);
361 }
362+EXPORT_SYMBOL(security_path_truncate);
363
7eafdf33
AM
364 int security_path_chmod(struct path *path, umode_t mode)
365 {
537831f9 366@@ -445,6 +449,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 367 return 0;
7eafdf33 368 return security_ops->path_chmod(path, mode);
7f207e10
AM
369 }
370+EXPORT_SYMBOL(security_path_chmod);
371
537831f9 372 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 373 {
537831f9 374@@ -452,6 +457,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10
AM
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 {
537831f9 382@@ -528,6 +534,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10
AM
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 {
537831f9 390@@ -542,6 +549,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 391 return 0;
1e00d052 392 return security_ops->inode_permission(inode, mask);
7f207e10
AM
393 }
394+EXPORT_SYMBOL(security_inode_permission);
395
1e00d052 396 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 397 {
537831f9 398@@ -663,6 +671,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
399
400 return fsnotify_perm(file, mask);
401 }
402+EXPORT_SYMBOL(security_file_permission);
403
404 int security_file_alloc(struct file *file)
405 {
537831f9 406@@ -723,6 +732,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
407 return ret;
408 return ima_file_mmap(file, prot);
409 }
0c3ec466 410+EXPORT_SYMBOL(security_mmap_file);
7f207e10 411
0c3ec466
AM
412 int security_mmap_addr(unsigned long addr)
413 {
7f207e10
AM
414diff -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
86dc4139
AM
416+++ linux/Documentation/ABI/testing/debugfs-aufs 2013-07-06 13:20:47.716863966 +0200
417@@ -0,0 +1,50 @@
7f207e10
AM
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.
1facf9fc 425+
86dc4139
AM
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+
7f207e10
AM
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.
468diff -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
86dc4139 470+++ linux/Documentation/ABI/testing/sysfs-aufs 2013-07-06 13:20:47.730197761 +0200
7f207e10
AM
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.
53392da6
AM
496diff -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
86dc4139 498+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
499@@ -0,0 +1,162 @@
500+
7a9e40b8 501+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
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.
662diff -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
86dc4139 664+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
665@@ -0,0 +1,226 @@
666+
7a9e40b8 667+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
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.
892diff -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
86dc4139 894+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
895@@ -0,0 +1,106 @@
896+
7a9e40b8 897+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
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).
1002diff -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
86dc4139 1004+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
1005@@ -0,0 +1,76 @@
1006+
7a9e40b8 1007+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
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.
1082diff -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
86dc4139 1084+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
1085@@ -0,0 +1,65 @@
1086+
7a9e40b8 1087+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
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.
1151diff -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
86dc4139 1153+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2013-07-06 13:20:47.730197761 +0200
53392da6
AM
1154@@ -0,0 +1,47 @@
1155+
7a9e40b8 1156+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
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.
1202diff -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
86dc4139 1204+++ linux/Documentation/filesystems/aufs/design/07export.txt 2013-07-06 13:20:47.736864659 +0200
53392da6
AM
1205@@ -0,0 +1,59 @@
1206+
7a9e40b8 1207+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
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.
1265diff -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
86dc4139 1267+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2013-07-06 13:20:47.736864659 +0200
53392da6
AM
1268@@ -0,0 +1,53 @@
1269+
7a9e40b8 1270+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
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.
1322diff -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
86dc4139 1324+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2013-07-06 13:20:47.736864659 +0200
53392da6
AM
1325@@ -0,0 +1,47 @@
1326+
7a9e40b8 1327+# Copyright (C) 2010-2013 Junjiro R. Okajima
53392da6
AM
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.
1373diff -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
86dc4139 1375+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2013-07-06 13:20:47.736864659 +0200
53392da6
AM
1376@@ -0,0 +1,96 @@
1377+
7a9e40b8 1378+# Copyright (C) 2005-2013 Junjiro R. Okajima
53392da6
AM
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.
1473diff -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
367653fa
AM
1475+++ linux/Documentation/filesystems/aufs/README 2013-07-30 22:42:46.229279157 +0200
1476@@ -0,0 +1,346 @@
53392da6
AM
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+----------------------------------------
1e00d052
AM
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
b4510431 1582+build aufs3 as an external kernel module.
1e00d052
AM
1583+
1584+On the other hand, the aufs3-standalone tree has only aufs source files
53392da6
AM
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,
1e00d052
AM
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 \
86dc4139 1594+ git://git.code.sf.net/p/aufs/aufs3-linux aufs-aufs3-linux \
1e00d052
AM
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
53392da6
AM
1599+
1600+o aufs3-standalone tree
86dc4139 1601+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
53392da6
AM
1602+ aufs3-standalone.git
1603+$ cd aufs3-standalone.git
1604+$ git checkout origin/aufs3.0
1605+
1606+o aufs-util tree
86dc4139 1607+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
53392da6
AM
1608+ aufs-util.git
1609+$ cd aufs-util.git
1610+$ git checkout origin/aufs3.0
1611+
9dbd164d
AM
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
53392da6 1622+nearest lower number.
9dbd164d
AM
1623+
1624+For (an unreleased) example:
1625+If you are using "linux-3.10" and the "aufs3.10" branch
7eafdf33 1626+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
9dbd164d
AM
1627+or something numerically smaller is the branch for your kernel.
1628+
53392da6
AM
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+
1e00d052 1637+For aufs3-linux tree,
c06a8ce3 1638+- enable CONFIG_AUFS_FS.
1e00d052
AM
1639+- set other aufs configurations if necessary.
1640+
53392da6
AM
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.
537831f9
AM
1652+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
1653+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 1654+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
1655+ =m or =y.
1656+- and build your kernel as usual.
1657+- install the built kernel.
c06a8ce3
AM
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.
7eafdf33
AM
1661+- install the header files too by "make headers_install" to the
1662+ directory where you specify. By default, it is $PWD/usr.
b4510431 1663+ "make help" shows a brief note for headers_install.
53392da6
AM
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.
b4510431 1675+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
1676+ every aufs configurations.
1677+- build the module by simple "make".
c06a8ce3
AM
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.
53392da6
AM
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
b4510431
AM
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.
53392da6
AM
1691+- no need to apply aufs3-kbuild.patch, nor copying source files to your
1692+ kernel source tree.
1693+
b4510431 1694+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
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
9dbd164d
AM
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."
53392da6
AM
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
b4510431 1778+ appreciate.
53392da6
AM
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).
537831f9
AM
1796+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
1797+11).
1e00d052 1798+Sam Liddicott made a donation (2011/9).
86dc4139
AM
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).
367653fa 1805+pemasu from Finland made a donation (2013/7).
53392da6
AM
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: ;
7f207e10
AM
1823diff -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
86dc4139 1825+++ linux/fs/aufs/aufs.h 2013-07-06 13:20:47.736864659 +0200
2cbb1c4b 1826@@ -0,0 +1,60 @@
7f207e10 1827+/*
7a9e40b8 1828+ * Copyright (C) 2005-2013 Junjiro R. Okajima
7f207e10
AM
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"
7f207e10
AM
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__ */
1887diff -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
367653fa 1889+++ linux/fs/aufs/branch.c 2013-07-30 22:42:55.839613269 +0200
86dc4139 1890@@ -0,0 +1,1213 @@
7f207e10 1891+/*
7a9e40b8 1892+ * Copyright (C) 2005-2013 Junjiro R. Okajima
7f207e10
AM
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+
027c5e7a 1913+#include <linux/compat.h>
7f207e10
AM
1914+#include <linux/statfs.h>
1915+#include "aufs.h"
1916+
1917+/*
1918+ * free a single branch
1facf9fc 1919+ */
86dc4139
AM
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+
1facf9fc 1948+static void au_br_do_free(struct au_branch *br)
1949+{
1950+ int i;
1951+ struct au_wbr *wbr;
4a4d8108 1952+ struct au_dykey **key;
1facf9fc 1953+
027c5e7a
AM
1954+ au_hnotify_fin_br(br);
1955+
1facf9fc 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));
dece6358 1967+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 1968+ }
1969+
4a4d8108
AM
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+
86dc4139
AM
1977+ au_br_dflags_restore(br);
1978+
537831f9
AM
1979+ /* recursive lock, s_umount of branch's */
1980+ lockdep_off();
86dc4139 1981+ path_put(&br->br_path);
537831f9 1982+ lockdep_on();
1facf9fc 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+
dece6358
AM
1995+ AuRwMustWriteLock(&sbinfo->si_rwsem);
1996+
1facf9fc 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+
b752ccd1
AM
2023+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2024+ struct dentry *h_root)
1facf9fc 2025+{
b752ccd1
AM
2026+ if (unlikely(h_adding == h_root
2027+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 2028+ return 1;
b752ccd1
AM
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);
1facf9fc 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;
4a4d8108 2044+ int err;
1facf9fc 2045+
4a4d8108 2046+ err = -ENOMEM;
1facf9fc 2047+ root = sb->s_root;
2048+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2049+ if (unlikely(!add_branch))
2050+ goto out;
2051+
027c5e7a
AM
2052+ err = au_hnotify_init_br(add_branch, perm);
2053+ if (unlikely(err))
2054+ goto out_br;
2055+
1facf9fc 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))
027c5e7a 2062+ goto out_hnotify;
1facf9fc 2063+ }
2064+
4a4d8108
AM
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 */
1facf9fc 2072+
1facf9fc 2073+ kfree(add_branch->br_wbr);
4a4d8108 2074+
027c5e7a
AM
2075+out_hnotify:
2076+ au_hnotify_fin_br(add_branch);
4f0767ce 2077+out_br:
1facf9fc 2078+ kfree(add_branch);
4f0767ce 2079+out:
4a4d8108 2080+ return ERR_PTR(err);
1facf9fc 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+
4a4d8108
AM
2090+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2091+ if (!err)
2092+ goto out;
1facf9fc 2093+
4a4d8108
AM
2094+ err = -EINVAL;
2095+ pr_err("write permission for readonly mount or inode, %s\n", path);
2096+
4f0767ce 2097+out:
1facf9fc 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;
4a4d8108 2121+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2122+ }
2123+ goto out;
2124+ }
2125+
2126+ err = -ENOSPC; /* -E2BIG; */
2127+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2128+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2129+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2130+ goto out;
2131+ }
2132+
2133+ err = -EDOM;
2134+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2135+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2136+ goto out;
2137+ }
2138+
2139+ inode = add->path.dentry->d_inode;
2140+ err = -ENOENT;
2141+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2142+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2143+ goto out;
2144+ }
2145+
2146+ err = -EINVAL;
2147+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2148+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2149+ goto out;
2150+ }
2151+
2152+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2153+ pr_err("unsupported filesystem, %s (%s)\n",
2154+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 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)))) {
4a4d8108 2169+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 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)
0c3ec466
AM
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));
1facf9fc 2185+ }
2186+
4f0767ce 2187+out:
1facf9fc 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,
86dc4139 2195+ int new_perm)
1facf9fc 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+
86dc4139
AM
2203+ err = vfsub_mnt_want_write(au_br_mnt(br));
2204+ if (unlikely(err))
2205+ goto out;
2206+
1facf9fc 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);
4a4d8108 2215+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 2216+ } else {
86dc4139 2217+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
1facf9fc 2218+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2219+ }
2220+ if (!wbr)
86dc4139 2221+ err = au_wh_init(br, sb);
1facf9fc 2222+ else {
2223+ wbr_wh_write_lock(wbr);
86dc4139 2224+ err = au_wh_init(br, sb);
1facf9fc 2225+ wbr_wh_write_unlock(wbr);
2226+ }
2227+ if (hdir)
4a4d8108 2228+ au_hn_imtx_unlock(hdir);
1facf9fc 2229+ else
2230+ mutex_unlock(h_mtx);
86dc4139 2231+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 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+
86dc4139 2239+out:
1facf9fc 2240+ return err;
2241+}
2242+
2243+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 2244+ int perm)
1facf9fc 2245+{
2246+ int err;
4a4d8108 2247+ struct kstatfs kst;
1facf9fc 2248+ struct au_wbr *wbr;
2249+
2250+ wbr = br->br_wbr;
dece6358 2251+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 2252+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2253+ atomic_set(&wbr->wbr_wh_running, 0);
2254+ wbr->wbr_bytes = 0;
2255+
4a4d8108
AM
2256+ /*
2257+ * a limit for rmdir/rename a dir
2258+ * cf. AUFS_MAX_NAMELEN in include/linux/aufs_type.h
2259+ */
86dc4139 2260+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
2261+ if (unlikely(err))
2262+ goto out;
2263+ err = -EINVAL;
2264+ if (kst.f_namelen >= NAME_MAX)
86dc4139 2265+ err = au_br_init_wh(sb, br, perm);
4a4d8108
AM
2266+ else
2267+ pr_err("%.*s(%s), unsupported namelen %ld\n",
86dc4139
AM
2268+ AuDLNPair(au_br_dentry(br)),
2269+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 2270+
4f0767ce 2271+out:
1facf9fc 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;
86dc4139
AM
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 */
4a4d8108
AM
2289+ spin_lock_init(&br->br_dykey_lock);
2290+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 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);
7f207e10 2295+ AuDebugOn(br->br_id < 0);
1facf9fc 2296+
2297+ if (au_br_writable(add->perm)) {
86dc4139 2298+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 2299+ if (unlikely(err))
b752ccd1 2300+ goto out_err;
1facf9fc 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);
b752ccd1 2308+ goto out_err;
1facf9fc 2309+ }
2310+ }
2311+
2312+ sysaufs_br_init(br);
86dc4139 2313+ path_get(&br->br_path);
b752ccd1 2314+ goto out; /* success */
1facf9fc 2315+
4f0767ce 2316+out_err:
86dc4139 2317+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 2318+out:
1facf9fc 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+
dece6358
AM
2328+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2329+
1facf9fc 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+
1308ab2a 2343+ AuRwMustWriteLock(&dinfo->di_rwsem);
2344+
1facf9fc 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+
1308ab2a 2358+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2359+
1facf9fc 2360+ hip = iinfo->ii_hinode + bindex;
2361+ memmove(hip + 1, hip, sizeof(*hip) * amount);
2362+ hip->hi_inode = NULL;
4a4d8108 2363+ au_hn_init(hip);
1facf9fc 2364+ iinfo->ii_bend++;
2365+ if (unlikely(bend < 0))
2366+ iinfo->ii_bstart = 0;
2367+}
2368+
86dc4139
AM
2369+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
2370+ aufs_bindex_t bindex)
1facf9fc 2371+{
86dc4139 2372+ struct dentry *root, *h_dentry;
1facf9fc 2373+ struct inode *root_inode;
2374+ aufs_bindex_t bend, amount;
2375+
86dc4139
AM
2376+ au_br_dflags_force(br);
2377+
1facf9fc 2378+ root = sb->s_root;
2379+ root_inode = root->d_inode;
1facf9fc 2380+ bend = au_sbend(sb);
2381+ amount = bend + 1 - bindex;
86dc4139 2382+ h_dentry = au_br_dentry(br);
53392da6 2383+ au_sbilist_lock();
1facf9fc 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);
53392da6 2390+ au_sbilist_unlock();
1facf9fc 2391+}
2392+
2393+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
2394+{
2395+ int err;
1facf9fc 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;
1facf9fc 2425+ if (!remount)
86dc4139 2426+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 2427+ else {
2428+ sysaufs_brs_del(sb, add_bindex);
86dc4139 2429+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 2430+ sysaufs_brs_add(sb, add_bindex);
2431+ }
2432+
86dc4139 2433+ h_dentry = add->path.dentry;
1308ab2a 2434+ if (!add_bindex) {
1facf9fc 2435+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 2436+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
2437+ } else
1facf9fc 2438+ au_add_nlink(root_inode, h_dentry->d_inode);
1facf9fc 2439+
2440+ /*
4a4d8108 2441+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 2442+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 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+
4f0767ce 2452+out:
1facf9fc 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 */
4a4d8108 2463+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 2464+ if (do_info) \
4a4d8108 2465+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 2466+} while (0)
2467+
027c5e7a
AM
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+
1facf9fc 2480+/*
2481+ * test if the branch is deletable or not.
2482+ */
2483+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 2484+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2485+{
2486+ int err, i, j, ndentry;
2487+ aufs_bindex_t bstart, bend;
1facf9fc 2488+ struct au_dcsub_pages dpages;
2489+ struct au_dpage *dpage;
2490+ struct dentry *d;
1facf9fc 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+
1facf9fc 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];
027c5e7a
AM
2504+ AuDebugOn(!d->d_count);
2505+ if (!au_digen_test(d, sigen)) {
1facf9fc 2506+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
2507+ if (unlikely(au_dbrange_test(d))) {
2508+ di_read_unlock(d, AuLock_IR);
2509+ continue;
2510+ }
2511+ } else {
1facf9fc 2512+ di_write_lock_child(d);
027c5e7a
AM
2513+ if (unlikely(au_dbrange_test(d))) {
2514+ di_write_unlock(d);
2515+ continue;
2516+ }
1facf9fc 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+
027c5e7a 2526+ /* AuDbgDentry(d); */
1facf9fc 2527+ bstart = au_dbstart(d);
2528+ bend = au_dbend(d);
2529+ if (bstart <= bindex
2530+ && bindex <= bend
2531+ && au_h_dptr(d, bindex)
027c5e7a 2532+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 2533+ err = -EBUSY;
2534+ AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d));
027c5e7a 2535+ AuDbgDentry(d);
1facf9fc 2536+ }
2537+ di_read_unlock(d, AuLock_IR);
2538+ }
2539+ }
2540+
4f0767ce 2541+out_dpages:
1facf9fc 2542+ au_dpages_free(&dpages);
4f0767ce 2543+out:
1facf9fc 2544+ return err;
2545+}
2546+
2547+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 2548+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2549+{
2550+ int err;
7f207e10
AM
2551+ unsigned long long max, ull;
2552+ struct inode *i, **array;
1facf9fc 2553+ aufs_bindex_t bstart, bend;
1facf9fc 2554+
7f207e10
AM
2555+ array = au_iarray_alloc(sb, &max);
2556+ err = PTR_ERR(array);
2557+ if (IS_ERR(array))
2558+ goto out;
2559+
1facf9fc 2560+ err = 0;
7f207e10
AM
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)
1facf9fc 2565+ continue;
2566+
7f207e10 2567+ /* AuDbgInode(i); */
537831f9 2568+ if (au_iigen(i, NULL) == sigen)
1facf9fc 2569+ ii_read_lock_child(i);
2570+ else {
2571+ ii_write_lock_child(i);
027c5e7a
AM
2572+ err = au_refresh_hinode_self(i);
2573+ au_iigen_dec(i);
1facf9fc 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)
027c5e7a 2587+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 2588+ err = -EBUSY;
2589+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 2590+ AuDbgInode(i);
1facf9fc 2591+ }
2592+ ii_read_unlock(i);
2593+ }
7f207e10 2594+ au_iarray_free(array, max);
1facf9fc 2595+
7f207e10 2596+out:
1facf9fc 2597+ return err;
2598+}
2599+
b752ccd1
AM
2600+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
2601+ const unsigned int verbose)
1facf9fc 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);
b752ccd1 2610+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 2611+ if (!err)
b752ccd1 2612+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 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+
dece6358
AM
2624+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2625+
1facf9fc 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+
53392da6 2632+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2633+ if (p)
2634+ sbinfo->si_branch = p;
4a4d8108 2635+ /* harmless error */
1facf9fc 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+
1308ab2a 2643+ AuRwMustWriteLock(&dinfo->di_rwsem);
2644+
4a4d8108 2645+ hdp = dinfo->di_hdentry;
1facf9fc 2646+ if (bindex < bend)
4a4d8108
AM
2647+ memmove(hdp + bindex, hdp + bindex + 1,
2648+ sizeof(*hdp) * (bend - bindex));
2649+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 2650+ dinfo->di_bend--;
2651+
53392da6 2652+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2653+ if (p)
2654+ dinfo->di_hdentry = p;
4a4d8108 2655+ /* harmless error */
1facf9fc 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+
1308ab2a 2663+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2664+
1facf9fc 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;
4a4d8108 2669+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 2670+ iinfo->ii_bend--;
2671+
53392da6 2672+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 2673+ if (p)
2674+ iinfo->ii_hinode = p;
4a4d8108 2675+ /* harmless error */
1facf9fc 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;
53392da6
AM
2683+ struct dentry *root, *h_root;
2684+ struct inode *inode, *h_inode;
2685+ struct au_hinode *hinode;
1facf9fc 2686+
dece6358
AM
2687+ SiMustWriteLock(sb);
2688+
1facf9fc 2689+ root = sb->s_root;
2690+ inode = root->d_inode;
1facf9fc 2691+ sbinfo = au_sbi(sb);
2692+ bend = sbinfo->si_bend;
2693+
53392da6
AM
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);
1facf9fc 2698+
53392da6 2699+ au_sbilist_lock();
1facf9fc 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);
53392da6
AM
2703+ au_sbilist_unlock();
2704+
2705+ dput(h_root);
2706+ iput(h_inode);
2707+ au_br_do_free(br);
1facf9fc 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;
4a4d8108 2725+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 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);
86dc4139 2739+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
1facf9fc 2740+ i = atomic_read(&br->br_count);
2741+ if (unlikely(i)) {
2742+ AuVerbose(verbose, "%d file(s) opened\n", i);
e49829fe 2743+ goto out;
1facf9fc 2744+ }
2745+
2746+ wbr = br->br_wbr;
2747+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
2748+ if (do_wh) {
1308ab2a 2749+ /* instead of WbrWhMustWriteLock(wbr) */
2750+ SiMustWriteLock(sb);
1facf9fc 2751+ for (i = 0; i < AuBrWh_Last; i++) {
2752+ dput(wbr->wbr_wh[i]);
2753+ wbr->wbr_wh[i] = NULL;
2754+ }
2755+ }
2756+
b752ccd1 2757+ err = test_children_busy(sb->s_root, bindex, verbose);
1facf9fc 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+
1308ab2a 2774+ if (!bindex) {
1facf9fc 2775+ au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
1308ab2a 2776+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
2777+ } else
1facf9fc 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+
b752ccd1 2782+ if (au_xino_brid(sb) == br_id)
1facf9fc 2783+ au_xino_brid_set(sb, -1);
2784+ goto out; /* success */
2785+
4f0767ce 2786+out_wh:
1facf9fc 2787+ /* revert */
86dc4139 2788+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 2789+ if (rerr)
0c3ec466
AM
2790+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
2791+ del->pathname, rerr);
4f0767ce 2792+out:
1facf9fc 2793+ return err;
2794+}
2795+
2796+/* ---------------------------------------------------------------------- */
2797+
027c5e7a
AM
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+
1facf9fc 2869+/*
2870+ * change a branch permission
2871+ */
2872+
dece6358
AM
2873+static void au_warn_ima(void)
2874+{
2875+#ifdef CONFIG_IMA
1308ab2a 2876+ /* since it doesn't support mark_files_ro() */
027c5e7a 2877+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
2878+#endif
2879+}
2880+
1facf9fc 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+
7f207e10
AM
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;
0c3ec466 2902+ lg_global_lock(&files_lglock);
7f207e10
AM
2903+ do_file_list_for_each_entry(sb, f) {
2904+ if (au_fi(f)
027c5e7a 2905+ && file_count(f)
c06a8ce3 2906+ && !special_file(file_inode(f)->i_mode)) {
7f207e10
AM
2907+ get_file(f);
2908+ *p++ = f;
2909+ n++;
2910+ AuDebugOn(n > max);
2911+ }
2912+ } while_file_list_for_each_entry;
0c3ec466 2913+ lg_global_unlock(&files_lglock);
7f207e10
AM
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+
1facf9fc 2935+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
2936+{
7f207e10 2937+ int err, do_warn;
027c5e7a 2938+ unsigned int mnt_flags;
7f207e10 2939+ unsigned long long ull, max;
e49829fe 2940+ aufs_bindex_t br_id;
027c5e7a 2941+ unsigned char verbose;
7f207e10 2942+ struct file *file, *hf, **array;
e49829fe
JR
2943+ struct inode *inode;
2944+ struct au_hfile *hfile;
1facf9fc 2945+
027c5e7a
AM
2946+ mnt_flags = au_mntflags(sb);
2947+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
2948+
7f207e10
AM
2949+ array = au_farray_alloc(sb, &max);
2950+ err = PTR_ERR(array);
2951+ if (IS_ERR(array))
1facf9fc 2952+ goto out;
2953+
7f207e10 2954+ do_warn = 0;
e49829fe 2955+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
2956+ for (ull = 0; ull < max; ull++) {
2957+ file = array[ull];
1facf9fc 2958+
7f207e10 2959+ /* AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); */
1facf9fc 2960+ fi_read_lock(file);
2961+ if (unlikely(au_test_mmapped(file))) {
2962+ err = -EBUSY;
027c5e7a
AM
2963+ AuVerbose(verbose, "mmapped %.*s\n",
2964+ AuDLNPair(file->f_dentry));
7f207e10 2965+ AuDbgFile(file);
1facf9fc 2966+ FiMustNoWaiters(file);
2967+ fi_read_unlock(file);
7f207e10 2968+ goto out_array;
1facf9fc 2969+ }
2970+
c06a8ce3 2971+ inode = file_inode(file);
e49829fe
JR
2972+ hfile = &au_fi(file)->fi_htop;
2973+ hf = hfile->hf_file;
2974+ if (!S_ISREG(inode->i_mode)
1facf9fc 2975+ || !(file->f_mode & FMODE_WRITE)
e49829fe 2976+ || hfile->hf_br->br_id != br_id
7f207e10
AM
2977+ || !(hf->f_mode & FMODE_WRITE))
2978+ array[ull] = NULL;
2979+ else {
2980+ do_warn = 1;
2981+ get_file(file);
1facf9fc 2982+ }
2983+
1facf9fc 2984+ FiMustNoWaiters(file);
2985+ fi_read_unlock(file);
7f207e10
AM
2986+ fput(file);
2987+ }
1facf9fc 2988+
2989+ err = 0;
7f207e10 2990+ if (do_warn)
dece6358 2991+ au_warn_ima();
7f207e10
AM
2992+
2993+ for (ull = 0; ull < max; ull++) {
2994+ file = array[ull];
2995+ if (!file)
2996+ continue;
2997+
1facf9fc 2998+ /* todo: already flushed? */
2999+ /* cf. fs/super.c:mark_files_ro() */
7f207e10
AM
3000+ /* fi_read_lock(file); */
3001+ hfile = &au_fi(file)->fi_htop;
3002+ hf = hfile->hf_file;
3003+ /* fi_read_unlock(file); */
027c5e7a 3004+ spin_lock(&hf->f_lock);
1facf9fc 3005+ hf->f_mode &= ~FMODE_WRITE;
027c5e7a 3006+ spin_unlock(&hf->f_lock);
1facf9fc 3007+ if (!file_check_writeable(hf)) {
c06a8ce3 3008+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 3009+ file_release_write(hf);
1facf9fc 3010+ }
3011+ }
3012+
7f207e10
AM
3013+out_array:
3014+ au_farray_free(array, max);
4f0767ce 3015+out:
7f207e10 3016+ AuTraceErr(err);
1facf9fc 3017+ return err;
3018+}
3019+
3020+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3021+ int *do_refresh)
1facf9fc 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;
1facf9fc 3029+ bindex = au_find_dbindex(root, mod->h_root);
3030+ if (bindex < 0) {
3031+ if (remount)
3032+ return 0; /* success */
3033+ err = -ENOENT;
4a4d8108 3034+ pr_err("%s no such branch\n", mod->path);
1facf9fc 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);
86dc4139 3044+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 3045+ if (br->br_perm == mod->perm)
3046+ return 0; /* success */
3047+
3048+ if (au_br_writable(br->br_perm)) {
3049+ /* remove whiteout base */
86dc4139 3050+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 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);
86dc4139
AM
3067+ if (br->br_wbr)
3068+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 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) {
86dc4139 3081+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 3082+ if (unlikely(err)) {
3083+ kfree(br->br_wbr);
3084+ br->br_wbr = NULL;
3085+ }
3086+ }
3087+ }
3088+
3089+ if (!err) {
86dc4139
AM
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);
7f207e10 3096+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
1facf9fc 3097+ br->br_perm = mod->perm;
3098+ }
3099+
4f0767ce 3100+out:
7f207e10 3101+ AuTraceErr(err);
1facf9fc 3102+ return err;
3103+}
7f207e10
AM
3104diff -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
86dc4139
AM
3106+++ linux/fs/aufs/branch.h 2013-07-06 13:20:47.740198107 +0200
3107@@ -0,0 +1,255 @@
1facf9fc 3108+/*
7a9e40b8 3109+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
1facf9fc 3135+#include <linux/mount.h>
4a4d8108 3136+#include "dynop.h"
1facf9fc 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 {
dece6358 3157+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 3158+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 3159+ atomic_t wbr_wh_running;
1facf9fc 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+
4a4d8108
AM
3168+/* ext2 has 3 types of operations at least, ext3 has 4 */
3169+#define AuBrDynOp (AuDyLast * 4)
3170+
1716fcea
AM
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+
1facf9fc 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;
86dc4139
AM
3185+ unsigned int br_dflags;
3186+ struct path br_path;
4a4d8108
AM
3187+ spinlock_t br_dykey_lock;
3188+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 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+
027c5e7a 3197+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 3198+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
3199+#endif
3200+
1facf9fc 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+
86dc4139
AM
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+
1e00d052
AM
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)
1facf9fc 3230+
1e00d052 3231+#define AuBrRAttr_WH (1 << 3) /* whiteout-able */
1facf9fc 3232+
1e00d052 3233+#define AuBrWAttr_NoLinkWH (1 << 4) /* un-hardlinkable whiteouts */
1facf9fc 3234+
86dc4139
AM
3235+#define AuBrAttr_UNPIN (1 << 5) /* rename-able top dir of
3236+ branch */
3237+
1facf9fc 3238+static inline int au_br_writable(int brperm)
3239+{
1e00d052 3240+ return brperm & AuBrPerm_RW;
1facf9fc 3241+}
3242+
3243+static inline int au_br_whable(int brperm)
3244+{
1e00d052
AM
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);
1facf9fc 3251+}
3252+
3253+static inline int au_br_rdonly(struct au_branch *br)
3254+{
86dc4139 3255+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 3256+ || !au_br_writable(br->br_perm))
3257+ ? -EROFS : 0;
3258+}
3259+
4a4d8108 3260+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 3261+{
4a4d8108 3262+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 3263+ return !(brperm & AuBrPerm_RR);
1facf9fc 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);
027c5e7a
AM
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
1facf9fc 3283+struct au_opt_mod;
3284+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3285+ int *do_refresh);
1facf9fc 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);
b752ccd1 3298+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 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+{
86dc4139 3325+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 3326+}
3327+
3328+static inline
3329+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
3330+{
86dc4139 3331+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 3332+}
3333+
3334+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
3335+{
e49829fe 3336+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 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+
dece6358
AM
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+
1facf9fc 3361+#endif /* __KERNEL__ */
3362+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
3363diff -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
86dc4139 3365+++ linux/fs/aufs/conf.mk 2013-07-06 13:20:47.740198107 +0200
2cbb1c4b 3366@@ -0,0 +1,38 @@
4a4d8108
AM
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+
b752ccd1 3376+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 3377+ SBILIST \
7f207e10 3378+ HNOTIFY HFSNOTIFY \
4a4d8108
AM
3379+ EXPORT INO_T_64 \
3380+ RDU \
2cbb1c4b 3381+ PROC_MAP \
4a4d8108
AM
3382+ SP_IATTR \
3383+ SHWH \
3384+ BR_RAMFS \
3385+ BR_FUSE POLL \
3386+ BR_HFSPLUS \
3387+ BDEV_LOOP \
b752ccd1
AM
3388+ DEBUG MAGIC_SYSRQ
3389+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
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}
b752ccd1
AM
3403+
3404+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
3405diff -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
367653fa
AM
3407+++ linux/fs/aufs/cpup.c 2013-07-30 22:42:46.232612606 +0200
3408@@ -0,0 +1,1247 @@
1facf9fc 3409+/*
7a9e40b8 3410+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 3425+ */
3426+
3427+/*
3428+ * copy-up functions, see wbr_policy.c for copy-down
3429+ */
3430+
3431+#include <linux/fs_stack.h>
dece6358 3432+#include <linux/mm.h>
1facf9fc 3433+#include "aufs.h"
3434+
86dc4139 3435+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 3436+{
3437+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 3438+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 3439+
86dc4139
AM
3440+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
3441+
3442+ dst->i_flags |= iflags & ~mask;
1facf9fc 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);
4a4d8108 3453+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 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+
7eafdf33
AM
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+ */
92d182d2 3476+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 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);
86dc4139 3501+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 3502+}
3503+
3504+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
3505+{
3506+ struct au_iinfo *iinfo = au_ii(inode);
3507+
1308ab2a 3508+ IiMustWriteLock(inode);
3509+
1facf9fc 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))
0c3ec466 3557+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 3558+}
3559+
3560+/* ---------------------------------------------------------------------- */
3561+
86dc4139
AM
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+
1facf9fc 3569+static noinline_for_stack
86dc4139
AM
3570+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
3571+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 3572+{
3573+ int err, sbits;
3574+ struct iattr ia;
3575+ struct path h_path;
1308ab2a 3576+ struct inode *h_isrc, *h_idst;
86dc4139 3577+ struct kstat *h_st;
1facf9fc 3578+
3579+ h_path.dentry = au_h_dptr(dst, bindex);
1308ab2a 3580+ h_idst = h_path.dentry->d_inode;
1facf9fc 3581+ h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
3582+ h_isrc = h_src->d_inode;
1308ab2a 3583+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 3584+ | ATTR_ATIME | ATTR_MTIME
3585+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
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);
1308ab2a 3611+ }
1facf9fc 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;
c06a8ce3 3711+ h_mtx = &file_inode(dst)->i_mutex;
1facf9fc 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+
4f0767ce 3752+out:
1facf9fc 3753+ return err;
3754+}
3755+
86dc4139
AM
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+
1facf9fc 3763+/*
3764+ * to support a sparse file which is opened with O_APPEND,
3765+ * we need to close the file.
3766+ */
86dc4139 3767+static int au_cp_regular(struct au_cpup_basic *basic)
1facf9fc 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+ {
86dc4139 3779+ .bindex = basic->bsrc,
1facf9fc 3780+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
3781+ .file = NULL,
3782+ .label = &&out,
3783+ .label_file = &&out_src
3784+ },
3785+ {
86dc4139 3786+ .bindex = basic->bdst,
1facf9fc 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. */
86dc4139 3796+ sb = basic->dentry->d_sb;
1facf9fc 3797+ f = file;
3798+ for (i = 0; i < 2; i++, f++) {
86dc4139
AM
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);
1facf9fc 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);
86dc4139 3812+ err = au_copy_file(file[DST].file, file[SRC].file, basic->len);
1facf9fc 3813+
4f0767ce 3814+out_dst:
1facf9fc 3815+ fput(file[DST].file);
3816+ au_sbr_put(sb, file[DST].bindex);
4f0767ce 3817+out_src:
1facf9fc 3818+ fput(file[SRC].file);
3819+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 3820+out:
1facf9fc 3821+ return err;
3822+}
3823+
86dc4139
AM
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)
1facf9fc 3826+{
3827+ int err, rerr;
3828+ loff_t l;
86dc4139
AM
3829+ struct path h_path;
3830+ struct inode *h_src_inode;
1facf9fc 3831+
3832+ err = 0;
86dc4139
AM
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);
1facf9fc 3841+
86dc4139
AM
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;
1facf9fc 3856+ }
3857+
4f0767ce 3858+out:
1facf9fc 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;
b752ccd1
AM
3867+ union {
3868+ char *k;
3869+ char __user *u;
3870+ } sym;
1facf9fc 3871+
3872+ err = -ENOSYS;
3873+ if (unlikely(!h_src->d_inode->i_op->readlink))
3874+ goto out;
3875+
3876+ err = -ENOMEM;
537831f9 3877+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 3878+ if (unlikely(!sym.k))
1facf9fc 3879+ goto out;
3880+
9dbd164d 3881+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 3882+ old_fs = get_fs();
3883+ set_fs(KERNEL_DS);
b752ccd1 3884+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 3885+ err = symlen;
3886+ set_fs(old_fs);
3887+
3888+ if (symlen > 0) {
b752ccd1
AM
3889+ sym.k[symlen] = 0;
3890+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 3891+ }
537831f9 3892+ free_page((unsigned long)sym.k);
1facf9fc 3893+
4f0767ce 3894+out:
1facf9fc 3895+ return err;
3896+}
3897+
1facf9fc 3898+static noinline_for_stack
86dc4139
AM
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)
1facf9fc 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. */
86dc4139 3915+ h_src = au_h_dptr(basic->dentry, basic->bsrc);
1facf9fc 3916+ h_inode = h_src->d_inode;
86dc4139 3917+ AuDebugOn(h_inode != au_h_iptr(basic->dentry->d_inode, basic->bsrc));
1facf9fc 3918+
3919+ /* try stopping to be referenced while we are creating */
86dc4139
AM
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));
1facf9fc 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+
86dc4139
AM
3929+ sb = basic->dentry->d_sb;
3930+ h_path.mnt = au_sbr_mnt(sb, basic->bdst);
1facf9fc 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:
b4510431
AM
3941+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
3942+ /*want_excl*/true);
1facf9fc 3943+ if (!err)
86dc4139 3944+ err = au_do_cpup_regular(basic, pin, h_src_attr);
1facf9fc 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+ */
86dc4139 3954+ if (au_ibstart(dst_parent->d_inode) == basic->bdst)
1facf9fc 3955+ au_cpup_attr_nlink(dst_parent->d_inode,
3956+ /*force*/1);
86dc4139 3957+ au_cpup_attr_nlink(basic->dentry->d_inode, /*force*/1);
1facf9fc 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? */
86dc4139
AM
3982+ /* && basic->dentry->d_inode->i_nlink == 1 */
3983+ && basic->bdst < basic->bsrc
1facf9fc 3984+ && !au_ftest_cpup(flags, KEEPLINO))
86dc4139 3985+ au_xino_write(sb, basic->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 3986+ /* ignore this error */
3987+
3988+ if (do_dt)
3989+ au_dtime_revert(&dt);
3990+ return err;
3991+}
3992+
86dc4139
AM
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+
1facf9fc 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+ */
86dc4139
AM
4027+static int au_cpup_single(struct au_cpup_basic *basic, unsigned int flags,
4028+ struct dentry *dst_parent, struct au_pin *pin)
1facf9fc 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;
86dc4139
AM
4038+ struct au_branch *br;
4039+ struct au_cpup_reg_attr h_src_attr = {
4040+ .valid = 0
4041+ };
1facf9fc 4042+
86dc4139 4043+ AuDebugOn(basic->bsrc <= basic->bdst);
1facf9fc 4044+
86dc4139
AM
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);
1facf9fc 4049+ h_parent = h_dst->d_parent; /* dir inode is locked */
4050+ h_dir = h_parent->d_inode;
4051+ IMustLock(h_dir);
4052+
86dc4139
AM
4053+ h_src = au_h_dptr(basic->dentry, basic->bsrc);
4054+ inode = basic->dentry->d_inode;
1facf9fc 4055+
4056+ if (!dst_parent)
86dc4139 4057+ dst_parent = dget_parent(basic->dentry);
1facf9fc 4058+ else
4059+ dget(dst_parent);
4060+
4061+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
86dc4139 4062+ dst_inode = au_h_iptr(inode, basic->bdst);
1facf9fc 4063+ if (dst_inode) {
4064+ if (unlikely(!plink)) {
4065+ err = -EIO;
027c5e7a
AM
4066+ AuIOErr("hi%lu(i%lu) exists on b%d "
4067+ "but plink is disabled\n",
86dc4139 4068+ dst_inode->i_ino, inode->i_ino, basic->bdst);
1facf9fc 4069+ goto out;
4070+ }
4071+
4072+ if (dst_inode->i_nlink) {
4073+ const int do_dt = au_ftest_cpup(flags, DTIME);
4074+
86dc4139 4075+ h_src = au_plink_lkup(inode, basic->bdst);
1facf9fc 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 "
027c5e7a
AM
4082+ "but not pseudo-linked\n",
4083+ inode->i_ino);
1facf9fc 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+ }
86dc4139 4092+
1facf9fc 4093+ h_path.dentry = h_dst;
4094+ err = vfsub_link(h_src, h_dir, &h_path);
86dc4139
AM
4095+ if (!err && au_ftest_cpup(flags, RENAME))
4096+ err = au_do_ren_after_cpup
4097+ (basic->dentry, basic->bdst, &h_path);
1facf9fc 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 */
4a4d8108 4105+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 4106+ }
4107+
86dc4139 4108+ isdir = S_ISDIR(inode->i_mode);
1facf9fc 4109+ old_ibstart = au_ibstart(inode);
86dc4139 4110+ err = cpup_entry(basic, flags, dst_parent, pin, &h_src_attr);
1facf9fc 4111+ if (unlikely(err))
86dc4139 4112+ goto out_rev;
1facf9fc 4113+ dst_inode = h_dst->d_inode;
4114+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
86dc4139
AM
4115+ /* todo: necessary? */
4116+ /* au_pin_hdir_unlock(pin); */
1facf9fc 4117+
86dc4139
AM
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;
4a4d8108 4133+ }
4a4d8108 4134+ }
86dc4139 4135+ au_set_ibstart(inode, basic->bdst);
1facf9fc 4136+ }
86dc4139
AM
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 */
1facf9fc 4157+
4158+ /* revert */
4a4d8108 4159+out_rev:
1facf9fc 4160+ h_path.dentry = h_parent;
1facf9fc 4161+ au_dtime_store(&dt, dst_parent, &h_path);
4162+ h_path.dentry = h_dst;
86dc4139
AM
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+ }
1facf9fc 4170+ au_dtime_revert(&dt);
4171+ if (rerr) {
4172+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
4173+ err = -EIO;
4174+ }
4f0767ce 4175+out:
1facf9fc 4176+ dput(dst_parent);
4177+ return err;
4178+}
4179+
4180+struct au_cpup_single_args {
4181+ int *errp;
86dc4139 4182+ struct au_cpup_basic *basic;
1facf9fc 4183+ unsigned int flags;
4184+ struct dentry *dst_parent;
86dc4139 4185+ struct au_pin *pin;
1facf9fc 4186+};
4187+
4188+static void au_call_cpup_single(void *args)
4189+{
4190+ struct au_cpup_single_args *a = args;
86dc4139
AM
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);
1facf9fc 4195+}
4196+
53392da6
AM
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+ */
86dc4139 4202+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
4203+{
4204+ int do_sio;
86dc4139
AM
4205+ struct super_block *sb;
4206+ struct inode *h_dir;
53392da6
AM
4207+
4208+ do_sio = 0;
86dc4139 4209+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
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));
86dc4139
AM
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+ }
53392da6
AM
4231+ }
4232+
4233+ return do_sio;
4234+}
4235+
1facf9fc 4236+int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst,
4237+ aufs_bindex_t bsrc, loff_t len, unsigned int flags,
86dc4139 4238+ struct dentry *dst_parent, struct au_pin *pin)
1facf9fc 4239+{
4240+ int err, wkq_err;
1facf9fc 4241+ struct dentry *h_dentry;
86dc4139
AM
4242+ struct au_cpup_basic basic = {
4243+ .dentry = dentry,
4244+ .bdst = bdst,
4245+ .bsrc = bsrc,
4246+ .len = len
4247+ };
1facf9fc 4248+
4249+ h_dentry = au_h_dptr(dentry, bsrc);
86dc4139
AM
4250+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
4251+ err = au_cpup_single(&basic, flags, dst_parent, pin);
1facf9fc 4252+ else {
4253+ struct au_cpup_single_args args = {
4254+ .errp = &err,
86dc4139 4255+ .basic = &basic,
1facf9fc 4256+ .flags = flags,
86dc4139
AM
4257+ .dst_parent = dst_parent,
4258+ .pin = pin
1facf9fc 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,
86dc4139 4273+ unsigned int flags, struct au_pin *pin)
1facf9fc 4274+{
4275+ int err;
4276+ aufs_bindex_t bsrc, bend;
86dc4139 4277+ struct dentry *h_dentry;
1facf9fc 4278+
86dc4139 4279+ DiMustWriteLock(dentry);
1facf9fc 4280+ bend = au_dbend(dentry);
86dc4139
AM
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);
1facf9fc 4285+ break;
86dc4139
AM
4286+ }
4287+ }
4288+ AuDebugOn(bsrc > bend);
1facf9fc 4289+
86dc4139 4290+ err = au_lkup_neg(dentry, bdst, /*wh*/1);
1facf9fc 4291+ if (!err) {
86dc4139
AM
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);
1facf9fc 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;
86dc4139 4316+ struct au_pin *pin;
1facf9fc 4317+};
4318+
4319+static void au_call_cpup_simple(void *args)
4320+{
4321+ struct au_cpup_simple_args *a = args;
86dc4139
AM
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);
1facf9fc 4326+}
4327+
4328+int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
86dc4139 4329+ unsigned int flags, struct au_pin *pin)
1facf9fc 4330+{
4331+ int err, wkq_err;
1facf9fc 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);
53392da6 4337+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
86dc4139
AM
4338+ && !au_cpup_sio_test(pin, dentry->d_inode->i_mode))
4339+ err = au_cpup_simple(dentry, bdst, len, flags, pin);
1facf9fc 4340+ else {
4341+ struct au_cpup_simple_args args = {
4342+ .errp = &err,
4343+ .dentry = dentry,
4344+ .bdst = bdst,
4345+ .len = len,
86dc4139
AM
4346+ .flags = flags,
4347+ .pin = pin
1facf9fc 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+
367653fa
AM
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+
1facf9fc 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,
86dc4139 4384+ loff_t len, struct au_pin *pin)
1facf9fc 4385+{
4386+ int err;
86dc4139
AM
4387+ struct au_cpup_basic basic = {
4388+ .dentry = dentry,
4389+ .bdst = bdst,
4390+ .bsrc = -1,
4391+ .len = len
4392+ };
1facf9fc 4393+ struct au_dinfo *dinfo;
4394+ struct dentry *h_d_dst, *h_d_start;
4a4d8108 4395+ struct au_hdentry *hdp;
1facf9fc 4396+
4397+ dinfo = au_di(dentry);
1308ab2a 4398+ AuRwMustWriteLock(&dinfo->di_rwsem);
4399+
86dc4139 4400+ basic.bsrc = dinfo->di_bstart;
4a4d8108
AM
4401+ hdp = dinfo->di_hdentry;
4402+ h_d_dst = hdp[0 + bdst].hd_dentry;
1facf9fc 4403+ dinfo->di_bstart = bdst;
4a4d8108 4404+ hdp[0 + bdst].hd_dentry = wh_dentry;
86dc4139 4405+ h_d_start = NULL;
027c5e7a 4406+ if (file) {
86dc4139
AM
4407+ h_d_start = hdp[0 + basic.bsrc].hd_dentry;
4408+ hdp[0 + basic.bsrc].hd_dentry = au_hf_top(file)->f_dentry;
027c5e7a 4409+ }
86dc4139 4410+ err = au_cpup_single(&basic, !AuCpup_DTIME, /*h_parent*/NULL, pin);
027c5e7a
AM
4411+ if (file) {
4412+ if (!err)
4413+ err = au_reopen_nondir(file);
86dc4139 4414+ hdp[0 + basic.bsrc].hd_dentry = h_d_start;
1facf9fc 4415+ }
4a4d8108 4416+ hdp[0 + bdst].hd_dentry = h_d_dst;
86dc4139 4417+ dinfo->di_bstart = basic.bsrc;
1facf9fc 4418+
4419+ return err;
4420+}
4421+
4422+static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
86dc4139 4423+ struct file *file, struct au_pin *pin)
1facf9fc 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;
86dc4139 4440+ h_path.mnt = au_br_mnt(br);
1facf9fc 4441+ au_dtime_store(&dt, parent, &h_path);
86dc4139 4442+ err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len, pin);
1facf9fc 4443+ if (unlikely(err))
4444+ goto out_wh;
4445+
4446+ dget(wh_dentry);
4447+ h_path.dentry = wh_dentry;
4a4d8108
AM
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);
1facf9fc 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+
4f0767ce 4460+out_wh:
1facf9fc 4461+ dput(wh_dentry);
4f0767ce 4462+out:
1facf9fc 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;
86dc4139 4473+ struct au_pin *pin;
1facf9fc 4474+};
4475+
4476+static void au_call_cpup_wh(void *args)
4477+{
4478+ struct au_cpup_wh_args *a = args;
86dc4139
AM
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);
1facf9fc 4483+}
4484+
4485+int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
86dc4139 4486+ struct file *file, struct au_pin *pin)
1facf9fc 4487+{
4488+ int err, wkq_err;
4489+ struct dentry *parent, *h_orph, *h_parent, *h_dentry;
86dc4139 4490+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 4491+ struct au_wbr *wbr;
86dc4139 4492+ struct au_pin wh_pin;
1facf9fc 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));
1facf9fc 4505+ au_set_h_dptr(parent, bdst, dget(h_orph));
4506+ h_tmpdir = h_orph->d_inode;
1facf9fc 4507+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
4508+
1facf9fc 4509+ if (file)
4a4d8108 4510+ h_dentry = au_hf_top(file)->f_dentry;
1facf9fc 4511+ else
4512+ h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
dece6358 4513+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4a4d8108 4514+ /* todo: au_h_open_pre()? */
86dc4139
AM
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;
1facf9fc 4519+ }
4520+
53392da6 4521+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
86dc4139
AM
4522+ && !au_cpup_sio_test(pin, dentry->d_inode->i_mode))
4523+ err = au_cpup_wh(dentry, bdst, len, file, pin);
1facf9fc 4524+ else {
4525+ struct au_cpup_wh_args args = {
4526+ .errp = &err,
4527+ .dentry = dentry,
4528+ .bdst = bdst,
4529+ .len = len,
86dc4139
AM
4530+ .file = file,
4531+ .pin = pin
1facf9fc 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);
4a4d8108 4540+ /* todo: au_h_open_post()? */
1facf9fc 4541+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 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,
86dc4139 4558+ struct au_pin *pin,
1facf9fc 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) {
86dc4139 4604+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 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+
4f0767ce 4615+out:
1facf9fc 4616+ dput(parent);
4617+ return err;
4618+}
4619+
4620+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 4621+ struct au_pin *pin,
1facf9fc 4622+ struct dentry *h_parent __maybe_unused ,
4623+ void *arg __maybe_unused)
4624+{
86dc4139 4625+ return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME, pin);
1facf9fc 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+
4f0767ce 4652+out:
1facf9fc 4653+ dput(parent);
4654+ return err;
4655+}
7f207e10
AM
4656diff -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
367653fa
AM
4658+++ linux/fs/aufs/cpup.h 2013-07-30 22:42:46.232612606 +0200
4659@@ -0,0 +1,87 @@
1facf9fc 4660+/*
7a9e40b8 4661+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
dece6358 4687+#include <linux/path.h>
1facf9fc 4688+
dece6358
AM
4689+struct inode;
4690+struct file;
86dc4139 4691+struct au_pin;
dece6358 4692+
86dc4139 4693+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 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) */
86dc4139 4706+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
1facf9fc 4707+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
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)
1facf9fc 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,
86dc4139 4716+ struct dentry *dst_parent, struct au_pin *pin);
1facf9fc 4717+int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
86dc4139 4718+ unsigned int flags, struct au_pin *pin);
367653fa
AM
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);
1facf9fc 4722+int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len,
86dc4139 4723+ struct file *file, struct au_pin *pin);
1facf9fc 4724+
4725+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4726+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 4727+ struct au_pin *pin,
1facf9fc 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__ */
7f207e10
AM
4747diff -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
86dc4139
AM
4749+++ linux/fs/aufs/dbgaufs.c 2013-07-06 13:20:47.740198107 +0200
4750@@ -0,0 +1,433 @@
1facf9fc 4751+/*
7a9e40b8 4752+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
c06a8ce3 4816+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 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+
4f0767ce 4833+out:
1facf9fc 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+
86dc4139
AM
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+
1facf9fc 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 = {
4a4d8108 4959+ .owner = THIS_MODULE,
1facf9fc 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;
9dbd164d 4985+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 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+
4f0767ce 4999+out:
1facf9fc 5000+ return err;
5001+}
5002+
5003+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 5004+ .owner = THIS_MODULE,
1facf9fc 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;
c06a8ce3
AM
5023+ debugfs_remove(xi->xi_dbgaufs);
5024+ xi->xi_dbgaufs = NULL;
1facf9fc 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 = {
4a4d8108 5074+ .owner = THIS_MODULE,
1facf9fc 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+
dece6358
AM
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+
1facf9fc 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+{
dece6358
AM
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+
1facf9fc 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+
dece6358
AM
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+
1facf9fc 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+
86dc4139
AM
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+
1facf9fc 5157+ err = dbgaufs_xigen_init(sbinfo);
5158+ if (!err)
5159+ goto out; /* success */
5160+
4f0767ce 5161+out_dir:
1facf9fc 5162+ dbgaufs_si_fin(sbinfo);
4f0767ce 5163+out:
1facf9fc 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+}
7f207e10
AM
5184diff -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
86dc4139 5186+++ linux/fs/aufs/dbgaufs.h 2013-07-06 13:20:47.740198107 +0200
f6c5ef8b 5187@@ -0,0 +1,49 @@
1facf9fc 5188+/*
7a9e40b8 5189+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 5204+ */
5205+
5206+/*
5207+ * debugfs interface
5208+ */
5209+
5210+#ifndef __DBGAUFS_H__
5211+#define __DBGAUFS_H__
5212+
5213+#ifdef __KERNEL__
5214+
dece6358 5215+struct super_block;
1facf9fc 5216+struct au_sbinfo;
dece6358 5217+
1facf9fc 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);
1facf9fc 5226+#else
4a4d8108
AM
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)
1facf9fc 5233+#endif /* CONFIG_DEBUG_FS */
5234+
5235+#endif /* __KERNEL__ */
5236+#endif /* __DBGAUFS_H__ */
7f207e10
AM
5237diff -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
367653fa 5239+++ linux/fs/aufs/dcsub.c 2013-07-30 22:42:55.839613269 +0200
027c5e7a 5240@@ -0,0 +1,243 @@
1facf9fc 5241+/*
7a9e40b8 5242+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
4f0767ce 5295+out_dpages:
1facf9fc 5296+ kfree(dpages->dpages);
4f0767ce 5297+out:
1facf9fc 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+
027c5e7a
AM
5341+ AuDebugOn(!dentry->d_count);
5342+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 5343+ return 0; /* success */
5344+
4f0767ce 5345+out:
1facf9fc 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;
027c5e7a 5353+ struct dentry *this_parent;
1facf9fc 5354+ struct list_head *next;
5355+ struct super_block *sb = root->d_sb;
5356+
5357+ err = 0;
027c5e7a
AM
5358+ write_seqlock(&rename_lock);
5359+ this_parent = root;
5360+ spin_lock(&this_parent->d_lock);
4f0767ce 5361+repeat:
1facf9fc 5362+ next = this_parent->d_subdirs.next;
4f0767ce 5363+resume:
1facf9fc 5364+ if (this_parent->d_sb == sb
5365+ && !IS_ROOT(this_parent)
027c5e7a
AM
5366+ && au_di(this_parent)
5367+ && this_parent->d_count
1facf9fc 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);
027c5e7a 5378+
1facf9fc 5379+ next = tmp->next;
027c5e7a
AM
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);
1facf9fc 5396+ }
027c5e7a
AM
5397+ spin_unlock(&dentry->d_lock);
5398+ if (unlikely(err))
5399+ goto out;
1facf9fc 5400+ }
5401+
5402+ if (this_parent != root) {
027c5e7a
AM
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;
1facf9fc 5414+ goto resume;
5415+ }
027c5e7a 5416+
4f0767ce 5417+out:
027c5e7a
AM
5418+ spin_unlock(&this_parent->d_lock);
5419+ write_sequnlock(&rename_lock);
1facf9fc 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;
027c5e7a
AM
5429+ write_seqlock(&rename_lock);
5430+ spin_lock(&dentry->d_lock);
5431+ if (do_include
5432+ && dentry->d_count
5433+ && (!test || test(dentry, arg)))
1facf9fc 5434+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
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+ */
1facf9fc 5443+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
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)))
1facf9fc 5448+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
5449+ spin_unlock(&dentry->d_lock);
5450+ if (unlikely(err))
5451+ break;
1facf9fc 5452+ }
5453+
4f0767ce 5454+out:
027c5e7a 5455+ write_sequnlock(&rename_lock);
1facf9fc 5456+ return err;
5457+}
5458+
027c5e7a
AM
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+
4a4d8108 5471+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 5472+{
4a4d8108
AM
5473+ struct path path[2] = {
5474+ {
5475+ .dentry = d1
5476+ },
5477+ {
5478+ .dentry = d2
5479+ }
5480+ };
1facf9fc 5481+
4a4d8108 5482+ return path_is_under(path + 0, path + 1);
1facf9fc 5483+}
7f207e10
AM
5484diff -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
86dc4139 5486+++ linux/fs/aufs/dcsub.h 2013-07-06 13:20:47.740198107 +0200
f6c5ef8b 5487@@ -0,0 +1,94 @@
1facf9fc 5488+/*
7a9e40b8 5489+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
7f207e10 5515+#include <linux/dcache.h>
027c5e7a 5516+#include <linux/fs.h>
dece6358
AM
5517+
5518+struct dentry;
1facf9fc 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+
7f207e10 5532+/* dcsub.c */
1facf9fc 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);
027c5e7a
AM
5540+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5541+ struct dentry *dentry, int do_include);
4a4d8108 5542+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 5543+
7f207e10
AM
5544+/* ---------------------------------------------------------------------- */
5545+
027c5e7a
AM
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)
7f207e10 5572+{
027c5e7a
AM
5573+ int err;
5574+ err = au_d_alive(d);
5575+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
5576+ err = -ENOENT;
5577+ return err;
7f207e10
AM
5578+}
5579+
1facf9fc 5580+#endif /* __KERNEL__ */
5581+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
5582diff -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
367653fa 5584+++ linux/fs/aufs/debug.c 2013-07-30 22:42:55.839613269 +0200
c06a8ce3 5585@@ -0,0 +1,491 @@
1facf9fc 5586+/*
7a9e40b8 5587+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 5602+ */
5603+
5604+/*
5605+ * debug print functions
5606+ */
5607+
7f207e10 5608+#include <linux/vt_kern.h>
1facf9fc 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;
e49829fe
JR
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__); \
1facf9fc 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;
c06a8ce3 5629+ struct au_vdir_wh *pos;
1facf9fc 5630+
5631+ n = whlist->nh_num;
5632+ head = whlist->nh_head;
5633+ for (ul = 0; ul < n; ul++) {
c06a8ce3 5634+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 5635+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
5636+ pos->wh_bindex,
5637+ pos->wh_str.len, pos->wh_str.name,
5638+ pos->wh_str.len);
1facf9fc 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+
53392da6 5664+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 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+
53392da6
AM
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,
1facf9fc 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,
53392da6 5689+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 5690+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
5691+ inode->i_state, inode->i_flags, inode->i_version,
5692+ inode->i_generation,
1facf9fc 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;
53392da6 5701+ int err, hn;
1facf9fc 5702+
53392da6 5703+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 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",
537831f9 5711+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 5712+ if (iinfo->ii_bstart < 0)
5713+ return;
53392da6
AM
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,
1facf9fc 5718+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 5719+ }
1facf9fc 5720+}
5721+
2cbb1c4b
JR
5722+void au_dpri_dalias(struct inode *inode)
5723+{
5724+ struct dentry *d;
5725+
5726+ spin_lock(&inode->i_lock);
c06a8ce3 5727+ hlist_for_each_entry(d, &inode->i_dentry, d_alias)
2cbb1c4b
JR
5728+ au_dpri_dentry(d);
5729+ spin_unlock(&inode->i_lock);
5730+}
5731+
1facf9fc 5732+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
5733+{
5734+ struct dentry *wh = NULL;
53392da6 5735+ int hn;
1facf9fc 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 */
027c5e7a 5742+ /* note: access d_xxx without d_lock */
1facf9fc 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) : "??",
027c5e7a 5747+ dentry->d_count, dentry->d_flags);
53392da6 5748+ hn = -1;
1facf9fc 5749+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
5750+ struct au_iinfo *iinfo = au_ii(dentry->d_inode);
53392da6
AM
5751+ if (iinfo) {
5752+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 5753+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 5754+ }
1facf9fc 5755+ }
53392da6 5756+ do_pri_inode(bindex, dentry->d_inode, hn, wh);
1facf9fc 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;
4a4d8108 5765+ struct au_hdentry *hdp;
1facf9fc 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;
4a4d8108 5779+ hdp = dinfo->di_hdentry;
1facf9fc 5780+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 5781+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 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))
e49829fe 5797+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 5798+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 5799+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 5800+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 5801+ file->f_version, file->f_pos, a);
1facf9fc 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;
4a4d8108
AM
5810+ struct au_fidir *fidir;
5811+ struct au_hfile *hfile;
1facf9fc 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;
4a4d8108 5822+ if (finfo->fi_btop < 0)
1facf9fc 5823+ return;
4a4d8108
AM
5824+ fidir = finfo->fi_hdir;
5825+ if (!fidir)
5826+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
5827+ else
e49829fe
JR
5828+ for (bindex = finfo->fi_btop;
5829+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
5830+ bindex++) {
5831+ hfile = fidir->fd_hfile + bindex;
5832+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
5833+ }
1facf9fc 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;
86dc4139 5843+ mnt = au_br_mnt(br);
1facf9fc 5844+ if (!mnt || IS_ERR(mnt))
5845+ goto out;
5846+ sb = mnt->mnt_sb;
5847+ if (!sb || IS_ERR(sb))
5848+ goto out;
5849+
1e00d052 5850+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 5851+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 5852+ "xino %d\n",
1e00d052
AM
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),
b752ccd1 5855+ sb->s_flags, sb->s_count,
1facf9fc 5856+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
5857+ return 0;
5858+
4f0767ce 5859+out:
1facf9fc 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;
86dc4139 5884+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 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+{
c06a8ce3
AM
5914+#define AuBit(name) \
5915+ do { \
5916+ if (ia->ia_valid & ATTR_ ## name) \
5917+ dpri(#name "\n"); \
5918+ } while (0)
1facf9fc 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+
027c5e7a
AM
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+
1facf9fc 5979+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
5980+{
5981+ struct dentry *parent;
5982+
5983+ parent = dget_parent(dentry);
027c5e7a
AM
5984+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
5985+ AuDebugOn(IS_ROOT(dentry));
5986+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 5987+ dput(parent);
5988+}
5989+
5990+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
5991+{
5992+ struct dentry *parent;
027c5e7a 5993+ struct inode *inode;
1facf9fc 5994+
5995+ parent = dget_parent(dentry);
027c5e7a
AM
5996+ inode = dentry->d_inode;
5997+ AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
5998+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 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);
027c5e7a 6011+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 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--)
027c5e7a 6017+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 6018+ }
6019+ au_dpages_free(&dpages);
6020+}
6021+
1facf9fc 6022+void au_dbg_verify_kthread(void)
6023+{
53392da6 6024+ if (au_wkq_test()) {
1facf9fc 6025+ au_dbg_blocked();
1e00d052
AM
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); */
1facf9fc 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
4a4d8108
AM
6047+#ifdef AuForceHnotify
6048+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
1facf9fc 6049+#endif
1308ab2a 6050+#ifdef AuForceRd0
6051+ sbinfo->si_rdblk = 0;
6052+ sbinfo->si_rdhash = 0;
6053+#endif
1facf9fc 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
0c3ec466 6068+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 6069+#endif
6070+
6071+#ifdef AuForceNoBrs
6072+ sysaufs_brs = 0;
6073+#endif
6074+
6075+ return 0;
6076+}
7f207e10
AM
6077diff -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
86dc4139 6079+++ linux/fs/aufs/debug.h 2013-07-06 13:20:47.740198107 +0200
92d182d2 6080@@ -0,0 +1,242 @@
1facf9fc 6081+/*
7a9e40b8 6082+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 6097+ */
6098+
6099+/*
6100+ * debug print functions
6101+ */
6102+
6103+#ifndef __AUFS_DEBUG_H__
6104+#define __AUFS_DEBUG_H__
6105+
6106+#ifdef __KERNEL__
6107+
4a4d8108
AM
6108+#include <linux/module.h>
6109+#include <linux/kallsyms.h>
1facf9fc 6110+#include <linux/sysrq.h>
4a4d8108 6111+
1facf9fc 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)
4a4d8108
AM
6129+AuStubVoid(au_debug, int n)
6130+AuStubInt0(au_debug_test, void)
1facf9fc 6131+#endif /* CONFIG_AUFS_DEBUG */
6132+
6133+/* ---------------------------------------------------------------------- */
6134+
6135+/* debug print */
6136+
4a4d8108 6137+#define AuDbg(fmt, ...) do { \
1facf9fc 6138+ if (au_debug_test()) \
4a4d8108 6139+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 6140+} while (0)
4a4d8108
AM
6141+#define AuLabel(l) AuDbg(#l "\n")
6142+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
6143+#define AuWarn1(fmt, ...) do { \
1facf9fc 6144+ static unsigned char _c; \
6145+ if (!_c++) \
0c3ec466 6146+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 6147+} while (0)
6148+
4a4d8108 6149+#define AuErr1(fmt, ...) do { \
1facf9fc 6150+ static unsigned char _c; \
6151+ if (!_c++) \
4a4d8108 6152+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 6153+} while (0)
6154+
4a4d8108 6155+#define AuIOErr1(fmt, ...) do { \
1facf9fc 6156+ static unsigned char _c; \
6157+ if (!_c++) \
4a4d8108 6158+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 6159+} while (0)
6160+
6161+#define AuUnsupportMsg "This operation is not supported." \
6162+ " Please report this application to aufs-users ML."
4a4d8108
AM
6163+#define AuUnsupport(fmt, ...) do { \
6164+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 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;
dece6358 6186+struct dentry;
1facf9fc 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);
dece6358 6193+struct inode;
1facf9fc 6194+void au_dpri_inode(struct inode *inode);
2cbb1c4b 6195+void au_dpri_dalias(struct inode *inode);
1facf9fc 6196+void au_dpri_dentry(struct dentry *dentry);
dece6358 6197+struct file;
1facf9fc 6198+void au_dpri_file(struct file *filp);
dece6358 6199+struct super_block;
1facf9fc 6200+void au_dpri_sb(struct super_block *sb);
6201+
6202+void au_dbg_sleep_jiffy(int jiffy);
dece6358 6203+struct iattr;
1facf9fc 6204+void au_dbg_iattr(struct iattr *ia);
6205+
027c5e7a
AM
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);
1facf9fc 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);
1facf9fc 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+
2cbb1c4b
JR
6230+#define AuDbgDAlias(i) do { \
6231+ AuDbg(#i "\n"); \
6232+ au_dpri_dalias(i); \
6233+} while (0)
6234+
1facf9fc 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)
4a4d8108
AM
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)
1facf9fc 6276+#else
027c5e7a 6277+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
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)
1facf9fc 6285+
1facf9fc 6286+#define AuDbgWhlist(w) do {} while (0)
6287+#define AuDbgVdir(v) do {} while (0)
6288+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 6289+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 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)
4a4d8108
AM
6296+#define AuDbgSym(addr) do {} while (0)
6297+#define AuInfoSym(addr) do {} while (0)
1facf9fc 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); \
0c5527e5 6309+ handle_sysrq('w'); \
1facf9fc 6310+} while (0)
6311+#else
4a4d8108 6312+AuStubVoid(au_dbg_blocked, void)
1facf9fc 6313+#endif
6314+
6315+#else
4a4d8108
AM
6316+AuStubInt0(__init au_sysrq_init, void)
6317+AuStubVoid(au_sysrq_fin, void)
6318+AuStubVoid(au_dbg_blocked, void)
1facf9fc 6319+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
6320+
6321+#endif /* __KERNEL__ */
6322+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
6323diff -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
86dc4139
AM
6325+++ linux/fs/aufs/dentry.c 2013-07-06 13:20:47.740198107 +0200
6326@@ -0,0 +1,1065 @@
1facf9fc 6327+/*
7a9e40b8 6328+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 6343+ */
6344+
6345+/*
6346+ * lookup and dentry operations
6347+ */
6348+
dece6358 6349+#include <linux/namei.h>
1facf9fc 6350+#include "aufs.h"
6351+
1facf9fc 6352+#define AuLkup_ALLOW_NEG 1
6353+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
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)
1facf9fc 6358+
6359+struct au_do_lookup_args {
6360+ unsigned int flags;
6361+ mode_t type;
1facf9fc 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;
1facf9fc 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+
1facf9fc 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+
4f0767ce 6397+real_lookup:
b4510431 6398+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
1facf9fc 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+
4f0767ce 6432+out_neg:
1facf9fc 6433+ dput(h_dentry);
6434+ h_dentry = NULL;
4f0767ce 6435+out:
1facf9fc 6436+ return h_dentry;
6437+}
6438+
dece6358
AM
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+
1facf9fc 6447+/*
6448+ * returns the number of lower positive dentries,
6449+ * otherwise an error.
6450+ * can be called at unlinking with @type is zero.
6451+ */
537831f9 6452+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 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 = {
b4510431 6459+ .flags = 0,
537831f9 6460+ .type = type
1facf9fc 6461+ };
6462+ const struct qstr *name = &dentry->d_name;
6463+ struct dentry *parent;
6464+ struct inode *inode;
6465+
dece6358
AM
6466+ err = au_test_shwh(dentry->d_sb, name);
6467+ if (unlikely(err))
1facf9fc 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;
4a4d8108 6480+ parent = dget_parent(dentry);
1facf9fc 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))
4a4d8108 6507+ goto out_parent;
1facf9fc 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)
027c5e7a 6536+ && au_dbstart(dentry) < 0)) {
1facf9fc 6537+ err = -EIO;
027c5e7a
AM
6538+ AuIOErr("both of real entry and whiteout found, %.*s, err %d\n",
6539+ AuDLNPair(dentry), err);
6540+ }
1facf9fc 6541+
4f0767ce 6542+out_parent:
4a4d8108 6543+ dput(parent);
1facf9fc 6544+ kfree(whname.name);
4f0767ce 6545+out:
1facf9fc 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))
b4510431 6556+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 6557+ else {
b4510431
AM
6558+ struct vfsub_lkup_one_args args = {
6559+ .errp = &dentry,
6560+ .name = name,
6561+ .parent = parent
1facf9fc 6562+ };
6563+
b4510431 6564+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 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+ */
86dc4139 6575+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 6576+{
6577+ int err;
6578+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 6579+ struct au_branch *br;
1facf9fc 6580+
1facf9fc 6581+ parent = dget_parent(dentry);
6582+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
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);
1facf9fc 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;
027c5e7a
AM
6593+ AuIOErr("%.*s should be negative on b%d.\n",
6594+ AuDLNPair(h_dentry), bindex);
1facf9fc 6595+ dput(h_dentry);
6596+ goto out;
6597+ }
6598+
4a4d8108 6599+ err = 0;
1facf9fc 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);
1facf9fc 6605+
4f0767ce 6606+out:
1facf9fc 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; */
0c3ec466
AM
6617+ kuid_t i_uid;
6618+ kgid_t i_gid;
1facf9fc 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 */
0c3ec466 6645+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 6646+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 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 */
b4510431 6676+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 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+
4f0767ce 6688+out:
1facf9fc 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;
027c5e7a
AM
6699+ if (udba == AuOpt_UDBA_REVAL
6700+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 6701+ IMustLock(h_dir);
6702+ err = (h_dentry->d_parent->d_inode != h_dir);
027c5e7a 6703+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 6704+ err = au_h_verify_dentry(h_dentry, h_parent, br);
6705+
6706+ return err;
6707+}
6708+
6709+/* ---------------------------------------------------------------------- */
6710+
027c5e7a 6711+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 6712+{
027c5e7a 6713+ int err;
1facf9fc 6714+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
6715+ struct au_hdentry tmp, *p, *q;
6716+ struct au_dinfo *dinfo;
6717+ struct super_block *sb;
1facf9fc 6718+
027c5e7a 6719+ DiMustWriteLock(dentry);
1308ab2a 6720+
027c5e7a
AM
6721+ sb = dentry->d_sb;
6722+ dinfo = au_di(dentry);
1facf9fc 6723+ bend = dinfo->di_bend;
6724+ bwh = dinfo->di_bwh;
6725+ bdiropq = dinfo->di_bdiropq;
027c5e7a 6726+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 6727+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 6728+ if (!p->hd_dentry)
1facf9fc 6729+ continue;
6730+
027c5e7a
AM
6731+ new_bindex = au_br_index(sb, p->hd_id);
6732+ if (new_bindex == bindex)
1facf9fc 6733+ continue;
1facf9fc 6734+
1facf9fc 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+
1facf9fc 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+
027c5e7a
AM
6766+ err = -EIO;
6767+ dinfo->di_bstart = -1;
6768+ dinfo->di_bend = -1;
1facf9fc 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+
027c5e7a
AM
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;
1facf9fc 6788+}
6789+
027c5e7a 6790+static void au_do_hide(struct dentry *dentry)
1facf9fc 6791+{
027c5e7a 6792+ struct inode *inode;
1facf9fc 6793+
027c5e7a
AM
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+}
1308ab2a 6808+
027c5e7a
AM
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;
1facf9fc 6815+
027c5e7a 6816+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 6817+ if (unlikely(err))
6818+ goto out;
027c5e7a
AM
6819+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
6820+ if (unlikely(err))
6821+ goto out_dpages;
1facf9fc 6822+
027c5e7a
AM
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+ }
1facf9fc 6833+
027c5e7a
AM
6834+out_dpages:
6835+ au_dpages_free(&dpages);
4f0767ce 6836+out:
027c5e7a 6837+ return err;
1facf9fc 6838+}
6839+
027c5e7a 6840+static void au_hide(struct dentry *dentry)
1facf9fc 6841+{
027c5e7a
AM
6842+ int err;
6843+ struct inode *inode;
1facf9fc 6844+
027c5e7a
AM
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+}
1facf9fc 6856+
027c5e7a
AM
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+ */
537831f9 7062+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
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+
b4510431
AM
7091+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
7092+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
7093+{
7094+ int err, valid;
027c5e7a
AM
7095+
7096+ err = 0;
7097+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
7098+ goto out;
027c5e7a
AM
7099+
7100+ AuDbg("b%d\n", bindex);
b4510431
AM
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);
1facf9fc 7109+
7110+ if (unlikely(valid < 0))
7111+ err = valid;
7112+ else if (!valid)
7113+ err = -EINVAL;
7114+
4f0767ce 7115+out:
1facf9fc 7116+ AuTraceErr(err);
7117+ return err;
7118+}
7119+
7120+/* todo: remove this */
7121+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 7122+ unsigned int flags, int do_udba)
1facf9fc 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;
4a4d8108 7128+ struct inode *h_inode, *h_cached_inode;
1facf9fc 7129+ struct dentry *h_dentry;
7130+ struct qstr *name, *h_name;
7131+
7132+ err = 0;
7133+ plus = 0;
7134+ mode = 0;
1facf9fc 7135+ ibs = -1;
7136+ ibe = -1;
7137+ unhashed = !!d_unhashed(dentry);
7138+ is_root = !!IS_ROOT(dentry);
7139+ name = &dentry->d_name;
7140+
7141+ /*
7f207e10
AM
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,
1facf9fc 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);
1facf9fc 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));
027c5e7a 7166+ spin_lock(&h_dentry->d_lock);
1facf9fc 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));
027c5e7a 7177+ spin_unlock(&h_dentry->d_lock);
1facf9fc 7178+ goto err;
7179+ }
027c5e7a 7180+ spin_unlock(&h_dentry->d_lock);
1facf9fc 7181+
b4510431 7182+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 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+
027c5e7a 7220+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 7221+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
7222+{
7223+ int err;
7224+ struct dentry *parent;
1facf9fc 7225+
027c5e7a 7226+ if (!au_digen_test(dentry, sigen))
1facf9fc 7227+ return 0;
7228+
7229+ parent = dget_parent(dentry);
7230+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 7231+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 7232+ au_dbg_verify_gen(parent, sigen);
027c5e7a 7233+ err = au_refresh_dentry(dentry, parent);
1facf9fc 7234+ di_read_unlock(parent, AuLock_IR);
7235+ dput(parent);
027c5e7a 7236+ AuTraceErr(err);
1facf9fc 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+
027c5e7a 7246+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 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;
027c5e7a 7253+ while (au_digen_test(dentry, sigen)) {
1facf9fc 7254+ d = dentry;
7255+ while (1) {
7256+ dput(parent);
7257+ parent = dget_parent(d);
027c5e7a 7258+ if (!au_digen_test(parent, sigen))
1facf9fc 7259+ break;
7260+ d = parent;
7261+ }
7262+
7263+ inode = d->d_inode;
7264+ if (d != dentry)
027c5e7a 7265+ di_write_lock_child2(d);
1facf9fc 7266+
7267+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
7268+ if (au_digen_test(d, sigen)) {
7269+ /*
7270+ * todo: consolidate with simple_reval_dpath(),
7271+ * do_refresh() and au_reval_for_attr().
7272+ */
1facf9fc 7273+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 7274+ err = au_refresh_dentry(d, parent);
1facf9fc 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+ */
b4510431 7291+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 7292+{
7293+ int valid, err;
7294+ unsigned int sigen;
7295+ unsigned char do_udba;
7296+ struct super_block *sb;
7297+ struct inode *inode;
7298+
027c5e7a 7299+ /* todo: support rcu-walk? */
b4510431 7300+ if (flags & LOOKUP_RCU)
027c5e7a
AM
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+
e49829fe 7311+ valid = 1;
1facf9fc 7312+ sb = dentry->d_sb;
e49829fe
JR
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;
027c5e7a 7321+ AuTraceErr(err);
e49829fe
JR
7322+ goto out;
7323+ }
027c5e7a
AM
7324+ if (unlikely(au_dbrange_test(dentry))) {
7325+ err = -EINVAL;
7326+ AuTraceErr(err);
7327+ goto out_dgrade;
1facf9fc 7328+ }
027c5e7a
AM
7329+
7330+ sigen = au_sigen(sb);
7331+ if (au_digen_test(dentry, sigen)) {
1facf9fc 7332+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
7333+ err = au_reval_dpath(dentry, sigen);
7334+ if (unlikely(err)) {
7335+ AuTraceErr(err);
1facf9fc 7336+ goto out_dgrade;
027c5e7a 7337+ }
1facf9fc 7338+ }
7339+ di_downgrade_lock(dentry, AuLock_IR);
7340+
1facf9fc 7341+ err = -EINVAL;
027c5e7a
AM
7342+ if (inode && (IS_DEADDIR(inode) || !inode->i_nlink))
7343+ goto out_inval;
7344+
1facf9fc 7345+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
7346+ if (do_udba && inode) {
7347+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 7348+ struct inode *h_inode;
1facf9fc 7349+
027c5e7a
AM
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+ }
1facf9fc 7355+ }
7356+
b4510431 7357+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 7358+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 7359+ err = -EIO;
027c5e7a
AM
7360+ AuDbg("both of real entry and whiteout found, %.*s, err %d\n",
7361+ AuDLNPair(dentry), err);
7362+ }
e49829fe 7363+ goto out_inval;
1facf9fc 7364+
4f0767ce 7365+out_dgrade:
1facf9fc 7366+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 7367+out_inval:
1facf9fc 7368+ aufs_read_unlock(dentry, AuLock_IR);
7369+ AuTraceErr(err);
7370+ valid = !err;
e49829fe 7371+out:
027c5e7a 7372+ if (!valid) {
e49829fe 7373+ AuDbg("%.*s invalid, %d\n", AuDLNPair(dentry), valid);
027c5e7a
AM
7374+ d_drop(dentry);
7375+ }
1facf9fc 7376+ return valid;
7377+}
7378+
7379+static void aufs_d_release(struct dentry *dentry)
7380+{
027c5e7a 7381+ if (au_di(dentry)) {
4a4d8108
AM
7382+ au_di_fin(dentry);
7383+ au_hn_di_reinit(dentry);
1facf9fc 7384+ }
1facf9fc 7385+}
7386+
4a4d8108 7387+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
7388+ .d_revalidate = aufs_d_revalidate,
7389+ .d_weak_revalidate = aufs_d_revalidate,
7390+ .d_release = aufs_d_release
1facf9fc 7391+};
7f207e10
AM
7392diff -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
86dc4139 7394+++ linux/fs/aufs/dentry.h 2013-07-06 13:20:47.740198107 +0200
537831f9 7395@@ -0,0 +1,234 @@
1facf9fc 7396+/*
7a9e40b8 7397+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
dece6358 7423+#include <linux/dcache.h>
1facf9fc 7424+#include "rwsem.h"
7425+
1facf9fc 7426+struct au_hdentry {
7427+ struct dentry *hd_dentry;
027c5e7a 7428+ aufs_bindex_t hd_id;
1facf9fc 7429+};
7430+
7431+struct au_dinfo {
7432+ atomic_t di_generation;
7433+
dece6358 7434+ struct au_rwsem di_rwsem;
1facf9fc 7435+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
7436+ struct au_hdentry *di_hdentry;
4a4d8108 7437+} ____cacheline_aligned_in_smp;
1facf9fc 7438+
7439+/* ---------------------------------------------------------------------- */
7440+
7441+/* dentry.c */
4a4d8108 7442+extern const struct dentry_operations aufs_dop;
1facf9fc 7443+struct au_branch;
1facf9fc 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+
537831f9 7449+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
86dc4139 7450+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 7451+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 7452+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
7453+
7454+/* dinfo.c */
4a4d8108 7455+void au_di_init_once(void *_di);
027c5e7a
AM
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);
4a4d8108
AM
7460+int au_di_init(struct dentry *dentry);
7461+void au_di_fin(struct dentry *dentry);
1facf9fc 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);
2cbb1c4b 7474+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 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);
027c5e7a
AM
7480+int au_digen_test(struct dentry *dentry, unsigned int sigen);
7481+int au_dbrange_test(struct dentry *dentry);
1facf9fc 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 */
4a4d8108 7500+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 7501+ AuLsc_DI_CHILD3, /* copyup dirs */
7502+ AuLsc_DI_PARENT,
7503+ AuLsc_DI_PARENT2,
027c5e7a
AM
7504+ AuLsc_DI_PARENT3,
7505+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 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)
dece6358
AM
7540+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
7541+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 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+{
4a4d8108
AM
7558+ if (hd)
7559+ dput(hd->hd_dentry);
1facf9fc 7560+}
7561+
7562+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
7563+{
1308ab2a 7564+ DiMustAnyLock(dentry);
1facf9fc 7565+ return au_di(dentry)->di_bstart;
7566+}
7567+
7568+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
7569+{
1308ab2a 7570+ DiMustAnyLock(dentry);
1facf9fc 7571+ return au_di(dentry)->di_bend;
7572+}
7573+
7574+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
7575+{
1308ab2a 7576+ DiMustAnyLock(dentry);
1facf9fc 7577+ return au_di(dentry)->di_bwh;
7578+}
7579+
7580+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
7581+{
1308ab2a 7582+ DiMustAnyLock(dentry);
1facf9fc 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+{
1308ab2a 7589+ DiMustWriteLock(dentry);
1facf9fc 7590+ au_di(dentry)->di_bstart = bindex;
7591+}
7592+
7593+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
7594+{
1308ab2a 7595+ DiMustWriteLock(dentry);
1facf9fc 7596+ au_di(dentry)->di_bend = bindex;
7597+}
7598+
7599+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
7600+{
1308ab2a 7601+ DiMustWriteLock(dentry);
1facf9fc 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+{
1308ab2a 7608+ DiMustWriteLock(dentry);
1facf9fc 7609+ au_di(dentry)->di_bdiropq = bindex;
7610+}
7611+
7612+/* ---------------------------------------------------------------------- */
7613+
4a4d8108 7614+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 7615+static inline void au_digen_dec(struct dentry *d)
7616+{
e49829fe 7617+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 7618+}
7619+
4a4d8108 7620+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 7621+{
7622+ dentry->d_fsdata = NULL;
7623+}
7624+#else
4a4d8108
AM
7625+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
7626+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 7627+
7628+#endif /* __KERNEL__ */
7629+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
7630diff -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
367653fa 7632+++ linux/fs/aufs/dinfo.c 2013-07-30 22:42:55.839613269 +0200
2cbb1c4b 7633@@ -0,0 +1,543 @@
1facf9fc 7634+/*
7a9e40b8 7635+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 7650+ */
7651+
7652+/*
7653+ * dentry private data
7654+ */
7655+
7656+#include "aufs.h"
7657+
e49829fe 7658+void au_di_init_once(void *_dinfo)
4a4d8108 7659+{
e49829fe
JR
7660+ struct au_dinfo *dinfo = _dinfo;
7661+ static struct lock_class_key aufs_di;
4a4d8108 7662+
e49829fe
JR
7663+ au_rw_init(&dinfo->di_rwsem);
7664+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
7665+}
7666+
027c5e7a 7667+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 7668+{
7669+ struct au_dinfo *dinfo;
027c5e7a 7670+ int nbr, i;
1facf9fc 7671+
7672+ dinfo = au_cache_alloc_dinfo();
7673+ if (unlikely(!dinfo))
7674+ goto out;
7675+
1facf9fc 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);
027c5e7a
AM
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+ }
1facf9fc 7690+
1facf9fc 7691+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
7692+ dinfo = NULL;
7693+
4f0767ce 7694+out:
027c5e7a 7695+ return dinfo;
1facf9fc 7696+}
7697+
027c5e7a 7698+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 7699+{
4a4d8108
AM
7700+ struct au_hdentry *p;
7701+ aufs_bindex_t bend, bindex;
7702+
7703+ /* dentry may not be revalidated */
027c5e7a 7704+ bindex = dinfo->di_bstart;
4a4d8108 7705+ if (bindex >= 0) {
027c5e7a
AM
7706+ bend = dinfo->di_bend;
7707+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
7708+ while (bindex++ <= bend)
7709+ au_hdput(p++);
7710+ }
027c5e7a
AM
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);
4a4d8108
AM
7778+}
7779+
1facf9fc 7780+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
7781+{
7782+ int err, sz;
7783+ struct au_hdentry *hdp;
7784+
1308ab2a 7785+ AuRwMustWriteLock(&dinfo->di_rwsem);
7786+
1facf9fc 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+{
dece6358 7856+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 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) {
027c5e7a
AM
7868+ if (au_ftest_lock(flags, IW)) {
7869+ au_dbg_verify_dinode(d);
1facf9fc 7870+ ii_write_unlock(d->d_inode);
027c5e7a
AM
7871+ } else if (au_ftest_lock(flags, IR)) {
7872+ au_dbg_verify_dinode(d);
1facf9fc 7873+ ii_read_unlock(d->d_inode);
027c5e7a 7874+ }
1facf9fc 7875+ }
dece6358 7876+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 7877+}
7878+
7879+void di_downgrade_lock(struct dentry *d, int flags)
7880+{
1facf9fc 7881+ if (d->d_inode && au_ftest_lock(flags, IR))
7882+ ii_downgrade_lock(d->d_inode);
dece6358 7883+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 7884+}
7885+
7886+void di_write_lock(struct dentry *d, unsigned int lsc)
7887+{
dece6358 7888+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 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+{
027c5e7a 7895+ au_dbg_verify_dinode(d);
1facf9fc 7896+ if (d->d_inode)
7897+ ii_write_unlock(d->d_inode);
dece6358 7898+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 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)
dece6358 7937+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 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+
1308ab2a 7948+ DiMustAnyLock(dentry);
7949+
1facf9fc 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;
027c5e7a 7954+ AuDebugOn(d && d->d_count <= 0);
1facf9fc 7955+ return d;
7956+}
7957+
2cbb1c4b
JR
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+
1facf9fc 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;
027c5e7a 8042+ struct au_branch *br;
1facf9fc 8043+
1308ab2a 8044+ DiMustWriteLock(dentry);
8045+
4a4d8108 8046+ au_hdput(hd);
1facf9fc 8047+ hd->hd_dentry = h_dentry;
027c5e7a
AM
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;
1facf9fc 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;
4a4d8108 8094+ struct au_hdentry *hdp;
1facf9fc 8095+
1308ab2a 8096+ DiMustWriteLock(dentry);
8097+
1facf9fc 8098+ dinfo = au_di(dentry);
8099+ if (!dinfo || dinfo->di_bstart < 0)
8100+ return;
8101+
4a4d8108 8102+ hdp = dinfo->di_hdentry;
1facf9fc 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++) {
4a4d8108 8108+ h_d = hdp[0 + bindex].hd_dentry;
1facf9fc 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)
4a4d8108 8116+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 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)
4a4d8108 8126+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 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);
7f207e10 8155+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 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+}
7f207e10
AM
8177diff -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
367653fa 8179+++ linux/fs/aufs/dir.c 2013-07-30 22:42:55.839613269 +0200
86dc4139 8180@@ -0,0 +1,632 @@
1facf9fc 8181+/*
7a9e40b8 8182+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+{
9dbd164d
AM
8208+ unsigned int nlink;
8209+
1facf9fc 8210+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8211+
9dbd164d
AM
8212+ nlink = dir->i_nlink;
8213+ nlink += h_dir->i_nlink - 2;
1facf9fc 8214+ if (h_dir->i_nlink < 2)
9dbd164d 8215+ nlink += 2;
86dc4139 8216+ smp_mb();
7eafdf33 8217+ /* 0 can happen in revaliding */
92d182d2 8218+ set_nlink(dir, nlink);
1facf9fc 8219+}
8220+
8221+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
8222+{
9dbd164d
AM
8223+ unsigned int nlink;
8224+
1facf9fc 8225+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8226+
9dbd164d
AM
8227+ nlink = dir->i_nlink;
8228+ nlink -= h_dir->i_nlink - 2;
1facf9fc 8229+ if (h_dir->i_nlink < 2)
9dbd164d 8230+ nlink -= 2;
86dc4139 8231+ smp_mb();
92d182d2 8232+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 8233+ set_nlink(dir, nlink);
1facf9fc 8234+}
8235+
1308ab2a 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) {
c06a8ce3
AM
8245+ AuDebugOn(!file_inode(file));
8246+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
1308ab2a 8247+
4a4d8108 8248+ bend = au_fbend_dir(file);
1308ab2a 8249+ for (bindex = au_fbstart(file);
8250+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
8251+ bindex++) {
4a4d8108 8252+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
8253+ if (h_file && file_inode(h_file))
8254+ sz += vfsub_f_size_read(h_file);
1308ab2a 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+
1facf9fc 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);
4a4d8108 8299+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 8300+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 8301+ au_set_fbend_dir(file, btail);
1facf9fc 8302+
4a4d8108 8303+ flags = vfsub_file_flags(file);
1facf9fc 8304+ for (bindex = bstart; bindex <= btail; bindex++) {
8305+ h_dentry = au_h_dptr(dentry, bindex);
8306+ if (!h_dentry)
8307+ continue;
4a4d8108 8308+ h_file = au_hf_dir(file, bindex);
1facf9fc 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+
4f0767ce 8323+out:
1facf9fc 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+
1308ab2a 8334+ FiMustWriteLock(file);
8335+
1facf9fc 8336+ dentry = file->f_dentry;
027c5e7a
AM
8337+ err = au_alive_dir(dentry);
8338+ if (unlikely(err))
8339+ goto out;
8340+
1facf9fc 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);
4a4d8108 8345+ au_set_fbend_dir(file, btail);
1facf9fc 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);
4a4d8108
AM
8368+ au_set_fbend_dir(file, -1);
8369+
027c5e7a 8370+out:
1facf9fc 8371+ return err;
8372+}
8373+
8374+static int aufs_open_dir(struct inode *inode __maybe_unused,
8375+ struct file *file)
8376+{
4a4d8108
AM
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);
e49829fe 8384+ fidir = au_fidir_alloc(sb);
4a4d8108
AM
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;
1facf9fc 8392+}
8393+
8394+static int aufs_release_dir(struct inode *inode __maybe_unused,
8395+ struct file *file)
8396+{
8397+ struct au_vdir *vdir_cache;
4a4d8108
AM
8398+ struct au_finfo *finfo;
8399+ struct au_fidir *fidir;
8400+ aufs_bindex_t bindex, bend;
1facf9fc 8401+
4a4d8108
AM
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;
1facf9fc 8421+ }
1facf9fc 8422+ au_finfo_fin(file);
1facf9fc 8423+ return 0;
8424+}
8425+
8426+/* ---------------------------------------------------------------------- */
8427+
4a4d8108
AM
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+
1facf9fc 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;
1facf9fc 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;
1facf9fc 8471+
1facf9fc 8472+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 8473+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 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;
1facf9fc 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;
c06a8ce3 8492+ inode = file_inode(file);
4a4d8108 8493+ bend = au_fbend_dir(file);
1facf9fc 8494+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 8495+ h_file = au_hf_dir(file, bindex);
1facf9fc 8496+ if (!h_file || au_test_ro(sb, bindex, inode))
8497+ continue;
8498+
53392da6 8499+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 8500+ }
8501+
4f0767ce 8502+out:
1facf9fc 8503+ return err;
8504+}
8505+
8506+/*
8507+ * @file may be NULL
8508+ */
1e00d052
AM
8509+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
8510+ int datasync)
1facf9fc 8511+{
8512+ int err;
b752ccd1 8513+ struct dentry *dentry;
1facf9fc 8514+ struct super_block *sb;
1e00d052 8515+ struct mutex *mtx;
1facf9fc 8516+
8517+ err = 0;
1e00d052
AM
8518+ dentry = file->f_dentry;
8519+ mtx = &dentry->d_inode->i_mutex;
8520+ mutex_lock(mtx);
1facf9fc 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);
1e00d052 8535+ mutex_unlock(mtx);
1facf9fc 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;
9dbd164d 8545+ struct inode *inode, *h_inode;
1facf9fc 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;
027c5e7a
AM
8557+ err = au_alive_dir(dentry);
8558+ if (!err)
8559+ err = au_vdir_init(file);
1facf9fc 8560+ di_downgrade_lock(dentry, AuLock_IR);
8561+ if (unlikely(err))
8562+ goto out_unlock;
8563+
9dbd164d 8564+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 8565+ if (!au_test_nfsd()) {
1facf9fc 8566+ err = au_vdir_fill_de(file, dirent, filldir);
9dbd164d 8567+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 8568+ } else {
8569+ /*
8570+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
8571+ * encode_fh() and others.
8572+ */
9dbd164d 8573+ atomic_inc(&h_inode->i_count);
1facf9fc 8574+ di_read_unlock(dentry, AuLock_IR);
8575+ si_read_unlock(sb);
1facf9fc 8576+ err = au_vdir_fill_de(file, dirent, filldir);
1facf9fc 8577+ fsstack_copy_attr_atime(inode, h_inode);
8578+ fi_write_unlock(file);
9dbd164d 8579+ iput(h_inode);
1facf9fc 8580+
8581+ AuTraceErr(err);
8582+ return err;
8583+ }
8584+
4f0767ce 8585+out_unlock:
1facf9fc 8586+ di_read_unlock(dentry, AuLock_IR);
8587+ fi_write_unlock(file);
4f0767ce 8588+out:
1facf9fc 8589+ si_read_unlock(sb);
8590+ return err;
8591+}
8592+
8593+/* ---------------------------------------------------------------------- */
8594+
8595+#define AuTestEmpty_WHONLY 1
dece6358
AM
8596+#define AuTestEmpty_CALLED (1 << 1)
8597+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 8598+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
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)
1facf9fc 8603+
dece6358
AM
8604+#ifndef CONFIG_AUFS_SHWH
8605+#undef AuTestEmpty_SHWH
8606+#define AuTestEmpty_SHWH 0
8607+#endif
8608+
1facf9fc 8609+struct test_empty_arg {
1308ab2a 8610+ struct au_nhash *whlist;
1facf9fc 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,
dece6358
AM
8617+ loff_t offset __maybe_unused, u64 ino,
8618+ unsigned int d_type)
1facf9fc 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)
1308ab2a 8633+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 8634+ arg->err = -ENOTEMPTY;
8635+ goto out;
8636+ }
8637+
8638+ name += AUFS_WH_PFX_LEN;
8639+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 8640+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 8641+ arg->err = au_nhash_append_wh
1308ab2a 8642+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 8643+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 8644+
4f0767ce 8645+out:
1facf9fc 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)
c06a8ce3 8665+ && !file_inode(h_file)->i_nlink)
1facf9fc 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+
4f0767ce 8677+out_put:
1facf9fc 8678+ fput(h_file);
8679+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 8680+out:
1facf9fc 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;
53392da6 8704+ /* todo: i_mode changes anytime? */
1facf9fc 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;
1308ab2a 8730+ unsigned int rdhash;
1facf9fc 8731+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 8732+ struct au_nhash whlist;
1facf9fc 8733+ struct test_empty_arg arg;
1facf9fc 8734+
dece6358
AM
8735+ SiMustAnyLock(dentry->d_sb);
8736+
1308ab2a 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);
dece6358 8741+ if (unlikely(err))
1facf9fc 8742+ goto out;
8743+
1facf9fc 8744+ arg.flags = 0;
1308ab2a 8745+ arg.whlist = &whlist;
8746+ bstart = au_dbstart(dentry);
dece6358
AM
8747+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8748+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 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+
4f0767ce 8766+out_whlist:
1308ab2a 8767+ au_nhash_wh_free(&whlist);
4f0767ce 8768+out:
1facf9fc 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;
1308ab2a 8779+ arg.whlist = whlist;
1facf9fc 8780+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
8781+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
8782+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 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 = {
4a4d8108 8800+ .owner = THIS_MODULE,
027c5e7a 8801+ .llseek = default_llseek,
1facf9fc 8802+ .read = generic_read_dir,
8803+ .readdir = aufs_readdir,
8804+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
8805+#ifdef CONFIG_COMPAT
8806+ .compat_ioctl = aufs_compat_ioctl_dir,
8807+#endif
1facf9fc 8808+ .open = aufs_open_dir,
8809+ .release = aufs_release_dir,
4a4d8108 8810+ .flush = aufs_flush_dir,
1facf9fc 8811+ .fsync = aufs_fsync_dir
8812+};
7f207e10
AM
8813diff -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
367653fa 8815+++ linux/fs/aufs/dir.h 2013-07-30 22:42:55.839613269 +0200
f6c5ef8b 8816@@ -0,0 +1,137 @@
1facf9fc 8817+/*
7a9e40b8 8818+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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>
1facf9fc 8845+
8846+/* ---------------------------------------------------------------------- */
8847+
8848+/* need to be faster and smaller */
8849+
8850+struct au_nhash {
dece6358
AM
8851+ unsigned int nh_num;
8852+ struct hlist_head *nh_head;
1facf9fc 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;
4a4d8108 8863+} ____cacheline_aligned_in_smp;
1facf9fc 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;
dece6358
AM
8874+#ifdef CONFIG_AUFS_SHWH
8875+ ino_t wh_ino;
1facf9fc 8876+ aufs_bindex_t wh_bindex;
dece6358
AM
8877+ unsigned char wh_type;
8878+#else
8879+ aufs_bindex_t wh_bindex;
8880+#endif
8881+ /* caution: packed */
1facf9fc 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;
1facf9fc 8893+ struct {
8894+ unsigned long ul;
8895+ union au_vdir_deblk_p p;
8896+ } vd_last;
8897+
8898+ unsigned long vd_version;
dece6358 8899+ unsigned int vd_deblk_sz;
1facf9fc 8900+ unsigned long vd_jiffy;
4a4d8108 8901+} ____cacheline_aligned_in_smp;
1facf9fc 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);
1308ab2a 8909+loff_t au_dir_size(struct file *file, struct dentry *dentry);
1facf9fc 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 */
1308ab2a 8914+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
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);
1facf9fc 8917+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
8918+ int limit);
dece6358
AM
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);
1facf9fc 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+
1308ab2a 8930+#ifdef CONFIG_AUFS_RDU
8931+/* rdu.c */
8932+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
8933+#ifdef CONFIG_COMPAT
8934+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
8935+ unsigned long arg);
8936+#endif
1308ab2a 8937+#else
8938+static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
8939+ unsigned long arg)
8940+{
8941+ return -EINVAL;
8942+}
b752ccd1
AM
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
1308ab2a 8950+#endif
8951+
1facf9fc 8952+#endif /* __KERNEL__ */
8953+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
8954diff -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
367653fa 8956+++ linux/fs/aufs/dynop.c 2013-07-30 22:42:55.839613269 +0200
b4510431 8957@@ -0,0 +1,379 @@
1facf9fc 8958+/*
7a9e40b8 8959+ * Copyright (C) 2010-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 8974+ */
8975+
8976+/*
4a4d8108 8977+ * dynamically customizable operations for regular files
1facf9fc 8978+ */
8979+
1facf9fc 8980+#include "aufs.h"
8981+
4a4d8108 8982+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 8983+
4a4d8108
AM
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)
1facf9fc 8991+{
4a4d8108
AM
8992+ struct au_dykey *key, *tmp;
8993+ struct list_head *head;
1facf9fc 8994+
4a4d8108
AM
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;
1facf9fc 9007+}
9008+
4a4d8108 9009+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 9010+{
4a4d8108
AM
9011+ struct au_dykey **k, *found;
9012+ const void *h_op = key->dk_op.dy_hop;
9013+ int i;
1facf9fc 9014+
4a4d8108
AM
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;
1facf9fc 9042+}
9043+
4a4d8108
AM
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;
1facf9fc 9050+
4a4d8108
AM
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);
1facf9fc 9063+
4a4d8108
AM
9064+ if (!found)
9065+ DyPrSym(key);
9066+ return found;
9067+}
9068+
9069+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 9070+{
4a4d8108
AM
9071+ struct au_dykey *key;
9072+
9073+ key = container_of(rcu, struct au_dykey, dk_rcu);
9074+ DyPrSym(key);
9075+ kfree(key);
1facf9fc 9076+}
9077+
4a4d8108
AM
9078+static void dy_free(struct kref *kref)
9079+{
9080+ struct au_dykey *key;
9081+ struct au_splhead *spl;
1facf9fc 9082+
4a4d8108
AM
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)
1facf9fc 9090+{
4a4d8108
AM
9091+ kref_put(&key->dk_kref, dy_free);
9092+}
1facf9fc 9093+
4a4d8108
AM
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
4f0767ce 9100+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
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 */
4a4d8108
AM
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);
027c5e7a 9146+ DySetAop(freepage);
4a4d8108
AM
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);
b4510431
AM
9154+ DySetAop(swap_activate);
9155+ DySetAop(swap_deactivate);
4a4d8108
AM
9156+
9157+ DyDbgSize(cnt, *h_aop);
9158+ dyaop->da_get_xip_mem = h_aop->get_xip_mem;
9159+}
9160+
4a4d8108
AM
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;
b752ccd1 9172+ struct op {
4a4d8108 9173+ unsigned int sz;
b752ccd1
AM
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[] = {
4a4d8108
AM
9178+ [AuDy_AOP] = {
9179+ .sz = sizeof(struct au_dyaop),
b752ccd1 9180+ .set = dy_aop
4a4d8108 9181+ }
b752ccd1
AM
9182+ };
9183+ const struct op *p;
4a4d8108
AM
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);
86dc4139 9199+ p->set(key, op->dy_hop, au_br_sb(br));
4a4d8108
AM
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+
b752ccd1
AM
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+
4a4d8108
AM
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+
4a4d8108
AM
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));
4a4d8108
AM
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+}
7f207e10
AM
9337diff -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
86dc4139 9339+++ linux/fs/aufs/dynop.h 2013-07-06 13:20:47.740198107 +0200
f6c5ef8b 9340@@ -0,0 +1,76 @@
4a4d8108 9341+/*
7a9e40b8 9342+ * Copyright (C) 2010-2013 Junjiro R. Okajima
4a4d8108
AM
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+
4a4d8108
AM
9368+#include "inode.h"
9369+
2cbb1c4b 9370+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
9371+
9372+struct au_dynop {
9373+ int dy_type;
9374+ union {
9375+ const void *dy_hop;
9376+ const struct address_space_operations *dy_haop;
4a4d8108
AM
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+
4a4d8108
AM
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);
b752ccd1 9409+int au_dy_irefresh(struct inode *inode);
4a4d8108 9410+void au_dy_arefresh(int do_dio);
4a4d8108
AM
9411+
9412+void __init au_dy_init(void);
9413+void au_dy_fin(void);
9414+
4a4d8108
AM
9415+#endif /* __KERNEL__ */
9416+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
9417diff -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
367653fa 9419+++ linux/fs/aufs/export.c 2013-07-30 22:42:55.839613269 +0200
c06a8ce3 9420@@ -0,0 +1,826 @@
4a4d8108 9421+/*
7a9e40b8 9422+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
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>
7eafdf33 9444+#include <linux/fs_struct.h>
4a4d8108
AM
9445+#include <linux/namei.h>
9446+#include <linux/nsproxy.h>
9447+#include <linux/random.h>
9448+#include <linux/writeback.h>
7eafdf33 9449+#include "../fs/mount.h"
4a4d8108
AM
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+{
027c5e7a 9508+ /* note: read d_flags without d_lock */
4a4d8108
AM
9509+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
9510+}
9511+
a2a7ad62
AM
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+
4a4d8108
AM
9527+/* ---------------------------------------------------------------------- */
9528+/* inode generation external table */
9529+
b752ccd1 9530+void au_xigen_inc(struct inode *inode)
4a4d8108 9531+{
4a4d8108
AM
9532+ loff_t pos;
9533+ ssize_t sz;
9534+ __u32 igen;
9535+ struct super_block *sb;
9536+ struct au_sbinfo *sbinfo;
9537+
4a4d8108 9538+ sb = inode->i_sb;
b752ccd1 9539+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 9540+
b752ccd1 9541+ sbinfo = au_sbi(sb);
1facf9fc 9542+ pos = inode->i_ino;
9543+ pos *= sizeof(igen);
9544+ igen = inode->i_generation + 1;
1facf9fc 9545+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
9546+ sizeof(igen), &pos);
9547+ if (sz == sizeof(igen))
b752ccd1 9548+ return; /* success */
1facf9fc 9549+
b752ccd1 9550+ if (unlikely(sz >= 0))
1facf9fc 9551+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 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;
dece6358 9568+ SiMustAnyLock(sb);
1facf9fc 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+
c06a8ce3 9585+ if (vfsub_f_size_read(file)
1facf9fc 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+
4f0767ce 9602+out:
1facf9fc 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+
dece6358
AM
9612+ SiMustWriteLock(sb);
9613+
1facf9fc 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+
4f0767ce 9624+out:
1facf9fc 9625+ return err;
9626+}
9627+
9628+void au_xigen_clr(struct super_block *sb)
9629+{
9630+ struct au_sbinfo *sbinfo;
9631+
dece6358
AM
9632+ SiMustWriteLock(sb);
9633+
1facf9fc 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)
537831f9 9659+ || sigen != au_iigen(inode, NULL)))
1facf9fc 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 {
027c5e7a 9666+ spin_lock(&inode->i_lock);
c06a8ce3 9667+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 9668+ spin_lock(&d->d_lock);
1facf9fc 9669+ if (!au_test_anon(d)
9670+ && d->d_parent->d_inode->i_ino == dir_ino) {
027c5e7a
AM
9671+ dentry = dget_dlock(d);
9672+ spin_unlock(&d->d_lock);
1facf9fc 9673+ break;
9674+ }
027c5e7a
AM
9675+ spin_unlock(&d->d_lock);
9676+ }
9677+ spin_unlock(&inode->i_lock);
1facf9fc 9678+ }
027c5e7a 9679+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 9680+ /* need to refresh */
1facf9fc 9681+ dput(dentry);
2cbb1c4b 9682+ dentry = NULL;
1facf9fc 9683+ }
9684+
4f0767ce 9685+out_iput:
1facf9fc 9686+ iput(inode);
4f0767ce 9687+out:
2cbb1c4b 9688+ AuTraceErrPtr(dentry);
1facf9fc 9689+ return dentry;
9690+}
9691+
9692+/* ---------------------------------------------------------------------- */
9693+
9694+/* todo: dirty? */
9695+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
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+
1facf9fc 9715+static struct vfsmount *au_mnt_get(struct super_block *sb)
9716+{
4a4d8108 9717+ int err;
7eafdf33 9718+ struct path root;
4a4d8108
AM
9719+ struct au_compare_mnt_args args = {
9720+ .sb = sb
9721+ };
1facf9fc 9722+
7eafdf33 9723+ get_fs_root(current->fs, &root);
0c3ec466 9724+ br_read_lock(&vfsmount_lock);
7eafdf33 9725+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
0c3ec466 9726+ br_read_unlock(&vfsmount_lock);
7eafdf33 9727+ path_put(&root);
4a4d8108
AM
9728+ AuDebugOn(!err);
9729+ AuDebugOn(!args.mnt);
9730+ return args.mnt;
1facf9fc 9731+}
9732+
9733+struct au_nfsd_si_lock {
4a4d8108 9734+ unsigned int sigen;
027c5e7a 9735+ aufs_bindex_t bindex, br_id;
1facf9fc 9736+ unsigned char force_lock;
9737+};
9738+
027c5e7a
AM
9739+static int si_nfsd_read_lock(struct super_block *sb,
9740+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 9741+{
027c5e7a 9742+ int err;
1facf9fc 9743+ aufs_bindex_t bindex;
9744+
9745+ si_read_lock(sb, AuLock_FLUSH);
9746+
9747+ /* branch id may be wrapped around */
027c5e7a 9748+ err = 0;
1facf9fc 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+
027c5e7a
AM
9753+ err = -ESTALE;
9754+ bindex = -1;
1facf9fc 9755+ if (!nsi_lock->force_lock)
9756+ si_read_unlock(sb);
1facf9fc 9757+
4f0767ce 9758+out:
027c5e7a
AM
9759+ nsi_lock->bindex = bindex;
9760+ return err;
1facf9fc 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);
4a4d8108 9798+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 9799+ dentry = (void *)file;
9800+ if (IS_ERR(file))
9801+ goto out;
9802+
9803+ dentry = ERR_PTR(-ENOMEM);
537831f9 9804+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 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;
1716fcea
AM
9817+ /* instead of ENOENT */
9818+ dentry = ERR_PTR(-ESTALE);
1facf9fc 9819+ if (!arg.found)
9820+ goto out_name;
9821+
b4510431 9822+ /* do not call vfsub_lkup_one() */
1facf9fc 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+
4f0767ce 9836+out_name:
537831f9 9837+ free_page((unsigned long)arg.name);
4f0767ce 9838+out_file:
1facf9fc 9839+ fput(file);
4f0767ce 9840+out:
1facf9fc 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+
4f0767ce 9871+out:
1facf9fc 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+
4f0767ce 9912+out:
1facf9fc 9913+ AuTraceErrPtr(p);
9914+ return p;
9915+}
9916+
9917+static
027c5e7a
AM
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)
1facf9fc 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+
027c5e7a 9929+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 9930+ h_mnt = au_br_mnt(br);
1facf9fc 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);
027c5e7a 9957+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 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+
4f0767ce 9980+out_path:
1facf9fc 9981+ path_put(&path);
4f0767ce 9982+out_relock:
1facf9fc 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+ }
4f0767ce 9988+out_pathname:
1facf9fc 9989+ free_page((unsigned long)pathname);
4f0767ce 9990+out_h_parent:
1facf9fc 9991+ dput(h_parent);
4f0767ce 9992+out:
1facf9fc 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;
027c5e7a 10005+ struct au_branch *br;
1facf9fc 10006+ ino_t ino, dir_ino;
1facf9fc 10007+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 10008+ .force_lock = 0
10009+ };
10010+
1facf9fc 10011+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
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+
1facf9fc 10018+ /* branch id may be wrapped around */
027c5e7a
AM
10019+ br = NULL;
10020+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 10021+ goto out;
10022+ nsi_lock.force_lock = 1;
10023+
10024+ /* is this inode still cached? */
10025+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
10026+ /* it should never happen */
10027+ if (unlikely(ino == AUFS_ROOT_INO))
10028+ goto out;
10029+
1facf9fc 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? */
027c5e7a
AM
10038+ br = au_sbr(sb, nsi_lock.bindex);
10039+ atomic_inc(&br->br_count);
1facf9fc 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 */
027c5e7a 10047+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 10048+ if (IS_ERR(dentry))
10049+ goto out_unlock;
10050+ if (unlikely(!dentry))
10051+ /* todo?: make it ESTALE */
10052+ goto out_unlock;
10053+
4f0767ce 10054+accept:
027c5e7a
AM
10055+ if (!au_digen_test(dentry, au_sigen(sb))
10056+ && dentry->d_inode->i_generation == fh[Fh_igen])
1facf9fc 10057+ goto out_unlock; /* success */
10058+
10059+ dput(dentry);
10060+ dentry = ERR_PTR(-ESTALE);
4f0767ce 10061+out_unlock:
027c5e7a
AM
10062+ if (br)
10063+ atomic_dec(&br->br_count);
1facf9fc 10064+ si_read_unlock(sb);
4f0767ce 10065+out:
1facf9fc 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+
4f0767ce 10087+out:
1facf9fc 10088+ AuTraceErrPtr(parent);
10089+ return parent;
10090+}
10091+#endif
10092+
10093+/* ---------------------------------------------------------------------- */
10094+
0c3ec466
AM
10095+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
10096+ struct inode *dir)
1facf9fc 10097+{
10098+ int err;
0c3ec466 10099+ aufs_bindex_t bindex;
1facf9fc 10100+ struct super_block *sb, *h_sb;
0c3ec466
AM
10101+ struct dentry *dentry, *parent, *h_parent;
10102+ struct inode *h_dir;
1facf9fc 10103+ struct au_branch *br;
10104+
1facf9fc 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;
0c3ec466
AM
10112+ if (inode->i_ino == AUFS_ROOT_INO) {
10113+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 10114+ goto out;
10115+ }
10116+
1facf9fc 10117+ h_parent = NULL;
0c3ec466
AM
10118+ sb = inode->i_sb;
10119+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
10120+ if (unlikely(err))
10121+ goto out;
10122+
1facf9fc 10123+#ifdef CONFIG_AUFS_DEBUG
10124+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10125+ AuWarn1("NFS-exporting requires xino\n");
10126+#endif
027c5e7a 10127+ err = -EIO;
0c3ec466
AM
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;
1facf9fc 10141+ }
0c3ec466
AM
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);
1facf9fc 10149+ if (unlikely(!h_parent))
0c3ec466 10150+ goto out_hparent;
1facf9fc 10151+
10152+ err = -EPERM;
10153+ br = au_sbr(sb, bindex);
86dc4139 10154+ h_sb = au_br_sb(br);
1facf9fc 10155+ if (unlikely(!h_sb->s_export_op)) {
10156+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 10157+ goto out_hparent;
1facf9fc 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);
0c3ec466 10163+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 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? */
1716fcea 10173+ if (err != FILEID_INVALID)
1facf9fc 10174+ err = 99;
10175+ else
10176+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
10177+
0c3ec466 10178+out_hparent:
1facf9fc 10179+ dput(h_parent);
0c3ec466 10180+out_parent:
1facf9fc 10181+ dput(parent);
0c3ec466
AM
10182+out_unlock:
10183+ ii_read_unlock(inode);
10184+ si_read_unlock(sb);
4f0767ce 10185+out:
1facf9fc 10186+ if (unlikely(err < 0))
1716fcea 10187+ err = FILEID_INVALID;
1facf9fc 10188+ return err;
10189+}
10190+
10191+/* ---------------------------------------------------------------------- */
10192+
4a4d8108
AM
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;
e49829fe 10202+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
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+
1facf9fc 10228+static struct export_operations aufs_export_op = {
4a4d8108 10229+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 10230+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
10231+ .encode_fh = aufs_encode_fh,
10232+ .commit_metadata = aufs_commit_metadata
1facf9fc 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+}
7f207e10
AM
10247diff -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
367653fa
AM
10249+++ linux/fs/aufs/file.c 2013-07-30 22:42:55.842946719 +0200
10250@@ -0,0 +1,689 @@
1facf9fc 10251+/*
7a9e40b8 10252+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 10267+ */
10268+
10269+/*
4a4d8108 10270+ * handling file/dir, and address_space operation
1facf9fc 10271+ */
10272+
7eafdf33
AM
10273+#ifdef CONFIG_AUFS_DEBUG
10274+#include <linux/migrate.h>
10275+#endif
4a4d8108 10276+#include <linux/pagemap.h>
1facf9fc 10277+#include "aufs.h"
10278+
4a4d8108
AM
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)
1facf9fc 10290+{
1308ab2a 10291+ struct file *h_file;
4a4d8108
AM
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;
1facf9fc 10298+
4a4d8108
AM
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);
b752ccd1 10302+ if (au_test_nfsd() && !h_dentry)
4a4d8108
AM
10303+ goto out;
10304+ h_inode = h_dentry->d_inode;
b752ccd1 10305+ if (au_test_nfsd() && !h_inode)
4a4d8108 10306+ goto out;
027c5e7a
AM
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))
4a4d8108 10314+ goto out;
1facf9fc 10315+
4a4d8108
AM
10316+ sb = dentry->d_sb;
10317+ br = au_sbr(sb, bindex);
10318+ h_file = ERR_PTR(-EACCES);
2cbb1c4b 10319+ exec_flag = flags & __FMODE_EXEC;
86dc4139 10320+ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
027c5e7a 10321+ goto out;
1facf9fc 10322+
4a4d8108
AM
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;
86dc4139 10329+ h_path.mnt = au_br_mnt(br);
4a4d8108
AM
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);
dece6358 10341+ }
4a4d8108
AM
10342+ if (IS_ERR(h_file))
10343+ goto out_br;
dece6358 10344+
4a4d8108
AM
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+ }
953406b4 10353+ fsnotify_open(h_file);
4a4d8108 10354+ goto out; /* success */
1facf9fc 10355+
4f0767ce 10356+out_br:
4a4d8108 10357+ atomic_dec(&br->br_count);
4f0767ce 10358+out:
4a4d8108
AM
10359+ return h_file;
10360+}
1308ab2a 10361+
4a4d8108
AM
10362+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
10363+ struct au_fidir *fidir)
1facf9fc 10364+{
dece6358 10365+ int err;
1facf9fc 10366+ struct dentry *dentry;
1308ab2a 10367+
4a4d8108
AM
10368+ err = au_finfo_init(file, fidir);
10369+ if (unlikely(err))
10370+ goto out;
1facf9fc 10371+
10372+ dentry = file->f_dentry;
4a4d8108
AM
10373+ di_read_lock_child(dentry, AuLock_IR);
10374+ err = open(file, vfsub_file_flags(file));
10375+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 10376+
4a4d8108
AM
10377+ fi_write_unlock(file);
10378+ if (unlikely(err)) {
10379+ au_fi(file)->fi_hdir = NULL;
10380+ au_finfo_fin(file);
1308ab2a 10381+ }
4a4d8108 10382+
4f0767ce 10383+out:
1308ab2a 10384+ return err;
10385+}
dece6358 10386+
4a4d8108 10387+int au_reopen_nondir(struct file *file)
1308ab2a 10388+{
4a4d8108
AM
10389+ int err;
10390+ aufs_bindex_t bstart;
10391+ struct dentry *dentry;
10392+ struct file *h_file, *h_file_tmp;
1308ab2a 10393+
4a4d8108
AM
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);
86dc4139
AM
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); */
1308ab2a 10418+
4a4d8108
AM
10419+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
10420+ file);
10421+ err = PTR_ERR(h_file);
86dc4139
AM
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+ }
4a4d8108 10428+ goto out; /* todo: close all? */
86dc4139 10429+ }
4a4d8108
AM
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+
4f0767ce 10438+out:
4a4d8108
AM
10439+ if (h_file_tmp)
10440+ fput(h_file_tmp);
10441+ return err;
1facf9fc 10442+}
10443+
1308ab2a 10444+/* ---------------------------------------------------------------------- */
10445+
4a4d8108
AM
10446+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
10447+ struct dentry *hi_wh)
1facf9fc 10448+{
4a4d8108
AM
10449+ int err;
10450+ aufs_bindex_t bstart;
10451+ struct au_dinfo *dinfo;
10452+ struct dentry *h_dentry;
10453+ struct au_hdentry *hdp;
1facf9fc 10454+
4a4d8108
AM
10455+ dinfo = au_di(file->f_dentry);
10456+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 10457+
4a4d8108
AM
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;
1facf9fc 10466+
1facf9fc 10467+ return err;
10468+}
10469+
4a4d8108 10470+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 10471+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 10472+{
4a4d8108 10473+ int err;
027c5e7a
AM
10474+ struct inode *inode, *h_inode;
10475+ struct dentry *dentry, *h_dentry, *hi_wh;
1facf9fc 10476+
dece6358 10477+ dentry = file->f_dentry;
4a4d8108 10478+ au_update_dbstart(dentry);
dece6358 10479+ inode = dentry->d_inode;
027c5e7a
AM
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+ }
4a4d8108 10486+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 10487+ if (!hi_wh && !h_inode)
86dc4139 10488+ err = au_sio_cpup_wh(dentry, bcpup, len, file, pin);
4a4d8108
AM
10489+ else
10490+ /* already copied-up after unlink */
10491+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 10492+
4a4d8108
AM
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));
1308ab2a 10497+
dece6358 10498+ return err;
1facf9fc 10499+}
10500+
4a4d8108
AM
10501+/*
10502+ * prepare the @file for writing.
10503+ */
10504+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 10505+{
4a4d8108 10506+ int err;
027c5e7a 10507+ aufs_bindex_t bstart, bcpup, dbstart;
4a4d8108 10508+ struct dentry *dentry, *parent, *h_dentry;
86dc4139 10509+ struct inode *inode;
1facf9fc 10510+ struct super_block *sb;
4a4d8108 10511+ struct file *h_file;
1facf9fc 10512+
10513+ dentry = file->f_dentry;
1facf9fc 10514+ sb = dentry->d_sb;
4a4d8108
AM
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);
1facf9fc 10521+ goto out;
4a4d8108 10522+ }
1facf9fc 10523+
027c5e7a 10524+ /* need to cpup or reopen */
4a4d8108
AM
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+
027c5e7a 10533+ if (!d_unhashed(dentry) && !au_h_dptr(parent, bcpup)) {
4a4d8108 10534+ err = au_cpup_dirs(dentry, bcpup);
1facf9fc 10535+ if (unlikely(err))
4a4d8108
AM
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;
027c5e7a
AM
10545+ dbstart = au_dbstart(dentry);
10546+ if (dbstart <= bcpup) {
10547+ h_dentry = au_h_dptr(dentry, bcpup);
10548+ AuDebugOn(!h_dentry);
027c5e7a
AM
10549+ bstart = bcpup;
10550+ }
10551+
10552+ if (dbstart <= bcpup /* just reopen */
10553+ || !d_unhashed(dentry) /* copyup and reopen */
10554+ ) {
027c5e7a 10555+ h_file = au_h_open_pre(dentry, bstart);
86dc4139 10556+ if (IS_ERR(h_file))
027c5e7a 10557+ err = PTR_ERR(h_file);
86dc4139 10558+ else {
027c5e7a
AM
10559+ di_downgrade_lock(parent, AuLock_IR);
10560+ if (dbstart > bcpup)
10561+ err = au_sio_cpup_simple(dentry, bcpup, len,
86dc4139 10562+ AuCpup_DTIME, pin);
027c5e7a
AM
10563+ if (!err)
10564+ err = au_reopen_nondir(file);
86dc4139 10565+ au_h_open_post(dentry, bstart, h_file);
027c5e7a 10566+ }
027c5e7a
AM
10567+ } else { /* copyup as wh and reopen */
10568+ /*
10569+ * since writable hfsplus branch is not supported,
10570+ * h_open_pre/post() are unnecessary.
10571+ */
86dc4139 10572+ err = au_ready_to_write_wh(file, len, bcpup, pin);
4a4d8108 10573+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 10574+ }
4a4d8108
AM
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;
1facf9fc 10582+
4f0767ce 10583+out_dgrade:
4a4d8108 10584+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 10585+out_unlock:
4a4d8108 10586+ di_read_unlock(parent, AuLock_IR);
4f0767ce 10587+out_dput:
4a4d8108 10588+ dput(parent);
4f0767ce 10589+out:
1facf9fc 10590+ return err;
10591+}
10592+
4a4d8108
AM
10593+/* ---------------------------------------------------------------------- */
10594+
10595+int au_do_flush(struct file *file, fl_owner_t id,
10596+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 10597+{
4a4d8108 10598+ int err;
1facf9fc 10599+ struct super_block *sb;
4a4d8108 10600+ struct inode *inode;
1facf9fc 10601+
c06a8ce3
AM
10602+ inode = file_inode(file);
10603+ sb = inode->i_sb;
4a4d8108
AM
10604+ si_noflush_read_lock(sb);
10605+ fi_read_lock(file);
b752ccd1 10606+ ii_read_lock_child(inode);
1facf9fc 10607+
4a4d8108
AM
10608+ err = flush(file, id);
10609+ au_cpup_attr_timesizes(inode);
1facf9fc 10610+
b752ccd1 10611+ ii_read_unlock(inode);
4a4d8108 10612+ fi_read_unlock(file);
1308ab2a 10613+ si_read_unlock(sb);
dece6358 10614+ return err;
1facf9fc 10615+}
10616+
4a4d8108
AM
10617+/* ---------------------------------------------------------------------- */
10618+
10619+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 10620+{
4a4d8108
AM
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;
1facf9fc 10627+ struct super_block *sb;
10628+
4a4d8108
AM
10629+ FiMustWriteLock(file);
10630+
10631+ err = 0;
10632+ finfo = au_fi(file);
1308ab2a 10633+ dentry = file->f_dentry;
10634+ sb = dentry->d_sb;
4a4d8108
AM
10635+ inode = dentry->d_inode;
10636+ bstart = au_ibstart(inode);
027c5e7a 10637+ if (bstart == finfo->fi_btop || IS_ROOT(dentry))
1308ab2a 10638+ goto out;
dece6358 10639+
4a4d8108
AM
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;
1facf9fc 10649+ }
1facf9fc 10650+
4a4d8108
AM
10651+ di_read_lock_parent(parent, AuLock_IR);
10652+ hi_wh = au_hi_wh(inode, bstart);
7f207e10
AM
10653+ if (!S_ISDIR(inode->i_mode)
10654+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 10655+ && au_plink_test(inode)
86dc4139
AM
10656+ && !d_unhashed(dentry)
10657+ && bstart < au_dbstart(dentry)) {
4a4d8108
AM
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);
367653fa 10665+ if (!err) {
4a4d8108 10666+ err = au_sio_cpup_simple(dentry, bstart, -1,
86dc4139 10667+ AuCpup_DTIME, &pin);
367653fa
AM
10668+ au_unpin(&pin);
10669+ }
4a4d8108
AM
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+ }
1facf9fc 10675+
4f0767ce 10676+out_unlock:
4a4d8108 10677+ di_read_unlock(parent, AuLock_IR);
4f0767ce 10678+out_parent:
4a4d8108 10679+ dput(parent);
4f0767ce 10680+out:
1308ab2a 10681+ return err;
dece6358 10682+}
1facf9fc 10683+
4a4d8108 10684+static void au_do_refresh_dir(struct file *file)
dece6358 10685+{
4a4d8108
AM
10686+ aufs_bindex_t bindex, bend, new_bindex, brid;
10687+ struct au_hfile *p, tmp, *q;
10688+ struct au_finfo *finfo;
1308ab2a 10689+ struct super_block *sb;
4a4d8108 10690+ struct au_fidir *fidir;
1facf9fc 10691+
4a4d8108 10692+ FiMustWriteLock(file);
1facf9fc 10693+
4a4d8108
AM
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;
1308ab2a 10704+
4a4d8108
AM
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+ }
1308ab2a 10712+
4a4d8108
AM
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+ }
1308ab2a 10723+
4a4d8108 10724+ p = fidir->fd_hfile;
027c5e7a 10725+ if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
4a4d8108
AM
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) {
c06a8ce3 10730+ if (file_inode(p->hf_file))
4a4d8108
AM
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+ }
1308ab2a 10743+
4a4d8108
AM
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) {
c06a8ce3 10748+ if (file_inode(p->hf_file))
4a4d8108
AM
10749+ break;
10750+ else
10751+ au_hfput(p, file);
10752+ }
10753+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 10754+}
10755+
4a4d8108
AM
10756+/*
10757+ * after branch manipulating, refresh the file.
10758+ */
10759+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 10760+{
4a4d8108
AM
10761+ int err, need_reopen;
10762+ aufs_bindex_t bend, bindex;
10763+ struct dentry *dentry;
1308ab2a 10764+ struct au_finfo *finfo;
4a4d8108 10765+ struct au_hfile *hfile;
1facf9fc 10766+
4a4d8108 10767+ dentry = file->f_dentry;
1308ab2a 10768+ finfo = au_fi(file);
4a4d8108
AM
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+ }
1facf9fc 10782+
4a4d8108
AM
10783+ err = 0;
10784+ need_reopen = 1;
10785+ if (!au_test_mmapped(file))
10786+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 10787+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
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+ }
1facf9fc 10800+
4f0767ce 10801+out:
1facf9fc 10802+ return err;
10803+}
10804+
4a4d8108
AM
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)
dece6358 10808+{
1308ab2a 10809+ int err;
4a4d8108
AM
10810+ unsigned int sigen, figen;
10811+ aufs_bindex_t bstart;
10812+ unsigned char pseudo_link;
10813+ struct dentry *dentry;
10814+ struct inode *inode;
1facf9fc 10815+
4a4d8108
AM
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+ }
dece6358 10833+
4a4d8108 10834+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 10835+ if (au_digen_test(dentry, sigen)) {
4a4d8108 10836+ err = au_reval_dpath(dentry, sigen);
027c5e7a 10837+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 10838+ }
dece6358 10839+
027c5e7a
AM
10840+ if (!err)
10841+ err = refresh_file(file, reopen);
4a4d8108
AM
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+ }
1facf9fc 10851+
4f0767ce 10852+out:
1308ab2a 10853+ return err;
10854+}
1facf9fc 10855+
4a4d8108
AM
10856+/* ---------------------------------------------------------------------- */
10857+
10858+/* cf. aufs_nopage() */
10859+/* for madvise(2) */
10860+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 10861+{
4a4d8108
AM
10862+ unlock_page(page);
10863+ return 0;
10864+}
1facf9fc 10865+
4a4d8108
AM
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; }
1facf9fc 10871+
4a4d8108
AM
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; }
1facf9fc 10879+
4a4d8108
AM
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; }
1308ab2a 10892+
4a4d8108
AM
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,
7eafdf33 10900+ struct page *page, enum migrate_mode mode)
4a4d8108
AM
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; }
b4510431
AM
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(); }
4a4d8108
AM
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,
4a4d8108
AM
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,
b4510431
AM
10935+ .error_remove_page = aufs_error_remove_page,
10936+ .swap_activate = aufs_swap_activate,
10937+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 10938+#endif /* CONFIG_AUFS_DEBUG */
dece6358 10939+};
7f207e10
AM
10940diff -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
86dc4139
AM
10942+++ linux/fs/aufs/file.h 2013-07-06 13:20:47.750198454 +0200
10943@@ -0,0 +1,308 @@
4a4d8108 10944+/*
7a9e40b8 10945+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
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+ */
1facf9fc 10961+
4a4d8108
AM
10962+/*
10963+ * file operations
10964+ */
1facf9fc 10965+
4a4d8108
AM
10966+#ifndef __AUFS_FILE_H__
10967+#define __AUFS_FILE_H__
1facf9fc 10968+
4a4d8108 10969+#ifdef __KERNEL__
1facf9fc 10970+
2cbb1c4b 10971+#include <linux/file.h>
4a4d8108
AM
10972+#include <linux/fs.h>
10973+#include <linux/poll.h>
4a4d8108 10974+#include "rwsem.h"
1facf9fc 10975+
4a4d8108
AM
10976+struct au_branch;
10977+struct au_hfile {
10978+ struct file *hf_file;
10979+ struct au_branch *hf_br;
10980+};
1facf9fc 10981+
4a4d8108
AM
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+};
1facf9fc 10989+
4a4d8108 10990+static inline int au_fidir_sz(int nent)
dece6358 10991+{
4f0767ce
JR
10992+ AuDebugOn(nent < 0);
10993+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 10994+}
1facf9fc 10995+
4a4d8108
AM
10996+struct au_finfo {
10997+ atomic_t fi_generation;
dece6358 10998+
4a4d8108
AM
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;
2cbb1c4b 11005+ atomic_t fi_mmapped;
4a4d8108
AM
11006+ };
11007+ struct au_fidir *fi_hdir; /* for dir only */
11008+} ____cacheline_aligned_in_smp;
1facf9fc 11009+
4a4d8108 11010+/* ---------------------------------------------------------------------- */
1facf9fc 11011+
4a4d8108
AM
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));
1facf9fc 11026+
4a4d8108
AM
11027+/* poll.c */
11028+#ifdef CONFIG_AUFS_POLL
11029+unsigned int aufs_poll(struct file *file, poll_table *wait);
11030+#endif
1facf9fc 11031+
4a4d8108
AM
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)
dece6358 11040+{
4a4d8108
AM
11041+ return NULL;
11042+}
1facf9fc 11043+
4a4d8108
AM
11044+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
11045+ struct file *h_file);
11046+#endif
1facf9fc 11047+
4a4d8108
AM
11048+/* f_op.c */
11049+extern const struct file_operations aufs_file_fop;
4a4d8108
AM
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 */
86dc4139 11055+struct au_finfo *au_fi_sp(struct file *file);
4a4d8108
AM
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
86dc4139
AM
11059+static inline struct au_finfo *au_fi_sp(struct file *file)
11060+{
11061+ return NULL;
11062+}
4a4d8108
AM
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
1facf9fc 11070+
4a4d8108
AM
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);
1facf9fc 11075+
4a4d8108 11076+void au_update_figen(struct file *file);
4a4d8108
AM
11077+struct au_fidir *au_fidir_alloc(struct super_block *sb);
11078+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 11079+
4a4d8108
AM
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);
1facf9fc 11083+
4a4d8108
AM
11084+/* ioctl.c */
11085+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
11086+#ifdef CONFIG_COMPAT
11087+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
11088+ unsigned long arg);
11089+#endif
1facf9fc 11090+
4a4d8108 11091+/* ---------------------------------------------------------------------- */
1facf9fc 11092+
4a4d8108
AM
11093+static inline struct au_finfo *au_fi(struct file *file)
11094+{
86dc4139
AM
11095+ struct au_finfo *finfo;
11096+
11097+ finfo = au_fi_sp(file);
11098+ if (!finfo)
11099+ finfo = file->private_data;
11100+ return finfo;
4a4d8108 11101+}
1facf9fc 11102+
4a4d8108 11103+/* ---------------------------------------------------------------------- */
1facf9fc 11104+
4a4d8108
AM
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);
1308ab2a 11110+
4a4d8108
AM
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)
1facf9fc 11114+
1308ab2a 11115+/* ---------------------------------------------------------------------- */
11116+
4a4d8108
AM
11117+/* todo: hard/soft set? */
11118+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 11119+{
4a4d8108
AM
11120+ FiMustAnyLock(file);
11121+ return au_fi(file)->fi_btop;
11122+}
dece6358 11123+
4a4d8108
AM
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+}
1facf9fc 11130+
4a4d8108
AM
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+}
1facf9fc 11137+
4a4d8108
AM
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+}
1facf9fc 11143+
4a4d8108
AM
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+}
1308ab2a 11150+
4a4d8108
AM
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+}
dece6358 11158+
4a4d8108
AM
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+}
1facf9fc 11165+
4a4d8108
AM
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;
dece6358
AM
11171+}
11172+
4a4d8108
AM
11173+/* todo: memory barrier? */
11174+static inline unsigned int au_figen(struct file *f)
dece6358 11175+{
4a4d8108
AM
11176+ return atomic_read(&au_fi(f)->fi_generation);
11177+}
dece6358 11178+
2cbb1c4b
JR
11179+static inline void au_set_mmapped(struct file *f)
11180+{
11181+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
11182+ return;
0c3ec466 11183+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
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+
4a4d8108
AM
11193+static inline int au_test_mmapped(struct file *f)
11194+{
2cbb1c4b
JR
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+{
53392da6
AM
11203+ struct file *f;
11204+
11205+ f = vma->vm_file;
2cbb1c4b
JR
11206+ get_file(file);
11207+ vma->vm_file = file;
53392da6 11208+ fput(f);
2cbb1c4b
JR
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+{
53392da6
AM
11226+ struct file *f;
11227+
2cbb1c4b 11228+ au_do_vm_file_reset(vma, file);
53392da6 11229+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
11230+ get_file(file);
11231+ vma->vm_region->vm_file = file;
53392da6 11232+ fput(f);
2cbb1c4b
JR
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
4a4d8108 11248+}
1308ab2a 11249+
4a4d8108
AM
11250+#endif /* __KERNEL__ */
11251+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
11252diff -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
86dc4139 11254+++ linux/fs/aufs/finfo.c 2013-07-06 13:20:47.750198454 +0200
1716fcea 11255@@ -0,0 +1,157 @@
4a4d8108 11256+/*
7a9e40b8 11257+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
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+ */
1308ab2a 11273+
4a4d8108
AM
11274+/*
11275+ * file private data
11276+ */
1facf9fc 11277+
4a4d8108 11278+#include "aufs.h"
1facf9fc 11279+
4a4d8108
AM
11280+void au_hfput(struct au_hfile *hf, struct file *file)
11281+{
11282+ /* todo: direct access f_flags */
2cbb1c4b 11283+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
11284+ allow_write_access(hf->hf_file);
11285+ fput(hf->hf_file);
11286+ hf->hf_file = NULL;
e49829fe 11287+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
11288+ hf->hf_br = NULL;
11289+}
1facf9fc 11290+
4a4d8108
AM
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);
1308ab2a 11310+ }
4a4d8108 11311+}
1facf9fc 11312+
4a4d8108
AM
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 */
1facf9fc 11317+}
11318+
4a4d8108
AM
11319+/* ---------------------------------------------------------------------- */
11320+
4a4d8108
AM
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+ }
1facf9fc 11356+
dece6358 11357+ return err;
1facf9fc 11358+}
1308ab2a 11359+
11360+/* ---------------------------------------------------------------------- */
11361+
4a4d8108 11362+void au_finfo_fin(struct file *file)
1308ab2a 11363+{
4a4d8108
AM
11364+ struct au_finfo *finfo;
11365+
7f207e10
AM
11366+ au_nfiles_dec(file->f_dentry->d_sb);
11367+
4a4d8108
AM
11368+ finfo = au_fi(file);
11369+ AuDebugOn(finfo->fi_hdir);
11370+ AuRwDestroy(&finfo->fi_rwsem);
11371+ au_cache_free_finfo(finfo);
1308ab2a 11372+}
1308ab2a 11373+
e49829fe 11374+void au_fi_init_once(void *_finfo)
4a4d8108 11375+{
e49829fe 11376+ struct au_finfo *finfo = _finfo;
2cbb1c4b 11377+ static struct lock_class_key aufs_fi;
1308ab2a 11378+
e49829fe
JR
11379+ au_rw_init(&finfo->fi_rwsem);
11380+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 11381+}
1308ab2a 11382+
4a4d8108
AM
11383+int au_finfo_init(struct file *file, struct au_fidir *fidir)
11384+{
1716fcea 11385+ int err;
4a4d8108
AM
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;
7f207e10 11396+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
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);
4a4d8108
AM
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+}
7f207e10
AM
11413diff -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
367653fa 11415+++ linux/fs/aufs/f_op.c 2013-07-30 22:42:55.839613269 +0200
86dc4139 11416@@ -0,0 +1,721 @@
dece6358 11417+/*
7a9e40b8 11418+ * Copyright (C) 2005-2013 Junjiro R. Okajima
dece6358
AM
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+ */
1facf9fc 11434+
11435+/*
4a4d8108 11436+ * file and vm operations
1facf9fc 11437+ */
dece6358 11438+
86dc4139 11439+#include <linux/aio.h>
4a4d8108
AM
11440+#include <linux/fs_stack.h>
11441+#include <linux/mman.h>
4a4d8108 11442+#include <linux/security.h>
dece6358
AM
11443+#include "aufs.h"
11444+
4a4d8108 11445+int au_do_open_nondir(struct file *file, int flags)
1facf9fc 11446+{
4a4d8108
AM
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+
4a4d8108 11455+ dentry = file->f_dentry;
027c5e7a
AM
11456+ err = au_d_alive(dentry);
11457+ if (unlikely(err))
11458+ goto out;
11459+
4a4d8108
AM
11460+ finfo = au_fi(file);
11461+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 11462+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108
AM
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+ }
027c5e7a
AM
11474+
11475+out:
4a4d8108 11476+ return err;
1facf9fc 11477+}
11478+
4a4d8108
AM
11479+static int aufs_open_nondir(struct inode *inode __maybe_unused,
11480+ struct file *file)
1facf9fc 11481+{
4a4d8108 11482+ int err;
1308ab2a 11483+ struct super_block *sb;
1facf9fc 11484+
2cbb1c4b 11485+ AuDbg("%.*s, f_flags 0x%x, f_mode 0x%x\n",
4a4d8108
AM
11486+ AuDLNPair(file->f_dentry), vfsub_file_flags(file),
11487+ file->f_mode);
1facf9fc 11488+
4a4d8108
AM
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+}
1facf9fc 11495+
4a4d8108
AM
11496+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
11497+{
11498+ struct au_finfo *finfo;
11499+ aufs_bindex_t bindex;
1facf9fc 11500+
4a4d8108
AM
11501+ finfo = au_fi(file);
11502+ bindex = finfo->fi_btop;
b4510431 11503+ if (bindex >= 0)
4a4d8108 11504+ au_set_h_fptr(file, bindex, NULL);
7f207e10 11505+
4a4d8108
AM
11506+ au_finfo_fin(file);
11507+ return 0;
1facf9fc 11508+}
11509+
4a4d8108
AM
11510+/* ---------------------------------------------------------------------- */
11511+
11512+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 11513+{
1308ab2a 11514+ int err;
4a4d8108
AM
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+/* ---------------------------------------------------------------------- */
9dbd164d
AM
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+ */
4a4d8108
AM
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;
dece6358 11542+ struct dentry *dentry;
4a4d8108 11543+ struct file *h_file;
dece6358 11544+ struct super_block *sb;
1facf9fc 11545+
dece6358
AM
11546+ dentry = file->f_dentry;
11547+ sb = dentry->d_sb;
e49829fe 11548+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 11549+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
dece6358
AM
11550+ if (unlikely(err))
11551+ goto out;
1facf9fc 11552+
4a4d8108 11553+ h_file = au_hf_top(file);
9dbd164d
AM
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 */
4a4d8108
AM
11559+ err = vfsub_read_u(h_file, buf, count, ppos);
11560+ /* todo: necessary? */
11561+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11562+ /* update without lock, I don't think it a problem */
c06a8ce3 11563+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 11564+ fput(h_file);
1308ab2a 11565+
4f0767ce 11566+out:
dece6358
AM
11567+ si_read_unlock(sb);
11568+ return err;
11569+}
1facf9fc 11570+
e49829fe
JR
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+
4a4d8108
AM
11593+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
11594+ size_t count, loff_t *ppos)
dece6358 11595+{
4a4d8108
AM
11596+ ssize_t err;
11597+ struct au_pin pin;
dece6358 11598+ struct dentry *dentry;
9dbd164d 11599+ struct super_block *sb;
4a4d8108 11600+ struct inode *inode;
4a4d8108
AM
11601+ struct file *h_file;
11602+ char __user *buf = (char __user *)ubuf;
1facf9fc 11603+
dece6358 11604+ dentry = file->f_dentry;
9dbd164d 11605+ sb = dentry->d_sb;
4a4d8108 11606+ inode = dentry->d_inode;
e49829fe 11607+ au_mtx_and_read_lock(inode);
1facf9fc 11608+
4a4d8108
AM
11609+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11610+ if (unlikely(err))
11611+ goto out;
1facf9fc 11612+
4a4d8108
AM
11613+ err = au_ready_to_write(file, -1, &pin);
11614+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11615+ if (unlikely(err)) {
11616+ di_read_unlock(dentry, AuLock_IR);
11617+ fi_write_unlock(file);
11618+ goto out;
11619+ }
1facf9fc 11620+
4a4d8108 11621+ h_file = au_hf_top(file);
9dbd164d 11622+ get_file(h_file);
4a4d8108 11623+ au_unpin(&pin);
9dbd164d
AM
11624+ di_read_unlock(dentry, AuLock_IR);
11625+ fi_write_unlock(file);
11626+
4a4d8108 11627+ err = vfsub_write_u(h_file, buf, count, ppos);
9dbd164d 11628+ ii_write_lock_child(inode);
4a4d8108 11629+ au_cpup_attr_timesizes(inode);
c06a8ce3 11630+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
11631+ ii_write_unlock(inode);
11632+ fput(h_file);
1facf9fc 11633+
4f0767ce 11634+out:
9dbd164d 11635+ si_read_unlock(sb);
4a4d8108 11636+ mutex_unlock(&inode->i_mutex);
dece6358
AM
11637+ return err;
11638+}
1facf9fc 11639+
4a4d8108
AM
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)
dece6358 11642+{
4a4d8108
AM
11643+ ssize_t err;
11644+ struct file *file;
11645+ ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
11646+ loff_t);
1facf9fc 11647+
4a4d8108
AM
11648+ err = security_file_permission(h_file, rw);
11649+ if (unlikely(err))
11650+ goto out;
1facf9fc 11651+
4a4d8108
AM
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;
2cbb1c4b 11661+ lockdep_off();
4a4d8108 11662+ err = func(kio, iov, nv, pos);
2cbb1c4b 11663+ lockdep_on();
4a4d8108
AM
11664+ kio->ki_filp = file;
11665+ } else
11666+ /* currently there is no such fs */
11667+ WARN_ON_ONCE(1);
1facf9fc 11668+
4f0767ce 11669+out:
dece6358
AM
11670+ return err;
11671+}
1facf9fc 11672+
4a4d8108
AM
11673+static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
11674+ unsigned long nv, loff_t pos)
1facf9fc 11675+{
4a4d8108
AM
11676+ ssize_t err;
11677+ struct file *file, *h_file;
11678+ struct dentry *dentry;
dece6358 11679+ struct super_block *sb;
1facf9fc 11680+
4a4d8108 11681+ file = kio->ki_filp;
dece6358 11682+ dentry = file->f_dentry;
1308ab2a 11683+ sb = dentry->d_sb;
e49829fe 11684+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
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);
9dbd164d
AM
11690+ get_file(h_file);
11691+ di_read_unlock(dentry, AuLock_IR);
11692+ fi_read_unlock(file);
11693+
4a4d8108
AM
11694+ err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
11695+ /* todo: necessary? */
11696+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11697+ /* update without lock, I don't think it a problem */
c06a8ce3 11698+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 11699+ fput(h_file);
1facf9fc 11700+
4f0767ce 11701+out:
4a4d8108 11702+ si_read_unlock(sb);
1308ab2a 11703+ return err;
11704+}
1facf9fc 11705+
4a4d8108
AM
11706+static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
11707+ unsigned long nv, loff_t pos)
1308ab2a 11708+{
4a4d8108
AM
11709+ ssize_t err;
11710+ struct au_pin pin;
11711+ struct dentry *dentry;
11712+ struct inode *inode;
4a4d8108 11713+ struct file *file, *h_file;
9dbd164d 11714+ struct super_block *sb;
1308ab2a 11715+
4a4d8108 11716+ file = kio->ki_filp;
1308ab2a 11717+ dentry = file->f_dentry;
9dbd164d 11718+ sb = dentry->d_sb;
1308ab2a 11719+ inode = dentry->d_inode;
e49829fe
JR
11720+ au_mtx_and_read_lock(inode);
11721+
4a4d8108
AM
11722+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11723+ if (unlikely(err))
1308ab2a 11724+ goto out;
1facf9fc 11725+
4a4d8108
AM
11726+ err = au_ready_to_write(file, -1, &pin);
11727+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11728+ if (unlikely(err)) {
11729+ di_read_unlock(dentry, AuLock_IR);
11730+ fi_write_unlock(file);
11731+ goto out;
11732+ }
1facf9fc 11733+
4a4d8108 11734+ h_file = au_hf_top(file);
9dbd164d
AM
11735+ get_file(h_file);
11736+ au_unpin(&pin);
11737+ di_read_unlock(dentry, AuLock_IR);
11738+ fi_write_unlock(file);
11739+
4a4d8108 11740+ err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
9dbd164d 11741+ ii_write_lock_child(inode);
4a4d8108 11742+ au_cpup_attr_timesizes(inode);
c06a8ce3 11743+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
11744+ ii_write_unlock(inode);
11745+ fput(h_file);
1facf9fc 11746+
4f0767ce 11747+out:
9dbd164d 11748+ si_read_unlock(sb);
4a4d8108 11749+ mutex_unlock(&inode->i_mutex);
dece6358 11750+ return err;
1facf9fc 11751+}
11752+
4a4d8108
AM
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)
1facf9fc 11756+{
4a4d8108
AM
11757+ ssize_t err;
11758+ struct file *h_file;
11759+ struct dentry *dentry;
dece6358 11760+ struct super_block *sb;
1facf9fc 11761+
dece6358 11762+ dentry = file->f_dentry;
dece6358 11763+ sb = dentry->d_sb;
e49829fe 11764+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11765+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
11766+ if (unlikely(err))
dece6358 11767+ goto out;
1facf9fc 11768+
4a4d8108
AM
11769+ err = -EINVAL;
11770+ h_file = au_hf_top(file);
9dbd164d 11771+ get_file(h_file);
4a4d8108 11772+ if (au_test_loopback_kthread()) {
87a755f4
AM
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+ }
1308ab2a 11778+ }
9dbd164d
AM
11779+ di_read_unlock(dentry, AuLock_IR);
11780+ fi_read_unlock(file);
11781+
4a4d8108
AM
11782+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
11783+ /* todo: necessasry? */
11784+ /* file->f_ra = h_file->f_ra; */
9dbd164d 11785+ /* update without lock, I don't think it a problem */
c06a8ce3 11786+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 11787+ fput(h_file);
1facf9fc 11788+
4f0767ce 11789+out:
4a4d8108 11790+ si_read_unlock(sb);
dece6358 11791+ return err;
1facf9fc 11792+}
11793+
4a4d8108
AM
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)
1facf9fc 11797+{
4a4d8108
AM
11798+ ssize_t err;
11799+ struct au_pin pin;
11800+ struct dentry *dentry;
11801+ struct inode *inode;
4a4d8108 11802+ struct file *h_file;
9dbd164d 11803+ struct super_block *sb;
1facf9fc 11804+
4a4d8108 11805+ dentry = file->f_dentry;
9dbd164d 11806+ sb = dentry->d_sb;
4a4d8108 11807+ inode = dentry->d_inode;
e49829fe 11808+ au_mtx_and_read_lock(inode);
9dbd164d 11809+
4a4d8108
AM
11810+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11811+ if (unlikely(err))
11812+ goto out;
1facf9fc 11813+
4a4d8108
AM
11814+ err = au_ready_to_write(file, -1, &pin);
11815+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
11816+ if (unlikely(err)) {
11817+ di_read_unlock(dentry, AuLock_IR);
11818+ fi_write_unlock(file);
11819+ goto out;
11820+ }
1facf9fc 11821+
4a4d8108 11822+ h_file = au_hf_top(file);
9dbd164d 11823+ get_file(h_file);
4a4d8108 11824+ au_unpin(&pin);
9dbd164d
AM
11825+ di_read_unlock(dentry, AuLock_IR);
11826+ fi_write_unlock(file);
11827+
4a4d8108 11828+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
9dbd164d 11829+ ii_write_lock_child(inode);
4a4d8108 11830+ au_cpup_attr_timesizes(inode);
c06a8ce3 11831+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
11832+ ii_write_unlock(inode);
11833+ fput(h_file);
1facf9fc 11834+
4f0767ce 11835+out:
9dbd164d 11836+ si_read_unlock(sb);
4a4d8108
AM
11837+ mutex_unlock(&inode->i_mutex);
11838+ return err;
11839+}
1facf9fc 11840+
4a4d8108
AM
11841+/* ---------------------------------------------------------------------- */
11842+
9dbd164d
AM
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+
2dfbb274
AM
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)
2dfbb274
AM
11893+ | AuConv_VM_MAP(flags, LOCKED);
11894+}
11895+
9dbd164d 11896+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 11897+{
4a4d8108
AM
11898+ int err;
11899+ aufs_bindex_t bstart;
11900+ const unsigned char wlock
9dbd164d 11901+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108
AM
11902+ struct dentry *dentry;
11903+ struct super_block *sb;
9dbd164d
AM
11904+ struct file *h_file;
11905+ struct au_branch *br;
11906+ struct au_pin pin;
11907+
11908+ AuDbgVmRegion(file, vma);
1308ab2a 11909+
4a4d8108
AM
11910+ dentry = file->f_dentry;
11911+ sb = dentry->d_sb;
9dbd164d 11912+ lockdep_off();
e49829fe 11913+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108
AM
11914+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11915+ if (unlikely(err))
11916+ goto out;
11917+
4a4d8108 11918+ if (wlock) {
4a4d8108
AM
11919+ err = au_ready_to_write(file, -1, &pin);
11920+ di_write_unlock(dentry);
9dbd164d
AM
11921+ if (unlikely(err)) {
11922+ fi_write_unlock(file);
11923+ goto out;
11924+ }
4a4d8108
AM
11925+ au_unpin(&pin);
11926+ } else
11927+ di_write_unlock(dentry);
9dbd164d 11928+
4a4d8108 11929+ bstart = au_fbstart(file);
9dbd164d
AM
11930+ br = au_sbr(sb, bstart);
11931+ h_file = au_hf_top(file);
11932+ get_file(h_file);
2cbb1c4b 11933+ au_set_mmapped(file);
4a4d8108 11934+ fi_write_unlock(file);
9dbd164d 11935+ lockdep_on();
1308ab2a 11936+
9dbd164d 11937+ au_vm_file_reset(vma, h_file);
2dfbb274
AM
11938+ err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
11939+ au_flag_conv(vma->vm_flags));
9dbd164d
AM
11940+ if (!err)
11941+ err = h_file->f_op->mmap(h_file, vma);
2cbb1c4b
JR
11942+ if (unlikely(err))
11943+ goto out_reset;
4a4d8108 11944+
2cbb1c4b 11945+ au_vm_prfile_set(vma, file);
4a4d8108 11946+ /* update without lock, I don't think it a problem */
c06a8ce3 11947+ fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
2cbb1c4b 11948+ goto out_fput; /* success */
4a4d8108 11949+
2cbb1c4b
JR
11950+out_reset:
11951+ au_unset_mmapped(file);
11952+ au_vm_file_reset(vma, file);
11953+out_fput:
9dbd164d
AM
11954+ fput(h_file);
11955+ lockdep_off();
4f0767ce 11956+out:
9dbd164d
AM
11957+ si_read_unlock(sb);
11958+ lockdep_on();
11959+ AuTraceErr(err);
4a4d8108
AM
11960+ return err;
11961+}
11962+
11963+/* ---------------------------------------------------------------------- */
11964+
1e00d052
AM
11965+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
11966+ int datasync)
4a4d8108
AM
11967+{
11968+ int err;
11969+ struct au_pin pin;
b752ccd1 11970+ struct dentry *dentry;
4a4d8108
AM
11971+ struct inode *inode;
11972+ struct file *h_file;
11973+ struct super_block *sb;
11974+
b752ccd1 11975+ dentry = file->f_dentry;
4a4d8108 11976+ inode = dentry->d_inode;
4a4d8108 11977+ sb = dentry->d_sb;
1e00d052 11978+ mutex_lock(&inode->i_mutex);
e49829fe
JR
11979+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
11980+ if (unlikely(err))
11981+ goto out;
4a4d8108
AM
11982+
11983+ err = 0; /* -EBADF; */ /* posix? */
11984+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
e49829fe 11985+ goto out_si;
4a4d8108
AM
11986+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
11987+ if (unlikely(err))
e49829fe 11988+ goto out_si;
4a4d8108
AM
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);
53392da6
AM
11998+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
11999+ au_cpup_attr_timesizes(inode);
4a4d8108 12000+
4f0767ce 12001+out_unlock:
4a4d8108 12002+ di_read_unlock(dentry, AuLock_IR);
1308ab2a 12003+ fi_write_unlock(file);
e49829fe 12004+out_si:
953406b4 12005+ si_read_unlock(sb);
e49829fe 12006+out:
1e00d052 12007+ mutex_unlock(&inode->i_mutex);
4a4d8108 12008+ return err;
dece6358
AM
12009+}
12010+
4a4d8108
AM
12011+/* no one supports this operation, currently */
12012+#if 0
12013+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 12014+{
4a4d8108
AM
12015+ int err;
12016+ struct au_pin pin;
1308ab2a 12017+ struct dentry *dentry;
4a4d8108
AM
12018+ struct inode *inode;
12019+ struct file *file, *h_file;
1308ab2a 12020+
4a4d8108 12021+ file = kio->ki_filp;
1308ab2a 12022+ dentry = file->f_dentry;
4a4d8108 12023+ inode = dentry->d_inode;
e49829fe 12024+ au_mtx_and_read_lock(inode);
4a4d8108
AM
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))
1308ab2a 12031+ goto out;
12032+
4a4d8108
AM
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);
1308ab2a 12038+
4a4d8108
AM
12039+ err = -ENOSYS;
12040+ h_file = au_hf_top(file);
12041+ if (h_file->f_op && h_file->f_op->aio_fsync) {
4a4d8108 12042+ struct mutex *h_mtx;
1308ab2a 12043+
c06a8ce3 12044+ h_mtx = &file_inode(h_file)->i_mutex;
4a4d8108
AM
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+ }
1308ab2a 12058+
4f0767ce 12059+out_unlock:
4a4d8108
AM
12060+ di_read_unlock(dentry, AuLock_IR);
12061+ fi_write_unlock(file);
4f0767ce 12062+out:
e49829fe 12063+ si_read_unlock(inode->sb);
4a4d8108
AM
12064+ mutex_unlock(&inode->i_mutex);
12065+ return err;
dece6358 12066+}
4a4d8108 12067+#endif
dece6358 12068+
4a4d8108 12069+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 12070+{
4a4d8108
AM
12071+ int err;
12072+ struct file *h_file;
12073+ struct dentry *dentry;
12074+ struct super_block *sb;
1308ab2a 12075+
4a4d8108
AM
12076+ dentry = file->f_dentry;
12077+ sb = dentry->d_sb;
e49829fe 12078+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
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);
1308ab2a 12089+
4f0767ce 12090+out:
4a4d8108 12091+ si_read_unlock(sb);
1308ab2a 12092+ return err;
dece6358 12093+}
4a4d8108
AM
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,
2cbb1c4b 12109+
027c5e7a 12110+ .llseek = default_llseek,
4a4d8108
AM
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,
b752ccd1
AM
12120+#ifdef CONFIG_COMPAT
12121+ .compat_ioctl = aufs_ioctl_nondir, /* same */
12122+#endif
4a4d8108
AM
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+};
7f207e10
AM
12138diff -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
86dc4139
AM
12140+++ linux/fs/aufs/f_op_sp.c 2013-07-06 13:20:47.750198454 +0200
12141@@ -0,0 +1,376 @@
1308ab2a 12142+/*
7a9e40b8 12143+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1308ab2a 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+ */
dece6358 12159+
1308ab2a 12160+/*
4a4d8108
AM
12161+ * file operations for special files.
12162+ * while they exist in aufs virtually,
12163+ * their file I/O is handled out of aufs.
1308ab2a 12164+ */
12165+
86dc4139 12166+#include <linux/aio.h>
4a4d8108 12167+#include "aufs.h"
1308ab2a 12168+
86dc4139
AM
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+
4a4d8108
AM
12240+static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
12241+ unsigned long nv, loff_t pos)
dece6358 12242+{
4a4d8108
AM
12243+ ssize_t err;
12244+ aufs_bindex_t bstart;
12245+ unsigned char wbr;
12246+ struct file *file, *h_file;
12247+ struct super_block *sb;
1308ab2a 12248+
4a4d8108
AM
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);
4a4d8108
AM
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 */
86dc4139 12306+ au_fi_sp_del(file);
4a4d8108
AM
12307+ return err;
12308+}
12309+
12310+/* ---------------------------------------------------------------------- */
12311+
12312+/* currently, support only FIFO */
4f0767ce
JR
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+};
4a4d8108
AM
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) {
86dc4139 12413+ err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME, &pin);
4a4d8108
AM
12414+ au_unpin(&pin);
12415+ }
12416+
4f0767ce 12417+out:
4a4d8108
AM
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+
86dc4139
AM
12430+ err = au_fi_sp_add(file);
12431+ if (unlikely(err))
12432+ goto out;
12433+
4a4d8108
AM
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))
86dc4139 12446+ goto out_del;
4a4d8108
AM
12447+
12448+ sb = dentry->d_sb;
12449+ h_file = au_hf_top(file);
c06a8ce3 12450+ h_inode = file_inode(h_file);
4a4d8108
AM
12451+ di_read_unlock(dentry, AuLock_IR);
12452+ fi_write_unlock(file);
12453+ si_read_unlock(sb);
12454+ /* open this fifo in aufs */
c06a8ce3 12455+ err = h_inode->i_fop->open(file_inode(file), file);
4a4d8108
AM
12456+ si_noflush_read_lock(sb);
12457+ fi_write_lock(file);
12458+ di_read_lock_child(dentry, AuLock_IR);
86dc4139 12459+ if (!err) {
4a4d8108 12460+ au_init_fop_sp(file);
86dc4139
AM
12461+ goto out; /* success */
12462+ }
4a4d8108 12463+
86dc4139
AM
12464+out_del:
12465+ au_fi_sp_del(file);
4f0767ce 12466+out:
4a4d8108
AM
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+}
7f207e10
AM
12518diff -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
86dc4139
AM
12520+++ linux/fs/aufs/fstype.h 2013-07-06 13:20:47.750198454 +0200
12521@@ -0,0 +1,480 @@
4a4d8108 12522+/*
7a9e40b8 12523+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
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>
4a4d8108
AM
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+}
1308ab2a 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;
dece6358
AM
12567+#else
12568+ return 0;
12569+#endif
12570+}
12571+
1308ab2a 12572+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 12573+{
1308ab2a 12574+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
12575+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
12576+#else
12577+ return 0;
12578+#endif
12579+}
12580+
1308ab2a 12581+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 12582+{
1308ab2a 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;
dece6358
AM
12593+#else
12594+ return 0;
12595+#endif
12596+}
12597+
1308ab2a 12598+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 12599+{
1308ab2a 12600+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
12601+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
12602+#else
12603+ return 0;
12604+#endif
12605+}
12606+
1308ab2a 12607+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 12608+{
1308ab2a 12609+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
12610+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
12611+#else
12612+ return 0;
12613+#endif
12614+}
12615+
1308ab2a 12616+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 12617+{
1308ab2a 12618+#ifdef CONFIG_TMPFS
12619+ return sb->s_magic == TMPFS_MAGIC;
12620+#else
12621+ return 0;
dece6358 12622+#endif
dece6358
AM
12623+}
12624+
1308ab2a 12625+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 12626+{
1308ab2a 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
1facf9fc 12632+}
12633+
1308ab2a 12634+static inline int au_test_smbfs(struct super_block *sb __maybe_unused)
1facf9fc 12635+{
1308ab2a 12636+#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE)
12637+ return sb->s_magic == SMB_SUPER_MAGIC;
12638+#else
12639+ return 0;
1facf9fc 12640+#endif
1facf9fc 12641+}
12642+
1308ab2a 12643+static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
1facf9fc 12644+{
1308ab2a 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
1facf9fc 12650+}
12651+
1308ab2a 12652+static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
1facf9fc 12653+{
1308ab2a 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
1facf9fc 12659+}
12660+
1308ab2a 12661+static inline int au_test_coda(struct super_block *sb __maybe_unused)
1facf9fc 12662+{
1308ab2a 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+
4a4d8108
AM
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+
1308ab2a 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+
1308ab2a 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)
4a4d8108
AM
12903+ || au_test_btrfs(sb)
12904+ || au_test_ubifs(sb)
12905+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 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 */
1308ab2a 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);
1facf9fc 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
4a4d8108 12934+ || au_test_ubifs(sb)
4a4d8108 12935+ || au_test_hfsplus(sb);
1facf9fc 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)
dece6358 12945+ || au_test_ubifs(sb)
1facf9fc 12946+ /* || au_test_cifs(sb) */ /* untested */
1facf9fc 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+{
dece6358
AM
12955+ return au_test_fuse(sb)
12956+ || au_test_ubifs(sb);
1facf9fc 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)
1facf9fc 12977+ /* don't want unnecessary work for xino */
12978+ || au_test_aufs(sb)
1308ab2a 12979+ || au_test_ecryptfs(sb)
12980+ || au_test_nilfs(sb);
1facf9fc 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__ */
7f207e10
AM
13002diff -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
86dc4139 13004+++ linux/fs/aufs/hfsnotify.c 2013-07-06 13:20:47.750198454 +0200
c06a8ce3 13005@@ -0,0 +1,296 @@
1facf9fc 13006+/*
7a9e40b8 13007+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 13022+ */
13023+
13024+/*
4a4d8108 13025+ * fsnotify for the lower directories
1facf9fc 13026+ */
13027+
13028+#include "aufs.h"
13029+
4a4d8108
AM
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);
7f207e10 13033+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 13034+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 13035+
0c5527e5 13036+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 13037+{
0c5527e5
AM
13038+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
13039+ hn_mark);
4a4d8108 13040+ AuDbg("here\n");
7eafdf33
AM
13041+ au_cache_free_hnotify(hn);
13042+ smp_mb__before_atomic_dec();
1716fcea
AM
13043+ if (atomic64_dec_and_test(&au_hfsn_ifree))
13044+ wake_up(&au_hfsn_wq);
4a4d8108 13045+}
1facf9fc 13046+
027c5e7a 13047+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 13048+{
1716fcea 13049+ int err;
027c5e7a
AM
13050+ struct au_hnotify *hn;
13051+ struct super_block *sb;
13052+ struct au_branch *br;
0c5527e5 13053+ struct fsnotify_mark *mark;
027c5e7a 13054+ aufs_bindex_t bindex;
1facf9fc 13055+
027c5e7a
AM
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);
1716fcea
AM
13060+ AuDebugOn(!br->br_hfsn);
13061+
0c5527e5
AM
13062+ mark = &hn->hn_mark;
13063+ fsnotify_init_mark(mark, au_hfsn_free_mark);
13064+ mark->mask = AuHfsnMask;
7f207e10
AM
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+ */
1716fcea 13069+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 13070+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
13071+ /* even if err */
13072+ fsnotify_put_mark(mark);
13073+
13074+ return err;
1facf9fc 13075+}
13076+
7eafdf33 13077+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 13078+{
0c5527e5 13079+ struct fsnotify_mark *mark;
7eafdf33 13080+ unsigned long long ull;
1716fcea 13081+ struct fsnotify_group *group;
7eafdf33
AM
13082+
13083+ ull = atomic64_inc_return(&au_hfsn_ifree);
13084+ BUG_ON(!ull);
953406b4 13085+
0c5527e5 13086+ mark = &hn->hn_mark;
1716fcea
AM
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);
7f207e10 13093+
7eafdf33
AM
13094+ /* free hn by myself */
13095+ return 0;
1facf9fc 13096+}
13097+
13098+/* ---------------------------------------------------------------------- */
13099+
4a4d8108 13100+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 13101+{
0c5527e5 13102+ struct fsnotify_mark *mark;
1facf9fc 13103+
0c5527e5
AM
13104+ mark = &hinode->hi_notify->hn_mark;
13105+ spin_lock(&mark->lock);
1facf9fc 13106+ if (do_set) {
0c5527e5
AM
13107+ AuDebugOn(mark->mask & AuHfsnMask);
13108+ mark->mask |= AuHfsnMask;
1facf9fc 13109+ } else {
0c5527e5
AM
13110+ AuDebugOn(!(mark->mask & AuHfsnMask));
13111+ mark->mask &= ~AuHfsnMask;
1facf9fc 13112+ }
0c5527e5 13113+ spin_unlock(&mark->lock);
4a4d8108 13114+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 13115+}
13116+
4a4d8108 13117+/* ---------------------------------------------------------------------- */
1facf9fc 13118+
4a4d8108
AM
13119+/* #define AuDbgHnotify */
13120+#ifdef AuDbgHnotify
13121+static char *au_hfsn_name(u32 mask)
13122+{
13123+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
13124+#define test_ret(flag) \
13125+ do { \
13126+ if (mask & flag) \
13127+ return #flag; \
13128+ } while (0)
4a4d8108
AM
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
1facf9fc 13152+}
4a4d8108 13153+#endif
1facf9fc 13154+
13155+/* ---------------------------------------------------------------------- */
13156+
1716fcea
AM
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+
4a4d8108 13165+static int au_hfsn_handle_event(struct fsnotify_group *group,
0c5527e5
AM
13166+ struct fsnotify_mark *inode_mark,
13167+ struct fsnotify_mark *vfsmount_mark,
4a4d8108 13168+ struct fsnotify_event *event)
1facf9fc 13169+{
13170+ int err;
4a4d8108
AM
13171+ struct au_hnotify *hnotify;
13172+ struct inode *h_dir, *h_inode;
13173+ __u32 mask;
0c3ec466 13174+ struct qstr h_child_qstr = QSTR_INIT(event->file_name, event->name_len);
4a4d8108
AM
13175+
13176+ AuDebugOn(event->data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 13177+
13178+ err = 0;
0c5527e5 13179+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108
AM
13180+ mask = event->mask;
13181+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 13182+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 13183+ goto out;
1facf9fc 13184+
4a4d8108
AM
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); */
1facf9fc 13195+ }
4a4d8108 13196+ au_debug(0);
1facf9fc 13197+#endif
4a4d8108 13198+
0c5527e5
AM
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);
1facf9fc 13202+
4a4d8108
AM
13203+out:
13204+ return err;
13205+}
1facf9fc 13206+
027c5e7a 13207+/* isn't it waste to ask every registered 'group'? */
7f207e10 13208+/* copied from linux/fs/notify/inotify/inotify_fsnotiry.c */
4a4d8108 13209+/* it should be exported to modules */
7f207e10
AM
13210+static bool au_hfsn_should_send_event(struct fsnotify_group *group,
13211+ struct inode *h_inode,
0c5527e5
AM
13212+ struct fsnotify_mark *inode_mark,
13213+ struct fsnotify_mark *vfsmount_mark,
13214+ __u32 mask, void *data, int data_type)
4a4d8108 13215+{
4a4d8108 13216+ mask = (mask & ~FS_EVENT_ON_CHILD);
7f207e10 13217+ return inode_mark->mask & mask;
4a4d8108
AM
13218+}
13219+
13220+static struct fsnotify_ops au_hfsn_ops = {
13221+ .should_send_event = au_hfsn_should_send_event,
1716fcea
AM
13222+ .handle_event = au_hfsn_handle_event,
13223+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
13224+};
13225+
13226+/* ---------------------------------------------------------------------- */
13227+
027c5e7a
AM
13228+static void au_hfsn_fin_br(struct au_branch *br)
13229+{
1716fcea 13230+ struct au_br_hfsnotify *hfsn;
027c5e7a 13231+
1716fcea
AM
13232+ hfsn = br->br_hfsn;
13233+ if (hfsn)
13234+ fsnotify_put_group(hfsn->hfsn_group);
027c5e7a
AM
13235+}
13236+
1716fcea 13237+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
13238+{
13239+ int err;
1716fcea
AM
13240+ struct fsnotify_group *group;
13241+ struct au_br_hfsnotify *hfsn;
1facf9fc 13242+
4a4d8108 13243+ err = 0;
1716fcea
AM
13244+ br->br_hfsn = NULL;
13245+ if (!au_br_hnotifyable(perm))
027c5e7a 13246+ goto out;
027c5e7a 13247+
1716fcea
AM
13248+ err = -ENOMEM;
13249+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
13250+ if (unlikely(!hfsn))
027c5e7a
AM
13251+ goto out;
13252+
1716fcea
AM
13253+ err = 0;
13254+ group = fsnotify_alloc_group(&au_hfsn_ops);
13255+ if (IS_ERR(group)) {
13256+ err = PTR_ERR(group);
0c5527e5 13257+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 13258+ goto out_hfsn;
4a4d8108 13259+ }
1facf9fc 13260+
1716fcea
AM
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);
027c5e7a 13268+out:
1716fcea
AM
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+
1facf9fc 13280+ return err;
13281+}
13282+
7eafdf33
AM
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+
4a4d8108
AM
13291+const struct au_hnotify_op au_hnotify_op = {
13292+ .ctl = au_hfsn_ctl,
13293+ .alloc = au_hfsn_alloc,
13294+ .free = au_hfsn_free,
1facf9fc 13295+
7eafdf33
AM
13296+ .fin = au_hfsn_fin,
13297+
027c5e7a
AM
13298+ .reset_br = au_hfsn_reset_br,
13299+ .fin_br = au_hfsn_fin_br,
13300+ .init_br = au_hfsn_init_br
4a4d8108 13301+};
7f207e10
AM
13302diff -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
86dc4139
AM
13304+++ linux/fs/aufs/hfsplus.c 2013-07-06 13:20:47.750198454 +0200
13305@@ -0,0 +1,56 @@
4a4d8108 13306+/*
7a9e40b8 13307+ * Copyright (C) 2010-2013 Junjiro R. Okajima
4a4d8108
AM
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+ */
1facf9fc 13323+
4a4d8108
AM
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+ */
1facf9fc 13333+
4a4d8108 13334+#include "aufs.h"
1facf9fc 13335+
4a4d8108
AM
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;
1facf9fc 13340+
4a4d8108
AM
13341+ h_dentry = au_h_dptr(dentry, bindex);
13342+ AuDebugOn(!h_dentry);
13343+ AuDebugOn(!h_dentry->d_inode);
4a4d8108
AM
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;
1facf9fc 13352+}
13353+
4a4d8108
AM
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+}
7f207e10
AM
13362diff -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
367653fa 13364+++ linux/fs/aufs/hnotify.c 2013-07-30 22:42:55.842946719 +0200
c06a8ce3 13365@@ -0,0 +1,712 @@
e49829fe 13366+/*
7a9e40b8 13367+ * Copyright (C) 2005-2013 Junjiro R. Okajima
e49829fe
JR
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+/*
7f207e10 13385+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
13386+ */
13387+
13388+#include "aufs.h"
13389+
027c5e7a 13390+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
13391+{
13392+ int err;
7f207e10 13393+ struct au_hnotify *hn;
1facf9fc 13394+
4a4d8108
AM
13395+ err = -ENOMEM;
13396+ hn = au_cache_alloc_hnotify();
13397+ if (hn) {
13398+ hn->hn_aufs_inode = inode;
027c5e7a
AM
13399+ hinode->hi_notify = hn;
13400+ err = au_hnotify_op.alloc(hinode);
13401+ AuTraceErr(err);
13402+ if (unlikely(err)) {
13403+ hinode->hi_notify = NULL;
4a4d8108
AM
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+ }
1308ab2a 13414+ }
1308ab2a 13415+
027c5e7a 13416+ AuTraceErr(err);
1308ab2a 13417+ return err;
dece6358 13418+}
1facf9fc 13419+
4a4d8108 13420+void au_hn_free(struct au_hinode *hinode)
dece6358 13421+{
4a4d8108 13422+ struct au_hnotify *hn;
1facf9fc 13423+
4a4d8108
AM
13424+ hn = hinode->hi_notify;
13425+ if (hn) {
4a4d8108 13426+ hinode->hi_notify = NULL;
7eafdf33
AM
13427+ if (au_hnotify_op.free(hinode, hn))
13428+ au_cache_free_hnotify(hn);
4a4d8108
AM
13429+ }
13430+}
dece6358 13431+
4a4d8108 13432+/* ---------------------------------------------------------------------- */
dece6358 13433+
4a4d8108
AM
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;
1facf9fc 13445+
1308ab2a 13446+ bend = au_ibend(inode);
4a4d8108
AM
13447+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
13448+ hi = au_h_iptr(inode, bindex);
13449+ if (!hi)
13450+ continue;
1308ab2a 13451+
4a4d8108
AM
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); */
1facf9fc 13463+ }
1facf9fc 13464+}
13465+
1308ab2a 13466+/* ---------------------------------------------------------------------- */
1facf9fc 13467+
4a4d8108 13468+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 13469+{
4a4d8108
AM
13470+ int err;
13471+ aufs_bindex_t bindex, bend, bfound, bstart;
13472+ struct inode *h_i;
1facf9fc 13473+
4a4d8108
AM
13474+ err = 0;
13475+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13476+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13477+ goto out;
13478+ }
1facf9fc 13479+
4a4d8108
AM
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)
1308ab2a 13495+ goto out;
1facf9fc 13496+
4a4d8108
AM
13497+ for (bindex = bstart; bindex <= bend; bindex++) {
13498+ h_i = au_h_iptr(inode, bindex);
13499+ if (!h_i)
13500+ continue;
1facf9fc 13501+
4a4d8108
AM
13502+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
13503+ /* ignore this error */
13504+ /* bad action? */
1facf9fc 13505+ }
1facf9fc 13506+
4a4d8108 13507+ /* children inode number will be broken */
1facf9fc 13508+
4f0767ce 13509+out:
4a4d8108
AM
13510+ AuTraceErr(err);
13511+ return err;
1facf9fc 13512+}
13513+
4a4d8108 13514+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 13515+{
4a4d8108
AM
13516+ int err, i, j, ndentry;
13517+ struct au_dcsub_pages dpages;
13518+ struct au_dpage *dpage;
13519+ struct dentry **dentries;
1facf9fc 13520+
4a4d8108
AM
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;
1facf9fc 13527+
4a4d8108
AM
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+
4a4d8108
AM
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);
1308ab2a 13544+ }
dece6358 13545+ }
1facf9fc 13546+
4f0767ce 13547+out_dpages:
4a4d8108 13548+ au_dpages_free(&dpages);
dece6358 13549+
027c5e7a 13550+#if 0
4a4d8108
AM
13551+ /* discard children */
13552+ dentry_unhash(dentry);
13553+ dput(dentry);
027c5e7a 13554+#endif
4f0767ce 13555+out:
dece6358
AM
13556+ return err;
13557+}
13558+
1308ab2a 13559+/*
4a4d8108 13560+ * return 0 if processed.
1308ab2a 13561+ */
4a4d8108
AM
13562+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
13563+ const unsigned int isdir)
dece6358 13564+{
1308ab2a 13565+ int err;
4a4d8108
AM
13566+ struct dentry *d;
13567+ struct qstr *dname;
1facf9fc 13568+
4a4d8108
AM
13569+ err = 1;
13570+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13571+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13572+ err = 0;
13573+ goto out;
13574+ }
dece6358 13575+
4a4d8108
AM
13576+ if (!isdir) {
13577+ AuDebugOn(!name);
13578+ au_iigen_dec(inode);
027c5e7a 13579+ spin_lock(&inode->i_lock);
c06a8ce3 13580+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 13581+ spin_lock(&d->d_lock);
4a4d8108
AM
13582+ dname = &d->d_name;
13583+ if (dname->len != nlen
027c5e7a
AM
13584+ && memcmp(dname->name, name, nlen)) {
13585+ spin_unlock(&d->d_lock);
4a4d8108 13586+ continue;
027c5e7a 13587+ }
4a4d8108 13588+ err = 0;
4a4d8108
AM
13589+ au_digen_dec(d);
13590+ spin_unlock(&d->d_lock);
13591+ break;
1facf9fc 13592+ }
027c5e7a 13593+ spin_unlock(&inode->i_lock);
1308ab2a 13594+ } else {
027c5e7a 13595+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
13596+ d = d_find_alias(inode);
13597+ if (!d) {
13598+ au_iigen_dec(inode);
13599+ goto out;
13600+ }
1facf9fc 13601+
027c5e7a 13602+ spin_lock(&d->d_lock);
4a4d8108 13603+ dname = &d->d_name;
027c5e7a
AM
13604+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
13605+ spin_unlock(&d->d_lock);
4a4d8108 13606+ err = hn_gen_tree(d);
027c5e7a
AM
13607+ spin_lock(&d->d_lock);
13608+ }
13609+ spin_unlock(&d->d_lock);
4a4d8108
AM
13610+ dput(d);
13611+ }
1facf9fc 13612+
4f0767ce 13613+out:
4a4d8108 13614+ AuTraceErr(err);
1308ab2a 13615+ return err;
13616+}
dece6358 13617+
4a4d8108 13618+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 13619+{
4a4d8108
AM
13620+ int err;
13621+ struct inode *inode;
1facf9fc 13622+
4a4d8108
AM
13623+ inode = dentry->d_inode;
13624+ if (IS_ROOT(dentry)
13625+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
13626+ ) {
0c3ec466 13627+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13628+ return 0;
13629+ }
1308ab2a 13630+
4a4d8108
AM
13631+ err = 0;
13632+ if (!isdir) {
4a4d8108
AM
13633+ au_digen_dec(dentry);
13634+ if (inode)
13635+ au_iigen_dec(inode);
13636+ } else {
027c5e7a 13637+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
13638+ if (inode)
13639+ err = hn_gen_tree(dentry);
13640+ }
13641+
13642+ AuTraceErr(err);
13643+ return err;
1facf9fc 13644+}
13645+
4a4d8108 13646+/* ---------------------------------------------------------------------- */
1facf9fc 13647+
4a4d8108
AM
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)
7f207e10
AM
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)
1facf9fc 13660+
4a4d8108
AM
13661+enum {
13662+ AuHn_CHILD,
13663+ AuHn_PARENT,
13664+ AuHnLast
13665+};
1facf9fc 13666+
4a4d8108
AM
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+};
1facf9fc 13674+
4a4d8108
AM
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+};
1308ab2a 13682+
4a4d8108
AM
13683+static int hn_job(struct hn_job_args *a)
13684+{
13685+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
1308ab2a 13686+
4a4d8108
AM
13687+ /* reset xino */
13688+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
13689+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 13690+
4a4d8108
AM
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);
1308ab2a 13698+ }
1facf9fc 13699+
4a4d8108
AM
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 */
1facf9fc 13709+ }
1facf9fc 13710+
4a4d8108
AM
13711+ /* make dir entries obsolete */
13712+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
13713+ struct au_vdir *vdir;
1facf9fc 13714+
4a4d8108
AM
13715+ vdir = au_ivdir(a->inode);
13716+ if (vdir)
13717+ vdir->vd_jiffy = 0;
13718+ /* IMustLock(a->inode); */
13719+ /* a->inode->i_version++; */
13720+ }
1facf9fc 13721+
4a4d8108
AM
13722+ /* can do nothing but warn */
13723+ if (au_ftest_hnjob(a->flags, MNTPNT)
13724+ && a->dentry
13725+ && d_mountpoint(a->dentry))
0c3ec466
AM
13726+ pr_warn("mount-point %.*s is removed or renamed\n",
13727+ AuDLNPair(a->dentry));
1facf9fc 13728+
4a4d8108 13729+ return 0;
1308ab2a 13730+}
1facf9fc 13731+
1308ab2a 13732+/* ---------------------------------------------------------------------- */
1facf9fc 13733+
4a4d8108
AM
13734+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
13735+ struct inode *dir)
1308ab2a 13736+{
4a4d8108
AM
13737+ struct dentry *dentry, *d, *parent;
13738+ struct qstr *dname;
1308ab2a 13739+
4a4d8108
AM
13740+ parent = d_find_alias(dir);
13741+ if (!parent)
13742+ return NULL;
1308ab2a 13743+
4a4d8108 13744+ dentry = NULL;
027c5e7a 13745+ spin_lock(&parent->d_lock);
4a4d8108
AM
13746+ list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
13747+ /* AuDbg("%.*s\n", AuDLNPair(d)); */
027c5e7a 13748+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
13749+ dname = &d->d_name;
13750+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
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);
4a4d8108 13758+ spin_unlock(&d->d_lock);
027c5e7a 13759+ break;
dece6358 13760+ }
1facf9fc 13761+
027c5e7a
AM
13762+ cont_unlock:
13763+ spin_unlock(&d->d_lock);
1308ab2a 13764+ }
027c5e7a 13765+ spin_unlock(&parent->d_lock);
4a4d8108 13766+ dput(parent);
1facf9fc 13767+
4a4d8108
AM
13768+ if (dentry)
13769+ di_write_lock_child(dentry);
1308ab2a 13770+
4a4d8108
AM
13771+ return dentry;
13772+}
dece6358 13773+
4a4d8108
AM
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)) {
0c3ec466 13789+ pr_warn("wrong root branch\n");
4a4d8108
AM
13790+ iput(inode);
13791+ inode = NULL;
13792+ goto out;
1308ab2a 13793+ }
13794+
4a4d8108 13795+ ii_write_lock_child(inode);
1308ab2a 13796+
4f0767ce 13797+out:
4a4d8108 13798+ return inode;
dece6358
AM
13799+}
13800+
4a4d8108 13801+static void au_hn_bh(void *_args)
1facf9fc 13802+{
4a4d8108
AM
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;
1facf9fc 13807+ int err;
1308ab2a 13808+ struct inode *inode;
4a4d8108
AM
13809+ ino_t h_ino;
13810+ struct hn_job_args args;
13811+ struct dentry *dentry;
13812+ struct au_sbinfo *sbinfo;
1facf9fc 13813+
4a4d8108
AM
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);
1facf9fc 13821+
4a4d8108
AM
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);
7f207e10 13832+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 13833+
4a4d8108
AM
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;
1facf9fc 13845+
4a4d8108
AM
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;
1facf9fc 13850+
4a4d8108
AM
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+ }
1facf9fc 13866+
4a4d8108
AM
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) {
027c5e7a 13877+ if (au_di(dentry))
4a4d8108
AM
13878+ di_write_unlock(dentry);
13879+ dput(dentry);
13880+ }
13881+ if (inode && try_iput) {
13882+ ii_write_unlock(inode);
13883+ iput(inode);
13884+ }
1facf9fc 13885+
4a4d8108
AM
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);
1facf9fc 13897+
4f0767ce 13898+out:
4a4d8108
AM
13899+ iput(a->h_child_inode);
13900+ iput(a->h_dir);
13901+ iput(a->dir);
027c5e7a
AM
13902+ si_write_unlock(sb);
13903+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 13904+ kfree(a);
dece6358 13905+}
1facf9fc 13906+
4a4d8108
AM
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)
dece6358 13911+{
4a4d8108 13912+ int err, len;
53392da6 13913+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
13914+ unsigned char isdir, isroot, wh;
13915+ struct inode *dir;
13916+ struct au_hnotify_args *args;
13917+ char *p, *h_child_name;
dece6358 13918+
1308ab2a 13919+ err = 0;
4a4d8108
AM
13920+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
13921+ dir = igrab(hnotify->hn_aufs_inode);
13922+ if (!dir)
13923+ goto out;
1facf9fc 13924+
4a4d8108
AM
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+ }
1facf9fc 13936+ }
dece6358 13937+
4a4d8108
AM
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;
1facf9fc 13956+
4a4d8108
AM
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;
dece6358 13967+
4a4d8108
AM
13968+ default:
13969+ AuDebugOn(1);
13970+ }
1308ab2a 13971+
4a4d8108
AM
13972+ if (wh)
13973+ h_child_inode = NULL;
1308ab2a 13974+
4a4d8108
AM
13975+ err = -ENOMEM;
13976+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 13977+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
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;
1308ab2a 13997+ }
1308ab2a 13998+
53392da6
AM
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);
4a4d8108
AM
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);
1facf9fc 14009+ }
1facf9fc 14010+
4a4d8108 14011+out:
1facf9fc 14012+ return err;
14013+}
14014+
027c5e7a
AM
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+
4a4d8108
AM
14047+static void au_hn_destroy_cache(void)
14048+{
14049+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
14050+ au_cachep[AuCache_HNOTIFY] = NULL;
14051+}
1308ab2a 14052+
4a4d8108 14053+int __init au_hnotify_init(void)
1facf9fc 14054+{
1308ab2a 14055+ int err;
1308ab2a 14056+
4a4d8108
AM
14057+ err = -ENOMEM;
14058+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
14059+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
14060+ err = 0;
14061+ if (au_hnotify_op.init)
14062+ err = au_hnotify_op.init();
4a4d8108
AM
14063+ if (unlikely(err))
14064+ au_hn_destroy_cache();
1308ab2a 14065+ }
1308ab2a 14066+ AuTraceErr(err);
4a4d8108 14067+ return err;
1308ab2a 14068+}
14069+
4a4d8108 14070+void au_hnotify_fin(void)
1308ab2a 14071+{
027c5e7a
AM
14072+ if (au_hnotify_op.fin)
14073+ au_hnotify_op.fin();
4a4d8108
AM
14074+ /* cf. au_cache_fin() */
14075+ if (au_cachep[AuCache_HNOTIFY])
14076+ au_hn_destroy_cache();
dece6358 14077+}
7f207e10
AM
14078diff -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
86dc4139 14080+++ linux/fs/aufs/iinfo.c 2013-07-06 13:20:47.750198454 +0200
537831f9 14081@@ -0,0 +1,276 @@
dece6358 14082+/*
7a9e40b8 14083+ * Copyright (C) 2005-2013 Junjiro R. Okajima
dece6358
AM
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+ */
1facf9fc 14099+
dece6358 14100+/*
4a4d8108 14101+ * inode private data
dece6358 14102+ */
1facf9fc 14103+
1308ab2a 14104+#include "aufs.h"
1facf9fc 14105+
4a4d8108 14106+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 14107+{
4a4d8108 14108+ struct inode *h_inode;
1facf9fc 14109+
4a4d8108 14110+ IiMustAnyLock(inode);
1facf9fc 14111+
4a4d8108
AM
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+}
1facf9fc 14116+
4a4d8108
AM
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+}
1facf9fc 14124+
4a4d8108
AM
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);
1facf9fc 14129+
4a4d8108
AM
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;
1facf9fc 14136+}
14137+
4a4d8108
AM
14138+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
14139+ struct inode *h_inode, unsigned int flags)
1308ab2a 14140+{
4a4d8108
AM
14141+ struct au_hinode *hinode;
14142+ struct inode *hi;
14143+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 14144+
4a4d8108 14145+ IiMustWriteLock(inode);
dece6358 14146+
4a4d8108
AM
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+
027c5e7a
AM
14159+ AuDebugOn(inode->i_mode
14160+ && (h_inode->i_mode & S_IFMT)
14161+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
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)) {
027c5e7a 14175+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
14176+ if (unlikely(err))
14177+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 14178+ }
14179+ }
4a4d8108 14180+}
dece6358 14181+
4a4d8108
AM
14182+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
14183+ struct dentry *h_wh)
14184+{
14185+ struct au_hinode *hinode;
dece6358 14186+
4a4d8108
AM
14187+ IiMustWriteLock(inode);
14188+
14189+ hinode = au_ii(inode)->ii_hinode + bindex;
14190+ AuDebugOn(hinode->hi_whdentry);
14191+ hinode->hi_whdentry = h_wh;
1facf9fc 14192+}
14193+
537831f9 14194+void au_update_iigen(struct inode *inode, int half)
1308ab2a 14195+{
537831f9
AM
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);
4a4d8108 14210+}
1facf9fc 14211+
4a4d8108
AM
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;
027c5e7a 14216+ aufs_bindex_t bindex, bend;
1facf9fc 14217+
4a4d8108 14218+ iinfo = au_ii(inode);
027c5e7a 14219+ if (!iinfo)
4a4d8108 14220+ return;
1facf9fc 14221+
4a4d8108 14222+ IiMustWriteLock(inode);
1facf9fc 14223+
027c5e7a 14224+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
14225+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14226+ bindex++) {
14227+ struct inode *h_i;
1facf9fc 14228+
4a4d8108 14229+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
027c5e7a
AM
14230+ if (h_i && !h_i->i_nlink)
14231+ au_set_h_iptr(inode, bindex, NULL, 0);
14232+ }
4a4d8108
AM
14233+ }
14234+
027c5e7a
AM
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;
4a4d8108 14241+ break;
027c5e7a
AM
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);
1308ab2a 14250+}
1facf9fc 14251+
dece6358 14252+/* ---------------------------------------------------------------------- */
1facf9fc 14253+
4a4d8108 14254+void au_icntnr_init_once(void *_c)
dece6358 14255+{
4a4d8108
AM
14256+ struct au_icntnr *c = _c;
14257+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 14258+ static struct lock_class_key aufs_ii;
1facf9fc 14259+
537831f9 14260+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 14261+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 14262+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
14263+ inode_init_once(&c->vfs_inode);
14264+}
1facf9fc 14265+
4a4d8108
AM
14266+int au_iinfo_init(struct inode *inode)
14267+{
14268+ struct au_iinfo *iinfo;
14269+ struct super_block *sb;
14270+ int nbr, i;
1facf9fc 14271+
4a4d8108
AM
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) {
7f207e10 14279+ au_ninodes_inc(sb);
4a4d8108
AM
14280+ for (i = 0; i < nbr; i++)
14281+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 14282+
537831f9 14283+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
14284+ iinfo->ii_bstart = -1;
14285+ iinfo->ii_bend = -1;
14286+ iinfo->ii_vdir = NULL;
14287+ return 0;
1308ab2a 14288+ }
4a4d8108
AM
14289+ return -ENOMEM;
14290+}
1facf9fc 14291+
4a4d8108
AM
14292+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
14293+{
14294+ int err, sz;
14295+ struct au_hinode *hip;
1facf9fc 14296+
4a4d8108
AM
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;
1308ab2a 14307+ }
4a4d8108 14308+
1308ab2a 14309+ return err;
1facf9fc 14310+}
14311+
4a4d8108 14312+void au_iinfo_fin(struct inode *inode)
1facf9fc 14313+{
4a4d8108
AM
14314+ struct au_iinfo *iinfo;
14315+ struct au_hinode *hi;
14316+ struct super_block *sb;
b752ccd1
AM
14317+ aufs_bindex_t bindex, bend;
14318+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 14319+
4a4d8108
AM
14320+ iinfo = au_ii(inode);
14321+ /* bad_inode case */
14322+ if (!iinfo)
14323+ return;
1308ab2a 14324+
b752ccd1 14325+ sb = inode->i_sb;
7f207e10 14326+ au_ninodes_dec(sb);
b752ccd1
AM
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+
4a4d8108
AM
14341+ if (iinfo->ii_vdir)
14342+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 14343+
b752ccd1
AM
14344+ bindex = iinfo->ii_bstart;
14345+ if (bindex >= 0) {
14346+ hi = iinfo->ii_hinode + bindex;
4a4d8108 14347+ bend = iinfo->ii_bend;
b752ccd1
AM
14348+ while (bindex++ <= bend) {
14349+ if (hi->hi_inode)
4a4d8108 14350+ au_hiput(hi);
4a4d8108
AM
14351+ hi++;
14352+ }
14353+ }
4a4d8108 14354+ kfree(iinfo->ii_hinode);
027c5e7a 14355+ iinfo->ii_hinode = NULL;
4a4d8108 14356+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 14357+}
7f207e10
AM
14358diff -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
86dc4139 14360+++ linux/fs/aufs/inode.c 2013-07-06 13:20:47.750198454 +0200
1716fcea 14361@@ -0,0 +1,492 @@
4a4d8108 14362+/*
7a9e40b8 14363+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
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+ */
1facf9fc 14379+
4a4d8108
AM
14380+/*
14381+ * inode functions
14382+ */
1facf9fc 14383+
4a4d8108 14384+#include "aufs.h"
1308ab2a 14385+
4a4d8108
AM
14386+struct inode *au_igrab(struct inode *inode)
14387+{
14388+ if (inode) {
14389+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 14390+ ihold(inode);
1facf9fc 14391+ }
4a4d8108
AM
14392+ return inode;
14393+}
1facf9fc 14394+
4a4d8108
AM
14395+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
14396+{
14397+ au_cpup_attr_all(inode, /*force*/0);
537831f9 14398+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
14399+ if (do_version)
14400+ inode->i_version++;
dece6358 14401+}
1facf9fc 14402+
027c5e7a 14403+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 14404+{
4a4d8108 14405+ int err, e;
027c5e7a 14406+ umode_t type;
4a4d8108 14407+ aufs_bindex_t bindex, new_bindex;
1308ab2a 14408+ struct super_block *sb;
4a4d8108 14409+ struct au_iinfo *iinfo;
027c5e7a 14410+ struct au_hinode *p, *q, tmp;
1facf9fc 14411+
4a4d8108 14412+ IiMustWriteLock(inode);
1facf9fc 14413+
027c5e7a 14414+ *update = 0;
4a4d8108 14415+ sb = inode->i_sb;
027c5e7a 14416+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
14417+ iinfo = au_ii(inode);
14418+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
14419+ if (unlikely(err))
1308ab2a 14420+ goto out;
1facf9fc 14421+
027c5e7a 14422+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 14423+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
14424+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14425+ bindex++, p++) {
14426+ if (!p->hi_inode)
14427+ continue;
1facf9fc 14428+
027c5e7a 14429+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
14430+ new_bindex = au_br_index(sb, p->hi_id);
14431+ if (new_bindex == bindex)
14432+ continue;
1facf9fc 14433+
4a4d8108 14434+ if (new_bindex < 0) {
027c5e7a 14435+ *update = 1;
4a4d8108
AM
14436+ au_hiput(p);
14437+ p->hi_inode = NULL;
14438+ continue;
1308ab2a 14439+ }
4a4d8108
AM
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--;
1308ab2a 14453+ }
14454+ }
4a4d8108
AM
14455+ au_update_ibrange(inode, /*do_put_zero*/0);
14456+ e = au_dy_irefresh(inode);
14457+ if (unlikely(e && !err))
14458+ err = e;
1facf9fc 14459+
4f0767ce 14460+out:
027c5e7a
AM
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);
4a4d8108
AM
14474+ return err;
14475+}
1facf9fc 14476+
4a4d8108
AM
14477+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
14478+{
027c5e7a 14479+ int err, e, update;
4a4d8108 14480+ unsigned int flags;
027c5e7a 14481+ umode_t mode;
4a4d8108 14482+ aufs_bindex_t bindex, bend;
027c5e7a 14483+ unsigned char isdir;
4a4d8108
AM
14484+ struct au_hinode *p;
14485+ struct au_iinfo *iinfo;
1facf9fc 14486+
027c5e7a 14487+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
14488+ if (unlikely(err))
14489+ goto out;
14490+
14491+ update = 0;
14492+ iinfo = au_ii(inode);
14493+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
14494+ mode = (inode->i_mode & S_IFMT);
14495+ isdir = S_ISDIR(mode);
4a4d8108
AM
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+
027c5e7a 14506+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
4a4d8108
AM
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;
1308ab2a 14522+ }
4a4d8108
AM
14523+ au_update_ibrange(inode, /*do_put_zero*/0);
14524+ e = au_dy_irefresh(inode);
14525+ if (unlikely(e && !err))
14526+ err = e;
027c5e7a
AM
14527+ if (!err)
14528+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 14529+
4f0767ce 14530+out:
4a4d8108 14531+ AuTraceErr(err);
1308ab2a 14532+ return err;
dece6358
AM
14533+}
14534+
4a4d8108 14535+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 14536+{
4a4d8108
AM
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;
dece6358 14545+
4a4d8108 14546+ IiMustWriteLock(inode);
dece6358 14547+
4a4d8108
AM
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;
1308ab2a 14583+ goto out;
4a4d8108 14584+ }
dece6358 14585+
4a4d8108
AM
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);
dece6358 14603+
4f0767ce 14604+out:
4a4d8108
AM
14605+ return err;
14606+}
dece6358 14607+
027c5e7a
AM
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)
4a4d8108
AM
14615+{
14616+ int err;
537831f9
AM
14617+ unsigned int gen;
14618+ struct au_iigen iigen;
4a4d8108
AM
14619+ aufs_bindex_t bindex, bend;
14620+ struct inode *h_inode, *h_dinode;
dece6358 14621+
4a4d8108
AM
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+
027c5e7a 14631+ err = 1;
4a4d8108
AM
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);
537831f9
AM
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))
4a4d8108 14644+ break;
537831f9
AM
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;
1facf9fc 14651+ }
dece6358 14652+
4a4d8108
AM
14653+ if (unlikely(err))
14654+ ii_write_unlock(inode);
4f0767ce 14655+out:
1facf9fc 14656+ return err;
14657+}
1facf9fc 14658+
4a4d8108
AM
14659+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
14660+ unsigned int d_type, ino_t *ino)
1facf9fc 14661+{
4a4d8108
AM
14662+ int err;
14663+ struct mutex *mtx;
1facf9fc 14664+
b752ccd1 14665+ /* prevent hardlinked inode number from race condition */
4a4d8108 14666+ mtx = NULL;
b752ccd1 14667+ if (d_type != DT_DIR) {
4a4d8108
AM
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;
1308ab2a 14674+
4a4d8108
AM
14675+ if (!*ino) {
14676+ err = -EIO;
14677+ *ino = au_xino_new_ino(sb);
14678+ if (unlikely(!*ino))
1facf9fc 14679+ goto out;
4a4d8108
AM
14680+ err = au_xino_write(sb, bindex, h_ino, *ino);
14681+ if (unlikely(err))
1308ab2a 14682+ goto out;
1308ab2a 14683+ }
1facf9fc 14684+
4f0767ce 14685+out:
b752ccd1 14686+ if (mtx)
4a4d8108 14687+ mutex_unlock(mtx);
1facf9fc 14688+ return err;
14689+}
14690+
4a4d8108
AM
14691+/* successful returns with iinfo write_locked */
14692+/* todo: return with unlocked? */
14693+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 14694+{
b752ccd1 14695+ struct inode *inode, *h_inode;
4a4d8108
AM
14696+ struct dentry *h_dentry;
14697+ struct super_block *sb;
b752ccd1 14698+ struct mutex *mtx;
4a4d8108 14699+ ino_t h_ino, ino;
1716fcea 14700+ int err;
4a4d8108 14701+ aufs_bindex_t bstart;
1facf9fc 14702+
4a4d8108
AM
14703+ sb = dentry->d_sb;
14704+ bstart = au_dbstart(dentry);
14705+ h_dentry = au_h_dptr(dentry, bstart);
b752ccd1
AM
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+
4f0767ce 14717+new_ino:
b752ccd1
AM
14718+ if (mtx)
14719+ mutex_lock(mtx);
4a4d8108
AM
14720+ err = au_xino_read(sb, bstart, h_ino, &ino);
14721+ inode = ERR_PTR(err);
14722+ if (unlikely(err))
14723+ goto out;
b752ccd1 14724+
4a4d8108
AM
14725+ if (!ino) {
14726+ ino = au_xino_new_ino(sb);
14727+ if (unlikely(!ino)) {
14728+ inode = ERR_PTR(-EIO);
dece6358
AM
14729+ goto out;
14730+ }
14731+ }
1facf9fc 14732+
4a4d8108
AM
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))
1facf9fc 14737+ goto out;
1facf9fc 14738+
4a4d8108
AM
14739+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
14740+ if (inode->i_state & I_NEW) {
1716fcea
AM
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);
2dfbb274 14751+
4a4d8108
AM
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+ }
1308ab2a 14758+
027c5e7a
AM
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);
4a4d8108 14765+ iget_failed(inode);
027c5e7a
AM
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) {
b752ccd1
AM
14771+ /*
14772+ * horrible race condition between lookup, readdir and copyup
14773+ * (or something).
14774+ */
14775+ if (mtx)
14776+ mutex_unlock(mtx);
027c5e7a
AM
14777+ err = reval_inode(inode, dentry);
14778+ if (unlikely(err < 0)) {
14779+ mtx = NULL;
14780+ goto out_iput;
14781+ }
14782+
b752ccd1
AM
14783+ if (!err) {
14784+ mtx = NULL;
4a4d8108 14785+ goto out; /* success */
b752ccd1
AM
14786+ } else if (mtx)
14787+ mutex_lock(mtx);
4a4d8108
AM
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);
b752ccd1
AM
14799+ if (mtx)
14800+ mutex_unlock(mtx);
4a4d8108
AM
14801+ goto new_ino;
14802+ }
1308ab2a 14803+
4f0767ce 14804+out_iput:
4a4d8108 14805+ iput(inode);
4a4d8108 14806+ inode = ERR_PTR(err);
4f0767ce 14807+out:
b752ccd1
AM
14808+ if (mtx)
14809+ mutex_unlock(mtx);
4a4d8108 14810+ return inode;
1facf9fc 14811+}
14812+
4a4d8108 14813+/* ---------------------------------------------------------------------- */
1facf9fc 14814+
4a4d8108
AM
14815+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
14816+ struct inode *inode)
14817+{
14818+ int err;
1facf9fc 14819+
4a4d8108 14820+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 14821+
4a4d8108
AM
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;
1facf9fc 14834+ }
14835+
4a4d8108
AM
14836+ return err;
14837+}
dece6358 14838+
4a4d8108
AM
14839+int au_test_h_perm(struct inode *h_inode, int mask)
14840+{
2dfbb274 14841+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
14842+ return 0;
14843+ return inode_permission(h_inode, mask);
14844+}
1facf9fc 14845+
4a4d8108
AM
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);
1facf9fc 14853+}
7f207e10
AM
14854diff -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
86dc4139
AM
14856+++ linux/fs/aufs/inode.h 2013-07-06 13:20:47.750198454 +0200
14857@@ -0,0 +1,600 @@
4a4d8108 14858+/*
7a9e40b8 14859+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
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+ */
1facf9fc 14875+
1308ab2a 14876+/*
4a4d8108 14877+ * inode operations
1308ab2a 14878+ */
dece6358 14879+
4a4d8108
AM
14880+#ifndef __AUFS_INODE_H__
14881+#define __AUFS_INODE_H__
dece6358 14882+
4a4d8108 14883+#ifdef __KERNEL__
1308ab2a 14884+
4a4d8108 14885+#include <linux/fsnotify.h>
4a4d8108 14886+#include "rwsem.h"
1308ab2a 14887+
4a4d8108 14888+struct vfsmount;
1facf9fc 14889+
4a4d8108
AM
14890+struct au_hnotify {
14891+#ifdef CONFIG_AUFS_HNOTIFY
14892+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 14893+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 14894+ struct fsnotify_mark hn_mark;
4a4d8108 14895+#endif
7f207e10 14896+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
14897+#endif
14898+} ____cacheline_aligned_in_smp;
1facf9fc 14899+
4a4d8108
AM
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
dece6358 14906+
4a4d8108
AM
14907+ /* reference to the copied-up whiteout with get/put */
14908+ struct dentry *hi_whdentry;
14909+};
dece6358 14910+
537831f9
AM
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+
4a4d8108
AM
14923+struct au_vdir;
14924+struct au_iinfo {
537831f9 14925+ spinlock_t ii_genspin;
7a9e40b8 14926+ struct au_iigen ii_generation;
4a4d8108 14927+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 14928+
4a4d8108
AM
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+};
1facf9fc 14935+
4a4d8108
AM
14936+struct au_icntnr {
14937+ struct au_iinfo iinfo;
14938+ struct inode vfs_inode;
14939+} ____cacheline_aligned_in_smp;
1308ab2a 14940+
4a4d8108
AM
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)
7f207e10
AM
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)
4a4d8108
AM
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;
86dc4139
AM
14961+
14962+ /* temporary unlock/relock for copyup */
14963+ struct dentry *h_dentry, *h_parent;
14964+ struct au_branch *br;
14965+ struct task_struct *task;
4a4d8108 14966+};
1facf9fc 14967+
86dc4139
AM
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+
1308ab2a 14974+/* ---------------------------------------------------------------------- */
14975+
4a4d8108 14976+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 14977+{
4a4d8108 14978+ struct au_iinfo *iinfo;
1facf9fc 14979+
4a4d8108
AM
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+}
1facf9fc 14985+
4a4d8108 14986+/* ---------------------------------------------------------------------- */
1facf9fc 14987+
4a4d8108
AM
14988+/* inode.c */
14989+struct inode *au_igrab(struct inode *inode);
027c5e7a 14990+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
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);
1facf9fc 14999+
4a4d8108
AM
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+}
1facf9fc 15009+
4a4d8108
AM
15010+/* i_op.c */
15011+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 15012+
4a4d8108
AM
15013+/* au_wr_dir flags */
15014+#define AuWrDir_ADD_ENTRY 1
86dc4139
AM
15015+#define AuWrDir_TMP_WHENTRY (1 << 1)
15016+#define AuWrDir_ISDIR (1 << 2)
4a4d8108 15017+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
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)
1facf9fc 15022+
4a4d8108
AM
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);
dece6358 15029+
4a4d8108
AM
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);
1facf9fc 15038+
4a4d8108
AM
15039+/* i_op_add.c */
15040+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15041+ struct dentry *h_parent, int isdir);
7eafdf33
AM
15042+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15043+ dev_t dev);
4a4d8108 15044+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 15045+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 15046+ bool want_excl);
4a4d8108
AM
15047+int aufs_link(struct dentry *src_dentry, struct inode *dir,
15048+ struct dentry *dentry);
7eafdf33 15049+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 15050+
4a4d8108
AM
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);
1308ab2a 15057+
4a4d8108
AM
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);
1facf9fc 15062+
4a4d8108
AM
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);
1308ab2a 15069+
4a4d8108
AM
15070+/* hinode flags */
15071+#define AuHi_XINO 1
15072+#define AuHi_HNOTIFY (1 << 1)
15073+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
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)
1facf9fc 15078+
4a4d8108
AM
15079+#ifndef CONFIG_AUFS_HNOTIFY
15080+#undef AuHi_HNOTIFY
15081+#define AuHi_HNOTIFY 0
15082+#endif
1facf9fc 15083+
4a4d8108
AM
15084+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15085+ struct inode *h_inode, unsigned int flags);
1facf9fc 15086+
537831f9 15087+void au_update_iigen(struct inode *inode, int half);
4a4d8108 15088+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 15089+
4a4d8108
AM
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);
1308ab2a 15094+
e49829fe 15095+#ifdef CONFIG_PROC_FS
4a4d8108 15096+/* plink.c */
e49829fe
JR
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);
4a4d8108
AM
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);
e49829fe
JR
15109+void au_plink_put(struct super_block *sb, int verbose);
15110+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 15111+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
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 */
1facf9fc 15126+
4a4d8108 15127+/* ---------------------------------------------------------------------- */
1308ab2a 15128+
4a4d8108
AM
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+};
1308ab2a 15139+
1facf9fc 15140+/*
4a4d8108
AM
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,
1facf9fc 15148+ */
4a4d8108
AM
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
1facf9fc 15176+
15177+/*
4a4d8108 15178+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 15179+ */
4a4d8108 15180+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 15181+
4a4d8108
AM
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)
1facf9fc 15185+
4a4d8108 15186+/* ---------------------------------------------------------------------- */
1308ab2a 15187+
027c5e7a
AM
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+
537831f9 15195+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 15196+{
537831f9
AM
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;
4a4d8108 15208+}
1308ab2a 15209+
4a4d8108
AM
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;
1308ab2a 15215+
4a4d8108
AM
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+}
1308ab2a 15221+
4a4d8108
AM
15222+static inline void au_iigen_dec(struct inode *inode)
15223+{
537831f9
AM
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);
027c5e7a
AM
15230+}
15231+
15232+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
15233+{
15234+ int err;
15235+
15236+ err = 0;
537831f9 15237+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
15238+ err = -EIO;
15239+
15240+ return err;
4a4d8108 15241+}
1308ab2a 15242+
4a4d8108 15243+/* ---------------------------------------------------------------------- */
1308ab2a 15244+
4a4d8108
AM
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+}
1308ab2a 15251+
4a4d8108
AM
15252+static inline aufs_bindex_t au_ibstart(struct inode *inode)
15253+{
15254+ IiMustAnyLock(inode);
15255+ return au_ii(inode)->ii_bstart;
15256+}
1308ab2a 15257+
4a4d8108
AM
15258+static inline aufs_bindex_t au_ibend(struct inode *inode)
15259+{
15260+ IiMustAnyLock(inode);
15261+ return au_ii(inode)->ii_bend;
15262+}
1308ab2a 15263+
4a4d8108
AM
15264+static inline struct au_vdir *au_ivdir(struct inode *inode)
15265+{
15266+ IiMustAnyLock(inode);
15267+ return au_ii(inode)->ii_vdir;
15268+}
1308ab2a 15269+
4a4d8108
AM
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+}
1308ab2a 15275+
4a4d8108 15276+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15277+{
4a4d8108
AM
15278+ IiMustWriteLock(inode);
15279+ au_ii(inode)->ii_bstart = bindex;
15280+}
1308ab2a 15281+
4a4d8108
AM
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;
1308ab2a 15286+}
15287+
4a4d8108
AM
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+}
1facf9fc 15293+
4a4d8108 15294+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15295+{
4a4d8108
AM
15296+ IiMustAnyLock(inode);
15297+ return au_ii(inode)->ii_hinode + bindex;
15298+}
dece6358 15299+
4a4d8108 15300+/* ---------------------------------------------------------------------- */
1facf9fc 15301+
4a4d8108
AM
15302+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
15303+{
15304+ if (pin)
15305+ return pin->parent;
15306+ return NULL;
1facf9fc 15307+}
15308+
4a4d8108 15309+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 15310+{
4a4d8108
AM
15311+ if (pin && pin->hdir)
15312+ return pin->hdir->hi_inode;
15313+ return NULL;
1308ab2a 15314+}
1facf9fc 15315+
4a4d8108
AM
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+}
1facf9fc 15322+
4a4d8108 15323+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 15324+{
4a4d8108
AM
15325+ if (pin)
15326+ pin->dentry = dentry;
15327+}
1308ab2a 15328+
4a4d8108
AM
15329+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
15330+ unsigned char lflag)
15331+{
15332+ if (pin) {
7f207e10 15333+ if (lflag)
4a4d8108 15334+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 15335+ else
4a4d8108 15336+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 15337+ }
4a4d8108
AM
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);
1facf9fc 15345+ }
4a4d8108 15346+}
1facf9fc 15347+
4a4d8108
AM
15348+/* ---------------------------------------------------------------------- */
15349+
027c5e7a 15350+struct au_branch;
4a4d8108
AM
15351+#ifdef CONFIG_AUFS_HNOTIFY
15352+struct au_hnotify_op {
15353+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 15354+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
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;
4a4d8108
AM
15362+
15363+ void (*fin)(void);
15364+ int (*init)(void);
027c5e7a
AM
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);
4a4d8108
AM
15369+};
15370+
15371+/* hnotify.c */
027c5e7a 15372+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
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);
027c5e7a
AM
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);
4a4d8108
AM
15381+int __init au_hnotify_init(void);
15382+void au_hnotify_fin(void);
15383+
7f207e10 15384+/* hfsnotify.c */
4a4d8108
AM
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;
1308ab2a 15391+}
15392+
53392da6
AM
15393+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15394+{
15395+ return hinode->hi_notify;
15396+}
15397+
4a4d8108
AM
15398+#else
15399+static inline
15400+int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
027c5e7a 15401+ struct inode *inode __maybe_unused)
1308ab2a 15402+{
4a4d8108
AM
15403+ return -EOPNOTSUPP;
15404+}
1308ab2a 15405+
53392da6
AM
15406+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15407+{
15408+ return NULL;
15409+}
15410+
4a4d8108
AM
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)
027c5e7a
AM
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)
4a4d8108
AM
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);
1308ab2a 15430+}
15431+
4a4d8108 15432+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 15433+{
4a4d8108
AM
15434+ au_hn_ctl(hdir, /*do_set*/1);
15435+}
1308ab2a 15436+
4a4d8108
AM
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+}
dece6358 15442+
4a4d8108
AM
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);
1facf9fc 15448+}
1facf9fc 15449+
4a4d8108
AM
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__ */
7f207e10
AM
15458diff -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
86dc4139 15460+++ linux/fs/aufs/ioctl.c 2013-07-06 13:20:47.750198454 +0200
f6c5ef8b 15461@@ -0,0 +1,196 @@
4a4d8108 15462+/*
7a9e40b8 15463+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
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+
4a4d8108
AM
15486+#include "aufs.h"
15487+
1e00d052 15488+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
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;
1e00d052
AM
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;
4a4d8108 15502+
1e00d052
AM
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))
4a4d8108 15523+ goto out;
4a4d8108 15524+
1e00d052 15525+ h_file = ERR_PTR(-EINVAL);
4a4d8108 15526+ wbi = 0;
1e00d052 15527+ br = NULL;
4a4d8108
AM
15528+ sb = path->dentry->d_sb;
15529+ root = sb->s_root;
15530+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
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)) {
4a4d8108 15549+ wbi = bindex;
1e00d052 15550+ br = au_sbr(sb, wbi);
4a4d8108
AM
15551+ break;
15552+ }
15553+ }
4a4d8108
AM
15554+ }
15555+ AuDbg("wbi %d\n", wbi);
1e00d052
AM
15556+ if (wbi >= 0)
15557+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL);
15558+
15559+out_unlock:
4a4d8108
AM
15560+ aufs_read_unlock(root, AuLock_IR);
15561+ err = PTR_ERR(h_file);
15562+ if (IS_ERR(h_file))
15563+ goto out_fd;
15564+
1e00d052 15565+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
15566+ fd_install(fd, h_file);
15567+ err = fd;
15568+ goto out; /* success */
15569+
4f0767ce 15570+out_fd:
4a4d8108 15571+ put_unused_fd(fd);
4f0767ce 15572+out:
1e00d052 15573+ AuTraceErr(err);
4a4d8108
AM
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) {
4a4d8108
AM
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:
1e00d052 15590+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
15591+ break;
15592+
027c5e7a
AM
15593+ case AUFS_CTL_IBUSY:
15594+ err = au_ibusy_ioctl(file, arg);
15595+ break;
15596+
4a4d8108
AM
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:
1e00d052 15613+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
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+}
b752ccd1
AM
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+
027c5e7a
AM
15638+ case AUFS_CTL_IBUSY:
15639+ err = au_ibusy_compat_ioctl(file, arg);
15640+ break;
15641+
b752ccd1
AM
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
7f207e10
AM
15658diff -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
367653fa
AM
15660+++ linux/fs/aufs/i_op_add.c 2013-07-30 22:42:46.235946055 +0200
15661@@ -0,0 +1,716 @@
4a4d8108 15662+/*
7a9e40b8 15663+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
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+
4f0767ce 15741+out:
4a4d8108
AM
15742+ return err;
15743+}
15744+
027c5e7a
AM
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+
4a4d8108
AM
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+
4f0767ce 15801+out:
4a4d8108
AM
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,
86dc4139 15854+ .mnt = au_br_mnt(br)
4a4d8108
AM
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+
4f0767ce 15865+out_unpin:
4a4d8108
AM
15866+ if (IS_ERR(wh_dentry))
15867+ au_unpin(pin);
4f0767ce 15868+out:
4a4d8108
AM
15869+ return wh_dentry;
15870+}
15871+
15872+/* ---------------------------------------------------------------------- */
15873+
15874+enum { Mknod, Symlink, Creat };
15875+struct simple_arg {
15876+ int type;
15877+ union {
15878+ struct {
7eafdf33 15879+ umode_t mode;
b4510431 15880+ bool want_excl;
4a4d8108
AM
15881+ } c;
15882+ struct {
15883+ const char *symname;
15884+ } s;
15885+ struct {
7eafdf33 15886+ umode_t mode;
4a4d8108
AM
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 */
027c5e7a
AM
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;
4a4d8108
AM
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))
027c5e7a 15923+ goto out_parent;
4a4d8108
AM
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:
537831f9
AM
15931+ err = vfsub_create(h_dir, &h_path, arg->u.c.mode,
15932+ arg->u.c.want_excl);
4a4d8108
AM
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);
4a4d8108
AM
15957+ }
15958+
15959+ au_unpin(&pin);
15960+ dput(wh_dentry);
15961+
027c5e7a
AM
15962+out_parent:
15963+ di_write_unlock(parent);
15964+out_unlock:
4a4d8108
AM
15965+ if (unlikely(err)) {
15966+ au_update_dbstart(dentry);
15967+ d_drop(dentry);
15968+ }
4a4d8108 15969+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 15970+out:
4a4d8108
AM
15971+ return err;
15972+}
15973+
7eafdf33
AM
15974+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15975+ dev_t dev)
4a4d8108
AM
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+
7eafdf33 15996+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 15997+ bool want_excl)
4a4d8108
AM
15998+{
15999+ struct simple_arg arg = {
16000+ .type = Creat,
16001+ .u.c = {
b4510431
AM
16002+ .mode = mode,
16003+ .want_excl = want_excl
4a4d8108
AM
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;
4a4d8108
AM
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);
4a4d8108
AM
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;
367653fa
AM
16035+
16036+ err = au_sio_cpup_simple_h_open(src_dentry, a->bdst, -1,
16037+ AuCpup_DTIME /* | AuCpup_KEEPLINO */,
16038+ &a->pin, a->bsrc);
4a4d8108
AM
16039+ au_unpin(&a->pin);
16040+
4f0767ce 16041+out:
4a4d8108
AM
16042+ di_read_unlock(a->src_parent, AuLock_IR);
16043+ return err;
16044+}
16045+
86dc4139
AM
16046+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
16047+ struct au_link_args *a)
4a4d8108
AM
16048+{
16049+ int err;
16050+ unsigned char plink;
86dc4139 16051+ aufs_bindex_t bend;
4a4d8108 16052+ struct dentry *h_src_dentry;
86dc4139 16053+ struct inode *h_inode, *inode;
4a4d8108
AM
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. */
86dc4139
AM
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))
4a4d8108 16075+ err = PTR_ERR(h_file);
86dc4139
AM
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);
4a4d8108
AM
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:
2cbb1c4b 16121+ AuTraceErr(err);
4a4d8108
AM
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+
4a4d8108
AM
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 */
027c5e7a
AM
16149+ err = aufs_read_and_write_lock2(dentry, src_dentry,
16150+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
16151+ if (unlikely(err))
16152+ goto out_kfree;
027c5e7a
AM
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;
e49829fe 16159+
4a4d8108 16160+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 16161+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
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))
027c5e7a 16169+ goto out_parent;
4a4d8108
AM
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);
2cbb1c4b
JR
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+
4a4d8108
AM
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 */)
86dc4139 16188+ err = au_cpup_or_link(src_dentry, dentry, a);
2cbb1c4b 16189+ else
4a4d8108
AM
16190+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
16191+ &a->h_path);
2cbb1c4b 16192+ dput(h_src_dentry);
4a4d8108
AM
16193+ } else {
16194+ /*
16195+ * copyup src_dentry to the branch we process,
16196+ * and then link(2) to it.
16197+ */
2cbb1c4b 16198+ dput(h_src_dentry);
4a4d8108
AM
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;
027c5e7a
AM
16237+ d_instantiate(dentry, au_igrab(inode));
16238+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
16239+ /* some filesystem calls d_drop() */
16240+ d_drop(dentry);
16241+ goto out_unpin; /* success */
16242+
4f0767ce 16243+out_revert:
4a4d8108 16244+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0);
027c5e7a
AM
16245+ if (unlikely(rerr)) {
16246+ AuIOErr("%.*s reverting failed(%d, %d)\n",
16247+ AuDLNPair(dentry), err, rerr);
16248+ err = -EIO;
16249+ }
4a4d8108 16250+ au_dtime_revert(&dt);
4f0767ce 16251+out_unpin:
4a4d8108 16252+ au_unpin(&a->pin);
4f0767ce 16253+out_wh:
4a4d8108 16254+ dput(wh_dentry);
027c5e7a
AM
16255+out_parent:
16256+ di_write_unlock(a->parent);
16257+ dput(a->src_parent);
4f0767ce 16258+out_unlock:
4a4d8108
AM
16259+ if (unlikely(err)) {
16260+ au_update_dbstart(dentry);
16261+ d_drop(dentry);
16262+ }
4a4d8108 16263+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 16264+out_kfree:
4a4d8108 16265+ kfree(a);
4f0767ce 16266+out:
86dc4139 16267+ AuTraceErr(err);
4a4d8108
AM
16268+ return err;
16269+}
16270+
7eafdf33 16271+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
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+
027c5e7a
AM
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+
4a4d8108
AM
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))
027c5e7a 16309+ goto out_parent;
4a4d8108
AM
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))
027c5e7a 16317+ goto out_unpin;
4a4d8108
AM
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);
027c5e7a 16337+ goto out_unpin; /* success */
4a4d8108
AM
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+
4f0767ce 16353+out_dir:
4a4d8108
AM
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+ }
4a4d8108 16361+ au_dtime_revert(&a->dt);
027c5e7a 16362+out_unpin:
4a4d8108
AM
16363+ au_unpin(&a->pin);
16364+ dput(wh_dentry);
027c5e7a
AM
16365+out_parent:
16366+ di_write_unlock(parent);
16367+out_unlock:
4a4d8108
AM
16368+ if (unlikely(err)) {
16369+ au_update_dbstart(dentry);
16370+ d_drop(dentry);
16371+ }
4a4d8108 16372+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 16373+out_free:
4a4d8108 16374+ kfree(a);
4f0767ce 16375+out:
4a4d8108
AM
16376+ return err;
16377+}
7f207e10
AM
16378diff -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
367653fa
AM
16380+++ linux/fs/aufs/i_op.c 2013-07-30 22:42:46.235946055 +0200
16381@@ -0,0 +1,1100 @@
4a4d8108 16382+/*
7a9e40b8 16383+ * Copyright (C) 2005-2013 Junjiro R. Okajima
4a4d8108
AM
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+ */
1facf9fc 16399+
1308ab2a 16400+/*
4a4d8108 16401+ * inode operations (except add/del/rename)
1308ab2a 16402+ */
4a4d8108
AM
16403+
16404+#include <linux/device_cgroup.h>
16405+#include <linux/fs_stack.h>
92d182d2 16406+#include <linux/mm.h>
4a4d8108
AM
16407+#include <linux/namei.h>
16408+#include <linux/security.h>
4a4d8108
AM
16409+#include "aufs.h"
16410+
1e00d052 16411+static int h_permission(struct inode *h_inode, int mask,
4a4d8108 16412+ struct vfsmount *h_mnt, int brperm)
1facf9fc 16413+{
1308ab2a 16414+ int err;
4a4d8108 16415+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 16416+
4a4d8108
AM
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); */
1e00d052 16435+ err = generic_permission(h_inode, mask);
1308ab2a 16436+ } else {
4a4d8108 16437+ /* AuLabel(h_inode->permission); */
1e00d052 16438+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
16439+ AuTraceErr(err);
16440+ }
1facf9fc 16441+
4a4d8108
AM
16442+ if (!err)
16443+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 16444+ if (!err)
4a4d8108 16445+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
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);
1308ab2a 16457+ }
4a4d8108 16458+#endif
dece6358 16459+
4f0767ce 16460+out:
1308ab2a 16461+ return err;
16462+}
dece6358 16463+
1e00d052 16464+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 16465+{
16466+ int err;
4a4d8108
AM
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;
1facf9fc 16473+
027c5e7a 16474+ /* todo: support rcu-walk? */
1e00d052 16475+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
16476+ return -ECHILD;
16477+
4a4d8108
AM
16478+ sb = inode->i_sb;
16479+ si_read_lock(sb, AuLock_FLUSH);
16480+ ii_read_lock_child(inode);
027c5e7a
AM
16481+#if 0
16482+ err = au_iigen_test(inode, au_sigen(sb));
16483+ if (unlikely(err))
16484+ goto out;
16485+#endif
dece6358 16486+
4a4d8108
AM
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;
1facf9fc 16494+
4a4d8108
AM
16495+ err = 0;
16496+ bindex = au_ibstart(inode);
16497+ br = au_sbr(sb, bindex);
86dc4139 16498+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
4a4d8108
AM
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+ }
dece6358 16512+
4a4d8108 16513+ /* non-write to dir */
1308ab2a 16514+ err = 0;
4a4d8108
AM
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);
86dc4139 16524+ err = h_permission(h_inode, mask, au_br_mnt(br),
4a4d8108
AM
16525+ br->br_perm);
16526+ }
16527+ }
1308ab2a 16528+
4f0767ce 16529+out:
4a4d8108
AM
16530+ ii_read_unlock(inode);
16531+ si_read_unlock(sb);
1308ab2a 16532+ return err;
16533+}
16534+
4a4d8108 16535+/* ---------------------------------------------------------------------- */
1facf9fc 16536+
4a4d8108 16537+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 16538+ unsigned int flags)
4a4d8108
AM
16539+{
16540+ struct dentry *ret, *parent;
b752ccd1 16541+ struct inode *inode;
4a4d8108 16542+ struct super_block *sb;
1716fcea 16543+ int err, npositive;
dece6358 16544+
4a4d8108 16545+ IMustLock(dir);
1308ab2a 16546+
537831f9
AM
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+
4a4d8108 16556+ sb = dir->i_sb;
7f207e10
AM
16557+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
16558+ ret = ERR_PTR(err);
16559+ if (unlikely(err))
16560+ goto out;
16561+
4a4d8108
AM
16562+ err = au_di_init(dentry);
16563+ ret = ERR_PTR(err);
16564+ if (unlikely(err))
7f207e10 16565+ goto out_si;
1308ab2a 16566+
9dbd164d 16567+ inode = NULL;
027c5e7a 16568+ npositive = 0; /* suppress a warning */
4a4d8108
AM
16569+ parent = dentry->d_parent; /* dir inode is locked */
16570+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
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),
537831f9 16576+ /*type*/0);
027c5e7a
AM
16577+ err = npositive;
16578+ }
4a4d8108 16579+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
16580+ ret = ERR_PTR(err);
16581+ if (unlikely(err < 0))
16582+ goto out_unlock;
1308ab2a 16583+
4a4d8108 16584+ if (npositive) {
b752ccd1 16585+ inode = au_new_inode(dentry, /*must_new*/0);
4a4d8108 16586+ ret = (void *)inode;
1facf9fc 16587+ }
9dbd164d
AM
16588+ if (IS_ERR(inode)) {
16589+ inode = NULL;
4a4d8108 16590+ goto out_unlock;
9dbd164d 16591+ }
4a4d8108
AM
16592+
16593+ ret = d_splice_alias(inode, dentry);
537831f9
AM
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
7f207e10 16601+ if (unlikely(IS_ERR(ret) && inode)) {
4a4d8108 16602+ ii_write_unlock(inode);
7f207e10 16603+ iput(inode);
2dfbb274 16604+ inode = NULL;
7f207e10 16605+ }
1facf9fc 16606+
4f0767ce 16607+out_unlock:
4a4d8108 16608+ di_write_unlock(dentry);
2dfbb274 16609+ if (inode) {
1716fcea
AM
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);
9dbd164d 16620+ }
7f207e10 16621+out_si:
4a4d8108 16622+ si_read_unlock(sb);
7f207e10 16623+out:
4a4d8108
AM
16624+ return ret;
16625+}
1facf9fc 16626+
4a4d8108 16627+/* ---------------------------------------------------------------------- */
1facf9fc 16628+
4a4d8108
AM
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;
1facf9fc 16636+
027c5e7a 16637+ if (add_entry)
4a4d8108 16638+ IMustLock(parent->d_inode);
027c5e7a 16639+ else
4a4d8108
AM
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);
86dc4139
AM
16653+ err = au_lkup_neg(dentry, bcpup,
16654+ au_ftest_wrdir(add_entry, TMP_WHENTRY));
4a4d8108
AM
16655+ /* todo: no unlock here */
16656+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
16657+
16658+ AuDbg("bcpup %d\n", bcpup);
16659+ if (!err) {
16660+ if (!dentry->d_inode)
16661+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
16662+ au_update_dbrange(dentry, /*do_put_zero*/0);
16663+ }
1308ab2a 16664+ }
1facf9fc 16665+
4a4d8108
AM
16666+ if (!add_entry)
16667+ di_write_unlock(parent);
16668+ if (!err)
16669+ err = bcpup; /* success */
1308ab2a 16670+
027c5e7a 16671+ AuTraceErr(err);
4a4d8108
AM
16672+ return err;
16673+}
1facf9fc 16674+
4a4d8108
AM
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;
86dc4139
AM
16685+ const unsigned char add_entry
16686+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
16687+ | au_ftest_wrdir(args->flags, TMP_WHENTRY);
4a4d8108
AM
16688+ struct super_block *sb;
16689+ struct dentry *parent;
16690+ struct au_sbinfo *sbinfo;
1facf9fc 16691+
4a4d8108
AM
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+ }
1facf9fc 16707+
4a4d8108
AM
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));
1308ab2a 16726+ }
027c5e7a 16727+
4a4d8108
AM
16728+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
16729+ err = bcpup;
16730+ if (bcpup == bstart)
16731+ goto out; /* success */
4a4d8108
AM
16732+
16733+ /* copyup the new parent into the branch we process */
16734+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a
AM
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+ }
86dc4139
AM
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+ }
dece6358 16820+}
1facf9fc 16821+
86dc4139
AM
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+}
1308ab2a 16829+
4a4d8108 16830+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 16831+{
4a4d8108
AM
16832+ if (pin && pin->parent)
16833+ return au_h_dptr(pin->parent, pin->bindex);
16834+ return NULL;
dece6358 16835+}
1facf9fc 16836+
4a4d8108 16837+void au_unpin(struct au_pin *p)
dece6358 16838+{
86dc4139
AM
16839+ if (p->hdir)
16840+ au_pin_hdir_unlock(p);
e49829fe 16841+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 16842+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
16843+ if (!p->hdir)
16844+ return;
1facf9fc 16845+
4a4d8108
AM
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;
86dc4139 16853+ /* do not clear p->task */
4a4d8108 16854+}
1308ab2a 16855+
4a4d8108
AM
16856+int au_do_pin(struct au_pin *p)
16857+{
16858+ int err;
16859+ struct super_block *sb;
4a4d8108
AM
16860+ struct inode *h_dir;
16861+
16862+ err = 0;
16863+ sb = p->dentry->d_sb;
86dc4139 16864+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
16865+ if (IS_ROOT(p->dentry)) {
16866+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 16867+ p->h_mnt = au_br_mnt(p->br);
b4510431 16868+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
16869+ if (unlikely(err)) {
16870+ au_fclr_pin(p->flags, MNT_WRITE);
16871+ goto out_err;
16872+ }
16873+ }
dece6358 16874+ goto out;
1facf9fc 16875+ }
16876+
86dc4139 16877+ p->h_dentry = NULL;
4a4d8108 16878+ if (p->bindex <= au_dbend(p->dentry))
86dc4139 16879+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 16880+
4a4d8108
AM
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);
dece6358 16884+
4a4d8108 16885+ h_dir = NULL;
86dc4139 16886+ p->h_parent = au_h_dptr(p->parent, p->bindex);
4a4d8108
AM
16887+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
16888+ if (p->hdir)
16889+ h_dir = p->hdir->hi_inode;
dece6358 16890+
b752ccd1
AM
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+ */
86dc4139 16896+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 16897+ err = -EBUSY;
4a4d8108
AM
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+ }
1308ab2a 16904+
4a4d8108 16905+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 16906+ p->h_mnt = au_br_mnt(p->br);
b4510431 16907+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 16908+ if (unlikely(err)) {
4a4d8108 16909+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
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;
dece6358
AM
16915+ }
16916+ }
4a4d8108 16917+
86dc4139
AM
16918+ au_igrab(h_dir);
16919+ err = au_pin_hdir_lock(p);
16920+ if (!err)
16921+ goto out; /* success */
16922+
4f0767ce 16923+out_err:
4a4d8108
AM
16924+ pr_err("err %d\n", err);
16925+ err = au_busy_or_stale();
4f0767ce 16926+out:
1facf9fc 16927+ return err;
16928+}
16929+
4a4d8108
AM
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;
86dc4139
AM
16944+
16945+ p->h_dentry = NULL;
16946+ p->h_parent = NULL;
16947+ p->br = NULL;
16948+ p->task = current;
4a4d8108
AM
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+
dece6358
AM
16959+/* ---------------------------------------------------------------------- */
16960+
1308ab2a 16961+/*
4a4d8108
AM
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.
1308ab2a 16967+ */
027c5e7a 16968+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
4a4d8108 16969+static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 16970+{
4a4d8108
AM
16971+ int err;
16972+ struct inode *inode;
16973+ struct dentry *parent;
1facf9fc 16974+
1308ab2a 16975+ err = 0;
4a4d8108 16976+ inode = dentry->d_inode;
027c5e7a 16977+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
16978+ parent = dget_parent(dentry);
16979+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 16980+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
16981+ di_read_unlock(parent, AuLock_IR);
16982+ dput(parent);
dece6358 16983+ }
1facf9fc 16984+
4a4d8108 16985+ AuTraceErr(err);
1308ab2a 16986+ return err;
16987+}
dece6358 16988+
4a4d8108
AM
16989+#define AuIcpup_DID_CPUP 1
16990+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
7f207e10
AM
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)
1308ab2a 16995+
4a4d8108
AM
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+};
1308ab2a 17005+
4a4d8108
AM
17006+static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
17007+ struct au_icpup_args *a)
1308ab2a 17008+{
17009+ int err;
4a4d8108 17010+ loff_t sz;
e49829fe 17011+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
17012+ struct dentry *hi_wh, *parent;
17013+ struct inode *inode;
4a4d8108
AM
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 */
e49829fe 17024+ ibstart = au_ibstart(inode);
027c5e7a 17025+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 17026+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
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;
86dc4139 17053+ mutex_unlock(&a->h_inode->i_mutex);
4a4d8108 17054+
4a4d8108 17055+ hi_wh = NULL;
027c5e7a 17056+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
17057+ hi_wh = au_hi_wh(inode, a->btgt);
17058+ if (!hi_wh) {
86dc4139
AM
17059+ err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL,
17060+ &a->pin);
4a4d8108
AM
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)) {
367653fa
AM
17078+ err = au_sio_cpup_simple_h_open(dentry, a->btgt, sz,
17079+ AuCpup_DTIME, &a->pin, bstart);
4a4d8108
AM
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 */
1308ab2a 17086+
4f0767ce 17087+out_unlock:
4a4d8108 17088+ a->h_inode = a->h_path.dentry->d_inode;
86dc4139 17089+ if (!err)
dece6358 17090+ goto out; /* success */
4a4d8108 17091+ au_unpin(&a->pin);
4f0767ce 17092+out_parent:
4a4d8108
AM
17093+ if (parent) {
17094+ di_write_unlock(parent);
17095+ dput(parent);
17096+ }
4f0767ce 17097+out:
86dc4139
AM
17098+ if (!err)
17099+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
1facf9fc 17100+ return err;
17101+}
17102+
4a4d8108 17103+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 17104+{
4a4d8108
AM
17105+ int err;
17106+ struct inode *inode;
17107+ struct super_block *sb;
17108+ struct file *file;
17109+ struct au_icpup_args *a;
1facf9fc 17110+
4a4d8108
AM
17111+ inode = dentry->d_inode;
17112+ IMustLock(inode);
dece6358 17113+
4a4d8108
AM
17114+ err = -ENOMEM;
17115+ a = kzalloc(sizeof(*a), GFP_NOFS);
17116+ if (unlikely(!a))
17117+ goto out;
1facf9fc 17118+
4a4d8108
AM
17119+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
17120+ ia->ia_valid &= ~ATTR_MODE;
dece6358 17121+
4a4d8108
AM
17122+ file = NULL;
17123+ sb = dentry->d_sb;
e49829fe
JR
17124+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17125+ if (unlikely(err))
17126+ goto out_kfree;
17127+
4a4d8108
AM
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);
027c5e7a
AM
17140+ di_write_lock_child(dentry);
17141+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
17142+ if (d_unhashed(dentry))
17143+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
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+ }
dece6358 17150+ }
dece6358 17151+
4a4d8108
AM
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;
1308ab2a 17158+ }
dece6358 17159+
4a4d8108
AM
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)) {
7eafdf33 17163+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
17164+ if (unlikely(err))
17165+ goto out_unlock;
17166+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
17167+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 17168+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
17169+ if (unlikely(err))
17170+ goto out_unlock;
17171+ }
dece6358 17172+
4a4d8108
AM
17173+ if (ia->ia_valid & ATTR_SIZE) {
17174+ struct file *f;
1308ab2a 17175+
953406b4 17176+ if (ia->ia_size < i_size_read(inode))
4a4d8108 17177+ /* unmap only */
953406b4 17178+ truncate_setsize(inode, ia->ia_size);
1308ab2a 17179+
4a4d8108
AM
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);
1308ab2a 17190+
4f0767ce 17191+out_unlock:
4a4d8108
AM
17192+ mutex_unlock(&a->h_inode->i_mutex);
17193+ au_unpin(&a->pin);
027c5e7a
AM
17194+ if (unlikely(err))
17195+ au_update_dbstart(dentry);
4f0767ce 17196+out_dentry:
4a4d8108
AM
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+ }
4f0767ce 17203+out_si:
4a4d8108 17204+ si_read_unlock(sb);
e49829fe 17205+out_kfree:
4a4d8108 17206+ kfree(a);
4f0767ce 17207+out:
4a4d8108
AM
17208+ AuTraceErr(err);
17209+ return err;
1facf9fc 17210+}
17211+
4a4d8108
AM
17212+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
17213+ unsigned int nlink)
1facf9fc 17214+{
9dbd164d
AM
17215+ unsigned int n;
17216+
4a4d8108 17217+ inode->i_mode = st->mode;
86dc4139
AM
17218+ /* don't i_[ug]id_write() here */
17219+ inode->i_uid = st->uid;
17220+ inode->i_gid = st->gid;
4a4d8108
AM
17221+ inode->i_atime = st->atime;
17222+ inode->i_mtime = st->mtime;
17223+ inode->i_ctime = st->ctime;
1facf9fc 17224+
4a4d8108
AM
17225+ au_cpup_attr_nlink(inode, /*force*/0);
17226+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
17227+ n = inode->i_nlink;
17228+ n -= nlink;
17229+ n += st->nlink;
86dc4139 17230+ smp_mb();
7eafdf33 17231+ /* 0 can happen */
92d182d2 17232+ set_nlink(inode, n);
4a4d8108 17233+ }
1facf9fc 17234+
4a4d8108
AM
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);
1facf9fc 17239+}
17240+
4a4d8108
AM
17241+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
17242+ struct dentry *dentry, struct kstat *st)
1facf9fc 17243+{
4a4d8108
AM
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;
c06a8ce3 17250+ struct path h_path;
1facf9fc 17251+
4a4d8108
AM
17252+ sb = dentry->d_sb;
17253+ inode = dentry->d_inode;
7f207e10
AM
17254+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17255+ if (unlikely(err))
17256+ goto out;
4a4d8108
AM
17257+ mnt_flags = au_mntflags(sb);
17258+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 17259+
4a4d8108 17260+ /* support fstat(2) */
027c5e7a 17261+ if (!d_unlinked(dentry) && !udba_none) {
4a4d8108 17262+ unsigned int sigen = au_sigen(sb);
027c5e7a
AM
17263+ err = au_digen_test(dentry, sigen);
17264+ if (!err) {
4a4d8108 17265+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a
AM
17266+ err = au_dbrange_test(dentry);
17267+ if (unlikely(err))
17268+ goto out_unlock;
17269+ } else {
4a4d8108
AM
17270+ AuDebugOn(IS_ROOT(dentry));
17271+ di_write_lock_child(dentry);
027c5e7a
AM
17272+ err = au_dbrange_test(dentry);
17273+ if (!err)
17274+ err = au_reval_for_attr(dentry, sigen);
4a4d8108
AM
17275+ di_downgrade_lock(dentry, AuLock_IR);
17276+ if (unlikely(err))
7f207e10 17277+ goto out_unlock;
4a4d8108
AM
17278+ }
17279+ } else
17280+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 17281+
4a4d8108 17282+ bindex = au_ibstart(inode);
c06a8ce3
AM
17283+ h_path.mnt = au_sbr_mnt(sb, bindex);
17284+ h_sb = h_path.mnt->mnt_sb;
4a4d8108
AM
17285+ if (!au_test_fs_bad_iattr(h_sb) && udba_none)
17286+ goto out_fill; /* success */
1facf9fc 17287+
c06a8ce3 17288+ h_path.dentry = NULL;
4a4d8108 17289+ if (au_dbstart(dentry) == bindex)
c06a8ce3 17290+ h_path.dentry = dget(au_h_dptr(dentry, bindex));
4a4d8108 17291+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c06a8ce3
AM
17292+ h_path.dentry = au_plink_lkup(inode, bindex);
17293+ if (IS_ERR(h_path.dentry))
4a4d8108
AM
17294+ goto out_fill; /* pretending success */
17295+ }
17296+ /* illegally overlapped or something */
c06a8ce3 17297+ if (unlikely(!h_path.dentry))
4a4d8108
AM
17298+ goto out_fill; /* pretending success */
17299+
c06a8ce3 17300+ positive = !!h_path.dentry->d_inode;
4a4d8108 17301+ if (positive)
c06a8ce3
AM
17302+ err = vfs_getattr(&h_path, st);
17303+ dput(h_path.dentry);
4a4d8108
AM
17304+ if (!err) {
17305+ if (positive)
c06a8ce3
AM
17306+ au_refresh_iattr(inode, st,
17307+ h_path.dentry->d_inode->i_nlink);
4a4d8108 17308+ goto out_fill; /* success */
1facf9fc 17309+ }
7f207e10
AM
17310+ AuTraceErr(err);
17311+ goto out_unlock;
4a4d8108 17312+
4f0767ce 17313+out_fill:
4a4d8108 17314+ generic_fillattr(inode, st);
7f207e10 17315+out_unlock:
4a4d8108
AM
17316+ di_read_unlock(dentry, AuLock_IR);
17317+ si_read_unlock(sb);
7f207e10
AM
17318+out:
17319+ AuTraceErr(err);
4a4d8108 17320+ return err;
1facf9fc 17321+}
17322+
17323+/* ---------------------------------------------------------------------- */
17324+
4a4d8108
AM
17325+static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
17326+ int bufsiz)
1facf9fc 17327+{
17328+ int err;
4a4d8108
AM
17329+ struct super_block *sb;
17330+ struct dentry *h_dentry;
1facf9fc 17331+
4a4d8108
AM
17332+ err = -EINVAL;
17333+ h_dentry = au_h_dptr(dentry, bindex);
17334+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
17335+ goto out;
1facf9fc 17336+
4a4d8108
AM
17337+ err = security_inode_readlink(h_dentry);
17338+ if (unlikely(err))
dece6358 17339+ goto out;
1facf9fc 17340+
4a4d8108
AM
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);
1facf9fc 17345+ }
4a4d8108 17346+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
1facf9fc 17347+
4f0767ce 17348+out:
4a4d8108
AM
17349+ return err;
17350+}
1facf9fc 17351+
4a4d8108
AM
17352+static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
17353+{
17354+ int err;
1facf9fc 17355+
027c5e7a
AM
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);
4a4d8108 17362+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 17363+
027c5e7a 17364+out:
4a4d8108
AM
17365+ return err;
17366+}
1facf9fc 17367+
4a4d8108
AM
17368+static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
17369+{
17370+ int err;
4a4d8108 17371+ mm_segment_t old_fs;
b752ccd1
AM
17372+ union {
17373+ char *k;
17374+ char __user *u;
17375+ } buf;
1facf9fc 17376+
4a4d8108 17377+ err = -ENOMEM;
537831f9 17378+ buf.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 17379+ if (unlikely(!buf.k))
4a4d8108 17380+ goto out;
1facf9fc 17381+
027c5e7a
AM
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+ }
4a4d8108 17393+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 17394+
4a4d8108 17395+ if (err >= 0) {
b752ccd1 17396+ buf.k[err] = 0;
4a4d8108 17397+ /* will be freed by put_link */
b752ccd1 17398+ nd_set_link(nd, buf.k);
4a4d8108 17399+ return NULL; /* success */
1308ab2a 17400+ }
1facf9fc 17401+
027c5e7a 17402+out_name:
537831f9 17403+ free_page((unsigned long)buf.k);
4f0767ce 17404+out:
4a4d8108
AM
17405+ AuTraceErr(err);
17406+ return ERR_PTR(err);
17407+}
1facf9fc 17408+
4a4d8108
AM
17409+static void aufs_put_link(struct dentry *dentry __maybe_unused,
17410+ struct nameidata *nd, void *cookie __maybe_unused)
17411+{
537831f9
AM
17412+ char *p;
17413+
17414+ p = nd_get_link(nd);
17415+ if (!IS_ERR_OR_NULL(p))
17416+ free_page((unsigned long)p);
4a4d8108 17417+}
1facf9fc 17418+
4a4d8108 17419+/* ---------------------------------------------------------------------- */
1facf9fc 17420+
0c3ec466 17421+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 17422+{
0c3ec466
AM
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;
4a4d8108 17440+}
1facf9fc 17441+
4a4d8108 17442+/* ---------------------------------------------------------------------- */
1308ab2a 17443+
4a4d8108
AM
17444+struct inode_operations aufs_symlink_iop = {
17445+ .permission = aufs_permission,
17446+ .setattr = aufs_setattr,
17447+ .getattr = aufs_getattr,
0c3ec466 17448+
4a4d8108
AM
17449+ .readlink = aufs_readlink,
17450+ .follow_link = aufs_follow_link,
0c3ec466
AM
17451+ .put_link = aufs_put_link,
17452+
17453+ /* .update_time = aufs_update_time */
4a4d8108
AM
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,
0c3ec466
AM
17469+ .getattr = aufs_getattr,
17470+
17471+ .update_time = aufs_update_time
b4510431 17472+ /* no support for atomic_open() */
4a4d8108
AM
17473+};
17474+
17475+struct inode_operations aufs_iop = {
17476+ .permission = aufs_permission,
17477+ .setattr = aufs_setattr,
17478+ .getattr = aufs_getattr,
0c3ec466
AM
17479+
17480+ .update_time = aufs_update_time
4a4d8108 17481+};
7f207e10
AM
17482diff -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
86dc4139 17484+++ linux/fs/aufs/i_op_del.c 2013-07-06 13:20:47.750198454 +0200
537831f9 17485@@ -0,0 +1,477 @@
1facf9fc 17486+/*
7a9e40b8 17487+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 17502+ */
17503+
17504+/*
4a4d8108 17505+ * inode operations (del entry)
1308ab2a 17506+ */
dece6358 17507+
1308ab2a 17508+#include "aufs.h"
dece6358 17509+
4a4d8108
AM
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)
1308ab2a 17521+{
4a4d8108
AM
17522+ int need_wh, err;
17523+ aufs_bindex_t bstart;
17524+ struct super_block *sb;
dece6358 17525+
4a4d8108
AM
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);
1308ab2a 17540+
4a4d8108
AM
17541+ if (*bcpup != bstart) {
17542+ err = au_cpup_dirs(dentry, *bcpup);
17543+ if (unlikely(err))
17544+ goto out;
17545+ need_wh = 1;
17546+ } else {
027c5e7a 17547+ struct au_dinfo *dinfo, *tmp;
4a4d8108 17548+
027c5e7a
AM
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 */
537831f9 17556+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
17557+ au_di_swap(tmp, dinfo);
17558+ au_rw_write_unlock(&tmp->di_rwsem);
17559+ au_di_free(tmp);
4a4d8108
AM
17560+ }
17561+ }
17562+ AuDbg("need_wh %d\n", need_wh);
17563+ err = need_wh;
17564+
4f0767ce 17565+out:
4a4d8108 17566+ return err;
1facf9fc 17567+}
17568+
4a4d8108
AM
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)
1facf9fc 17575+{
4a4d8108
AM
17576+ int err;
17577+ umode_t h_mode;
17578+ struct dentry *h_dentry, *h_latest;
1308ab2a 17579+ struct inode *h_inode;
1facf9fc 17580+
4a4d8108
AM
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;
1facf9fc 17587+
4a4d8108
AM
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+ }
1facf9fc 17603+
4a4d8108
AM
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+
4f0767ce 17627+out:
4a4d8108 17628+ return err;
1308ab2a 17629+}
1facf9fc 17630+
4a4d8108
AM
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)
1308ab2a 17640+{
4a4d8108
AM
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;
dece6358 17647+
4a4d8108
AM
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+
4f0767ce 17684+out_unpin:
4a4d8108 17685+ au_unpin(pin);
4f0767ce 17686+out:
4a4d8108 17687+ return wh_dentry;
1facf9fc 17688+}
17689+
4a4d8108
AM
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)
1facf9fc 17701+{
4a4d8108
AM
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+ }
1facf9fc 17725+
4a4d8108
AM
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+ }
dece6358 17732+
4f0767ce 17733+out:
4a4d8108
AM
17734+ AuTraceErr(err);
17735+ return err;
17736+}
1308ab2a 17737+
4a4d8108
AM
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;
1308ab2a 17746+
4a4d8108
AM
17747+ inode = dentry->d_inode;
17748+ d_drop(dentry);
17749+ inode->i_ctime = dir->i_ctime;
1308ab2a 17750+
4a4d8108
AM
17751+ if (au_ibstart(dir) == bindex)
17752+ au_cpup_attr_timesizes(dir);
17753+ dir->i_version++;
1facf9fc 17754+}
17755+
4a4d8108
AM
17756+/*
17757+ * when an error happened, remove the created whiteout and revert everything.
17758+ */
7f207e10
AM
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)
1facf9fc 17762+{
4a4d8108
AM
17763+ int rerr;
17764+ struct path h_path = {
17765+ .dentry = wh_dentry,
7f207e10 17766+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 17767+ };
dece6358 17768+
7f207e10 17769+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
17770+ if (!rerr) {
17771+ au_set_dbwh(dentry, bwh);
17772+ au_dtime_revert(dt);
17773+ return 0;
17774+ }
dece6358 17775+
4a4d8108
AM
17776+ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
17777+ AuDLNPair(dentry), err, rerr);
17778+ return -EIO;
1facf9fc 17779+}
17780+
4a4d8108 17781+/* ---------------------------------------------------------------------- */
1facf9fc 17782+
4a4d8108 17783+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 17784+{
4a4d8108
AM
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;
1facf9fc 17792+
4a4d8108 17793+ IMustLock(dir);
027c5e7a
AM
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;
4a4d8108 17801+ inode = dentry->d_inode;
4a4d8108 17802+ IMustLock(inode);
027c5e7a
AM
17803+ err = -EISDIR;
17804+ if (unlikely(S_ISDIR(inode->i_mode)))
17805+ goto out_unlock; /* possible? */
1facf9fc 17806+
4a4d8108
AM
17807+ bstart = au_dbstart(dentry);
17808+ bwh = au_dbwh(dentry);
17809+ bindex = -1;
027c5e7a
AM
17810+ parent = dentry->d_parent; /* dir inode is locked */
17811+ di_write_lock_parent(parent);
4a4d8108
AM
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))
027c5e7a 17815+ goto out_parent;
1facf9fc 17816+
4a4d8108
AM
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+ }
dece6358 17829+
4a4d8108 17830+ if (!err) {
7f207e10 17831+ vfsub_drop_nlink(inode);
4a4d8108
AM
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;
027c5e7a 17841+ goto out_unpin; /* success */
1facf9fc 17842+ }
17843+
4a4d8108
AM
17844+ /* revert */
17845+ if (wh_dentry) {
17846+ int rerr;
17847+
7f207e10 17848+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
4a4d8108
AM
17849+ if (rerr)
17850+ err = rerr;
dece6358 17851+ }
1facf9fc 17852+
027c5e7a 17853+out_unpin:
4a4d8108
AM
17854+ au_unpin(&pin);
17855+ dput(wh_dentry);
17856+ dput(h_path.dentry);
027c5e7a 17857+out_parent:
4a4d8108 17858+ di_write_unlock(parent);
027c5e7a 17859+out_unlock:
4a4d8108 17860+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 17861+out:
4a4d8108 17862+ return err;
dece6358
AM
17863+}
17864+
4a4d8108 17865+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 17866+{
4a4d8108
AM
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;
1facf9fc 17874+
4a4d8108 17875+ IMustLock(dir);
027c5e7a
AM
17876+
17877+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
17878+ if (unlikely(err))
4a4d8108 17879+ goto out;
53392da6
AM
17880+ err = au_alive_dir(dentry);
17881+ if (unlikely(err))
027c5e7a 17882+ goto out_unlock;
53392da6 17883+ inode = dentry->d_inode;
4a4d8108 17884+ IMustLock(inode);
027c5e7a
AM
17885+ err = -ENOTDIR;
17886+ if (unlikely(!S_ISDIR(inode->i_mode)))
17887+ goto out_unlock; /* possible? */
dece6358 17888+
4a4d8108
AM
17889+ err = -ENOMEM;
17890+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
17891+ if (unlikely(!args))
17892+ goto out_unlock;
dece6358 17893+
4a4d8108
AM
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))
027c5e7a 17898+ goto out_parent;
1facf9fc 17899+
4a4d8108
AM
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))
027c5e7a 17906+ goto out_parent;
1facf9fc 17907+
4a4d8108
AM
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);
1facf9fc 17923+ err = 0;
17924+ }
17925+
4a4d8108 17926+ if (!err) {
027c5e7a 17927+ vfsub_dead_dir(inode);
4a4d8108
AM
17928+ au_set_dbdiropq(dentry, -1);
17929+ epilog(dir, dentry, bindex);
1308ab2a 17930+
4a4d8108
AM
17931+ if (rmdir_later) {
17932+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
17933+ args = NULL;
17934+ }
1308ab2a 17935+
4a4d8108 17936+ goto out_unpin; /* success */
1facf9fc 17937+ }
17938+
4a4d8108
AM
17939+ /* revert */
17940+ AuLabel(revert);
17941+ if (wh_dentry) {
17942+ int rerr;
1308ab2a 17943+
7f207e10 17944+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
4a4d8108
AM
17945+ if (rerr)
17946+ err = rerr;
1facf9fc 17947+ }
17948+
4f0767ce 17949+out_unpin:
4a4d8108
AM
17950+ au_unpin(&pin);
17951+ dput(wh_dentry);
17952+ dput(h_dentry);
027c5e7a 17953+out_parent:
4a4d8108
AM
17954+ di_write_unlock(parent);
17955+ if (args)
17956+ au_whtmp_rmdir_free(args);
4f0767ce 17957+out_unlock:
4a4d8108 17958+ aufs_read_unlock(dentry, AuLock_DW);
4f0767ce 17959+out:
4a4d8108
AM
17960+ AuTraceErr(err);
17961+ return err;
dece6358 17962+}
7f207e10
AM
17963diff -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
367653fa
AM
17965+++ linux/fs/aufs/i_op_ren.c 2013-07-30 22:42:46.235946055 +0200
17966@@ -0,0 +1,1045 @@
1facf9fc 17967+/*
7a9e40b8 17968+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 17983+ */
17984+
17985+/*
4a4d8108
AM
17986+ * inode operation (rename entry)
17987+ * todo: this is crazy monster
1facf9fc 17988+ */
17989+
17990+#include "aufs.h"
17991+
4a4d8108
AM
17992+enum { AuSRC, AuDST, AuSrcDst };
17993+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 17994+
4a4d8108
AM
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)
7f207e10
AM
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)
1facf9fc 18008+
4a4d8108
AM
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];
1facf9fc 18018+
4a4d8108
AM
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
1facf9fc 18030+
4a4d8108
AM
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;
027c5e7a 18048+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 18049+
1308ab2a 18050+ unsigned int flags;
1facf9fc 18051+
4a4d8108
AM
18052+ struct au_whtmp_rmdir *thargs;
18053+ struct dentry *h_dst;
18054+};
1308ab2a 18055+
4a4d8108 18056+/* ---------------------------------------------------------------------- */
1308ab2a 18057+
4a4d8108
AM
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+ */
1facf9fc 18065+
4a4d8108
AM
18066+#define RevertFailure(fmt, ...) do { \
18067+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
18068+ ##__VA_ARGS__, err, rerr); \
18069+ err = -EIO; \
18070+} while (0)
1facf9fc 18071+
4a4d8108 18072+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 18073+{
4a4d8108 18074+ int rerr;
1facf9fc 18075+
4a4d8108
AM
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);
027c5e7a 18079+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108
AM
18080+ if (rerr)
18081+ RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry));
18082+}
1facf9fc 18083+
4a4d8108
AM
18084+static void au_ren_rev_rename(int err, struct au_ren_args *a)
18085+{
18086+ int rerr;
1facf9fc 18087+
b4510431
AM
18088+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
18089+ a->src_h_parent);
4a4d8108
AM
18090+ rerr = PTR_ERR(a->h_path.dentry);
18091+ if (IS_ERR(a->h_path.dentry)) {
b4510431 18092+ RevertFailure("lkup one %.*s", AuDLNPair(a->src_dentry));
4a4d8108 18093+ return;
1facf9fc 18094+ }
18095+
4a4d8108
AM
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));
1facf9fc 18104+}
18105+
4a4d8108 18106+static void au_ren_rev_cpup(int err, struct au_ren_args *a)
1facf9fc 18107+{
4a4d8108 18108+ int rerr;
1facf9fc 18109+
4a4d8108
AM
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));
1facf9fc 18116+}
18117+
4a4d8108 18118+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 18119+{
4a4d8108 18120+ int rerr;
dece6358 18121+
b4510431
AM
18122+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
18123+ a->dst_h_parent);
4a4d8108
AM
18124+ rerr = PTR_ERR(a->h_path.dentry);
18125+ if (IS_ERR(a->h_path.dentry)) {
b4510431 18126+ RevertFailure("lkup one %.*s", AuDLNPair(a->dst_dentry));
4a4d8108
AM
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;
dece6358
AM
18133+ }
18134+
4a4d8108
AM
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+}
1308ab2a 18143+
4a4d8108
AM
18144+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
18145+{
18146+ int rerr;
1308ab2a 18147+
4a4d8108
AM
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);
027c5e7a 18150+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108
AM
18151+ if (rerr)
18152+ RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry));
18153+}
4a4d8108 18154+#undef RevertFailure
1facf9fc 18155+
1308ab2a 18156+/* ---------------------------------------------------------------------- */
18157+
4a4d8108
AM
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)
1facf9fc 18164+{
dece6358 18165+ int err;
4a4d8108 18166+ struct dentry *d;
1facf9fc 18167+
4a4d8108
AM
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 {
86dc4139
AM
18178+#if 1
18179+ BUG();
18180+#else
4a4d8108 18181+ struct file *h_file;
1308ab2a 18182+
4a4d8108 18183+ au_fset_ren(a->flags, CPUP);
4a4d8108
AM
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);
86dc4139 18187+ if (IS_ERR(h_file))
4a4d8108 18188+ err = PTR_ERR(h_file);
86dc4139 18189+ else {
4a4d8108
AM
18190+ err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1,
18191+ !AuCpup_DTIME, a->dst_parent);
86dc4139
AM
18192+ au_h_open_post(d, a->src_bstart, h_file);
18193+ }
4a4d8108
AM
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+ }
86dc4139 18202+#endif
1308ab2a 18203+ }
027c5e7a
AM
18204+ if (!err && a->h_dst)
18205+ /* it will be set to dinfo later */
18206+ dget(a->h_dst);
1facf9fc 18207+
dece6358
AM
18208+ return err;
18209+}
1facf9fc 18210+
4a4d8108
AM
18211+/* cf. aufs_rmdir() */
18212+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 18213+{
4a4d8108
AM
18214+ int err;
18215+ struct inode *dir;
1facf9fc 18216+
4a4d8108
AM
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))
0c3ec466
AM
18224+ pr_warn("failed removing whtmp dir %.*s (%d), "
18225+ "ignored.\n", AuDLNPair(a->h_dst), err);
4a4d8108
AM
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;
1308ab2a 18236+}
1facf9fc 18237+
4a4d8108
AM
18238+/* make it 'opaque' dir. */
18239+static int au_ren_diropq(struct au_ren_args *a)
18240+{
18241+ int err;
18242+ struct dentry *diropq;
1facf9fc 18243+
4a4d8108 18244+ err = 0;
027c5e7a 18245+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
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);
1facf9fc 18253+
4a4d8108
AM
18254+ return err;
18255+}
1facf9fc 18256+
4a4d8108
AM
18257+static int do_rename(struct au_ren_args *a)
18258+{
18259+ int err;
18260+ struct dentry *d, *h_d;
1facf9fc 18261+
4a4d8108
AM
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+ }
1facf9fc 18271+
4a4d8108
AM
18272+ /* create whiteout for src_dentry */
18273+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
18274+ a->src_bwh = au_dbwh(a->src_dentry);
18275+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
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+ }
1facf9fc 18282+
4a4d8108
AM
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+ }
1facf9fc 18295+
4a4d8108
AM
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;
dece6358 18301+
4a4d8108
AM
18302+ d = a->dst_dentry;
18303+ au_set_h_dptr(d, a->btgt, NULL);
86dc4139 18304+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
4a4d8108
AM
18305+ if (unlikely(err))
18306+ goto out_whtmp;
18307+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
18308+ }
1facf9fc 18309+
4a4d8108
AM
18310+ /* cpup src */
18311+ if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) {
86dc4139
AM
18312+#if 1
18313+ BUG();
18314+#else
4a4d8108 18315+ struct file *h_file;
1facf9fc 18316+
4a4d8108 18317+ h_file = au_h_open_pre(a->src_dentry, a->src_bstart);
86dc4139 18318+ if (IS_ERR(h_file))
4a4d8108 18319+ err = PTR_ERR(h_file);
86dc4139 18320+ else {
4a4d8108
AM
18321+ err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1,
18322+ !AuCpup_DTIME);
86dc4139
AM
18323+ au_h_open_post(a->src_dentry, a->src_bstart, h_file);
18324+ }
4a4d8108
AM
18325+ if (unlikely(err))
18326+ goto out_whtmp;
86dc4139 18327+#endif
4a4d8108 18328+ }
1facf9fc 18329+
4a4d8108
AM
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;
1308ab2a 18343+
4a4d8108
AM
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+ }
1308ab2a 18350+
4a4d8108
AM
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;
1facf9fc 18356+
4a4d8108
AM
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+ }
1facf9fc 18365+
4a4d8108
AM
18366+ /* remove whtmp */
18367+ if (a->thargs)
18368+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 18369+
4a4d8108
AM
18370+ err = 0;
18371+ goto out_success;
18372+
4f0767ce 18373+out_diropq:
4a4d8108
AM
18374+ if (au_ftest_ren(a->flags, DIROPQ))
18375+ au_ren_rev_diropq(err, a);
4f0767ce 18376+out_rename:
4a4d8108
AM
18377+ if (!au_ftest_ren(a->flags, CPUP))
18378+ au_ren_rev_rename(err, a);
18379+ else
18380+ au_ren_rev_cpup(err, a);
027c5e7a 18381+ dput(a->h_dst);
4f0767ce 18382+out_whtmp:
4a4d8108
AM
18383+ if (a->thargs)
18384+ au_ren_rev_whtmp(err, a);
4f0767ce 18385+out_whdst:
4a4d8108
AM
18386+ dput(a->dst_wh_dentry);
18387+ a->dst_wh_dentry = NULL;
4f0767ce 18388+out_whsrc:
4a4d8108
AM
18389+ if (a->src_wh_dentry)
18390+ au_ren_rev_whsrc(err, a);
4f0767ce 18391+out_success:
4a4d8108
AM
18392+ dput(a->src_wh_dentry);
18393+ dput(a->dst_wh_dentry);
4f0767ce 18394+out_thargs:
4a4d8108
AM
18395+ if (a->thargs) {
18396+ dput(a->h_dst);
18397+ au_whtmp_rmdir_free(a->thargs);
18398+ a->thargs = NULL;
18399+ }
4f0767ce 18400+out:
4a4d8108 18401+ return err;
dece6358 18402+}
1facf9fc 18403+
1308ab2a 18404+/* ---------------------------------------------------------------------- */
1facf9fc 18405+
4a4d8108
AM
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)
1308ab2a 18411+{
4a4d8108 18412+ return au_test_empty(dentry, whlist);
1308ab2a 18413+}
1facf9fc 18414+
4a4d8108
AM
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;
1facf9fc 18428+
4a4d8108
AM
18429+ bstart = au_dbstart(dentry);
18430+ if (bstart != btgt) {
18431+ struct au_nhash whlist;
dece6358 18432+
4a4d8108
AM
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+ }
dece6358 18445+
4a4d8108
AM
18446+ if (bstart == au_dbtaildir(dentry))
18447+ return 0; /* success */
dece6358 18448+
4a4d8108 18449+ err = au_test_empty_lower(dentry);
1facf9fc 18450+
4f0767ce 18451+out:
4a4d8108
AM
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+}
1308ab2a 18459+
4a4d8108
AM
18460+/* side effect: sets whlist and h_dentry */
18461+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 18462+{
4a4d8108
AM
18463+ int err;
18464+ unsigned int rdhash;
18465+ struct dentry *d;
1facf9fc 18466+
4a4d8108
AM
18467+ d = a->dst_dentry;
18468+ SiMustAnyLock(d->d_sb);
1facf9fc 18469+
4a4d8108
AM
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;
1308ab2a 18478+
4a4d8108
AM
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+ }
4f0767ce 18496+out:
4a4d8108 18497+ return err;
1facf9fc 18498+}
18499+
4a4d8108 18500+/* ---------------------------------------------------------------------- */
1facf9fc 18501+
4a4d8108
AM
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;
1facf9fc 18510+
4a4d8108
AM
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+ }
1facf9fc 18520+
4a4d8108
AM
18521+ err = 0;
18522+ if (a->dst_bstart != a->btgt)
18523+ goto out;
1facf9fc 18524+
027c5e7a
AM
18525+ err = -ENOTEMPTY;
18526+ if (unlikely(a->dst_h_dentry == a->h_trap))
18527+ goto out;
18528+
4a4d8108
AM
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;
4a4d8108 18544+ }
1facf9fc 18545+
4f0767ce 18546+out:
4a4d8108
AM
18547+ if (unlikely(err == -ENOENT || err == -EEXIST))
18548+ err = -EIO;
18549+ AuTraceErr(err);
18550+ return err;
18551+}
1facf9fc 18552+
1308ab2a 18553+/* ---------------------------------------------------------------------- */
1facf9fc 18554+
4a4d8108
AM
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)
1308ab2a 18579+{
4a4d8108
AM
18580+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
18581+ a->dst_h_parent, a->dst_hdir);
86dc4139
AM
18582+ if (au_ftest_ren(a->flags, MNT_WRITE))
18583+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 18584+}
18585+
4a4d8108 18586+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 18587+{
4a4d8108
AM
18588+ int err;
18589+ unsigned int udba;
1308ab2a 18590+
4a4d8108
AM
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);
86dc4139
AM
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);
4a4d8108
AM
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);
86dc4139 18615+ if (!err)
4a4d8108 18616+ goto out; /* success */
4a4d8108
AM
18617+
18618+ err = au_busy_or_stale();
4a4d8108 18619+ au_ren_unlock(a);
86dc4139 18620+
4f0767ce 18621+out:
4a4d8108 18622+ return err;
1facf9fc 18623+}
18624+
18625+/* ---------------------------------------------------------------------- */
18626+
4a4d8108 18627+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 18628+{
4a4d8108 18629+ struct inode *dir;
dece6358 18630+
4a4d8108
AM
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);
4a4d8108 18637+ }
027c5e7a 18638+
4a4d8108
AM
18639+ if (au_ibstart(dir) == a->btgt)
18640+ au_cpup_attr_timesizes(dir);
dece6358 18641+
4a4d8108
AM
18642+ if (au_ftest_ren(a->flags, ISSAMEDIR))
18643+ return;
dece6358 18644+
4a4d8108
AM
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);
1facf9fc 18651+}
18652+
4a4d8108 18653+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 18654+{
4a4d8108
AM
18655+ aufs_bindex_t bend, bindex;
18656+ struct dentry *d, *h_d;
18657+ struct inode *i, *h_i;
18658+ struct super_block *sb;
dece6358 18659+
027c5e7a
AM
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+
4a4d8108
AM
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);
1308ab2a 18710+}
dece6358 18711+
4a4d8108
AM
18712+/* ---------------------------------------------------------------------- */
18713+
18714+/* mainly for link(2) and rename(2) */
18715+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 18716+{
4a4d8108
AM
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;
1facf9fc 18734+}
18735+
4a4d8108
AM
18736+/* sets src_bstart, dst_bstart and btgt */
18737+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 18738+{
4a4d8108
AM
18739+ int err;
18740+ struct au_wr_dir_args wr_dir_args = {
18741+ /* .force_btgt = -1, */
18742+ .flags = AuWrDir_ADD_ENTRY
18743+ };
dece6358 18744+
4a4d8108
AM
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;
dece6358 18755+
4a4d8108 18756+ return err;
1facf9fc 18757+}
18758+
4a4d8108 18759+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 18760+{
4a4d8108
AM
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+ }
1facf9fc 18767+
4a4d8108
AM
18768+ au_fclr_ren(a->flags, DT_DSTDIR);
18769+ if (!au_ftest_ren(a->flags, ISDIR))
18770+ return;
dece6358 18771+
4a4d8108
AM
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+ }
1308ab2a 18779+}
dece6358 18780+
4a4d8108 18781+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 18782+{
4a4d8108
AM
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);
1facf9fc 18803+ }
18804+ }
18805+}
18806+
4a4d8108
AM
18807+/* ---------------------------------------------------------------------- */
18808+
18809+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
18810+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 18811+{
e49829fe 18812+ int err, flags;
4a4d8108
AM
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);
1facf9fc 18837+ }
1facf9fc 18838+
4a4d8108 18839+ err = -ENOTDIR;
027c5e7a 18840+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
4a4d8108
AM
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;
e49829fe
JR
18845+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18846+ AuLock_DIR | flags);
4a4d8108 18847+ } else
e49829fe
JR
18848+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
18849+ flags);
18850+ if (unlikely(err))
18851+ goto out_free;
1facf9fc 18852+
027c5e7a
AM
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+
7eafdf33
AM
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+
4a4d8108
AM
18882+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
18883+ di_write_lock_parent(a->dst_parent);
1facf9fc 18884+
4a4d8108
AM
18885+ /* which branch we process */
18886+ err = au_ren_wbr(a);
18887+ if (unlikely(err < 0))
027c5e7a 18888+ goto out_parent;
4a4d8108 18889+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 18890+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 18891+
4a4d8108
AM
18892+ /* are they available to be renamed */
18893+ err = au_ren_may_dir(a);
18894+ if (unlikely(err))
18895+ goto out_children;
1facf9fc 18896+
4a4d8108
AM
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+ }
1facf9fc 18905+
4a4d8108
AM
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);
1facf9fc 18927+
86dc4139
AM
18928+ /* cpup src */
18929+ if (a->src_bstart != a->btgt) {
86dc4139
AM
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);
367653fa
AM
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);
86dc4139 18941+ }
86dc4139
AM
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+
4a4d8108
AM
18949+ /* lock them all */
18950+ err = au_ren_lock(a);
18951+ if (unlikely(err))
86dc4139 18952+ /* leave the copied-up one */
4a4d8108 18953+ goto out_children;
1facf9fc 18954+
4a4d8108
AM
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;
1facf9fc 18961+
4a4d8108
AM
18962+ /* store timestamps to be revertible */
18963+ au_ren_dt(a);
1facf9fc 18964+
4a4d8108
AM
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+
4f0767ce 18978+out_dt:
4a4d8108 18979+ au_ren_rev_dt(err, a);
4f0767ce 18980+out_hdir:
4a4d8108 18981+ au_ren_unlock(a);
4f0767ce 18982+out_children:
4a4d8108 18983+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
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);
4a4d8108 18988+ }
027c5e7a 18989+out_parent:
4a4d8108
AM
18990+ if (!err)
18991+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
18992+ else {
18993+ au_update_dbstart(a->dst_dentry);
18994+ if (!a->dst_inode)
18995+ d_drop(a->dst_dentry);
18996+ }
4a4d8108
AM
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);
027c5e7a 19001+out_unlock:
4a4d8108 19002+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 19003+out_free:
4a4d8108
AM
19004+ iput(a->dst_inode);
19005+ if (a->thargs)
19006+ au_whtmp_rmdir_free(a->thargs);
19007+ kfree(a);
4f0767ce 19008+out:
4a4d8108
AM
19009+ AuTraceErr(err);
19010+ return err;
1308ab2a 19011+}
7f207e10
AM
19012diff -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
86dc4139 19014+++ linux/fs/aufs/Kconfig 2013-07-06 13:20:47.736864659 +0200
c06a8ce3 19015@@ -0,0 +1,202 @@
4a4d8108
AM
19016+config AUFS_FS
19017+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
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.
1facf9fc 19026+
4a4d8108
AM
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
1facf9fc 19060+
e49829fe
JR
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+
4a4d8108
AM
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.
7f207e10 19075+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
19076+ It will have a negative impact to the performance.
19077+ See detail in aufs.5.
dece6358 19078+
4a4d8108
AM
19079+choice
19080+ prompt "method" if AUFS_HNOTIFY
19081+ default AUFS_HFSNOTIFY
19082+config AUFS_HFSNOTIFY
19083+ bool "fsnotify"
19084+ select FSNOTIFY
4a4d8108 19085+endchoice
1facf9fc 19086+
4a4d8108
AM
19087+config AUFS_EXPORT
19088+ bool "NFS-exportable aufs"
2cbb1c4b 19089+ depends on EXPORTFS
4a4d8108
AM
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.
1facf9fc 19094+
4a4d8108
AM
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 */
1facf9fc 19104+
4a4d8108
AM
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.
1facf9fc 19116+
2cbb1c4b
JR
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+
4a4d8108
AM
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.
1facf9fc 19150+
4a4d8108
AM
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.
1facf9fc 19158+
4a4d8108
AM
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.
1facf9fc 19171+
4a4d8108
AM
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).
1facf9fc 19181+
4a4d8108
AM
19182+config AUFS_POLL
19183+ bool
19184+ help
19185+ Automatic configuration for internal use.
1facf9fc 19186+
4a4d8108
AM
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.
1facf9fc 19195+
4a4d8108
AM
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.
1308ab2a 19203+
4a4d8108
AM
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
7f207e10
AM
19218diff -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
367653fa 19220+++ linux/fs/aufs/loop.c 2013-07-30 22:42:55.842946719 +0200
a2a7ad62 19221@@ -0,0 +1,135 @@
1facf9fc 19222+/*
7a9e40b8 19223+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+ */
b752ccd1 19250+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 19251+{
b752ccd1 19252+ struct super_block *h_sb;
1facf9fc 19253+ struct loop_device *l;
19254+
b752ccd1
AM
19255+ h_sb = h_adding->d_sb;
19256+ if (MAJOR(h_sb->s_dev) != LOOP_MAJOR)
1facf9fc 19257+ return 0;
19258+
b752ccd1
AM
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))
1facf9fc 19266+ return 1;
b752ccd1 19267+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 19268+}
19269+
19270+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
19271+int au_test_loopback_kthread(void)
19272+{
b752ccd1
AM
19273+ int ret;
19274+ struct task_struct *tsk = current;
a2a7ad62 19275+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
19276+
19277+ ret = 0;
19278+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
19279+ get_task_comm(comm, tsk);
19280+ c = comm[4];
b752ccd1 19281+ ret = ('0' <= c && c <= '9'
a2a7ad62 19282+ && !strncmp(comm, "loop", 4));
b752ccd1 19283+ }
1facf9fc 19284+
b752ccd1 19285+ return ret;
1facf9fc 19286+}
87a755f4
AM
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);
0c3ec466
AM
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);
87a755f4
AM
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+}
7f207e10
AM
19357diff -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
367653fa 19359+++ linux/fs/aufs/loop.h 2013-07-30 22:42:55.842946719 +0200
87a755f4 19360@@ -0,0 +1,50 @@
1facf9fc 19361+/*
7a9e40b8 19362+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
dece6358
AM
19388+struct dentry;
19389+struct super_block;
1facf9fc 19390+
19391+#ifdef CONFIG_AUFS_BDEV_LOOP
19392+/* loop.c */
b752ccd1 19393+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 19394+int au_test_loopback_kthread(void);
87a755f4
AM
19395+void au_warn_loopback(struct super_block *h_sb);
19396+
19397+int au_loopback_init(void);
19398+void au_loopback_fin(void);
1facf9fc 19399+#else
4a4d8108 19400+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 19401+ struct dentry *h_adding)
4a4d8108 19402+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
19403+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
19404+
19405+AuStubInt0(au_loopback_init, void)
19406+AuStubVoid(au_loopback_fin, void)
1facf9fc 19407+#endif /* BLK_DEV_LOOP */
19408+
19409+#endif /* __KERNEL__ */
19410+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
19411diff -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
86dc4139 19413+++ linux/fs/aufs/magic.mk 2013-07-06 13:20:47.750198454 +0200
4a4d8108 19414@@ -0,0 +1,54 @@
1facf9fc 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+
1facf9fc 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
4a4d8108
AM
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
7f207e10
AM
19469diff -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
86dc4139 19471+++ linux/fs/aufs/Makefile 2013-07-06 13:20:47.736864659 +0200
2dfbb274 19472@@ -0,0 +1,42 @@
4a4d8108
AM
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
f6c5ef8b
AM
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
4a4d8108
AM
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 \
e49829fe 19493+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
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
e49829fe 19502+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
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
4a4d8108
AM
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
7f207e10
AM
19515diff -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
86dc4139 19517+++ linux/fs/aufs/module.c 2013-07-06 13:20:47.750198454 +0200
c06a8ce3 19518@@ -0,0 +1,203 @@
1facf9fc 19519+/*
7a9e40b8 19520+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+{
4a4d8108 19564+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 19565+ if (au_cachep[AuCache_DINFO])
027c5e7a 19566+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
19567+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
19568+ au_icntnr_init_once);
1facf9fc 19569+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
19570+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
19571+ au_fi_init_once);
1facf9fc 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;
4a4d8108 19585+
537831f9
AM
19586+ /*
19587+ * Make sure all delayed rcu free inodes are flushed before we
19588+ * destroy cache.
19589+ */
19590+ rcu_barrier();
19591+
7eafdf33
AM
19592+ /* excluding AuCache_HNOTIFY */
19593+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
19594+ for (i = 0; i < AuCache_HNOTIFY; i++)
1facf9fc 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+
e49829fe 19605+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
19606+/*
19607+ * iterate_supers_type() doesn't protect us from
19608+ * remounting (branch management)
19609+ */
e49829fe
JR
19610+struct au_splhead au_sbilist;
19611+#endif
19612+
9dbd164d
AM
19613+struct lock_class_key au_lc_key[AuLcKey_Last];
19614+
1facf9fc 19615+/*
19616+ * functions for module interface.
19617+ */
19618+MODULE_LICENSE("GPL");
19619+/* MODULE_LICENSE("GPL v2"); */
dece6358 19620+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 19621+MODULE_DESCRIPTION(AUFS_NAME
19622+ " -- Advanced multi layered unification filesystem");
19623+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 19624+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 19625+
1facf9fc 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+
e49829fe 19656+ au_sbilist_init();
1facf9fc 19657+ sysaufs_brs_init();
19658+ au_debug_init();
4a4d8108 19659+ au_dy_init();
1facf9fc 19660+ err = sysaufs_init();
19661+ if (unlikely(err))
19662+ goto out;
e49829fe 19663+ err = au_procfs_init();
4f0767ce 19664+ if (unlikely(err))
953406b4 19665+ goto out_sysaufs;
e49829fe
JR
19666+ err = au_wkq_init();
19667+ if (unlikely(err))
19668+ goto out_procfs;
87a755f4 19669+ err = au_loopback_init();
1facf9fc 19670+ if (unlikely(err))
19671+ goto out_wkq;
87a755f4
AM
19672+ err = au_hnotify_init();
19673+ if (unlikely(err))
19674+ goto out_loopback;
1facf9fc 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;
4a4d8108
AM
19684+ /* since we define pr_fmt, call printk directly */
19685+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 19686+ goto out; /* success */
19687+
4f0767ce 19688+out_cache:
1facf9fc 19689+ au_cache_fin();
4f0767ce 19690+out_sysrq:
1facf9fc 19691+ au_sysrq_fin();
4f0767ce 19692+out_hin:
4a4d8108 19693+ au_hnotify_fin();
87a755f4
AM
19694+out_loopback:
19695+ au_loopback_fin();
4f0767ce 19696+out_wkq:
1facf9fc 19697+ au_wkq_fin();
e49829fe
JR
19698+out_procfs:
19699+ au_procfs_fin();
4f0767ce 19700+out_sysaufs:
1facf9fc 19701+ sysaufs_fin();
4a4d8108 19702+ au_dy_fin();
4f0767ce 19703+out:
1facf9fc 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();
4a4d8108 19712+ au_hnotify_fin();
87a755f4 19713+ au_loopback_fin();
1facf9fc 19714+ au_wkq_fin();
e49829fe 19715+ au_procfs_fin();
1facf9fc 19716+ sysaufs_fin();
4a4d8108 19717+ au_dy_fin();
1facf9fc 19718+}
19719+
19720+module_init(aufs_init);
19721+module_exit(aufs_exit);
7f207e10
AM
19722diff -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
86dc4139 19724+++ linux/fs/aufs/module.h 2013-07-06 13:20:47.750198454 +0200
7eafdf33 19725@@ -0,0 +1,105 @@
1facf9fc 19726+/*
7a9e40b8 19727+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
dece6358
AM
19755+struct path;
19756+struct seq_file;
19757+
1facf9fc 19758+/* module parameters */
1facf9fc 19759+extern int sysaufs_brs;
19760+
19761+/* ---------------------------------------------------------------------- */
19762+
19763+extern int au_dir_roflags;
19764+
9dbd164d
AM
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+
1facf9fc 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+
e49829fe
JR
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+
4f0767ce
JR
19793+/* ---------------------------------------------------------------------- */
19794+
19795+/* kmem cache */
1facf9fc 19796+enum {
19797+ AuCache_DINFO,
19798+ AuCache_ICNTNR,
19799+ AuCache_FINFO,
19800+ AuCache_VDIR,
19801+ AuCache_DEHSTR,
7eafdf33 19802+ AuCache_HNOTIFY, /* must be last */
1facf9fc 19803+ AuCache_Last
19804+};
19805+
4a4d8108
AM
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)
1facf9fc 19811+
19812+extern struct kmem_cache *au_cachep[];
19813+
19814+#define AuCacheFuncs(name, index) \
4a4d8108 19815+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 19816+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 19817+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 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);
4a4d8108
AM
19824+AuCacheFuncs(vdir_dehstr, DEHSTR);
19825+#ifdef CONFIG_AUFS_HNOTIFY
19826+AuCacheFuncs(hnotify, HNOTIFY);
19827+#endif
1facf9fc 19828+
4a4d8108
AM
19829+#endif /* __KERNEL__ */
19830+#endif /* __AUFS_MODULE_H__ */
7f207e10
AM
19831diff -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
86dc4139
AM
19833+++ linux/fs/aufs/opts.c 2013-07-06 13:20:47.753531903 +0200
19834@@ -0,0 +1,1697 @@
1facf9fc 19835+/*
7a9e40b8 19836+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 19851+ */
19852+
19853+/*
19854+ * mount options/flags
19855+ */
19856+
dece6358 19857+#include <linux/namei.h>
1facf9fc 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,
dece6358 19869+ Opt_rdblk_def, Opt_rdhash_def,
1facf9fc 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,
dece6358 19874+ Opt_shwh, Opt_noshwh,
1facf9fc 19875+ Opt_plink, Opt_noplink, Opt_list_plink,
19876+ Opt_udba,
4a4d8108 19877+ Opt_dio, Opt_nodio,
1facf9fc 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+
e49829fe 19922+#ifdef CONFIG_PROC_FS
1facf9fc 19923+ {Opt_plink, "plink"},
e49829fe
JR
19924+#else
19925+ {Opt_ignore_silent, "plink"},
19926+#endif
19927+
1facf9fc 19928+ {Opt_noplink, "noplink"},
e49829fe 19929+
1facf9fc 19930+#ifdef CONFIG_AUFS_DEBUG
19931+ {Opt_list_plink, "list_plink"},
19932+#endif
19933+
19934+ {Opt_udba, "udba=%s"},
19935+
4a4d8108
AM
19936+ {Opt_dio, "dio"},
19937+ {Opt_nodio, "nodio"},
19938+
1facf9fc 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"},
1facf9fc 19951+ {Opt_ignore_silent, "clean_plink"},
19952+
dece6358
AM
19953+#ifdef CONFIG_AUFS_SHWH
19954+ {Opt_shwh, "shwh"},
19955+#endif
19956+ {Opt_noshwh, "noshwh"},
19957+
1facf9fc 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"},
dece6358 19976+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 19977+ {Opt_rdhash, "rdhash=%d"},
dece6358 19978+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 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+
1308ab2a 19995+ /* temporary workaround, due to old mount(8)? */
19996+ {Opt_ignore_silent, "relatime"},
19997+
1facf9fc 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+
1e00d052 20016+static match_table_t brperm = {
1facf9fc 20017+ {AuBrPerm_RO, AUFS_BRPERM_RO},
20018+ {AuBrPerm_RR, AUFS_BRPERM_RR},
20019+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
20020+ {0, NULL}
20021+};
1facf9fc 20022+
86dc4139
AM
20023+static match_table_t brattr = {
20024+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
1e00d052 20025+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
1e00d052
AM
20026+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
20027+ {0, NULL}
1facf9fc 20028+};
20029+
86dc4139
AM
20030+#define AuBrStr_LONGEST AUFS_BRPERM_RW \
20031+ "+" AUFS_BRATTR_UNPIN \
20032+ "+" AUFS_BRWATTR_NLWH
1e00d052
AM
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 = '+';
0c3ec466 20050+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
20051+ break;
20052+ }
20053+ if (p)
20054+ str = p + 1;
20055+ } while (p);
20056+
20057+ return attr;
20058+}
20059+
4a4d8108 20060+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 20061+{
20062+ int val;
86dc4139 20063+ char *p, *q;
1facf9fc 20064+ substring_t args[MAX_OPT_ARGS];
20065+
1e00d052
AM
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 = '+';
0c3ec466 20073+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
20074+ val = AuBrPerm_RO;
20075+ goto out;
20076+ }
20077+ if (!p)
20078+ goto out;
20079+
86dc4139
AM
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) {
1e00d052
AM
20093+ case AuBrPerm_RO:
20094+ case AuBrPerm_RR:
86dc4139
AM
20095+ if (unlikely(val & AuBrWAttr_NoLinkWH)) {
20096+ pr_warn("ignored branch attribute %s\n",
20097+ AUFS_BRWATTR_NLWH);
20098+ val &= ~AuBrWAttr_NoLinkWH;
20099+ }
1e00d052
AM
20100+ break;
20101+ case AuBrPerm_RW:
86dc4139
AM
20102+ if (unlikely(val & AuBrRAttr_WH)) {
20103+ pr_warn("ignored branch attribute %s\n",
20104+ AUFS_BRRATTR_WH);
20105+ val &= ~AuBrRAttr_WH;
20106+ }
1e00d052
AM
20107+ break;
20108+ }
20109+
20110+out:
1facf9fc 20111+ return val;
20112+}
20113+
1e00d052
AM
20114+/* Caller should free the return value */
20115+char *au_optstr_br_perm(int brperm)
1facf9fc 20116+{
1e00d052
AM
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+
86dc4139 20149+ AppendAttr(AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN);
1e00d052
AM
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
1facf9fc 20157+}
20158+
20159+/* ---------------------------------------------------------------------- */
20160+
20161+static match_table_t udbalevel = {
20162+ {AuOpt_UDBA_REVAL, "reval"},
20163+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
20164+#ifdef CONFIG_AUFS_HNOTIFY
20165+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
20166+#ifdef CONFIG_AUFS_HFSNOTIFY
20167+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 20168+#endif
1facf9fc 20169+#endif
20170+ {-1, NULL}
20171+};
20172+
4a4d8108 20173+static int noinline_for_stack udba_val(char *str)
1facf9fc 20174+{
20175+ substring_t args[MAX_OPT_ARGS];
20176+
7f207e10 20177+ return match_token(str, udbalevel, args);
1facf9fc 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+
dece6358
AM
20205+/*
20206+ * cf. linux/lib/parser.c and cmdline.c
20207+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 20208+ * kstrto...().
dece6358 20209+ */
4a4d8108
AM
20210+static int noinline_for_stack
20211+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 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';
9dbd164d 20222+ err = kstrtoull(a, 0, result);
1facf9fc 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 {
4a4d8108 20237+ pr_err("bad integer in %s\n", str);
1facf9fc 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;
027c5e7a 20250+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 20251+ create->mfs_second = n;
20252+ else {
4a4d8108 20253+ pr_err("bad integer in %s\n", str);
1facf9fc 20254+ err = -EINVAL;
20255+ }
20256+
20257+ return err;
20258+}
20259+
4a4d8108
AM
20260+static int noinline_for_stack
20261+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 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:
027c5e7a 20285+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 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+
4a4d8108 20313+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 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;
dece6358
AM
20385+ case Opt_rdblk_def:
20386+ AuDbg("rdblk_def\n");
20387+ break;
1facf9fc 20388+ case Opt_rdhash:
20389+ AuDbg("rdhash %u\n", opt->rdhash);
20390+ break;
dece6358
AM
20391+ case Opt_rdhash_def:
20392+ AuDbg("rdhash_def\n");
20393+ break;
1facf9fc 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;
dece6358
AM
20421+ case Opt_shwh:
20422+ AuLabel(shwh);
20423+ break;
20424+ case Opt_noshwh:
20425+ AuLabel(noshwh);
20426+ break;
1facf9fc 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;
4a4d8108
AM
20440+ case Opt_dio:
20441+ AuLabel(dio);
20442+ break;
20443+ case Opt_nodio:
20444+ AuLabel(nodio);
20445+ break;
1facf9fc 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;
1e00d052 20547+ add->perm = AuBrPerm_RO;
1facf9fc 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+ }
4a4d8108 20568+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 20569+ err = -EINVAL;
20570+
4f0767ce 20571+out:
1facf9fc 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))
4a4d8108 20584+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 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) {
4a4d8108 20600+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 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+
4f0767ce 20608+out:
1facf9fc 20609+ aufs_read_unlock(root, !AuLock_IR);
20610+ return err;
20611+}
20612+#endif
20613+
4a4d8108
AM
20614+static int noinline_for_stack
20615+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 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)) {
4a4d8108 20625+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 20626+ goto out;
20627+ }
20628+
20629+ *p++ = 0;
20630+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
20631+ if (unlikely(err)) {
4a4d8108 20632+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 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+
4f0767ce 20641+out:
1facf9fc 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) {
4a4d8108 20656+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 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+
4f0767ce 20666+out:
1facf9fc 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);
4a4d8108 20686+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 20687+ goto out;
20688+ }
20689+
20690+ err = 0;
20691+ xino->file = file;
20692+ xino->path = args[0].from;
20693+
4f0767ce 20694+out:
1facf9fc 20695+ return err;
20696+}
20697+
4a4d8108
AM
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[])
1facf9fc 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)) {
4a4d8108 20710+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 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)) {
4a4d8108 20728+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 20729+ err = -EINVAL;
20730+ }
20731+
4f0767ce 20732+out:
1facf9fc 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))) {
4a4d8108 20786+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 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))) {
4a4d8108 20816+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 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))) {
4a4d8108 20833+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 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))) {
4a4d8108 20857+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20858+ break;
20859+ }
20860+ u.xino_itrunc->bindex = n;
20861+ aufs_read_lock(root, AuLock_FLUSH);
20862+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 20863+ pr_err("out of bounds, %d\n", n);
1facf9fc 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:
027c5e7a
AM
20880+ if (unlikely(match_int(&a->args[0], &n))) {
20881+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20882+ break;
027c5e7a
AM
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;
1facf9fc 20890+ err = 0;
20891+ opt->type = token;
20892+ break;
20893+ case Opt_rdblk:
20894+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 20895+ || n < 0
1facf9fc 20896+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 20897+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 20898+ break;
20899+ }
1308ab2a 20900+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
20901+ pr_err("rdblk must be larger than %d\n",
20902+ NAME_MAX);
1facf9fc 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)
1308ab2a 20911+ || n < 0
1facf9fc 20912+ || n * sizeof(struct hlist_head)
20913+ > KMALLOC_MAX_SIZE)) {
4a4d8108 20914+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 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:
dece6358
AM
20927+ case Opt_shwh:
20928+ case Opt_noshwh:
1facf9fc 20929+ case Opt_plink:
20930+ case Opt_noplink:
20931+ case Opt_list_plink:
4a4d8108
AM
20932+ case Opt_dio:
20933+ case Opt_nodio:
1facf9fc 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:
dece6358
AM
20945+ case Opt_rdblk_def:
20946+ case Opt_rdhash_def:
1facf9fc 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
4a4d8108 20957+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 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
4a4d8108 20968+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 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
4a4d8108 20976+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 20977+ break;
20978+
20979+ case Opt_ignore:
0c3ec466 20980+ pr_warn("ignored %s\n", opt_str);
1facf9fc 20981+ /*FALLTHROUGH*/
20982+ case Opt_ignore_silent:
20983+ skipped = 1;
20984+ err = 0;
20985+ break;
20986+ case Opt_err:
4a4d8108 20987+ pr_err("unknown option %s\n", opt_str);
1facf9fc 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+
4f0767ce 21007+out:
1facf9fc 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+
dece6358
AM
21017+ SiMustWriteLock(sb);
21018+
1facf9fc 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:
e49829fe
JR
21038+ sbinfo->si_wbr_mfs.mfs_expire
21039+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 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+
dece6358
AM
21060+ SiMustWriteLock(sb);
21061+
1facf9fc 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))
e49829fe 21076+ au_plink_put(sb, /*verbose*/1);
1facf9fc 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+
4a4d8108
AM
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+
1facf9fc 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:
e49829fe
JR
21145+ sbinfo->si_rdcache
21146+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 21147+ break;
21148+ case Opt_rdblk:
21149+ sbinfo->si_rdblk = opt->rdblk;
21150+ break;
dece6358
AM
21151+ case Opt_rdblk_def:
21152+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
21153+ break;
1facf9fc 21154+ case Opt_rdhash:
21155+ sbinfo->si_rdhash = opt->rdhash;
21156+ break;
dece6358
AM
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;
1facf9fc 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;
027c5e7a 21223+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 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);
027c5e7a 21234+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 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;
027c5e7a
AM
21245+ if (do_refresh)
21246+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 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+
dece6358
AM
21309+ SiMustAnyLock(sb);
21310+
1facf9fc 21311+ sbinfo = au_sbi(sb);
21312+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
21313+
dece6358
AM
21314+ if (!(sb_flags & MS_RDONLY)) {
21315+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 21316+ pr_warn("first branch should be rw\n");
dece6358 21317+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 21318+ pr_warn("shwh should be used with ro\n");
dece6358 21319+ }
1facf9fc 21320+
4a4d8108 21321+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 21322+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 21323+ pr_warn("udba=*notify requires xino\n");
1facf9fc 21324+
21325+ err = 0;
21326+ root = sb->s_root;
4a4d8108 21327+ dir = root->d_inode;
1facf9fc 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+
1e00d052 21340+ if (!au_br_writable(br->br_perm)) {
1facf9fc 21341+ do_free = !!wbr;
21342+ skip = (!wbr
21343+ || (!wbr->wbr_whbase
21344+ && !wbr->wbr_plink
21345+ && !wbr->wbr_orph));
1e00d052 21346+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 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+ }
1e00d052 21355+ } else {
1facf9fc 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+ }
1facf9fc 21364+ }
21365+ if (wbr)
21366+ wbr_wh_read_unlock(wbr);
21367+
21368+ if (skip)
21369+ continue;
21370+
21371+ hdir = au_hi(dir, bindex);
4a4d8108 21372+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 21373+ if (wbr)
21374+ wbr_wh_write_lock(wbr);
86dc4139 21375+ err = au_wh_init(br, sb);
1facf9fc 21376+ if (wbr)
21377+ wbr_wh_write_unlock(wbr);
4a4d8108 21378+ au_hn_imtx_unlock(hdir);
1facf9fc 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;
027c5e7a 21393+ aufs_bindex_t bindex, bend;
1facf9fc 21394+ struct au_opt *opt;
21395+ struct au_opt_xino *opt_xino, xino;
21396+ struct au_sbinfo *sbinfo;
027c5e7a 21397+ struct au_branch *br;
1facf9fc 21398+
dece6358
AM
21399+ SiMustWriteLock(sb);
21400+
1facf9fc 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;
4a4d8108 21428+ pr_err("no branches\n");
1facf9fc 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 */
027c5e7a 21458+ tmp &= AuOptMask_UDBA;
1facf9fc 21459+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
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+ }
4a4d8108 21470+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
1facf9fc 21471+ struct inode *dir = sb->s_root->d_inode;
4a4d8108 21472+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 21473+ }
21474+
4f0767ce 21475+out:
1facf9fc 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+
dece6358
AM
21487+ SiMustWriteLock(sb);
21488+
1facf9fc 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 */
027c5e7a 21518+ if (!au_ftest_opts(opts->flags, REFRESH)
1facf9fc 21519+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
027c5e7a 21520+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 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+}
7f207e10
AM
21532diff -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
86dc4139 21534+++ linux/fs/aufs/opts.h 2013-07-06 13:20:47.753531903 +0200
f6c5ef8b 21535@@ -0,0 +1,209 @@
1facf9fc 21536+/*
7a9e40b8 21537+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 21552+ */
21553+
21554+/*
21555+ * mount options/flags
21556+ */
21557+
21558+#ifndef __AUFS_OPTS_H__
21559+#define __AUFS_OPTS_H__
21560+
21561+#ifdef __KERNEL__
21562+
dece6358 21563+#include <linux/path.h>
1facf9fc 21564+
dece6358
AM
21565+struct file;
21566+struct super_block;
21567+
1facf9fc 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)
4a4d8108 21576+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
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 */
4a4d8108 21586+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 21587+
4a4d8108
AM
21588+#ifndef CONFIG_AUFS_HNOTIFY
21589+#undef AuOpt_UDBA_HNOTIFY
21590+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 21591+#endif
dece6358
AM
21592+#ifndef CONFIG_AUFS_SHWH
21593+#undef AuOpt_SHWH
21594+#define AuOpt_SHWH 0
21595+#endif
1facf9fc 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 \
4a4d8108 21604+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 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)
7f207e10
AM
21615+#define au_opt_clr(flags, name) do { \
21616+ ((flags) &= ~AuOpt_##name); \
21617+} while (0)
1facf9fc 21618+
e49829fe
JR
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+
1facf9fc 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
027c5e7a
AM
21707+#define AuOpts_REFRESH (1 << 1)
21708+#define AuOpts_TRUNC_XIB (1 << 2)
21709+#define AuOpts_REFRESH_DYAOP (1 << 3)
1facf9fc 21710+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
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)
1facf9fc 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+
1e00d052 21727+char *au_optstr_br_perm(int brperm);
1facf9fc 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__ */
7f207e10
AM
21745diff -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
86dc4139
AM
21747+++ linux/fs/aufs/plink.c 2013-07-06 13:20:47.753531903 +0200
21748@@ -0,0 +1,520 @@
1facf9fc 21749+/*
7a9e40b8 21750+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 21765+ */
21766+
21767+/*
21768+ * pseudo-link
21769+ */
21770+
21771+#include "aufs.h"
21772+
21773+/*
e49829fe 21774+ * the pseudo-link maintenance mode.
1facf9fc 21775+ * during a user process maintains the pseudo-links,
21776+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
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.
1facf9fc 21791+ */
e49829fe
JR
21792+
21793+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 21794+{
e49829fe
JR
21795+ int err;
21796+ pid_t pid, ppid;
21797+ struct au_sbinfo *sbi;
dece6358
AM
21798+
21799+ SiMustAnyLock(sb);
21800+
e49829fe
JR
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)) {
027c5e7a
AM
21818+ /* if there is no i_mutex lock in VFS, we don't need to wait */
21819+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
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;
4a4d8108
AM
21836+}
21837+
e49829fe 21838+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 21839+{
4a4d8108 21840+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 21841+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 21842+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 21843+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
21844+}
21845+
e49829fe 21846+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
21847+{
21848+ int err;
4a4d8108
AM
21849+ struct au_sbinfo *sbinfo;
21850+
21851+ err = 0;
4a4d8108
AM
21852+ sbinfo = au_sbi(sb);
21853+ /* make sure i am the only one in this fs */
e49829fe
JR
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+ }
4a4d8108
AM
21863+ si_write_unlock(sb);
21864+
21865+ return err;
1facf9fc 21866+}
21867+
21868+/* ---------------------------------------------------------------------- */
21869+
1facf9fc 21870+#ifdef CONFIG_AUFS_DEBUG
21871+void au_plink_list(struct super_block *sb)
21872+{
86dc4139 21873+ int i;
1facf9fc 21874+ struct au_sbinfo *sbinfo;
86dc4139 21875+ struct hlist_head *plink_hlist;
1facf9fc 21876+ struct pseudo_link *plink;
21877+
dece6358
AM
21878+ SiMustAnyLock(sb);
21879+
1facf9fc 21880+ sbinfo = au_sbi(sb);
21881+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 21882+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 21883+
86dc4139
AM
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+ }
1facf9fc 21891+}
21892+#endif
21893+
21894+/* is the inode pseudo-linked? */
21895+int au_plink_test(struct inode *inode)
21896+{
86dc4139 21897+ int found, i;
1facf9fc 21898+ struct au_sbinfo *sbinfo;
86dc4139 21899+ struct hlist_head *plink_hlist;
1facf9fc 21900+ struct pseudo_link *plink;
21901+
21902+ sbinfo = au_sbi(inode->i_sb);
dece6358 21903+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 21904+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 21905+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 21906+
21907+ found = 0;
86dc4139
AM
21908+ i = au_plink_hash(inode->i_ino);
21909+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 21910+ rcu_read_lock();
86dc4139 21911+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
1facf9fc 21912+ if (plink->inode == inode) {
21913+ found = 1;
21914+ break;
21915+ }
4a4d8108 21916+ rcu_read_unlock();
1facf9fc 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+
7f207e10
AM
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);
b4510431 21956+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
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+
1facf9fc 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;
7f207e10 21973+ int wkq_err;
1facf9fc 21974+ char a[PLINK_NAME_LEN];
0c3ec466 21975+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 21976+
e49829fe
JR
21977+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
21978+
1facf9fc 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+
2dfbb274 21984+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
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+
1facf9fc 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 = {
86dc4139 22007+ .mnt = au_br_mnt(br)
1facf9fc 22008+ };
22009+ struct inode *h_dir;
22010+
22011+ h_dir = h_parent->d_inode;
7f207e10 22012+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 22013+again:
b4510431 22014+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 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 */
7f207e10 22021+ /* todo: is it really safe? */
1facf9fc 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+
4f0767ce 22034+out:
7f207e10 22035+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 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];
0c3ec466 22061+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 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. */
2dfbb274 22069+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 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);
1facf9fc 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+{
1facf9fc 22089+ if (do_del)
86dc4139 22090+ hlist_del(&plink->hlist);
4a4d8108
AM
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);
1facf9fc 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;
86dc4139 22113+ struct hlist_head *plink_hlist;
4a4d8108 22114+ struct pseudo_link *plink, *tmp;
86dc4139
AM
22115+ struct au_sphlhead *sphl;
22116+ int found, err, cnt, i;
1facf9fc 22117+
22118+ sb = inode->i_sb;
22119+ sbinfo = au_sbi(sb);
22120+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 22121+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 22122+
86dc4139 22123+ found = au_plink_test(inode);
4a4d8108 22124+ if (found)
1facf9fc 22125+ return;
4a4d8108 22126+
86dc4139
AM
22127+ i = au_plink_hash(inode->i_ino);
22128+ sphl = sbinfo->si_plink + i;
22129+ plink_hlist = &sphl->head;
4a4d8108
AM
22130+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
22131+ if (tmp)
22132+ tmp->inode = au_igrab(inode);
22133+ else {
22134+ err = -ENOMEM;
22135+ goto out;
1facf9fc 22136+ }
22137+
86dc4139
AM
22138+ spin_lock(&sphl->spin);
22139+ hlist_for_each_entry(plink, plink_hlist, hlist) {
4a4d8108
AM
22140+ if (plink->inode == inode) {
22141+ found = 1;
22142+ break;
22143+ }
1facf9fc 22144+ }
4a4d8108 22145+ if (!found)
86dc4139
AM
22146+ hlist_add_head_rcu(&tmp->hlist, plink_hlist);
22147+ spin_unlock(&sphl->spin);
4a4d8108 22148+ if (!found) {
86dc4139
AM
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
1facf9fc 22154+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
22155+ } else {
22156+ do_put_plink(tmp, 0);
22157+ return;
1facf9fc 22158+ }
22159+
4a4d8108 22160+out:
1facf9fc 22161+ if (unlikely(err)) {
0c3ec466 22162+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108 22163+ if (tmp) {
86dc4139 22164+ au_sphl_del_rcu(&tmp->hlist, sphl);
4a4d8108
AM
22165+ call_rcu(&tmp->rcu, do_put_plink_rcu);
22166+ }
1facf9fc 22167+ }
22168+}
22169+
22170+/* free all plinks */
e49829fe 22171+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 22172+{
86dc4139 22173+ int i, warned;
1facf9fc 22174+ struct au_sbinfo *sbinfo;
86dc4139
AM
22175+ struct hlist_head *plink_hlist;
22176+ struct hlist_node *tmp;
22177+ struct pseudo_link *plink;
1facf9fc 22178+
dece6358
AM
22179+ SiMustWriteLock(sb);
22180+
1facf9fc 22181+ sbinfo = au_sbi(sb);
22182+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 22183+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 22184+
1facf9fc 22185+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
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+ }
1facf9fc 22197+}
22198+
e49829fe
JR
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+
86dc4139
AM
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+
1facf9fc 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;
86dc4139
AM
22243+ struct hlist_head *plink_hlist;
22244+ struct hlist_node *tmp;
22245+ struct pseudo_link *plink;
1facf9fc 22246+ struct inode *inode;
86dc4139 22247+ int i, do_put;
1facf9fc 22248+
dece6358
AM
22249+ SiMustWriteLock(sb);
22250+
1facf9fc 22251+ sbinfo = au_sbi(sb);
22252+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 22253+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 22254+
1facf9fc 22255+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
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);
dece6358
AM
22262+ if (do_put)
22263+ do_put_plink(plink, 1);
86dc4139
AM
22264+ ii_write_unlock(inode);
22265+ iput(inode);
dece6358 22266+ }
dece6358
AM
22267+ }
22268+}
7f207e10
AM
22269diff -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
86dc4139 22271+++ linux/fs/aufs/poll.c 2013-07-06 13:20:47.753531903 +0200
dece6358
AM
22272@@ -0,0 +1,56 @@
22273+/*
7a9e40b8 22274+ * Copyright (C) 2005-2013 Junjiro R. Okajima
dece6358
AM
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+
1308ab2a 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;
e49829fe 22310+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
1308ab2a 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;
4a4d8108 22317+ h_file = au_hf_top(file);
1308ab2a 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+
4f0767ce 22324+out:
1308ab2a 22325+ si_read_unlock(sb);
22326+ AuTraceErr((int)mask);
22327+ return mask;
22328+}
7f207e10
AM
22329diff -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
86dc4139 22331+++ linux/fs/aufs/procfs.c 2013-07-06 13:20:47.753531903 +0200
53392da6 22332@@ -0,0 +1,170 @@
e49829fe 22333+/*
7a9e40b8 22334+ * Copyright (C) 2010-2013 Junjiro R. Okajima
e49829fe
JR
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;
53392da6 22391+ /* don't use au_sbilist_lock() here */
e49829fe
JR
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+
9dbd164d 22449+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
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+}
7f207e10
AM
22503diff -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
367653fa 22505+++ linux/fs/aufs/rdu.c 2013-07-30 22:42:55.842946719 +0200
92d182d2 22506@@ -0,0 +1,384 @@
1308ab2a 22507+/*
7a9e40b8 22508+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1308ab2a 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+
b752ccd1 22529+#include <linux/compat.h>
4a4d8108 22530+#include <linux/fs_stack.h>
1308ab2a 22531+#include <linux/security.h>
1308ab2a 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)
7f207e10
AM
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)
1308ab2a 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;
4a4d8108
AM
22570+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
22571+ ent.type = DT_UNKNOWN;
1308ab2a 22572+
9dbd164d 22573+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 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+
4f0767ce 22593+out:
1308ab2a 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+
92d182d2 22604+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 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+
4f0767ce 22623+out:
1308ab2a 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
1308ab2a 22671+
22672+ arg.sb = inode->i_sb;
e49829fe
JR
22673+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
22674+ if (unlikely(err))
22675+ goto out_mtx;
027c5e7a
AM
22676+ err = au_alive_dir(dentry);
22677+ if (unlikely(err))
22678+ goto out_si;
e49829fe 22679+ /* todo: reval? */
1308ab2a 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;
4a4d8108 22696+ bend = au_fbend_dir(file);
1308ab2a 22697+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
22698+ for (; !err && cookie->bindex <= bend;
22699+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 22700+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 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+
4f0767ce 22722+out_unlock:
1308ab2a 22723+ fi_read_unlock(file);
027c5e7a 22724+out_si:
1308ab2a 22725+ si_read_unlock(arg.sb);
4f0767ce 22726+out_mtx:
1308ab2a 22727+ mutex_unlock(&inode->i_mutex);
4f0767ce 22728+out:
1308ab2a 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) {
9dbd164d 22748+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 22749+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
22750+ if (!err)
22751+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 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+{
b752ccd1 22786+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 22787+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 22788+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 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);
dece6358 22793+
b752ccd1 22794+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 22795+ return 0;
dece6358 22796+
b752ccd1
AM
22797+ AuDbg("%u:%u\n",
22798+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 22799+ return -EINVAL;
22800+}
22801+
22802+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 22803+{
1308ab2a 22804+ long err, e;
22805+ struct aufs_rdu rdu;
22806+ void __user *p = (void __user *)arg;
dece6358 22807+
1308ab2a 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);
dece6358
AM
22815+ if (unlikely(err))
22816+ goto out;
22817+
1308ab2a 22818+ switch (cmd) {
22819+ case AUFS_CTL_RDU:
22820+ err = au_rdu(file, &rdu);
22821+ if (unlikely(err))
22822+ break;
dece6358 22823+
1308ab2a 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:
4a4d8108 22835+ /* err = -ENOTTY; */
1308ab2a 22836+ err = -EINVAL;
22837+ }
dece6358 22838+
4f0767ce 22839+out:
1308ab2a 22840+ AuTraceErr(err);
22841+ return err;
1facf9fc 22842+}
b752ccd1
AM
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+
4f0767ce 22886+out:
b752ccd1
AM
22887+ AuTraceErr(err);
22888+ return err;
22889+}
22890+#endif
7f207e10
AM
22891diff -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
86dc4139 22893+++ linux/fs/aufs/rwsem.h 2013-07-06 13:20:47.753531903 +0200
f6c5ef8b 22894@@ -0,0 +1,188 @@
1facf9fc 22895+/*
7a9e40b8 22896+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
4a4d8108 22922+#include "debug.h"
dece6358
AM
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+
e49829fe 22939+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 22940+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 22941+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
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+
e49829fe
JR
22961+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
22962+
dece6358
AM
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+}
1facf9fc 23023+
dece6358
AM
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
1facf9fc 23053+
23054+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
23055+static inline void prefix##_read_lock(param) \
dece6358 23056+{ au_rw_read_lock(rwsem); } \
1facf9fc 23057+static inline void prefix##_write_lock(param) \
dece6358 23058+{ au_rw_write_lock(rwsem); } \
1facf9fc 23059+static inline int prefix##_read_trylock(param) \
dece6358 23060+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 23061+static inline int prefix##_write_trylock(param) \
dece6358 23062+{ return au_rw_write_trylock(rwsem); }
1facf9fc 23063+/* why is not _nested version defined */
23064+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 23065+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 23066+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 23067+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 23068+
23069+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
23070+static inline void prefix##_read_unlock(param) \
dece6358 23071+{ au_rw_read_unlock(rwsem); } \
1facf9fc 23072+static inline void prefix##_write_unlock(param) \
dece6358 23073+{ au_rw_write_unlock(rwsem); } \
1facf9fc 23074+static inline void prefix##_downgrade_lock(param) \
dece6358 23075+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 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__ */
7f207e10
AM
23083diff -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
86dc4139
AM
23085+++ linux/fs/aufs/sbinfo.c 2013-07-06 13:20:47.753531903 +0200
23086@@ -0,0 +1,346 @@
1facf9fc 23087+/*
7a9e40b8 23088+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+{
86dc4139 23116+ int i;
1facf9fc 23117+ struct au_sbinfo *sbinfo;
b752ccd1 23118+ char *locked __maybe_unused; /* debug only */
1facf9fc 23119+
23120+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
23121+ for (i = 0; i < AuPlink_NHASH; i++)
23122+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
e49829fe 23123+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 23124+
e49829fe 23125+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 23126+ au_br_free(sbinfo);
e49829fe 23127+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
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+
1facf9fc 23134+ kfree(sbinfo->si_branch);
b752ccd1 23135+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 23136+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 23137+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 23138+
23139+ kfree(sbinfo);
23140+}
23141+
23142+int au_si_alloc(struct super_block *sb)
23143+{
86dc4139 23144+ int err, i;
1facf9fc 23145+ struct au_sbinfo *sbinfo;
e49829fe 23146+ static struct lock_class_key aufs_si;
1facf9fc 23147+
23148+ err = -ENOMEM;
4a4d8108 23149+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 23150+ if (unlikely(!sbinfo))
23151+ goto out;
23152+
b752ccd1
AM
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+
1facf9fc 23161+ /* will be reallocated separately */
23162+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
23163+ if (unlikely(!sbinfo->si_branch))
b752ccd1 23164+ goto out_pidmap;
1facf9fc 23165+
1facf9fc 23166+ err = sysaufs_si_init(sbinfo);
23167+ if (unlikely(err))
23168+ goto out_br;
23169+
23170+ au_nwt_init(&sbinfo->si_nowait);
dece6358 23171+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 23172+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
23173+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
23174+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
23175+
7f207e10 23176+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
23177+ atomic_long_set(&sbinfo->si_nfiles, 0);
23178+
1facf9fc 23179+ sbinfo->si_bend = -1;
1facf9fc 23180+
23181+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
23182+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
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;
1facf9fc 23185+
e49829fe 23186+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 23187+
1facf9fc 23188+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 23189+ sbinfo->si_xino_brid = -1;
23190+ /* leave si_xib_last_pindex and si_xib_next_bit */
23191+
e49829fe 23192+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 23193+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
23194+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
23195+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
23196+
86dc4139
AM
23197+ for (i = 0; i < AuPlink_NHASH; i++)
23198+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 23199+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 23200+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 23201+
23202+ /* leave other members for sysaufs and si_mnt. */
23203+ sbinfo->si_sb = sb;
23204+ sb->s_fs_info = sbinfo;
b752ccd1 23205+ si_pid_set(sb);
1facf9fc 23206+ au_debug_sbinfo_init(sbinfo);
23207+ return 0; /* success */
23208+
4f0767ce 23209+out_br:
1facf9fc 23210+ kfree(sbinfo->si_branch);
4f0767ce 23211+out_pidmap:
b752ccd1 23212+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 23213+out_sbinfo:
1facf9fc 23214+ kfree(sbinfo);
4f0767ce 23215+out:
1facf9fc 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+
dece6358
AM
23224+ AuRwMustWriteLock(&sbinfo->si_rwsem);
23225+
1facf9fc 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+
dece6358
AM
23245+ SiMustWriteLock(sb);
23246+
1facf9fc 23247+ gen = ++au_sbi(sb)->si_generation;
23248+ au_update_digen(sb->s_root);
537831f9 23249+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
1facf9fc 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+
dece6358
AM
23260+ SiMustWriteLock(sb);
23261+
1facf9fc 23262+ sbinfo = au_sbi(sb);
23263+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
23264+ br_id = ++sbinfo->si_last_br_id;
7f207e10 23265+ AuDebugOn(br_id < 0);
1facf9fc 23266+ if (br_id && au_br_index(sb, br_id) < 0)
23267+ return br_id;
23268+ }
23269+
23270+ return -1;
23271+}
23272+
23273+/* ---------------------------------------------------------------------- */
23274+
e49829fe
JR
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+
1facf9fc 23307+/* dentry and super_block lock. call at entry point */
e49829fe 23308+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 23309+{
e49829fe 23310+ int err;
027c5e7a 23311+ struct super_block *sb;
e49829fe 23312+
027c5e7a
AM
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);
e49829fe
JR
23328+ }
23329+
027c5e7a 23330+out:
e49829fe 23331+ return err;
1facf9fc 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+{
e49829fe 23345+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 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+
e49829fe 23355+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 23356+{
e49829fe 23357+ int err;
027c5e7a
AM
23358+ unsigned int sigen;
23359+ struct super_block *sb;
e49829fe 23360+
027c5e7a
AM
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:
e49829fe 23381+ return err;
1facf9fc 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+}
b752ccd1
AM
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+
027c5e7a 23400+ return (long)!!p;
b752ccd1
AM
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,
027c5e7a 23415+ /*any valid ptr*/sb);
b752ccd1
AM
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);
b752ccd1 23432+}
7f207e10
AM
23433diff -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
86dc4139
AM
23435+++ linux/fs/aufs/spl.h 2013-07-06 13:20:47.753531903 +0200
23436@@ -0,0 +1,112 @@
1facf9fc 23437+/*
7a9e40b8 23438+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
1facf9fc 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+
4a4d8108
AM
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+
86dc4139
AM
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+
1facf9fc 23547+#endif /* __KERNEL__ */
23548+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
23549diff -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
86dc4139 23551+++ linux/fs/aufs/super.c 2013-07-06 13:20:47.753531903 +0200
c06a8ce3 23552@@ -0,0 +1,992 @@
1facf9fc 23553+/*
7a9e40b8 23554+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 23569+ */
23570+
23571+/*
23572+ * mount and super_block operations
23573+ */
23574+
f6c5ef8b 23575+#include <linux/mm.h>
dece6358 23576+#include <linux/module.h>
1facf9fc 23577+#include <linux/seq_file.h>
23578+#include <linux/statfs.h>
7f207e10
AM
23579+#include <linux/vmalloc.h>
23580+#include <linux/writeback.h>
1facf9fc 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) {
027c5e7a 23592+ au_icntnr_init(c);
1facf9fc 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+
027c5e7a
AM
23600+static void aufs_destroy_inode_cb(struct rcu_head *head)
23601+{
23602+ struct inode *inode = container_of(head, struct inode, i_rcu);
23603+
b4510431 23604+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
23605+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
23606+}
23607+
1facf9fc 23608+static void aufs_destroy_inode(struct inode *inode)
23609+{
23610+ au_iinfo_fin(inode);
027c5e7a 23611+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 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+
4f0767ce 23637+out:
1facf9fc 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;
4a4d8108 23650+ struct au_hdentry *hdp;
1facf9fc 23651+ struct au_branch *br;
1e00d052 23652+ char *perm;
1facf9fc 23653+
23654+ err = 0;
23655+ bend = au_sbend(sb);
4a4d8108 23656+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 23657+ for (bindex = 0; !err && bindex <= bend; bindex++) {
23658+ br = au_sbr(sb, bindex);
86dc4139 23659+ path.mnt = au_br_mnt(br);
4a4d8108 23660+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 23661+ err = au_seq_path(seq, &path);
1e00d052
AM
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+ }
1facf9fc 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+
dece6358
AM
23684+ AuRwMustAnyLock(&sbinfo->si_rwsem);
23685+
1facf9fc 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",
e49829fe
JR
23697+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23698+ / MSEC_PER_SEC);
1facf9fc 23699+ break;
23700+ case AuWbrCreate_PMFSV:
23701+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
23702+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23703+ / MSEC_PER_SEC);
1facf9fc 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,
e49829fe
JR
23712+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
23713+ / MSEC_PER_SEC);
1facf9fc 23714+ break;
23715+ }
23716+}
23717+
7eafdf33 23718+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 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;
1facf9fc 23726+ struct qstr *name;
23727+ struct file *f;
23728+ struct dentry *d, *h_root;
4a4d8108 23729+ struct au_hdentry *hdp;
1facf9fc 23730+
dece6358
AM
23731+ AuRwMustAnyLock(&sbinfo->si_rwsem);
23732+
1facf9fc 23733+ err = 0;
1facf9fc 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);
4a4d8108
AM
23743+ hdp = au_di(sb->s_root)->di_hdentry;
23744+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 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+
4f0767ce 23757+out:
1facf9fc 23758+ return err;
23759+#endif
23760+}
23761+
23762+/* seq_file will re-call me in case of too long string */
7eafdf33 23763+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 23764+{
027c5e7a 23765+ int err;
1facf9fc 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 */
7eafdf33 23788+ sb = dentry->d_sb;
1facf9fc 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)) {
7eafdf33 23795+ err = au_show_xino(m, sb);
1facf9fc 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);
dece6358 23803+ AuBool(SHWH, shwh);
1facf9fc 23804+ AuBool(PLINK, plink);
4a4d8108 23805+ AuBool(DIO, dio);
1facf9fc 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+
027c5e7a
AM
23823+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
23824+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 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+
4f0767ce 23834+out:
1facf9fc 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+
1facf9fc 23843+#undef AuBool
23844+#undef AuStr
4a4d8108 23845+#undef AuUInt
1facf9fc 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;
92d182d2
AM
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)
1facf9fc 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;
92d182d2 23877+ long bsize, factor;
1facf9fc 23878+ u64 blocks, bfree, bavail, files, ffree;
23879+ aufs_bindex_t bend, bindex, i;
23880+ unsigned char shared;
7f207e10 23881+ struct path h_path;
1facf9fc 23882+ struct super_block *h_sb;
23883+
92d182d2
AM
23884+ err = 0;
23885+ bsize = LONG_MAX;
23886+ files = 0;
23887+ ffree = 0;
1facf9fc 23888+ blocks = 0;
23889+ bfree = 0;
23890+ bavail = 0;
1facf9fc 23891+ bend = au_sbend(sb);
92d182d2 23892+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
23893+ h_path.mnt = au_sbr_mnt(sb, bindex);
23894+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 23895+ shared = 0;
92d182d2 23896+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 23897+ shared = (au_sbr_sb(sb, i) == h_sb);
23898+ if (shared)
23899+ continue;
23900+
23901+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
23902+ h_path.dentry = h_path.mnt->mnt_root;
23903+ err = vfs_statfs(&h_path, buf);
1facf9fc 23904+ if (unlikely(err))
23905+ goto out;
23906+
92d182d2
AM
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));
1facf9fc 23926+ files = au_add_till_max(files, buf->f_files);
23927+ ffree = au_add_till_max(ffree, buf->f_ffree);
23928+ }
23929+
92d182d2 23930+ buf->f_bsize = bsize;
1facf9fc 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;
92d182d2 23936+ buf->f_frsize = 0;
1facf9fc 23937+
4f0767ce 23938+out:
1facf9fc 23939+ return err;
23940+}
23941+
23942+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
23943+{
23944+ int err;
7f207e10 23945+ struct path h_path;
1facf9fc 23946+ struct super_block *sb;
23947+
23948+ /* lock free root dinfo */
23949+ sb = dentry->d_sb;
23950+ si_noflush_read_lock(sb);
7f207e10 23951+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 23952+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
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
1facf9fc 23957+ err = au_statfs_sum(sb, buf);
23958+ si_read_unlock(sb);
23959+
23960+ if (!err) {
23961+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 23962+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 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+
537831f9
AM
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+
1facf9fc 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+
1facf9fc 24011+ dbgaufs_si_fin(sbinfo);
24012+ kobject_put(&sbinfo->si_kobj);
24013+}
24014+
24015+/* ---------------------------------------------------------------------- */
24016+
7f207e10
AM
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;
2cbb1c4b 24070+ spin_lock(&inode_sb_list_lock);
7f207e10
AM
24071+ list_for_each_entry(inode, head, i_sb_list) {
24072+ if (!is_bad_inode(inode)
24073+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
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);
7f207e10
AM
24082+ }
24083+ }
2cbb1c4b 24084+ spin_unlock(&inode_sb_list_lock);
7f207e10
AM
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+
1facf9fc 24106+/*
24107+ * refresh dentry and inode at remount time.
24108+ */
027c5e7a
AM
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)
1facf9fc 24112+{
24113+ int err;
1facf9fc 24114+
24115+ di_write_lock_child(dentry);
1facf9fc 24116+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
24117+ err = au_refresh_dentry(dentry, parent);
24118+ if (!err && dir_flags)
24119+ au_hn_reset(dentry->d_inode, dir_flags);
1facf9fc 24120+ di_read_unlock(parent, AuLock_IR);
1facf9fc 24121+ di_write_unlock(dentry);
24122+
24123+ return err;
24124+}
24125+
027c5e7a
AM
24126+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
24127+ struct au_sbinfo *sbinfo,
24128+ const unsigned int dir_flags)
1facf9fc 24129+{
027c5e7a
AM
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;
1facf9fc 24155+}
24156+
027c5e7a 24157+static int au_refresh_d(struct super_block *sb)
1facf9fc 24158+{
24159+ int err, i, j, ndentry, e;
027c5e7a 24160+ unsigned int sigen;
1facf9fc 24161+ struct au_dcsub_pages dpages;
24162+ struct au_dpage *dpage;
027c5e7a
AM
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);
1facf9fc 24167+
027c5e7a
AM
24168+ err = au_dpages_init(&dpages, GFP_NOFS);
24169+ if (unlikely(err))
1facf9fc 24170+ goto out;
027c5e7a
AM
24171+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
24172+ if (unlikely(err))
1facf9fc 24173+ goto out_dpages;
1facf9fc 24174+
027c5e7a
AM
24175+ sigen = au_sigen(sb);
24176+ sbinfo = au_sbi(sb);
24177+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 24178+ dpage = dpages.dpages + i;
24179+ dentries = dpage->dentries;
24180+ ndentry = dpage->ndentry;
027c5e7a 24181+ for (j = 0; j < ndentry; j++) {
1facf9fc 24182+ d = dentries[j];
027c5e7a
AM
24183+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
24184+ if (unlikely(e && !err))
24185+ err = e;
24186+ /* go on even err */
1facf9fc 24187+ }
24188+ }
24189+
4f0767ce 24190+out_dpages:
1facf9fc 24191+ au_dpages_free(&dpages);
4f0767ce 24192+out:
1facf9fc 24193+ return err;
24194+}
24195+
027c5e7a 24196+static int au_refresh_i(struct super_block *sb)
1facf9fc 24197+{
027c5e7a
AM
24198+ int err, e;
24199+ unsigned int sigen;
24200+ unsigned long long max, ull;
24201+ struct inode *inode, **array;
1facf9fc 24202+
027c5e7a
AM
24203+ array = au_iarray_alloc(sb, &max);
24204+ err = PTR_ERR(array);
24205+ if (IS_ERR(array))
24206+ goto out;
1facf9fc 24207+
24208+ err = 0;
027c5e7a
AM
24209+ sigen = au_sigen(sb);
24210+ for (ull = 0; ull < max; ull++) {
24211+ inode = array[ull];
537831f9 24212+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 24213+ ii_write_lock_child(inode);
027c5e7a 24214+ e = au_refresh_hinode_self(inode);
1facf9fc 24215+ ii_write_unlock(inode);
24216+ if (unlikely(e)) {
027c5e7a 24217+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 24218+ if (!err)
24219+ err = e;
24220+ /* go on even if err */
24221+ }
24222+ }
1facf9fc 24223+ }
24224+
027c5e7a 24225+ au_iarray_free(array, max);
1facf9fc 24226+
4f0767ce 24227+out:
1facf9fc 24228+ return err;
24229+}
24230+
027c5e7a 24231+static void au_remount_refresh(struct super_block *sb)
1facf9fc 24232+{
027c5e7a
AM
24233+ int err, e;
24234+ unsigned int udba;
24235+ aufs_bindex_t bindex, bend;
1facf9fc 24236+ struct dentry *root;
24237+ struct inode *inode;
027c5e7a 24238+ struct au_branch *br;
1facf9fc 24239+
24240+ au_sigen_inc(sb);
027c5e7a 24241+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
1facf9fc 24242+
24243+ root = sb->s_root;
24244+ DiMustNoWaiters(root);
24245+ inode = root->d_inode;
24246+ IiMustNoWaiters(inode);
1facf9fc 24247+
027c5e7a
AM
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);
1facf9fc 24253+ if (unlikely(err))
027c5e7a
AM
24254+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
24255+ bindex, err);
24256+ /* go on even if err */
1facf9fc 24257+ }
027c5e7a 24258+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 24259+
027c5e7a
AM
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;
1facf9fc 24265+ /* aufs_write_lock() calls ..._child() */
24266+ di_write_lock_child(root);
027c5e7a
AM
24267+
24268+ au_cpup_attr_all(inode, /*force*/1);
24269+
24270+ if (unlikely(err))
24271+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 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+{
4a4d8108
AM
24291+ int err, do_dx;
24292+ unsigned int mntflags;
1facf9fc 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) {
e49829fe
JR
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+ }
1facf9fc 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);
e49829fe
JR
24327+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
24328+ if (unlikely(err))
24329+ goto out_mtx;
24330+ di_write_lock_child(root);
1facf9fc 24331+
24332+ /* au_opts_remount() may return an error */
24333+ err = au_opts_remount(sb, &opts);
24334+ au_opts_free(&opts);
24335+
027c5e7a
AM
24336+ if (au_ftest_opts(opts.flags, REFRESH))
24337+ au_remount_refresh(sb);
1facf9fc 24338+
4a4d8108
AM
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+
1facf9fc 24345+ aufs_write_unlock(root);
953406b4 24346+
e49829fe
JR
24347+out_mtx:
24348+ mutex_unlock(&inode->i_mutex);
4f0767ce 24349+out_opts:
1facf9fc 24350+ free_page((unsigned long)opts.opt);
4f0767ce 24351+out:
1facf9fc 24352+ err = cvt_err(err);
24353+ AuTraceErr(err);
24354+ return err;
24355+}
24356+
4a4d8108 24357+static const struct super_operations aufs_sop = {
1facf9fc 24358+ .alloc_inode = aufs_alloc_inode,
24359+ .destroy_inode = aufs_destroy_inode,
b752ccd1 24360+ /* always deleting, no clearing */
1facf9fc 24361+ .drop_inode = generic_delete_inode,
24362+ .show_options = aufs_show_options,
24363+ .statfs = aufs_statfs,
24364+ .put_super = aufs_put_super,
537831f9 24365+ .sync_fs = aufs_sync_fs,
1facf9fc 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;
9dbd164d 24386+ set_nlink(inode, 2);
1facf9fc 24387+ unlock_new_inode(inode);
24388+
92d182d2 24389+ root = d_make_root(inode);
1facf9fc 24390+ if (unlikely(!root))
92d182d2 24391+ goto out;
1facf9fc 24392+ err = PTR_ERR(root);
24393+ if (IS_ERR(root))
92d182d2 24394+ goto out;
1facf9fc 24395+
4a4d8108 24396+ err = au_di_init(root);
1facf9fc 24397+ if (!err) {
24398+ sb->s_root = root;
24399+ return 0; /* success */
24400+ }
24401+ dput(root);
1facf9fc 24402+
4f0767ce 24403+out:
1facf9fc 24404+ return err;
1facf9fc 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;
4a4d8108 24418+ pr_err("no arg\n");
1facf9fc 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;
027c5e7a 24437+ sb->s_d_op = &aufs_dop;
1facf9fc 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);
1facf9fc 24463+ aufs_write_lock(root);
24464+ err = au_opts_mount(sb, &opts);
24465+ au_opts_free(&opts);
1facf9fc 24466+ aufs_write_unlock(root);
24467+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
24468+ if (!err)
24469+ goto out_opts; /* success */
1facf9fc 24470+
4f0767ce 24471+out_root:
1facf9fc 24472+ dput(root);
24473+ sb->s_root = NULL;
4f0767ce 24474+out_info:
2cbb1c4b 24475+ dbgaufs_si_fin(au_sbi(sb));
1facf9fc 24476+ kobject_put(&au_sbi(sb)->si_kobj);
24477+ sb->s_fs_info = NULL;
4f0767ce 24478+out_opts:
1facf9fc 24479+ free_page((unsigned long)opts.opt);
4f0767ce 24480+out:
1facf9fc 24481+ AuTraceErr(err);
24482+ err = cvt_err(err);
24483+ AuTraceErr(err);
24484+ return err;
24485+}
24486+
24487+/* ---------------------------------------------------------------------- */
24488+
027c5e7a
AM
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)
1facf9fc 24492+{
027c5e7a 24493+ struct dentry *root;
1facf9fc 24494+ struct super_block *sb;
24495+
24496+ /* all timestamps always follow the ones on the branch */
24497+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
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;
1facf9fc 24510+}
24511+
e49829fe
JR
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);
027c5e7a 24524+ au_remount_refresh(sb);
e49829fe
JR
24525+ }
24526+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
24527+ au_plink_put(sb, /*verbose*/1);
24528+ au_xino_clr(sb);
1e00d052 24529+ sbinfo->si_sb = NULL;
e49829fe 24530+ aufs_write_unlock(sb->s_root);
e49829fe
JR
24531+ au_nwt_flush(&sbinfo->si_nowait);
24532+ }
24533+ generic_shutdown_super(sb);
24534+}
24535+
1facf9fc 24536+struct file_system_type aufs_fs_type = {
24537+ .name = AUFS_FSTYPE,
c06a8ce3
AM
24538+ /* a race between rename and others */
24539+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 24540+ .mount = aufs_mount,
e49829fe 24541+ .kill_sb = aufs_kill_sb,
1facf9fc 24542+ /* no need to __module_get() and module_put(). */
24543+ .owner = THIS_MODULE,
24544+};
7f207e10
AM
24545diff -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
86dc4139
AM
24547+++ linux/fs/aufs/super.h 2013-07-06 13:20:47.753531903 +0200
24548@@ -0,0 +1,555 @@
1facf9fc 24549+/*
7a9e40b8 24550+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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>
1facf9fc 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+
86dc4139
AM
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+
1facf9fc 24620+struct au_branch;
24621+struct au_sbinfo {
24622+ /* nowait tasks in the system-wide workqueue */
24623+ struct au_nowait_tasks si_nowait;
24624+
b752ccd1
AM
24625+ /*
24626+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
24627+ * rwsem for au_sbinfo is necessary.
24628+ */
dece6358 24629+ struct au_rwsem si_rwsem;
1facf9fc 24630+
b752ccd1
AM
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+
7f207e10
AM
24638+ /*
24639+ * dirty approach to protect sb->sb_inodes and ->s_files from remount.
24640+ */
24641+ atomic_long_t si_ninodes, si_nfiles;
24642+
1facf9fc 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;
7f207e10
AM
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;
1facf9fc 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 */
e49829fe 24691+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 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 */
86dc4139 24710+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 24711+ wait_queue_head_t si_plink_wq;
4a4d8108 24712+ spinlock_t si_plink_maint_lock;
e49829fe 24713+ pid_t si_plink_maint_pid;
1facf9fc 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
86dc4139
AM
24723+ struct dentry *si_dbgaufs;
24724+ struct dentry *si_dbgaufs_plink;
24725+ struct dentry *si_dbgaufs_xib;
1facf9fc 24726+#ifdef CONFIG_AUFS_EXPORT
24727+ struct dentry *si_dbgaufs_xigen;
24728+#endif
24729+#endif
24730+
e49829fe
JR
24731+#ifdef CONFIG_AUFS_SBILIST
24732+ struct list_head si_list;
24733+#endif
24734+
1facf9fc 24735+ /* dirty, necessary for unmounting, sysfs and sysrq */
24736+ struct super_block *si_sb;
24737+};
24738+
dece6358
AM
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+ */
027c5e7a 24745+#define AuSi_FAILED_REFRESH_DIR 1
dece6358
AM
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+
1facf9fc 24762+/* ---------------------------------------------------------------------- */
24763+
24764+/* policy to select one among writable branches */
4a4d8108
AM
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__))
1facf9fc 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 */
e49829fe
JR
24776+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
24777+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 24778+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 24779+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
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)
1facf9fc 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);
7f207e10
AM
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);
1facf9fc 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+
e49829fe
JR
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);
1facf9fc 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);
e49829fe 24811+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 24812+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
24813+
b752ccd1
AM
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+
1facf9fc 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
a2a7ad62 24833+int au_test_nfsd(void);
1facf9fc 24834+void au_export_init(struct super_block *sb);
b752ccd1 24835+void au_xigen_inc(struct inode *inode);
1facf9fc 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+{
b752ccd1 24842+ if (!au_test_nfsd())
1facf9fc 24843+ return -EBUSY;
24844+ return -ESTALE;
24845+}
24846+#else
b752ccd1 24847+AuStubInt0(au_test_nfsd, void)
a2a7ad62 24848+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 24849+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
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)
1facf9fc 24853+static inline int au_busy_or_stale(void)
24854+{
24855+ return -EBUSY;
24856+}
24857+#endif /* CONFIG_AUFS_EXPORT */
24858+
24859+/* ---------------------------------------------------------------------- */
24860+
e49829fe
JR
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+}
53392da6
AM
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 */
e49829fe
JR
24896+#else
24897+AuStubVoid(au_sbilist_init, void)
24898+AuStubVoid(au_sbilist_add, struct super_block*)
24899+AuStubVoid(au_sbilist_del, struct super_block*)
53392da6
AM
24900+AuStubVoid(au_sbilist_lock, void)
24901+AuStubVoid(au_sbilist_unlock, void)
24902+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
24903+#endif
24904+
24905+/* ---------------------------------------------------------------------- */
24906+
1facf9fc 24907+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
24908+{
dece6358
AM
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); */
1facf9fc 24914+#ifdef CONFIG_DEBUG_FS
24915+ sbinfo->si_dbgaufs = NULL;
86dc4139 24916+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 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+
b752ccd1
AM
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+
1facf9fc 24965+/* lock superblock. mainly for entry point functions */
24966+/*
b752ccd1
AM
24967+ * __si_read_lock, __si_write_lock,
24968+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 24969+ */
b752ccd1 24970+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 24971+
dece6358
AM
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+
b752ccd1
AM
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+
e49829fe 25004+#if 0 /* unused */
1facf9fc 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+}
e49829fe 25011+#endif
1facf9fc 25012+
b752ccd1
AM
25013+static inline void si_read_unlock(struct super_block *sb)
25014+{
25015+ si_pid_clr(sb);
25016+ __si_read_unlock(sb);
25017+}
25018+
b752ccd1 25019+#if 0 /* unused */
1facf9fc 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+}
b752ccd1
AM
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
1facf9fc 25040+
25041+/* ---------------------------------------------------------------------- */
25042+
25043+static inline aufs_bindex_t au_sbend(struct super_block *sb)
25044+{
dece6358 25045+ SiMustAnyLock(sb);
1facf9fc 25046+ return au_sbi(sb)->si_bend;
25047+}
25048+
25049+static inline unsigned int au_mntflags(struct super_block *sb)
25050+{
dece6358 25051+ SiMustAnyLock(sb);
1facf9fc 25052+ return au_sbi(sb)->si_mntflags;
25053+}
25054+
25055+static inline unsigned int au_sigen(struct super_block *sb)
25056+{
dece6358 25057+ SiMustAnyLock(sb);
1facf9fc 25058+ return au_sbi(sb)->si_generation;
25059+}
25060+
7f207e10
AM
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+
1facf9fc 25083+static inline struct au_branch *au_sbr(struct super_block *sb,
25084+ aufs_bindex_t bindex)
25085+{
dece6358 25086+ SiMustAnyLock(sb);
1facf9fc 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+{
dece6358 25092+ SiMustWriteLock(sb);
1facf9fc 25093+ au_sbi(sb)->si_xino_brid = brid;
25094+}
25095+
25096+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
25097+{
dece6358 25098+ SiMustAnyLock(sb);
1facf9fc 25099+ return au_sbi(sb)->si_xino_brid;
25100+}
25101+
25102+#endif /* __KERNEL__ */
25103+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
25104diff -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
86dc4139 25106+++ linux/fs/aufs/sysaufs.c 2013-07-06 13:20:47.753531903 +0200
f6c5ef8b 25107@@ -0,0 +1,105 @@
1facf9fc 25108+/*
7a9e40b8 25109+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 25124+ */
25125+
25126+/*
25127+ * sysfs interface and lifetime management
25128+ * they are necessary regardless sysfs is disabled.
25129+ */
25130+
1facf9fc 25131+#include <linux/random.h>
1facf9fc 25132+#include "aufs.h"
25133+
25134+unsigned long sysaufs_si_mask;
e49829fe 25135+struct kset *sysaufs_kset;
1facf9fc 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+
4a4d8108 25148+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 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+
e49829fe 25164+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 25165+ /* cf. sysaufs_name() */
25166+ err = kobject_init_and_add
e49829fe 25167+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 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();
e49829fe
JR
25182+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
25183+ kset_unregister(sysaufs_kset);
1facf9fc 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+
4a4d8108 25194+ err = -EINVAL;
e49829fe
JR
25195+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
25196+ if (unlikely(!sysaufs_kset))
4a4d8108 25197+ goto out;
e49829fe
JR
25198+ err = PTR_ERR(sysaufs_kset);
25199+ if (IS_ERR(sysaufs_kset))
1facf9fc 25200+ goto out;
e49829fe 25201+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 25202+ if (unlikely(err)) {
e49829fe 25203+ kset_unregister(sysaufs_kset);
1facf9fc 25204+ goto out;
25205+ }
25206+
25207+ err = dbgaufs_init();
25208+ if (unlikely(err))
25209+ sysaufs_fin();
4f0767ce 25210+out:
1facf9fc 25211+ return err;
25212+}
7f207e10
AM
25213diff -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
86dc4139 25215+++ linux/fs/aufs/sysaufs.h 2013-07-06 13:20:47.753531903 +0200
f6c5ef8b 25216@@ -0,0 +1,104 @@
1facf9fc 25217+/*
7a9e40b8 25218+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
1facf9fc 25244+#include <linux/sysfs.h>
1facf9fc 25245+#include "module.h"
25246+
dece6358
AM
25247+struct super_block;
25248+struct au_sbinfo;
25249+
1facf9fc 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;
e49829fe 25259+extern struct kset *sysaufs_kset;
1facf9fc 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+
4a4d8108 25299+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
1facf9fc 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+
4a4d8108
AM
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)
1facf9fc 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__ */
7f207e10
AM
25321diff -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
86dc4139 25323+++ linux/fs/aufs/sysfs.c 2013-07-06 13:20:47.753531903 +0200
f6c5ef8b 25324@@ -0,0 +1,257 @@
1facf9fc 25325+/*
7a9e40b8 25326+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 25341+ */
25342+
25343+/*
25344+ * sysfs interface
25345+ */
25346+
1facf9fc 25347+#include <linux/seq_file.h>
1facf9fc 25348+#include "aufs.h"
25349+
4a4d8108
AM
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+
1facf9fc 25370+static struct attribute *au_attr[] = {
4a4d8108
AM
25371+#ifdef CONFIG_AUFS_FS_MODULE
25372+ &au_config_attr.attr,
25373+#endif
1facf9fc 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+
dece6358
AM
25389+ SiMustAnyLock(sb);
25390+
1facf9fc 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+{
1e00d052 25407+ int err;
1facf9fc 25408+ struct path path;
25409+ struct dentry *root;
25410+ struct au_branch *br;
1e00d052 25411+ char *perm;
1facf9fc 25412+
25413+ AuDbg("b%d\n", bindex);
25414+
1e00d052 25415+ err = 0;
1facf9fc 25416+ root = sb->s_root;
25417+ di_read_lock_parent(root, !AuLock_IR);
25418+ br = au_sbr(sb, bindex);
86dc4139 25419+ path.mnt = au_br_mnt(br);
1facf9fc 25420+ path.dentry = au_h_dptr(root, bindex);
25421+ au_seq_path(seq, &path);
25422+ di_read_unlock(root, !AuLock_IR);
1e00d052
AM
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;
1facf9fc 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,
1308ab2a 25456+ char *buf)
1facf9fc 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;
1308ab2a 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;
1facf9fc 25483+
25484+ seq = au_seq(buf, PAGE_SIZE);
25485+ err = PTR_ERR(seq);
25486+ if (IS_ERR(seq))
1308ab2a 25487+ goto out_unlock;
1facf9fc 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;
9dbd164d 25503+ err = kstrtol(name, 10, &l);
1facf9fc 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+
4f0767ce 25514+out_seq:
1facf9fc 25515+ if (!err) {
25516+ err = seq->count;
25517+ /* sysfs limit */
25518+ if (unlikely(err == PAGE_SIZE))
25519+ err = -EFBIG;
25520+ }
25521+ kfree(seq);
4f0767ce 25522+out_unlock:
1facf9fc 25523+ si_read_unlock(sb);
4f0767ce 25524+out:
1facf9fc 25525+ return err;
25526+}
25527+
25528+/* ---------------------------------------------------------------------- */
25529+
25530+void sysaufs_br_init(struct au_branch *br)
25531+{
4a4d8108
AM
25532+ struct attribute *attr = &br->br_attr;
25533+
25534+ sysfs_attr_init(attr);
25535+ attr->name = br->br_name;
25536+ attr->mode = S_IRUGO;
1facf9fc 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))
0c3ec466
AM
25578+ pr_warn("failed %s under sysfs(%d)\n",
25579+ br->br_name, err);
1facf9fc 25580+ }
25581+}
7f207e10
AM
25582diff -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
86dc4139 25584+++ linux/fs/aufs/sysrq.c 2013-07-06 13:20:47.753531903 +0200
c06a8ce3 25585@@ -0,0 +1,151 @@
1facf9fc 25586+/*
7a9e40b8 25587+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 25602+ */
25603+
25604+/*
25605+ * magic sysrq hanlder
25606+ */
25607+
1facf9fc 25608+/* #include <linux/sysrq.h> */
027c5e7a 25609+#include <linux/writeback.h>
1facf9fc 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;
1facf9fc 25622+
4a4d8108 25623+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
25624+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
25625+
25626+ sbinfo = au_sbi(sb);
4a4d8108 25627+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 25628+ pr("superblock\n");
1facf9fc 25629+ au_dpri_sb(sb);
027c5e7a
AM
25630+
25631+#if 0
c06a8ce3 25632+ pr("root dentry\n");
1facf9fc 25633+ au_dpri_dentry(sb->s_root);
c06a8ce3 25634+ pr("root inode\n");
1facf9fc 25635+ au_dpri_inode(sb->s_root->d_inode);
027c5e7a
AM
25636+#endif
25637+
1facf9fc 25638+#if 0
027c5e7a
AM
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;
c06a8ce3 25662+ pr("isolated inode\n");
2cbb1c4b
JR
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);
b4510431 25666+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 25667+ au_dpri_inode(i);
2cbb1c4b
JR
25668+ spin_unlock(&i->i_lock);
25669+ }
25670+ spin_unlock(&inode_sb_list_lock);
027c5e7a 25671+ }
1facf9fc 25672+#endif
c06a8ce3 25673+ pr("files\n");
0c3ec466 25674+ lg_global_lock(&files_lglock);
0c5527e5 25675+ do_file_list_for_each_entry(sb, file) {
4a4d8108 25676+ umode_t mode;
c06a8ce3 25677+ mode = file_inode(file)->i_mode;
4a4d8108 25678+ if (!special_file(mode) || au_special_file(mode))
1facf9fc 25679+ au_dpri_file(file);
0c5527e5 25680+ } while_file_list_for_each_entry;
0c3ec466 25681+ lg_global_unlock(&files_lglock);
c06a8ce3 25682+ pr("done\n");
1facf9fc 25683+
c06a8ce3 25684+#undef pr
1facf9fc 25685+ au_plevel = plevel;
1facf9fc 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+
0c5527e5 25695+static void au_sysrq(int key __maybe_unused)
1facf9fc 25696+{
1facf9fc 25697+ struct au_sbinfo *sbinfo;
25698+
027c5e7a 25699+ lockdep_off();
53392da6 25700+ au_sbilist_lock();
e49829fe 25701+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 25702+ sysrq_sb(sbinfo->si_sb);
53392da6 25703+ au_sbilist_unlock();
027c5e7a 25704+ lockdep_on();
1facf9fc 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))
4a4d8108 25726+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 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))
4a4d8108 25735+ pr_err("err %d (ignored)\n", err);
1facf9fc 25736+}
7f207e10
AM
25737diff -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
367653fa 25739+++ linux/fs/aufs/vdir.c 2013-07-30 22:42:55.842946719 +0200
c06a8ce3 25740@@ -0,0 +1,878 @@
1facf9fc 25741+/*
7a9e40b8 25742+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 25757+ */
25758+
25759+/*
25760+ * virtual or vertical directory
25761+ */
25762+
25763+#include "aufs.h"
25764+
dece6358 25765+static unsigned int calc_size(int nlen)
1facf9fc 25766+{
dece6358 25767+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 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+
1308ab2a 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;
4a4d8108 25808+ /* pr_info("n %u\n", n); */
1308ab2a 25809+ return n;
25810+}
25811+
1facf9fc 25812+/*
25813+ * the allocated memory has to be freed by
dece6358 25814+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 25815+ */
dece6358 25816+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 25817+{
1facf9fc 25818+ struct hlist_head *head;
dece6358 25819+ unsigned int u;
1facf9fc 25820+
dece6358
AM
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++)
1facf9fc 25826+ INIT_HLIST_HEAD(head++);
dece6358 25827+ return 0; /* success */
1facf9fc 25828+ }
1facf9fc 25829+
dece6358 25830+ return -ENOMEM;
1facf9fc 25831+}
25832+
dece6358
AM
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++;
4a4d8108 25842+ pr_info("%lu\n", n);
dece6358
AM
25843+#endif
25844+}
25845+
25846+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 25847+{
c06a8ce3
AM
25848+ struct au_vdir_wh *pos;
25849+ struct hlist_node *node;
1facf9fc 25850+
c06a8ce3
AM
25851+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
25852+ kfree(pos);
1facf9fc 25853+}
25854+
dece6358 25855+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 25856+{
c06a8ce3
AM
25857+ struct au_vdir_dehstr *pos;
25858+ struct hlist_node *node;
1facf9fc 25859+
c06a8ce3
AM
25860+ hlist_for_each_entry_safe(pos, node, head, hash)
25861+ au_cache_free_vdir_dehstr(pos);
1facf9fc 25862+}
25863+
dece6358
AM
25864+static void au_nhash_do_free(struct au_nhash *nhash,
25865+ void (*free)(struct hlist_head *head))
1facf9fc 25866+{
1308ab2a 25867+ unsigned int n;
1facf9fc 25868+ struct hlist_head *head;
1facf9fc 25869+
dece6358 25870+ n = nhash->nh_num;
1308ab2a 25871+ if (!n)
25872+ return;
25873+
dece6358 25874+ head = nhash->nh_head;
1308ab2a 25875+ while (n-- > 0) {
dece6358
AM
25876+ nhash_count(head);
25877+ free(head++);
1facf9fc 25878+ }
dece6358 25879+ kfree(nhash->nh_head);
1facf9fc 25880+}
25881+
dece6358 25882+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 25883+{
dece6358
AM
25884+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
25885+}
1facf9fc 25886+
dece6358
AM
25887+static void au_nhash_de_free(struct au_nhash *delist)
25888+{
25889+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 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;
c06a8ce3 25900+ struct au_vdir_wh *pos;
1facf9fc 25901+
25902+ num = 0;
25903+ n = whlist->nh_num;
25904+ head = whlist->nh_head;
1308ab2a 25905+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
25906+ hlist_for_each_entry(pos, head, wh_hash)
25907+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 25908+ return 1;
1facf9fc 25909+ return 0;
25910+}
25911+
25912+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 25913+ unsigned char *name,
1facf9fc 25914+ unsigned int len)
25915+{
dece6358
AM
25916+ unsigned int v;
25917+ /* const unsigned int magic_bit = 12; */
25918+
1308ab2a 25919+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
25920+
dece6358
AM
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);
1facf9fc 25933+}
25934+
25935+/* returns found or not */
dece6358 25936+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 25937+{
25938+ struct hlist_head *head;
c06a8ce3 25939+ struct au_vdir_wh *pos;
1facf9fc 25940+ struct au_vdir_destr *str;
25941+
dece6358 25942+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
25943+ hlist_for_each_entry(pos, head, wh_hash) {
25944+ str = &pos->wh_str;
1facf9fc 25945+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
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;
c06a8ce3 25956+ struct au_vdir_dehstr *pos;
dece6358
AM
25957+ struct au_vdir_destr *str;
25958+
25959+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
25960+ hlist_for_each_entry(pos, head, hash) {
25961+ str = pos->str;
dece6358
AM
25962+ AuDbg("%.*s\n", str->len, str->name);
25963+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 25964+ return 1;
25965+ }
25966+ return 0;
25967+}
25968+
dece6358
AM
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)
1facf9fc 25983+{
25984+ int err;
25985+ struct au_vdir_destr *str;
25986+ struct au_vdir_wh *wh;
25987+
dece6358 25988+ AuDbg("%.*s\n", nlen, name);
1308ab2a 25989+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
25990+
1facf9fc 25991+ err = -ENOMEM;
dece6358 25992+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 25993+ if (unlikely(!wh))
25994+ goto out;
25995+
25996+ err = 0;
25997+ wh->wh_bindex = bindex;
dece6358
AM
25998+ if (shwh)
25999+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 26000+ str = &wh->wh_str;
dece6358
AM
26001+ str->len = nlen;
26002+ memcpy(str->name, name, nlen);
26003+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 26004+ /* smp_mb(); */
26005+
4f0767ce 26006+out:
1facf9fc 26007+ return err;
26008+}
26009+
1facf9fc 26010+static int append_deblk(struct au_vdir *vdir)
26011+{
26012+ int err;
dece6358 26013+ unsigned long ul;
1facf9fc 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;
dece6358
AM
26019+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
26020+ GFP_NOFS);
1facf9fc 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+
4f0767ce 26035+out:
1facf9fc 26036+ return err;
26037+}
26038+
dece6358
AM
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;
4a4d8108 26067+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
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+
4f0767ce 26084+out:
dece6358
AM
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+
1308ab2a 26101+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 26102+{
26103+ struct au_vdir *vdir;
1308ab2a 26104+ struct super_block *sb;
1facf9fc 26105+ int err;
26106+
1308ab2a 26107+ sb = file->f_dentry->d_sb;
dece6358
AM
26108+ SiMustAnyLock(sb);
26109+
1facf9fc 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;
1308ab2a 26120+ if (!vdir->vd_deblk_sz) {
26121+ /* estimate the apropriate size for deblk */
26122+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 26123+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 26124+ }
1facf9fc 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+
4f0767ce 26134+out_free:
1facf9fc 26135+ au_cache_free_vdir(vdir);
4f0767ce 26136+out:
1facf9fc 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+
1facf9fc 26165+#define AuFillVdir_CALLED 1
26166+#define AuFillVdir_WHABLE (1 << 1)
dece6358 26167+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 26168+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
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)
1facf9fc 26173+
dece6358
AM
26174+#ifndef CONFIG_AUFS_SHWH
26175+#undef AuFillVdir_SHWH
26176+#define AuFillVdir_SHWH 0
26177+#endif
26178+
1facf9fc 26179+struct fillvdir_arg {
26180+ struct file *file;
26181+ struct au_vdir *vdir;
dece6358
AM
26182+ struct au_nhash delist;
26183+ struct au_nhash whlist;
1facf9fc 26184+ aufs_bindex_t bindex;
26185+ unsigned int flags;
26186+ int err;
26187+};
26188+
dece6358 26189+static int fillvdir(void *__arg, const char *__name, int nlen,
1facf9fc 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;
1facf9fc 26196+ ino_t ino;
dece6358 26197+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 26198+
1facf9fc 26199+ arg->err = 0;
dece6358 26200+ sb = arg->file->f_dentry->d_sb;
1facf9fc 26201+ au_fset_fillvdir(arg->flags, CALLED);
26202+ /* smp_mb(); */
dece6358 26203+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 26204+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
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 */
1facf9fc 26208+
26209+ sb = arg->file->f_dentry->d_sb;
dece6358 26210+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
26211+ if (!arg->err) {
26212+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
26213+ d_type = DT_UNKNOWN;
dece6358
AM
26214+ arg->err = append_de(arg->vdir, name, nlen, ino,
26215+ d_type, &arg->delist);
4a4d8108 26216+ }
1facf9fc 26217+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
26218+ name += AUFS_WH_PFX_LEN;
dece6358
AM
26219+ nlen -= AUFS_WH_PFX_LEN;
26220+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
26221+ goto out; /* already whiteouted */
1facf9fc 26222+
dece6358
AM
26223+ if (shwh)
26224+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
26225+ &ino);
4a4d8108
AM
26226+ if (!arg->err) {
26227+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
26228+ d_type = DT_UNKNOWN;
1facf9fc 26229+ arg->err = au_nhash_append_wh
dece6358
AM
26230+ (&arg->whlist, name, nlen, ino, d_type,
26231+ arg->bindex, shwh);
4a4d8108 26232+ }
1facf9fc 26233+ }
26234+
4f0767ce 26235+out:
1facf9fc 26236+ if (!arg->err)
26237+ arg->vdir->vd_jiffy = jiffies;
26238+ /* smp_mb(); */
26239+ AuTraceErr(arg->err);
26240+ return arg->err;
26241+}
26242+
dece6358
AM
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;
c06a8ce3
AM
26250+ struct au_vdir_wh *pos;
26251+ struct hlist_node *n;
dece6358
AM
26252+ char *p, *o;
26253+ struct au_vdir_destr *destr;
26254+
26255+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
26256+
26257+ err = -ENOMEM;
537831f9 26258+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
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;
c06a8ce3
AM
26268+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
26269+ destr = &pos->wh_str;
dece6358
AM
26270+ memcpy(p, destr->name, destr->len);
26271+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 26272+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
26273+ if (unlikely(err))
26274+ break;
26275+ }
26276+ }
26277+
537831f9 26278+ free_page((unsigned long)o);
dece6358 26279+
4f0767ce 26280+out:
dece6358
AM
26281+ AuTraceErr(err);
26282+ return err;
26283+#else
26284+ return 0;
26285+#endif
26286+}
26287+
1facf9fc 26288+static int au_do_read_vdir(struct fillvdir_arg *arg)
26289+{
26290+ int err;
dece6358 26291+ unsigned int rdhash;
1facf9fc 26292+ loff_t offset;
dece6358
AM
26293+ aufs_bindex_t bend, bindex, bstart;
26294+ unsigned char shwh;
1facf9fc 26295+ struct file *hf, *file;
26296+ struct super_block *sb;
26297+
1facf9fc 26298+ file = arg->file;
26299+ sb = file->f_dentry->d_sb;
dece6358
AM
26300+ SiMustAnyLock(sb);
26301+
26302+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 26303+ if (!rdhash)
26304+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
26305+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
26306+ if (unlikely(err))
1facf9fc 26307+ goto out;
dece6358
AM
26308+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
26309+ if (unlikely(err))
1facf9fc 26310+ goto out_delist;
26311+
26312+ err = 0;
26313+ arg->flags = 0;
dece6358
AM
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);
4a4d8108 26320+ bend = au_fbend_dir(file);
dece6358 26321+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 26322+ hf = au_hf_dir(file, bindex);
1facf9fc 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);
dece6358
AM
26333+ if (shwh
26334+ || (bindex != bend
26335+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 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+ }
dece6358
AM
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);
1facf9fc 26351+
4f0767ce 26352+out_delist:
dece6358 26353+ au_nhash_de_free(&arg->delist);
4f0767ce 26354+out:
1facf9fc 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;
c06a8ce3 26368+ inode = file_inode(file);
1facf9fc 26369+ IMustLock(inode);
dece6358
AM
26370+ SiMustAnyLock(inode->i_sb);
26371+
1facf9fc 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;
1308ab2a 26378+ vdir = alloc_vdir(file);
1facf9fc 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+
4f0767ce 26409+out:
1facf9fc 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+
dece6358
AM
26425+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
26426+ GFP_NOFS);
1facf9fc 26427+ if (unlikely(!p))
26428+ goto out;
26429+ tgt->vd_deblk = p;
26430+ }
26431+
1308ab2a 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+ }
1facf9fc 26441+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 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++) {
dece6358
AM
26447+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
26448+ GFP_NOFS);
26449+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 26450+ goto out;
1308ab2a 26451+ tgt->vd_nblk++;
1facf9fc 26452+ }
1308ab2a 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];
1facf9fc 26458+ /* smp_mb(); */
26459+ return 0; /* success */
26460+
4f0767ce 26461+out:
1facf9fc 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) {
1308ab2a 26480+ vdir_cache = alloc_vdir(file);
1facf9fc 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+
c06a8ce3 26492+ inode = file_inode(file);
1facf9fc 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+
4f0767ce 26501+out:
1facf9fc 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+
4f0767ce 26566+out:
1facf9fc 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+}
7f207e10
AM
26619diff -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
367653fa 26621+++ linux/fs/aufs/vfsub.c 2013-07-30 22:42:55.842946719 +0200
c06a8ce3 26622@@ -0,0 +1,769 @@
1facf9fc 26623+/*
7a9e40b8 26624+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 26639+ */
26640+
26641+/*
26642+ * sub-routines for VFS
26643+ */
26644+
1308ab2a 26645+#include <linux/ima.h>
dece6358
AM
26646+#include <linux/namei.h>
26647+#include <linux/security.h>
26648+#include <linux/splice.h>
1facf9fc 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)
c06a8ce3 26666+ err = vfs_getattr(h_path, &st);
1facf9fc 26667+
26668+ return err;
26669+}
26670+
26671+/* ---------------------------------------------------------------------- */
26672+
4a4d8108 26673+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 26674+{
26675+ struct file *file;
26676+
b4510431 26677+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 26678+ current_cred());
2cbb1c4b
JR
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);
4a4d8108 26682+
1308ab2a 26683+ return file;
26684+}
26685+
1facf9fc 26686+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
26687+{
26688+ struct file *file;
26689+
2cbb1c4b 26690+ lockdep_off();
7f207e10 26691+ file = filp_open(path,
2cbb1c4b 26692+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 26693+ mode);
2cbb1c4b 26694+ lockdep_on();
1facf9fc 26695+ if (IS_ERR(file))
26696+ goto out;
26697+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
26698+
4f0767ce 26699+out:
1facf9fc 26700+ return file;
26701+}
26702+
26703+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
26704+{
26705+ int err;
26706+
1facf9fc 26707+ err = kern_path(name, flags, path);
1facf9fc 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+
1308ab2a 26720+ /* VFS checks it too, but by WARN_ON_ONCE() */
1facf9fc 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+
4f0767ce 26729+out:
4a4d8108 26730+ AuTraceErrPtr(path.dentry);
1facf9fc 26731+ return path.dentry;
26732+}
26733+
b4510431 26734+void vfsub_call_lkup_one(void *args)
2cbb1c4b 26735+{
b4510431
AM
26736+ struct vfsub_lkup_one_args *a = args;
26737+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
26738+}
26739+
1facf9fc 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+
2cbb1c4b 26747+ lockdep_off();
1facf9fc 26748+ d = lock_rename(d1, d2);
2cbb1c4b 26749+ lockdep_on();
4a4d8108 26750+ au_hn_suspend(hdir1);
1facf9fc 26751+ if (hdir1 != hdir2)
4a4d8108 26752+ au_hn_suspend(hdir2);
1facf9fc 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+{
4a4d8108 26760+ au_hn_resume(hdir1);
1facf9fc 26761+ if (hdir1 != hdir2)
4a4d8108 26762+ au_hn_resume(hdir2);
2cbb1c4b 26763+ lockdep_off();
1facf9fc 26764+ unlock_rename(d1, d2);
2cbb1c4b 26765+ lockdep_on();
1facf9fc 26766+}
26767+
26768+/* ---------------------------------------------------------------------- */
26769+
b4510431 26770+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 26771+{
26772+ int err;
26773+ struct dentry *d;
26774+
26775+ IMustLock(dir);
26776+
26777+ d = path->dentry;
26778+ path->dentry = d->d_parent;
b752ccd1 26779+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 26780+ path->dentry = d;
26781+ if (unlikely(err))
26782+ goto out;
26783+
b4510431 26784+ err = vfs_create(dir, path->dentry, mode, want_excl);
1facf9fc 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+
4f0767ce 26797+out:
1facf9fc 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;
b752ccd1 26810+ err = security_path_symlink(path, d, symname);
1facf9fc 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+
4f0767ce 26828+out:
1facf9fc 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;
027c5e7a 26841+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 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+
4f0767ce 26859+out:
1facf9fc 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+
b4510431 26884+ /* we don't call may_linkat() */
1facf9fc 26885+ d = path->dentry;
26886+ path->dentry = d->d_parent;
b752ccd1 26887+ err = security_path_link(src_dentry, path, d);
1facf9fc 26888+ path->dentry = d;
26889+ if (unlikely(err))
26890+ goto out;
26891+
2cbb1c4b 26892+ lockdep_off();
1facf9fc 26893+ err = vfs_link(src_dentry, dir, path->dentry);
2cbb1c4b 26894+ lockdep_on();
1facf9fc 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+
4f0767ce 26910+out:
1facf9fc 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;
b752ccd1 26929+ err = security_path_rename(&tmp, src_dentry, path, d);
1facf9fc 26930+ path->dentry = d;
26931+ if (unlikely(err))
26932+ goto out;
26933+
2cbb1c4b 26934+ lockdep_off();
1facf9fc 26935+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
2cbb1c4b 26936+ lockdep_on();
1facf9fc 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+
4f0767ce 26951+out:
1facf9fc 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;
b752ccd1 26964+ err = security_path_mkdir(path, d, mode);
1facf9fc 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+
4f0767ce 26982+out:
1facf9fc 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;
b752ccd1 26995+ err = security_path_rmdir(path, d);
1facf9fc 26996+ path->dentry = d;
26997+ if (unlikely(err))
26998+ goto out;
26999+
2cbb1c4b 27000+ lockdep_off();
1facf9fc 27001+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 27002+ lockdep_on();
1facf9fc 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+
4f0767ce 27012+out:
1facf9fc 27013+ return err;
27014+}
27015+
27016+/* ---------------------------------------------------------------------- */
27017+
9dbd164d 27018+/* todo: support mmap_sem? */
1facf9fc 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+
2cbb1c4b 27024+ lockdep_off();
1facf9fc 27025+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 27026+ lockdep_on();
1facf9fc 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;
b752ccd1
AM
27038+ union {
27039+ void *k;
27040+ char __user *u;
27041+ } buf;
1facf9fc 27042+
b752ccd1 27043+ buf.k = kbuf;
1facf9fc 27044+ oldfs = get_fs();
27045+ set_fs(KERNEL_DS);
b752ccd1 27046+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 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+
2cbb1c4b 27056+ lockdep_off();
1facf9fc 27057+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 27058+ lockdep_on();
1facf9fc 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;
b752ccd1
AM
27068+ union {
27069+ void *k;
27070+ const char __user *u;
27071+ } buf;
1facf9fc 27072+
b752ccd1 27073+ buf.k = kbuf;
1facf9fc 27074+ oldfs = get_fs();
27075+ set_fs(KERNEL_DS);
b752ccd1 27076+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 27077+ set_fs(oldfs);
27078+ return err;
27079+}
27080+
4a4d8108
AM
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) {
2cbb1c4b
JR
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+ }
4a4d8108
AM
27094+ if (!err)
27095+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
27096+ /*ignore*/
27097+ }
27098+ return err;
27099+}
27100+
1facf9fc 27101+int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
27102+{
27103+ int err;
27104+
2cbb1c4b 27105+ lockdep_off();
1facf9fc 27106+ err = vfs_readdir(file, filldir, arg);
2cbb1c4b 27107+ lockdep_on();
1facf9fc 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+
2cbb1c4b 27119+ lockdep_off();
0fc653ad 27120+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 27121+ lockdep_on();
4a4d8108 27122+ file_accessed(in);
1facf9fc 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+
2cbb1c4b 27133+ lockdep_off();
0fc653ad 27134+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 27135+ lockdep_on();
1facf9fc 27136+ if (err >= 0)
27137+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
27138+ return err;
27139+}
27140+
53392da6
AM
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+
1facf9fc 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;
c06a8ce3 27165+ struct super_block *h_sb;
1facf9fc 27166+
1facf9fc 27167+ if (!h_file) {
c06a8ce3
AM
27168+ err = vfsub_truncate(h_path, length);
27169+ goto out;
1facf9fc 27170+ }
27171+
c06a8ce3
AM
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();
1facf9fc 27177+ err = locks_verify_truncate(h_inode, h_file, length);
27178+ if (!err)
953406b4 27179+ err = security_path_truncate(h_path);
2cbb1c4b
JR
27180+ if (!err) {
27181+ lockdep_off();
1facf9fc 27182+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
27183+ lockdep_on();
27184+ }
c06a8ce3
AM
27185+ lockdep_off();
27186+ sb_end_write(h_sb);
27187+ lockdep_on();
1facf9fc 27188+
4f0767ce 27189+out:
1facf9fc 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)) {
1facf9fc 27281+ *a->errp = notify_change(a->path->dentry, a->ia);
1facf9fc 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)
027c5e7a 27332+ && d->d_count == 1);
1facf9fc 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)
027c5e7a 27346+ ihold(h_inode);
1facf9fc 27347+
2cbb1c4b 27348+ lockdep_off();
1facf9fc 27349+ *a->errp = vfs_unlink(a->dir, d);
2cbb1c4b 27350+ lockdep_on();
1facf9fc 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+}
7f207e10
AM
27392diff -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
367653fa 27394+++ linux/fs/aufs/vfsub.h 2013-07-30 22:42:55.842946719 +0200
86dc4139 27395@@ -0,0 +1,294 @@
1facf9fc 27396+/*
7a9e40b8 27397+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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>
0c5527e5 27424+#include <linux/lglock.h>
b4510431 27425+#include <linux/mount.h>
7f207e10 27426+#include "debug.h"
1facf9fc 27427+
7f207e10 27428+/* copied from linux/fs/internal.h */
2cbb1c4b 27429+/* todo: BAD approach!! */
0c3ec466 27430+extern struct lglock vfsmount_lock;
c06a8ce3 27431+extern void __mnt_drop_write(struct vfsmount *);
2cbb1c4b 27432+extern spinlock_t inode_sb_list_lock;
0c5527e5 27433+
7f207e10 27434+/* copied from linux/fs/file_table.c */
0c3ec466 27435+extern struct lglock files_lglock;
0c5527e5
AM
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+}
7f207e10
AM
27463+#endif
27464+
27465+/* ---------------------------------------------------------------------- */
1facf9fc 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 */
dece6358 27474+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 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+
7f207e10
AM
27486+static inline void vfsub_drop_nlink(struct inode *inode)
27487+{
27488+ AuDebugOn(!inode->i_nlink);
27489+ drop_nlink(inode);
27490+}
27491+
027c5e7a
AM
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+
7f207e10
AM
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);
1facf9fc 27504+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 27505+
1facf9fc 27506+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
27507+ int len);
b4510431
AM
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+}
1facf9fc 27540+
c06a8ce3
AM
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+
1facf9fc 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+
537831f9
AM
27556+int vfsub_create(struct inode *dir, struct path *path, int mode,
27557+ bool want_excl);
1facf9fc 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);
4a4d8108 27578+int vfsub_flush(struct file *file, fl_owner_t id);
1facf9fc 27579+int vfsub_readdir(struct file *file, filldir_t filldir, void *arg);
27580+
c06a8ce3
AM
27581+static inline loff_t vfsub_f_size_read(struct file *file)
27582+{
27583+ return i_size_read(file_inode(file));
27584+}
27585+
4a4d8108
AM
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+}
1308ab2a 27596+
1facf9fc 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+ };
92d182d2 27610+ touch_atime(&h_path);
1facf9fc 27611+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
27612+}
27613+
0c3ec466
AM
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+
4a4d8108
AM
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);
c06a8ce3
AM
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+
4a4d8108
AM
27636+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
27637+ struct file *h_file);
53392da6 27638+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 27639+
1facf9fc 27640+/* ---------------------------------------------------------------------- */
27641+
27642+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
27643+{
27644+ loff_t err;
27645+
2cbb1c4b 27646+ lockdep_off();
1facf9fc 27647+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 27648+ lockdep_on();
1facf9fc 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+
4a4d8108
AM
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+
1facf9fc 27688+#endif /* __KERNEL__ */
27689+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
27690diff -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
86dc4139
AM
27692+++ linux/fs/aufs/wbr_policy.c 2013-07-06 13:20:47.753531903 +0200
27693@@ -0,0 +1,701 @@
1facf9fc 27694+/*
7a9e40b8 27695+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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));
86dc4139 27733+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
1facf9fc 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)
7f207e10
AM
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)
1facf9fc 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+
4f0767ce 27774+out:
1facf9fc 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) {
86dc4139 27793+ h_path.mnt = au_br_mnt(br);
1facf9fc 27794+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
27795+ dentry);
27796+ }
27797+ dput(h_path.dentry);
27798+
4f0767ce 27799+out:
1facf9fc 27800+ return err;
27801+}
27802+
27803+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 27804+ struct au_pin *pin,
1facf9fc 27805+ struct dentry *h_parent, void *arg)
27806+{
27807+ int err, rerr;
4a4d8108 27808+ aufs_bindex_t bopq, bstart;
1facf9fc 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+
86dc4139 27822+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 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+
1facf9fc 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);
1facf9fc 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 */
4f0767ce 27869+out_opq:
1facf9fc 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+ }
4f0767ce 27881+out_dir:
1facf9fc 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+ }
4f0767ce 27890+out_put:
1facf9fc 27891+ au_set_h_dptr(dentry, bdst, NULL);
27892+ if (au_dbend(dentry) == bdst)
27893+ au_update_dbend(dentry);
4f0767ce 27894+out:
1facf9fc 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+
4a4d8108
AM
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);
027c5e7a 27929+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
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+
1facf9fc 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 */
4a4d8108 27992+ if (unlikely(err < 0)) {
1facf9fc 27993+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
27994+ if (err >= 0)
27995+ err = au_wbr_nonopq(dentry, err);
27996+ }
1facf9fc 27997+
4f0767ce 27998+out:
1facf9fc 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+
4a4d8108
AM
28028+ if (err >= 0)
28029+ err = au_wbr_nonopq(dentry, err);
28030+
1facf9fc 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 */
dece6358 28047+ /* smp_mb(); */
1facf9fc 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+
4a4d8108
AM
28086+ if (err >= 0)
28087+ err = au_wbr_nonopq(dentry, err);
28088+
4f0767ce 28089+out:
1facf9fc 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;
7f207e10 28105+ struct path h_path;
1facf9fc 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;
dece6358 28118+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 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 */
86dc4139 28128+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
28129+ h_path.dentry = h_path.mnt->mnt_root;
28130+ err = vfs_statfs(&h_path, st);
1facf9fc 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+
4a4d8108
AM
28173+ if (err >= 0)
28174+ err = au_wbr_nonopq(dentry, err);
28175+
4f0767ce 28176+out:
1facf9fc 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;
dece6358 28210+ mutex_lock(&mfs->mfs_lock);
1facf9fc 28211+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
28212+ err = au_wbr_create_rr(dentry, isdir);
dece6358 28213+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 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+
4a4d8108
AM
28274+ if (err >= 0)
28275+ err = au_wbr_nonopq(dentry, err);
28276+
4f0767ce 28277+out_parent:
1facf9fc 28278+ dput(parent);
4f0767ce 28279+out:
1facf9fc 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;
4a4d8108 28330+ aufs_bindex_t bstart;
1facf9fc 28331+
4a4d8108
AM
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);
1facf9fc 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+};
7f207e10
AM
28395diff -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
86dc4139
AM
28397+++ linux/fs/aufs/whout.c 2013-07-06 13:20:47.760198800 +0200
28398@@ -0,0 +1,1022 @@
1facf9fc 28399+/*
7a9e40b8 28400+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 28415+ */
28416+
28417+/*
28418+ * whiteout for logical deletion and opaque directory
28419+ */
28420+
1facf9fc 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+ */
0c3ec466
AM
28429+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
28430+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 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;
1facf9fc 28470+
1facf9fc 28471+ if (!try_sio)
b4510431 28472+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 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+
4f0767ce 28491+out_wh:
1facf9fc 28492+ dput(wh_dentry);
4f0767ce 28493+out:
1facf9fc 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+{
1facf9fc 28517+ struct dentry *dentry;
28518+ int i;
027c5e7a 28519+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 28520+ *name, *p;
027c5e7a 28521+ /* strict atomic_t is unnecessary here */
1facf9fc 28522+ static unsigned short cnt;
28523+ struct qstr qs;
28524+
4a4d8108
AM
28525+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
28526+
1facf9fc 28527+ name = defname;
027c5e7a
AM
28528+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
28529+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 28530+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 28531+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 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++ = '.';
4a4d8108 28545+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 28546+
28547+ qs.name = name;
28548+ for (i = 0; i < 3; i++) {
b752ccd1 28549+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
1facf9fc 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+ }
0c3ec466 28555+ /* pr_warn("could not get random name\n"); */
1facf9fc 28556+ dentry = ERR_PTR(-EEXIST);
28557+ AuDbg("%.*s\n", AuLNPair(&qs));
28558+ BUG();
28559+
4f0767ce 28560+out_name:
1facf9fc 28561+ if (name != defname)
28562+ kfree(name);
4f0767ce 28563+out:
4a4d8108 28564+ AuTraceErrPtr(dentry);
1facf9fc 28565+ return dentry;
1facf9fc 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 = {
86dc4139 28575+ .mnt = au_br_mnt(br)
1facf9fc 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+
4f0767ce 28594+out:
4a4d8108 28595+ AuTraceErr(err);
1facf9fc 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)
0c3ec466 28613+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
1facf9fc 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 = {
86dc4139 28634+ .mnt = au_br_mnt(br)
1facf9fc 28635+ };
28636+
28637+ err = 0;
b4510431 28638+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 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+
86dc4139
AM
28664+ if (isdir)
28665+ err = vfsub_rmdir(h_dir, whpath);
28666+ else
28667+ err = vfsub_unlink(h_dir, whpath, /*force*/0);
1facf9fc 28668+ if (unlikely(err))
0c3ec466
AM
28669+ pr_warn("failed removing %.*s (%d), ignored.\n",
28670+ AuDLNPair(whpath->dentry), err);
1facf9fc 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+
4a4d8108
AM
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));
1facf9fc 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;
86dc4139 28696+ err = vfsub_mkdir(h_dir, path, mode);
1facf9fc 28697+ } else if (S_ISDIR(path->dentry->d_inode->i_mode))
28698+ err = 0;
28699+ else
4a4d8108 28700+ pr_err("unknown %.*s exists\n", AuDLNPair(path->dentry));
1facf9fc 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+
4f0767ce 28757+out:
1facf9fc 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+
1308ab2a 28776+ WbrWhMustWriteLock(wbr);
28777+
1facf9fc 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) {
86dc4139
AM
28790+ h_path->dentry = base[AuBrWh_BASE].dentry;
28791+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
1facf9fc 28792+ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
28793+ err = 0;
28794+ else
4a4d8108
AM
28795+ pr_err("unknown %.*s/%.*s exists\n",
28796+ AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry));
1facf9fc 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+
4f0767ce 28816+out:
1facf9fc 28817+ return err;
28818+}
28819+
28820+/*
28821+ * initialize the whiteout base file/dir for @br.
28822+ */
86dc4139 28823+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 28824+{
28825+ int err, i;
28826+ const unsigned char do_plink
28827+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 28828+ struct inode *h_dir;
86dc4139
AM
28829+ struct path path = br->br_path;
28830+ struct dentry *h_root = path.dentry;
1facf9fc 28831+ struct au_wbr *wbr = br->br_wbr;
28832+ static const struct qstr base_name[] = {
0c3ec466
AM
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)
1facf9fc 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+
1308ab2a 28855+ if (wbr)
28856+ WbrWhMustWriteLock(wbr);
1facf9fc 28857+
1facf9fc 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;
1e00d052 28880+ if (!au_br_writable(br->br_perm)) {
4a4d8108 28881+ h_dir = h_root->d_inode;
1facf9fc 28882+ au_wh_init_ro(h_dir, base, &path);
1e00d052 28883+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 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;
1e00d052 28889+ } else {
1facf9fc 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;
1facf9fc 28895+ }
28896+ goto out; /* success */
28897+
4f0767ce 28898+out_err:
4a4d8108
AM
28899+ pr_err("an error(%d) on the writable branch %.*s(%s)\n",
28900+ err, AuDLNPair(h_root), au_sbtype(h_root->d_sb));
4f0767ce 28901+out:
1facf9fc 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+
1308ab2a 28940+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
1facf9fc 28941+ dir = a->sb->s_root->d_inode;
1facf9fc 28942+ hdir = au_hi(dir, bindex);
28943+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 28944+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 28945+
4a4d8108 28946+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 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) {
86dc4139
AM
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);
1facf9fc 28954+ } else {
0c3ec466
AM
28955+ pr_warn("%.*s is moved, ignored\n",
28956+ AuDLNPair(wbr->wbr_whbase));
1facf9fc 28957+ err = 0;
28958+ }
28959+ dput(wbr->wbr_whbase);
28960+ wbr->wbr_whbase = NULL;
28961+ if (!err)
86dc4139 28962+ err = au_wh_init(a->br, a->sb);
1facf9fc 28963+ wbr_wh_write_unlock(wbr);
4a4d8108 28964+ au_hn_imtx_unlock(hdir);
1308ab2a 28965+ di_read_unlock(a->sb->s_root, AuLock_IR);
1facf9fc 28966+
4f0767ce 28967+out:
1facf9fc 28968+ if (wbr)
28969+ atomic_dec(&wbr->wbr_wh_running);
28970+ atomic_dec(&a->br->br_count);
1facf9fc 28971+ si_write_unlock(a->sb);
027c5e7a 28972+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 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);
53392da6 28997+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 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+
4f0767ce 29006+out:
1facf9fc 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);
86dc4139 29033+ h_path.mnt = au_br_mnt(br);
1facf9fc 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 */
b4510431 29046+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
1facf9fc 29047+
4f0767ce 29048+out:
1facf9fc 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);
b4510431 29069+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 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,
86dc4139 29082+ .mnt = au_br_mnt(br)
1facf9fc 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+
4f0767ce 29091+out:
1facf9fc 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) {
b4510431 29151+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 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;
c06a8ce3 29193+ struct au_vdir_wh *pos;
1facf9fc 29194+ struct au_vdir_destr *str;
29195+
29196+ err = -ENOMEM;
537831f9 29197+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 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++) {
c06a8ce3
AM
29208+ hlist_for_each_entry(pos, head, wh_hash) {
29209+ if (pos->wh_bindex != bindex)
1facf9fc 29210+ continue;
29211+
c06a8ce3 29212+ str = &pos->wh_str;
1facf9fc 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+ }
537831f9 29227+ free_page((unsigned long)wh_name.name);
1facf9fc 29228+
4f0767ce 29229+out:
1facf9fc 29230+ return err;
29231+}
29232+
29233+struct del_wh_children_args {
29234+ int *errp;
29235+ struct dentry *h_dentry;
1308ab2a 29236+ struct au_nhash *whlist;
1facf9fc 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;
1308ab2a 29244+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 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;
dece6358 29252+ int err;
1308ab2a 29253+ unsigned int rdhash;
dece6358
AM
29254+
29255+ SiMustAnyLock(sb);
1facf9fc 29256+
29257+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
29258+ if (unlikely(!whtmp)) {
29259+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 29260+ goto out;
dece6358 29261+ }
1facf9fc 29262+
29263+ whtmp->dir = NULL;
027c5e7a 29264+ whtmp->br = NULL;
1facf9fc 29265+ whtmp->wh_dentry = NULL;
1308ab2a 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+ }
dece6358 29275+
4f0767ce 29276+out:
dece6358 29277+ return whtmp;
1facf9fc 29278+}
29279+
29280+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
29281+{
027c5e7a
AM
29282+ if (whtmp->br)
29283+ atomic_dec(&whtmp->br->br_count);
1facf9fc 29284+ dput(whtmp->wh_dentry);
29285+ iput(whtmp->dir);
dece6358 29286+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 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,
1308ab2a 29320+ .whlist = whlist,
1facf9fc 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;
86dc4139 29333+ h_tmp.mnt = au_br_mnt(br);
1facf9fc 29334+ err = vfsub_rmdir(h_dir, &h_tmp);
1facf9fc 29335+ }
29336+
29337+ if (!err) {
29338+ if (au_ibstart(dir) == bindex) {
7f207e10 29339+ /* todo: dir->i_mutex is necessary */
1facf9fc 29340+ au_cpup_attr_timesizes(dir);
7f207e10 29341+ vfsub_drop_nlink(dir);
1facf9fc 29342+ }
29343+ return 0; /* success */
29344+ }
29345+
0c3ec466
AM
29346+ pr_warn("failed removing %.*s(%d), ignored\n",
29347+ AuDLNPair(wh_dentry), err);
1facf9fc 29348+ return err;
29349+}
29350+
29351+static void call_rmdir_whtmp(void *args)
29352+{
29353+ int err;
e49829fe 29354+ aufs_bindex_t bindex;
1facf9fc 29355+ struct au_whtmp_rmdir *a = args;
29356+ struct super_block *sb;
29357+ struct dentry *h_parent;
29358+ struct inode *h_dir;
1facf9fc 29359+ struct au_hinode *hdir;
29360+
29361+ /* rmdir by nfsd may cause deadlock with this i_mutex */
29362+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 29363+ err = -EROFS;
1facf9fc 29364+ sb = a->dir->i_sb;
e49829fe
JR
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))
1facf9fc 29370+ goto out;
29371+
29372+ err = -EIO;
1facf9fc 29373+ ii_write_lock_parent(a->dir);
29374+ h_parent = dget_parent(a->wh_dentry);
29375+ h_dir = h_parent->d_inode;
e49829fe 29376+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
29377+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
29378+ if (unlikely(err))
29379+ goto out_mnt;
4a4d8108 29380+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
29381+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
29382+ a->br);
86dc4139
AM
29383+ if (!err)
29384+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
4a4d8108 29385+ au_hn_imtx_unlock(hdir);
86dc4139
AM
29386+ vfsub_mnt_drop_write(au_br_mnt(a->br));
29387+
29388+out_mnt:
1facf9fc 29389+ dput(h_parent);
29390+ ii_write_unlock(a->dir);
4f0767ce 29391+out:
1facf9fc 29392+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 29393+ au_whtmp_rmdir_free(a);
027c5e7a
AM
29394+ si_read_unlock(sb);
29395+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 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;
e49829fe 29404+ struct super_block *sb;
1facf9fc 29405+
29406+ IMustLock(dir);
29407+
29408+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 29409+ sb = dir->i_sb;
1facf9fc 29410+ args->dir = au_igrab(dir);
e49829fe
JR
29411+ args->br = au_sbr(sb, bindex);
29412+ atomic_inc(&args->br->br_count);
1facf9fc 29413+ args->wh_dentry = dget(wh_dentry);
53392da6 29414+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 29415+ if (unlikely(wkq_err)) {
0c3ec466
AM
29416+ pr_warn("rmdir error %.*s (%d), ignored\n",
29417+ AuDLNPair(wh_dentry), wkq_err);
1facf9fc 29418+ au_whtmp_rmdir_free(args);
29419+ }
29420+}
7f207e10
AM
29421diff -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
86dc4139
AM
29423+++ linux/fs/aufs/whout.h 2013-07-06 13:20:47.760198800 +0200
29424@@ -0,0 +1,87 @@
1facf9fc 29425+/*
7a9e40b8 29426+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
1facf9fc 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);
86dc4139 29465+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 29466+
29467+/* diropq flags */
29468+#define AuDiropq_CREATE 1
29469+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
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)
1facf9fc 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;
e49829fe 29485+ struct au_branch *br;
1facf9fc 29486+ struct dentry *wh_dentry;
dece6358 29487+ struct au_nhash whlist;
1facf9fc 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__ */
7f207e10
AM
29512diff -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
86dc4139
AM
29514+++ linux/fs/aufs/wkq.c 2013-07-06 13:20:47.760198800 +0200
29515@@ -0,0 +1,213 @@
1facf9fc 29516+/*
7a9e40b8 29517+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 29532+ */
29533+
29534+/*
29535+ * workqueue for asynchronous/super-io operations
29536+ * todo: try new dredential scheme
29537+ */
29538+
dece6358 29539+#include <linux/module.h>
1facf9fc 29540+#include "aufs.h"
29541+
9dbd164d 29542+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 29543+
9dbd164d 29544+static struct workqueue_struct *au_wkq;
1facf9fc 29545+
29546+struct au_wkinfo {
29547+ struct work_struct wk;
7f207e10 29548+ struct kobject *kobj;
1facf9fc 29549+
29550+ unsigned int flags; /* see wkq.h */
29551+
29552+ au_wkq_func_t func;
29553+ void *args;
29554+
1facf9fc 29555+ struct completion *comp;
29556+};
29557+
29558+/* ---------------------------------------------------------------------- */
29559+
1facf9fc 29560+static void wkq_func(struct work_struct *wk)
29561+{
29562+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
29563+
2dfbb274 29564+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
29565+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
29566+
1facf9fc 29567+ wkinfo->func(wkinfo->args);
1facf9fc 29568+ if (au_ftest_wkq(wkinfo->flags, WAIT))
29569+ complete(wkinfo->comp);
29570+ else {
7f207e10 29571+ kobject_put(wkinfo->kobj);
9dbd164d 29572+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 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+
53392da6 29618+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 29619+{
53392da6
AM
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)) {
a1f66529 29629+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 29630+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
29631+ } else {
29632+ INIT_WORK(&wkinfo->wk, wkq_func);
29633+ schedule_work(&wkinfo->wk);
29634+ }
1facf9fc 29635+}
29636+
7f207e10
AM
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+ */
b752ccd1 29643+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 29644+{
29645+ int err;
29646+ AuWkqCompDeclare(comp);
29647+ struct au_wkinfo wkinfo = {
b752ccd1 29648+ .flags = flags,
1facf9fc 29649+ .func = func,
29650+ .args = args
29651+ };
29652+
29653+ err = au_wkq_comp_alloc(&wkinfo, &comp);
29654+ if (!err) {
53392da6 29655+ au_wkq_run(&wkinfo);
1facf9fc 29656+ /* no timeout, no interrupt */
29657+ wait_for_completion(wkinfo.comp);
29658+ au_wkq_comp_free(comp);
4a4d8108 29659+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 29660+ }
29661+
29662+ return err;
29663+
29664+}
29665+
027c5e7a
AM
29666+/*
29667+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
29668+ * problem in a concurrent umounting.
29669+ */
53392da6
AM
29670+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
29671+ unsigned int flags)
1facf9fc 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) {
7f207e10 29685+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 29686+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 29687+ wkinfo->func = func;
29688+ wkinfo->args = args;
29689+ wkinfo->comp = NULL;
7f207e10 29690+ kobject_get(wkinfo->kobj);
9dbd164d 29691+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 29692+
53392da6 29693+ au_wkq_run(wkinfo);
1facf9fc 29694+ } else {
29695+ err = -ENOMEM;
e49829fe 29696+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 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);
4a4d8108 29707+ /* smp_mb(); */ /* atomic_set */
1facf9fc 29708+ init_waitqueue_head(&nwt->nw_wq);
29709+}
29710+
29711+void au_wkq_fin(void)
29712+{
9dbd164d 29713+ destroy_workqueue(au_wkq);
1facf9fc 29714+}
29715+
29716+int __init au_wkq_init(void)
29717+{
9dbd164d 29718+ int err;
b752ccd1
AM
29719+
29720+ err = 0;
86dc4139 29721+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
29722+ if (IS_ERR(au_wkq))
29723+ err = PTR_ERR(au_wkq);
29724+ else if (!au_wkq)
29725+ err = -ENOMEM;
b752ccd1
AM
29726+
29727+ return err;
1facf9fc 29728+}
7f207e10
AM
29729diff -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
86dc4139 29731+++ linux/fs/aufs/wkq.h 2013-07-06 13:20:47.760198800 +0200
f6c5ef8b 29732@@ -0,0 +1,92 @@
1facf9fc 29733+/*
7a9e40b8 29734+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 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+
dece6358
AM
29761+struct super_block;
29762+
1facf9fc 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
9dbd164d 29779+#define AuWkq_NEST (1 << 1)
1facf9fc 29780+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
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)
1facf9fc 29785+
9dbd164d
AM
29786+#ifndef CONFIG_AUFS_HNOTIFY
29787+#undef AuWkq_NEST
29788+#define AuWkq_NEST 0
29789+#endif
29790+
1facf9fc 29791+/* wkq.c */
b752ccd1 29792+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
29793+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
29794+ unsigned int flags);
1facf9fc 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+
53392da6
AM
29801+static inline int au_wkq_test(void)
29802+{
29803+ return current->flags & PF_WQ_WORKER;
29804+}
29805+
b752ccd1 29806+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 29807+{
b752ccd1 29808+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 29809+}
29810+
29811+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
29812+{
e49829fe 29813+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 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__ */
7f207e10
AM
29825diff -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
86dc4139 29827+++ linux/fs/aufs/xino.c 2013-07-06 13:20:47.760198800 +0200
c06a8ce3 29828@@ -0,0 +1,1264 @@
1facf9fc 29829+/*
7a9e40b8 29830+ * Copyright (C) 2005-2013 Junjiro R. Okajima
1facf9fc 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.
dece6358
AM
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
1facf9fc 29845+ */
29846+
29847+/*
29848+ * external inode number translation table and bitmap
29849+ */
29850+
29851+#include <linux/seq_file.h>
1facf9fc 29852+#include "aufs.h"
29853+
9dbd164d 29854+/* todo: unnecessary to support mmap_sem since kernel-space? */
b752ccd1 29855+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 29856+ loff_t *pos)
29857+{
29858+ ssize_t err;
29859+ mm_segment_t oldfs;
b752ccd1
AM
29860+ union {
29861+ void *k;
29862+ char __user *u;
29863+ } buf;
1facf9fc 29864+
b752ccd1 29865+ buf.k = kbuf;
1facf9fc 29866+ oldfs = get_fs();
29867+ set_fs(KERNEL_DS);
29868+ do {
29869+ /* todo: signal_pending? */
b752ccd1 29870+ err = func(file, buf.u, size, pos);
1facf9fc 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+
b752ccd1 29884+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
1facf9fc 29885+ size_t size, loff_t *pos)
29886+{
29887+ ssize_t err;
29888+ mm_segment_t oldfs;
b752ccd1
AM
29889+ union {
29890+ void *k;
29891+ const char __user *u;
29892+ } buf;
1facf9fc 29893+
b752ccd1 29894+ buf.k = kbuf;
1facf9fc 29895+ oldfs = get_fs();
29896+ set_fs(KERNEL_DS);
1facf9fc 29897+ do {
29898+ /* todo: signal_pending? */
b752ccd1 29899+ err = func(file, buf.u, size, pos);
1facf9fc 29900+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 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? */
b752ccd1
AM
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+ */
1facf9fc 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;
b752ccd1 29954+ }
1facf9fc 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;
4a4d8108 29967+ struct dentry *base, *parent;
1facf9fc 29968+ struct inode *dir;
29969+ struct qstr *name;
1308ab2a 29970+ struct path path;
4a4d8108 29971+ int err;
1facf9fc 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;
4a4d8108
AM
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));
1facf9fc 29985+ goto out;
29986+ }
29987+
29988+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 29989+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 29990+ if (unlikely(err)) {
29991+ file = ERR_PTR(err);
4a4d8108 29992+ pr_err("%.*s create err %d\n", AuLNPair(name), err);
1facf9fc 29993+ goto out_dput;
29994+ }
29995+
c06a8ce3 29996+ path.mnt = base_file->f_path.mnt;
4a4d8108 29997+ file = vfsub_dentry_open(&path,
7f207e10 29998+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 29999+ /* | __FMODE_NONOTIFY */);
1facf9fc 30000+ if (IS_ERR(file)) {
4a4d8108 30001+ pr_err("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
1facf9fc 30002+ goto out_dput;
30003+ }
30004+
30005+ err = vfsub_unlink(dir, &file->f_path, /*force*/0);
30006+ if (unlikely(err)) {
4a4d8108 30007+ pr_err("%.*s unlink err %d\n", AuLNPair(name), err);
1facf9fc 30008+ goto out_fput;
30009+ }
30010+
30011+ if (copy_src) {
30012+ /* no one can touch copy_src xino */
c06a8ce3 30013+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 30014+ if (unlikely(err)) {
4a4d8108 30015+ pr_err("%.*s copy err %d\n", AuLNPair(name), err);
1facf9fc 30016+ goto out_fput;
30017+ }
30018+ }
30019+ goto out_dput; /* success */
30020+
4f0767ce 30021+out_fput:
1facf9fc 30022+ fput(file);
30023+ file = ERR_PTR(err);
4f0767ce 30024+out_dput:
4a4d8108 30025+ dput(path.dentry);
4f0767ce 30026+out:
1facf9fc 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);
4a4d8108 30048+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 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)
4a4d8108 30059+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 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+
86dc4139 30099+ h_sb = au_br_sb(br);
1facf9fc 30100+ for (bi = 0; bi <= bend; bi++) {
30101+ if (unlikely(bi == bindex))
30102+ continue;
30103+ br = au_sbr(sb, bi);
86dc4139 30104+ if (au_br_sb(br) != h_sb)
1facf9fc 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+
4f0767ce 30112+out:
1facf9fc 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);
dece6358 30139+ if (!err
c06a8ce3 30140+ && file_inode(br->br_xino.xi_file)->i_blocks
1facf9fc 30141+ >= br->br_xino_upper)
30142+ br->br_xino_upper += AUFS_XINO_TRUNC_STEP;
30143+
1facf9fc 30144+ ii_read_unlock(dir);
30145+ if (unlikely(err))
1716fcea
AM
30146+ pr_warn("err b%d, upper %llu, (%d)\n",
30147+ bindex, (unsigned long long)br->br_xino_upper, err);
1facf9fc 30148+ atomic_dec(&br->br_xino_running);
30149+ atomic_dec(&br->br_count);
1facf9fc 30150+ si_write_unlock(sb);
027c5e7a 30151+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 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+
c06a8ce3 30160+ if (file_inode(br->br_xino.xi_file)->i_blocks
1facf9fc 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+
e49829fe 30174+ atomic_inc(&br->br_count);
1facf9fc 30175+ args->sb = sb;
30176+ args->br = br;
53392da6 30177+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 30178+ if (!wkq_err)
30179+ return; /* success */
30180+
4a4d8108 30181+ pr_err("wkq %d\n", wkq_err);
e49829fe 30182+ atomic_dec(&br->br_count);
1facf9fc 30183+
4f0767ce 30184+out_args:
1facf9fc 30185+ kfree(args);
4f0767ce 30186+out:
e49829fe 30187+ atomic_dec(&br->br_xino_running);
1facf9fc 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);
dece6358 30228+ SiMustAnyLock(sb);
1facf9fc 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)
86dc4139 30239+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 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;
c06a8ce3 30297+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 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+
4f0767ce 30308+out:
b752ccd1
AM
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;
1facf9fc 30368+
b752ccd1
AM
30369+ bindex = iinfo->ii_bstart;
30370+ if (bindex < 0)
30371+ return;
1facf9fc 30372+
b752ccd1
AM
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;
1facf9fc 30382+
b752ccd1
AM
30383+ /* inode may not be revalidated */
30384+ bi = au_br_index(sb, hi->hi_id);
30385+ if (bi < 0)
30386+ continue;
1facf9fc 30387+
b752ccd1
AM
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
86dc4139 30392+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 30393+ xino_try_trunc(sb, br);
1facf9fc 30394+ }
1facf9fc 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;
c06a8ce3 30430+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 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+
4f0767ce 30441+out:
1facf9fc 30442+ set_bit(free_bit, p);
7f207e10 30443+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 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;
4f0767ce 30449+out_err:
1facf9fc 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;
c06a8ce3 30483+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 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,
4a4d8108 30512+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 30513+ * when a user specified the xino, we cannot get au_hdir to be ignored.
30514+ */
7f207e10 30515+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 30516+ /* | __FMODE_NONOTIFY */,
1facf9fc 30517+ S_IRUGO | S_IWUGO);
30518+ if (IS_ERR(file)) {
30519+ if (!silent)
4a4d8108 30520+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 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)
4a4d8108 30534+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 30535+ goto out;
30536+ }
30537+
30538+ err = -EINVAL;
30539+ d = file->f_dentry;
30540+ if (unlikely(sb == d->d_sb)) {
30541+ if (!silent)
4a4d8108 30542+ pr_err("%s must be outside\n", fname);
1facf9fc 30543+ goto out;
30544+ }
30545+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
30546+ if (!silent)
4a4d8108
AM
30547+ pr_err("xino doesn't support %s(%s)\n",
30548+ fname, au_sbtype(d->d_sb));
1facf9fc 30549+ goto out;
30550+ }
30551+ return file; /* success */
30552+
4f0767ce 30553+out:
1facf9fc 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) {
86dc4139 30599+ tgt_sb = au_br_sb(br);
1facf9fc 30600+ for (bindex = 0; bindex <= bend; bindex++) {
30601+ b = au_sbr(sb, bindex);
86dc4139 30602+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 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);
b752ccd1
AM
30628+ if (unlikely(err)) {
30629+ fput(br->br_xino.xi_file);
30630+ br->br_xino.xi_file = NULL;
30631+ }
1facf9fc 30632+
4f0767ce 30633+out:
1facf9fc 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);
dece6358 30655+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 30656+ p = sbinfo->si_xib_buf;
30657+ func = sbinfo->si_xread;
c06a8ce3 30658+ pend = vfsub_f_size_read(file);
1facf9fc 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+
4f0767ce 30681+out:
1facf9fc 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+
4f0767ce 30706+out:
1facf9fc 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+
dece6358
AM
30720+ SiMustWriteLock(sb);
30721+
1facf9fc 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;
c06a8ce3 30728+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 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+
dece6358
AM
30798+ SiMustWriteLock(sb);
30799+
1facf9fc 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+
dece6358
AM
30817+ SiMustWriteLock(sb);
30818+
1facf9fc 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;
c06a8ce3 30838+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 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+
4f0767ce 30848+out_free:
1facf9fc 30849+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
30850+ sbinfo->si_xib_buf = NULL;
30851+ if (err >= 0)
30852+ err = -EIO;
4f0767ce 30853+out_unset:
b752ccd1
AM
30854+ fput(sbinfo->si_xib);
30855+ sbinfo->si_xib = NULL;
30856+ sbinfo->si_xread = NULL;
30857+ sbinfo->si_xwrite = NULL;
4f0767ce 30858+out:
b752ccd1 30859+ return err;
1facf9fc 30860+}
30861+
b752ccd1
AM
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;
1facf9fc 30867+
b752ccd1
AM
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)
1facf9fc 30880+{
30881+ int err;
b752ccd1
AM
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;
1facf9fc 30890+
b752ccd1
AM
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))
1facf9fc 30897+ goto out;
30898+
b752ccd1
AM
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+ }
1facf9fc 30935+
4f0767ce 30936+out_pair:
b752ccd1
AM
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);
4f0767ce 30943+out:
1facf9fc 30944+ return err;
30945+}
b752ccd1
AM
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+
4f0767ce 31006+out:
b752ccd1
AM
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)
86dc4139 31031+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
31032+ bwr = bindex;
31033+ break;
31034+ }
31035+ }
31036+
7f207e10
AM
31037+ if (bwr >= 0) {
31038+ file = ERR_PTR(-ENOMEM);
537831f9 31039+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
31040+ if (unlikely(!page))
31041+ goto out;
86dc4139 31042+ path.mnt = au_br_mnt(br);
7f207e10
AM
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+ }
537831f9 31053+ free_page((unsigned long)page);
7f207e10
AM
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+ }
0c5527e5 31068+
7f207e10
AM
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+}
31093diff -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
86dc4139 31095+++ linux/include/linux/aufs_type.h 2013-07-06 13:20:47.760198800 +0200
537831f9
AM
31096@@ -0,0 +1,19 @@
31097+/*
7a9e40b8 31098+ * Copyright (C) 2012-2013 Junjiro R. Okajima
537831f9
AM
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>
31116diff -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
367653fa 31118+++ linux/include/uapi/linux/aufs_type.h 2013-07-30 22:42:55.842946719 +0200
86dc4139 31119@@ -0,0 +1,235 @@
7f207e10 31120+/*
7a9e40b8 31121+ * Copyright (C) 2005-2013 Junjiro R. Okajima
7f207e10
AM
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+
f6c5ef8b
AM
31141+#define AUFS_NAME "aufs"
31142+
9dbd164d 31143+#ifdef __KERNEL__
f6c5ef8b
AM
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
a2a7ad62
AM
31152+#define pr_fmt(fmt) \
31153+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
31154+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
31155+#else
31156+#include <stdint.h>
31157+#include <sys/types.h>
f6c5ef8b 31158+#endif /* __KERNEL__ */
7f207e10 31159+
f6c5ef8b
AM
31160+#include <linux/limits.h>
31161+
367653fa 31162+#define AUFS_VERSION "3.10-20130722"
7f207e10
AM
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
9dbd164d 31170+typedef int8_t aufs_bindex_t;
7f207e10
AM
31171+#define AUFS_BRANCH_MAX 127
31172+#else
9dbd164d 31173+typedef int16_t aufs_bindex_t;
7f207e10
AM
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+
7f207e10
AM
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
86dc4139 31199+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
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 */
027c5e7a 31210+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
31211+#define AUFS_RDBLK_DEF 512 /* bytes */
31212+#define AUFS_RDHASH_DEF 32
31213+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
31214+#define AUFS_MFS_DEF_SEC 30 /* seconds */
31215+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
86dc4139 31216+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
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+
1e00d052 31235+/* branch permissions and attributes */
7f207e10
AM
31236+#define AUFS_BRPERM_RW "rw"
31237+#define AUFS_BRPERM_RO "ro"
31238+#define AUFS_BRPERM_RR "rr"
1e00d052
AM
31239+#define AUFS_BRRATTR_WH "wh"
31240+#define AUFS_BRWATTR_NLWH "nolwh"
86dc4139 31241+#define AUFS_BRATTR_UNPIN "unpin"
7f207e10
AM
31242+
31243+/* ---------------------------------------------------------------------- */
31244+
31245+/* ioctl */
31246+enum {
31247+ /* readdir in userspace */
31248+ AuCtl_RDU,
31249+ AuCtl_RDU_INO,
31250+
31251+ /* pathconf wrapper */
027c5e7a
AM
31252+ AuCtl_WBR_FD,
31253+
31254+ /* busy inode */
31255+ AuCtl_IBUSY
7f207e10
AM
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)))
53392da6
AM
31267+#endif
31268+
31269+#ifdef __KERNEL__
31270+#ifndef __packed
7f207e10
AM
31271+#define __packed __attribute__((packed))
31272+#endif
53392da6 31273+#endif
7f207e10
AM
31274+
31275+struct au_rdu_cookie {
9dbd164d
AM
31276+ uint64_t h_pos;
31277+ int16_t bindex;
31278+ uint8_t flags;
31279+ uint8_t pad;
31280+ uint32_t generation;
7f207e10
AM
31281+} __aligned(8);
31282+
31283+struct au_rdu_ent {
9dbd164d
AM
31284+ uint64_t ino;
31285+ int16_t bindex;
31286+ uint8_t type;
31287+ uint8_t nlen;
31288+ uint8_t wh;
7f207e10
AM
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,
9dbd164d 31296+ sizeof(uint64_t));
7f207e10
AM
31297+}
31298+
31299+union au_rdu_ent_ul {
31300+ struct au_rdu_ent __user *e;
9dbd164d 31301+ uint64_t ul;
7f207e10
AM
31302+};
31303+
31304+enum {
31305+ AufsCtlRduV_SZ,
31306+ AufsCtlRduV_End
31307+};
31308+
31309+struct aufs_rdu {
31310+ /* input */
31311+ union {
9dbd164d
AM
31312+ uint64_t sz; /* AuCtl_RDU */
31313+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
31314+ };
31315+ union au_rdu_ent_ul ent;
9dbd164d 31316+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
31317+
31318+ /* input/output */
9dbd164d 31319+ uint32_t blk;
7f207e10
AM
31320+
31321+ /* output */
31322+ union au_rdu_ent_ul tail;
31323+ /* number of entries which were added in a single call */
9dbd164d
AM
31324+ uint64_t rent;
31325+ uint8_t full;
31326+ uint8_t shwh;
7f207e10
AM
31327+
31328+ struct au_rdu_cookie cookie;
31329+} __aligned(8);
31330+
1e00d052
AM
31331+/* ---------------------------------------------------------------------- */
31332+
31333+struct aufs_wbr_fd {
9dbd164d
AM
31334+ uint32_t oflags;
31335+ int16_t brid;
1e00d052
AM
31336+} __aligned(8);
31337+
31338+/* ---------------------------------------------------------------------- */
31339+
027c5e7a 31340+struct aufs_ibusy {
9dbd164d
AM
31341+ uint64_t ino, h_ino;
31342+ int16_t bindex;
027c5e7a
AM
31343+} __aligned(8);
31344+
1e00d052
AM
31345+/* ---------------------------------------------------------------------- */
31346+
7f207e10
AM
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)
1e00d052
AM
31350+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
31351+ struct aufs_wbr_fd)
027c5e7a 31352+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
7f207e10
AM
31353+
31354+#endif /* __AUFS_TYPE_H__ */
367653fa 31355
This page took 5.825395 seconds and 4 git commands to generate.